Org Unit OU

Organizational Units (ou=org units,dc=berkeley,dc=edu)

The CalNet Directory includes a complete hierarchical representation of the entire UC Berkeley campus organizational unit structure. This information is publicly available and can be accessed by all anonymous and privileged application binds (accounts) for use in their applications. The Organizational Unit, or "Org Unit" data structure is refreshed nightly from data provided by the Enterprise Data Warehouse (EDW). This data allows applications to grant permissions to or collect information for units on Campus at various levels such as College, Department, or Payroll unit. It will be used when implementing roles information.

Org Unit Entry Structure

The entire Org Unit structure resides in the node ou=org units,dc=berkeley,dc=edu of the CalNet Directory. (see figure 1).

This node is not recognized as part of the campus structure, but merely a container to encapsulate the entire structure within a logically named node/OU.

Applications should use this node as the search-base for all queries. If the entire Org Unit structure needs to be examined from the beginning, recursive searches with scopes of "one" will need to be used in order to not exceed the Directory Search Results Limit.

Please refer to the Programmatically Exploring the Organizational Unit Tree Structure section for more information.

Description

Figure 1: Organizational Unit Hierarchy

Within this top-level 'org units' branch of the Directory resides the ou=UCBKL Campus Root node. This node is the base, or root, of the entire UC Berkeley Organizational Tree. All Berkeley-related organization units are located within the ou=UCBKL Campus Root node.

Because the Org Unit structure is a hierarchy, applications can selectively browse discrete portions of the tree or can recursively traverse the entire structure.

For instance, to find all control units immediately under the ou=UCBKL root node, query the directory using the search-base'ou=UCBKL, ou=org units,dc=berkeley,dc=edu' with a scope of 'one' and the filter '(berkeleyEduOrgUnitParent=UCBKL)'. Or, to find all process units under the control unit ou=VRIST , query the directory using the search-base 'ou=org units,dc=berkeley,dc=edu'with a scope of 'subtree' and the filter '(&(berkeleyEduOrgUnitParent=VRIST)(berkeleyEduOrgUnitProcessUnitFlag=))'*.

Each organizational unit entry in the org-unit structure is based upon the berkeleyEduOrgUnit objectclass and has been designed to make it as easy as possible for applications to target the data they need.

For example, applications can determine whether a particular organizational unit is a "control unit" or a "processing unit" by use of the berkeleyEduOrgUnitProcessUnitFlag attribute.

The berkeleyEduOrgUnitHierarchyString attribute allows applications to determine an organizational unit's position in the overall hierarchy in relation to the campus root node.

The berkeleyEduOrgUnitParent attribute can be used to quickly find the parent units of any organizational unit without having to perform complex string manipulation.

The rest of this document will cover the specifics of the berkeleyEduOrgUnit objectclass and related attributes and includes a few code examples with several sample ldap search filters for convenience.

For more search examples, please refer to the Example Search filters section below

The ou=UCBKL Campus root node

The ou=UCBKL Campus root node is the top node of the organizational unit of the Berkeley Campus and it is the parent of all other campus organizational units. This entry can be located by searching the Directory using either of the following sets of criteria:

searchbase: "ou=org units,dc=berkeley,dc=edu"
scope: "one"
filter: '(objectclass=*)'

or

searchbase: "ou=org units,dc=berkeley,dc=edu"
scope: "subtree"
filter = '(ou=UCBKL)'

Below is an example of the Campus Root Node entry as returned by the Directory:

dn: ou=UCBKL,ou=org units,dc=berkeley,dc=edu
description: UC Berkeley Campus
ou : UCBKL
objectclass = top
objectclass = organizationalunit
objectclass = berkeleyEduOrgUnit
berkeleyEduOrgUnitHierarchyString = UCBKL

The Campus Root node entry does not contain the berkeleyEduOrgUnitParent attribute.

The berkeleyEduOrgUnit objectclass

