21071979
21071979

Reputation: 1

Java code wrote for AD account creation but LDAP exception occurred

Java code wrote for AD account creation but LDAP exception occurred such as LDAP security context error and some times LdapErr: DSID-0C0910B5, comment: Error in attribute conversion operation exemption occurred.

then it connects to my domain: success Status : false javax.naming.directory.NoSuchAttributeException: [LDAP: error code 16 - 00000057: LdapErr: DSID-0C0910B5, comment: Error in attribute conversion operation, data 0, v4563

Could you please help me to correct the issue. Following listed the class I wrote

package com.mycom.mysys.ActiveDirectory;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

public class NewUser_Test {

    private static final String DOMAIN_ROOT = "OU=Mycomname Bank,DC=TESTAD,DC=LOCAL";

    private String userName, firstName, lastName, password, organisationUnit;
    private LdapContext context;
    private Hashtable hashtable;

    public static void main(String[] args) {
        try {

            NewUser_Test tst = new NewUser_Test("ACMYCOM1494", "Athuru", "Liyanage", "peLa071it", "OU=Information Technology,OU=HO,OU=Users");
            boolean b = tst.addUser();
            System.out.println("Status : " + b);

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

    public NewUser_Test(String userName, String firstName, String lastName, String password, String organisationUnit) {

        this.userName = userName;
        this.firstName = firstName;
        this.lastName = lastName;
        this.password = password;
        this.organisationUnit = organisationUnit;

        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.SECURITY_AUTHENTICATION, "Simple");
        env.put(Context.SECURITY_PRINCIPAL, "mysys" + "@TESTAD.LOCAL");
        env.put(Context.SECURITY_CREDENTIALS, "FCMycom1982@it");
        env.put(Context.PROVIDER_URL, "ldap://10.0.8.1:389");

        try {
            this.context = new InitialLdapContext(env, null);
            System.out.println("connect to my domain: success");
        } catch (NamingException e) {
            System.err.println("Problem creating object: ");
            e.printStackTrace();
        }

    }

    public boolean addUser() throws NamingException {

        // Create a container set of attributes
        Attributes container = new BasicAttributes();

        // Create the objectclass to add
        Attribute objClasses = new BasicAttribute("user");
        objClasses.add("top");
        objClasses.add("person");
        objClasses.add("organizationalPerson");
        objClasses.add("user");

        // Assign the username, first name, and last name
        String cnValue = new StringBuffer(firstName).append(" ").append(lastName).toString();
        Attribute cn = new BasicAttribute("cn", cnValue);
        Attribute sAMAccountName = new BasicAttribute("sAMAccountName", userName);
        Attribute principalName = new BasicAttribute("userPrincipalName", userName + "@TESTAD.LOCAL");
        Attribute givenName = new BasicAttribute("givenName", firstName);
        Attribute sn = new BasicAttribute("sn", lastName);
        Attribute uid = new BasicAttribute("uid", userName);
        Attribute displayName = new BasicAttribute("displayName", "Athuru Liyanage");

        //User Account Options lmaccess.h
        int UF_ACCOUNTDISABLE = 0x0002;
        int UF_PASSWD_NOTREQD = 0x0020;
        int UF_PASSWD_CANT_CHANGE = 0x0040;
        int UF_NORMAL_ACCOUNT = 0x0200;
        int UF_DONT_EXPIRE_PASSWD = 0x10000;
        int UF_PASSWORD_EXPIRED = 0x800000;
        int UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000;

        Attribute accountOption = new BasicAttribute("userAccountControl", Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD + UF_PASSWORD_EXPIRED + UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION));
        // Add password
        Attribute userPassword = new BasicAttribute("userpassword", password);
        Attribute email = new BasicAttribute("mail", "[email protected]");
        Attribute designation = new BasicAttribute("title", "Junior Executive - Marketing / Credit");

        // Add these to the container
        container.put(objClasses);
        container.put(sAMAccountName);
        container.put(principalName);
        container.put(cn);
        container.put(sn);
        container.put(givenName);
        container.put(uid);
        container.put(accountOption);
        container.put(userPassword);
        container.put(displayName);
        container.put(email);
        container.put(designation);

        // Create the entry
        try {
            context.createSubcontext(getUserDN(cnValue, organisationUnit), container);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private static String getUserDN(String aUsername, String aOU) {
        return "cn=" + aUsername + ",ou=" + aOU + "," + DOMAIN_ROOT;
    }
}

Upvotes: 0

Views: 1852

Answers (1)

Gabriel Luci
Gabriel Luci

Reputation: 40958

There are two red flags I see. First:

Attribute accountOption = new BasicAttribute("userAccountControl", Integer.toString(UF_NORMAL_ACCOUNT + UF_PASSWD_NOTREQD + UF_PASSWORD_EXPIRED + UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION));

The userAccountControl attribute is a number, but you are assigning a string to it. You don't need to use Integer.toString here. You are also assigning UF_PASSWD_NOTREQD to tell it that the account does not require a password, but then you're assigning a password?

That brings us to the password:

Attribute userPassword = new BasicAttribute("userpassword", password);

Setting the password is a strange thing in AD. Technically setting the userPassword attribute can work, if your domain is setup to allow it. If so, that code should work. If not, then you'll have to use the actual password attribute, unicodePwd, which is a little more difficult to set because it requires a very specific format: it must enclosed in quotes and encoded in UTF-16. There is an example here of how to do that. For example:

String quotedPassword = "\"" + password + "\"";
char unicodePwd[] = quotedPassword.toCharArray();
byte pwdArray[] = new byte[unicodePwd.length * 2];
for (int i = 0; i < unicodePwd.length; i++)
{
    pwdArray[i * 2 + 1] = (byte) (unicodePwd[i] >>> 8);
    pwdArray[i * 2 + 0] = (byte) (unicodePwd[i] & 0xff);
}

Then you can set unicodePwd to pwdArray:

Attribute userPassword = new BasicAttribute("unicodePwd", pwdArray);

Upvotes: 0

Related Questions