Location: PHPKode > projects > LDAP Navigator > ldapnavigator-0.9.6/lib/Net/LDAP/Schema.php
<?php

/***

LDAP Schema Component

load schema information from a LDAP server
informations retrieved for now are objectclasses and attributes.

@SYNOPSIS

	$cnx = ldap_connect( "ldap.host.com", 389 );
	$s = new Net_LDAP_schema( $cnx );

	if( ! $s->Read() ) {
		die( "Error: $s->errmsg\n" );
	}
	$info = $s->objectclasses['person'];
	echo "infos about the 'person' objectclass : "; 
	print_r($info);

	$info = $s->attributes['userpassword'];
	echo "infos about the 'userpassword' attribute : "; 
	print_r($info);

@COMPATIBILITY
	Tested against iPlanet-Netscape Directory Server 4.x, openLDAP 2.0.x, Domino/R5 slapd
	
@TODO
	load & parse matchingrules
	read ldapSyntaxes definitions

@AUTHOR
	Leo West <west_leo AT yahoo DOT com>
	
***/

class Net_LDAP_Schema
{
	var 
		$objectclasses,
		$attributes;
			
	function Net_LDAP_Schema( $ldap_cnx )
	{
		$this->cnx = $ldap_cnx;
		// syntax helper
		$this->known_syntaxes = array(
			'1.3.6.1.4.1.1466.115.121.1.5' => "bin",
			'1.3.6.1.4.1.1466.115.121.1.7' => "boolean",
			'1.3.6.1.4.1.1466.115.121.1.12' => 'dn',
			'1.3.6.1.4.1.1466.115.121.1.27' => "int",
			'1.3.6.1.4.1.1466.115.121.1.50' => "tel",
			'1.3.6.1.4.1.1466.115.121.1.26' => "ia5", // aci attribute
		);
		
	}
	
