LDAP validation fails when “User must change password on next log on”. Any solution?

后端 未结 3 903
醉话见心
醉话见心 2021-01-01 03:57

I\'m having trouble with a user validation when the \"User must change password on next log on\" is set.

Here\'s how I validate the user:

Boolean Val         


        
相关标签:
3条回答
  • 2021-01-01 04:28

    Unfortunately, using an error message is not a fool-proof way to accomplish verify the reasons an account login was rejected. For this reason, it is important to understand how your LDAP environment manages user accounts. In Microsoft Active Directory, the userAccountControl field is used to handle most account statuses. Here is a list of common userAccountControl bits:

    LDAP_UF_ACCOUNT_DISABLE = 2
    LDAP_UF_HOMEDIR_REQUIRED = 8
    LDAP_UF_LOCKOUT = 16
    LDAP_UF_PASSWD_NOTREQD = 32
    LDAP_UF_PASSWD_CANT_CHANGE = 64
    LDAP_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 128
    LDAP_UF_NORMAL_ACCOUNT = 512
    LDAP_UF_INTERDOMAIN_TRUST_ACCOUNT = 2048
    LDAP_UF_WORKSTATION_TRUST_ACCOUNT = 4096
    LDAP_UF_SERVER_TRUST_ACCOUNT = 8192
    LDAP_UF_DONT_EXPIRE_PASSWD = 65536
    LDAP_UF_MNS_LOGON_ACCOUNT = 131072
    LDAP_UF_SMARTCARD_REQUIRED = 262144
    LDAP_UF_TRUSTED_FOR_DELEGATION = 524288
    LDAP_UF_NOT_DELEGATED = 1048576
    LDAP_UF_USE_DES_KEY_ONLY = 2097152
    LDAP_UF_DONT_REQUIRE_PREAUTH = 4194304
    LDAP_UF_PASSWORD_EXPIRED = 8388608
    LDAP_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 16777216
    LDAP_UF_NO_AUTH_DATA_REQUIRED = 33554432
    LDAP_UF_PARTIAL_SECRETS_ACCOUNT = 67108864
    

    Keep in mind that these are often combined. So, for instance, if a user with a normal account (LDAP_UF_NORMAL_ACCOUNT) is also disabled (LDAP_UF_ACCOUNT_DISABLE), the LDAP field userAccountControl would be set to 514 (Because 512 + 2 = 514)

    Now, to answer the original question: When a user account is set for "Password must be changed", AD simply adds LDAP_UF_PASSWORD_EXPIRED to the userAccountControl field. So: Normal Account: LDAP_UF_NORMAL_ACCOUNT + LDAP_UF_PASSWORD_EXPIRED = 8389120

    For this specific instance (Password Expired), that is by far the most common value, but it isn't the only one. You need to consider all possible options when evaluating if the account is set for password expired.

    Of course, this isn't the easiest way to verify settings, but it is the most reliable way.

    0 讨论(0)
  • 2021-01-01 04:36

    After a long search on the Internet, some empirical work with error messages and some spelunking through Win32API, I've came up with a solution that, so far works.

    Boolean ValidateUser(String userName, String password)
    {
      try
      {
        var user = new DirectoryEntry("LDAP://<my LDAP server>", 
                        userName, 
                        password);
        var obj = user.NativeObject;
        return true;
      }
      catch (DirectoryServicesCOMException ex)
      {
        /*
         * The string " 773," was discovered empirically and it is related to the
         * ERROR_PASSWORD_MUST_CHANGE = 0x773 that is returned by the LogonUser API.
         * 
         * However this error code is not in any value field of the 
         * error message, therefore we need to check for the existence of 
         * the string in the error message.
         */
         if (ex.ExtendedErrorMessage.Contains(" 773,"))
            throw new UserMustChangePasswordException();
    
         return false;
      }
      catch
      {
         throw;
      }
    }
    
    0 讨论(0)
  • 2021-01-01 04:50

    Thank you Paulo. This works for me. Using this link I've expanded response after exception occur, something like this:

    Catch ex As DirectoryServicesCOMException
            Dim msg As String = Nothing
            Select Case True
                Case ex.ExtendedErrorMessage.Contains("773")
                    msg = "Error 773. User must change password at next logon is set.​ Please contact support."
                Case ex.ExtendedErrorMessage.Contains("525")
                    msg = "User not found"
                Case ex.ExtendedErrorMessage.Contains("52e")
                    msg = "Invalid credentials"
                Case ex.ExtendedErrorMessage.Contains("530")
                    msg = "Not permitted to logon at this time​"
                Case ex.ExtendedErrorMessage.Contains("531")
                    msg = "Not permitted to logon at this workstation​"
                Case ex.ExtendedErrorMessage.Contains("532")
                    msg = "Password expired"
                Case ex.ExtendedErrorMessage.Contains("533")
                    msg = "Account disabled"
                Case ex.ExtendedErrorMessage.Contains("701")
                    msg = "Account expired"
                Case ex.ExtendedErrorMessage.Contains("775")
                    msg = "User account is locked"
            End Select
            If msg IsNot Nothing Then
                errorLabel.Text = ex.Message & " " & msg
            Else
                errorLabel.Text = ex.Message
            End If
        End Try
    
    0 讨论(0)
提交回复
热议问题