summaryrefslogtreecommitdiff
path: root/extlib/Net/LDAP2/Schema.php
diff options
context:
space:
mode:
Diffstat (limited to 'extlib/Net/LDAP2/Schema.php')
-rw-r--r--extlib/Net/LDAP2/Schema.php516
1 files changed, 0 insertions, 516 deletions
diff --git a/extlib/Net/LDAP2/Schema.php b/extlib/Net/LDAP2/Schema.php
deleted file mode 100644
index b590eabc5..000000000
--- a/extlib/Net/LDAP2/Schema.php
+++ /dev/null
@@ -1,516 +0,0 @@
-<?php
-/* vim: set expandtab tabstop=4 shiftwidth=4: */
-/**
-* File containing the Net_LDAP2_Schema interface class.
-*
-* PHP version 5
-*
-* @category Net
-* @package Net_LDAP2
-* @author Jan Wagner <wagner@netsols.de>
-* @author Benedikt Hallinger <beni@php.net>
-* @copyright 2009 Jan Wagner, Benedikt Hallinger
-* @license http://www.gnu.org/licenses/lgpl-3.0.txt LGPLv3
-* @version SVN: $Id: Schema.php 286718 2009-08-03 07:30:49Z beni $
-* @link http://pear.php.net/package/Net_LDAP2/
-* @todo see the comment at the end of the file
-*/
-
-/**
-* Includes
-*/
-require_once 'PEAR.php';
-
-/**
-* Syntax definitions
-*
-* Please don't forget to add binary attributes to isBinary() below
-* to support proper value fetching from Net_LDAP2_Entry
-*/
-define('NET_LDAP2_SYNTAX_BOOLEAN', '1.3.6.1.4.1.1466.115.121.1.7');
-define('NET_LDAP2_SYNTAX_DIRECTORY_STRING', '1.3.6.1.4.1.1466.115.121.1.15');
-define('NET_LDAP2_SYNTAX_DISTINGUISHED_NAME', '1.3.6.1.4.1.1466.115.121.1.12');
-define('NET_LDAP2_SYNTAX_INTEGER', '1.3.6.1.4.1.1466.115.121.1.27');
-define('NET_LDAP2_SYNTAX_JPEG', '1.3.6.1.4.1.1466.115.121.1.28');
-define('NET_LDAP2_SYNTAX_NUMERIC_STRING', '1.3.6.1.4.1.1466.115.121.1.36');
-define('NET_LDAP2_SYNTAX_OID', '1.3.6.1.4.1.1466.115.121.1.38');
-define('NET_LDAP2_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.
-*
-* @category Net
-* @package Net_LDAP2
-* @author Jan Wagner <wagner@netsols.de>
-* @author Benedikt Hallinger <beni@php.net>
-* @license http://www.gnu.org/copyleft/lesser.html LGPL
-* @link http://pear.php.net/package/Net_LDAP22/
-*/
-class Net_LDAP2_Schema extends PEAR
-{
- /**
- * Map of entry types to ldap attributes of subschema entry
- *
- * @access public
- * @var array
- */
- public $types = array(
- 'attribute' => 'attributeTypes',
- 'ditcontentrule' => 'dITContentRules',
- 'ditstructurerule' => 'dITStructureRules',
- 'matchingrule' => 'matchingRules',
- 'matchingruleuse' => 'matchingRuleUse',
- 'nameform' => 'nameForms',
- 'objectclass' => 'objectClasses',
- 'syntax' => 'ldapSyntaxes'
- );
-
- /**
- * Array of entries belonging to this type
- *
- * @access protected
- * @var array
- */
- protected $_attributeTypes = array();
- protected $_matchingRules = array();
- protected $_matchingRuleUse = array();
- protected $_ldapSyntaxes = array();
- protected $_objectClasses = array();
- protected $_dITContentRules = array();
- protected $_dITStructureRules = array();
- protected $_nameForms = array();
-
-
- /**
- * hash of all fetched oids
- *
- * @access protected
- * @var array
- */
- protected $_oids = array();
-
- /**
- * Tells if the schema is initialized
- *
- * @access protected
- * @var boolean
- * @see parse(), get()
- */
- protected $_initialized = false;
-
-
- /**
- * Constructor of the class
- *
- * @access protected
- */
- protected function __construct()
- {
- $this->PEAR('Net_LDAP2_Error'); // default error class
- }
-
- /**
- * Fetch the Schema from an LDAP connection
- *
- * @param Net_LDAP2 $ldap LDAP connection
- * @param string $dn (optional) Subschema entry dn
- *
- * @access public
- * @return Net_LDAP2_Schema|NET_LDAP2_Error
- */
- public function fetch($ldap, $dn = null)
- {
- if (!$ldap instanceof Net_LDAP2) {
- return PEAR::raiseError("Unable to fetch Schema: Parameter \$ldap must be a Net_LDAP2 object!");
- }
-
- $schema_o = new Net_LDAP2_Schema();
-
- if (is_null($dn)) {
- // get the subschema entry via root dse
- $dse = $ldap->rootDSE(array('subschemaSubentry'));
- if (false == Net_LDAP2::isError($dse)) {
- $base = $dse->getValue('subschemaSubentry', 'single');
- if (!Net_LDAP2::isError($base)) {
- $dn = $base;
- }
- }
- }
-
- // 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.
- if (is_null($dn)) {
- // get the subschema entry via root dse
- $dse = $ldap->rootDSE(array('subSchemaSubentry'));
- if (false == Net_LDAP2::isError($dse)) {
- $base = $dse->getValue('subSchemaSubentry', 'single');
- if (!Net_LDAP2::isError($base)) {
- $dn = $base;
- }
- }
- }
-
- // 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).
- if (is_null($dn)) {
- $dn = 'cn=Subschema';
- }
-
- // fetch the subschema entry
- $result = $ldap->search($dn, '(objectClass=*)',
- array('attributes' => array_values($schema_o->types),
- 'scope' => 'base'));
- if (Net_LDAP2::isError($result)) {
- return $result;
- }
-
- $entry = $result->shiftEntry();
- if (!$entry instanceof Net_LDAP2_Entry) {
- return PEAR::raiseError('Could not fetch Subschema entry');
- }
-
- $schema_o->parse($entry);
- return $schema_o;
- }
-
- /**
- * 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
- *
- * @access public
- * @return array|Net_LDAP2_Error Array or Net_LDAP2_Error
- */
- public function &getAll($type)
- {
- $map = array('objectclasses' => &$this->_objectClasses,
- 'attributes' => &$this->_attributeTypes,
- 'ditcontentrules' => &$this->_dITContentRules,
- 'ditstructurerules' => &$this->_dITStructureRules,
- 'matchingrules' => &$this->_matchingRules,
- 'matchingruleuses' => &$this->_matchingRuleUse,
- 'nameforms' => &$this->_nameForms,
- 'syntaxes' => &$this->_ldapSyntaxes );
-
- $key = strtolower($type);
- $ret = ((key_exists($key, $map)) ? $map[$key] : PEAR::raiseError("Unknown type $type"));
- return $ret;
- }
-
- /**
- * Return a specific entry
- *
- * @param string $type Type of name
- * @param string $name Name or OID to fetch
- *
- * @access public
- * @return mixed Entry or Net_LDAP2_Error
- */
- public function &get($type, $name)
- {
- if ($this->_initialized) {
- $type = strtolower($type);
- if (false == key_exists($type, $this->types)) {
- return PEAR::raiseError("No such type $type");
- }
-
- $name = strtolower($name);
- $type_var = &$this->{'_' . $this->types[$type]};
-
- if (key_exists($name, $type_var)) {
- return $type_var[$name];
- } elseif (key_exists($name, $this->_oids) && $this->_oids[$name]['type'] == $type) {
- return $this->_oids[$name];
- } else {
- return PEAR::raiseError("Could not find $type $name");
- }
- } else {
- $return = null;
- return $return;
- }
- }
-
-
- /**
- * Fetches attributes that MAY be present in the given objectclass
- *
- * @param string $oc Name or OID of objectclass
- *
- * @access public
- * @return array|Net_LDAP2_Error Array with attributes or Net_LDAP2_Error
- */
- public function may($oc)
- {
- return $this->_getAttr($oc, 'may');
- }
-
- /**
- * Fetches attributes that MUST be present in the given objectclass
- *
- * @param string $oc Name or OID of objectclass
- *
- * @access public
- * @return array|Net_LDAP2_Error Array with attributes or Net_LDAP2_Error
- */
- public function must($oc)
- {
- return $this->_getAttr($oc, 'must');
- }
-
- /**
- * Fetches the given attribute from the given objectclass
- *
- * @param string $oc Name or OID of objectclass
- * @param string $attr Name of attribute to fetch
- *
- * @access protected
- * @return array|Net_LDAP2_Error The attribute or Net_LDAP2_Error
- */
- protected function _getAttr($oc, $attr)
- {
- $oc = strtolower($oc);
- if (key_exists($oc, $this->_objectClasses) && key_exists($attr, $this->_objectClasses[$oc])) {
- return $this->_objectClasses[$oc][$attr];
- } elseif (key_exists($oc, $this->_oids) &&
- $this->_oids[$oc]['type'] == 'objectclass' &&
- key_exists($attr, $this->_oids[$oc])) {
- return $this->_oids[$oc][$attr];
- } else {
- 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
- *
- * @access public
- * @return array|Net_LDAP2_Error Array of names or Net_LDAP2_Error
- */
- public function superclass($oc)
- {
- $o = $this->get('objectclass', $oc);
- if (Net_LDAP2::isError($o)) {
- return $o;
- }
- return (key_exists('sup', $o) ? $o['sup'] : array());
- }
-
- /**
- * Parses the schema of the given Subschema entry
- *
- * @param Net_LDAP2_Entry &$entry Subschema entry
- *
- * @access public
- * @return void
- */
- public function parse(&$entry)
- {
- foreach ($this->types as $type => $attr) {
- // initialize map type to entry
- $type_var = '_' . $attr;
- $this->{$type_var} = array();
-
- // get values for this type
- if ($entry->exists($attr)) {
- $values = $entry->getValue($attr);
- if (is_array($values)) {
- foreach ($values as $value) {
-
- unset($schema_entry); // this was a real mess without it
-
- // get the schema entry
- $schema_entry = $this->_parse_entry($value);
-
- // set the type
- $schema_entry['type'] = $type;
-
- // save a ref in $_oids
- $this->_oids[$schema_entry['oid']] = &$schema_entry;
-
- // save refs for all names in type map
- $names = $schema_entry['aliases'];
- array_push($names, $schema_entry['name']);
- foreach ($names as $name) {
- $this->{$type_var}[strtolower($name)] = &$schema_entry;
- }
- }
- }
- }
- }
- $this->_initialized = true;
- }
-
- /**
- * Parses an attribute value into a schema entry
- *
- * @param string $value Attribute value
- *
- * @access protected
- * @return array|false Schema entry array or false
- */
- protected function &_parse_entry($value)
- {
- // tokens that have no value associated
- $noValue = array('single-value',
- 'obsolete',
- 'collective',
- 'no-user-modification',
- 'abstract',
- 'structural',
- 'auxiliary');
-
- // 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[0] == '(') array_shift($tokens);
- 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) {
- $token = strtolower(array_shift($tokens));
- if (in_array($token, $noValue)) {
- $schema_entry[$token] = 1; // single value token
- } else {
- // 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();
- while ($tmp = array_shift($tokens)) {
- if ($tmp == ')') break;
- if ($tmp != '$') array_push($schema_entry[$token], $tmp);
- }
- }
- // create a array if the value should be multivalued but was not
- if (in_array($token, $multiValue) && !is_array($schema_entry[$token])) {
- $schema_entry[$token] = array($schema_entry[$token]);
- }
- }
- }
- // get max length from syntax
- if (key_exists('syntax', $schema_entry)) {
- if (preg_match('/{(\d+)}/', $schema_entry['syntax'], $matches)) {
- $schema_entry['max_length'] = $matches[1];
- }
- }
- // force a name
- if (empty($schema_entry['name'])) {
- $schema_entry['name'] = $schema_entry['oid'];
- }
- // make one name the default and put the other ones into aliases
- if (is_array($schema_entry['name'])) {
- $aliases = $schema_entry['name'];
- $schema_entry['name'] = array_shift($aliases);
- $schema_entry['aliases'] = $aliases;
- }
- return $schema_entry;
- }
-
- /**
- * Tokenizes the given value into an array of tokens
- *
- * @param string $value String to parse
- *
- * @access protected
- * @return array Array of tokens
- */
- protected function _tokenize($value)
- {
- $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
- * enclosed by '
- */
- preg_match_all($pattern, $value, $matches);
-
- 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
- }
- }
- }
- return $tokens;
- }
-
- /**
- * 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')
- *
- * @access public
- * @return boolean
- */
- public function isBinary($attribute)
- {
- $return = false; // default to false
-
- // 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
- $syntax_binary = array(
- NET_LDAP2_SYNTAX_OCTET_STRING,
- NET_LDAP2_SYNTAX_JPEG
- );
-
- // Check Syntax
- $attr_s = $this->get('attribute', $attribute);
- if (Net_LDAP2::isError($attr_s)) {
- // Attribute not found in schema
- $return = false; // consider attr not binary
- } elseif (isset($attr_s['syntax']) && in_array($attr_s['syntax'], $syntax_binary)) {
- // Syntax is defined as binary in schema
- $return = true;
- } else {
- // Syntax not defined as binary, or not found
- // if attribute is a subtype, check superior attribute syntaxes
- if (isset($attr_s['sup'])) {
- foreach ($attr_s['sup'] as $superattr) {
- $return = $this->isBinary($superattr);
- if ($return) {
- break; // stop checking parents since we are binary
- }
- }
- }
- }
-
- return $return;
- }
-
- // [TODO] add method that allows us to see to which objectclasses a certain attribute belongs to
- // it should return the result structured, e.g. sorted in "may" and "must". Optionally it should
- // be able to return it just "flat", e.g. array_merge()d.
- // We could use get_all() to achieve this easily, i think
-}
-?>