Active Directory (ADAM) on Windows Server 2000 SP4 .Net 1.1 does not work
I am working for a large banking client who have older infrastructure in the Application services layer.
I have created a COM+ component that resides in an Application server with the following specs:
* Windows Server 2000 SP4
* .Net Framework 1.1
* has its own workgroup
This component communicates to an ADAM (AD) server with the following specs:
* Windows Server 2003 Standard Edition R2 (5.2.3790)
To remove any COM+ complexity, I have created a simple .Net Windows application to test the ADAM calls.
When I call ResetPassword from my XP SP2 machine, it works as does the test from another Windows Server 2003 R2 machine on the domain.
When I move the same binary to the Windows 2000 box, the ResetPassword call DOES NOT work. I have another method called IsValid that takes in a user id and password and validates it in ADAM. IsValid WORKS on the Windows 2000 box.
I raised a call with a Microsoft representative and they have been able to replicate this issue on their environments.
After debugging code, I have observed that the bind to ADAM works. It only breaks when ResetPassword is called and only from Windows 2000.
I have spent close to a week going to and fro with Microsoft and still do not have a resolution.
I think it could be one of the following:
- A bug with .Net framework 1.1 on Windows 2000
- Incorrect code on my part
- Incorrect setup of ADAM
Here why I think it may be a Microsoft bug:
- the code WORKS from other non-Windows 2000 machines
- I am using AD PwdReset code from MSDN (http://msdn.microsoft.com/en-us/library/aa772136.aspx) which has been verified by Microsoft (with a minor tweak, see code below where the invoke arguments are explicitly cast to object)
=========================================================================
Here is the ResetPassword code:
Code Snippetpublic Response ResetPassword(User user, string newPassword, bool useSSL) {
Response response;
try {
AuthenticationTypes authTypes = (useSSL ? (AuthenticationTypes.None | AuthenticationTypes.SecureSocketsLayer) : (AuthenticationTypes.None));
Trace.WriteLine("===============================================================");
Trace.WriteLine(string.Format("Authentication format is : {0}", authTypes.ToString()));
Trace.WriteLine("===============================================================");
Trace.Flush();
// Bind to user object using LDAP port.
// GetOrgUrl = LDAP://m01:50008/CN=Users,CN=org1
using (DirectoryEntry entry = new DirectoryEntry(GetOrgUrl(useSSL),
_adminUser, _adminPwd, authTypes)) {
Trace.WriteLine("===============================================================");
Trace.WriteLine(string.Format("LDAP Top Level Path for ResetPasswod (SSL) function is: {0}", OrgUrl(useSSL)));
Trace.WriteLine("===============================================================");
Trace.Flush();
entry.RefreshCache();
Trace.WriteLine("===============================================================");
Trace.WriteLine(string.Format("Successfully bound to: {0}", GetOrgUrl(useSSL)));
Trace.WriteLine("===============================================================");
Trace.Flush();
/* Find the user */
using (DirectorySearcher ds = new DirectorySearcher(entry)) {
ds.SearchScope = SearchScope.Subtree;
ds.Filter = "(&(objectclass=*)(cn= " + user.UserName + "))";
SearchResult sr;
sr = ds.FindOne();
if (sr != null) {
using (DirectoryEntry de = new DirectoryEntry(sr.Path, _adminUser, _adminPwd, authTypes)) {
Trace.WriteLine("===============================================================");
Trace.WriteLine(string.Format("Binding to user path: {0} using authentication type: {1}",
sr.Path, authTypes));
Trace.WriteLine("===============================================================");
Trace.Flush();
de.RefreshCache();
Trace.WriteLine("===============================================================");
Trace.WriteLine("Invoking ResetPassword ...");
Trace.WriteLine("===============================================================");
Trace.Flush();
//Reset password throws an exception here while running on Windows Server 2000
de.Invoke("SetOption", new object[] {(int)ADS_OPTION_PASSWORD_PORTNUMBER, (object)_portNo });
de.Invoke("SetOption", new object[] { (int)ADS_OPTION_PASSWORD_METHOD, (object)ADS_PASSWORD_ENCODE_CLEAR});
de.Invoke("SetPassword", new object[] {newPassword});
response = new Response();
response.IsSuccess = true;
response.Data = "TRUE";
}}
else {
Trace.WriteLine("=======================================================================");
Trace.WriteLine(string.Format("User {0} not found", user.UserName));
Trace.WriteLine("=======================================================================");
Trace.Flush();
response = new Response();
response.IsSuccess = false;
response.FriendlyMessage = string.Format("ResetPassword call failed for user {0}", user.UserName);
response.Message = string.Format("User {0} does not exist.", user.UserName);
response.Data = "FALSE";
}}}}
catch (System.Reflection.TargetInvocationException tEx) {
response = GetError(tEx);
response.FriendlyMessage = string.Format("ResetPassword call failed for user {0}", user.UserName);
response.Data = "FALSE";
}
catch (Exception ex) {
response = GetError(ex);
response.FriendlyMessage = string.Format("ResetPassword call failed for user {0}", user.UserName);
response.Data = "FALSE"; }
return response; }
Here is the error message that I get:
ResetPasswordNonSSL() called.
Response
===========
IsSuccess: False
Data: FALSE
Friendly Message:ResetPassword call failed for user user1
Message: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException (0x80005008): Exception from HRESULT: 0x80005008.
--- End of inner exception stack trace ---
at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)
at ADAM.ADAMHelper.ResetPassword(User user, String newPassword, Boolean useSSL)
Stack Trace: at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)
at ADAM.ADAMHelper.ResetPassword(User user, String newPassword, Boolean useSSL)
======================================================================================
Authentication format is : None
======================================================================================
LDAP Top Level Path for ResetPasswod (SSL) function is: LDAP://m01:50008/CN=Users,CN=org1
======================================================================================
======================================================================================
Successfully bound to: LDAP://m01:50008/CN=Users,CN=org1
======================================================================================
======================================================================================
Binding to user path: LDAP://m01:50008/CN=user1,CN=Users,CN=org1 using authentication type: None
======================================================================================
======================================================================================
Invoking ResetPassword ...
======================================================================================
Réponses
This issue has been resolved !!!
I had to apply a Hotfix on the Windows 2000 machine that was calling ADAM.
See this url:
http://support.microsoft.com/kb/817583
The principal cause was the following:
"This problem occurs because ADSI is restricted to SSL port number 636 when it makes a bind call to the LDAP server."
Toutes les réponses
This issue has been resolved !!!
I had to apply a Hotfix on the Windows 2000 machine that was calling ADAM.
See this url:
http://support.microsoft.com/kb/817583
The principal cause was the following:
"This problem occurs because ADSI is restricted to SSL port number 636 when it makes a bind call to the LDAP server."

