Introduce custom schema to LDAP

Why we need ldap custom schema

There are common and default set of attributes already have in ldap implementation. But some times those atrributes may not meet the user requirements. Hence LDAP servers like ApacheDS, OpenLDAP give the flexibility and extendibility to define our own attributes and introduce them to the LDAP server instance and use them as we need.

Schema, Object class and Attributes in LDAP

Object classes are define within schema. Attributes also defined in schema. But every attribute is included in one or more object classes.

There are two ways introduce a custom object class to ldap server.

  1. Writing an object class and attributes in a ldif (ldap data interchange format) file and importing it to the LDAP schema.
  2. Programmatic way — you can use JNDI for that.

According to first way there also have two ways write an object class in ldif.

  1. object class and all the attributes define in same ldif file.
  2. object class and attributes define in two separated ldif files.

Note: Here I’m going to explain about second way. You can see there are several tutorials related to first way. This is another alternative way. In this way I changed the ldif format. Here, may not change the characteristics and properties of attributes and object classes.

Write an Object Class

version: 1
dn: m-oid=1.3.6.1.4.1.37505.1.1,ou=objectClasses,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaObjectClass
m-oid: 1.3.6.1.4.1.37505.1.1
m-description: wso2Person
m-may: gender
m-may: country
m-may: nickName
m-may: timeZone
m-may: dateOfBirth
m-may: role
m-may: im
m-may: url
m-may: otherPhone
m-may: privatePersonalIdentifier
m-may: profileconfiguration
m-may: prefferedLanguage
m-name: wso2Person
m-obsolete: FALSE
m-supobjectclass: inetOrgPerson
m-typeobjectclass: STRUCTURAL
  • m-oid oid is globally unique name or identifier. There are several ways you can obtain oid. iana is one way you can obtain oid.
  • m-may is those attribute may have in object class.
  • m-supobjectclass shows this superior class is inetOrgPerson.
  • m-typeobjectclass shows this class type is STRUCTURAL.

Important:According to this way before you adding objectclass in to the schema, the attributes should be already existing inside the schema. next I will show how define an attribute for ldap object class.

Write an attribute

version: 1
dn: m-oid=1.3.6.1.4.1.37505.1.2,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.2
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: gender
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
  • m-name: attribute name
  • m-oid: you can obtain oid from iana.
  • m-collective: Collective is only valid with USAGE ‘userApplication’ (the default) and if present in an attribute definition allows all instances of the attribute’s SUPerior to share the same value.
  • m-singlevalue: single-value Omission of this entry means that it is multi-valued, that is, it can appear more than once in an objectclass.
  • m-nousermodification: no-user-modification If present this indicates the attribute may not be modified by the user irrespective of any assigned permissions in ACL/Security statement.
  • m-obsolete:Indicates that the attribute type is obsolete.
  • m-equality and m-substr: equality caseIgnoreMatch and substr caseIgnoreSubstringsMatch indicates how this will behave when used in a search filter.
  • m-syntax: define attributes type. eg- String , integer, boolean

There are several properties that we have to specify when defining attributes and object classes for LDAP as you can see in the above ldif files. You can learn about more of them in detail from the RFC here.

As an example here shows all the attributes of wso2person object class.Later I’ll show how to introduce this object class and attributes to ldapserver.

version: 1
dn: ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: organizationalUnit
ou: attributetypes
dn: m-oid=1.3.6.1.4.1.37505.1.2,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.2
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: gender
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.3,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.3
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: country
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.4,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.4
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: nickName
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.5,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.5
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: timeZone
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.6,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.6
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: dateOfBirth
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.7,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.7
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: role
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.8,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.8
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: im
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.9,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.9
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: url
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.10,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.10
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: otherPhone
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.11,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.11
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: privatePersonalIdentifier
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.12,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.12
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: profileconfiguration
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS
dn: m-oid=1.3.6.1.4.1.37505.1.13,ou=attributeTypes,cn=other,ou=schema
objectClass: top
objectClass: metaTop
objectClass: metaAttributeType
m-oid: 1.3.6.1.4.1.37505.1.13
m-collective: FALSE
m-equality: caseIgnoreMatch
m-name: prefferedLanguage
m-nousermodification: FALSE
m-obsolete: FALSE
m-singlevalue: FALSE
m-substr: caseIgnoreSubstringsMatch
m-syntax: 1.3.6.1.4.1.1466.115.121.1.15
m-usage: USER_APPLICATIONS

Let’s create a wso2schema

WSO2 Identity Server has it’s own ldap schema. Here I’am going to explain how create custom ldap schema for WSO2 Identity Server.

You can download all the resource file form here.

When you going to add your object class to ldap schema that object class related attributes should be already exist. So add your own object classes attributes to ldap schema before you adding to your own object class.

Object class inheritance

Here, wso2person superior class is inetOrgPerson object class. As an example if you want to create wso2 whole schema you should consider about this inheritance.

Here inheritance hierarchy looks like this.

identityPerson -> scimPerson -> wso2Person -> inetOrgPerson

Step 1:

Delete attributeTypes DN.

here wso2schema create under the DN: cn=other,ou=schema

before adding all the attributes you should delete DN: ou=attributeTypes,cn=other,ou=schema. here it shows below figure.

(If you want add attributes without deleting dn: ou=attributeTypes,cn=other,ou=schema you have to add each attribute one by one.)

Go ou=attributesTypes then right click-> Delete Entry

Step 2:(import wso2attributes)

Go cn=other,ou=schema then right click->import->Ldif import

Step 3: (import wso2 object classes)

Go ou=objectClasses,cn=other,ou=schema then right click->import-> import Ldif

inheritance hierarchy is like this.

identityPerson -> scimPerson -> wso2Person -> inetOrgPerson

So you should add all the object classes following order

1) wso2Person2) scimPerson3) identityPerson

here I explained how add the wso2person class. Other two object classes you can add following the same way.At the second step I added all the object classes attributes at once. Hence scimPerson and identityPerson attributes also already existing in the schema.

Note:If you need add these attributes and object classes without using the ldap browser you can use this commands with console.

  1. Delete DN:ou=attributeTypes,cn=other,ou=schema.
ldapdelete -h localhost -p 10389 -D “uid=admin,ou=system” -w secret “ou=attributeTypes,cn=other,ou=schema”

2. Add wso2attributes file

ldapadd -h localhost -p 10389 -D “uid=admin,ou=system” -w secret -f wso2attributes.ldif

3.Add wso2person objectclass

ldapadd -h localhost -p 10389 -D “uid=admin,ou=system” -w secret -f wso2person.ldif

4.Add scimPerson objectclass

ldapadd -h localhost -p 10389 -D “uid=admin,ou=system” -w secret -f scimperson.ldif

5Add identityPerson object class

ldapadd -h localhost -p 10389 -D “uid=admin,ou=system” -w secret -f identityperson.ldif

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade