go-ldap / ldap

Basic LDAP v3 functionality for the GO programming language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Set password on AD

1995parham opened this issue · comments

Dear all, I am using the following code to set a user password on Active directory:

utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)

pwdEncoded, err := utf16.NewEncoder().String(fmt.Sprintf("\"%s\"", password))
if err != nil {
  return fmt.Errorf("cannot encode password using utf16: %w", err)
}

m.Logger.Info("password encoded to utf16",
zap.String("username", username),
zap.String("encoded-password", pwdEncoded),
)

passReq := ldap.NewModifyRequest(userDN, nil)

passReq.Replace("unicodePwd", []string{pwdEncoded})

if err := conn.Modify(passReq); err != nil {
  if ldap.IsErrorWithCode(err, 32) {
	  return ErrUserNotFound
  }

  // catch some common ldap error messages and make them human readable
  if ldap.IsErrorWithCode(err, ldap.LDAPResultUnwillingToPerform) {
	  errCodes := ldapErrorMatchRegex.FindStringSubmatch(err.Error())
	  if errCodes != nil {
		  switch errCodes[1] {
		  case "0000052D":
			  return ErrPasswordPolicyFailed
		  default:
		  }
	  }
 }

  return fmt.Errorf("ldap modify request failed: %w", err)
}

The code finished without error, but I cannot log in with the set password. Am I doing it wrong?

The password is not accessible or modifiable through LDAP in Active Directory. See the following example

ldap/examples_test.go

Lines 86 to 104 in cdb0754

func ExampleConn_PasswordModify_admin() {
l, err := DialURL("ldap://ldap.example.com:389")
if err != nil {
log.Fatal(err)
}
defer l.Close()
err = l.Bind("cn=admin,dc=example,dc=com", "password")
if err != nil {
log.Fatal(err)
}
passwordModifyRequest := NewPasswordModifyRequest("cn=user,dc=example,dc=com", "", "NewPassword")
_, err = l.PasswordModify(passwordModifyRequest)
if err != nil {
log.Fatalf("Password could not be changed: %s", err.Error())
}
}

@cpuschma Yes, and because of that I use the attribute replacing procedure as mentioned before in issues (#106). You think this solution is not going to work too? How I can do this set-password procedure?

I don't understand the comment by @cpuschma. they say its not possible, then they provide code that shows IT IS possible. show which is it?

any news?

You cannot read or list the user password attribute in Active Directory. You can set a users password with the passwordModify, which is governed by Conn.PasswordModify

passwordModifyRequest := NewPasswordModifyRequest("cn=user,dc=example,dc=com", "", "NewPassword") 
_, err = l.PasswordModify(passwordModifyRequest) 

Or through the unicodePwd, see https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/6e803168-f140-4d23-b2d3-c3a8ab5917d2, which requires you to encode the password in UTF-16 beforehand.