<?
/***************************************************************************
*
* Schema.php
* -------------------
*
* begin : Friday, Jul 5, 2002
* copyright : (C) 2002 The Kabramps Team
* email : hide@address.com,
* hide@address.com
*
*
*
***************************************************************************/
/***************************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
* (http://www.gnu.org/licenses/gpl.html)
*
***************************************************************************/
/***************************************************************************
*
* Schema.php was create in conjunction with ldap.inc - version 1.1
* written by Eric Kilfoil hide@address.com
*
* Thanks to the author of the ldap.inc class who can be reached at hide@address.com
*
***************************************************************************/
class Schema {
var $error = ""; // Any error messages to be returned can be put here
var $objectClasses = array(); // Information read from slapd.oc.conf
var $attributeTypes = array();
var $attributeNames = array();
var $sup = array();
var $connection;
function Schema($connection) {
$this->connection=$connection;
}
function readConfiguration() {
$objectfilter="(objectClass=*)";
$search = ldap_read($this->connection, "cn=subschema", $objectfilter,array("objectClasses","attributeTypes"));
if ($search) {
$objects = array();
if (ldap_count_entries($this->connection, $search) > 0) {
for ($object=ldap_first_entry($this->connection,$search);$object;$object=ldap_next_entry($this->connection,$object)) {
$attribut = ldap_get_attributes($this->connection,$object);
// READ and EVALUATE attributeTypes
$attributes = ldap_get_values($this->connection,$object,"attributeTypes");
for ($i=0;$i<count($attributes);$i++) {
$line = split(" ", $attributes[$i]);
$open=0;
$n=0;
for ($j=0;$j<count($line);$j++) {
switch ($line[$j]) {
case 'NAME':
$type="name";
$n=0;
break;
case 'EQUALITY':
$type="match";
break;
case '(':
if ($open > -1) $open++;
else echo "Error parsing '('<br>";
break;
case ')':
if ($open > 0) {
$open--;
$type=null;
} else echo "Error parsing ')'<br>";
break;
default:
switch ($type) {
case 'name':
if ( $n == 0 ) {
$alias = substr(strtolower($line[$j]),1,-1);
}
$this->attributeNames[substr(strtolower($line[$j]),1,-1)]=$alias;
//echo "Attributename: '".$line[$j]."' ".$n." '".$alias."'<br>";
if ( $open > 1 ) {
$n++;
}
break;
case 'match':
$this->attributeTypes[$alias]=strtolower($line[$j]);
//echo "Attributetype ".$alias." ".$this->attributeTypes[$alias]."<br>";
break;
}
if ( $open == 1 ) $type = null;
}
//echo $attributes[$i]."<br>";
}
}
// READ and EVALUATE objectClasses
$value = ldap_get_values($this->connection,$object,"objectClasses");
for ( $i=0; $i<count($value);$i++) {
//echo $value[$i]."<br>";
$line = split(" ", $value[$i]);
$open=0;
$n=0;
$attribute=null;
$type=null;
for ($j=0;$j<count($line);$j++) {
switch ($line[$j]) {
case 'NAME':
$type="name";
break;
case 'MAY':
$type="may";
$n=0;
break;
case 'MUST':
$type="must";
$n=0;
break;
case 'SUP':
$type="sup";
break;
case '(':
if ($open > -1) $open++;
else echo "Error parsing '('<br>";
break;
case ')':
if ($open > 0) {
$open--;
$type = null;
} else echo "Error parsing ')'<br>";
break;
case '$':
if ($open == 2) {
$n++;
//$attribute = $last;
} else echo "Error parsing '$'<br>";
break;
default:
switch ($type) {
case 'name':
//echo "Name: :".substr($line[$j],1,-1).":<br>"; //$attributes[$attribute]=strtolower($line[$j]);
$attribute = strtolower(substr($line[$j],1,-1));
$this->sup[$attribute] = array();
//echo $attribute."<br>";
break;
case 'may':
//echo "may '".$attribute."' ".$n." '".$line[$j]."'<br>";
$this->objectClasses[$attribute]['allows'][$n]=strtolower($line[$j]);
break;
case 'must':
//echo "must '".$attribute."' ".$n." '".$line[$j]."'<br>";
$this->objectClasses[$attribute]['requires'][$n]=strtolower($line[$j]);
break;
case 'sup':
$this->sup[$attribute][] = strtolower($line[$j]);
//echo "OC: ".$attribute." sup: ".$this->sup[$attribute][count($this->sup[$attribute])-1]."<br>";
}
if ( $open == 1 ) $type = null;
}
}
}
}
}
}
}
function getObjectClasses() {
if (count($this->objectClasses) == 0)
$this->readConfiguration();
$ocs = array();
for ($ctr = 0, reset($this->objectClasses); $OCName = key($this->objectClasses); next($this->objectClasses), $ctr++) {
$ocs[$ctr] = $OCName;
}
return($ocs);
}
function isObjectClass($ocname) {
$ocname = strtolower($ocname);
if (count($this->objectClasses) == 0)
$this->readConfiguration();
if (is_array($this->objectClasses[$ocname]))
return(1);
return(0);
}
function getAllows($ocname) {
$ocname = strtolower($ocname);
if (count($this->objectClasses) == 0)
$this->readConfiguration();
if (! $this->isObjectClass($ocname))
return(array());
$allows = array();
$allows = $this->objectClasses[$ocname]["allows"];
for ( $i=0; $i<count($this->sup[$ocname]); $i++ ) {
$tmp=$this->getAllows($this->sup[$ocname][$i]);
for ( $j=0; $j<count($tmp); $j++) {
if ( $tmp[$j] != "" ) {
if ( ( count($allows) == 0 ) || ( ! in_array($tmp[$j],$allows) ) ) $allows[] = $tmp[$j];
}
}
}
return($allows);
}
function getRequires($ocname) {
$ocname = strtolower($ocname);
if (count($this->objectClasses) == 0)
$this->readConfiguration();
if (! $this->isObjectClass($ocname))
return(array());
$requires = array();
$requires = $this->objectClasses[$ocname]["requires"];
for ( $i=0; $i<count($this->sup[$ocname]); $i++ ) {
if ($this->sup[$ocname][$i] != 'top') { // don't wanna have the objectclass attribute as a required field
// just make trouble
$tmp=$this->getRequires($this->sup[$ocname][$i]);
for ( $j=0; $j<count($tmp); $j++) {
if ( $tmp[$j] != "" ) {
if ( ( count($requires) == 0 ) || ( ! in_array($tmp[$j],$requires) ) ) $requires[] = $tmp[$j];
}
}
}
}
// uncomment it to see how often the method is called
/*
echo "<br>".$ocname.":<br>";
for ( $j = 0; $j < count($requires); $j++) {
echo $requires[$j]."<br>";
}
*/
return($requires);
}
function isAllowed($ocname, $allowed) {
$ocname = strtolower($ocname);
$allowed = strtolower($allowed);
if (count($this->objectClasses) == 0)
$this->readConfiguration();
if (! $this->isObjectClass($ocname))
return(0);
for ($ctr = 0; $ctr < count($this->objectClasses[$ocname]["allows"]); $ctr++)
if (strcasecmp($this->objectClasses[$ocname]["allows"][$ctr], $allowed) == 0)
return(1);
return(0);
}
function isRequired($ocname, $required) {
$ocname = strtolower($ocname);
$required = strtolower($required);
if (count($this->objectClasses) == 0)
$this->readConfiguration();
if (! $this->isObjectClass($ocname))
return(0);
for ($ctr = 0; $ctr < count($this->objectClasses[$ocname]["requires"]); $ctr++)
if (strcasecmp($this->objectClasses[$ocname]["requires"][$ctr], $required) == 0)
return(1);
return(0);
}
function getAttributeName($attribute) {
if ( count($this->attributeNames) == 0 )
$this->readConfiguration();
return $this->attributeNames[strtolower($attribute)];
}
function getAttributeType($attribute) {
if ( count($this->attributeTypes) == 0 )
$this->readConfiguration();
return $this->attributeTypes[$attribute];
}
}
?>