更改Active Directory的邮件属性

时间:2014-01-31 12:33:06

标签: java active-directory ldap runtime-error change-password

我正在尝试使用java更改Active Directory的邮件和密码属性。为此,它生成了一个安全证书并导入到jvm(carcerts)的证书存储区中。连接是使用ssl成功进行的,但是当尝试更改任何字段,例如邮件时,我收到以下错误消息:

javax.naming.OperationNotSupportedException:[LDAP:错误代码53 - 00002035:LdapErr:DSID-0C090B3E,注释:不允许通过GC端口操作,数据0,v1db1

源代码:

// change mail
private void salvarEmailESenhaNoAd() throws IOException, NamingException {
    Properties mudaSenhaProperties = new PropertiesFactory().propertiesByJndi("mudaSenha");

    ADUtil adUtil = null;

    try
    {
        adUtil = new ADUtil(mudaSenhaProperties);

        adUtil.changeEmail("CN=018061671627,OU=SDS,OU=CS,OU=STI,OU=DG,OU=PRES,OU=TRERN,DC=tre-rn,DC=jus,DC=br", dadosUsuario.getEmail());

    }
    finally
    {
        if (adUtil != null)
        {
            adUtil.close();
        }
    }
}



public class ADUtil {

private LdapContext ldapContext = null;

public ADUtil(Properties properties) throws NamingException
{
    ldapContext = createUserContext(properties);
}


private LdapContext createUserContext(Properties properties) throws NamingException {


    String javaNamingFactoryInitial = properties.getProperty("java.naming.factory.initial");
    String javaNamingProviderUrl = properties.getProperty("java.naming.provider.url");
    String javaNamingSecurityAuthentication = properties.getProperty("java.naming.security.authentication");
    String javaNamingSecurityPrincipal = properties.getProperty("java.naming.security.principal");
    String javaNamingSecurityCredentials = properties.getProperty("java.naming.security.credentials");
    String javaNamingSecurityProtocol = properties.getProperty("java.naming.security.protocol");
    String javaNamingReferral = properties.getProperty("java.naming.referral");
    String javaNetSslTrustStore = properties.getProperty("javax.net.ssl.trustStore");
    String javaNetSslTrustStorePassword = properties.getProperty("javax.net.ssl.trustStorePassword");

    Hashtable<String, String> env = new Hashtable<String, String>();

    System.setProperty("javax.net.ssl.trustStore", javaNetSslTrustStore);
    System.setProperty("javax.net.ssl.trustStorePassword", javaNetSslTrustStorePassword);

    env.put(Context.INITIAL_CONTEXT_FACTORY, javaNamingFactoryInitial);
    env.put(Context.SECURITY_AUTHENTICATION, javaNamingSecurityAuthentication);
    env.put(Context.SECURITY_PRINCIPAL, javaNamingSecurityPrincipal);
    env.put(Context.SECURITY_CREDENTIALS, javaNamingSecurityCredentials);
    env.put(Context.SECURITY_PROTOCOL, javaNamingSecurityProtocol); // para poder modificar password y grupos del usuario.
    env.put(Context.PROVIDER_URL, javaNamingProviderUrl);
    env.put(Context.REFERRAL, javaNamingReferral);

    return new InitialLdapContext(env, null);
}


public void changePassword(String userCN, String newPassword) throws NamingException, UnsupportedEncodingException, IOException {

    modifyAdAttribute(userCN, "unicodePwd", converteString(newPassword));
    System.out.println("Password changed for " + userCN);
}

public void changeEmail(String userDN, String newEmail) throws NamingException, UnsupportedEncodingException, IOException {

    modifyAdAttribute(userDN, "mail", converteString(newEmail));
    System.out.println("Email changed for " + newEmail);

} 


private void modifyAdAttribute(String userCN, String attribute, Object value) throws NamingException{
    ModificationItem[] modificationItem = new ModificationItem[1];
    modificationItem[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
            new BasicAttribute(attribute, value));
    ldapContext.modifyAttributes(userCN, modificationItem);

}


private static byte[] converteString(String password) throws UnsupportedEncodingException{
    String newQuotedPassword = "\"" + password + "\"";
    return newQuotedPassword.getBytes("UTF-16LE");
}

public void close() throws NamingException
{
    if (ldapContext != null)
    {
        ldapContext.close();
    }
}

通常使用以下代码读取属性:

public class TesteLdap {

/**
 * @param args the command line arguments
 */
private static SearchControls getSimpleSearchControls() {
    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    searchControls.setTimeLimit(30000);
    //String[] attrIDs = {"objectGUID"};
    //searchControls.setReturningAttributes(attrIDs);
    return searchControls;
}

public static void main(String[] args) throws NamingException {


    try {

        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://rndc10.tre-rn.jus.br:3269");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "user");
        env.put(Context.SECURITY_CREDENTIALS, "password");

        env.put(Context.SECURITY_PROTOCOL, "ssl");
        env.put(Context.REFERRAL, "ignore");

        String filter = "(&(objectClass=user)(CN=018061671627))";

        LdapContext ctx = new InitialLdapContext(env, null);
        ctx.setRequestControls(null);
        NamingEnumeration<?> namingEnum = ctx.search("OU=DG,OU=PRES,OU=TRERN,DC=tre-rn,DC=jus,DC=br", filter, getSimpleSearchControls());

        while (namingEnum.hasMore()) {
            SearchResult result = (SearchResult) namingEnum.next();
            Attributes attrs = result.getAttributes();
            System.out.println(attrs.get("cn"));
            System.out.println(attrs.get("displayname"));
            System.out.println(attrs.get("mail"));
            System.out.println(attrs.get("distinguishedName"));

        }
        namingEnum.close();
    } catch (Exception e) {
        e.printStackTrace();

我的环境:Windows 2008R2 Standart上的Active Directory,在unbutu 12.10上运行的打开JDK 7.

如果有人帮助我,我会很感激,因为我已经尝试了所有的东西,但是我无法让它发挥作用。

2 个答案:

答案 0 :(得分:1)

错误似乎是不言自明的。您应该使用端口636通过LDAPS执行此操作。 你有没有尝试过使用

env.put(Context.PROVIDER_URL, "ldaps://rndc10.tre-rn.jus.br:636");

(注意,如果单独指定ssl,则ldaps://不是必需的)。

答案 1 :(得分:0)

您的环境中是否有RODC(只读DC)?如果是这样,rndc10.tre-rn.jus.br是RODC吗?

也许你应该指向一个可写的DC?

您是否尝试过更新此字符串:

 env.put(Context.PROVIDER_URL, "ldap://rndc10.tre-rn.jus.br:3269");

为:

 env.put(Context.PROVIDER_URL, "ldaps://rndc10.tre-rn.jus.br:3269");
                                    ^