⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.78
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-pear
/
pear
/
php
/
Horde
/
Ldap
/
Edit File: Schema.php
<?php /** * 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. * * Copyright 2009 Jan Wagner, Benedikt Hallinger * Copyright 2010-2017 Horde LLC (http://www.horde.org/) * * @category Horde * @package Ldap * @author Jan Wagner <wagner@netsols.de> * @author Benedikt Hallinger <beni@php.net> * @author Jan Schneider <jan@horde.org> * @license http://www.gnu.org/licenses/lgpl-3.0.html LGPL-3.0 */ class Horde_Ldap_Schema { /** * Syntax definitions. * * Please don't forget to add binary attributes to isBinary() below to * support proper value fetching from Horde_Ldap_Entry. */ const SYNTAX_BOOLEAN = '1.3.6.1.4.1.1466.115.121.1.7'; const SYNTAX_DIRECTORY_STRING = '1.3.6.1.4.1.1466.115.121.1.15'; const SYNTAX_DISTINGUISHED_NAME = '1.3.6.1.4.1.1466.115.121.1.12'; const SYNTAX_INTEGER = '1.3.6.1.4.1.1466.115.121.1.27'; const SYNTAX_JPEG = '1.3.6.1.4.1.1466.115.121.1.28'; const SYNTAX_NUMERIC_STRING = '1.3.6.1.4.1.1466.115.121.1.36'; const SYNTAX_OID = '1.3.6.1.4.1.1466.115.121.1.38'; const SYNTAX_OCTET_STRING = '1.3.6.1.4.1.1466.115.121.1.40'; /** * Map of entry types to LDAP attributes of subschema entry. * * @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 * * @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. * * @var array */ protected $_oids = array(); /** * Whether the schema is initialized. * * @see parse(), get() * @var boolean */ protected $_initialized = false; /** * Constructor. * * Fetches the Schema from an LDAP connection. * * @param Horde_Ldap $ldap LDAP connection. * @param string $dn Subschema entry DN. * * @throws Horde_Ldap_Exception */ public function __construct(Horde_Ldap $ldap, $dn = null) { if (is_null($dn)) { // Get the subschema entry via rootDSE. $dse = $ldap->rootDSE(array('subschemaSubentry')); $base = $dse->getValue('subschemaSubentry', 'single'); $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 rootDSE. $dse = $ldap->rootDSE(array('subSchemaSubentry')); $base = $dse->getValue('subSchemaSubentry', 'single'); $dn = $base; } // Final fallback in case there is no subschemaSubentry attribute in // the root DSE (this is a bug for an LDAPv3 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($this->types), 'scope' => 'base')); $entry = $result->shiftEntry(); if (!($entry instanceof Horde_Ldap_Entry)) { throw new Horde_Ldap_Exception('Could not fetch Subschema entry'); } $this->parse($entry); } /** * Returns a hash of entries for the given type. * * Types may be: objectclasses, attributes, ditcontentrules, * ditstructurerules, matchingrules, matchingruleuses, nameforms, syntaxes. * * @param string $type Type to fetch. * * @return array * @throws Horde_Ldap_Exception */ 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 = Horde_String::lower($type); if (!isset($map[$key])) { throw new Horde_Ldap_Exception("Unknown type $type"); } return $map[$key]; } /** * Returns a specific entry. * * @param string $type Type of name. * @param string $name Name or OID to fetch. * * @return mixed * @throws Horde_Ldap_Exception */ public function get($type, $name) { if (!$this->_initialized) { return null; } $type = Horde_String::lower($type); if (!isset($this->types[$type])) { throw new Horde_Ldap_Exception("No such type $type"); } $name = Horde_String::lower($name); $type_var = $this->{'_' . $this->types[$type]}; if (isset($type_var[$name])) { return $type_var[$name]; } if (isset($this->_oids[$name]) && $this->_oids[$name]['type'] == $type) { return $this->_oids[$name]; } throw new Horde_Ldap_Exception("Could not find $type $name"); } /** * Fetches attributes that MAY be present in the given objectclass. * * @param string $oc Name or OID of objectclass. * @param boolean $checksup Check all superiour objectclasses too? * * @return array Array with attributes. */ public function may($oc, $checksup = false) { try { $attributes = $this->_getAttr($oc, 'may'); } catch (Horde_Ldap_Exception $e) { $attributes = array(); } if ($checksup) { try { foreach ($this->superclass($oc) as $sup) { $attributes = array_merge($attributes, $this->may($sup, true)); } } catch (Horde_Ldap_Exception $e) { } $attributes = array_values(array_unique($attributes)); } return $attributes; } /** * Fetches attributes that MUST be present in the given objectclass. * * @param string $oc Name or OID of objectclass. * @param boolean $checksup Check all superiour objectclasses too? * * @return array Array with attributes. */ public function must($oc, $checksup = false) { try { $attributes = $this->_getAttr($oc, 'must'); } catch (Horde_Ldap_Exception $e) { $attributes = array(); } if ($checksup) { try { foreach ($this->superclass($oc) as $sup) { $attributes = array_merge($attributes, $this->must($sup, true)); } } catch (Horde_Ldap_Exception $e) { } $attributes = array_values(array_unique($attributes)); } return $attributes; } /** * 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 The attribute. * @throws Horde_Ldap_Exception */ protected function _getAttr($oc, $attr) { $oc = Horde_String::lower($oc); if (isset($this->_objectClasses[$oc]) && isset($this->_objectClasses[$oc][$attr])) { return $this->_objectClasses[$oc][$attr]; } if (isset($this->_oids[$oc]) && $this->_oids[$oc]['type'] == 'objectclass' && isset($this->_oids[$oc][$attr])) { return $this->_oids[$oc][$attr]; } throw new Horde_Ldap_Exception("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 * @throws Horde_Ldap_Exception */ public function superclass($oc) { $o = $this->get('objectclass', $oc); return isset($o['sup']) ? $o['sup'] : array(); } /** * Parses the schema of the given subschema entry. * * @param Horde_Ldap_Entry $entry Subschema entry. */ public function parse($entry) { foreach ($this->types as $type => $attr) { // Initialize map type to entry. $type_var = '_' . $attr; $this->{$type_var} = array(); if (!$entry->exists($attr)) { continue; } // Get values for this type. $values = $entry->getValue($attr); if (!is_array($values)) { continue; } foreach ($values as $value) { // 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']; $names[] = $schema_entry['name']; foreach ($names as $name) { $this->{$type_var}[Horde_String::lower($name)] = $schema_entry; } } } $this->_initialized = true; } /** * Parses an attribute value into a schema entry. * * @param string $value Attribute value. * * @return array Schema entry array. */ 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'); // Get an array of tokens. $tokens = $this->_tokenize($value); // Remove surrounding brackets. if ($tokens[0] == '(') { array_shift($tokens); } if ($tokens[count($tokens) - 1] == ')') { array_pop($tokens); } // First token is the oid. $schema_entry = array('aliases' => array(), 'oid' => array_shift($tokens)); // Cycle over the tokens until none are left. while (count($tokens) > 0) { $token = Horde_String::lower(array_shift($tokens)); if (in_array($token, $noValue)) { // Single value token. $schema_entry[$token] = 1; } else { // Follow a string or a list if it is multivalued. if (($schema_entry[$token] = array_shift($tokens)) == '(') { // Create 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 != '$') { $schema_entry[$token][] = $tmp; } } } // Create an 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 (isset($schema_entry['syntax'])) { 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. * * @return array Array of tokens. */ protected function _tokenize($value) { /* Match one big pattern where only one of the three subpatterns * matches. 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("/\s* (?:([()]) | ([^'\s()]+) | '((?:[^']+|'[^\s)])*)') \s*/x", $value, $matches); $tokens = array(); // Number of tokens (full pattern match). for ($i = 0, $c = count($matches[0]); $i < $c; $i++) { // Each subpattern. for ($j = 1; $j < 4; $j++) { // Pattern match in this subpattern. if (null != trim($matches[$j][$i])) { // This is the token. $tokens[$i] = trim($matches[$j][$i]); } } } return $tokens; } /** * Returns wether a attribute syntax is binary or not. * * This method is used by Horde_Ldap_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'). * * @return boolean True if the attribute is a binary type. */ public function isBinary($attribute) { // All syntax that should be treaten as containing binary values. $syntax_binary = array(self::SYNTAX_OCTET_STRING, self::SYNTAX_JPEG); // Check Syntax. try { $attr_s = $this->get('attribute', $attribute); } catch (Horde_Ldap_Exception $e) { // Attribute not found in schema, consider attr not binary. return false; } if (isset($attr_s['syntax']) && in_array($attr_s['syntax'], $syntax_binary)) { // Syntax is defined as binary in schema return true; } // 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) { if ($this->isBinary($superattr)) { // Stop checking parents since we are binary. return true; } } } return false; } }
Simpan