How to extend schema using JNDI in Active Directory

Hi,

I am a newbie to JNDI and schema extension. I have an Active Directory setup on win2k3. I was trying the following example to add an attribute to the schema, but i am getting the following error.

javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031001C6, problem 2001 (NO_OBJECT), data 0, best match of:

'CN=Schema,CN=Configuration,DC=ric,DC=com';

remaining name 'CN=fooattr,CN=Schema,CN=Configuration,DC=ric,DC=com'

at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source)

at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source)

at com.sun.jndi.ldap.LdapCtx.processReturnCode(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 AddAttr.main(AddAttr.java:52)

Here is the code is was trying

import java.util.Hashtable;

import javax.naming.ldap.LdapContext;

import javax.naming.ldap.InitialLdapContext;

import javax.naming.*;

import javax.naming.directory.*;

publicclass AddAttr{

publicstaticvoid main(String[] args){

// Open an LDAP association

try

{

Hashtable env =new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");

env.put(Context.PROVIDER_URL,"ldap://schema-test:389");

env.put(Context.SECURITY_PRINCIPAL,"cn=administrator,cn=users,dc=ric,dc=com");

env.put(Context.SECURITY_CREDENTIALS,"notallowed");

LdapContext ctx =new InitialLdapContext(env,null);

String snc ="schemaNamingContext";// DSE attribute

Attributes attrs = ctx.getAttributes("",new String[]{ snc});

DirContext schema = (DirContext)ctx.lookup((String) attrs.get(snc).get());

String dn = schema.getNameInNamespace();

Attributes attr =new BasicAttributes(true);

attr.put("cn","fooattr");

attr.put("objectClass","attributeSchema");

attr.put("ldapDisplayName","fooattr");

attr.put("isSingleValued","TRUE");

attr.put("attributeID","1.3.6.1.4.1.791.2.3.5.5.1.4.4");

attr.put("attributeSyntax","2.5.5.9");

schema.createSubcontext("CN=fooattr," + dn,attr);

// Close the LDAP association

ctx.close();

}

catch(Exception exc)

{

exc.printStackTrace();

}

}

}

Can anyone suggest what am i doing wrong here. Also, please suggest me any documentation for schema extension using jndi.

Thanks & Regards,

kelloogo

[4230 byte] By [kelloogoa] at [2007-11-26 14:06:32]
# 1

Hi,

Also wanted to know if there is ome initial setting we have to do in AD. The same program I am able to run on the Sun One and Novell directory setup.

I found some mention in this link

http://java.sun.com/products/jndi/tutorial/basics/prepare/content.html

But does that mean that we cannot add a new objectclass or attribute in AD using JNDI. In this link itself there is a sample program to create Java Schema. They use the similar code i have used. But I am not able to do so for a simple new objectclass.

Or do I have to import the java schema from the following location.

http://java.sun.com/products/jndi/tutorial/config/LDAP/java.schema

kelloogoa at 2007-7-8 1:51:56 > top of Java-index,Core,Core APIs...
# 2
I am facing the same problem.Please help me if any one has the solution.
Panks.Ta at 2007-7-8 1:51:56 > top of Java-index,Core,Core APIs...
# 3

The first example was almost correct !

The error message: "javax.naming.NameNotFoundException: [LDAP: error code 32 - 0000208D: NameErr: DSID-031001C6, problem 2001 (NO_OBJECT), data 0, best match of: 'CN=Schema,CN=Configuration,DC=ric,DC=com'; " simply indicates a naming error.

If you follow the logic of your code, you are trying to create an attribute with the distinguished name:CN=fooattr,CN=Schema,CN=Configuration,DC=ric,DC=com,CN=Schema,CN=Configuration,DC=ric,DC=com

If you are wondering why, it is because you are attempting to create the subcontext from the schema naming context.schema.createSubcontext("CN=fooattr," + dn,attr);

You can correct this by changing your code toschema.createSubcontext("CN=fooattr",attr);

or toctx.createSubcontext("CN=fooattr," + dn,attr);

One other error, you are missing one of the mandatory attributes; namely oMSyntax.attrs.put("oMSyntax","2");

You can find details on the Active Directory Schema at http://technet2.microsoft.com/WindowsServer/en/library/97cae647-d996-48ff-b478-c96193abeadb1033.mspx

A simple way of checking the mandatory attributes for any object class is to look at the values of the systemMustContain attribute of the objectClass definition. In the case of attributeSchema, the systemMustContain attribute includes: schemaIDGUID (automagically generated), oMSyntax, ldapDisplayName, isSingleValued, cn, attributeSyntax and attributeID

Another reference that is helpful is a table of Attribute Syntax definitions at http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/distrib/dsbe_ext_dghb.mspx

The only words of advice for extending the schema are:

1. Test, Test, Test, before deploying in production

2. Do not ever reuse attributeID's or make up your own! If you are extending the schema get your own OID from an appropriate standards authority, or they may be obtained from Microsoft. Refer to http://msdn2.microsoft.com/en-us/library/ms677621.aspx or http://msdn2.microsoft.com/en-us/library/ms677620.aspx

adler_stevena at 2007-7-8 1:51:56 > top of Java-index,Core,Core APIs...
# 4

Wow! It worked. Thanks a lot.

I was just testing the schema extension on my local setup, so i was using my own ID, but I do have the appropriate OID with me.

Also, the AD uses diferent way of adding attributes.

I was looking at a common way of extending the schema for all LDAP directories using JNDI. But if we have to use different attributes for AD, then is there anyway using JNDI to find out what is the directory type or find out if the LDAP directory is an AD or some other directory.

Thanks again for your help.

Message was edited by:

kelloogo

kelloogoa at 2007-7-8 1:51:56 > top of Java-index,Core,Core APIs...
# 5

I think the easiest way to detect different LDAP directories is to look at either the supportedControls or supportedCapabilities attributes of the rootDSE.

The list of LDAP Controls supported by Active Directory is available at http://msdn2.microsoft.com/en-us/library/aa366108.aspx

I'm sure you will be able to find a LDAP Control that is only supported on Active Directory and not on other LDAP directories.

adler_stevena at 2007-7-8 1:51:56 > top of Java-index,Core,Core APIs...
# 6
I was able to get the LDAP control which is supported by Active Directory only, i.e., LDAP_SERVER_DIRSYNC_OID. I used it to identify an AD. Not sure if this is the right way, but it is working fine. Thank you once more for the help.
kelloogoa at 2007-7-8 1:51:56 > top of Java-index,Core,Core APIs...