package org.safehaus.penrose.schema; import org.safehaus.penrose.ldap.*; import org.safehaus.penrose.Penrose; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.StringReader; /** * @author Endi Sukma Dewata */ public class SchemaUtil { public Logger log = LoggerFactory.getLogger(getClass()); public Schema getSchema(LDAPClient client) throws Exception { boolean debug = log.isDebugEnabled(); SearchResult rootDSE = client.getRootDSE(); if (debug) log.debug("Searching Schema ..."); try { Attribute schemaNamingContext = rootDSE.getAttributes().get("schemaNamingContext"); Attribute subschemaSubentry = rootDSE.getAttributes().get("subschemaSubentry"); String schemaDn; if (schemaNamingContext != null) { schemaDn = (String)schemaNamingContext.getValue(); if (debug) log.debug("Active Directory Schema: "+schemaDn); return getActiveDirectorySchema(client, schemaDn); } else if (subschemaSubentry != null) { schemaDn = (String)subschemaSubentry.getValue(); if (debug) log.debug("Standard LDAP Schema: "+schemaDn); return getLDAPSchema(client, schemaDn); } else { schemaDn = "cn=schema"; if (debug) log.debug("Default Schema: "+schemaDn); return getLDAPSchema(client, schemaDn); } } catch (Exception e) { Penrose.errorLog.error(e.getMessage(), e); throw e; } } public Schema getLDAPSchema(LDAPClient client, String schemaDn) throws Exception { boolean debug = log.isDebugEnabled(); Schema schema = new Schema("ldap"); if (debug) log.debug("Searching "+schemaDn+" ..."); SearchRequest request = new SearchRequest(); request.setDn(schemaDn); request.setScope(SearchRequest.SCOPE_BASE); request.setAttributes(new String[] { "attributeTypes", "objectClasses" }); SearchResponse response = new SearchResponse(); client.search(request, response); SearchResult sr = response.next(); Attributes attributes = sr.getAttributes(); //log.debug("Object Classes:"); for (Object value : attributes.getValues("objectClasses")) { ObjectClass oc = parseObjectClass((String)value); if (oc == null) continue; //log.debug(" - "+oc.getName()); schema.addObjectClass(oc); } //log.debug("Attribute Types:"); for (Object value : attributes.getValues("attributeTypes")) { AttributeType at = parseAttributeType((String)value); if (at == null) continue; //log.debug(" - "+at.getName()); schema.addAttributeType(at); } return schema; } public AttributeType parseAttributeType(String line) throws Exception { try { line = "attributetype "+line; SchemaParser parser = new SchemaParser(new StringReader(line)); Schema schema = parser.parse(); return schema.getAttributeTypes().iterator().next(); } catch (Exception e) { Penrose.errorLog.error(e.getMessage(), e); return null; } } public ObjectClass parseObjectClass(String line) throws Exception { try { line = "objectclass "+line; SchemaParser parser = new SchemaParser(new StringReader(line)); Schema schema = parser.parse(); return schema.getObjectClasses().iterator().next(); } catch (Exception e) { Penrose.errorLog.error(e.getMessage(), e); return null; } } public Schema getActiveDirectorySchema(LDAPClient client, String schemaDn) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Searching "+schemaDn+" ..."); Schema schema = new Schema("ad"); getActiveDirectoryAttributeTypes(client, schema, schemaDn); getActiveDirectoryObjectClasses(client, schema, schemaDn); return schema; } public synchronized void getActiveDirectoryAttributeTypes(LDAPClient client, Schema schema, String schemaDn) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Search \""+ schemaDn +"\""); SearchRequest request = new SearchRequest(); request.setDn(schemaDn); request.setScope(SearchRequest.SCOPE_ONE); request.setFilter("(objectClass=attributeSchema)"); SearchResponse response = new SearchResponse(); try { client.search(request, response); } catch (Exception e) { Penrose.errorLog.error(e.getMessage(), e); } while (response.hasNext()) { SearchResult sr = response.next(); Attributes attributes = sr.getAttributes(); String atName = (String)attributes.getValue("lDAPDisplayName"); AttributeType at = new AttributeType(); at.setName(atName); at.setOid((String)attributes.getValue("attributeID")); at.setDescription((String)attributes.getValue("adminDescription")); at.setSyntax((String)attributes.getValue("attributeSyntax")); at.setSingleValued(Boolean.valueOf((String)attributes.getValue("isSingleValued"))); schema.addAttributeType(at); } } public synchronized void getActiveDirectoryObjectClasses(LDAPClient client, Schema schema, String schemaDn) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Search \""+ schemaDn +"\""); SearchRequest request = new SearchRequest(); request.setDn(schemaDn); request.setScope(SearchRequest.SCOPE_ONE); request.setFilter("(objectClass=classSchema)"); SearchResponse response = new SearchResponse(); try { client.search(request, response); } catch (Exception e) { Penrose.errorLog.error(e.getMessage(), e); } while (response.hasNext()) { SearchResult sr = response.next(); Attributes attributes = sr.getAttributes(); ObjectClass oc = new ObjectClass(); oc.setName((String)attributes.getValue("lDAPDisplayName")); oc.setOid((String)attributes.getValue("governsID")); oc.setDescription((String)attributes.getValue("adminDescription")); for (Object value : attributes.getValues("mustContain")) { oc.addRequiredAttribute((String)value); } for (Object value : attributes.getValues("systemMustContain")) { oc.addRequiredAttribute((String)value); } for (Object value : attributes.getValues("mayContain")) { oc.addOptionalAttribute((String)value); } for (Object value : attributes.getValues("systemMayContain")) { oc.addOptionalAttribute((String)value); } schema.addObjectClass(oc); } } }