Each organizational unit entry in the org-unit structure is based upon the berkeleyEduOrgUnit objectclass and has been designed to make it as easy as possible for applications to target the data they need.

Below is the LDAP schema definition of the berkeleyEduOrgUnit objectclass:

objectclass - berkeleyEduOrgUnit

objectClasses: ( 1.3.6.1.4.1.4995.2.600.20.1
NAME 'berkeleyEduOrgUnit'
DESC 'Organizational Units'
SUP organizationalUnit
STRUCTURAL
MAY ( berkeleyEduOrgUnitParent
$ berkeleyEduOrgUnitProcessUnitFlag
$ berkeleyEduOrgUnitHierarchyString
)
X-ORIGIN ('user defined' 'Berkeley.edu University defined') )

The berkeleyEduOrgUnit objectclass is based upon Netscape's standard organizationalUnit LDAP objectclass and extends its functionality with the addition of three new attributes:

Each of these attributes will be explained in detail in subsequent sections.

The berkeleyEduOrgUnitParent attribute

This multi-valued attribute contains the org-unit code for each parent Org Unit associated with in the hierarchy of the a given entry.

For example, let's examine the values of the berkeleyEduOrgUnitParent attribute found in the organizational unit ou=VRIST:

berkeleyEduOrgUnitParent: UCBKL
berkeleyEduOrgUnitParent: AVCIS

The ou=VRIST Org Unit only has two parent entries: ou=UCBKL, which is the Campus Root Node, and ou=AVCIS (Information Sys & Technology) (see figure 1).

Applications should not rely on the order that values from a multi-valued attribute are returned. There is no guarantee that the middleware used to enable LDAP support in any application will preserve the order of multi-values returned by an LDAP server.

The berkeleyEduOrgUnitProcessUnitFlag attribute

Every node under the root node is either a "Control Unit" or a "Process Unit." This can be determined by examining the 'berkeleyEduOrgUnitProcessUnitFlag' attribute:

berkeleyEduOrgUnitProcessUnitFlag: true

If 'berkeleyEduOrgUnitProcessUnitFlag' attribute is defined and set with a value of 'true,' the entry/node is a "Process Unit."

The berkeleyEduOrgUnitHierarchyString attribute

This single-valued attribute contains the entire ou hierarchy of an Org Unit, expressed in terms of a single string.

For example, let's examine the value of the berkeleyEduOrgUnitHierarchyString attribute found in the organizational unit ou=JICCS:

berkeleyEduOrgUnitHierarchyString: UCBKL-AVCIS-VRIST-JICCS

The Org Unit ou=JICCS is located three levels beneath the Campus Root Node (UCBKL). Notice that the hierarchy string preserves the exact order the hierarchy (unlike the berkeleyEduOrgUnitParent attribute).

This allows applications to easily determine the immediate parent of any Org Unit. In the above example, we see that ou=VRIST is the parent of ou=JICCS

Example of a Process Unit entry

Using Ldap Filter:

'(ou=JICCS)'

dn: ou=JICCS,ou=VRIST,ou=AVCIS,ou=UCBKL,ou=ou=org units,dc=berkeley,dc=edu
description: Central Computing Services
ou: JICCS
berkeleyEduOrgUnitProcessUnitFlag: 1
berkeleyEduOrgUnitParent: UCBKL
berkeleyEduOrgUnitParent: AVCIS
berkeleyEduOrgUnitParent: VRIST
berkeleyEduOrgUnitHierarchyString: UCBKL-AVCIS-VRIST-JICCS
objectclass: top
objectclass: organizationalunit
objectclass: berkeleyEduOrgUnit

Example of a Control Unit entry

Using Ldap Filter:

'(ou= VRIST)'

dn: ou=VRIST,ou=AVCIS,ou=UCBKL,ou=ou=org units,dc=berkeley,dc=edu
description: Info Systems & Technology
ou: VRIST
objectclass: top
objectclass: organizationalunit
objectclass: berkeleyEduOrgUnit
berkeleyEduOrgUnitParent: UCBKL
berkeleyEduOrgUnitParent: AVCIS
berkeleyEduOrgUnitHierarchyString: UCBKL-AVCIS-VRIST

