16.5.3. DIT Design Under Governance - A Practical Overview

This section will cover the highlights of creating initial DIT content while under the control of easily-understood DIT structure rules enforcing the use of common attribute types within entry RDNs.

The following basic assumptions apply:

  • A new userRoot backend exists and is identified by the base-dn of dc=example,dc=com, containing no entries whatsoever, and ...

  • The eight (8) definitions described have already been saved to /opt/opendj/config/schema/99-user.ldif or a similar file, or otherwise added via ldapmodify

To begin, let's take a look at the following nameForms definitions:

      #
      nameForms: ( 1.3.6.1.4.1.56521.999.2.7.1
         NAME 'rootSuffixForm'
         OC domain
         MUST dc )
      #
      nameForms: ( 1.3.6.1.4.1.56521.999.2.7.2
         NAME 'ouForm'
         OC organizationalUnit
         MUST ou )
      #
      nameForms: ( 1.3.6.1.4.1.56521.999.2.7.3
         NAME 'accountForm'
         OC inetOrgPerson
         MUST uid )
      #
      nameForms: ( 1.3.6.1.4.1.56521.999.2.7.4
         NAME 'groupForm'
         OC groupOfNames
         MUST cn )

These name forms declare the following mandates:

  • Entries bearing the domain STRUCTURAL class, MUST utilize dc for their respective RDNs
  • Entries bearing the organizationalUnit STRUCTURAL class, MUST utilize ou for their respective RDNs
  • Entries bearing the inetOrgPerson STRUCTURAL class, MUST utilize uid for their respective RDNs
  • Entries bearing the groupOfNames STRUCTURAL class, MUST utilize cn for their respective RDNs

Next, we'll take a look at the new dITStructureRules instances, which will bring the above name forms to life:

      #
      dITStructureRules: ( 20
                NAME 'rootSuffixStructure'
                FORM rootSuffixForm )
      #
      dITStructureRules: ( 21
                NAME 'ouStructure'
                FORM ouForm
                SUP ( 20 21 ) )
      #
      dITStructureRules: ( 22
                NAME 'accountStructure'
                FORM accountForm
                SUP 21 )
      #
      dITStructureRules: ( 23
                NAME 'groupStructure'
                FORM groupForm
                SUP 21 )

From these rules, one can begin to perceive an abstract DIT structure, defined by the incrementing -- and hierarchically-significant -- integer identifiers, each of which reflect the following respective conditions:

  • Given the absence of other entries, the introduction of an entry bearing the domain STRUCTURAL class and dc RDN attribute signifies the start of the administrative area, or the start of the "chain of enforced rules"

    When added, this entry SHOULD bear a governingStructureRule integer identifier of 20

  • Given the introduction of an entry, positioned directly subordinate to the root suffix and bearing the organizationalUnit STRUCTURAL class and ou RDN attribute, the entry is accepted

    When added, this entry SHOULD bear a governingStructureRule integer identifier of 21, the subordinate structure rule of its superior structure rule, 20

  • Given the introduction of any additional organizationalUnit entries, whether descending directly from the root suffix, OR if subordinate to other organizationalUnit entries in "nested" fashion, the entry is accepted by rite of structure rule recursion

    When added, this entry SHOULD also bear a governingStructureRule integer identifier of 21, as with the previous case

  • Given the introduction of an entry, positioned directly subordinate to any organizationalUnit entry presently governed by DIT structure rule 21 and bearing the inetOrgPerson STRUCTURAL class and uid RDN attribute, the entry is accepted

    When added, this entry SHOULD bear a governingStructureRule integer identifier of 22

  • Given the introduction of an entry, positioned directly subordinate to any organizationalUnit entry presently governed by DIT structure rule 21 and bearing the groupOfNames STRUCTURAL class and cn RDN attribute, the entry is accepted

    When added, this entry SHOULD bear a governingStructureRule integer identifier of 23

Next, we'll be creating the initial portions of the governed DIT using ldapmodify, and periodically checking the results with ldapsearch along the way.

[Note] Note
In cases where changes are made in this section, the root DN user (cn=Directory Manager) is purposely used. This is simply to demonstrate that no user, regardless of privilege, can "bypass" or otherwise violate DIT structure rules in force.
    $ ldapmodify -w password \ 
      -D "cn=Directory Manager" \
      -h opendj.example.com

    dn: dc=example,dc=com
    changetype: add
    objectClass: domain

    Processing ADD request for dc=example,dc=com
    ADD operation successful for DN dc=example,dc=com
    
    dn: ou=Accounts,dc=example,dc=com
    changetype: add
    objectClass: organizationalUnit
    
    Processing ADD request for ou=Accounts,dc=example,dc=com
    ADD operation successful for DN ou=Accounts,dc=example,dc=com
    
    dn: ou=Consultants,ou=Accounts,dc=example,dc=com
    changetype: add
    objectClass: organizationalUnit

    Processing ADD request for ou=Consultants,dc=example,dc=com
    ADD operation successful for DN ou=Consultants,dc=example,dc=com

So far, so good. What we've just done is create the initial structure of our DIT, and in doing so we've confirmed the DIT structure rules do not seem to be interfering.

