Source for file Schema.php
Documentation is available at Schema.php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
* Please don't forget to add binary attributes to isBinary() below
* to support proper value fetching from Net_LDAP2_Entry
define('NET_LDAP_SYNTAX_BOOLEAN', '1.3.6.1.4.1.1466.115.121.1.7');
define('NET_LDAP_SYNTAX_DIRECTORY_STRING', '1.3.6.1.4.1.1466.115.121.1.15');
define('NET_LDAP_SYNTAX_DISTINGUISHED_NAME', '1.3.6.1.4.1.1466.115.121.1.12');
define('NET_LDAP_SYNTAX_INTEGER', '1.3.6.1.4.1.1466.115.121.1.27');
define('NET_LDAP_SYNTAX_JPEG', '1.3.6.1.4.1.1466.115.121.1.28');
define('NET_LDAP_SYNTAX_NUMERIC_STRING', '1.3.6.1.4.1.1466.115.121.1.36');
define('NET_LDAP_SYNTAX_OID', '1.3.6.1.4.1.1466.115.121.1.38');
define('NET_LDAP_SYNTAX_OCTET_STRING', '1.3.6.1.4.1.1466.115.121.1.40');
* Load an LDAP Schema and provide information
* This class takes a Subschema entry, parses this information
* and makes it available in an array. Most of the code has been
* inspired by perl-ldap( http://perl-ldap.sourceforge.net).
* You will find portions of their implementation in here.
* @author Jan Wagner <wagner@netsols.de>
* @author Benedikt Hallinger <beni@php.net>
* @license http://www.gnu.org/copyleft/lesser.html LGPL
* @version CVS: $Id: Schema.php,v 1.2 2008/03/20 09:32:39 beni Exp $
* @link http://pear.php.net/package/Net_LDAP22/
* Map of entry types to ldap attributes of subschema entry
'attribute' => 'attributeTypes',
'ditcontentrule' => 'dITContentRules',
'ditstructurerule' => 'dITStructureRules',
'matchingrule' => 'matchingRules',
'matchingruleuse' => 'matchingRuleUse',
'nameform' => 'nameForms',
'objectclass' => 'objectClasses',
'syntax' => 'ldapSyntaxes'
* Array of entries belonging to this type
* hash of all fetched oids
* Tells if the schema is initialized
* Constructor of the class
$this->PEAR ('Net_LDAP2_Error'); // default error class
* Fetch the Schema from an LDAP connection
* @param Net_LDAP2 LDAP connection
* @param string $dn (optional) Subschema entry dn
* @author Jan Wagner <wagner@netsols.de>
* @return Net_LDAP2_Schema|Net_LDAP_Error
public function fetch(&$ldap, $dn = null ) {
return PEAR ::raiseError ("Unable to fetch Schema: Parameter \$ldap must be a Net_LDAP2 object!");
// get the subschema entry via root dse
$dse = $ldap->rootDSE (array ('subschemaSubentry'));
$base = $dse->getValue ('subschemaSubentry', 'single');
// Support for buggy LDAP servers (e.g. Siemens DirX 6.x) that incorrectly
// call this entry subSchemaSubentry instead of subschemaSubentry.
// Note the correct case/spelling as per RFC 2251.
// get the subschema entry via root dse
$dse = $ldap->rootDSE (array ('subSchemaSubentry'));
$base = $dse->getValue ('subSchemaSubentry', 'single');
// Final fallback case where there is no subschemaSubentry attribute
// in the root DSE (this is a bug for an LDAP v3 server so report this
// to your LDAP vendor if you get this far).
// fetch the subschema entry
$result = $ldap->search ($dn, '(objectClass=*)',
$entry = $result->shiftEntry ();
return PEAR ::raiseError ('Could not fetch Subschema entry');
$schema_o->parse ($entry);
* Return a hash of entries for the given type
* Returns a hash of entry for th givene type. Types may be:
* objectclasses, attributes, ditcontentrules, ditstructurerules, matchingrules,
* matchingruleuses, nameforms, syntaxes
* @param string $type Type to fetch
* @return array|Net_LDAP2_ErrorArray or Net_LDAP2_Error
public function &getAll($type)
$ret = ((key_exists($key, $map)) ? $map[$key] : PEAR ::raiseError (" Unknown type $type" ));
* Return a specific entry
* @param string $type Type of name
* @param string $name Name or OID to fetch
* @return mixed Entry or Net_LDAP2_Error
public function &get($type, $name)
return PEAR ::raiseError (" No such type $type" );
$type_var = &$this->{'_' . $this->types[$type]};
return $this->_oids[$name];
return PEAR ::raiseError (" Could not find $type $name" );
* Fetches attributes that MAY be present in the given objectclass
* @param string $oc Name or OID of objectclass
* @return array|Net_LDAP2_ErrorArray with attributes or Net_LDAP2_Error
* Fetches attributes that MUST be present in the given objectclass
* @param string $oc Name or OID of objectclass
* @return array|Net_LDAP2_ErrorArray with attributes or Net_LDAP2_Error
public function must($oc)
* Fetches the given attribute from the given objectclass
* @param string $oc Name or OID of objectclass
* @param string $attr Name of attribute to fetch
* @return array|Net_LDAP2_ErrorThe attribute or Net_LDAP2_Error
$this->_oids[$oc]['type'] == 'objectclass' &&
return $this->_oids[$oc][$attr];
return PEAR ::raiseError (" Could not find $attr attributes for $oc " );
* Returns the name(s) of the immediate superclass(es)
* @param string $oc Name or OID of objectclass
* @return array|Net_LDAP2_Error Array of names or Net_LDAP2_Error
$o = $this->get('objectclass', $oc);
return (key_exists('sup', $o) ? $o['sup'] : array ());
* Parses the schema of the given Subschema entry
* @param Net_LDAP2_Entry &$entry Subschema entry
public function parse(&$entry)
foreach ($this->types as $type => $attr) {
// initialize map type to entry
$this->{$type_var} = array ();
// get values for this type
if ($entry->exists ($attr)) {
$values = $entry->getValue ($attr);
foreach ($values as $value) {
unset ($schema_entry); // this was a real mess without it
$schema_entry['type'] = $type;
$this->_oids[$schema_entry['oid']] = &$schema_entry;
// save refs for all names in type map
$names = $schema_entry['aliases'];
foreach ($names as $name) {
$this->{$type_var}[strtolower($name)] = &$schema_entry;
* Parses an attribute value into a schema entry
* @param string $value Attribute value
* @return array|falseSchema entry array or false
// tokens that have no value associated
$noValue = array ('single-value',
// tokens that can have multiple values
$multiValue = array ('must', 'may', 'sup');
$schema_entry = array ('aliases' => array ()); // initilization
$tokens = $this->_tokenize($value); // get an array of tokens
// remove surrounding brackets
if ($tokens[count($tokens) - 1 ] == ')') array_pop($tokens); // -1 doesnt work on arrays :-(
$schema_entry['oid'] = array_shift($tokens); // first token is the oid
// cycle over the tokens until none are left
while (count($tokens) > 0 ) {
$schema_entry[$token] = 1; // single value token
// this one follows a string or a list if it is multivalued
if (($schema_entry[$token] = array_shift($tokens)) == '(') {
// this creates the list of values and cycles through the tokens
// until the end of the list is reached ')'
$schema_entry[$token] = array ();
if ($tmp != '$') array_push($schema_entry[$token], $tmp);
// create a array if the value should be multivalued but was not
$schema_entry[$token] = array ($schema_entry[$token]);
// get max length from syntax
if (preg_match('/{(\d+)}/', $schema_entry['syntax'], $matches)) {
$schema_entry['max_length'] = $matches[1 ];
if (empty ($schema_entry['name'])) {
$schema_entry['name'] = $schema_entry['oid'];
// make one name the default and put the other ones into aliases
$aliases = $schema_entry['name'];
$schema_entry['aliases'] = $aliases;
* Tokenizes the given value into an array of tokens
* @param string $value String to parse
* @return array Array of tokens
$tokens = array (); // array of tokens
$matches = array (); // matches[0] full pattern match, [1,2,3] subpatterns
// this one is taken from perl-ldap, modified for php
$pattern = "/\s* (?:([()]) | ([^'\s()]+) | '((?:[^']+|'[^\s)])*)') \s*/x";
* This one matches one big pattern wherin only one of the three subpatterns matched
* We are interested in the subpatterns that matched. If it matched its value will be
* non-empty and so it is a token. Tokens may be round brackets, a string, or a string
for ($i = 0; $i < count($matches[0 ]); $i++ ) { // number of tokens (full pattern match)
for ($j = 1; $j < 4; $j++ ) { // each subpattern
if (null != trim($matches[$j][$i])) { // pattern match in this subpattern
$tokens[$i] = trim($matches[$j][$i]); // this is the token
* Returns wether a attribute syntax is binary or not
* This method gets used by Net_LDAP2_Entry to decide which
* PHP function needs to be used to fetch the value in the
* proper format (e.g. binary or string)
* @param string $attribute The name of the attribute (eg.: 'sn')
// This list contains all syntax that should be treaten as
// containing binary values
// The Syntax Definitons go into constants at the top of this page
$attr_s = $this->get('attribute', $attribute);
Documentation generated on Mon, 11 Mar 2019 15:17:51 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|