phpldapadmin/lib/schema_functions.php

1861 lines
48 KiB
PHP
Raw Permalink Normal View History

<?php
/**
* Classes and functions for fetching and parsing schema from an LDAP server.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Generic parent class for all schema items. A schema item is
* an ObjectClass, an AttributeBype, a MatchingRule, or a Syntax.
* All schema items have at least two things in common: An OID
* and a description. This class provides an implementation for
* these two data.
*
* @package phpLDAPadmin
* @subpackage Schema
*/
abstract class SchemaItem {
# The schema item's name.
protected $name = null;
# The OID of this schema item.
private $oid = null;
# The description of this schema item.
protected $description = null;
# Boolean value indicating whether this objectClass is obsolete
private $is_obsolete = false;
public function setOID($oid) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->oid = $oid;
}
public function setDescription($desc) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->description = $desc;
}
public function getOID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->oid);
}
return $this->oid;
}
public function getDescription() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->description);
}
return $this->description;
}
/**
* Gets whether this objectClass is flagged as obsolete by the LDAP server.
*/
public function getIsObsolete() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->is_obsolete);
}
return $this->is_obsolete;
}
/**
* Return the objects name.
*
* param boolean $lower Return the name in lower case (default)
2019-02-12 14:52:01 -05:00
* @param bool $lower
* @return string The name
*/
public function getName($lower=true) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->name);
}
return $lower ? strtolower($this->name) : $this->name;
}
}
/**
* Represents an LDAP objectClass
*
* @package phpLDAPadmin
* @subpackage Schema
*/
class ObjectClass extends SchemaItem {
# The server ID that this objectclass belongs to.
private $server_id = null;
# Array of objectClass names from which this objectClass inherits
private $sup_classes = array();
# One of STRUCTURAL, ABSTRACT, or AUXILIARY
private $type;
# Arrays of attribute names that this objectClass requires
private $must_attrs = array();
# Arrays of attribute names that this objectClass allows, but does not require
private $may_attrs = array();
# Arrays of attribute names that this objectClass has been forced to MAY attrs, due to configuration
private $force_may = array();
# Array of objectClasses which inherit from this one (must be set at runtime explicitly by the caller)
private $children_objectclasses = array();
# The objectclass hierarchy
private $hierarchy = array();
/**
* Creates a new ObjectClass object given a raw LDAP objectClass string.
2019-02-12 14:52:01 -05:00
* @param $class
* @param $server
*/
public function __construct($class,$server) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->server_id = $server->getIndex();
$this->type = $server->getValue('server','schema_oclass_default');
$strings = preg_split('/[\s,]+/',$class,-1,PREG_SPLIT_DELIM_CAPTURE);
$str_count = count($strings);
for ($i=0; $i < $str_count; $i++) {
switch ($strings[$i]) {
case '(':
break;
case 'NAME':
if ($strings[$i+1]!='(') {
do {
$i++;
if (strlen($this->name) == 0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match('/\'$/s',$strings[$i]));
} else {
$i++;
do {
$i++;
if (strlen($this->name) == 0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match('/\'$/s',$strings[$i]));
do {
$i++;
} while (! preg_match('/\)+\)?/',$strings[$i]));
}
$this->name = preg_replace('/^\'/','',$this->name);
$this->name = preg_replace('/\'$/','',$this->name);
if (DEBUG_ENABLED)
{
debug_log('Case NAME returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->name);
}
break;
case 'DESC':
do {
$i++;
if (strlen($this->description) == 0)
{
$this->description .= $strings[$i];
}
else
{
$this->description = $this->description . ' ' . $strings[$i];
}
} while (! preg_match('/\'$/s',$strings[$i]));
if (DEBUG_ENABLED)
{
debug_log('Case DESC returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->description);
}
break;
case 'OBSOLETE':
$this->is_obsolete = TRUE;
if (DEBUG_ENABLED)
{
debug_log('Case OBSOLETE returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->is_obsolete);
}
break;
case 'SUP':
if ($strings[$i+1] != '(') {
$i++;
2019-02-12 15:23:38 -05:00
$this->sup_classes[] = preg_replace("/'/", '', $strings[$i]);
} else {
$i++;
do {
$i++;
if ($strings[$i] != '$')
{
2019-02-12 15:23:38 -05:00
$this->sup_classes[] = preg_replace("/'/", '', $strings[$i]);
}
} while (! preg_match('/\)+\)?/',$strings[$i+1]));
}
if (DEBUG_ENABLED)
{
debug_log('Case SUP returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->sup_classes);
}
break;
case 'ABSTRACT':
$this->type = 'abstract';
if (DEBUG_ENABLED)
{
debug_log('Case ABSTRACT returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->type);
}
break;
case 'STRUCTURAL':
$this->type = 'structural';
if (DEBUG_ENABLED)
{
debug_log('Case STRUCTURAL returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->type);
}
break;
case 'AUXILIARY':
$this->type = 'auxiliary';
if (DEBUG_ENABLED)
{
debug_log('Case AUXILIARY returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->type);
}
break;
case 'MUST':
$attrs = array();
$i = $this->parseList(++$i,$strings,$attrs);
if (DEBUG_ENABLED)
{
debug_log('parseList returned %d (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $i, $attrs);
}
foreach ($attrs as $string) {
$attr = new ObjectClass_ObjectClassAttribute($string,$this->name);
if ($server->isForceMay($attr->getName())) {
2019-02-12 15:23:38 -05:00
$this->force_may[] = $attr;
$this->may_attrs[] = $attr;
} else
{
2019-02-12 15:23:38 -05:00
$this->must_attrs[] = $attr;
}
}
if (DEBUG_ENABLED)
{
debug_log('Case MUST returned (%s) (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->must_attrs, $this->force_may);
}
break;
case 'MAY':
$attrs = array();
$i = $this->parseList(++$i,$strings,$attrs);
if (DEBUG_ENABLED)
{
debug_log('parseList returned %d (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $i, $attrs);
}
foreach ($attrs as $string) {
$attr = new ObjectClass_ObjectClassAttribute($string,$this->name);
2019-02-12 15:23:38 -05:00
$this->may_attrs[] = $attr;
}
if (DEBUG_ENABLED)
{
debug_log('Case MAY returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->may_attrs);
}
break;
default:
if (preg_match('/[\d\.]+/i',$strings[$i]) && $i == 1) {
$this->setOID($strings[$i]);
if (DEBUG_ENABLED)
{
debug_log('Case default returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->getOID());
}
}
break;
}
}
$this->description = preg_replace("/^\'/",'',$this->description);
$this->description = preg_replace("/\'$/",'',$this->description);
if (DEBUG_ENABLED)
{
debug_log('Returning () - NAME (%s), DESCRIPTION (%s), MUST (%s), MAY (%s), FORCE MAY (%s)', 9, 0, __FILE__, __LINE__, __METHOD__,
$this->name, $this->description, $this->must_attrs, $this->may_attrs, $this->force_may);
}
}
/**
* Parse an LDAP schema list
2019-02-12 14:52:01 -05:00
* @param $i
* @param $strings
* @param $attrs
* @return
*/
private function parseList($i,$strings,&$attrs) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
/*
* A list starts with a ( followed by a list of attributes separated by $ terminated by )
* The first token can therefore be a ( or a (NAME or a (NAME)
* The last token can therefore be a ) or NAME)
* The last token may be terminate by more than one bracket
*/
$string = $strings[$i];
if (! preg_match('/^\(/',$string)) {
# A bareword only - can be terminated by a ) if the last item
if (preg_match('/\)+$/',$string))
{
$string = preg_replace('/\)+$/', '', $string);
}
2019-02-12 15:23:38 -05:00
$attrs[] = $string;
} elseif (preg_match('/^\(.*\)$/',$string)) {
$string = preg_replace('/^\(/','',$string);
$string = preg_replace('/\)+$/','',$string);
2019-02-12 15:23:38 -05:00
$attrs[] = $string;
} else {
# Handle the opening cases first
if ($string == '(') {
$i++;
} elseif (preg_match('/^\(./',$string)) {
$string = preg_replace('/^\(/','',$string);
2019-02-12 15:23:38 -05:00
$attrs[] = $string;
$i++;
}
# Token is either a name, a $ or a ')'
# NAME can be terminated by one or more ')'
while (! preg_match('/\)+$/',$strings[$i])) {
$string = $strings[$i];
if ($string == '$') {
$i++;
continue;
}
if (preg_match('/\)$/',$string))
{
$string = preg_replace('/\)+$/', '', $string);
}
else
{
$i++;
}
2019-02-12 15:23:38 -05:00
$attrs[] = $string;
}
}
sort($attrs);
if (DEBUG_ENABLED)
{
debug_log('Returning (%d,[%s],[%s])', 9, 0, __FILE__, __LINE__, __METHOD__, $i, $strings, $attrs);
}
return $i;
}
/**
* This will return all our parent ObjectClass Objects
*/
public function getParents() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if ((count($this->sup_classes) == 1) && ($this->sup_classes[0] == 'top'))
{
return array();
}
$server = $_SESSION[APPCONFIG]->getServer($this->server_id);
$return = array();
foreach ($this->sup_classes as $object_class) {
2019-02-12 15:23:38 -05:00
$return[] = $object_class;
$oc = $server->getSchemaObjectClass($object_class);
if ($oc)
{
$return = array_merge($return, $oc->getParents());
}
}
return $return;
}
/**
* Gets an array of AttributeType objects that entries of this ObjectClass must define.
* This differs from getMustAttrNames in that it returns an array of AttributeType objects
*
2019-02-12 14:52:01 -05:00
* @param bool $parents An array of ObjectClass objects to use when traversing
* the inheritance tree. This presents some what of a bootstrapping problem
* as we must fetch all objectClasses to determine through inheritance which
* attributes this objectClass requires.
* @return array The array of required AttributeType objects.
*
* @see getMustAttrNames
* @see getMayAttrs
* @see getMayAttrNames
*/
public function getMustAttrs($parents=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if (! $parents)
{
return $this->must_attrs;
}
$server = $_SESSION[APPCONFIG]->getServer($this->server_id);
$attrs = $this->must_attrs;
foreach ($this->getParents() as $sup_class) {
$sc = $server->getSchemaObjectClass($sup_class);
$attrs = array_merge($attrs,$sc->getMustAttrs());
}
masort($attrs,'name,source');
# Remove any duplicates
foreach ($attrs as $index => $attr)
{
if (isset($allattr[$attr->getName()]))
{
unset($attrs[$index]);
} else
{
$allattr[$attr->getName()] = 1;
}
}
return $attrs;
}
/**
* Gets an array of AttributeType objects that entries of this ObjectClass may define.
* This differs from getMayAttrNames in that it returns an array of AttributeType objects
*
2019-02-12 14:52:01 -05:00
* @param bool $parents An array of ObjectClass objects to use when traversing
* the inheritance tree. This presents some what of a bootstrapping problem
* as we must fetch all objectClasses to determine through inheritance which
* attributes this objectClass provides.
* @return array The array of allowed AttributeType objects.
*
* @see getMustAttrNames
* @see getMustAttrs
* @see getMayAttrNames
* @see AttributeType
*/
public function getMayAttrs($parents=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if (! $parents)
{
return $this->may_attrs;
}
$server = $_SESSION[APPCONFIG]->getServer($this->server_id);
$attrs = $this->may_attrs;
foreach ($this->getParents() as $sup_class) {
$sc = $server->getSchemaObjectClass($sup_class);
$attrs = array_merge($attrs,$sc->getMayAttrs());
}
masort($attrs,'name,source');
# Remove any duplicates
foreach ($attrs as $index => $attr)
{
if (isset($allattr[$attr->name]))
{
unset($attrs[$index]);
} else
{
$allattr[$attr->name] = 1;
}
}
return $attrs;
}
public function getForceMayAttrs() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
return $this->force_may;
}
/**
* Gets an array of attribute names (strings) that entries of this ObjectClass must define.
* This differs from getMustAttrs in that it returns an array of strings rather than
* array of AttributeType objects
*
2019-02-12 14:52:01 -05:00
* @param bool $parents An array of ObjectClass objects to use when traversing
* the inheritance tree. This presents some what of a bootstrapping problem
* as we must fetch all objectClasses to determine through inheritance which
* attributes this objectClass provides.
* @return array The array of allowed attribute names (strings).
*
* @see getMustAttrs
* @see getMayAttrs
* @see getMayAttrNames
*/
public function getMustAttrNames($parents=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$attr_names = array();
foreach ($this->getMustAttrs($parents) as $attr)
{
2019-02-12 15:23:38 -05:00
$attr_names[] = $attr->getName();
}
return $attr_names;
}
/**
* Gets an array of attribute names (strings) that entries of this ObjectClass must define.
* This differs from getMayAttrs in that it returns an array of strings rather than
* array of AttributeType objects
*
2019-02-12 14:52:01 -05:00
* @param bool $parents An array of ObjectClass objects to use when traversing
* the inheritance tree. This presents some what of a bootstrapping problem
* as we must fetch all objectClasses to determine through inheritance which
* attributes this objectClass provides.
* @return array The array of allowed attribute names (strings).
*
* @see getMustAttrs
* @see getMayAttrs
* @see getMustAttrNames
*/
public function getMayAttrNames($parents=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$attr_names = array();
foreach ($this->getMayAttrs($parents) as $attr)
{
2019-02-12 15:23:38 -05:00
$attr_names[] = $attr->getName();
}
return $attr_names;
}
/**
* Adds an objectClass to the list of objectClasses that inherit
* from this objectClass.
*
* @param String $name The name of the objectClass to add
* @return boolean Returns true on success or false on failure (objectclass already existed for example)
*/
public function addChildObjectClass($name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$name = trim($name);
foreach ($this->children_objectclasses as $existing_objectclass)
{
if (strcasecmp($name, $existing_objectclass) == 0)
{
return FALSE;
}
}
2019-02-12 15:23:38 -05:00
$this->children_objectclasses[] = $name;
}
/**
* Returns the array of objectClass names which inherit from this objectClass.
*
* @return Array Names of objectClasses which inherit from this objectClass.
*/
public function getChildObjectClasses() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
return $this->children_objectclasses;
}
/**
* Gets the objectClass names from which this objectClass inherits.
*
* @return array An array of objectClass names (strings)
*/
public function getSupClasses() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
return $this->sup_classes;
}
/**
* Return if this objectClass is related to $oclass
*
* @param array ObjectClasses that this attribute may be related to
*/
public function isRelated($oclass) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
# If I am in the array, we'll just return false
if (in_array_ignore_case($this->name,$oclass))
{
return FALSE;
}
$server = $_SESSION[APPCONFIG]->getServer($this->server_id);
foreach ($oclass as $object_class) {
$oc = $server->getSchemaObjectClass($object_class);
if ($oc->isStructural() && in_array_ignore_case($this->getName(),$oc->getParents()))
{
return TRUE;
}
}
return false;
}
/**
* Gets the type of this objectClass: STRUCTURAL, ABSTRACT, or AUXILIARY.
*/
public function getType() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->type);
}
return $this->type;
}
/**
* Adds the specified array of attributes to this objectClass' list of
* MUST attributes. The resulting array of must attributes will contain
* unique members.
*
* @param array $attr An array of attribute names (strings) to add.
*/
private function addMustAttrs($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if (! is_array($attr) || ! count($attr))
{
return;
}
$this->must_attrs = array_values(array_unique(array_merge($this->must_attrs,$attr)));
}
/**
* Behaves identically to addMustAttrs, but it operates on the MAY
* attributes of this objectClass.
*
* @param array $attr An array of attribute names (strings) to add.
*/
private function addMayAttrs($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if (! is_array($attr) || ! count($attr))
{
return;
}
$this->may_attrs = array_values(array_unique(array_merge($this->may_attrs,$attr)));
}
/**
* Determine if an array is listed in the force_may attrs
2019-02-12 14:52:01 -05:00
* @param $attr
* @return bool
*/
public function isForceMay($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->force_may as $forcemay)
{
if ($forcemay->getName() == $attr)
{
return TRUE;
}
}
return false;
}
public function isStructural() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if ($this->type == 'structural')
{
return TRUE;
}
else
{
return FALSE;
}
}
}
/**
* A simple class for representing AttributeTypes used only by the ObjectClass class.
* Users should never instantiate this class. It represents an attribute internal to
* an ObjectClass. If PHP supported inner-classes and variable permissions, this would
* be interior to class ObjectClass and flagged private. The reason this class is used
* and not the "real" class AttributeType is because this class supports the notion of
* a "source" objectClass, meaning that it keeps track of which objectClass originally
* specified it. This class is therefore used by the class ObjectClass to determine
* inheritance.
*
* @package phpLDAPadmin
* @subpackage Schema
*/
class ObjectClass_ObjectClassAttribute {
# This Attribute's name (needs to be public, as we sort on it with masort).
public $name;
# This Attribute's root (needs to be public, as we sort on it with masort).
public $source;
/**
* Creates a new ObjectClass_ObjectClassAttribute with specified name and source objectClass.
*
* @param string $name the name of the new attribute.
* @param string $source the name of the ObjectClass which specifies this attribute.
*/
public function __construct($name,$source) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->name = $name;
$this->source = $source;
}
# Gets this attribute's name
public function getName($lower=true) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->name);
}
return $lower ? strtolower($this->name) : $this->name;
}
# Gets the name of the ObjectClass which originally specified this attribute.
public function getSource() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->source);
}
return $this->source;
}
}
/**
* Represents an LDAP AttributeType
*
* @package phpLDAPadmin
* @subpackage Schema
*/
class AttributeType extends SchemaItem {
# The attribute from which this attribute inherits (if any)
private $sup_attribute = null;
# The equality rule used
private $equality = null;
# The ordering of the attributeType
private $ordering = null;
# Boolean: supports substring matching?
private $sub_str = null;
# The full syntax string, ie 1.2.3.4{16}
private $syntax = null;
private $syntax_oid = null;
# boolean: is single valued only?
private $is_single_value = false;
# boolean: is collective?
private $is_collective = false;
# boolean: can use modify?
private $is_no_user_modification = false;
# The usage string set by the LDAP schema
private $usage = null;
# An array of alias attribute names, strings
private $aliases = array();
# The max number of characters this attribute can be
private $max_length = null;
# A string description of the syntax type (taken from the LDAPSyntaxes)
private $type = null;
# An array of objectClasses which use this attributeType (must be set by caller)
private $used_in_object_classes = array();
# A list of object class names that require this attribute type.
private $required_by_object_classes = array();
# This attribute has been forced a MAY attribute by the configuration.
private $forced_as_may = false;
/**
* Creates a new AttributeType object from a raw LDAP AttributeType string.
2019-02-12 14:52:01 -05:00
* @param $attr
*/
public function __construct($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$strings = preg_split('/[\s,]+/',$attr,-1,PREG_SPLIT_DELIM_CAPTURE);
for($i=0; $i<count($strings); $i++) {
switch($strings[$i]) {
case '(':
break;
case 'NAME':
# Some schema's return a (' instead of a ( '
if ($strings[$i+1] != '(' && ! preg_match('/^\(/',$strings[$i+1])) {
do {
$i++;
if (strlen($this->name)==0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
# This attribute has no aliases
$this->aliases = array();
} else {
$i++;
do {
# In case we came here becaues of a ('
if (preg_match('/^\(/',$strings[$i]))
{
$strings[$i] = preg_replace('/^\(/', '', $strings[$i]);
}
else
{
$i++;
}
if (strlen($this->name) == 0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
# Add alias names for this attribute
while ($strings[++$i] != ')') {
$alias = $strings[$i];
$alias = preg_replace("/^\'/",'',$alias);
$alias = preg_replace("/\'$/",'',$alias);
$this->addAlias($alias);
}
}
if (DEBUG_ENABLED)
{
debug_log('Case NAME returned (%s) (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->name, $this->aliases);
}
break;
case 'DESC':
do {
$i++;
if (strlen($this->description)==0)
{
$this->description .= $strings[$i];
}
else
{
$this->description = $this->description . ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
if (DEBUG_ENABLED)
{
debug_log('Case DESC returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->description);
}
break;
case 'OBSOLETE':
$this->is_obsolete = TRUE;
if (DEBUG_ENABLED)
{
debug_log('Case OBSOLETE returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->is_obsolete);
}
break;
case 'SUP':
$i++;
$this->sup_attribute = $strings[$i];
if (DEBUG_ENABLED)
{
debug_log('Case SUP returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->sup_attribute);
}
break;
case 'EQUALITY':
$i++;
$this->equality = $strings[$i];
if (DEBUG_ENABLED)
{
debug_log('Case EQUALITY returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->equality);
}
break;
case 'ORDERING':
$i++;
$this->ordering = $strings[$i];
if (DEBUG_ENABLED)
{
debug_log('Case ORDERING returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->ordering);
}
break;
case 'SUBSTR':
$i++;
$this->sub_str = $strings[$i];
if (DEBUG_ENABLED)
{
debug_log('Case SUBSTR returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->sub_str);
}
break;
case 'SYNTAX':
$i++;
$this->syntax = $strings[$i];
$this->syntax_oid = preg_replace('/{\d+}$/','',$this->syntax);
# Does this SYNTAX string specify a max length (ie, 1.2.3.4{16})
if (preg_match('/{(\d+)}$/',$this->syntax,$this->max_length))
{
$this->max_length = $this->max_length[1];
}
else
{
$this->max_length = NULL;
}
if ($i < count($strings) - 1 && $strings[$i+1] == '{') {
do {
$i++;
$this->name .= ' '.$strings[$i];
} while ($strings[$i] != '}');
}
if (DEBUG_ENABLED)
{
debug_log('Case SYNTAX returned (%s) (%s) (%s)', 8, 0, __FILE__, __LINE__, __METHOD__,
$this->syntax, $this->syntax_oid, $this->max_length);
}
break;
case 'SINGLE-VALUE':
$this->is_single_value = TRUE;
if (DEBUG_ENABLED)
{
debug_log('Case SINGLE-VALUE returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->is_single_value);
}
break;
case 'COLLECTIVE':
$this->is_collective = TRUE;
if (DEBUG_ENABLED)
{
debug_log('Case COLLECTIVE returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->is_collective);
}
break;
case 'NO-USER-MODIFICATION':
$this->is_no_user_modification = TRUE;
if (DEBUG_ENABLED)
{
debug_log('Case NO-USER-MODIFICATION returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->is_no_user_modification);
}
break;
case 'USAGE':
$i++;
$this->usage = $strings[$i];
if (DEBUG_ENABLED)
{
debug_log('Case USAGE returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->usage);
}
break;
default:
if (preg_match('/[\d\.]+/i',$strings[$i]) && $i == 1) {
$this->setOID($strings[$i]);
if (DEBUG_ENABLED)
{
debug_log('Case default returned (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $this->getOID());
}
}
}
}
$this->name = preg_replace("/^\'/",'',$this->name);
$this->name = preg_replace("/\'$/",'',$this->name);
$this->description = preg_replace("/^\'/",'',$this->description);
$this->description = preg_replace("/\'$/",'',$this->description);
$this->syntax = preg_replace("/^\'/",'',$this->syntax);
$this->syntax = preg_replace("/\'$/",'',$this->syntax);
$this->syntax_oid = preg_replace("/^\'/",'',$this->syntax_oid);
$this->syntax_oid = preg_replace("/\'$/",'',$this->syntax_oid);
$this->sup_attribute = preg_replace("/^\'/",'',$this->sup_attribute);
$this->sup_attribute = preg_replace("/\'$/",'',$this->sup_attribute);
if (DEBUG_ENABLED)
{
debug_log('Returning ()', 9, 0, __FILE__, __LINE__, __METHOD__);
}
}
/**
* Gets this attribute's usage string as defined by the LDAP server
*
* @return string
*/
public function getUsage() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->usage);
}
return $this->usage;
}
/**
* Gets this attribute's parent attribute (if any). If this attribute does not
* inherit from another attribute, null is returned.
*
* @return string
*/
public function getSupAttribute() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->sup_attribute);
}
return $this->sup_attribute;
}
/**
* Gets this attribute's equality string
*
* @return string
*/
public function getEquality() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->equality);
}
return $this->equality;
}
/**
* Gets this attribute's ordering specification.
*
* @return string
*/
public function getOrdering() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->ordering);
}
return $this->ordering;
}
/**
* Gets this attribute's substring matching specification
*
* @return string
*/
public function getSubstr() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->sub_str);
}
return $this->sub_str;
}
/**
* Gets the names of attributes that are an alias for this attribute (if any).
*
* @return array An array of names of attributes which alias this attribute or
* an empty array if no attribute aliases this object.
*/
public function getAliases() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->aliases);
}
return $this->aliases;
}
/**
* Returns whether the specified attribute is an alias for this one (based on this attribute's alias list).
*
* @param string $attr_name The name of the attribute to check.
* @return boolean True if the specified attribute is an alias for this one, or false otherwise.
*/
public function isAliasFor($attr_name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->aliases as $alias_attr_name)
{
if (strcasecmp($alias_attr_name, $attr_name) == 0)
{
return TRUE;
}
}
return false;
}
/**
* Gets this attribute's raw syntax string (ie: "1.2.3.4{16}").
*
* @return string The raw syntax string
*/
public function getSyntaxString() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->syntax);
}
return $this->syntax;
}
/**
* Gets this attribute's syntax OID. Differs from getSyntaxString() in that this
* function only returns the actual OID with any length specification removed.
* Ie, if the syntax string is "1.2.3.4{16}", this function only retruns
* "1.2.3.4".
*
* @return string The syntax OID string.
*/
public function getSyntaxOID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->syntax_oid);
}
return $this->syntax_oid;
}
/**
* Gets this attribute's the maximum length. If no maximum is defined by the LDAP server, null is returned.
*
* @return int The maximum length (in characters) of this attribute or null if no maximum is specified.
*/
public function getMaxLength() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->max_length);
}
return $this->max_length;
}
/**
* Gets whether this attribute is single-valued. If this attribute only supports single values, true
* is returned. If this attribute supports multiple values, false is returned.
*
* @return boolean Returns true if this attribute is single-valued or false otherwise.
*/
public function getIsSingleValue() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->is_single_value);
}
return $this->is_single_value;
}
/**
* Sets whether this attribute is single-valued.
*
* @param boolean $is
*/
public function setIsSingleValue($is) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->is_single_value = $is;
}
/**
* Gets whether this attribute is collective.
*
* @return boolean Returns true if this attribute is collective and false otherwise.
*/
public function getIsCollective() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->is_collective);
}
return $this->is_collective;
}
/**
* Gets whether this attribute is not modifiable by users.
*
* @return boolean Returns true if this attribute is not modifiable by users.
*/
public function getIsNoUserModification() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->is_no_user_modification);
}
return $this->is_no_user_modification;
}
/**
* Gets this attribute's type
*
* @return string The attribute's type.
*/
public function getType() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->type);
}
return $this->type;
}
/**
* Removes an attribute name from this attribute's alias array.
*
* @param string $remove_alias_name The name of the attribute to remove.
* @return boolean true on success or false on failure (ie, if the specified
* attribute name is not found in this attribute's list of aliases)
*/
public function removeAlias($remove_alias_name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->aliases as $i => $alias_name) {
if (strcasecmp($alias_name,$remove_alias_name) == 0) {
unset($this->aliases[$i]);
$this->aliases = array_values($this->aliases);
return true;
}
}
return false;
}
/**
* Adds an attribute name to the alias array.
*
* @param string $alias The name of a new attribute to add to this attribute's list of aliases.
*/
public function addAlias($alias) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
2019-02-12 15:23:38 -05:00
$this->aliases[] = $alias;
}
/**
* Sets this attriute's name.
*
* @param string $name The new name to give this attribute.
*/
public function setName($name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->name = $name;
}
/**
* Sets this attriute's SUP attribute (ie, the attribute from which this attribute inherits).
*
* @param string $attr The name of the new parent (SUP) attribute
*/
public function setSupAttribute($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->sup_attribute = $attr;
}
/**
* Sets this attribute's list of aliases.
*
* @param array $aliases The array of alias names (strings)
*/
public function setAliases($aliases) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->aliases = $aliases;
}
/**
* Sets this attribute's type.
*
* @param string $type The new type.
*/
public function setType($type) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->type = $type;
}
/**
* Adds an objectClass name to this attribute's list of "used in" objectClasses,
* that is the list of objectClasses which provide this attribute.
*
* @param string $name The name of the objectClass to add.
*/
public function addUsedInObjectClass($name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->used_in_object_classes as $used_in_object_class) {
if (DEBUG_ENABLED)
{
debug_log('Checking (%s) with (%s)', 8, 0, __FILE__, __LINE__, __METHOD__, $used_in_object_class, $name);
}
if (strcasecmp($used_in_object_class,$name) == 0)
{
return FALSE;
}
}
2019-02-12 15:23:38 -05:00
$this->used_in_object_classes[] = $name;
}
/**
* Gets the list of "used in" objectClasses, that is the list of objectClasses
* which provide this attribute.
*
* @return array An array of names of objectclasses (strings) which provide this attribute
*/
public function getUsedInObjectClasses() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->used_in_object_classes);
}
return $this->used_in_object_classes;
}
/**
* Adds an objectClass name to this attribute's list of "required by" objectClasses,
* that is the list of objectClasses which must have this attribute.
*
* @param string $name The name of the objectClass to add.
*/
public function addRequiredByObjectClass($name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->required_by_object_classes as $required_by_object_class)
{
if (strcasecmp($required_by_object_class, $name) == 0)
{
return FALSE;
}
}
2019-02-12 15:23:38 -05:00
$this->required_by_object_classes[] = $name;
}
/**
* Gets the list of "required by" objectClasses, that is the list of objectClasses
* which provide must have attribute.
*
* @return array An array of names of objectclasses (strings) which provide this attribute
*/
public function getRequiredByObjectClasses() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->required_by_object_classes);
}
return $this->required_by_object_classes;
}
/**
* This function will mark this attribute as a forced MAY attribute
*/
public function setForceMay() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->forced_as_may = true;
}
public function isForceMay() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->forced_as_may);
}
return $this->forced_as_may;
}
}
/**
* Represents an LDAP Syntax
*
* @package phpLDAPadmin
* @subpackage Schema
*/
class Syntax extends SchemaItem {
/**
* Creates a new Syntax object from a raw LDAP syntax string.
2019-02-12 14:52:01 -05:00
* @param $class
*/
public function __construct($class) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$strings = preg_split('/[\s,]+/',$class,-1,PREG_SPLIT_DELIM_CAPTURE);
for($i=0; $i<count($strings); $i++) {
switch($strings[$i]) {
case '(':
break;
case 'DESC':
do {
$i++;
if (strlen($this->description) == 0)
{
$this->description .= $strings[$i];
}
else
{
$this->description = $this->description . ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
break;
default:
if (preg_match('/[\d\.]+/i',$strings[$i]) && $i == 1)
{
$this->setOID($strings[$i]);
}
}
}
$this->description = preg_replace("/^\'/",'',$this->description);
$this->description = preg_replace("/\'$/",'',$this->description);
}
}
/**
* Represents an LDAP MatchingRule
*
* @package phpLDAPadmin
* @subpackage Schema
*/
class MatchingRule extends SchemaItem {
# This rule's syntax OID
private $syntax = null;
# An array of attribute names who use this MatchingRule
private $used_by_attrs = array();
/**
* Creates a new MatchingRule object from a raw LDAP MatchingRule string.
2019-02-12 14:52:01 -05:00
* @param $strings
*/
2019-02-12 14:52:01 -05:00
public function __construct($strings) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$strings = preg_split('/[\s,]+/',$strings,-1,PREG_SPLIT_DELIM_CAPTURE);
for ($i=0; $i<count($strings); $i++) {
switch($strings[$i]) {
case '(':
break;
case 'NAME':
if ($strings[$i+1] != '(') {
do {
$i++;
if (strlen($this->name) == 0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
} else {
$i++;
do {
$i++;
if (strlen($this->name) == 0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
do {
$i++;
} while (! preg_match('/\)+\)?/',$strings[$i]));
}
$this->name = preg_replace("/^\'/",'',$this->name);
$this->name = preg_replace("/\'$/",'',$this->name);
break;
case 'DESC':
do {
$i++;
if (strlen($this->description)==0)
{
$this->description .= $strings[$i];
}
else
{
$this->description = $this->description . ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
break;
case 'OBSOLETE':
$this->is_obsolete = TRUE;
break;
case 'SYNTAX':
$this->syntax = $strings[++$i];
break;
default:
if (preg_match('/[\d\.]+/i',$strings[$i]) && $i == 1)
{
$this->setOID($strings[$i]);
}
}
}
$this->description = preg_replace("/^\'/",'',$this->description);
$this->description = preg_replace("/\'$/",'',$this->description);
}
/**
* Sets the list of used_by_attrs to the array specified by $attrs;
*
* @param array $attrs The array of attribute names (strings) which use this MatchingRule
*/
public function setUsedByAttrs($attrs) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->used_by_attrs = $attrs;
}
/**
* Adds an attribute name to the list of attributes who use this MatchingRule
*
2019-02-12 14:52:01 -05:00
* @param $attr
* @return true if the attribute was added and false otherwise (already in the list)
*/
public function addUsedByAttr($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->used_by_attrs as $attr_name)
{
if (strcasecmp($attr_name, $attr) == 0)
{
return FALSE;
}
}
2019-02-12 15:23:38 -05:00
$this->used_by_attrs[] = $attr;
return true;
}
/**
* Gets an array of attribute names (strings) which use this MatchingRule
*
* @return array The array of attribute names (strings).
*/
public function getUsedByAttrs() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->used_by_attrs);
}
return $this->used_by_attrs;
}
}
/**
* Represents an LDAP schema matchingRuleUse entry
*
* @package phpLDAPadmin
* @subpackage Schema
*/
class MatchingRuleUse extends SchemaItem {
# An array of attribute names who use this MatchingRule
private $used_by_attrs = array();
2019-02-12 14:52:01 -05:00
public function __construct($strings) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$strings = preg_split('/[\s,]+/',$strings,-1,PREG_SPLIT_DELIM_CAPTURE);
for($i=0; $i<count($strings); $i++) {
switch($strings[$i]) {
case '(':
break;
case 'NAME':
if ($strings[$i+1] != '(') {
do {
$i++;
if (! isset($this->name) || strlen($this->name) == 0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
} else {
$i++;
do {
$i++;
if (strlen($this->name) == 0)
{
$this->name = $strings[$i];
}
else
{
$this->name .= ' ' . $strings[$i];
}
} while (! preg_match("/\'$/s",$strings[$i]));
do {
$i++;
} while (! preg_match('/\)+\)?/',$strings[$i]));
}
$this->name = preg_replace("/^\'/",'',$this->name);
$this->name = preg_replace("/\'$/",'',$this->name);
break;
case 'APPLIES':
if ($strings[$i+1] != '(') {
# Has a single attribute name
$i++;
$this->used_by_attrs = array($strings[$i]);
} else {
# Has multiple attribute names
$i++;
while ($strings[$i] != ')') {
$i++;
$new_attr = $strings[$i];
$new_attr = preg_replace("/^\'/",'',$new_attr);
$new_attr = preg_replace("/\'$/",'',$new_attr);
2019-02-12 15:23:38 -05:00
$this->used_by_attrs[] = $new_attr;
$i++;
}
}
break;
default:
if (preg_match('/[\d\.]+/i',$strings[$i]) && $i == 1)
{
$this->setOID($strings[$i]);
}
}
}
sort($this->used_by_attrs);
}
/**
* Gets an array of attribute names (strings) which use this MatchingRuleUse object.
*
* @return array The array of attribute names (strings).
*/
public function getUsedByAttrs() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 9, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->used_by_attrs);
}
return $this->used_by_attrs;
}
}
2019-02-12 14:52:01 -05:00