But, let's stop for now and check our work. We want to see the DIT structure rules that are actively governing our entries. To do this, we need only perform a simple anonymous LDAP search:

    $ ldapsearch -h opendj.example.com \
      -b dc=example,dc=com \
      "(objectClass=*)" \
      governingStructureRule

    dn: dc=example,dc=com
    governingStructureRule: 20
    
    dn: ou=Accounts,dc=example,dc=com
    governingStructureRule: 21
    
    dn: ou=Consultants,ou=Accounts,dc=example,dc=com
    governingStructureRule: 21

This proves the following:

  • Rule 20, the rootSuffixStructure definition, represents the start of the structure chain
  • Rule 21, the ouStructure definition, represents the permitted subordinate naming context below entries governed by the rootSuffixStructure rule
  • Rule 21, as it supports recursion by nature, allows organizationalUnit entries to reside within organizationalUnit entries, thus allowing categorical organizational structures to exist

Let's see what happens when we attempt to add an entry bearing an unauthorized RDN syntax.

    $ ldapmodify -w password \
      -D "cn=Directory Manager"\
      -h opendj.example.com

    dn: mail=user@example.com,ou=Consultants,ou=Accounts,dc=example,dc=com
    changetype: add
    objectClass: inetOrgPerson
    cn: User Person
    sn: Person

    Processing ADD request for
    mail=user@example.com,ou=Consultants,ou=Accounts,dc=example,dc=com
    The LDAP modify request failed: 65 (Object Class Violation)
    Additional Information:  Entry
    mail=user@example.com,ou=Consultants,ou=Accounts,dc=example,dc=com violates
    the Directory Server schema configuration because its RDN does not contain
    attribute uid that is required by name form accountForm

Good, the DIT structure rule in question seems to work in preventing bogus RDNs. Now let's continue with entries that are expected to work.

    $ ldapmodify -w password \
      -D "cn=Directory Manager" \
      -h opendj.example.com
 
    dn: uid=userPerson,ou=Consultants,ou=Accounts,dc=example,dc=com
    changetype: add
    objectClass: inetOrgPerson
    sn: Person
    cn: User Person
   
    Processing ADD request for uid=userPerson,ou=Consultants,ou=Accounts,dc=example,dc=com
    ADD operation successful for DN uid=userPerson,ou=Consultants,ou=Accounts,dc=example,dc=com
    
    dn: ou=Groups,dc=example,dc=com
    changetype: add
    objectClass: organizationalUnit
    
    Processing ADD request for ou=Groups,dc=example,dc=com
    ADD operation successful for DN ou=Groups,dc=example,dc=com
    
    dn: ou=Corporate,ou=Groups,dc=example,dc=com
    changetype: add
    objectClass: organizationalUnit
    
    Processing ADD request for ou=Corporate,ou=Groups,dc=example,dc=com
    ADD operation successful for DN ou=Corporate,ou=Groups,dc=example,dc=com
    
    dn: ou=Infrastructure,ou=Groups,dc=example,dc=com
    changetype: add
    objectClass: organizationalUnit
    
    Processing ADD request for ou=Infrastructure,ou=Groups,dc=example,dc=com
    ADD operation successful for DN ou=Infrastructure,ou=Groups,dc=example,dc=com
    
    dn: cn=Abuse Mail,ou=Infrastructure,ou=Groups,dc=example,dc=com
    changetype: add
    objectClass: groupOfNames
    
    Processing ADD request for cn=Abuse Mail,ou=Infrastructure,ou=Groups,dc=example,dc=com
    ADD operation successful for DN cn=Abuse Mail,ou=Infrastructure,ou=Groups,dc=example,dc=com

Again, let's check our work (omitting the contents of the previous LDAP search):

    $ ldapsearch -h opendj.example.com \
      -b dc=example,dc=com \
      "(objectClass=*)" \
      governingStructureRule
 
    dn: uid=userPerson,ou=Consultants,ou=Accounts,dc=example,dc=com
    governingStructureRule: 22
    
    dn: ou=Groups,dc=example,dc=com
    governingStructureRule: 21
    
    dn: ou=Corporate,ou=Groups,dc=example,dc=com
    governingStructureRule: 21
    
    dn: ou=Infrastructure,ou=Groups,dc=example,dc=com
    governingStructureRule: 21
    
    dn: cn=Abuse Mail,ou=Infrastructure,ou=Groups,dc=example,dc=com
    governingStructureRule: 23

So, what did we learn?

  • ouStructure rule 21 continues to allow recursive organizationalUnit entries, so long as they ultimately extend from the rootSuffixStructure superior structure (ancestor) rule 20, or another such entry governed by rule 21
  • accountStructure rule 22 is correctly governing entries bearing the inetOrgPerson STRUCTURAL class found within an organizationalUnit entry (superior structure rule 21)
  • groupStructure rule 23 is correctly governing entries bearing the groupOfNames STRUCTURAL class found within an organizationalUnit entry (superior structure rule 21)

DIT structure rules are extremely powerful. When properly planned and implemented, they can greatly aid in the formation of clean and orderly directory structures without the need for additional ACIs.