Recursos para Profesionales de TI > Página principal de foros > Development > Active Directory (ADAM) on Windows Server 2000 SP4 .Net 1.1 does not work
Formular una preguntaFormular una pregunta
 

RespondidaActive Directory (ADAM) on Windows Server 2000 SP4 .Net 1.1 does not work

  • lunes, 20 de octubre de 2008 2:51Shailen Sukul Medallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuarioMedallas del usuario
     

    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 Snippet

    public 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 ...

    ======================================================================================


     

     

Respuestas

Todas las respuestas