	function Read()
	{
		// get the root informations
		$sr = ldap_read( $this->cnx, "", "objectclass=*", array('subschemasubentry') );
		if( ! $sr ) {
			$this->errmsg = "Can not read schema: reading root DN failed";
			return false;
		}
		$tmp = ldap_get_entries( $this->cnx, $sr );
		$info = $tmp[0];
		if( ! $info['subschemasubentry'] ) {
			$this->errmsg = "Can not read schema: not subschemasubentry attribute in root DN";
			return false;
		}
		$this->schema_dn = $info['subschemasubentry'][0];
		
		// read and store the schema
		$schemaAttributes = array( 'objectClasses', 'attributeTypes', 'matchingRules', 'ldapSyntaxes' );
		$sr = ldap_read( $this->cnx, $this->schema_dn, "objectclass=*", $schemaAttributes );
		if( ! $sr ) {
			$this->errmsg = "Can not read schema: reading schema DN $this->schema_dn failed";
			return false;
		}

		list( $info, ) = ldap_get_entries($this->cnx, $sr );
		$attrSplitRegex = '\s*\$\s*';
//		dump( $info );
		// parse OBJECTCLASSES definitions
		for( $i=0; $i < $info['objectclasses']['count']; $i++ ) {

			$str = $info['objectclasses'][$i];
			$ok = false;
			$oc = array();

			if( preg_match( "|([\d+\.]+) NAME '(.*)'|Ui", $str, $a )) {
				$oc['oid'] = $a[1];
				$oc['name'] = $a[2];
				$ok = true;	
			
			// multiple names TODO : one entry for each or an alias system
			} elseif( preg_match( "|([\d+\.]+) NAME \( ('(.*)' )+\) |Ui", $str, $a )) {
				$oc['oid'] = $a[1];
				$oc['name'] = $a[3];
				$ok = true;
			}
		
			if( preg_match( "|DESC '(.*)'|Ui", $str, $a )) {
				$oc['description'] = $a[1];
			}
			if( preg_match( "|SUP '?(\w+)'?|i", $str, $a )) {
				$oc['superiorClass'] = $a[1];
			}
			if( preg_match( "|MUST\s*\(\s*(.*)\s*\)|Ui", $str, $a )) {
				$atrlist = $a[1];
				$atrs = split( $attrSplitRegex, $atrlist );				
				$oc['requires'] = $atrs;
			}			
			if( preg_match( "|MAY\s*\(\s*(.*)\s*\)|Ui", $str, $a )) {
				$atrlist = $a[1];
				$atrs = split( $attrSplitRegex, $atrlist );
				$oc['allows'] = $atrs;
			}
			if( preg_match( "|STRUCTURAL|", $str )) {
				$oc['type'] = 'structural';
			}elseif( preg_match( "|AUXILIARY|", $str )) {
				$oc['type'] = 'auxiliary';
			}
			
			// add it to our list if ok
			if( $ok ) {
				$key = strtolower($oc['name']);
				$this->objectclasses[$key] = $oc;
			} else {
				echo "Warning: could not read oc definition $str\n";
			}
		}
		
		// parse ATTRIBUTES definitions
		for( $i=0; $i < $info['attributetypes']['count']; $i++ ) {
			$str = $info['attributetypes'][$i];
			$ok = false;
			$attr = array();
			if( preg_match( "|NAME '(.*)'|Ui", $str, $a )) {
				$attr['name'] = $a[1];
				$ok = true;	
			}elseif( preg_match( "|NAME \( ('(.*)' )+\)|Ui", $str, $a )) {
				$attr['name'] = $a[2];
				$ok = true;					
//				echo "multiple attrname for $str\n"; dump( $attr );
			}
			if( preg_match( "|DESC '(.*)'|Ui", $str, $a )) {
				$attr['description'] = $a[1];
			}
			if( preg_match( "|SYNTAX '(.*)'|Ui", $str, $a )) {			
				$attr['syntax'] = $a[1];
				if( $this->known_syntaxes[$attr['syntax']] ) {
					$attr['type'] = $this->known_syntaxes[$attr['syntax']];
				}
			}
			if( preg_match( "|SINGLE-VALUE|Ui", $str )) {
				$attr['single-value'] = true;
			}
			// add it to our list if ok
			if( $ok ) {
				$this->attributes[strtolower($attr['name'])] = $attr;
			} else {
				echo "Warning: could not read attribute definition $str\n";
			}
		}
//		echo "<pre>"; print_r($info); echo "</pre>";
				
		ldap_free_result( $sr );		
		return true;
	}
	

}

	/*
	SYNTAXES LIST (RFC2252)
	'1.3.6.1.4.1.1466.115.121.1.3' => "Attribute Type Description"
	'1.3.6.1.4.1.1466.115.121.1.5' => "Binary syntax"
	'1.3.6.1.4.1.1466.115.121.1.6' => "Bit string syntax"
	'1.3.6.1.4.1.1466.115.121.1.7' => "Boolean syntax"
	'1.3.6.1.4.1.1466.115.121.1.8' => "Certificate syntax"
	'1.3.6.1.4.1.1466.115.121.1.9' => "Certificate List syntax"
	'1.3.6.1.4.1.1466.115.121.1.10' => "Certificate Pair syntax"
	'1.3.6.1.4.1.1466.115.121.1.11' => "Country String syntax"
	'1.3.6.1.4.1.1466.115.121.1.12' => "Distinguished Name syntax"
	'1.3.6.1.4.1.1466.115.121.1.15' => "Directory String syntax"
	'1.3.6.1.4.1.1466.115.121.1.16' => "DIT Content Rule syntax"
	'1.3.6.1.4.1.1466.115.121.1.17' => "DIT Structure Rule Description syntax"
	'1.3.6.1.4.1.1466.115.121.1.22' => "Facsimile Telephone Number syntax"
	'1.3.6.1.4.1.1466.115.121.1.23' => "Fax image syntax"
	'1.3.6.1.4.1.1466.115.121.1.24' => "Generalized Time syntax"
	'1.3.6.1.4.1.1466.115.121.1.26' => "IA5 String syntax"
	'1.3.6.1.4.1.1466.115.121.1.27' => "Integer syntax"
	'1.3.6.1.4.1.1466.115.121.1.28' => "JPeg Image syntax"
	'1.3.6.1.4.1.1466.115.121.1.30' => "Matching Rule Description syntax"
	'1.3.6.1.4.1.1466.115.121.1.31' => "Matching Rule Use Description syntax"
	'1.3.6.1.4.1.1466.115.121.1.33' => "MHS OR Address syntax"
	'1.3.6.1.4.1.1466.115.121.1.34' => "Name and Optional UID syntax"
	'1.3.6.1.4.1.1466.115.121.1.35' => "Name Form syntax"
	'1.3.6.1.4.1.1466.115.121.1.36' => "Numeric String syntax"
	'1.3.6.1.4.1.1466.115.121.1.37' => "Object Class Description syntax"
	'1.3.6.1.4.1.1466.115.121.1.38' => "OID syntax"
	'1.3.6.1.4.1.1466.115.121.1.39' => "Other Mailbox syntax"
	'1.3.6.1.4.1.1466.115.121.1.40' => "Octet String"
	'1.3.6.1.4.1.1466.115.121.1.41' => "Postal Address syntax"
	'1.3.6.1.4.1.1466.115.121.1.43' => "Presentation Address syntax"
	'1.3.6.1.4.1.1466.115.121.1.44' => "Printable string syntax"
	'1.3.6.1.4.1.1466.115.121.1.50' => "Telephone number syntax"
	'1.3.6.1.4.1.1466.115.121.1.53' => "UTCTime syntax"
	'1.3.6.1.4.1.1466.115.121.1.54' => "LDAP Syntax Description syntax"
*/

?>
Return current item: LDAP Navigator