I have Active Directory, with Users in it, i am trying to change a users password from a Java Program as follows:
Properties prop = new Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
prop.put(Context.SECURITY_AUTHENTICATION, "simple");
prop.put(Context.SECURITY_PRINCIPAL,"user1");
prop.put(Context.SECURITY_CREDENTIALS,"pass1");
prop.put(Context.SECURITY_PROTOCOL,"ADSecurityProtocol");
prop.put(Context.PROVIDER_URL, "ldap://host:389/OU=My Org,DC=domain,DC=com");
try
{
LdapContext ctx =new InitialLdapContext(prop,null);
String oldPassword="pass1";
String newPassword="passnew1";
ModificationItem[] mods = new ModificationItem[2];
String oldQuotedPassword = "\"" + oldPassword + "\"";
byte[] oldUnicodePassword = oldQuotedPassword.getBytes("UTF-16LE");
String newQuotedPassword = "\"" + newPassword + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REMOVE_ATTRIBUTE,
new BasicAttribute("unicodePwd", oldUnicodePassword));
mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE,
new BasicAttribute("unicodePwd", newUnicodePassword));
String theUserName="CN="+"user1"+",OU=My Org,DC=domain,DC=com";
// Perform the update
ctx.modifyAttributes(theUserName, mods);
System.out.println("Changed Password for successfully");
ctx.close();
}
catch (Exception e) {
System.err.println("Problem changing password: " + e);
}
The error message i get is:
Problem changing password: javax.naming.NamingException:
[LDAP: error code 1 - 000020D6: SvcErr: DSID-031007DB,
problem 5012 (DIR_ERROR), data 0]; remaining name
'CN=user1,OU=My Org,DC=domain,DC=com'
Edit 1:
Based on Suggestions i have tried this with port 636 and ldaps as well:
prop.put(Context.PROVIDER_URL, "ldap://host:636/OU=My Org,DC=domain,DC=com");
Also tried
prop.put(Context.PROVIDER_URL, "ldaps://host:636/OU=My Org,DC=domain,DC=com");
I am getting MalformedURLException: Invalid URI:
Invalid URI: Org,DC=domain,DC=com]
When i try (not sure if anything is listening on 636, it appears it is tho):
$ telnet LDAPHost 636
Escape character is '^]'.
Connection closed by foreign host.
Edit2:
Changed:
prop.put(Context.PROVIDER_URL, "ldap://host:636/OU=My Org,DC=domain,DC=com");
to:
prop.put(Context.PROVIDER_URL, "ldap://host:636/OU=My%20Org,DC=domain,DC=com");
The error is:
javax.naming.CommunicationException: simple bind failed: host:636
[Root exception is java.net.SocketException: Connection reset]
Probably the LDAP Server is not even listening on ssl port: 636
You only have a plain unsecure
ldap://
connection instead ofldaps://
, so that won't work according to the above restrictions.See more details at: http://support.microsoft.com/kb/269190
Basically, you need to modify the
unicodePwd
attribute of the user.I use AWS Simple AD implementation and, as it is based on Samba 4, this attribute doesn't work. You need to use
clearTextPassword
in this case. See my blog post about it: http://blog.techutils.space/2016/02/changing-samba4-aws-simple-ad-user.htmlNote: AWS Simple AD doesn't support SSL yet, so find a way to mitigate this risk.
If you are on Windows, then you can call
NetUserChangePassword()
function that is available insidenetapi32.dll
.Using
JNA
, the code will be like this:Note: Unlike the ldap approach, this approach will work even if the old password is already expired.
The JVM executing the password change call needs to be trusted by the directory service provider. This means importing a certificate generated from AD into the JVM trust store.
You have to change the attribute. Try to change
unicodePwd
withuserpassword
from :
to :