B
bakarirum
I have a delimma. I am trying to use Java and JNDI to allow a user to
update his (/her) password. I have searched all the groups and have
found all the standard examples. I have all the examples working with
the exception of one problem. If I try to call the java code below to
bind to a particular DN with the user's password and the password has
already expired, then an Exception is thrown that informs you that the
user's password has expired. I can catch this exception and handle as
needed. However, every time I try to validate under the credentials
with an account with the expired password, the exception is always
thrown and I cannot use that user's credentials to change his password.
I know you can use an administrator's account and binding and change
the password. However, this would require that a username/password be
store somewhere that a programmer could see. This is a security risk
that has to be avoided. How can you get around this problem? I have
posted the code below for completeness sake, however you have see the
code many times in the past.
Thank you,
Marc
Hashtable env = new Hashtable();
String principal = "CN=lookupname,CN=Users,DC=mydomain,DC=net";
String oldPassword = "lookuppass";
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//set security credentials, note using simple cleartext
authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,principal);
env.put(Context.SECURITY_CREDENTIALS,oldPassword);
//specify use of ssl
env.put(Context.SECURITY_PROTOCOL,"ssl");
String ldapURL =
"ldaps://mymachine.mydomain.net:636/DC=mydomain,DC=net?sAMAccountName?sub?(objectClass=user)";
env.put(Context.PROVIDER_URL,ldapURL);
env.put(Context.REFERRAL,"follow");
//When calling the constructor for the InitialLdapContext, the
exception is thrown.
//I can catch the exception, but I cannot do anything with the ctx
reference.
//Exception stack trace listed below.
LdapContext ctx = new InitialLdapContext(env,null);
ModificationItem[] mods = new ModificationItem[2];
byte[] oldpass = ("\"" + oldPassword + "\"").getBytes("UTF-16LE");
byte[] newpass = ("\"" + "123pass" + "\"").getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.DELETE_ATTRIBUTE,
new BasicAttribute("unicodePwd",oldpass));
mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE,
new BasicAttribute("unicodePwd",newpass));
ctx.modifyAttributes (dn,mods);
ctx.close();
javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308:
LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 773,
v893
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:2988)
at
com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2934)
at
com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2735)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2649)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:290)
at
com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
at
com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
at
com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
at
com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
at
javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at
javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:243)
at javax.naming.InitialContext.init(InitialContext.java:219)
at javax.naming.InitialContext.<init>(InitialContext.java:195)
at
javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:80)
update his (/her) password. I have searched all the groups and have
found all the standard examples. I have all the examples working with
the exception of one problem. If I try to call the java code below to
bind to a particular DN with the user's password and the password has
already expired, then an Exception is thrown that informs you that the
user's password has expired. I can catch this exception and handle as
needed. However, every time I try to validate under the credentials
with an account with the expired password, the exception is always
thrown and I cannot use that user's credentials to change his password.
I know you can use an administrator's account and binding and change
the password. However, this would require that a username/password be
store somewhere that a programmer could see. This is a security risk
that has to be avoided. How can you get around this problem? I have
posted the code below for completeness sake, however you have see the
code many times in the past.
Thank you,
Marc
Hashtable env = new Hashtable();
String principal = "CN=lookupname,CN=Users,DC=mydomain,DC=net";
String oldPassword = "lookuppass";
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
//set security credentials, note using simple cleartext
authentication
env.put(Context.SECURITY_AUTHENTICATION,"simple");
env.put(Context.SECURITY_PRINCIPAL,principal);
env.put(Context.SECURITY_CREDENTIALS,oldPassword);
//specify use of ssl
env.put(Context.SECURITY_PROTOCOL,"ssl");
String ldapURL =
"ldaps://mymachine.mydomain.net:636/DC=mydomain,DC=net?sAMAccountName?sub?(objectClass=user)";
env.put(Context.PROVIDER_URL,ldapURL);
env.put(Context.REFERRAL,"follow");
//When calling the constructor for the InitialLdapContext, the
exception is thrown.
//I can catch the exception, but I cannot do anything with the ctx
reference.
//Exception stack trace listed below.
LdapContext ctx = new InitialLdapContext(env,null);
ModificationItem[] mods = new ModificationItem[2];
byte[] oldpass = ("\"" + oldPassword + "\"").getBytes("UTF-16LE");
byte[] newpass = ("\"" + "123pass" + "\"").getBytes("UTF-16LE");
mods[0] = new ModificationItem(DirContext.DELETE_ATTRIBUTE,
new BasicAttribute("unicodePwd",oldpass));
mods[1] = new ModificationItem(DirContext.ADD_ATTRIBUTE,
new BasicAttribute("unicodePwd",newpass));
ctx.modifyAttributes (dn,mods);
ctx.close();
javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308:
LdapErr: DSID-0C09030B, comment: AcceptSecurityContext error, data 773,
v893
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:2988)
at
com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2934)
at
com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2735)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2649)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:290)
at
com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
at
com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
at
com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
at
com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
at
javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at
javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:243)
at javax.naming.InitialContext.init(InitialContext.java:219)
at javax.naming.InitialContext.<init>(InitialContext.java:195)
at
javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:80)