Add user to LDAP using JAVA. Naming.InvalidNameException: Invalid Name

5.8k views Asked by At

I am practicing in Java, adding a user to LDAP(v3, running on my Virtual machine). Userdetails and attributes are obtained from postgres database running locally. This is my code (may not be a good approach):

public class LDAPConnector {
    static final String DOMAIN_URL = "ldaps://10.10.10.180:636/";
    static final String ADMIN_NAME = "cn=Administrator,ou=users,dc=example,dc=com";
    static final String ADMIN_PASSWORD = "password";
    static final String url = "jdbc:postgresql://localhost/users";
    static final String user = "username";
    static final String password = "password";
    static final ArrayList<String> attributeList = new ArrayList<String>();
    static final Properties props = new Properties();
    static DirContext ctx;

    public static void main(String[] args) {
        try {
            props.put(Context.INITIAL_CONTEXT_FACTORY,
                    "com.sun.jndi.ldap.LdapCtxFactory");
            props.put(Context.SECURITY_AUTHENTICATION, "simple");
            props.put(Context.SECURITY_PRINCIPAL, ADMIN_NAME);
            props.put(Context.SECURITY_CREDENTIALS, ADMIN_PASSWORD);
            props.put(Context.PROVIDER_URL, DOMAIN_URL);
            props.put(Context.SECURITY_PROTOCOL, "ssl");
            props.put("java.naming.ldap.version", "3");
            ctx = new InitialDirContext(props);
            HashMap<String, String> attributeValueList = new HashMap<String, String>();
            Connection con = DriverManager.getConnection(url, user, password);
            Statement st = con.createStatement();
            String query = "SELECT * FROM userdata";
            ResultSet rs = st.executeQuery(query);
            ResultSetMetaData rsmd = rs.getMetaData();
            for (int i = 1; i < rsmd.getColumnCount(); i++) {
                String attributeName = rsmd.getColumnName(i);
                attributeList.add(attributeName);
            }
            while (rs.next()) {
                for (int i = 0; i < attributeList.size(); i++) {
                    attributeValueList.put(attributeList.get(i), rs.getString(i+1));
                }
            }
            String DN = "dn: cn="+attributeValueList.get("cn").replaceAll(" ", "")+",ou=Users"+",dc=example,dc=com";
            Attribute dn = new BasicAttribute("dn",DN);
            String CN = "cn: "+attributeValueList.get("cn");
            Attribute cn = new BasicAttribute("cn",CN);
            String SN = "sn: "+attributeValueList.get("sn");
            Attribute sn = new BasicAttribute("sn",SN);
            String GivenName = "givenName: "+attributeValueList.get("givenname");
            Attribute givenName = new BasicAttribute("givenName",GivenName);
            String ObjectClass = "objectClass: inetOrgPerson";
            Attribute objectClass = new BasicAttribute("objectClass",ObjectClass);
            String DisplayName = "displayName: "+attributeValueList.get("displayName");
            Attribute displayName = new BasicAttribute("displayName",DisplayName);
            String password = "userPassword: "+attributeValueList.get("userpassword");
            Attribute userPassword = new BasicAttribute("userPassword",password);
            Attributes container = new BasicAttributes();
            container.put(dn);
            container.put(cn);
            container.put(sn);
            container.put(givenName);
            container.put(objectClass);
            container.put(displayName);
            container.put(userPassword);
            String context = DN+"\r\n"+CN+"\r\n"+SN+"\r\n"+GivenName+"\r\n"+ObjectClass+"\r\n"+DisplayName+"\r\n"+password;
            ctx.createSubcontext(context,container);
            ctx.close();
            rs.close();
            con.close();

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

}

Here is the Exception trace I am getting:

javax.naming.InvalidNameException: Invalid name: dn: cn=username,ou=Users,dc=example,dc=com cn: User Name sn: User givenName: Name objectClass: inetOrgPerson displayName: user Name userPassword: Password; remaining name 'dn: cn=UserName,ou=Users,dc=example,dc=com cn: User Name sn: User givenName: Name objectClass: inetOrgPerson displayName: User Name userPassword: 123456'  at
javax.naming.ldap.Rfc2253Parser.doParse(Unknown Source)     at
javax.naming.ldap.Rfc2253Parser.parseDn(Unknown Source)     at
javax.naming.ldap.LdapName.parse(Unknown Source)    at
javax.naming.ldap.LdapName.<init>(Unknown Source)   at
com.sun.jndi.ldap.LdapCtx.addRdnAttributes(Unknown Source)  at
com.sun.jndi.ldap.LdapCtx.c_createSubcontext(Unknown Source)    at
com.sun.jndi.toolkit.ctx.ComponentDirContext.p_createSubcontext(Unknown Source)     at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.createSubcontext(Unknown Source)    at
com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.createSubcontext(Unknown Source)    at
javax.naming.directory.InitialDirContext.createSubcontext(Unknown Source)   at
com.example.ldap.LDAPConnector.main(LDAPConnector.java:107)

Anythoughts on how to resolve the exception? I am following Java JNDI tutorials

2

There are 2 answers

0
eckes On BEST ANSWER

For the attributes and the DN you need to use only the values (i.e. nowehere use the "DN:" LDIF syntax):

String DN = "cn="+a.get("cn").replaceAll(" ","")+",ou=Users"+",dc=example,dc=com";
Attribute dn = new BasicAttribute("dn",DN);
Attribute cn = new BasicAttribute("cn",a.get("cn"));
Attribute objectClass = new BasicAttribute("objectClass", "inetOrgPerson");
...
Attributes atts = new BasicAttributes();
atts.put(dn);
atts.put(cn);
atts.put(objectClass);
ctx.createSubcontext(DN, atts);

And I would recommend you start with a hardcoded sample user without any DB access till you have debugged your JNDI usage problems and only then go up a step (This also helps for asking on SO :).

0
Anvesh Raavi On

here is my code: Additional to eckes answer, Quotes should be escaped in Java so that user can be created in LDAP.

String DN = "\"cn="+a.get("cn").replaceAll(" ","")+",ou=Users"+",dc=example,dc=com\"";
Attribute dn = new BasicAttribute("dn",DN);
Attribute cn = new BasicAttribute("cn",a.get("cn"));
Attribute objectClass = new BasicAttribute("objectClass", "inetOrgPerson");
...
Attributes atts = new BasicAttributes();
atts.put(dn);
atts.put(cn);
atts.put(objectClass);
ctx.createSubcontext(DN, atts);