Directory Search Results Limit

In an effort to limit "email harvesting," the CalNet Directory will not return search results to any query that results in more than 500 entries. Thus, a query for all control units under the root node using the filter '(berkeleyEduOrgUnitParent=UCBKL)' with a scope of 'subtree' and a search-base of 'ou=org units,dc=berkeley,dc=edu', though valid, would fail since there are more then 500 control-units under the Campus Root Node. Applications that need to explore the entire tree will need to perform a series of smaller recursive-like queries, rather then a single large query.

Please refer to the Programmatic Exploration the Organizational Unit Tree Structure section for more information.

Programmatic Exploration of the Organizational Unit Tree Structure

As previously noted, the CalNet Directory will not return search results to any query that results in more than 500 entries. Under this restriction, applications will need to be careful in the manner in which they search the org-unit hierarchy.

Included below is a sample PERL script that demonstrates how to recursively browse the entire Org Unit structure without exceeding the directory search-result limit.

#!/bin/perl
 
use Mozilla::LDAP::Conn;
 
$LDAPSRVR         = 'caldir.berkeley.edu';
$LDAPPORT         = '389';
$LDAP_SEARCH_BASE = 'ou=UCBKL,ou=Org Units,dc=berkeley,dc=edu';
 
 
$conn = new Mozilla::LDAP::Conn($LDAPSRVR,$LDAPPORT,'','');
die "Couldn't connect to LDAP server $LDAPSRVR" unless ($conn);
 
 
# initial call to recursive search function.
#   searching will begin at the Campus Root Node, which
#   is passed into the function as a required parameter.
&traverse_org_unit($LDAP_SEARCH_BASE);
 
exit(0);
 
 
##############################################################################
sub traverse_org_unit()
##############################################################################
{
  my ($start_dn) = @_;
   
  my ($entry, $dn, $ldap_scope, $filter, $dn) = "";
  my (@dns@attributes) = ();
   
   
  @attributes = ( "ou" );
  $ldap_scope = "one";
  $filter = "(ou=*)";
   
  # search the directory for all entries 1-level
  # beneath the $start_dn
  $entry = $conn->search($start_dn, $ldap_scope, $filter, 0@attributes);
   
  if (! $entry)
  {
    # No child org-units found
  }
  else
  {
    while ($entry)
    {
      # fetch the DN for each entry found,
      # and push it onto the dns array.
      $dn = $entry->getDN();
      push (@dns,$dn);
       
      print "Org-Unit: $dn\n";
 
      $entry = $conn->nextEntry();
    }
  }
 
  # recursively call self using each dn in dns array
  # as the parameter
  foreach $dn (@dns)
  {
    &traverse_org_unit($dn)
  }
   
}

Example Search Filters and Settings

To search for...

search-base

scope

filter

all Process Units:

ou=org units,dc=berkeley,dc=edu

subtree

(berkeleyEduOrgUnitProcessUnitFlag=*)

all Units under Control Unit 'VPUEI':

ou=org units,dc=berkeley,dc=edu

subtree

(berkeleyEduOrgUnitParent=VPUEI)

all Process Units under Control Unit 'VRIST':

ou=org units,dc=berkeley,dc=edu

subtree

(&(berkeleyEduOrgUnitParent=VRIST)(berkeleyEduOrgUnitProcessUnitFlag=*))

all Control Units under Control Unit 'VRIST':

ou=org units,dc=berkeley,dc=edu

subtree

(&(berkeleyEduOrgUnitParent=VRIST)(!(berkeleyEduOrgUnitProcessUnitFlag=*)))

all Units directly beneath Control Unit 'VRIST':

ou=VRIST,ou=AVCIS,ou=UCBKL,ou=org units,dc=berkeley,dc=edu

one

(objectclass=*)