Problem trying to reset password on Active Directory using Kerberos
Hi everybody,
I am writing an utility program for resetting a user's password on Active Directory.
I have read the excellent posts by Steven Adler and tried both with SSL and Kerberos.
With SSL everything works fine, but with Kerberos I get the following error:
javax.naming.OperationNotSupportedException: [LDAP: error code 53 - 00002077: SvcErr: DSID-031D0AAB, problem 5003 (WILL_NOT_PERFORM), data 0
]; remaining name'CN=Alberto Test,CN=Users,DC=adtest,DC=lynxpd'
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.c_modifyAttributes(Unknown Source)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_modifyAttributes(Unknown Source)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(Unknown Source)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.modifyAttributes(Unknown Source)
at javax.naming.directory.InitialDirContext.modifyAttributes(Unknown Source)
at com.lynxspa.utils.auth.IdentityUtils.run(IdentityUtils.java:117)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Unknown Source)
at com.lynxspa.test.TestIdentityUtils.performWithKerberosAuth(TestIdentityUtils.java:41)
at com.lynxspa.test.TestIdentityUtils.main(TestIdentityUtils.java:27)
I am using j2k 1.5.0_08 on Windows XP SP2.
I have performed the registry hack and tried both with Windows2K and Windows2003 domain servers, with both user scenarios (administrator changing another user's password or user changing his/her password).
Am I missing something?
Thanks for your help
[1855 byte] By [
zigoala] at [2007-10-3 3:53:12]

I'm assuming you are attempting to set the password from with the privilegedAction, possibly something similar to this:class PwdSet implements java.security.PrivilegedAction {
public PwdSet() {
}
public Object run() {
performPwdSet();
return null;
}
private static void performPwdSet() {
String userName = "cn=Albert Einstein,ou=Research,dc=Antipodes,dc=com";
String newPassword = "Password123";
// Set up environment for creating initial context
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
// Connect to my domain controller
String ldapURL = "ldap://mydc.antipodes.com:389";
env.put(Context.PROVIDER_URL,ldapURL);
// Specify GSSAPI as the SASL provider
env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
//Specify the quality of protection
//Eg. auth-conf; confidentiality, auth-int; integrity
env.put("javax.security.sasl.qop","auth-conf");
//Could also specify mutual authentication
env.put("javax.security.sasl.server.authentication","true");
try {
// Create the initial directory context
LdapContext ctx = new InitialLdapContext(env,null);
//set password is a ldap modfy operation
ModificationItem[] mods = new ModificationItem[1];
//Replace the "unicdodePwd" attribute with a new value
//Password must be both Unicode and a quoted string
String newQuotedPassword = "\"" + newPassword + "\"";
byte[] newUnicodePassword = newQuotedPassword.getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("unicodePwd", newUnicodePassword));
// Perform the update
ctx.modifyAttributes(userName, mods);
System.out.println("Reset Password for: " + userName);
ctx.close();
}
catch (UnsupportedEncodingException e) {
System.out.println("Problem encoding password: " + e);
}
catch (NamingException e) {
System.out.println("Problem resetting password: " + e);
}
}
}
Well I guess the good news/bad news, is that I get the same error. I think the problem is that AD will only accept password modifications using LDAP over a secure channel that supports 128bit encryption.
From playing around with Kerberos in Java to date, it seems that the only Kerberos encryption method common to both JDK 1.5 & AD is DES, which IIRC is only 56 bit.
I did notice that the beta JDK 1.6 will support AES as a Kerberos encryption mechanism, so perhaps that should work as it supports a stronger key length. Something to try at a later date :-)
> I'm assuming you are attempting to set the password
> from with the privilegedAction, possibly something
> similar to this...
Of course I am using JAAS with Kerberos.
> I did notice that the beta JDK 1.6 will support AES
> as a Kerberos encryption mechanism, so perhaps that
> should work as it supports a stronger key length.
> Something to try at a later date :-)
I'll take a look at the Beta release.
Thanks for your help
I should make the following correction.
Windows 2000 & Windows Server 2003 both support RC4-HMAC (which is natively used by Windows) as well as DES-CBC. Longhorn Server will also add AES.
The JDK 1.6 beta now supports RC4-HMAC & AES in addition to DES-CBC and 3DES.
Conceivably you may be able to use RC4-HMAC with Windows today, and AES with Longhorn when it is available.
But as I mentioned, I haven't been able to get RC4-HMAC to work. I can't work out exactly what encryption key length is being negotiated between AD & the Java app.
I'm now getting the feeling that settting the password over LDAP may only work with TLS/SSL where I know we are using 128bit keys.
Note that you can use also use the Kerberos Change Password protocol (kpasswd). This definitely works.
The benefit of kpasswd is that it solves the ldap chicken & egg situation. If the user's password has expired they can't successfully bind with ldap, so they can't change their password over ldap. However if their password has expired, they can change their password using kpasswd.
> But as I mentioned, I haven't been able to get
> RC4-HMAC to work. I can't work out exactly what
> encryption key length is being negotiated between AD
> & the Java app.
>
This is exactly the same problem I have.
I have set in my krb5.conf file with the following:
[libdefaults]
default_tkt_enctypes = aes128-cts des3-cbc-sha1 rc4-hmac des-cbc-md5 des-cbc-crc
default_tgs_enctypes = aes128-cts des3-cbc-sha1 rc4-hmac des-cbc-md5 des-cbc-crc
permitted_enctypes = aes128-cts des3-cbc-sha1 rc4-hmac des-cbc-md5 des-cbc-crc
Using Ethereal I have analyzed the traffic and seen that RC4-HMAC algorithm is being used, but I cannot figure out the key length, though I think it is 40 bytes long.
>
> Note that you can use also use the Kerberos Change
> Password protocol (kpasswd). This definitely works.
>
Do you mean I should make a Runtime.exec() call from within my Java classes?
Besides, AFAIK kpasswd is available only in Linux (but I'm not a Windows expert).
Thanks again