4

I don't (and will not) have administators account. I want to change myself (user) password in Active Directory from java. How can I do this?

Using code from web:

private void changePass() throws Exception {
    String oldpass = this.encodePassword("oldpass!");
    String newpass = this.encodePassword("newpass!");
    Attribute oldattr = new BasicAttribute("unicodePwd", oldpass);
    Attribute newattr = new BasicAttribute("unicodePwd", newpass);
    ModificationItem olditem = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, oldattr);
    ModificationItem newitem = new ModificationItem(DirContext.ADD_ATTRIBUTE, newattr);
    ModificationItem repitem = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, newattr);
    ModificationItem[] mods = new ModificationItem[2];
    mods[0] = olditem;
    mods[1] = newitem;
    // ldapTemplate.modifyAttributes("cn=administrator,cn=Users", mods);
    ldapTemplate.modifyAttributes("cn=smith,cn=Users", new ModificationItem[] { repitem });
}

here is the contextSource

<bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
    <property name="url" value="ldap://ldapserver:389"/>
    <property name="base" value="dc=company,dc=com"/>
    <property name="userDn" value="smith@company"/>
    <property name="password" value="oldpass"/>
</bean>

I got:

LDAP: error code 32 - 0000208D: NameErr: DSID-0310020A, problem 2001 (NO_OBJECT), data 0, best match of:
'CN=Users,DC=company,DC=com'

if I change userDn to "cn=smith" I got:

LdapErr: DSID-0C0903A9, comment: AcceptSecurityContext error

Maybe my problem is that I do not understand how is LDAP working? Is it possible (change user password by using user-account) or not? And, if it is possible, can I check account locked / expires with same privileges?

UPDATE / RESOLVE

thank you very match for your help. That was very helpful too me.

for future searchers:

NO_OBJECT - means that ACtive Directory cannot find object (my cn=Users,cn=Smith) To find fully qualified canonical path to user catalogue you can use user attribute "distinguishedName" (in my, worstest case it is "cn=John\, Smith",ou=Contractors,ou=User Accounts,ou=Accounts")

then I got:

WILL_NOT_PERFORM - this can mean different type of things. In my case there was wrong object type, but, possible other cases, as described below - not SSL connection (not ldaps://), and others.

then:

INSUFF_ACCESS_RIGHTS - user (not administrator doesn't have right to REPLACE-password attribute), to change password he must enter old password and new password, and then REMOVE old and ADD new.

Attribute oldattr = new BasicAttribute("unicodePwd", oldQuotedPassword.getBytes("UTF-16LE"));
Attribute newattr = new BasicAttribute("unicodePwd", newQuotedPassword.getBytes("UTF-16LE"));
ModificationItem olditem = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, oldattr);
ModificationItem newitem = new ModificationItem(DirContext.ADD_ATTRIBUTE, newattr);
ldapTemplate.modifyAttributes("cn=John\\, Smith,ou=Contractors,ou=User Accounts,ou=Accounts", new ModificationItem[] { olditem, newitem });

problem 1005 (CONSTRAINT_ATT_TYPE) - if old password wrong

btw

javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name '/' - when searching person/user global (for example, in authenticate-method) ldapTemplate.setIgnorePartialResultException(true); can fix it

4

2 回答 2

4

是的,你可以,但它有点棘手。

首先要更改密码,您必须通过 LDAPS 而不是 LDAP 进行连接。那就是使用 TLS 或 SSL(至少 128 位)连接。这是一个如何使用JNDI完成此操作的示例。

其次,您必须将密码作为 UTF-16LE 编码的字节数组传递。但在编码之前,你应该用双引号将它括起来。所以这里有一个例子:

String pass = "\"" + "newpass" + "\"";
byte[] password = pass.getBytes("UTF-16LE");
// You will need to handle UnsupportedEncodingException here
于 2012-03-14T12:47:49.137 回答
1
  1. 如果cn=smith,cn=Users不是条目的真实 DN,则必须是。

  2. 您不需要所有删除/添加/替换的东西:只需使用 REPLACE_ATTRIBUTE; 如果您使用管理帐户更改密码。

    如果您以自己的身份更新密码,即绑定到您正在更新的同一帐户,则确实需要它。原因是您必须提供用于删除的旧密码和用于插入的新密码,以便可以检测到旧密码的匹配失败。或者,您可以使用扩展的密码修改操作,其中您再次提供旧密码和新密码。

于 2012-03-14T10:55:30.810 回答