Search code examples
javasslactive-directoryldapapache-directory

Apache directory API refuses to add user to Active Directory "(UNWILLING_TO_PERFORM)"


Im trying to add a user using Java 6 and Apache Directory API to Active Directory running on windows server 2008, but the result i get is (UNWILLING_TO_PERFORM), now i understand that it needs a secure connection and to use unicodePwd attribute to add the password, which i did, or at least tried to do. The server admin created a certificate for the account i use when adding users, i exported it and added it to cacert in /jre/lib/security/.

I tried to see if i can just connect securely to the AD server without performing any operations, i get 2 scenarios that fail on the binding operation .bind():

1- if i connect using port 636 and use startTLS() available in ldapNetworkConnection : then i either get PROTOCOL_ERROR server will disconnect

2- if i connect using port 389 and use startTLS() available in LdapConnectionConfig i get "Failed to initialize the SSL context" and "IllegalArgumentException :TLSv1.1"

I added the trust manager but still no luck, below is the code so far.

  LdapConnectionConfig config = new LdapConnectionConfig();
            config.setLdapHost(IP);
            config.setLdapPort(389);


            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

            tmf.init((KeyStore)null);
            config.setTrustManagers(tmf.getTrustManagers());
            config.setName("CN=TestAdmin,CN=Users,DC=bmrk,DC=com");
            config.setCredentials("P@ssw0rd");

 LdapNetworkConnection ldapNetworkConnection = new LdapNetworkConnection(config);
ldapNetworkConnection.connect();
            ldapNetworkConnection.startTls();
            ldapNetworkConnection.bind();

// EDIT i switched to JNDI LDAP APIs it gave me a more reasonable error, apparently the issue comes from the SSL handshake, my app isn't able to find the valid certificate, any recommendations?

Any help is really appreciated.

Thanks,


Solution

  • In Case anyone is interested, my only issue was in the adding the server that generated the certificate as a CA authority in the cacerts file so that the JVM can trust certificates issued by the server although it worked smoothly and perfect with JNDI ldap APIs it doesn't work with Apache Directory not sure why.

    so my recommendation is to use JNDI instead of Apache Directory and make sure you export the certificate for the account used to login to Active Directory as PKCS12 and add it to the keystore.

    so it's 2 certificates, 1 for the login/bind account and 1 for the server to act as a CA (Certificate Authority).

    Also Java 6 support TLSv1 as a maximum security protocol which isn't the standard case with Apache LDAP, so either upgrade you Java or use JNDI.

    it works perfectly with Java 7.