/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Sun Microsystems nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 2006. Sun Microsystems. All rights reserved.
*
* Creates the schema for storing CORBA object references according
* to RFC 2714. After running this program, you should verify that
* the schema has been updated correctly by using the directory server's
* administration tool. If the schema has not been properly updated,
* use the administration tool to correct it.
*
* You should first turn off schema-checking at the directory server
* before running this program.
*
* usage:
* java [-Djava.naming.provider.url=<ldap_server_url>] \
* CreateCorbaSchema [-h|-l|-s[n|n41|ad]] [-n<dn>] [-p<passwd>] [-a<auth>]
*
* -h Print the usage message
*
* -l List the CORBA schema in the directory
*
* -s[n|n41|ad] Update schema:
* -sn means use a workaround for schema bugs in
* pre-4.1 releases of Netscape Directory Server;
*
* -sn41 means use a workaround for schema bugs in
* Netscape Directory Server version 4.1;
*
* -sad means use a workaround for schema bugs in
* Microsoft Windows 2000 Active Directory
*
* -n<dn> Use <dn> as the distinguished name for authentication
*
* -p<passwd> Use <passwd> as the password for authentication
*
* -a<auth> Use <auth> as the authentication mechanism. Default is "simple".
*
*
* If neither -s, -l, nor -h has been specified, the default is "-l".
*
* The following example inserts the CORBA schema from RFC 2714 in a
* Netscape Directory (using the workaround for 4.1 schema bugs),
* logging in as "cn=directory manager" with the password "secret".
*
* java CreateCorbaSchema -sn41 "-ncn=directory manager" -psecret
*
* @author Rosanna Lee
*/
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.InitialDirContext;
import javax.naming.directory.ModificationItem;
public class CreateCorbaSchema extends CreateJavaSchema {
private static String[] allAttrs = { "corbaIor", "corbaRepositoryId" };
private static String[] allOCs = { "corbaObject", "corbaObjectReference",
"corbaContainer" };
public static void main(String[] args) {
new CreateCorbaSchema().run(args, allAttrs, allOCs);
}
CreateCorbaSchema() {
}
/**
* Add new attributes: corbaIor corbaRepositoryId
*/
protected void updateAttributes(DirContext attrRoot, String[] attrIDs)
throws NamingException {
/* Get rid of old attr IDs */
for (int i = 0; i < attrIDs.length; i++) {
attrRoot.destroySubcontext(attrIDs[i]);
}
/* Add new and updated attr definitions */
// corbaIor
Attributes attrs = new BasicAttributes(true); // ignore case
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.14");
attrs.put("NAME", "corbaIor");
attrs.put("DESC",
"Stringified interoperable object reference of a CORBA object");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.26");
attrs.put("EQUALITY", "caseIgnoreIA5Match");
attrs.put("SINGLE-VALUE", "true");
attrRoot.createSubcontext("corbaIor", attrs);
System.out.println("Created corbaIor attribute");
// corbaRepositoryId
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.15");
attrs.put("NAME", "corbaRepositoryId");
attrs.put("DESC",
"Repository ids of interfaces implemented by a CORBA object");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.15");
attrs.put("EQUALITY", "caseExactMatch");
attrRoot.createSubcontext("corbaRepositoryId", attrs);
System.out.println("Created corbaRepositoryId attribute");
}
// Object Classes
protected void updateObjectClasses(DirContext ocRoot, String[] ocIDs)
throws NamingException {
/* Get rid of old OCs - reverse order */
for (int i = ocIDs.length - 1; i >= 0; i--) {
ocRoot.destroySubcontext(ocIDs[i]);
}
// corbaObject
Attributes attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.9");
attrs.put("NAME", "corbaObject");
attrs.put("DESC", "CORBA object representation");
attrs.put("SUP", "top");
attrs.put("ABSTRACT", "true");
Attribute optional = new BasicAttribute("MAY", "corbaRepositoryId");
optional.add("description");
attrs.put(optional);
ocRoot.createSubcontext("corbaObject", attrs);
System.out.println("Created corbaObject object class");
// corbaObjectReference
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.11");
attrs.put("NAME", "corbaObjectReference");
attrs.put("DESC", "CORBA interoperable object reference");
attrs.put("SUP", "corbaObject");
attrs.put("AUXILIARY", "true");
Attribute corMust = new BasicAttribute("MUST", "corbaIor");
if (netscape41bug) {
corMust.add("objectclass");
}
if (netscapebug) {
// Netscape ignores 'SUP' so we must add explicitly
attrs.put(optional);
}
attrs.put(corMust);
ocRoot.createSubcontext("corbaObjectReference", attrs);
System.out.println("Created corbaObjectReference object class");
// corbaContainer
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.10");
attrs.put("NAME", "corbaContainer");
attrs.put("DESC", "Container for a CORBA object");
attrs.put("SUP", "top");
attrs.put("STRUCTURAL", "true");
Attribute ccMust = new BasicAttribute("MUST", "cn");
if (netscape41bug) {
ccMust.add("objectclass");
}
attrs.put(ccMust);
ocRoot.createSubcontext("corbaContainer", attrs);
System.out.println("Created corbaContainer object class");
}
/**
* Inserts attribute definitions from RFC 2714 into the schema.
*
* This method maps the LDAP schema definitions in RFC 2714 onto the
* proprietary attributes required by the Active Directory schema.
*
* The resulting attribute definitions are identical to those of RFC 2714.
*/
protected void insertADAttributes(DirContext rootCtx, DirContext schemaCtx)
throws NamingException {
System.out.println(" [inserting new attribute definitions ...]");
String dn = schemaCtx.getNameInNamespace();
String attrID;
attrID = new String("corbaIor");
Attributes attrs1 = new BasicAttributes();
attrs1.put(new BasicAttribute("adminDescription", attrID));
attrs1.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.14"));
attrs1.put(new BasicAttribute("attributeSyntax", "2.5.5.5"));
attrs1.put(new BasicAttribute("cn", attrID));
attrs1.put(new BasicAttribute("description",
"Stringified interoperable object reference of a CORBA object"));
attrs1.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs1.put(new BasicAttribute("isSingleValued", "TRUE"));
attrs1.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs1.put(new BasicAttribute("name", attrID));
attrs1
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs1.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs1.put(new BasicAttribute("oMSyntax", "22"));
attrs1.put(new BasicAttribute("searchFlags", "0"));
attrs1.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs1);
System.out.println(" [" + attrID + "]");
attrID = new String("corbaRepositoryId");
Attributes attrs2 = new BasicAttributes();
attrs2.put(new BasicAttribute("adminDescription", attrID));
attrs2.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.15"));
attrs2.put(new BasicAttribute("attributeSyntax", "2.5.5.12"));
attrs2.put(new BasicAttribute("cn", attrID));
attrs2.put(new BasicAttribute("description",
"Repository ids of interfaces implemented by a CORBA object"));
attrs2.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs2.put(new BasicAttribute("isSingleValued", "FALSE"));
attrs2.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs2.put(new BasicAttribute("name", attrID));
attrs2
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs2.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs2.put(new BasicAttribute("oMSyntax", "64"));
attrs2.put(new BasicAttribute("searchFlags", "0"));
attrs2.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs2);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // finally
}
/**
* Inserts object class definitions from RFC 2714 into the schema.
*
* This method maps the LDAP schema definitions in RFC 2714 onto the
* proprietary attributes required by the Active Directory schema.
*
* The resulting object class definitions differ from those of RFC 2714 in the
* following ways:
* - Abstract and auxiliary classes are now defined as structural. - The
* corbaObject class now inherits from corbaContainer. - The
* corbaObjectReference class now inherits from corbaObject.
*
* The effect of these differences is that CORBA object references cannot be
* mixed-in with other directory entries, they may only be stored as
* stand-alone entries.
*
* The reason for these differences is due to the way auxiliary classes are
* supported in Active Directory. Only the names of structural classes (not
* auxiliary) may appear in the object class attribute of an entry. Therefore,
* the abstract and auxiliary classes in the CORBA schema definition is
* re-defined as structural.
*/
protected void insertADObjectClasses(DirContext rootCtx, DirContext schemaCtx)
throws NamingException {
System.out.println(" [inserting new object class definitions ...]");
String dn = schemaCtx.getNameInNamespace();
String attrID;
attrID = new String("corbaContainer");
Attributes attrs1 = new BasicAttributes();
attrs1.put(new BasicAttribute("cn", attrID));
attrs1.put(new BasicAttribute("objectClass", "classSchema"));
attrs1.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs1.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.10"));
attrs1.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs1.put(new BasicAttribute("mustContain", "cn"));
attrs1.put(new BasicAttribute("objectClassCategory", "1"));
attrs1.put(new BasicAttribute("systemOnly", "FALSE"));
attrs1.put(new BasicAttribute("subclassOf", "top"));
attrs1.put(new BasicAttribute("possSuperiors", "top")); // any superior
attrs1
.put(new BasicAttribute("description", "Container for a CORBA object"));
schemaCtx.createSubcontext("cn=" + attrID, attrs1);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // corbaObject relys on corbaContainer
attrID = new String("corbaObject");
Attributes attrs2 = new BasicAttributes();
attrs2.put(new BasicAttribute("cn", attrID));
attrs2.put(new BasicAttribute("objectClass", "classSchema"));
attrs2.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs2.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.9"));
attrs2.put(new BasicAttribute("lDAPDisplayName", attrID));
Attribute coMay = new BasicAttribute("mayContain");
coMay.add("corbaRepositoryId");
coMay.add("description");
attrs2.put(coMay);
attrs2.put(new BasicAttribute("objectClassCategory", "1"));
attrs2.put(new BasicAttribute("systemOnly", "FALSE"));
attrs2.put(new BasicAttribute("subclassOf", "corbaContainer"));
attrs2
.put(new BasicAttribute("description", "CORBA object representation"));
schemaCtx.createSubcontext("cn=" + attrID, attrs2);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // corbaObjectReference relys on corbaObject
attrID = new String("corbaObjectReference");
Attributes attrs3 = new BasicAttributes();
attrs3.put(new BasicAttribute("cn", attrID));
attrs3.put(new BasicAttribute("objectClass", "classSchema"));
attrs3.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs3.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.11"));
attrs3.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs3.put(new BasicAttribute("mustContain", "corbaIor"));
attrs3.put(new BasicAttribute("objectClassCategory", "1"));
attrs3.put(new BasicAttribute("systemOnly", "FALSE"));
attrs3.put(new BasicAttribute("subclassOf", "corbaObject"));
attrs3.put(new BasicAttribute("description",
"CORBA interoperable object reference"));
schemaCtx.createSubcontext("cn=" + attrID, attrs3);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // finally
}
protected void printUsage(String msg) {
printUsageAux(msg, "Corba");
}
}
class CreateJavaSchema {
protected static String dn, passwd, auth;
protected static boolean netscapebug;
// NS 4.1 has problems parsing an object class definition which contains
// a MUST clause without parentheses. The workaround is to add a
// superfluous value (objectClass) to each MUST clause.
//
// It also doesn't like the Octet String syntax (use Binary instead)
//
protected static boolean netscape41bug = false;
// AD supports auxiliary classes in a peculiar way.
protected static boolean activeDirectorySchemaBug = false;
protected static boolean traceLdap = false;
protected static final int LIST = 0;
protected static final int UPDATE = 1;
private static String[] allAttrs = { "javaSerializedObject",
"javaFactoryLocation", "javaReferenceAddress", "javaFactory",
"javaClassName", "javaClassNames", "javaDoc", "javaSerializedData",
"javaCodebase", "javaFactory", "javaReferenceAddress" };
private static String[] allOCs = { "javaObject", "javaNamingReference",
"javaSerializedObject", "javaRemoteObject", "javaMarshalledObject",
"javaContainer" };
public static void main(String[] args) {
new CreateJavaSchema().run(args, allAttrs, allOCs);
}
CreateJavaSchema() {
}
protected void run(String[] args, String[] attrIDs, String[] ocIDs) {
int cmd = processCommandLine(args);
try {
DirContext ctx = signOn();
switch (cmd) {
case UPDATE:
updateSchema(ctx, attrIDs, ocIDs);
break;
default:
showSchema(ctx, attrIDs, ocIDs);
}
} catch (NamingException e) {
e.printStackTrace();
}
}
/**
* Signs on to directory server using parameters supplied to program.
*
* @return The initial context to the server.
*/
private DirContext signOn() throws NamingException {
if (dn != null && auth == null) {
auth = "simple"; // use simple for Netscape
}
Hashtable env = new Hashtable();
env
.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.REFERRAL, "follow");
if (auth != null) {
env.put(Context.SECURITY_AUTHENTICATION, auth);
env.put(Context.SECURITY_PRINCIPAL, dn);
env.put(Context.SECURITY_CREDENTIALS, passwd);
}
// Workaround for Netscape schema bugs
if (netscapebug) {
env.put("com.sun.naming.netscape.schemaBugs", "true");
}
// LDAP protocol tracing
if (traceLdap) {
env.put("com.sun.jndi.ldap.trace.ber", System.err);
}
return new InitialDirContext(env);
}
void showSchema(DirContext ctx, String[] attrs, String[] ocs)
throws NamingException {
DirContext attrRoot = (DirContext) ctx.getSchema("").lookup(
"AttributeDefinition");
printSchema(attrRoot, attrs);
DirContext ocRoot = (DirContext) ctx.getSchema("")
.lookup("ClassDefinition");
printSchema(ocRoot, ocs);
}
private void printSchema(DirContext ctx, String[] ids) {
for (int i = 0; i < ids.length; i++) {
try {
System.out.print(ids[i] + ": ");
System.out.print(ctx.getAttributes(ids[i]));
} catch (NamingException e) {
} finally {
System.out.println();
}
}
}
/**
* Updates the schema:
*
* Delete obsolete attributes: javaSerializedObject javaFactoryLocation
* javaReferenceAddress javaFactory javaClassName + all the new ones that
* we're going to add Add new and updated attributes: javaSerializedData
* javaCodebase javaClassName javaClassNames javaFactory javaReferenceAddress
* javaDoc
*
* Delete obsolete object classes: javaNamingReference javaObject + all the
* new ones that we're going to add Add new and updated object classes:
* javaObject javaSerializedObject javaMarshalledObject javaNamingReference
*/
private void updateSchema(DirContext ctx, String[] attrIDs, String[] ocIDs)
throws NamingException {
if (activeDirectorySchemaBug) {
updateADSchema(ctx);
} else {
updateAttributes((DirContext) ctx.getSchema("").lookup(
"AttributeDefinition"), attrIDs);
updateObjectClasses((DirContext) ctx.getSchema("").lookup(
"ClassDefinition"), ocIDs);
}
System.out
.println("Please use your directory server's administration tool to verify");
System.out.println("the correctness of the schema.");
}
/* Add new and updated attr definitions */
protected void updateAttributes(DirContext attrRoot, String[] attrIDs)
throws NamingException {
/* Get rid of old attr IDs */
for (int i = 0; i < attrIDs.length; i++) {
attrRoot.destroySubcontext(attrIDs[i]);
}
// javaSerializedData
Attributes attrs = new BasicAttributes(true); // ignore case
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.8");
attrs.put("NAME", "javaSerializedData");
attrs.put("DESC", "Serialized form of a Java object");
if (netscape41bug) {
// DS 4.1 doesn't like Octet String
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.5");
} else {
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.40");
}
attrs.put("SINGLE-VALUE", "true");
attrRoot.createSubcontext("javaSerializedData", attrs);
System.out.println("Created javaSerializedData attribute");
// javaCodebase
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.7");
attrs.put("NAME", "javaCodebase");
attrs.put("DESC", "URL(s) specifying the location of class definition");
attrs.put("EQUALITY", "caseExactIA5Match");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.26");
attrRoot.createSubcontext("javaCodebase", attrs);
System.out.println("Created javaCodebase attribute");
// javaClassName
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.6");
attrs.put("NAME", "javaClassName");
attrs.put("DESC",
"Fully qualified name of distinguished class or interface");
attrs.put("EQUALITY", "caseExactMatch");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.15");
attrs.put("SINGLE-VALUE", "true");
attrRoot.createSubcontext("javaClassName", attrs);
System.out.println("Created javaClassName attribute");
// javaClassNames
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.13");
attrs.put("NAME", "javaClassNames");
attrs.put("DESC", "Fully qualified Java class or interface name");
attrs.put("EQUALITY", "caseExactMatch");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.15");
attrRoot.createSubcontext("javaClassNames", attrs);
System.out.println("Created javaClassNames attribute");
// javaFactory
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.10");
attrs.put("NAME", "javaFactory");
attrs.put("DESC",
"Fully qualified Java class name of a JNDI object factory");
attrs.put("EQUALITY", "caseExactMatch");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.15");
attrs.put("SINGLE-VALUE", "true");
attrRoot.createSubcontext("javaFactory", attrs);
System.out.println("Created javaFactory attribute");
// javaReferenceAddress
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.11");
attrs.put("NAME", "javaReferenceAddress");
attrs.put("DESC", "Addresses associated with a JNDI Reference");
attrs.put("EQUALITY", "caseExactMatch");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.15");
attrRoot.createSubcontext("javaReferenceAddress", attrs);
System.out.println("Created javaReferenceAddress attribute");
// javaDoc
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.1.12");
attrs.put("NAME", "javaDoc");
attrs.put("DESC", "The Java documentation for the class");
attrs.put("EQUALITY", "caseExactIA5Match");
attrs.put("SYNTAX", "1.3.6.1.4.1.1466.115.121.1.26");
attrRoot.createSubcontext("javaDoc", attrs);
System.out.println("Created javaDoc attribute");
}
// Object Classes
protected void updateObjectClasses(DirContext ocRoot, String[] ocIDs)
throws NamingException {
/* Get rid of old OCs - reverse order */
for (int i = ocIDs.length - 1; i >= 0; i--) {
ocRoot.destroySubcontext(ocIDs[i]);
}
// javaContainer
Attributes attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.1");
attrs.put("NAME", "javaContainer");
attrs.put("DESC", "Container for a Java object");
attrs.put("SUP", "top");
attrs.put("STRUCTURAL", "true");
Attribute jcMust = new BasicAttribute("MUST", "cn");
if (netscape41bug) {
jcMust.add("objectClass");
}
attrs.put(jcMust);
ocRoot.createSubcontext("javaContainer", attrs);
System.out.println("Created javaContainer object class");
// javaObject
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.4");
attrs.put("NAME", "javaObject");
attrs.put("DESC", "Java object representation");
attrs.put("SUP", "top");
attrs.put("ABSTRACT", "true");
Attribute joMust = new BasicAttribute("MUST", "javaClassName");
if (netscape41bug) {
joMust.add("objectClass");
}
attrs.put(joMust);
Attribute optional = new BasicAttribute("MAY", "javaCodebase");
optional.add("javaClassNames");
optional.add("javaDoc");
optional.add("description");
attrs.put(optional);
ocRoot.createSubcontext("javaObject", attrs);
System.out.println("Created javaObject object class");
// javaSerializedObject
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.5");
attrs.put("NAME", "javaSerializedObject");
attrs.put("DESC", "Java serialized object");
attrs.put("SUP", "javaObject");
attrs.put("AUXILIARY", "true");
Attribute jsoMust = new BasicAttribute("MUST", "javaSerializedData");
if (netscape41bug) {
jsoMust.add("objectClass");
}
if (netscapebug) {
// Netscape ignores 'SUP' so we must add explicitly
attrs.put(optional);
jsoMust.add("javaClassName");
}
attrs.put(jsoMust);
ocRoot.createSubcontext("javaSerializedObject", attrs);
System.out.println("Created javaSerializedObject object class");
// javaMarshalledObject
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.8");
attrs.put("NAME", "javaMarshalledObject");
attrs.put("DESC", "Java marshalled object");
attrs.put("SUP", "javaObject");
attrs.put("AUXILIARY", "true");
if (netscapebug) {
// Netscape ignores 'SUP' so we must add explicitly
attrs.put(optional);
}
attrs.put(jsoMust); // re-use the MUST from javaSerializedObject
ocRoot.createSubcontext("javaMarshalledObject", attrs);
System.out.println("Created javaMarshalledObject object class");
// javaNamingReference
attrs = new BasicAttributes(true);
attrs.put("NUMERICOID", "1.3.6.1.4.1.42.2.27.4.2.7");
attrs.put("NAME", "javaNamingReference");
attrs.put("DESC", "JNDI reference");
attrs.put("SUP", "javaObject");
attrs.put("AUXILIARY", "true");
if (netscapebug) {
// Netscape ignores 'SUP' so we must add explicitly
attrs.put("MUST", "javaClassName");
} else {
optional = new BasicAttribute("MAY");
}
optional.add("javaReferenceAddress");
optional.add("javaFactory");
attrs.put(optional);
ocRoot.createSubcontext("javaNamingReference", attrs);
System.out.println("Created javaNamingReference object class");
}
/**
* Updates the Active Directory schema.
*
* Modification of the (RFC 2252) schema descriptions is not supported in
* Active Directory. Instead, the Active Directory (internal) schema must be
* modified.
*/
private void updateADSchema(DirContext rootCtx) throws NamingException {
System.out.println("[updating Active Directory schema ...]");
// acquire schema context
DirContext schemaCtx = getADSchema(rootCtx);
// insert attribute definitions
insertADAttributes(rootCtx, schemaCtx);
// insert object class definitions
insertADObjectClasses(rootCtx, schemaCtx);
System.out.println("[update completed]\n");
}
/**
* Locates the Active Directory schema.
*
* @return A context for the root of the Active Directory schema.
*/
private DirContext getADSchema(DirContext rootCtx) throws NamingException {
System.out.println(" [locating the schema]");
String snc = "schemaNamingContext"; // DSE attribute
Attributes attrs = rootCtx.getAttributes("", new String[] { snc });
return (DirContext) rootCtx.lookup((String) attrs.get(snc).get());
}
/**
* Inserts attribute definitions from RFC 2713 into the schema.
*
* This method maps the LDAP schema definitions in RFC 2713 onto the
* proprietary attributes required by the Active Directory schema.
*
* The resulting attribute definitions are identical to those of RFC 2713.
*/
protected void insertADAttributes(DirContext rootCtx, DirContext schemaCtx)
throws NamingException {
System.out.println(" [inserting new attribute definitions ...]");
String dn = schemaCtx.getNameInNamespace();
String attrID;
attrID = new String("javaClassName");
Attributes attrs1 = new BasicAttributes();
attrs1.put(new BasicAttribute("adminDescription", attrID));
attrs1.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.6"));
attrs1.put(new BasicAttribute("attributeSyntax", "2.5.5.12"));
attrs1.put(new BasicAttribute("cn", attrID));
attrs1.put(new BasicAttribute("description",
"Fully qualified name of distinguished Java class or interface"));
attrs1.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs1.put(new BasicAttribute("isSingleValued", "TRUE"));
attrs1.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs1.put(new BasicAttribute("name", attrID));
attrs1
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs1.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs1.put(new BasicAttribute("oMSyntax", "64"));
attrs1.put(new BasicAttribute("searchFlags", "0"));
attrs1.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs1);
System.out.println(" [" + attrID + "]");
attrID = new String("javaCodeBase");
Attributes attrs2 = new BasicAttributes();
attrs2.put(new BasicAttribute("adminDescription", attrID));
attrs2.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.7"));
attrs2.put(new BasicAttribute("attributeSyntax", "2.5.5.5"));
attrs2.put(new BasicAttribute("cn", attrID));
attrs2.put(new BasicAttribute("description",
"URL(s) specifying the location of class definition"));
attrs2.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs2.put(new BasicAttribute("isSingleValued", "FALSE"));
attrs2.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs2.put(new BasicAttribute("name", attrID));
attrs2
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs2.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs2.put(new BasicAttribute("oMSyntax", "22"));
attrs2.put(new BasicAttribute("searchFlags", "0"));
attrs2.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs2);
System.out.println(" [" + attrID + "]");
attrID = new String("javaSerializedData");
Attributes attrs3 = new BasicAttributes();
attrs3.put(new BasicAttribute("adminDescription", attrID));
attrs3.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.8"));
attrs3.put(new BasicAttribute("attributeSyntax", "2.5.5.10"));
attrs3.put(new BasicAttribute("cn", attrID));
attrs3.put(new BasicAttribute("description",
"Serialized form of a Java object"));
attrs3.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs3.put(new BasicAttribute("isSingleValued", "TRUE"));
attrs3.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs3.put(new BasicAttribute("name", attrID));
attrs3
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs3.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs3.put(new BasicAttribute("oMSyntax", "4"));
attrs3.put(new BasicAttribute("searchFlags", "0"));
attrs3.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs3);
System.out.println(" [" + attrID + "]");
attrID = new String("javaFactory");
Attributes attrs4 = new BasicAttributes();
attrs4.put(new BasicAttribute("adminDescription", attrID));
attrs4.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.10"));
attrs4.put(new BasicAttribute("attributeSyntax", "2.5.5.12"));
attrs4.put(new BasicAttribute("cn", attrID));
attrs4.put(new BasicAttribute("description",
"Fully qualified Java class name of a JNDI object factory"));
attrs4.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs4.put(new BasicAttribute("isSingleValued", "TRUE"));
attrs4.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs4.put(new BasicAttribute("name", attrID));
attrs4
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs4.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs4.put(new BasicAttribute("oMSyntax", "64"));
attrs4.put(new BasicAttribute("searchFlags", "0"));
attrs4.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs4);
System.out.println(" [" + attrID + "]");
attrID = new String("javaReferenceAddress");
Attributes attrs5 = new BasicAttributes();
attrs5.put(new BasicAttribute("adminDescription", attrID));
attrs5.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.11"));
attrs5.put(new BasicAttribute("attributeSyntax", "2.5.5.12"));
attrs5.put(new BasicAttribute("cn", attrID));
attrs5.put(new BasicAttribute("description",
"Addresses associated with a JNDI Reference"));
attrs5.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs5.put(new BasicAttribute("isSingleValued", "FALSE"));
attrs5.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs5.put(new BasicAttribute("name", attrID));
attrs5
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs5.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs5.put(new BasicAttribute("oMSyntax", "64"));
attrs5.put(new BasicAttribute("searchFlags", "0"));
attrs5.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs5);
System.out.println(" [" + attrID + "]");
attrID = new String("javaDoc");
Attributes attrs6 = new BasicAttributes();
attrs6.put(new BasicAttribute("adminDescription", attrID));
attrs6.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.12"));
attrs6.put(new BasicAttribute("attributeSyntax", "2.5.5.5"));
attrs6.put(new BasicAttribute("cn", attrID));
attrs6.put(new BasicAttribute("description",
"The Java documentation for the class"));
attrs6.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs6.put(new BasicAttribute("isSingleValued", "FALSE"));
attrs6.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs6.put(new BasicAttribute("name", attrID));
attrs6
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs6.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs6.put(new BasicAttribute("oMSyntax", "22"));
attrs6.put(new BasicAttribute("searchFlags", "0"));
attrs6.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs6);
System.out.println(" [" + attrID + "]");
attrID = new String("javaClassNames");
Attributes attrs7 = new BasicAttributes();
attrs7.put(new BasicAttribute("adminDescription", attrID));
attrs7.put(new BasicAttribute("attributeID", "1.3.6.1.4.1.42.2.27.4.1.13"));
attrs7.put(new BasicAttribute("attributeSyntax", "2.5.5.12"));
attrs7.put(new BasicAttribute("cn", attrID));
attrs7.put(new BasicAttribute("description",
"Fully qualified Java class or interface name"));
attrs7.put(new BasicAttribute("distinguishedName", "CN=" + attrID + ","
+ dn));
attrs7.put(new BasicAttribute("isSingleValued", "FALSE"));
attrs7.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs7.put(new BasicAttribute("name", attrID));
attrs7
.put(new BasicAttribute("objectCategory", "CN=Attribute-Schema," + dn));
attrs7.put(new BasicAttribute("objectClass", "attributeSchema"));
attrs7.put(new BasicAttribute("oMSyntax", "64"));
attrs7.put(new BasicAttribute("searchFlags", "0"));
attrs7.put(new BasicAttribute("systemOnly", "FALSE"));
schemaCtx.createSubcontext("cn=" + attrID, attrs7);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // finally
}
/**
* Inserts object class definitions from RFC 2713 into the schema.
*
* This method maps the LDAP schema definitions in RFC 2713 onto the
* proprietary attributes required by the Active Directory schema.
*
* The resulting object class definitions differ from those of RFC 2713 in the
* following ways: - Abstract and auxiliary classes are now defined as
* structural. - The javaObject class now inherits from javaContainer. - The
* javaNamingReference, javaSerializedObject and javaMarshalledObject now
* inherit from javaObject.
*
* The effect of these differences is that Java objects cannot be mixed-in
* with other directory entries, they may only be stored as stand-alone
* entries.
*
* The reason for these differences is due to the way auxiliary classes are
* supported the Active Directory. Only the names of structural classes (not
* auxiliary) may appear in the object class attribute of an entry. Therefore,
* the abstract and auxiliary classes in the Java schema definition are
* re-defined as structural.
*/
protected void insertADObjectClasses(DirContext rootCtx, DirContext schemaCtx)
throws NamingException {
System.out.println(" [inserting new object class definitions ...]");
String dn = schemaCtx.getNameInNamespace();
String attrID;
attrID = new String("javaContainer");
Attributes attrs1 = new BasicAttributes();
attrs1.put(new BasicAttribute("objectClass", "classSchema"));
attrs1.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs1.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.1"));
attrs1.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs1.put(new BasicAttribute("mustContain", "cn"));
attrs1.put(new BasicAttribute("objectClassCategory", "1"));
attrs1.put(new BasicAttribute("systemOnly", "FALSE"));
attrs1.put(new BasicAttribute("subclassOf", "top"));
attrs1.put(new BasicAttribute("possSuperiors", "top")); // any superior
attrs1
.put(new BasicAttribute("description", "Container for a Java object"));
schemaCtx.createSubcontext("CN=" + attrID, attrs1);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // because javaObject relys on javaContainer
attrID = new String("javaObject");
Attributes attrs2 = new BasicAttributes();
attrs2.put(new BasicAttribute("objectClass", "classSchema"));
attrs2.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs2.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.4"));
attrs2.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs2.put(new BasicAttribute("mustContain", "javaClassName"));
Attribute joMay = new BasicAttribute("mayContain");
joMay.add("javaClassNames");
joMay.add("javaCodeBase");
joMay.add("javaDoc");
joMay.add("description");
attrs2.put(joMay);
attrs2.put(new BasicAttribute("objectClassCategory", "1"));
attrs2.put(new BasicAttribute("systemOnly", "FALSE"));
attrs2.put(new BasicAttribute("subclassOf", "javaContainer"));
attrs2.put(new BasicAttribute("description", "Java object representation"));
schemaCtx.createSubcontext("CN=" + attrID, attrs2);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // because next 3 rely on javaObject
attrID = new String("javaSerializedObject");
Attributes attrs3 = new BasicAttributes();
attrs3.put(new BasicAttribute("objectClass", "classSchema"));
attrs3.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs3.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.5"));
attrs3.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs3.put(new BasicAttribute("mustContain", "javaSerializedData"));
attrs3.put(new BasicAttribute("objectClassCategory", "1"));
attrs3.put(new BasicAttribute("systemOnly", "FALSE"));
attrs3.put(new BasicAttribute("subclassOf", "javaObject"));
attrs3.put(new BasicAttribute("description", "Java serialized object"));
schemaCtx.createSubcontext("CN=" + attrID, attrs3);
System.out.println(" [" + attrID + "]");
attrID = new String("javaNamingReference");
Attributes attrs4 = new BasicAttributes();
attrs4.put(new BasicAttribute("objectClass", "classSchema"));
attrs4.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs4.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.7"));
attrs4.put(new BasicAttribute("lDAPDisplayName", attrID));
Attribute jnrMay = new BasicAttribute("mayContain");
jnrMay.add("javaReferenceAddress");
jnrMay.add("javaFactory");
attrs4.put(jnrMay);
attrs4.put(new BasicAttribute("objectClassCategory", "1"));
attrs4.put(new BasicAttribute("systemOnly", "FALSE"));
attrs4.put(new BasicAttribute("subclassOf", "javaObject"));
attrs4.put(new BasicAttribute("description", "JNDI reference"));
schemaCtx.createSubcontext("CN=" + attrID, attrs4);
System.out.println(" [" + attrID + "]");
attrID = new String("javaMarshalledObject");
Attributes attrs5 = new BasicAttributes();
attrs5.put(new BasicAttribute("objectClass", "classSchema"));
attrs5.put(new BasicAttribute("defaultHidingValue", "FALSE"));
attrs5.put(new BasicAttribute("governsID", "1.3.6.1.4.1.42.2.27.4.2.8"));
attrs5.put(new BasicAttribute("lDAPDisplayName", attrID));
attrs5.put(new BasicAttribute("mustContain", "javaSerializedData"));
attrs5.put(new BasicAttribute("objectClassCategory", "1"));
attrs5.put(new BasicAttribute("systemOnly", "FALSE"));
attrs5.put(new BasicAttribute("subclassOf", "javaObject"));
attrs5.put(new BasicAttribute("description", "Java marshalled object"));
schemaCtx.createSubcontext("CN=" + attrID, attrs5);
System.out.println(" [" + attrID + "]");
flushADSchemaMods(rootCtx); // finally
}
/**
* Writes schema modifications to the Active Directory schema immediately.
*/
protected void flushADSchemaMods(DirContext rootCtx) throws NamingException {
rootCtx
.modifyAttributes("", new ModificationItem[] { new ModificationItem(
DirContext.ADD_ATTRIBUTE,
new BasicAttribute("schemaUpdateNow", "1")) });
}
private int processCommandLine(String[] args) {
String option;
boolean schema = false;
boolean list = false;
for (int i = 0; i < args.length; i++) {
option = args[i];
if (option.startsWith("-h")) {
printUsage(null);
}
if (option.startsWith("-s")) {
schema = true;
netscapebug = option.equals("-sn");
netscape41bug = option.equals("-sn41");
activeDirectorySchemaBug = option.equals("-sad");
} else if (option.startsWith("-l")) {
list = true;
} else if (option.startsWith("-a")) {
auth = option.substring(2);
} else if (option.startsWith("-n")) {
dn = option.substring(2);
} else if (option.startsWith("-p")) {
passwd = option.substring(2);
} else if (option.startsWith("-trace")) {
traceLdap = true;
} else {
// invalid option
printUsage("Invalid option");
}
}
if (!schema) {
return LIST;
} else {
return UPDATE;
}
}
protected void printUsage(String msg) {
printUsageAux(msg, "Java");
}
protected void printUsageAux(String msg, String key) {
if (msg != null) {
System.out.println(msg);
}
System.out.print("Usage: ");
System.out
.println("java [-Djava.naming.provider.url=<ldap_server_url>] \\");
System.out.println(" Create" + key
+ "Schema [-h|-l|-s[n|n41|ad]] [-n<dn>] [-p<passwd>] [-a<auth>]");
System.out.println();
System.out.println(" -h\t\tPrint the usage message");
System.out.println(" -l\t\tList the " + key + " schema in the directory");
System.out.println(" -s[n|n41|ad]\tUpdate schema:");
System.out
.println("\t\t -sn use workaround for Netscape Directory pre-4.1 schema bug");
System.out
.println("\t\t -sn41 use workaround for Netscape Directory 4.1 schema bug");
System.out
.println("\t\t -sad use workaround for Active Directory schema bug");
System.out
.println(" -n<dn>\tUse <dn> as the distinguished name for authentication");
System.out
.println(" -p<passwd>\tUse <passwd> as the password for authentication");
System.out
.println(" -a<auth>\tUse <auth> as the authentication mechanism");
System.out
.println("\t\t Default is 'simple' if dn specified; otherwise 'none'");
System.exit(-1);
}
}
|