first commit

This commit is contained in:
aschwarz
2023-04-25 13:25:59 +02:00
commit 086d1e1e9e
1774 changed files with 396049 additions and 0 deletions

307
phpldapadmin/lib/AJAXTree.php Executable file
View File

@ -0,0 +1,307 @@
<?php
/**
* Classes and functions for the LDAP tree.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* This class implements an AJAX based tree.
*
* @package phpLDAPadmin
* @subpackage Tree
* @see HTMLTree Tree
*/
class AJAXTree extends HTMLTree {
/**
* Draw a node of the tree
*
* @param dn The Base DN to draw
* @param string $level a string of 0 and 1 ; $level == "000101" will draw " | |<node>"
* @param boolean $first_child is the first child entry, which is normally the "Create New Entry" option
* @param boolean $last_child is the last child entry, which is normally the "Create New Entry" option
*/
protected function draw_item($item,$level,$first_child=true,$last_child=true) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
# Level pre-treatment
$code = '';
if (is_string($level)) {
for ($i=0; $i<strlen($level); $i++) {
if ($level[$i] == '0')
$code .= '0';
elseif ($level[$i] == '1')
$code .= '1';
}
} elseif ($level > 0)
$code = '0' * $level;
$level = strlen($code);
# Get entry to display as node
$entry = $this->getEntry($item);
# If the entry doesnt exist, we'll add it.
if (! $entry) {
$this->addEntry($item);
$entry = $this->getEntry($item);
}
# If the entry doesnt exist in the server, then return here with an empty string.
if (! $entry)
return '';
# Get our children.
$child_count = $this->readChildrenNumber($entry->getDN());
$nb = 0;
if ($first_child)
$nb += 1;
if ($last_child)
$nb += 2;
$imgs['expand'] = array('tree_expand.png','tree_expand.png','tree_expand_corner.png',
($level > 0) ? 'tree_expand_corner.png' : 'tree_expand_corner_first.png');
$imgs['collapse'] = array('tree_collapse.png','tree_collapse.png','tree_collapse_corner.png',
($level > 0) ? 'tree_collapse_corner.png' : 'tree_collapse_corner_first.png');
$imgs['tree'] = array('tree_split.png','tree_split.png','tree_corner.png','tree_corner.png');
/** Information on array[$nb]
* nb == 1 => the node is the first child
* nb == 2 => the node is the last child
* nb == 3 => the node is the unique child
* nb == 0 => the node is a child */
$new_code = array('1','1','0','0');
# Links
$parms['openclose'] = htmlspecialchars(sprintf('server_id=%s&dn=%s&code=%s%s',$this->getServerID(),$entry->getDNEncode(),$code,$new_code[$nb]));
$parms['edit'] = htmlspecialchars(sprintf('cmd=template_engine&server_id=%s&dn=%s',$this->getServerID(),$entry->getDNEncode()));
$href = sprintf('cmd.php?%s',$parms['edit']);
# Each node has a unique id based on dn
$node_id = sprintf('node%s',base64_encode(sprintf('%s-%s',$server->getIndex(),$entry->getDN())));
$node_id = str_replace('=','_',$node_id);
if ($level == 0)
printf('<tr><td class="spacer"></td><td colspan="%s">',$this->getDepth()+3-1);
printf('<div id="jt%s" class="treemenudiv">',$node_id);
echo $this->get_indentation($code);
if (! $child_count)
printf('<img id="jt%snode" src="%s/%s" alt="--" class="imgs" style="border: 0px; vertical-align:text-top;" />',$node_id,IMGDIR,$imgs['tree'][$nb]);
else {
printf('<a href="#" onclick="return opencloseTreeNode(\'%s\',\'%s\',\'%s\');">',$node_id,$parms['openclose'],IMGDIR);
if ($entry->isOpened())
printf('<img id="jt%snode" src="%s/%s" alt="+-" class="imgs" style="border: 0px; vertical-align:text-top;" />',$node_id,IMGDIR,$imgs['collapse'][$nb]);
else
printf('<img id="jt%snode" src="%s/%s" alt="+-" class="imgs" style="border: 0px; vertical-align:text-top;" />',$node_id,IMGDIR,$imgs['expand'][$nb]);
echo '</a>';
}
printf('<a href="%s" onclick="return ajDISPLAY(\'BODY\',\'%s\',\'%s\');" title="%s" >',$href,$parms['edit'],_('Retrieving DN'),htmlspecialchars($entry->getDN()));
printf('<span class="dnicon"><img id="jt%sfolder" src="%s/%s" alt="->" class="imgs" style="border: 0px; vertical-align:text-top;" /></span>',$node_id,IMGDIR,$entry->getIcon($server));
echo '</a>';
echo '&nbsp;';
printf('<a href="%s" onclick="return ajDISPLAY(\'BODY\',\'%s\',\'%s\');" title="%s" class="phplm">',$href,$parms['edit'],_('Retrieving DN'),htmlspecialchars($entry->getDN()));
echo $this->get_formatted_dn($entry,$level-1);
echo ($child_count ? (sprintf(' (%s%s)',$child_count,($entry->isSizeLimited() ? '+' : ''))) : '');
echo '</a>';
echo '</div>';
printf('<div id="jt%sson" style="display: %s" class="treemenudiv">',$node_id,($entry->isOpened() ? 'block' : 'none'));
if ($entry->isOpened())
$this->draw_children($entry,$code.$new_code[$nb]);
echo '</div>';
if ($level == 0)
echo '</td></tr>';
}
/**
* Expand and draw a child entry, when it is clicked on. This is using AJAX just to render this section of the tree.
*/
public function draw_children($parent_entry,$code) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$children = array();
foreach ($parent_entry->getChildren() as $child) {
if (! $this->getEntry($child))
$this->addEntry($child);
array_push($children,$this->getEntry($child));
}
$first_child = $this->create_before_child($parent_entry,$code);
$last_child = $this->create_after_child($parent_entry,$code);
# If compression is on, we need to compress this output - but only if called by draw_tree_node
if (function_exists('isCompress') && isCompress() && get_request('cmd','REQUEST') == 'draw_tree_node')
ob_start();
echo $first_child;
for ($i=0; $i<count($children); $i++) {
$first = ($i == 0) && (! $first_child);
$last = ($i == (count($children)-1)) && (! $last_child);
if (is_object($children[$i]))
$this->draw_item($children[$i]->getDN(),$code,$first,$last);
else
echo '<br/>problem getting DN entry from ldap';
echo "\n";
}
echo $last_child;
# If compression is on, we need to compress this output
if (function_exists('isCompress') && isCompress() && get_request('cmd','REQUEST') == 'draw_tree_node') {
$output = ob_get_clean();
echo gzencode($output);
}
}
/**
* Return the indentation before a node
*
* @param $code a string of 0 and 1 ; $code == "000101" will return " | |"
*/
protected function get_indentation($code) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$indent = '';
for ($i=0; $i<strlen($code); $i++) {
switch ($code[$i]) {
case '0':
$indent .= sprintf('<img src="%s/tree_space.png" alt=" " class="imgs" style="border: 0px; vertical-align:text-top;" />',IMGDIR);
break;
case '1':
$indent .= sprintf('<img src="%s/tree_vertline.png" alt="| " class="imgs" style="border: 0px; vertical-align:text-top;" />',IMGDIR);
break;
}
}
return $indent;
}
/**
* Draw the javascript to support the tree.
*/
protected function draw_javascript() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
parent::draw_javascript();
printf('<script type="text/javascript" src="%slayersmenu-browser_detection.js"></script>',JSDIR);
printf('<script type="text/javascript" src="%sajax_tree.js"></script>',JSDIR);
}
/**
* Draw the "Create New Entry" item before the children.
*/
private function create_before_child($entry,$level) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (strlen($level) == 0)
return '';
$server = $this->getServer();
$output = '';
if (! $server->isReadOnly() && ! $entry->isLeaf() && (count($entry->getChildren()) > 10) && $this->getServer()->isShowCreateEnabled()
&& $_SESSION[APPCONFIG]->getValue('appearance','show_top_create'))
$output = $this->draw_create_new_entry($entry,$level,IMGDIR.'/tree_split.png');
return $output;
}
/**
* Draw the "Create New Entry" item after the children.
*/
private function create_after_child($entry,$level) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (strlen($level) == 0)
return '';
$server = $this->getServer();
$output = '';
if (! $server->isReadOnly() && ! $entry->isLeaf() && $this->getServer()->isShowCreateEnabled())
$output = $this->draw_create_new_entry($entry,$level,IMGDIR.'/tree_corner.png');
return $output;
}
/**
* Draw the "Create New Entry" item.
*/
private function draw_create_new_entry($entry,$level,$img) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$output = '';
$href = sprintf('cmd=template_engine&server_id=%s&container=%s',$this->getServerID(),$entry->getDNEncode());
$output .= $this->get_indentation($level);
$output .= sprintf('<img src="%s" alt="--" class="imgs" style="border: 0px; vertical-align:text-top;" />',$img);
$output .= sprintf('<a href="%s" title="%s">',htmlspecialchars($href),$entry->getDN());
$output .= sprintf('<img src="%s/create.png" alt="->" class="imgs" style="border: 0px; vertical-align:text-top;" />',IMGDIR);
$output .= '</a>';
$output .= '&nbsp;';
if (isAjaxEnabled())
$output .= sprintf('<a href="cmd.php?%s" title="%s" class="phplm" onclick="return ajDISPLAY(\'BODY\',\'%s\',\'%s\');">',
htmlspecialchars($href),_('Create new entry here'),
htmlspecialchars($href),_('Loading'));
else
$output .= sprintf('<a href="cmd.php?%s" title="%s" class="phplm">',htmlspecialchars($href),_('Create new entry here'));
$output .= _('Create new entry here');
$output .= '</a>';
return $output;
}
/**
* List the items in the tree that are open
*
* @return array List of open nodes
*/
public function listOpenItems() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = array();
foreach ($this->entries as $dn => $value)
if ($value->isOpened())
array_push($result,$value->getDN());
return $result;
}
}
?>

917
phpldapadmin/lib/Attribute.php Executable file
View File

@ -0,0 +1,917 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute of a template.
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class Attribute {
# Attribute Name
public $name;
# Source of this attribute definition
protected $source;
# Current and Old Values
protected $oldvalues = array();
protected $values = array();
# MIN/MAX number of values
protected $min_value_count = -1;
protected $max_value_count = -1;
# Is the attribute internal
protected $internal = false;
# Has the attribute been modified
protected $modified = false;
# Is the attribute being deleted because of an object class removal
protected $forcedelete = false;
# Is the attribute visible
protected $visible = false;
protected $forcehide = false;
# Is the attribute modifiable
protected $readonly = false;
# LDAP attribute type MUST/MAY
protected $ldaptype = null;
# Attribute property type (eg password, select, multiselect)
protected $type = '';
# Attribute value to keep unique
protected $unique = false;
# Display parameters
protected $display = '';
protected $icon = '';
protected $hint = '';
# Helper details
protected $helper = array();
protected $helpervalue = array();
# Onchange details
protected $onchange = array();
# Show spacer after this attribute is rendered
protected $spacer = false;
protected $verify = false;
# Component size
protected $size = 0;
# Value max length
protected $maxlength = 0;
# Text Area sizings
protected $cols = 0;
protected $rows = 0;
# Public for sorting
public $page = 1;
public $order = 255;
public $ordersort = 255;
public $rdn = false;
# Schema Aliases for this attribute (stored in lowercase)
protected $aliases = array();
# Configuration for automatically generated values
protected $autovalue = array();
protected $postvalue = array();
public function __construct($name,$values,$server_id,$source=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $_SESSION[APPCONFIG]->getServer($server_id);
$sattr = $server->getSchemaAttribute($name);
if ($sattr) {
$this->name = $sattr->getName(false);
$this->setLDAPdetails($sattr);
} else
$this->name = $name;
$this->source = $source;
# XML attributes are shown by default
switch ($source) {
case 'XML': $this->show();
$this->setXML($values);
break;
default:
if (! isset($values['values']))
debug_dump_backtrace('no index "values"',1);
$this->initValue($values['values']);
}
# Should this attribute be hidden
if ($server->isAttrHidden($this->name))
$this->forcehide = true;
# Should this attribute value be read only
if ($server->isAttrReadOnly($this->name))
$this->readonly = true;
# Should this attribute value be unique
if ($server->isAttrUnique($this->name))
$this->unique = true;
}
/**
* Return the name of the attribute.
*
* @param boolean $lower - Return the attribute in normal or lower case (default lower)
* @param boolean $real - Return the real attribute name (with ;binary, or just the name)
* @return string Attribute name
*/
public function getName($lower=true,$real=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs,$this->name);
if ($real)
return $lower ? strtolower($this->name) : $this->name;
else
return $lower ? strtolower($this->real_attr_name()) : $this->real_attr_name();
}
public function getValues() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->values);
return $this->values;
}
public function getOldValues() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->oldvalues);
return $this->oldvalues;
}
public function getValueCount() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs,$this->values);
return count($this->values);
}
public function getSource() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->source);
return $this->source;
}
/**
* Autovalue is called after the attribute is initialised, and thus the values from the ldap server will be set.
*/
public function autoValue($new_val) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->values)
return;
$this->values = $new_val;
}
public function initValue($new_val) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->values || $this->oldvalues) {
debug_dump(array('new_val'=>$new_val,'this'=>$this));
debug_dump_backtrace('new and/or old values are set',1);
}
$this->values = $new_val;
}
public function clearValue() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->values = array();
}
public function setOldValue($val) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->oldvalues = $val;
}
public function setValue($new_val) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->values) {
if ($this->values == $new_val)
return;
if ($this->oldvalues) {
debug_dump($this);
debug_dump_backtrace('old values are set',1);
} else
$this->oldvalues = $this->values;
}
if ($new_val == $this->values)
return;
$this->values = $new_val;
$this->justModified();
}
public function addValue($new_val,$i=-1) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($i < 0)
$i = $this->getValueCount();
$old_val = $this->getValue($i);
if (is_null($old_val) || ($old_val != $new_val))
$this->justModified();
$this->values[$i] = $new_val;
}
public function delValue($i=-1) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($i < 0)
$this->setValue(array());
if (! $this->hasBeenModified())
$this->oldvalues = $this->values;
if (isset($this->values[$i])) {
unset($this->values[$i]);
$this->values = array_values($this->values);
$this->justModified();
}
}
public function getValue($i) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (isset($this->values[$i]))
return $this->values[$i];
else
return null;
}
public function getOldValue($i) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (isset($this->oldvalues[$i]))
return $this->oldvalues[$i];
else
return null;
}
public function getMinValueCount() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->min_value_count);
return $this->min_value_count;
}
public function setMinValueCount($min) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->min_value_count = $min;
}
public function getMaxValueCount() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->max_value_count);
return $this->max_value_count;
}
public function setMaxValueCount($max) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->max_value_count = $max;
}
public function haveMoreValues() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->getMaxValueCount() < 0 || ($this->getValueCount() < $this->getMaxValueCount()))
return true;
else
return false;
}
public function justModified() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->modified = true;
}
public function hasBeenModified() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->modified);
return $this->modified;
}
public function isForceDelete() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->forcedelete);
return $this->forcedelete;
}
public function setForceDelete() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->forcedelete = true;
$this->oldvalues = $this->values;
$this->values = array();
$this->justModified();
}
public function isInternal() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->internal);
return $this->internal;
}
public function setInternal() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->internal = true;
}
public function isRequired() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->getMinValueCount() > 0)
return true;
elseif ($this->ldaptype == 'must')
return true;
elseif ($this->isRDN())
return true;
else
return false;
}
public function isMay() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (($this->ldaptype == 'may') && ! $this->isRequired())
return true;
else
return false;
}
public function setType($type) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->type = strtolower($type);
}
public function getType() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->type);
return $this->type;
}
public function setLDAPtype($type) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->ldaptype = strtolower($type);
}
public function getLDAPtype() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->ldaptype);
return $this->ldaptype;
}
public function setProperties($properties) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
foreach ($properties as $index => $value) {
if ($index == 'maxvalnb') {
$this->setMaxValueCount($value);
continue;
} elseif ($index == 'minvalnb') {
$this->setMinValueCount($value);
continue;
} elseif ($index == 'maxlength') {
$this->setMinValueCount($value);
continue;
} elseif ($index == 'hidden') {
$this->visible = $value;
continue;
} elseif (in_array($index,array('cols','rows'))) {
# @todo To be implemented
continue;
}
if (isset($this->$index))
$this->$index = $value;
else {
debug_dump($this);
debug_dump_backtrace(sprintf('Unknown property (%s) with value (%s) for (%s)',$index,$value,$this->getName()),1);
}
}
}
public function setRequired() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->getMinValueCount() <= 0)
$this->setMinValueCount(1);
}
public function setOptional() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->setMinValueCount(0);
}
public function isReadOnly() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->readonly);
return $this->readonly;
}
public function setReadOnly() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->readonly = true;
}
public function isMultiple() {
return false;
}
public function isVisible() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $this->visible && (! $this->forcehide);
}
public function hide() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->visible = false;
}
public function show() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->visible = true;
}
public function haveFriendlyName() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $_SESSION[APPCONFIG]->haveFriendlyName($this);
}
public function getFriendlyName() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->display);
if ($this->display)
return $this->display;
else
return $_SESSION[APPCONFIG]->getFriendlyName($this);
}
public function setDescription($description) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->description = $description;
}
public function getDescription() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->description);
return $this->description;
}
public function setIcon($icon) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->icon = $icon;
}
public function getIcon() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->icon);
return $this->icon ? sprintf('%s/%s',IMGDIR,$this->icon) : '';
}
public function getHint() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->hint);
return $this->hint;
}
public function setHint($hint) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->hint = $hint;
}
public function getMaxLength() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->maxlength);
return $this->maxlength;
}
public function setMaxLength($maxlength) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->maxlength = $maxlength;
}
public function getSize() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->size);
return $this->size;
}
public function setSize($size) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->size = $size;
}
public function getSpacer() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->spacer);
return $this->spacer;
}
public function getPage() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->page);
return $this->page;
}
public function setPage($page) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->page = $page;
}
public function getOnChange() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->onchange);
return $this->onchange;
}
public function getHelper() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->helper);
return $this->helper;
}
public function getHelperValue() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->helpervalue);
return $this->helpervalue;
}
public function getVerify() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->verify);
return $this->verify;
}
public function setRDN($rdn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->rdn = $rdn;
}
/**
* Return if this attribute is an RDN attribute
*
* @return boolean
*/
public function isRDN() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs,$this->rdn);
return $this->rdn;
}
/**
* Capture all the LDAP details we are interested in
*
* @param sattr Schema Attribute
*/
private function setLDAPdetails($sattr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
# By default, set this as a MAY attribute, later processing should make it a MUST attribute if it is.
if (! $this->ldaptype)
$this->ldaptype = 'may';
# Store our Aliases
foreach ($sattr->getAliases() as $alias)
array_push($this->aliases,strtolower($alias));
if ($sattr->getIsSingleValue())
$this->setMaxValueCount(1);
}
/**
* Return a list of aliases for this Attribute (as defined by the schema)
* This list will be lowercase.
*/
public function getAliases() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->aliases);
return $this->aliases;
}
public function getAutoValue() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->autovalue);
return $this->autovalue;
}
public function getPostValue() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->postvalue);
return $this->postvalue;
}
public function setPostValue($postvalue) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->postvalue = $postvalue;
}
public function setXML($values) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
# Mostly all the time, this should be an array
if (is_array($values))
foreach ($values as $index => $value)
switch ($index) {
# Helpers should be accompanied with a <post> attribute.
case 'helper':
if (! isset($values['post']) && ! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Missing [post] setting in XML file'),$index),
'body'=>_('[helper] needs an accompanying [post] action.'),
'type'=>'warn'));
if (isset($value['value']) && ! is_array($value['value']) && preg_match('/^=php\.(\w+)\((.*)\)$/',$value['value'],$matches)) {
$this->helpervalue['function'] = $matches[1];
$this->helpervalue['args'] = $matches[2];
unset ($value['value']);
}
foreach ($value as $i => $detail) {
if (! in_array($i,array('default','display','id','value'))) {
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$i),
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown XML type setting for helper will be ignored.'),$detail),
'type'=>'warn'));
unset($value[$i]);
}
}
$this->$index = $value;
break;
case 'hidden': $value ? $this->visible = false : $this->visible = true;
break;
case 'spacer': $value ? $this->$index = true : $this->$index = false;
break;
# Essentially, we ignore type, it is used to select an Attribute type in the Factory. But we'll generated a warning if there is an unknown type.
case 'type':
if (! in_array($value,array('password','multiselect','select','textarea')) && ! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$index),
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown XML type setting will be ignored.'),$value),
'type'=>'warn'));
break;
case 'post':
if (preg_match('/^=php\.(\w+)\((.*)\)$/',$value,$matches)) {
$this->postvalue['function'] = $matches[1];
$this->postvalue['args'] = $matches[2];
} else
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$index),
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown XML type setting will be ignored.'),$value),
'type'=>'warn'));
case 'value':
if (is_array($value))
foreach ($value as $x => $y) {
if (! $this->haveMoreValues()) {
system_message(array(
'title'=>_('Automatically removed attribute values from template'),
'body'=>sprintf('%s <small>[%s]</small>',_('Template defines more values than can be accepted by attribute.'),$this->getName(true)),
'type'=>'warn'));
$this->clearValue();
break;
} else
$this->addValue($x,$y);
}
else
# Check to see if the value is auto generated.
if (preg_match('/^=php\.(\w+)\((.*)\)$/',$value,$matches)) {
$this->autovalue['function'] = $matches[1];
$this->autovalue['args'] = $matches[2];
# We'll add a hint too
if (! $this->hint)
$this->hint = _('Automatically determined');
} else
$this->addValue($value);
break;
# Queries
case 'ordersort':
# Creation/Editing Templates
case 'cols':
case 'default':
case 'display':
case 'hint':
case 'icon':
case 'maxlength':
case 'onchange':
case 'order':
case 'page':
case 'readonly':
case 'rows':
case 'size':
case 'values':
case 'verify': $this->$index = $value;
break;
case 'max':
if ($this->getMaxValueCount() == -1)
$this->setMaxValueCount($value);
default:
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown XML setting'),$index),
'body'=>sprintf('%s <small>[%s]</small>',_('Unknown attribute setting will be ignored.'),serialize($value)),
'type'=>'warn'));
}
elseif (is_string($values) && (strlen($values) > 0))
$this->values = array($values);
}
/**
* Display the values removed in an attribute.
*/
public function getRemovedValues() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
return array_diff($this->getOldValues(),$this->getValues());
}
/**
* Display the values removed in an attribute.
*/
public function getAddedValues() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
return array_diff($this->getValues(),$this->getOldValues());
}
/**
* Prunes off anything after the ";" in an attr name. This is useful for
* attributes that may have ";binary" appended to their names. With
* real_attr_name(), you can more easily fetch these attributes' schema
* with their "real" attribute name.
*
* @param string $attr_name The name of the attribute to examine.
* @return string
*/
private function real_attr_name() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->name);
return preg_replace('/;.*$/U','',$this->name);
}
/**
* Does this attribute need supporting JS
*/
public function needJS($type=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (is_null($type)) {
foreach (array('focus','blur','validate') as $type)
if ($this->needJS($type))
return true;
return false;
} elseif ($type == 'focus') {
# We dont have any focus javascript routines.
return false;
} elseif ($type == 'blur') {
if ($this->onchange || $this->isRequired())
return true;
else
return false;
} elseif ($type == 'validate') {
if ($this->isRequired())
return true;
else
return false;
} else
debug_dump_backtrace(sprintf('Unknown JS request %s',$type),1);
}
}
?>

View File

@ -0,0 +1,188 @@
<?php
/**
* Allows to create new attributes
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* AttributeFactory Class
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class AttributeFactory {
public function newAttribute($name,$values,$server_id,$source=null) {
global $app;
# Check to see if the value is auto generated, our attribute type is dependant on the function called.
if (isset($values['post']) && ! is_array($values['post'])) {
if (preg_match('/^=php\.(\w+)\((.*)\)$/',$values['post'],$matches)) {
switch ($matches[1]) {
case 'Join':
case 'PasswordEncrypt':
break;
default:
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown template [post] function'),$matches[1]),
'body'=>sprintf('%s <small>[%s]</small>',_('The template function is not known and will be ignored.'),$values['post']),
'type'=>'warn'));
unset($values['post']);
}
}
}
# Check our helper functions exists
if (isset($values['helper']['value']) && ! is_array($values['helper']['value']))
if (preg_match('/^=php\.(\w+)\((.*)\)$/',$values['helper']['value'],$matches))
if (! in_array($matches[1],array('GetNextNumber','PasswordEncryptionTypes'))) {
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown template helper function'),$matches[1]),
'body'=>sprintf('%s <small>[%s]</small>',_('The template helper function is not known and will be ignored.'),$values['helper']['value']),
'type'=>'warn'));
unset($values['helper']['value']);
}
# Check to see if the value is auto generated, our attribute type is dependant on the function called.
if (isset($values['value']) && ! is_array($values['value'])) {
if (preg_match('/^=php\.(\w+)\((.*)\)$/',$values['value'],$matches)) {
switch ($matches[1]) {
case 'MultiList':
if (! isset($values['type']))
$values['type'] = 'multiselect';
case 'PickList':
return $this->newSelectionAttribute($name,$values,$server_id,$source);
case 'RandomPassword':
return $this->newRandomPasswordAttribute($name,$values,$server_id,$source);
# Fall through and determine the attribute using other methods.
case 'GetNextNumber':
case 'Function' :
break;
default:
if (! $_SESSION[APPCONFIG]->getValue('appearance','hide_template_warning'))
system_message(array(
'title'=>sprintf('%s [<i>%s</i>]',_('Unknown template function'),$matches[1]),
'body'=>sprintf('%s <small>[%s]</small>',_('The template function is not known and will be ignored.'),$values['value']),
'type'=>'warn'));
unset($values['value']);
}
}
}
if (isset($values['type']))
switch ($values['type']) {
case 'password':
if (! strcasecmp($name,'sambaLMPassword') || ! strcasecmp($name,'sambaNTPassword'))
return $this->newSambaPasswordAttribute($name,$values,$server_id,$source);
else
return $this->newPasswordAttribute($name,$values,$server_id,$source);
case 'multiselect':
case 'select':
return $this->newSelectionAttribute($name,$values,$server_id,$source);
case 'textarea':
return $this->newMultiLineAttribute($name,$values,$server_id,$source);
}
if (! strcasecmp($name,'objectClass')) {
return $this->newObjectClassAttribute($name,$values,$server_id,$source);
} elseif ($app['server']->isJpegPhoto($name) || in_array($name,$app['server']->getValue('server','jpeg_attributes'))) {
return $this->newJpegAttribute($name,$values,$server_id,$source);
} elseif ($app['server']->isAttrBinary($name)) {
return $this->newBinaryAttribute($name,$values,$server_id,$source);
} elseif (! strcasecmp($name,'userPassword')) {
return $this->newPasswordAttribute($name,$values,$server_id,$source);
} elseif (! strcasecmp($name,'sambaLMPassword') || ! strcasecmp($name,'sambaNTPassword')) {
return $this->newSambaPasswordAttribute($name,$values,$server_id,$source);
} elseif (in_array(strtolower($name),array_keys(array_change_key_case($_SESSION[APPCONFIG]->getValue('appearance','date_attrs'))))) {
return $this->newDateAttribute($name,$values,$server_id,$source);
} elseif (in_array(strtolower($name),array('shadowlastchange','shadowmin','shadowmax','shadowexpire','shadowwarning','shadowinactive'))) {
return $this->newShadowAttribute($name,$values,$server_id,$source);
} elseif ($app['server']->isAttrBoolean($name)) {
$attribute = $this->newSelectionAttribute($name,$values,$server_id,$source);
$attribute->addOption('TRUE',_('true'));
$attribute->addOption('FALSE',_('false'));
return $attribute;
} elseif ($app['server']->isDNAttr($name)) {
return $this->newDnAttribute($name,$values,$server_id,$source);
} elseif ($app['server']->isMultiLineAttr($name)) {
return $this->newMultiLineAttribute($name,$values,$server_id,$source);
} elseif (! strcasecmp($name,'gidNumber')) {
return $this->newGidAttribute($name,$values,$server_id,$source);
} else {
return new Attribute($name,$values,$server_id,$source);
}
}
private function newJpegAttribute($name,$values,$server_id,$source) {
return new JpegAttribute($name,$values,$server_id,$source);
}
private function newBinaryAttribute($name,$values,$server_id,$source) {
return new BinaryAttribute($name,$values,$server_id,$source);
}
private function newPasswordAttribute($name,$values,$server_id,$source) {
return new PasswordAttribute($name,$values,$server_id,$source);
}
private function newSambaPasswordAttribute($name,$values,$server_id,$source) {
return new SambaPasswordAttribute($name,$values,$server_id,$source);
}
private function newRandomPasswordAttribute($name,$values,$server_id,$source) {
return new RandomPasswordAttribute($name,$values,$server_id,$source);
}
private function newShadowAttribute($name,$values,$server_id,$source) {
return new ShadowAttribute($name,$values,$server_id,$source);
}
private function newSelectionAttribute($name,$values,$server_id,$source) {
return new SelectionAttribute($name,$values,$server_id,$source);
}
private function newMultiLineAttribute($name,$values,$server_id,$source) {
return new MultiLineAttribute($name,$values,$server_id,$source);
}
private function newDateAttribute($name,$values,$server_id,$source) {
return new DateAttribute($name,$values,$server_id,$source);
}
private function newObjectClassAttribute($name,$values,$server_id,$source) {
return new ObjectClassAttribute($name,$values,$server_id,$source);
}
private function newDnAttribute($name,$values,$server_id,$source) {
return new DnAttribute($name,$values,$server_id,$source);
}
private function newGidAttribute($name,$values,$server_id,$source) {
return new GidAttribute($name,$values,$server_id,$source);
}
}
?>

View File

@ -0,0 +1,60 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are binary
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class BinaryAttribute extends Attribute {
protected $filepaths;
protected $filenames;
public function __construct($name,$values,$server_id,$source=null) {
parent::__construct($name,$values,$server_id,$source);
$this->filepaths = array();
$this->filenames = array();
}
public function getFileNames() {
return $this->filenames;
}
public function getFileName($i) {
if (isset($this->filenames[$i])) return $this->filenames[$i];
else return null;
}
public function addFileName($name, $i = -1) {
if ($i < 0) {
$this->filenames[] = $name;
} else {
$this->filenames[$i] = $name;
}
}
public function getFilePaths() {
return $this->filepaths;
}
public function getFilePath($i) {
if (isset($this->filepaths[$i])) return $this->filepaths[$i];
else return null;
}
public function addFilePath($path, $i = -1) {
if ($i < 0) {
$this->filepaths[] = $path;
} else {
$this->filepaths[$i] = $path;
}
}
}
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are dates
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class DateAttribute extends Attribute {
}
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are DNs
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class DnAttribute extends Attribute {
}
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents a 'gidNumber' attribute
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class GidAttribute extends Attribute {
}
?>

587
phpldapadmin/lib/HTMLTree.php Executable file
View File

@ -0,0 +1,587 @@
<?php
/**
* Classes and functions for the LDAP tree.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* This class implements a straight HTML tree - no AJAX rendering is used.
*
* @package phpLDAPadmin
* @subpackage Tree
* @see AJAXTree Tree
*/
class HTMLTree extends Tree {
protected $javascript = '';
/**
* Required ABSTRACT methods
*/
/**
* Displays the tree in HTML
*
* @param boolean Only display the tree, or include the server name and menu items
*/
public function draw($onlytree=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
static $js_drawn = false;
$server = $this->getServer();
echo '<table class="tree" border="0">';
if (! $onlytree)
$this->draw_server_name();
$this->javascript = '';
$javascript_id = 0;
/* Do we have what it takes to authenticate here, or do we need to
* present the user with a login link (for 'cookie' and 'session' auth_types)?
*/
if ($server->isLoggedIn(null)) {
if (! $onlytree) {
$this->draw_menu();
if ($server->getAuthType() != 'config')
$this->draw_logged_in_user();
else
printf('<tr><td class="blank" colspan="%s">&nbsp;</td></tr>',$this->getDepth()+3);
if ($server->isReadOnly())
printf('<tr><td class="spacer"></td><td class="logged_in" colspan="%s">(%s)</td></tr>',$this->getDepth()+3-1,_('read only'));
else
printf('<tr><td class="blank" colspan="%s">&nbsp;</td></tr>',$this->getDepth()+3);
printf('<tr><td>&nbsp;</td><td><div style="overflow: auto; %s%s" id="ajSID_%s_nodes">',
$_SESSION[APPCONFIG]->getValue('appearance','tree_width') ? sprintf('width: %spx; ',$_SESSION[APPCONFIG]->getValue('appearance','tree_width')) : '',
$_SESSION[APPCONFIG]->getValue('appearance','tree_height') ? sprintf('height: %spx; ',$_SESSION[APPCONFIG]->getValue('appearance','tree_height')) : '',
$server->getIndex());
}
echo '<table class="tree" border="0">';
if (! count($this->getBaseEntries())) {
# We didnt get any baseDN entries in our tree?
printf('<tr><td class="spacer"></td><td class="spacer"></td><td colspan="%s"><small>%s<br />%s<br /><b>%s</b></small></td></tr>',
$this->getDepth()+3-2,
_('Could not determine the root of your LDAP tree.'),
_('It appears that the LDAP server has been configured to not reveal its root.'),
_('Please specify it in config.php'));
echo '</table>';
if (! $onlytree)
echo '</div></td></tr>';
echo '</table>';
return;
}
/**
* Check if the LDAP server is not yet initialized
* (ie, the base DN configured in config.php does not exist)
*/
foreach ($this->getBaseEntries() as $base) {
if (! $base->isInLDAP()) {
$js_drawn = false;
$javascript_id++;
$rdn = explode('=',get_rdn($base->getDN()));
printf('<tr><td class="spacer"></td><td class="spacer"></td><td><img src="%s/unknown.png" alt="" /></td><td colspan="%s">%s</td></tr>',
IMGDIR,$this->getDepth()+3-3,pretty_print_dn($base->getDN()));
$this->javascript .= sprintf('<form id="create_base_form_%s_%s" method="post" action="cmd.php">',$server->getIndex(),$javascript_id);
$this->javascript .= '<div>';
$this->javascript .= '<input type="hidden" name="cmd" value="template_engine" />';
$this->javascript .= sprintf('<input type="hidden" name="server_id" value="%s" />',$server->getIndex());
$this->javascript .= sprintf('<input type="hidden" name="container" value="%s" />',htmlspecialchars($server->getContainer($base->getDN())));
$this->javascript .= sprintf('<input type="hidden" name="rdn" value="%s" />',get_rdn($base->getDN()));
$this->javascript .= sprintf('<input type="hidden" name="rdn_attribute[]" value="%s" />',$rdn[0]);
$this->javascript .= sprintf('<input type="hidden" name="new_values[%s][]" value="%s" />',$rdn[0],$rdn[1]);
$this->javascript .= '<input type="hidden" name="template" value="none" />';
$this->javascript .= '<input type="hidden" name="create_base" value="true" />';
$this->javascript .= '</div>';
$this->javascript .= sprintf('</form>');
if (preg_match('/,/',$base->getDN()))
printf('<tr><td class="spacer"></td><td class="spacer"></td><td class="spacer"></td><td colspan="%s"><small>%s</small></td></tr>',
$this->getDepth()+3-3,_('This base cannot be created with PLA.'));
else
printf('<tr><td class="spacer"></td><td class="spacer"></td><td class="spacer"></td><td colspan="%s"><small>%s <a href="javascript:document.getElementById(\'create_base_form_%s_%s\').submit()">%s</a></small></td></tr>',
$this->getDepth()+3-3,_('This base entry does not exist.'),$server->getIndex(),$javascript_id,_('Create it?'));
} else {
$this->draw_item($base->getDN(),-1);
}
}
echo '</table>';
if (! $onlytree)
echo '</div></td></tr>';
# We are not logged in, draw a login... link.
} else {
switch ($server->getAuthType()) {
case 'cookie':
case 'http':
case 'session':
$this->draw_login_link();
break;
case 'config':
case 'proxy':
case 'sasl':
break;
default:
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$server->getAuthType()));
}
}
# Tree Footer.
echo '</table>';
echo "\n\n";
if (! $js_drawn) {
$this->draw_javascript();
$js_drawn = true;
}
}
/**
* Draw the server name
*/
protected function draw_server_name() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
echo '<tr class="server">';
printf('<td class="icon"><img src="%s/server.png" alt="%s" /></td>',IMGDIR,_('Server'));
printf('<td class="name" colspan="%s">',$this->getDepth()+3-1);
printf('%s',$server->getName());
if (! is_null($server->inactivityTime())) {
$m = sprintf(_('Inactivity will log you off at %s'),
strftime('%H:%M',$server->inactivityTime()));
printf(' <img width="14" height="14" src="%s/timeout.png" title="%s" alt="%s"/>',IMGDIR,$m,'Timeout');
}
echo '</td></tr>';
}
/**
* Draw the tree menu options
*/
protected function draw_menu() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$links = '';
if (is_array($_SESSION[APPCONFIG]->getValue('menu','session')))
foreach ($_SESSION[APPCONFIG]->getValue('menu','session') as $link => $title) {
if ($this->get_menu_item($link))
$links .= sprintf('<td class="server_links">%s</td>',$this->get_menu_item($link));
}
# Finally add our logout link.
$links .= sprintf('<td class="server_links">%s</td>',$this->get_logout_menu_item());
# Draw the quick-links below the server name:
if ($links) {
printf('<tr><td class="spacer"></td><td colspan="%s" class="links">',$this->getDepth()+3-1);
printf('<table><tr>%s</tr></table>',$links);
echo '</td></tr>';
}
}
/**
* Get the HTML for each tree menu option
*/
protected function get_menu_item($item) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$menu = array();
switch($item) {
case 'schema':
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','schema'))
return '';
$menu['cmd'] = 'schema';
$menu['ajax'] = _('Loading Schema');
$menu['div'] = 'BODY';
$menu['title'] = _('View schema for');
$menu['img'] = 'schema-big.png';
$menu['name'] = _('schema');
break;
case 'search':
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','query_engine'))
return '';
$menu['cmd'] = 'query_engine';
$menu['ajax'] = _('Loading Search');
$menu['div'] = 'BODY';
$menu['title'] = _('Search');
$menu['img'] = 'search-big.png';
$menu['name'] = _('search');
break;
case 'refresh':
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','refresh'))
return '';
$menu['cmd'] = 'refresh';
$menu['href'] = '&noheader=1&purge=1';
$menu['ajax'] = _('Refreshing Tree');
$menu['div'] = sprintf('SID_%s_nodes',$server->getIndex());
$menu['title'] = _('Refresh');
$menu['img'] = 'refresh-big.png';
$menu['name'] = _('refresh');
break;
case 'server_info':
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','server_info'))
return '';
$menu['cmd'] = 'server_info';
$menu['ajax'] = _('Loading Info');
$menu['div'] = 'BODY';
$menu['title'] = _('Info');
$menu['img'] = 'info-big.png';
$menu['name'] = _('info');
break;
case 'monitor':
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','monitor'))
return '';
$attrs = $server->getRootDSE();
if (! $attrs || ! isset($attrs['monitorcontext']))
return '';
$menu['cmd'] = 'monitor';
$menu['ajax'] = _('Loading Monitor Info');
$menu['div'] = 'BODY';
$menu['title'] = _('Monitor');
$menu['img'] = 'monitorserver-big.png';
$menu['name'] = _('monitor');
break;
case 'import':
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','import_form') || ! $_SESSION[APPCONFIG]->isCommandAvailable('script','import') || $server->isReadOnly())
return '';
$menu['cmd'] = 'import_form';
$menu['ajax'] = _('Loading Import');
$menu['div'] = 'BODY';
$menu['title'] = _('Import');
$menu['img'] = 'import-big.png';
$menu['name'] = _('import');
break;
case 'export':
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','export_form') || ! $_SESSION[APPCONFIG]->isCommandAvailable('script','export'))
return '';
$menu['cmd'] = 'export_form';
$menu['ajax'] = _('Loading Export');
$menu['div'] = 'BODY';
$menu['title'] = _('Export');
$menu['img'] = 'export-big.png';
$menu['name'] = _('export');
break;
default:
return false;
}
$href_parms = htmlspecialchars(sprintf('cmd=%s&server_id=%s%s',$menu['cmd'],$server->getIndex(),isset($menu['href']) ? $menu['href'] : ''));
if (isAjaxEnabled())
return sprintf('<a href="cmd.php?%s" onclick="return ajDISPLAY(\'%s\',\'%s\',\'%s\');" title="%s %s"><img src="%s/%s" alt="%s" /><br />%s</a>',
$href_parms,$menu['div'],$href_parms,$menu['ajax'],$menu['title'],$server->getName(),IMGDIR,$menu['img'],$menu['name'],$menu['name']);
else
return sprintf('<a href="cmd.php?%s" title="%s %s"><img src="%s/%s" alt="%s" /><br />%s</a>',
$href_parms,$menu['title'],$server->getName(),IMGDIR,$menu['img'],$menu['name'],$menu['name']);
}
protected function get_logout_menu_item() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$href = sprintf('cmd.php?cmd=logout&server_id=%s',$server->getIndex());
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','logout') || in_array($server->getAuthType(),array('config','http','proxy','sasl')))
return '';
else
return sprintf('<a href="%s" title="%s"><img src="%s/%s" alt="%s" /><br />%s</a>',
htmlspecialchars($href),_('Logout of this server'),IMGDIR,'logout-big.png',_('logout'),_('logout'));
}
/**
* Draw the Logged in User
*/
protected function draw_logged_in_user() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$logged_in_dn = $server->getLogin(null);
echo '<tr>';
echo '<td class="spacer"></td>';
printf('<td class="logged_in" colspan="%s">%s: ',$this->getDepth()+3-1,_('Logged in as'));
if ($server->getContainerTop($logged_in_dn) == $logged_in_dn) {
$logged_in_branch = '';
$logged_in_dn_array = array();
} else {
$logged_in_branch = preg_replace('/,'.$server->getContainerTop($logged_in_dn).'$/','',$logged_in_dn);
$logged_in_dn_array = pla_explode_dn($logged_in_branch);
}
$bases = $server->getContainerTop($logged_in_dn);
if (is_array($bases) && count($bases))
array_push($logged_in_dn_array,$bases);
$rdn = $logged_in_dn;
# Some sanity checking here, in case our DN doesnt look like a DN
if (! is_array($logged_in_dn_array))
$logged_in_dn_array = array($logged_in_dn);
if (trim($logged_in_dn)) {
if ($server->dnExists($logged_in_dn))
foreach ($logged_in_dn_array as $rdn_piece) {
$href = sprintf('cmd.php?cmd=template_engine&server_id=%s&dn=%s',$server->getIndex(),rawurlencode($rdn));
printf('<a href="%s">%s</a>',htmlspecialchars($href),pretty_print_dn($rdn_piece));
if ($rdn_piece != end($logged_in_dn_array))
echo ',';
$rdn = substr($rdn,(1 + strpos($rdn,',')));
}
else
echo $logged_in_dn;
} else {
echo 'Anonymous';
}
echo '</td>';
echo '</tr>';
}
/**
* Recursively descend on the given dn and draw the tree in html
*
* @param dn $dn Current dn.
* @param int $level Level to start drawing (start to -1)
*/
protected function draw_item($item,$level) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
# Get entry to display as node
$entry = $this->getEntry($item);
# If the entry doesnt exist, we'll add it.
if (! $entry) {
$this->addEntry($item);
$entry = $this->getEntry($item);
}
# If the entry doesnt exist in the server, then return here with an empty string.
if (! $entry)
return;
# Get our children.
$child_count = $this->readChildrenNumber($item);
$rdn = get_rdn($item);
$dnENCODE = rawurlencode($item);
$href['expand'] = htmlspecialchars(sprintf('cmd.php?cmd=expand&server_id=%s&dn=%s',$server->getIndex(),$dnENCODE));
$href['collapse'] = htmlspecialchars(sprintf('cmd.php?cmd=collapse&server_id=%s&dn=%s',$server->getIndex(),$dnENCODE));
$href['edit'] = htmlspecialchars(sprintf('cmd.php?cmd=template_engine&server_id=%s&dn=%s',$server->getIndex(),$dnENCODE));
echo '<tr class="option">';
printf('<td class="spacer" colspan="%s"></td>',$level+2);
# Is this node expanded? (deciding whether to draw "+" or "-")
if ($entry->isOpened())
if (! $child_count && ! $this->getServer()->isShowCreateEnabled())
printf('<td class="expander"><img src="%s/minus.png" alt="-" /></td>',IMGDIR);
else
printf('<td class="expander"><a href="%s"><img src="%s/minus.png" alt="-" /></a></td>',$href['collapse'],IMGDIR);
else
if (($child_count !== false) && (! $child_count) && (! $this->getServer()->isShowCreateEnabled()))
printf('<td class="expander"><img src="%s/minus.png" alt="-" /></td>',IMGDIR);
else
printf('<td class="expander"><a href="%s"><img src="%s/plus.png" alt="+" /></a></td>',$href['expand'],IMGDIR);
printf('<td class="icon"><a href="%s" id="node_%s_%s"><img src="%s/%s" alt="img" /></a></td>',
$href['edit'],$server->getIndex(),preg_replace('/=/','_',base64_encode($item)),IMGDIR,$entry->getIcon());
printf('<td class="phplm" colspan="%s" style="width: 100%%;"><span style="white-space: nowrap;">',$this->getDepth()+3-$level);
printf('<a href="%s">%s</a>',$href['edit'],$this->get_formatted_dn($entry,$level));
if ($child_count)
printf(' <span class="count">(%s)</span>',$child_count);
echo '</span></td></tr>';
if ($entry->isOpened()) {
/* Draw the "create new" link at the top of the tree list if there are more than 10
* entries in the listing for this node.
*/
if (!$server->isReadOnly() && (count($entry->getChildren()) > 10)
&& $this->getServer()->isShowCreateEnabled()) {
$this->draw_create_link($rdn,$level,$dnENCODE);
}
foreach ($entry->getChildren() as $dnChildEntry)
$this->draw_item($dnChildEntry,$level+1);
# Always draw the "create new" link at the bottom of the listing
if (! $server->isReadOnly() && ! $entry->isLeaf() && $this->getServer()->isShowCreateEnabled()) {
$this->draw_create_link($rdn,$level,$dnENCODE);
}
}
if (DEBUG_ENABLED)
debug_log('Leaving (%s,%s)',33,0,__FILE__,__LINE__,__METHOD__,$item,$level);
}
protected function get_formatted_dn($entry,$level) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($level < 0)
return pretty_print_dn($entry->getDN());
else
return draw_formatted_dn($this->getServer(),$entry);
}
/**
* Print the HTML to show the "create new entry here".
*
* @param dn $rdn
* @param int $level
* @param dn $encoded_dn
*/
protected function draw_create_link($rdn,$level,$encoded_dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
# print the "Create New object" link.
$href = htmlspecialchars(sprintf('cmd.php?cmd=template_engine&server_id=%s&container=%s',$this->getServerID(),$encoded_dn));
echo '<tr>';
printf('<td class="spacer" colspan="%s"></td>',$level+3);
printf('<td class="icon"><a href="%s"><img src="%s/create.png" alt="%s" /></a></td>',$href,IMGDIR,_('new'));
printf('<td class="link" colspan="%s"><a href="%s" title="%s %s">%s</a></td>',
$this->getDepth()+3-$level,$href,_('Create a new entry in'),$rdn,_('Create new entry here'));
echo '</tr>';
}
/**
* Draw login link
*/
protected function draw_login_link() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$href_parm = htmlspecialchars(sprintf('cmd=%s&server_id=%s',get_custom_file($server->getIndex(),'login_form',''),$server->getIndex()));
echo '<tr class="option"><td class="spacer"></td>';
if (isAjaxEnabled()) {
printf('<td class="icon"><a href="cmd.php?%s" onclick="return ajDISPLAY(\'BODY\',\'%s\',\'%s\');" title="%s %s"><img src="%s/%s" alt="%s" /></a></td>',
$href_parm,$href_parm,_('Loading Login'),_('Login to'),$server->getName(),IMGDIR,'login.png',_('login'));
printf('<td class="logged_in" colspan="%s"><a href="cmd.php?%s" onclick="return ajDISPLAY(\'BODY\',\'%s\',\'%s\');" title="%s %s">%s</a></td>',
$this->getDepth()+3-2,$href_parm,$href_parm,_('Loading Login'),_('Login to'),$server->getName(),_('login'));
} else {
printf('<td class="icon"><a href="cmd.php?%s"><img src="%s/%s" alt="%s" /></a></td>',$href_parm,IMGDIR,'login.png',_('login'));
printf('<td class="logged_in" colspan="%s"><a href="cmd.php?%s">%s...</a></td>',$this->getDepth()+3-2,$href_parm,_('Login'));
}
echo '</tr>';
printf('<tr><td class="blank" colspan="%s">&nbsp;</td></tr>',$this->getDepth()+3);
printf('<tr><td class="blank" colspan="%s">&nbsp;</td></tr>',$this->getDepth()+3);
}
/**
* If there is javascript, draw it
*/
protected function draw_javascript() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->javascript) {
echo "<!-- Forms for javascript submit to call to create base_dns -->\n";
echo $this->javascript;
echo "<!-- The end of the forms for javascript submit to call to create base_dns -->\n";
$this->javascript = '';
}
}
/**
* Work out how deep the "opened" tree is.
*/
public function getDepth() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
# If we are not logged in
if (! $server->isLoggedIn(null))
return 0;
static $depths = array();
if (! isset($depths[$server->getIndex()])) {
$max = 0; # BaseDN are open, so we start at 1.
foreach ($this->entries as $dn) {
$basedepth = count(pla_explode_dn($server->getContainerPath($dn->getDN(),'/')));
$depth = 0;
$depth = count(pla_explode_dn($dn->getDN()))+1-$basedepth;
if ($depth > $max)
$max = $depth;
}
$depths[$server->getIndex()] = $max;
}
return $depths[$server->getIndex()];
}
}
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are jpeg pictures
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class JpegAttribute extends BinaryAttribute {
}
?>

48
phpldapadmin/lib/MassRender.php Executable file
View File

@ -0,0 +1,48 @@
<?php
/**
* This class will render the editing of multiple LDAP entries.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* TemplateRender class
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class MassRender extends TemplateRender {
protected function drawMassFormReadWriteValueAttribute($attribute,$i,$j) {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$val = $attribute->getValue($i);
if ($attribute->getHelper())
echo '<table cellspacing="0" cellpadding="0" border=1><tr><td valign="top">';
printf('<input type="text" class="value" name="mass_values[%s][%s][%s]" id="new_values_%s_%s_%s" value="%s" %s%s %s %s/>',
$j,htmlspecialchars($attribute->getName()),$i,
$j,htmlspecialchars($attribute->getName()),$i,
htmlspecialchars($val),
$attribute->needJS('focus') ? sprintf('onfocus="focus_%s(this);" ',$attribute->getName()) : '',
$attribute->needJS('blur') ? sprintf('onblur="blur_%s(this);" ',$attribute->getName()) : '',
($attribute->getSize() > 0) ? sprintf('size="%s"',$attribute->getSize()) : '',
($attribute->getMaxLength() > 0) ? sprintf('maxlength="%s"',$attribute->getMaxLength()) : '');
if ($attribute->getHelper()) {
echo '</td><td valign="top">';
$this->draw('AttributeHelper',$attribute,$i);
echo '</td></tr></table>';
}
}
protected function drawMassFormReadWriteValueBinaryAttribute($attribute,$i,$j) {
$this->drawFormReadWriteValueBinaryAttribute($attribute,$i);
}
protected function drawMassFormReadWriteValueJpegAttribute($attribute,$i,$j) {
$this->drawFormReadOnlyValueJpegAttribute($attribute,$i);
}
}
?>

View File

@ -0,0 +1,35 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents a attribute whose values are multiline text
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class MultiLineAttribute extends Attribute {
protected $rows = 0;
protected $cols = 0;
public function getRows() {
return $this->rows;
}
public function setRows($rows) {
$this->rows = $rows;
}
public function getCols() {
return $this->cols;
}
public function setCols($cols) {
$this->cols = $cols;
}
}
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an 'objectClass' attribute
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class ObjectClassAttribute extends Attribute {
}
?>

1244
phpldapadmin/lib/PageRender.php Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are passwords
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class PasswordAttribute extends Attribute {
}
?>

283
phpldapadmin/lib/Query.php Executable file
View File

@ -0,0 +1,283 @@
<?php
/**
* Classes and functions for the query engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Query Class
*
* @package phpLDAPadmin
* @subpackage Queries
*/
class Query extends xmlTemplate {
protected $description = '';
public $results = array();
/**
* Main processing to store the template.
*
* @param xmldata Parsed xmldata from xml2array object
*/
protected function storeTemplate($xmldata) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
foreach ($xmldata['query'] as $xml_key => $xml_value) {
if (DEBUG_ENABLED)
debug_log('Foreach loop Key [%s] Value [%s]',4,0,__FILE__,__LINE__,__METHOD__,$xml_key,is_array($xml_value));
switch ($xml_key) {
# Build our attribute list from the DN and Template.
case ('attributes'):
if (DEBUG_ENABLED)
debug_log('Case [%s]',4,0,__FILE__,__LINE__,__METHOD__,$xml_key);
if (is_array($xmldata['query'][$xml_key])) {
foreach ($xmldata['query'][$xml_key] as $tattrs) {
foreach ($tattrs as $index => $details) {
if (DEBUG_ENABLED)
debug_log('Foreach tattrs Key [%s] Value [%s]',4,0,__FILE__,__LINE__,__METHOD__,
$index,$details);
# If there is no schema definition for the attribute, it will be ignored.
if ($sattr = $server->getSchemaAttribute($index)) {
if (is_null($attribute = $this->getAttribute($sattr->getName())))
$attribute = $this->addAttribute($sattr->getName(false),array('values'=>array()));
$attribute->show();
$attribute->setXML($details);
}
}
}
}
break;
# Build our bases list from the DN and Template.
case ('bases'):
if (isset($xmldata['query'][$xml_key]['base']))
if (is_array($xmldata['query'][$xml_key]['base']))
$this->base = $xmldata['query'][$xml_key]['base'];
else
$this->base = array($xmldata['query'][$xml_key]['base']);
else
error(sprintf(_('In the XML file (%s), [%s] contains an unknown key.'),
$this->filename,$xml_key),'error','index.php');
$this->base = array_unique($this->base);
break;
default:
if (DEBUG_ENABLED)
debug_log('Case [%s]',4,0,__FILE__,__LINE__,__METHOD__,$xml_key);
# Some key definitions need to be an array, some must not be:
$allowed_arrays = array('');
$storelower = array('');
$storearray = array('');
# Items that must be stored lowercase
if (in_array($xml_key,$storelower))
if (is_array($xml_value))
foreach ($xml_value as $index => $value)
$xml_value[$index] = strtolower($value);
else
$xml_value = strtolower($xml_value);
# Items that must be stored as arrays
if (in_array($xml_key,$storearray) && ! is_array($xml_value))
$xml_value = array($xml_value);
# Items that should not be an array
if (! in_array($xml_key,$allowed_arrays) && is_array($xml_value)) {
debug_dump(array(__METHOD__,'key'=>$xml_key,'value'=>$xml_value));
error(sprintf(_('In the XML file (%s), [%s] is an array, it must be a string.'),
$this->filename,$xml_key),'error');
}
$this->$xml_key = $xml_value;
}
}
# Check we have some manditory items.
foreach (array() as $key) {
if (! isset($this->$key)
|| (! is_array($this->$key) && ! trim($this->$key))) {
$this->setInvalid(sprintf(_('Missing %s in the XML file.'),$key));
break;
}
}
}
/**
* Accept will run the query and store the results in results()
*/
public function accept() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$query = array();
$query['size_limit'] = get_request('size_limit','REQUEST',false,$_SESSION[APPCONFIG]->getValue('search','size_limit'));
$query['format'] = get_request('format','REQUEST',false,$_SESSION[APPCONFIG]->getValue('search','display'));
$query['orderby'] = get_request('orderby','REQUEST',false,'dn');
# If this is a custom search, we need to populate are paramters
if ($this->getID() == 'none') {
$bases = get_request('base','REQUEST',false,null);
$query['filter'] = get_request('filter','REQUEST',false,'objectClass=*');
$query['scope'] = get_request('scope','REQUEST',false,'sub');
$attrs = get_request('display_attrs','REQUEST');
$attrs = preg_replace('/\s+/','',$attrs);
if ($attrs)
$query['attrs'] = explode(',',$attrs);
else
$query['attrs'] = array('*');
} else {
$bases = $this->base;
$query['filter'] = $this->filter;
$query['scope'] = $this->scope;
$query['attrs'] = $this->getAttributeNames();
}
if (! $bases)
$bases = $server->getBaseDN();
elseif (! is_array($bases))
$bases = explode('|',$bases);
foreach ($bases as $base) {
$query['base'] = $base;
$time_start = utime();
$this->results[$base] = $server->query($query,null);
$time_end = utime();
$this->resultsdata[$base]['time'] = round($time_end-$time_start,2);
$this->resultsdata[$base]['scope'] = $query['scope'];
$this->resultsdata[$base]['filter'] = $query['filter'];
$this->resultsdata[$base]['attrs'] = $query['attrs'];
if ($this->getAttrSortOrder() == 'dn')
usort($this->results[$base],'pla_compare_dns');
elseif ($this->getAttrSortOrder())
masort($this->results[$base],$this->getAttrSortOrder());
}
}
/**
* This is temporary to get around objects that use a DN for rendering, for example jpegPhoto
*/
public function setDN($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->dn = $dn;
}
/**
* This is temporary to get around objects that use a DN for rendering, for example jpegPhoto
*/
public function getDN() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->dn);
return $this->dn;
}
public function getDNEncode($url=true) {
// @todo Be nice to do all this in 1 location
if ($url)
return urlencode(preg_replace('/%([0-9a-fA-F]+)/',"%25\\1",$this->dn));
else
return preg_replace('/%([0-9a-fA-F]+)/',"%25\\1",$this->dn);
}
public function getAttrSortOrder() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = array();
if (count($this->attributes)) {
masort($this->attributes,'ordersort');
foreach ($this->attributes as $attribute)
array_push($result,$attribute->getName());
} else {
$display = preg_replace('/,\s+/',',',get_request('orderby','REQUEST',false,'dn'));
if (trim($display))
$result = explode(',',$display);
}
return implode(',',$result);
}
public function getAttrDisplayOrder() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = array();
if (count($this->attributes)) {
masort($this->attributes,'order');
foreach ($this->attributes as $attribute)
array_push($result,$attribute->getName());
} else {
$display = preg_replace('/,\s+/',',',get_request('display_attrs','REQUEST',false,''));
if (trim($display))
$result = explode(',',$display);
}
# If our display order is empty, then dynamically build it
if (! count($result)) {
foreach ($this->results as $details)
foreach ($details as $attrs)
$result = array_merge($result,array_keys(array_change_key_case($attrs)));
$result = array_unique($result);
sort($result);
}
# Put the DN first
array_unshift($result,'dn');
$result = array_unique($result);
return implode(',',$result);
}
/**
* Test if the template is visible
*
* @return boolean
*/
public function isVisible() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->visible);
return $this->visible;
}
public function getDescription() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->description);
return $this->description;
}
}
?>

557
phpldapadmin/lib/QueryRender.php Executable file
View File

@ -0,0 +1,557 @@
<?php
/**
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* QueryRender class
*
* @package phpLDAPadmin
* @subpackage Templates
* @todo need to add paging
*/
class QueryRender extends PageRender {
/** CORE FUNCTIONS **/
/**
* Intialise and Render the QueryRender
*/
public function accept() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
if (DEBUGTMP||DEBUGTMPSUB) printf('<font size=-2>* %s [GETquery:%s]</font><br />',__METHOD__,get_request('query','REQUEST'));
if (DEBUGTMP||DEBUGTMPSUB) printf('<font size=-2>* %s [Page:%s]</font><br />',__METHOD__,get_request('page','REQUEST'));
$this->template_id = $this->getTemplateChoice();
$this->page = get_request('page','REQUEST',false,1);
# If we are the default template, make sure we pressed search
if ($this->template_id == 'none' && ! get_request('search','REQUEST'))
$this->drawTemplateChoice();
elseif ($this->template_id) {
$templates = $this->getTemplates();
$this->template = $templates->getTemplate($this->template_id);
$this->template->accept();
$this->visitStart();
$this->visitEnd();
}
}
/**
* Get our templates applicable for this object
*/
protected function getTemplates() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
return new Queries($this->server_id);
}
/**
* Are default queries enabled?
*/
protected function haveDefaultTemplate() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
if ($server->getValue('query','disable_default'))
return false;
else
return true;
}
protected function drawTemplateChoice() {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$server = $this->getServer();
$this->drawTitle(_('Search'));
$this->drawSubTitle();
echo "\n";
$baseDNs = $server->getBaseDN();
printf('<script type="text/javascript" src="%sdnChooserPopup.js"></script>',JSDIR);
echo '<form action="cmd.php" id="advanced_search_form">';
echo '<div>';
echo '<input type="hidden" name="cmd" value="query_engine" />';
printf('<input type="hidden" name="server_id" value="%s" />',$server->getIndex());
echo '</div>';
echo '<table class="forminput" border="0" style="margin-left: auto; margin-right: auto;">';
echo '<tr><td colspan="2">&nbsp;</td></tr>';
$templates = $this->getTemplates();
if (count($templates->getTemplates())) {
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',_('Run a predefined query'),_('Predefined Query'));
echo '<td>';
echo '<select name="query">';
if ($this->haveDefaultTemplate())
printf('<option value="%s" %s>%s</option>','none','',_('Custom Query'));
foreach ($templates->getTemplates() as $template)
printf('<option value="%s" %s>%s</option>',
$template->getID(),
($this->template_id == $template->getID() ? 'selected="selected"' : ''),
$template->getDescription());
echo '</select>';
echo '</td>';
echo '</tr>';
}
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',_('The format to show the query results'),_('Display Format'));
echo '<td>';
echo '<select name="format" style="width: 200px">';
printf('<option value="list" %s>%s</option>',
$_SESSION[APPCONFIG]->getValue('search','display') == 'list' ? 'selected="selected"' : '',_('list'));
printf('<option value="table" %s>%s</option>',
$_SESSION[APPCONFIG]->getValue('search','display') == 'table' ? 'selected="selected"' : '',_('table'));
echo '</select>';
echo '</td>';
echo '</tr>';
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',_('Entries to show per page'),_('Show Results'));
echo '<td>';
echo '<select name="showresults" style="width: 200px">';
printf('<option value="na" %s>%s</option>',
'','NA');
echo '</select>';
echo '</td>';
echo '</tr>';
echo '<tr>';
echo '<td colspan="2">';
printf('<div id="customquery" style="display: %s">','block');
echo '<br/>';
echo '<fieldset>';
printf('<legend>%s</legend>',_('Custom Query'));
echo '<table border="0"><tr>';
printf('<td>%s</td>',_('Base DN'));
printf('<td><input type="text" name="base" value="%s" style="width: 200px" id="base" />',count($baseDNs) == 1 ? $baseDNs[0] : '');
draw_chooser_link('advanced_search_form','base');
echo '</td>';
echo '</tr>';
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',_('The scope in which to search'),_('Search Scope'));
echo '<td>';
echo '<select name="scope" style="width: 200px">';
printf('<option value="sub" %s>%s</option>',
'',_('Sub (entire subtree)'));
printf('<option value="one" %s>%s</option>',
'',_('One (one level beneath base)'));
printf('<option value="base" %s>%s</option>',
'',_('Base (base dn only)'));
echo '</select>';
echo '</td>';
echo '</tr>';
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',
htmlspecialchars(_('Standard LDAP search filter. Example: (&(sn=Smith)(givenName=David))')),_('Search Filter'));
printf('<td><input type="text" name="filter" id="filter" style="width: 200px" value="%s" /></td>',
'objectClass=*');
echo '</tr>';
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',
_('A list of attributes to display in the results (comma-separated)'),_('Show Attributes'));
printf('<td><input type="text" name="display_attrs" style="width: 200px" value="%s" /></td>',
implode(', ',$_SESSION[APPCONFIG]->getValue('search','result_attributes')));
echo '</tr>';
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',_('Order by'),_('Order by'));
printf('<td><input type="text" name="orderby" id="orderby" style="width: 200px" value="%s" /></td>','');
echo '</tr>';
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',_('Set the search results to 0 to retrieve all available records'),_('Search Results'));
printf('<td><input type="text" name="size_limit" id="size_limit" style="width: 200px" value="%s" /></td>',$_SESSION[APPCONFIG]->getValue('search','size_limit'));
echo '</tr>';
echo '</table>';
echo '</fieldset>';
echo '</div>';
echo '</td>';
echo '</tr>';
printf('<tr><td colspan="2" style="text-align: center;"><br /><input type="submit" name="search" value="%s" /></td></tr>',_('Search'));
echo '</table>';
echo '</form>';
}
private function visitStart() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->drawTitle(_('Search Results'));
$this->drawSubTitle();
echo '<br/>';
}
private function visitEnd() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$afattrs = $this->getAFAttrs();
# If Mass Actions Enabled
if ($_SESSION[APPCONFIG]->getValue('mass','enabled')) {
$mass_actions = array(
_('delete') => 'mass_delete',
_('edit') => 'mass_edit'
);
}
$this->drawBaseTabs();
$ado = $this->template->getAttrDisplayOrder();
$counter = 0;
$j = 0;
foreach ($this->template->results as $base => $results) {
$counter++;
if (! $show = get_request('show','REQUEST'))
$show = ($counter === 1 ? $this->getAjaxRef($base) : null);
printf('<div id="DN%s" style="display: %s">',
$this->getAjaxRef($base), ($show == $this->getAjaxRef($base) ? 'block' : 'none'));
echo '<table class="result_box" border="0" width="100%">';
echo '<tr><td>';
echo '<br/>';
echo '<br/>';
$this->drawResultsTable($base,count($results));
echo '<br/>';
echo '<br/>';
switch(get_request('format','REQUEST',false,$_SESSION[APPCONFIG]->getValue('search','display'))) {
case 'list':
foreach ($results as $dndetails) {
$dndetails = array_change_key_case($dndetails);
# Temporarily set our DN, for rendering that leverages our DN (eg: JpegPhoto)
$this->template->setDN($dndetails['dn']);
echo '<table class="result" border="0">';
echo '<tr class="list_title">';
printf('<td class="icon"><img src="%s/%s" alt="icon" /></td>',IMGDIR,get_icon($server->getIndex(),$dndetails['dn']));
printf('<td colspan="2"><a href="cmd.php?cmd=template_engine&amp;server_id=%s&amp;dn=%s">%s</a></td>',
$server->getIndex(),$this->template->getDNEncode(),htmlspecialchars(get_rdn($dndetails['dn'])));
echo '</tr>';
printf('<tr class="list_item"><td class="blank">&nbsp;</td><td class="heading">dn</td><td class="value">%s</td></tr>',
htmlspecialchars(dn_unescape($dndetails['dn'])));
# Iterate over each attribute for this entry
foreach (explode(',',$ado) as $attr) {
$attr = strtolower($attr);
# Ignore DN, we've already displayed it.
if ($attr == 'dn')
continue;
if (! isset($dndetails[$attr]))
continue;
# Set our object with our values
$afattrs[$attr]->clearValue();
if (is_array($dndetails[$attr]))
$afattrs[$attr]->initValue($dndetails[$attr]);
else
$afattrs[$attr]->initValue(array($dndetails[$attr]));
echo '<tr class="list_item">';
echo '<td class="blank">&nbsp;</td>';
echo '<td class="heading">';
$this->draw('Name',$afattrs[$attr]);
echo '</td>';
echo '<td>';
$this->draw('CurrentValues',$afattrs[$attr]);
echo '</td>';
echo '</tr>';
}
echo '</table>';
echo '<br/>';
}
break;
# Display the results.
case 'table':
if (! $results) {
echo _('Search returned no results');
continue;
}
printf('<form action="cmd.php" method="post" id="massform_%s">',$counter);
echo '<div>';
printf('<input type="hidden" name="server_id" value="%s" />',$server->getIndex());
foreach ($this->template->resultsdata[$base]['attrs'] as $attr)
printf('<input type="hidden" name="attrs[]" value="%s" />',$attr);
echo '</div>';
echo '<table class="result_table" border="0">';
echo '<thead class="fixheader">';
echo '<tr class="heading">';
echo '<td>&nbsp;</td>';
echo '<td>&nbsp;</td>';
foreach (explode(',',$ado) as $attr) {
echo '<td>';
$this->draw('Name',$afattrs[$attr]);
echo '</td>';
}
echo '</tr>';
echo '</thead>';
echo '<tbody class="scroll">';
foreach ($results as $dndetails) {
$j++;
$dndetails = array_change_key_case($dndetails);
# Temporarily set our DN, for rendering that leverages our DN (eg: JpegPhoto)
$this->template->setDN($dndetails['dn']);
printf('<tr class="%s" id="tr_ma_%s" onclick="var cb=document.getElementById(\'ma_%s\'); cb.checked=!cb.checked;">',
$j%2 ? 'even' : 'odd',$j,$j);
# Is mass action enabled.
if ($_SESSION[APPCONFIG]->getValue('mass','enabled'))
printf('<td><input type="checkbox" id="ma_%s" name="dn[]" value="%s" onclick="this.checked=!this.checked;" /></td>',$j,$dndetails['dn']);
$href = sprintf('cmd=template_engine&server_id=%s&dn=%s',$server->getIndex(),$this->template->getDNEncode());
printf('<td class="icon"><a href="cmd.php?%s"><img src="%s/%s" alt="icon" /></a></td>',
htmlspecialchars($href),
IMGDIR,get_icon($server->getIndex(),$dndetails['dn']));
# We'll clone our attribute factory attributes, since we need to add the values to them for rendering.
foreach (explode(',',$ado) as $attr) {
# If the entry is blank, we'll draw an empty box and continue.
if (! isset($dndetails[$attr])) {
echo '<td>&nbsp;</td>';
continue;
}
# Special case for DNs
if ($attr == 'dn') {
$dn_display = strlen($dndetails['dn']) > 40
? sprintf('<acronym title="%s">%s...</acronym>',htmlspecialchars($dndetails['dn']),htmlspecialchars(substr($dndetails['dn'],0,40)))
: htmlspecialchars($dndetails['dn']);
printf('<td><a href="cmd.php?%s">%s</a></td>',htmlspecialchars($href),$dn_display);
continue;
}
# Set our object with our values
$afattrs[$attr]->clearValue();
if (is_array($dndetails[$attr]))
$afattrs[$attr]->initValue($dndetails[$attr]);
else
$afattrs[$attr]->initValue(array($dndetails[$attr]));
echo '<td>';
$this->draw('CurrentValues',$afattrs[$attr]);
echo '</td>';
}
echo '</tr>';
}
# Is mass action enabled.
if ($_SESSION[APPCONFIG]->getValue('mass','enabled')) {
printf('<tr class="%s">',++$j%2 ? 'odd' : 'even');
printf('<td><input type="checkbox" name="allbox" value="1" onclick="CheckAll(1,\'massform_\',%s);" /></td>',$counter);
printf('<td colspan="%s">',2+count(explode(',',$ado)));
foreach ($mass_actions as $display => $action)
printf('<button type="submit" name="cmd" value="%s">%s</button>&nbsp;&nbsp;',$action,$display);
echo '</td>';
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
echo '</form>';
echo "\n\n";
break;
default:
printf('Have ID [%s], run this query for page [%s]',$this->template_id,$this->page);
}
echo '</td></tr>';
echo '</table>';
echo '</div>';
echo "\n\n";
}
if (get_request('format','REQUEST',false,'table') == 'table')
printf('<script type="text/javascript" src="%sCheckAll.js"></script>',JSDIR);
}
public function drawSubTitle($subtitle=null) {
if (is_null($subtitle)) {
$server = $this->getServer();
$subtitle = sprintf('%s: <b>%s</b>',_('Server'),$server->getName());
if ($this->template) {
$subtitle .= '<br />';
$subtitle .= sprintf('%s: <b>%s</b>',('Query'),$this->template->getID() != 'none' ? $this->template->getTitle() : _('Default'));
if ($this->template->getName())
$subtitle .= sprintf(' (<b>%s</b>)',$this->template->getName(false));
}
}
parent::drawSubTitle($subtitle);
}
private function getAFattrs() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
$attribute_factory = new AttributeFactory();
$results = array();
foreach (explode(',',$this->template->getAttrDisplayOrder()) as $attr)
$results[strtolower($attr)] = $attribute_factory->newAttribute($attr,array('values'=>array()),$this->getServerID());
return $results;
}
private function getAjaxRef($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
return preg_replace('/=/','.',base64_encode($dn));
}
private function drawBaseTabs() {
# Setup the Javascript to show/hide our DIVs.
echo '<script type="text/javascript">';
echo 'function items() {';
echo 'var $items = new Array();';
$counter = 0;
foreach ($this->template->results as $base => $results)
printf("items[%s] = '%s';",$counter++,$this->getAjaxRef($base));
echo 'return items;';
echo '}</script>';
echo "\n\n";
echo '<table class="result_table" border="0">';
echo '<tr>';
$counter = 0;
foreach ($this->template->results as $base => $results) {
if (! $show = get_request('show','REQUEST'))
$show = ($counter++ === 0 ? $this->getAjaxRef($base) : null);
printf('<td id="CTL%s" onclick="return ajSHOWTHIS(\'DN\',\'%s\',\'CTL\');" style="background-color: %s;">%s</td>',
$this->getAjaxRef($base),
$this->getAjaxRef($base),
($show == $this->getAjaxRef($base) ? '#F0F0F0' : '#E0E0E0'),
htmlspecialchars($base));
}
echo '</tr>';
echo '</table>';
echo "\n\n";
}
private function drawResultsTable($base,$results) {
$server = $this->getServer();
echo '<table class="result" border="0">';
echo '<tr>';
printf('<td>%s: <b>%s</b><br/><br/><div class="execution_time">(%s %s)</div></td>',_('Entries found'),
number_format($results),$this->template->resultsdata[$base]['time'],_('seconds'));
if ($_SESSION[APPCONFIG]->isCommandAvailable('script','export') && $_SESSION[APPCONFIG]->isCommandAvailable('script','export_form')) {
$href = htmlspecialchars(sprintf('cmd.php?cmd=export_form&server_id=%s&scope=%s&dn=%s&filter=%s&attributes=%s',
$server->getIndex(),$this->template->resultsdata[$base]['scope'],
$base,rawurlencode($this->template->resultsdata[$base]['filter']),
rawurlencode(implode(', ',$this->template->resultsdata[$base]['attrs']))));
printf('<td style="text-align: right; width: 85%%"><small>[ <a href="%s"><img src="%s/save.png" alt="Save" /> %s</a> ]</small>',
$href,IMGDIR,_('export results'));
}
printf('<small>[ <img src="%s/rename.png" alt="rename" /> %s:',IMGDIR,_('Format'));
foreach (array('list','table') as $f) {
echo '&nbsp;';
if (get_request('format','REQUEST',false,$_SESSION[APPCONFIG]->getValue('search','display')) == $f) {
printf('<b>%s</b>',_($f));
} else {
$query_string = htmlspecialchars(sprintf('%s&format=%s&show=%s&focusbase=%s',array_to_query_string($_GET,array('format','meth')),$f,$this->getAjaxRef($base),$base));
if (isAjaxEnabled())
printf('<a href="cmd.php?%s" onclick="return ajDISPLAY(\'BODY\',\'%s\',\'%s\');">%s</a>',
$query_string,$query_string,_('Loading Search'),_($f));
else
printf('<a href="cmd.php?%s">%s</a>',$query_string,_($f));
}
}
echo ' ]</small>';
echo '<br />';
printf('<small>%s: <b>%s</b></small>',_('Base DN'),htmlspecialchars($base));
echo '<br />';
printf('<small>%s: <b>%s</b></small>',_('Filter performed'),htmlspecialchars($this->template->resultsdata[$base]['filter']));
echo '</td>';
echo '</tr>';
echo '</table>';
}
}
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are random passwords
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class RandomPasswordAttribute extends PasswordAttribute {
}
?>

View File

@ -0,0 +1,17 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are SAMBA passwords
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class SambaPasswordAttribute extends PasswordAttribute {
}
?>

View File

@ -0,0 +1,71 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an attribute whose values are in a predefined list
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class SelectionAttribute extends Attribute {
protected $selection = array();
protected $multiple;
protected $default;
public function __construct($name,$values,$server_id,$source=null) {
# Call our parent constructor
parent::__construct($name,$values,$server_id,$source);
# Our values are set by parent(). If we do have values, and the source was XML, move them to our selection.
if ($this->source == 'XML' && $this->values) {
$this->selection = $this->values;
$this->values = array();
}
if (isset($values['type']) && $values['type'] == 'multiselect')
$this->multiple = true;
else
$this->multiple = false;
}
public function addOption($value,$description) {
$this->selection[$value] = $description;
}
public function addValue($new_val,$i=-1) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->addOption($new_val,$i);
}
public function getOptionCount() {
return count($this->selection);
}
public function getSelection() {
return $this->selection;
}
public function autoValue($value) {
$this->selection = $value;
}
public function getDefault() {
return $this->default;
}
public function isMultiple() {
return $this->multiple;
}
public function setMultiple() {
$this->multiple = true;
}
}
?>

View File

@ -0,0 +1,19 @@
<?php
/**
* Classes and functions for the template engine.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents a shadow date attribute
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class ShadowAttribute extends Attribute {
public $shadow_before_today_attrs = array('shadowLastChange','shadowMin');
public $shadow_after_today_attrs = array('shadowMax','shadowExpire','shadowWarning','shadowInactive');
}
?>

1571
phpldapadmin/lib/Template.php Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

351
phpldapadmin/lib/Tree.php Executable file
View File

@ -0,0 +1,351 @@
<?php
/**
* Classes and functions for the LDAP tree.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Abstract class which represents the LDAP tree view ; the draw() method
* must be implemented by subclasses
*
* @package phpLDAPadmin
* @subpackage Tree
* @see HTMLTree AJAXTree
*/
abstract class Tree {
# Server that this tree represents
private $server_id = null;
# List of entries in the tree view cache
protected $entries = array();
/**
* Displays the LDAP tree
*/
abstract public function draw();
protected function __construct($server_id) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->server_id = $server_id;
}
/**
* Create an instance of the tree - this is used when we call this class directly
* Tree::getInstance($index)
*
* @return object Tree
*/
static public function getInstance($server_id) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$tree = get_cached_item($server_id,'tree');
if (! $tree) {
$server = $_SESSION[APPCONFIG]->getServer($server_id);
if (! $server)
return null;
$treeclass = $_SESSION[APPCONFIG]->getValue('appearance','tree');
$tree = new $treeclass($server_id);
# If we are not logged in, just return the empty tree.
if (is_null($server->getLogin(null)))
return $tree;
foreach ($server->getBaseDN(null) as $base) {
if ($base) {
$tree->addEntry($base);
if ($server->getValue('appearance','open_tree')) {
$baseEntry = $tree->getEntry($base);
$baseEntry->open();
}
}
}
set_cached_item($server_id,'tree','null',$tree);
}
return $tree;
}
/**
* Get the Server ID for this tree
*
* @return int Server ID that this tree is for
*/
protected function getServerID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->server_id);
return $this->server_id;
}
/**
* Get the server Object for this tree
*
* @return object Server Object for this tree
*/
protected function getServer() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $_SESSION[APPCONFIG]->getServer($this->server_id);
}
/**
* Get the entries that are BaseDN entries.
*
* @return array Base DN entries
*/
public function getBaseEntries() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$return = array();
foreach ($this->entries as $details)
if ($details->isBaseDN() AND ((! $this->getServer()->getValue('server','hide_noaccess_base')) OR $details->isInLdap()))
array_push($return,$details);
return $return;
}
/**
* This function will take the DN, convert it to lowercase and strip unnessary
* commas. This result will be used as the index for the tree object.
* Any display of a DN should use the object->dn entry, not the index.
* The reason we need to do this is because:
* uid=User A,ou=People,c=AU and
* uid=User B, ou=PeOpLe, c=au
* are infact in the same branch, but PLA will show them inconsistently.
*
* @param dn DN to clean
* @return dn Lowercase clean DN
*/
private function indexDN($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$index = strtolower(implode(',',pla_explode_dn($dn)));
if (DEBUG_ENABLED)
debug_log('Result (%s)',1,0,__FILE__,__LINE__,__METHOD__,$index);
return $index;
}
/**
* Get a tree entry
*
* @param dn DN to retrieve
* @return object Tree DN object
*/
public function getEntry($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$dnlower = $this->indexDN($dn);
if (isset($this->entries[$dnlower]))
return $this->entries[$dnlower];
else
return null;
}
/**
* Add an entry in the tree view ; the entry is added in the
* children array of its parent
*
* @param dn DN to add
* @param string $dn the dn of the entry to create
*/
public function addEntry($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$dnlower = $this->indexDN($dn);
# @todo Temporarily removed, some non-ascii char DNs that do exist, fail here for some reason?
#if (! ($server->dnExists($dn)))
# return;
if (isset($this->entries[$dnlower]))
debug_dump_backtrace('Calling add entry to an entry that ALREADY exists?',1);
if (DEBUG_ENABLED)
debug_log('New ENTRY (%s).',64,0,__FILE__,__LINE__,__METHOD__,$dn);
$tree_factory = new TreeItem($server->getIndex(),$dn);
$tree_factory->setObjectClasses($server->getDNAttrValue($dn,'objectClass'));
if ((($isleaf = $server->getDNAttrValue($dn,'hassubordinates')) && ! strcasecmp($isleaf[0],'false')))
$tree_factory->setLeaf();
$this->entries[$dnlower] = $tree_factory;
# Is this entry in a base entry?
if (in_array_ignore_case($dn,$server->getBaseDN(null))) {
$this->entries[$dnlower]->setBase();
# If the parent entry is not in the tree, we add it. This routine will in itself
# recall this method until we get to the top of the tree (the base).
} else {
$parent_dn = $server->getContainer($dn);
if (DEBUG_ENABLED)
debug_log('Parent DNs (%s)',64,0,__FILE__,__LINE__,__METHOD__,$parent_dn);
if ($parent_dn) {
$parent_entry = $this->getEntry($parent_dn);
if (! $parent_entry) {
$this->addEntry($parent_dn);
$parent_entry = $this->getEntry($parent_dn);
}
# Update this DN's parent's children list as well.
$parent_entry->addChild($dn);
}
}
}
/**
* Delete an entry from the tree view ; the entry is deleted from the
* children array of its parent
*
* @param dn DN to remote
*/
public function delEntry($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$dnlower = $this->indexDN($dn);
if (isset($this->entries[$dnlower]))
unset($this->entries[$dnlower]);
# Delete entry from parent's children as well.
$parent_dn = $server->getContainer($dn);
$parent_entry = $this->getEntry($parent_dn);
if ($parent_entry)
$parent_entry->delChild($dn);
}
/**
* Rename an entry in the tree
*
* @param dn Old DN
* @param dn New DN
*/
public function renameEntry($dnOLD,$dnNEW) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$dnlowerOLD = $this->indexDN($dnOLD);
$dnlowerNEW = $this->indexDN($dnNEW);
$this->entries[$dnlowerNEW] = $this->entries[$dnlowerOLD];
if ($dnlowerOLD != $dnlowerNEW)
unset($this->entries[$dnlowerOLD]);
$this->entries[$dnlowerNEW]->rename($dnNEW);
# Update the parent's children
$parentNEW = $server->getContainer($dnNEW);
$parentOLD = $server->getContainer($dnOLD);
$parent_entry = $this->getEntry($parentNEW);
if ($parent_entry)
$parent_entry->addChild($dnNEW);
$parent_entry = $this->getEntry($parentOLD);
if ($parent_entry)
$parent_entry->delChild($dnOLD);
}
/**
* Read the children of a tree entry
*
* @param dn DN of the entry
* @param boolean LDAP Size Limit
*/
public function readChildren($dn,$nolimit=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$server = $this->getServer();
$dnlower = $this->indexDN($dn);
if (! isset($this->entries[$dnlower]))
debug_dump_backtrace('Reading children on an entry that isnt set? '.$dnlower,true);
$ldap['child_limit'] = $nolimit ? 0 : $_SESSION[APPCONFIG]->getValue('search','size_limit');
$ldap['filter'] = $_SESSION[APPCONFIG]->getValue('appearance','tree_filter');
$ldap['deref'] = $_SESSION[APPCONFIG]->getValue('deref','tree');
# Perform the query to get the children.
$ldap['children'] = $server->getContainerContents($dn,null,$ldap['child_limit'],$ldap['filter'],$ldap['deref']);
if (! count($ldap['children'])) {
$this->entries[$dnlower]->unsetSizeLimited();
return;
}
if (DEBUG_ENABLED)
debug_log('Children of (%s) are (%s)',64,0,__FILE__,__LINE__,__METHOD__,$dn,$ldap['children']);
# Relax our execution time, it might take some time to load this
if ($nolimit)
@set_time_limit($_SESSION[APPCONFIG]->getValue('search','time_limit'));
$this->entries[$dnlower]->readingChildren(true);
foreach ($ldap['children'] as $child) {
if (DEBUG_ENABLED)
debug_log('Adding (%s)',64,0,__FILE__,__LINE__,__METHOD__,$child);
if (! in_array($child,$this->entries[$dnlower]->getChildren()))
$this->entries[$dnlower]->addChild($child);
}
$this->entries[$dnlower]->readingChildren(false);
if (count($this->entries[$dnlower]->getChildren()) == $ldap['child_limit'])
$this->entries[$dnlower]->setSizeLimited();
else
$this->entries[$dnlower]->unsetSizeLimited();
}
/**
* Return the number of children an entry has. Optionally autoread the child entry.
*
* @param dn DN of the entry
* @param boolean LDAP Size Limit
*/
protected function readChildrenNumber($dn,$nolimit=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$dnlower = $this->indexDN($dn);
if (! isset($this->entries[$dnlower]))
debug_dump_backtrace('Reading children on an entry that isnt set?',true);
# Read the entry if we havent got it yet.
if (! $this->entries[$dnlower]->isLeaf() && ! $this->entries[$dnlower]->getChildren())
$this->readChildren($dn,$nolimit);
return count($this->entries[$dnlower]->getChildren());
}
}
?>

312
phpldapadmin/lib/TreeItem.php Executable file
View File

@ -0,0 +1,312 @@
<?php
/**
* Classes and functions for the LDAP tree.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Represents an item in the tree.
*
* @package phpLDAPadmin
* @subpackage Tree
*/
class TreeItem {
# This entry's DN
protected $dn;
# The server this entry belongs to.
private $server_id;
# The objectclasses in LDAP, used to deterimine the icon and template
protected $objectclasses = array();
# Is this a base entry?
private $base_entry = false;
# Array of dn - the children
private $children = array();
# An icon file path
protected $icon;
# Is the entry a leaf?
private $leaf = false;
# Is the node open?
private $open = false;
# Is the size of children limited?
private $size_limited = true;
# Last template used to edit this entry
private $template = null;
# Do we need to sort the children
private $childsort = true;
# Are we reading the children
private $reading_children = false;
public function __construct($server_id,$dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->server_id = $server_id;
$this->dn = $dn;
}
/**
* Get the DN of this tree item.
*
* @return DN The DN of this item.
*/
public function getDN() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->dn);
return $this->dn;
}
public function getDNEncode() {
return urlencode(preg_replace('/%([0-9a-fA-F]+)/',"%25\\1",$this->dn));
}
/**
* Get the RDN of this tree items DN.
*
* @return RDN The RDN of this items DN.
*/
public function getRDN() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
return get_rdn($this->getDn(),0,true);
}
/**
* Set this item as a LDAP base DN item.
*/
public function setBase() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->base_entry = true;
}
/**
* Return if this item is a base DN item.
*/
public function isBaseDN() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->base_entry);
return $this->base_entry;
}
public function setObjectClasses($oc) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->objectclasses = $oc;
}
public function getObjectClasses() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->objectclasses);
return $this->objectclasses;
}
public function isInLDAP() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
return count($this->objectclasses) ? true : false;
}
/**
* Returns null if the children have never be defined
* or an array of the dn of the children
*/
public function getChildren() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->children);
if ($this->childsort && ! $this->reading_children) {
usort($this->children,'pla_compare_dns');
$this->childsort = false;
}
return $this->children;
}
public function readingChildren($bool) {
$this->reading_children = $bool;
}
/**
* Do the children require resorting
*/
public function isChildSorted() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->childsort);
return $this->childsort;
}
/**
* Mark the children as sorted
*/
public function childSorted() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->childsort = false;
}
/**
* Add a child to this DN entry.
*
* @param DN The DN to add.
*/
public function addChild($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (in_array($dn,$this->children))
return;
array_push($this->children,$dn);
$this->childsort = true;
}
/**
* Delete a child from this DN entry.
*
* @param DN The DN to add.
*/
public function delChild($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->children) {
# If the parent hasnt been opened in the tree, then there wont be any children.
$index = array_search($dn,$this->children);
if ($index !== false)
unset($this->children[$index]);
}
}
/**
* Rename this DN.
*
* @param DN The DN to rename to.
*/
public function rename($dn) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->dn = $dn;
}
/**
* Return if this item has been opened.
*/
public function isOpened() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->open);
return $this->open;
}
/**
* Mark this node as closed.
*/
public function close() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->open = false;
}
/**
* Opens the node ; the children of the node must have been defined
*/
public function open() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->open = true;
}
/**
* Mark this node as a leaf.
*/
public function setLeaf() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->leaf = true;
}
/**
* Return if this node is a leaf.
*/
public function isLeaf() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->leaf);
return $this->leaf;
}
/**
* Returns the path of the icon file used to represent this node ;
* If the icon hasnt been set, it will call get_icon()
*/
public function getIcon() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->icon);
if (! $this->icon)
$this->icon = get_icon($this->server_id,$this->dn,$this->objectclasses);
return $this->icon;
}
/**
* Mark this node as a size limited (it wont have all its children).
*/
public function setSizeLimited() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->size_limited = true;
}
/**
* Clear the size limited flag.
*/
public function unsetSizeLimited() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->size_limited = false;
}
/**
* Return if this node has hit an LDAP size limit (and thus doesnt have all its children).
*/
public function isSizeLimited() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $this->size_limited;
}
public function setTemplate($template) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,1,__FILE__,__LINE__,__METHOD__,$fargs);
$this->template = $template;
}
public function getTemplate() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',33,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $this->template;
}
}
?>

99
phpldapadmin/lib/Visitor.php Executable file
View File

@ -0,0 +1,99 @@
<?php
/**
* Classes and functions for the template engines.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**/
# To make it easier to debug this script, define these constants, which will add some __METHOD__ location displays to the rendered text.
define('DEBUGTMP',0);
define('DEBUGTMPSUB',0);
/**
* Abstract Visitor class
*
* @package phpLDAPadmin
* @subpackage Templates
*/
abstract class Visitor {
# The server that was used to configure the templates
protected $server_id;
public function __call($method,$args) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! in_array($method,array('get','visit','draw')))
debug_dump_backtrace(sprintf('Incorrect use of method loading [%s]',$method),1);
$methods = array();
$fnct = array_shift($args);
$object = $args[0];
$class = get_class($object);
$call = "$method$fnct$class";
array_push($methods,$call);
while ($class && ! method_exists($this,$call)) {
if (defined('DEBUGTMP') && DEBUGTMP)
printf('<font size=-2><i>Class (%s): Method doesnt exist (%s,%s)</i></font><br />',$class,get_class($this),$call);
$class = get_parent_class($class);
$call = "$method$fnct$class";
array_push($methods,$call);
}
if (defined('DEBUGTMP') && DEBUGTMP)
printf('<font size=-2><i>Calling Methods: %s</i></font><br />',implode('|',$methods));
if (defined('DEBUGTMP') && DEBUGTMP && method_exists($this,$call))
printf('<font size=-2>Method Exists: %s::%s (%s)</font><br />',get_class($this),$call,$args);
if (method_exists($this,$call)) {
$r = call_user_func_array(array($this,$call),$args);
if (isset($r))
return $r;
else
return;
} elseif (DEBUG_ENABLED) {
debug_log('Doesnt exist param (%s,%s)',1,0,__FILE__,__LINE__,__METHOD__,$method,$fnct);
}
printf('<font size=-2><i>NO Methods: %s</i></font><br />',implode('|',$methods));
}
/**
* Return the LDAP server ID
*
* @return int Server ID
*/
public function getServerID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->server_id);
if (isset($this->server_id))
return $this->server_id;
else
return null;
}
/**
* Return this LDAP Server object
*
* @return object DataStore Server
*/
protected function getServer() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $_SESSION[APPCONFIG]->getServer($this->getServerID());
}
}
?>

480
phpldapadmin/lib/blowfish.php Executable file
View File

@ -0,0 +1,480 @@
<?php
/**
* The Cipher_blowfish:: class implements the Cipher interface enryption data
* using the Blowfish algorithm.
*
* $Horde: horde/lib/Cipher/blowfish.php,v 1.2.2.3 2003/01/03 13:23:22 jan Exp $
*
* Copyright 2002-2003 Mike Cochrane <mike@graftonhall.co.nz>
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see https://www.fsf.org/copyleft/lgpl.html.
*
* @author Mike Cochrane <mike@graftonhall.co.nz>
* @version $Revision$
* @since Horde 2.2
* @package horde.cipher
*/
/**
* @package horde.cipher
*/
// Change for phpMyAdmin by lem9:
//class Horde_Cipher_blowfish extends Horde_Cipher {
class Horde_Cipher_blowfish {
/* Pi Array */
public $p = array(
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
0x9216D5D9, 0x8979FB1B);
/* S Boxes */
public $s1 = array(
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A);
public $s2 = array(
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7);
public $s3 = array(
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0);
public $s4 = array(
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6);
/* The number of rounds to do */
public $_rounds = 16;
/* Constructor */
function Cipher_blowfish($params = null)
{
}
/**
* Set the key to be used for en/decryption
*
* @param String $key The key to use
*/
function setKey($key)
{
$key = $this->_formatKey($key);
$keyPos = $keyXor = 0;
$iMax = count($this->p);
$keyLen = count($key);
for ($i = 0; $i < $iMax; $i++) {
for ($t = 0; $t < 4; $t++) {
$keyXor = ($keyXor << 8) | (($key[$keyPos]) & 0x0ff);
if (++$keyPos == $keyLen) {
$keyPos = 0;
}
}
$this->p[$i] = $this->p[$i] ^ $keyXor;
}
$encZero = array('L' => 0, 'R' => 0);
for ($i = 0; $i + 1 < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->p[$i] = $encZero['L'];
$this->p[$i + 1] = $encZero['R'];
}
$iMax = count($this->s1);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s1[$i] = $encZero['L'];
$this->s1[$i + 1] = $encZero['R'];
}
$iMax = count($this->s2);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s2[$i] = $encZero['L'];
$this->s2[$i + 1] = $encZero['R'];
}
$iMax = count($this->s3);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s3[$i] = $encZero['L'];
$this->s3[$i + 1] = $encZero['R'];
}
$iMax = count($this->s4);
for ($i = 0; $i < $iMax; $i += 2) {
$encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
$this->s4[$i] = $encZero['L'];
$this->s4[$i + 1] = $encZero['R'];
}
}
/**
* Return the size of the blocks that this cipher needs
*
* @return Integer The number of characters per block
*/
function getBlockSize()
{
return 8;
}
/**
* Encrypt a block on data.
*
* @param String $block The data to encrypt
* @param optional String $key The key to use
*
* @return String the encrypted output
*/
function encryptBlock($block, $key = null)
{
if (!is_null($key)) {
$this->setKey($key);
}
list($L, $R) = array_values(unpack('N*', $block));
$parts = $this->_encryptBlock($L, $R);
return pack("NN", $parts['L'], $parts['R']);
}
/**
* Encrypt a block on data.
*
* @param String $L The data to encrypt.
* @param String $R The data to encrypt.
*
* @return String The encrypted output.
*/
function _encryptBlock($L, $R)
{
$L ^= $this->p[0];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[1];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[2];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[3];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[4];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[5];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[6];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[7];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[8];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[9];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[10];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[11];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[12];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[13];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[14];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[15];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[16];
$R ^= $this->p[17];
return array('L' => $R, 'R' => $L);
}
/**
* Decrypt a block on data.
*
* @param String $block The data to decrypt
* @param optional String $key The key to use
*
* @return String the decrypted output
*/
function decryptBlock($block, $key = null)
{
if (!is_null($key)) {
$this->setKey($key);
}
$unpack = unpack('N*', $block);
if (! is_array($unpack))
error(
sprintf('BLOWFISH: decryptBock()<br>We expected unpack to produce an array, but instead it produced [%s]. This function was entered with (%s,%s). If you think that this is a bug, then please tell the PLA developers how you got here. You are using PLA [%s,%s]',
serialize($unpack),$block,$key,app_version(),phpversion()),'error','index.php');
list($L, $R) = array_values($unpack);
$L ^= $this->p[17];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[16];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[15];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[14];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[13];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[12];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[11];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[10];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[9];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[8];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[7];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[6];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[5];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[4];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[3];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[2];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[1];
$decrypted = pack("NN", $R ^ $this->p[0], $L);
return $decrypted;
}
/**
* Converts a text key into an array.
*
* @return array The key.
*/
function _formatKey($key)
{
return array_values(unpack('C*', $key));
}
}
?>

334
phpldapadmin/lib/common.php Executable file
View File

@ -0,0 +1,334 @@
<?php
/**
* Contains code to be executed at the top of each application page.
* include this file at the top of every PHP file.
*
* This file will "pre-initialise" an application environment so that any PHP file will have a consistent
* environment with other application PHP files.
*
* This code WILL NOT check that all required functions are usable/readable, etc. This process has
* been moved to index.php (which really is only called once when a browser hits the application for the first time).
*
* The list of ADDITIONAL function files is now defined in functions.php.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* @package phpLDAPadmin
* @subpackage Functions
*/
/* Initialize the app array. The app array is initialised each invocation of a PLA script and therefore
has no state between invocations.*/
$app = array();
/** The index we will store our config in $_SESSION */
if (! defined('APPCONFIG'))
define('APPCONFIG','plaConfig');
/**
* Catch any scripts that are called directly.
* If they are called directly, then they should be routed back through index.php
*/
$app['direct_scripts'] = array('cmd.php','index.php',
'view_jpeg_photo.php','entry_chooser.php',
'password_checker.php','download_binary_attr.php',
'unserialize.php'
);
# Which script was invoked.
$app['script_running'] = $_SERVER['SCRIPT_NAME'];
foreach ($app['direct_scripts'] as $script) {
$app['scriptOK'] = false;
if (preg_match('/'.$script.'$/',$app['script_running'])) {
$app['scriptOK'] = true;
break;
}
}
# Anything in the tools dir or cron dir can be executed directly.
if ((! $app['scriptOK'] && preg_match('/^\/[cron|tools]/',$app['script_running'])) || ! isset($_SERVER['SERVER_SOFTWARE']))
$app['scriptOK'] = true;
if (! $app['scriptOK']) {
if (isset($_REQUEST['server_id']))
header(sprintf('Location: index.php?server_id=%s',$_REQUEST['server_id']));
else
header('Location: index.php');
die();
}
/**
* All commands are disabled in read-only unless specified here
*/
$app['readwrite_cmds'] = array(
'collapse','draw_tree_node','expand',
'compare_form','compare',
'download_binary_attr','view_jpeg_photo',
'entry_chooser',
'export_form','export',
'login_form','login','logout',
'monitor',
'password_checker',
'purge_cache',
'refresh','schema','query_engine','server_info','show_cache','template_engine',
'welcome'
);
/**
* Timer stopwatch, used to instrument the application
*/
if (! function_exists('stopwatch')) {
function stopwatch() {
static $mt_previous = 0;
list($usec,$sec) = explode(' ',microtime());
$mt_current = (float)$usec + (float)$sec;
if (! $mt_previous) {
$mt_previous = $mt_current;
return 0;
} else {
$mt_diff = ($mt_current - $mt_previous);
$mt_previous = $mt_current;
return sprintf('%.5f',$mt_diff);
}
}
# For compatability - if common has been sourced a second time, then return to the calling script.
} else {
return;
}
# Set the defualt time zone, if it isnt set in php.ini
if (function_exists('date_default_timezone_set') && ! ini_get('date.timezone'))
date_default_timezone_set('UTC');
# If we are called from index.php, LIBDIR will be set, all other calls to common.php dont need to set it.
if (! defined('LIBDIR'))
define('LIBDIR','../lib/');
# For PHP5 backward/forward compatibility
if (! defined('E_STRICT'))
define('E_STRICT',2048);
# General functions needed to proceed.
ob_start();
require_once realpath(LIBDIR.'functions.php');
if (ob_get_level())
ob_end_clean();
/**
* Turn on all notices and warnings. This helps us write cleaner code (we hope at least)
* Our custom error handler receives all error notices that pass the error_reporting()
* level set above.
*/
# Call our custom defined error handler, if it is defined in functions.php
if (function_exists('app_error_handler'))
set_error_handler('app_error_handler');
# Disable error reporting until all our required functions are loaded.
error_reporting(0);
/**
* functions.php should have defined our $app['function_files'] array, listing all our
* required functions (order IS important).
* index.php should have checked they exist and are usable - we'll assume that the user
* has been via index.php, and fixed any problems already.
*/
ob_start();
if (isset($app['function_files']) && is_array($app['function_files']))
foreach ($app['function_files'] as $script)
require_once realpath($script);
# Now read in config_default.php
require_once realpath(LIBDIR.'config_default.php');
if (ob_get_level())
ob_end_clean();
# We are now ready for error reporting.
error_reporting(E_ALL);
# Start our session.
app_session_start();
# See if we have a session, we can then get our theme out
$app['theme'] = 'default';
if (isset($_SESSION[APPCONFIG]))
if (is_dir(realpath(sprintf('images/%s',$_SESSION[APPCONFIG]->getValue('appearance','theme'))))
&& is_file(realpath(sprintf('css/%s/%s',$_SESSION[APPCONFIG]->getValue('appearance','theme'),$_SESSION[APPCONFIG]->getValue('appearance','stylesheet')))))
$app['theme'] = $_SESSION[APPCONFIG]->getValue('appearance','theme');
define('CSSDIR',sprintf('css/%s',$app['theme']));
define('IMGDIR',sprintf('images/%s',$app['theme']));
# Initialise the hooks
if (file_exists(LIBDIR.'hooks.php'))
require_once LIBDIR.'hooks.php';
# If we get here, and $_SESSION[APPCONFIG] is not set, then redirect the user to the index.
if (isset($_SERVER['SERVER_SOFTWARE']) && ! isset($_SESSION[APPCONFIG])) {
if ($_SERVER['QUERY_STRING'])
header(sprintf('Location: index.php?URI=%s',base64_encode($_SERVER['QUERY_STRING'])));
else
header('Location: index.php');
die();
} else {
# SF Bug #1903987
if (! method_exists($_SESSION[APPCONFIG],'CheckCustom'))
error('Unknown situation, $_SESSION[APPCONFIG] exists, but method CheckCustom() does not','error',null,true,true);
# Check our custom variables.
# @todo Change this so that we dont process a cached session.
$_SESSION[APPCONFIG]->CheckCustom();
}
# Check for safe mode.
if (@ini_get('safe_mode') && ! get_request('cmd','GET'))
system_message(array(
'title'=>_('PHP Safe Mode'),
'body'=>_('You have PHP Safe Mode enabled. This application may work unexpectedly in Safe Mode.'),
'type'=>'info'));
# Set our timezone, if it is specified in config.php
if ($_SESSION[APPCONFIG]->getValue('appearance','timezone'))
date_default_timezone_set($_SESSION[APPCONFIG]->getValue('appearance','timezone'));
# If we are here, $_SESSION is set - so enabled DEBUGing if it has been configured.
if (($_SESSION[APPCONFIG]->getValue('debug','syslog') || $_SESSION[APPCONFIG]->getValue('debug','file'))
&& $_SESSION[APPCONFIG]->getValue('debug','level'))
define('DEBUG_ENABLED',1);
else
define('DEBUG_ENABLED',0);
if (DEBUG_ENABLED)
debug_log('Application (%s) initialised and starting with (%s).',1,0,__FILE__,__LINE__,__METHOD__,
app_version(),$_REQUEST);
# Set our PHP timelimit.
if ($_SESSION[APPCONFIG]->getValue('session','timelimit') && ! @ini_get('safe_mode'))
set_time_limit($_SESSION[APPCONFIG]->getValue('session','timelimit'));
# If debug mode is set, increase the time_limit, since we probably need it.
if (DEBUG_ENABLED && $_SESSION[APPCONFIG]->getValue('session','timelimit') && ! @ini_get('safe_mode'))
set_time_limit($_SESSION[APPCONFIG]->getValue('session','timelimit') * 5);
/**
* Language configuration. Auto or specified?
* Shall we attempt to auto-determine the language?
*/
# If we are in safe mode, and LANG is not in the allowed vars, display an error.
if (@ini_get('safe_mode') && ! in_array('LANG',explode(',',@ini_get('safe_mode_allowed_env_vars'))))
error('You are running in SAFE_MODE, but LANG is not in the safe_mode_allowed_env_vars. Please add LANG to safe_mode_allowed_env_vars','error',true,false);
$app['language'] = $_SESSION[APPCONFIG]->getValue('appearance','language');
if ($app['language'] == 'auto') {
# Make sure their browser correctly reports language. If not, skip this.
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
# Get the languages which are spetcified in the HTTP header
$app['lang_http'] = preg_split ('/[;,]+/',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach ($app['lang_http'] as $key => $value) {
if (substr($value,0,2) == 'q=') {
unset($app['lang_http'][$key]);
continue;
}
$value = preg_split('/[-]+/',$value);
if (sizeof($value) == 2)
$app['lang_http'][$key] = strtolower($value[0]).'_'.strtoupper($value[1]);
else
$app['lang_http'][$key] = auto_lang(strtolower($value[0]));
}
$app['lang_http'] = array_unique($app['lang_http']);
foreach ($app['lang_http'] as $lang) {
$app['language_dir'] = LANGDIR.$lang;
if ((substr($lang,0,2) == 'en') ||
(file_exists($app['language_dir']) && is_readable($app['language_dir']))) {
# Set language
putenv('LANG='.$lang); # e.g. LANG=de_DE
$lang .= '.UTF-8';
setlocale(LC_ALL,$lang); # set LC_ALL to de_DE
bindtextdomain('messages',LANGDIR);
bind_textdomain_codeset('messages','UTF-8');
textdomain('messages');
header('Content-type: text/html; charset=UTF-8',true);
break;
}
}
#todo Generate an error if language doesnt exist.
}
} else {
# Grab the language file configured in config.php
#todo Generate an error if language doesnt exist.
if ($app['language'] != null) {
if (strcmp($app['language'],'english') == 0)
$app['language'] = 'en_GB';
# Set language
putenv('LANG='.$app['language']); # e.g. LANG=de_DE
$app['language'] .= '.UTF-8';
setlocale(LC_ALL,$app['language']); # set LC_ALL to de_DE
bindtextdomain('messages',LANGDIR);
bind_textdomain_codeset('messages','UTF-8');
textdomain('messages');
header('Content-type: text/html; charset=UTF-8',true);
}
}
/**
* Strip slashes from GET, POST, and COOKIE variables if this
* PHP install is configured to automatically addslashes()
*/
if (@get_magic_quotes_gpc() && (! isset($slashes_stripped) || ! $slashes_stripped)) {
array_stripslashes($_REQUEST);
array_stripslashes($_GET);
array_stripslashes($_POST);
array_stripslashes($_COOKIE);
$slashes_stripped = true;
}
# Create our application repository variable.
$app['server'] = $_SESSION[APPCONFIG]->getServer(get_request('server_id','REQUEST'));
/**
* Look/evaluate our timeout
*/
if (! $app['server']->isSessionValid()) {
system_message(array(
'title'=>_('Session Timed Out'),
'body'=>sprintf('%s %s %s',
_('Your Session timed out after'),$app['server']->getValue('login','timeout'),
_('min. of inactivity. You have been automatically logged out.')),
'type'=>'info'),sprintf('index.php?server_id=%s&refresh=SID_%s',$app['server']->getIndex(),$app['server']->getIndex()));
die();
}
# If syslog is enabled, we need to include the supporting file.
if ($_SESSION[APPCONFIG]->getValue('debug','syslog'))
require LIBDIR.'syslog.php';
/**
* At this point we have read all our additional function PHP files and our configuration.
* If we are using hooks, run the session_init hook.
*/
if (function_exists('run_hook'))
run_hook('post_session_init',array());
?>

View File

@ -0,0 +1,808 @@
<?php
/**
* Configuration processing and defaults.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
* @todo Add validation of set variables to enforce limits or particular values.
*/
/** The minimum version of PHP required to run phpLDAPadmin. */
define('REQUIRED_PHP_VERSION','5.0.0');
/**
* The config class contains all our configuration settings for a session.
*
* An instance of this class should be stored in $_SESSION to maintain state, and to avoid
* rebuilding/rereading it at the state of each page output.
*
* @package phpLDAPadmin
* @subpackage Tree
*/
class Config {
public $custom;
protected $default;
protected $servers = array();
public $hooks = array();
public function __construct() {
$this->custom = new stdClass;
$this->default = new stdClass;
/*
* What to do after entry creation :
* 2 : display the creation form again
* 1 : display the new created entry
* 0 : display the choice between 1 and 2
*/
$this->default->appearance['action_after_creation'] = array(
'desc'=>'Display the new created entry',
'default'=>1);
## Appearance Attributes
/** Anonymous implies read only
* Set to true if you want LDAP data to be displayed read-only (without input fields)
* when a user logs in to a server anonymously
*/
$this->default->appearance['anonymous_bind_implies_read_only'] = array(
'desc'=>'Display as read only if user logs in with anonymous bind',
'default'=>true);
$this->default->appearance['attr_display_order'] = array(
'desc'=>'Custom order to display attributes',
'default'=>array());
/*
* @todo Compression is not working,
* purge_cache shows blank,
* tree refresh shows blank - and if view_tree_node is modified to compress output, then previously opened items show up as compressed data.
*/
$this->default->appearance['compress'] = array(
'desc'=>'Compress Output',
'untested'=>true,
'default'=>false);
$this->default->appearance['control_icons'] = array(
'desc'=>'Show the control as icons or text',
'default'=>false);
$this->default->appearance['custom_templates_only'] = array(
'desc'=>'Only display the custom templates.',
'default'=>false);
$this->default->appearance['date'] = array(
'desc'=>'Date format whenever dates are shown',
'default'=>'%A %e %B %Y');
$this->default->appearance['date_attrs'] = array(
'desc'=>'Array of attributes that should show a jscalendar',
'default'=>array('shadowExpire'=>'%es','shadowLastChange'=>'%es'));
$this->default->appearance['date_attrs_showtime'] = array(
'desc'=>'Array of attributes that should show a the time when showing the jscalendar',
'default'=>array(''));
$this->default->appearance['disable_default_template'] = array(
'desc'=>'Disabled the Default Template',
'default'=>false);
$this->default->appearance['disable_default_leaf'] = array(
'desc'=>'Disabled creating leaf entries in the Default Template',
'default'=>false);
$this->default->appearance['friendly_attrs'] = array(
'desc'=>'Friendly names for attributes',
'default'=>array());
$this->default->appearance['hide_attrs'] = array(
'desc'=>'Hide attributes from display',
'default'=>array());
$this->default->appearance['hide_attrs_exempt'] = array(
'desc'=>'Group DN, where membership will exempt the users from hide_attrs',
'default'=>null);
$this->default->appearance['hide_debug_info'] = array(
'desc'=>'Hide the features that may provide sensitive debugging information to the browser',
'default'=>true);
$this->default->appearance['hide_template_regexp'] = array(
'desc'=>'Templates that are disabled by their regex are not shown',
'default'=>false);
$this->default->appearance['hide_template_warning'] = array(
'desc'=>'Hide template errors from being displayed',
'default'=>false);
/** Language
* The language setting. If you set this to 'auto', phpLDAPadmin will
* attempt to determine your language automatically. Otherwise, set
* this to your applicable language in xx_XX format.
* Localization is not complete yet, but most strings have been translated.
* Please help by writing language files.
*/
$this->default->appearance['language'] = array(
'desc'=>'Language',
'default'=>'auto');
$this->default->appearance['max_add_attrs'] = array(
'desc'=>'Maximum number of attrs to show in the add attr form',
'default'=>10);
/**
* If you want certain attributes to be editable as multi-line, include them in this list
* A multi-line textarea will be drawn instead of a single-line text field
*/
$this->default->appearance['multi_line_attributes'] = array(
'desc'=>'Attributes to show as multiline attributes',
'default'=>array('postalAddress','homePostalAddress','personalSignature','description','mailReplyText'));
/**
* A list of syntax OIDs which support multi-line attribute values:
*/
$this->default->appearance['multi_line_syntax_oids'] = array(
'desc'=>'Attributes to show as multiline attributes',
'default'=>array(
// octet string syntax OID:
'1.3.6.1.4.1.1466.115.121.1.40',
// postal address syntax OID:
'1.3.6.1.4.1.1466.115.121.1.41'));
/** Obfuscate Password
* If true, display all password hash values as "******". Note that clear-text
* passwords will always be displayed as "******", regardless of this setting.
*/
$this->default->appearance['obfuscate_password_display'] = array(
'desc'=>'Obfuscate the display of passwords',
'default'=>true);
$this->default->appearance['page_title'] = array(
'desc'=>'Change the page title to this text',
'default'=>'');
$this->default->appearance['rdn_all_attrs'] = array(
'desc'=>'Whether to show all attributes in the RDN chooser, or just the required ones',
'default'=>true);
$this->default->appearance['readonly_attrs'] = array(
'desc'=>'Mark these attributes as readonly',
'default'=>array());
$this->default->appearance['readonly_attrs_exempt'] = array(
'desc'=>'Group DN, where membership will exempt the users from readonly attrs',
'default'=>null);
$this->default->appearance['remoteurls'] = array(
'desc'=>'Whether to include renders for remote URLs',
'default'=>true);
$this->default->appearance['show_clear_password'] = array(
'desc'=>'Whether to show clear passwords if we dont obfuscate them',
'default'=>false);
$this->default->appearance['show_hints'] = array(
'desc'=>'Show helpful hints',
'default'=>true);
$this->default->appearance['show_top_create'] = array(
'desc'=>'Show a additional create link on the top of the list if there are more than 10 entries',
'default'=>true);
$this->default->appearance['show_schema_link'] = array(
'desc'=>'Show the schema link for each attribute',
'default'=>true);
$this->default->appearance['show_attribute_notes'] = array(
'desc'=>'Show notes for each attribute',
'default'=>true);
$this->default->appearance['stylesheet'] = array(
'desc'=>'Style sheet to use',
'default'=>'style.css');
$this->default->appearance['theme'] = array(
'desc'=>'Which theme to use',
'default'=>'default');
$this->default->appearance['timezone'] = array(
'desc'=>'Define our timezone, if not defined in php.ini',
'default'=>null);
$this->default->appearance['tree'] = array(
'desc'=>'Class name which inherits from Tree class and implements the draw() method',
'default'=>'AJAXTree');
/** Tree display
* An array of format strings used to display enties in the
* tree viewer (left-hand side). The first format string that
* is completely defined (i.e., does not reference attributes
* that are not defined the object). If there is no format
* string that is completely defined, the last one is used.
*
* You can use special tokens to draw the entries as you wish.
* You can even mix in HTML to format the string.
* Here are all the tokens you can use:
* %rdn - draw the RDN of the entry (ie, "cn=Dave")
* %dn - draw the DN of the entry (ie, "cn=Dave,ou=People,dc=example,dc=com"
* %rdnValue - draw the value of the RDN (ie, instead of "cn=Dave", just draw "Dave")
* %[attrname]- draw the value (or values) of the specified attribute.
* example: %gidNumber
*
* Any multivalued attributes will be displayed as a comma separated list.
*
* Examples:
*
* To draw the gidNumber and uidNumber to the right of the RDN in a small, gray font:
* '%rdn <small style="color:gray">( %gidNumber / %uidNumber )</small>'
* To draw the full DN of each entry:
* '%dn'
* To draw the objectClasses to the right in parenthesis:
* '%rdn <small style="color: gray">( %objectClass )</small>'
* To draw the user-friendly RDN value (ie, instead of "cn=Dave", just draw "Dave"):
* '%rdnValue'
*/
$this->default->appearance['tree_display_format'] = array(
'desc'=>'LDAP attribute to show in the tree',
'default'=>array('%rdn'));
$this->default->appearance['tree_height'] = array(
'desc'=>'Pixel height of the tree browser',
'default'=>null);
$this->default->appearance['tree_width'] = array(
'desc'=>'Pixel width of the tree browser',
'default'=>null);
/** Tree display filter
* LDAP filter used to search entries for the tree viewer (left-hand side)
*/
$this->default->appearance['tree_filter'] = array(
'desc'=>'LDAP search filter for the tree entries',
'default'=>'(objectClass=*)');
# PLA will not display the header and footer parts in minimal mode.
$this->default->appearance['minimalMode'] = array(
'desc'=>'Minimal mode hides header and footer parts',
'default'=>false);
## Caching
$this->default->cache['schema'] = array(
'desc'=>'Cache Schema Activity',
'default'=>true);
$this->default->cache['query'] = array(
'desc'=>'Cache Query Configuration',
'default'=>true);
$this->default->cache['query_time'] = array(
'desc'=>'Cache the query configuration for atleast this amount of time in seconds',
'default'=>5);
$this->default->cache['template'] = array(
'desc'=>'Cache Template Configuration',
'default'=>true);
$this->default->cache['template_time'] = array(
'desc'=>'Cache the template configuration for atleast this amount of time in seconds',
'default'=>60);
$this->default->cache['tree'] = array(
'desc'=>'Cache Browser Tree',
'default'=>true);
/** Confirm actions
*/
$this->default->confirm['copy'] = array(
'desc'=>'Confirm copy actions',
'default'=>true);
$this->default->confirm['create'] = array(
'desc'=>'Confirm creation actions',
'default'=>true);
$this->default->confirm['update'] = array(
'desc'=>'Confirm update actions',
'default'=>true);
/** Commands
* Define command availability ; if the value of a command is true,
* the command will be available.
*/
$this->default->commands['cmd'] = array(
'desc'=>'Define command availability',
'default'=> array(
'entry_internal_attributes_show' => true,
'entry_refresh' => true,
'oslinks' => true,
'switch_template' => true
));
$this->default->commands['script'] = array(
'desc'=>'Define scripts availability',
'default'=> array(
'add_attr_form' => true,
'add_oclass_form' => true,
'add_value_form' => true,
'collapse' => true,
'compare' => true,
'compare_form' => true,
'copy' => true,
'copy_form' => true,
'create' => true,
'create_confirm' => true,
'delete' => true,
'delete_attr' => true,
'delete_form' => true,
'draw_tree_node' => true,
'expand' => true,
'export' => true,
'export_form' => true,
'import' => true,
'import_form' => true,
'login' => true,
'logout' => true,
'login_form' => true,
'mass_delete' => true,
'mass_edit' => true,
'mass_update' => true,
'modify_member_form' => true,
'monitor' => true,
'purge_cache' => true,
'query_engine' => true,
'rename' => true,
'rename_form' => true,
'rdelete' => true,
'refresh' => true,
'schema' => true,
'server_info' => true,
'show_cache' => true,
'template_engine' => true,
'update_confirm' => true,
'update' => true
));
/** Aliases and Referrrals
* Similar to ldapsearch's -a option, the following options allow you to configure
* how phpLDAPadmin will treat aliases and referrals in the LDAP tree.
* For the following four settings, avaialable options include:
*
* LDAP_DEREF_NEVER - aliases are never dereferenced (eg, the contents of
* the alias itself are shown and not the referenced entry).
* LDAP_DEREF_SEARCHING - aliases should be dereferenced during the search but
* not when locating the base object of the search.
* LDAP_DEREF_FINDING - aliases should be dereferenced when locating the base
* object but not during the search.
* LDAP_DEREF_ALWAYS - aliases should be dereferenced always (eg, the contents
* of the referenced entry is shown and not the aliasing entry)
* We superceed these definitions with @ to suppress the error if php-ldap is
* not installed.
*/
@$this->default->deref['export'] = array(
'desc'=>'',
'default'=>LDAP_DEREF_NEVER);
@$this->default->deref['search'] = array(
'desc'=>'',
'default'=>LDAP_DEREF_ALWAYS);
@$this->default->deref['tree'] = array(
'desc'=>'',
'default'=>LDAP_DEREF_NEVER);
@$this->default->deref['view'] = array(
'desc'=>'',
'default'=>LDAP_DEREF_NEVER);
## Debug Attributes
$this->default->debug['level'] = array(
'desc'=>'Debug level verbosity',
'default'=>0);
$this->default->debug['syslog'] = array(
'desc'=>'Whether to send debug messages to syslog',
'default'=>false);
$this->default->debug['file'] = array(
'desc'=>'Name of file to send debug output to',
'default'=>null);
$this->default->debug['addr'] = array(
'desc'=>'IP address of client to provide debugging info.',
'default'=>null);
$this->default->debug['append'] = array(
'desc'=>'Whether to append to the debug file, or create it fresh each time',
'default'=>true);
## Temp Directories
/** JPEG TMPDir
* This directory must be readable and writable by your web server
*/
$this->default->jpeg['tmpdir'] = array(
'desc'=>'Temporary directory for jpegPhoto data',
'default'=>'/tmp');
## Mass update commands
$this->default->mass['enabled'] = array(
'desc'=>'Are mass update commands enabled',
'default'=>true);
## Modify members feature
/**
* Search filter setting for new members. This is used to search possible members that can be added
* to the group. See modify_member_form.php
*/
$this->default->modify_member['filter'] = array(
'desc'=>'Search filter for member searches',
'default'=>'(objectclass=Person)');
/**
* Group attributes. When these attributes are seen in template_engine.php, add "modify group members"
* link to the attribute
* See template_engine.php
*/
$this->default->modify_member['groupattr'] = array(
'desc'=>'Group member attributes',
'default'=>array('member','uniqueMember','memberUid'));
/**
* Attribute that is added to the group member attribute. For groupOfNames or groupOfUniqueNames this is dn,
* for posixGroup it's uid. See modify_member_form.php
*/
$this->default->modify_member['attr'] = array(
'desc'=>'Default attribute that is added to the group member attribute',
'default'=>'dn');
/**
* Attribute that is added to the group member attribute.
* For posixGroup it's uid. See modify_member_form.php
*/
$this->default->modify_member['posixattr'] = array(
'desc'=>'Contents of the group member attribute',
'default'=>'uid');
/**
* Search filter setting for new members to group. This is used to search possible members that can be added
* to the posixGroup. See modify_member_form.php
*/
$this->default->modify_member['posixfilter'] = array(
'desc'=>'Search filter for posixmember searches',
'default'=>'(uid=*)');
/**
* posixGroup attribute. When this attribute are seen in modify_member_form.php, only posixGroup members are shown
* See modify_member_form.php
*/
$this->default->modify_member['posixgroupattr'] = array(
'desc'=>'posixGroup member attribute',
'default'=>'memberUid');
## Session Attributes
/** Cookie Encryption
* phpLDAPadmin can encrypt the content of sensitive cookies if you set this to a big random string.
*/
$this->default->session['blowfish'] = array(
'desc'=>'Blowfish key to encrypt cookie details',
'default'=>null);
/** Cookie Time
* If you used auth_type 'form' in the servers list, you can adjust how long the cookie will last
* (default is 0 seconds, which expires when you close the browser)
*/
$this->default->session['cookie_time'] = array(
'desc'=>'Time in seconds for the life of cookies',
'default'=>0);
$this->default->session['http_realm'] = array(
'desc'=>'HTTP Authentication Realm',
'default'=>sprintf('%s %s',app_name(),_('login')));
$this->default->session['memorylimit'] = array(
'desc'=>'Set the PHP memorylimit warning threshold.',
'default'=>24);
$this->default->session['timelimit'] = array(
'desc'=>'Set the PHP timelimit.',
'default'=>30);
/**
* Session Menu
*/
$this->default->menu['session'] = array(
'desc'=>'Menu items when logged in.',
'default'=>array(
'schema'=>true,
'search'=>true,
'refresh'=>true,
'server_info'=>true,
'monitor'=>true,
'import'=>true,
'export'=>true
));
## Password Generation
$this->default->password['length'] = array(
'desc'=>'Length of autogenerated password',
'default'=>8);
$this->default->password['numbers'] = array(
'desc'=>'Number of numbers required in the password',
'default'=>2);
$this->default->password['lowercase'] = array(
'desc'=>'Number of lowercase letters required in the password',
'default'=>2);
$this->default->password['uppercase'] = array(
'desc'=>'Number of uppercase letters required in the password',
'default'=>2);
$this->default->password['punctuation'] = array(
'desc'=>'Number of punctuation letters required in the password',
'default'=>2);
$this->default->password['use_similar'] = array(
'desc'=>'Whether to use similiar characters',
'default'=>true);
$this->default->password['no_random_crypt_salt'] = array(
'desc'=>'Disable random salt for crypt()',
'default'=>false);
/** Search display
* By default, when searching you may display a list or a table of results.
* Set this to 'table' to see table formatted results.
* Set this to 'list' to see "Google" style formatted search results.
*/
$this->default->search['display'] = array(
'desc'=>'Display a list or table of search results',
'default'=>'list');
$this->default->search['size_limit'] = array(
'desc'=>'Limit the size of searchs on the search page',
'default'=>50);
/**
* The list of attributes to display in each search result entry.
* Note that you can add * to the list to display all attributes
*/
$this->default->search['result_attributes'] = array(
'desc'=>'List of attributes to display in each search result entry',
'default'=>array('cn','sn','uid','postalAddress','telephoneNumber'));
$this->default->search['time_limit'] = array(
'desc'=>'Maximum time to allow unlimited size_limit searches to the ldap server',
'default'=>120);
}
/**
* Access the configuration, taking into account the defaults and the customisations
*/
private function getConfigArray($usecache=true) {
static $CACHE = array();
if ($usecache && count($CACHE))
return $CACHE;
foreach ($this->default as $key => $vals)
$CACHE[$key] = $vals;
foreach ($this->custom as $key => $vals)
foreach ($vals as $index => $val)
$CACHE[$key][$index]['value'] = $val;
return $CACHE;
}
/**
* Get a configuration value.
*/
public function getValue($key,$index,$fatal=true) {
$config = $this->getConfigArray();
if (! isset($config[$key]))
if ($fatal)
error(sprintf('A call was made in [%s] to getValue requesting [%s] that isnt predefined.',
basename($_SERVER['PHP_SELF']),$key),'error',null,true);
else
return '';
if (! isset($config[$key][$index]))
if ($fatal)
error(sprintf('Requesting an index [%s] in key [%s] that isnt predefined.',$index,$key),'error',null,true);
else
return '';
return isset($config[$key][$index]['value']) ? $config[$key][$index]['value'] : $config[$key][$index]['default'];
}
/**
* Return the untested config items
*/
public function untested() {
$result = array();
foreach ($this->default as $option => $details)
foreach ($details as $param => $values)
if (isset($values['untested']) && $values['untested'])
array_push($result,sprintf('%s.%s',$option,$param));
return $result;
}
/**
* Function to check and warn about any unusual defined variables.
*/
public function CheckCustom() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (isset($this->custom)) {
foreach ($this->custom as $masterkey => $masterdetails) {
if (isset($this->default->$masterkey)) {
if (! is_array($masterdetails))
error(sprintf('Error in configuration file, [%s] should be an ARRAY.',$masterdetails),'error',null,true);
foreach ($masterdetails as $key => $value) {
# Test that the key is correct.
if (! in_array($key,array_keys($this->default->$masterkey)))
error(sprintf('Error in configuration file, [%s] has not been defined as a configurable variable.',$key),'error',null,true);
# Test if its should be an array or not.
if (is_array($this->default->{$masterkey}[$key]['default']) && ! is_array($value))
error(sprintf('Error in configuration file, %s[\'%s\'] SHOULD be an array of values.',$masterkey,$key),'error',null,true);
if (! is_array($this->default->{$masterkey}[$key]['default']) && is_array($value))
error(sprintf('Error in configuration file, %s[\'%s\'] should NOT be an array of values.',$masterkey,$key),'error',null,true);
}
} else {
error(sprintf('Error in configuration file, [%s] has not been defined as a MASTER configurable variable.',$masterkey),'error',null,true);
}
}
}
}
/**
* Get a list of available commands.
*/
public function getCommandList() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
$config = $this->getConfigArray(false);
masort($config['command'],'summary');
if (isset($config['command']) && is_array($config['command']))
return $config['command'];
else
return array();
}
/**
* Simple ACL to see if commands can be run
*/
public function isCommandAvailable($index='cmd') {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
$a = func_get_args();
array_shift($a);
$a = $a[0];
# Command availability list
$cmd = $this->getValue('commands',$index);
if (! is_string($a) || ! isset($cmd[$a]))
return false;
else
return $cmd[$a];
}
public function configDefinition($key,$index,$config) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! is_array($config) || ! array_key_exists('desc',$config) || ! array_key_exists('default',$config))
return;
if (isset($this->default->$key))
$definition = $this->default->$key;
$definition[$index] = $config;
$this->default->$key = $definition;
}
/**
* Return the friendly attributes names
*/
private function getFriendlyAttrs() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
return array_change_key_case($this->getValue('appearance','friendly_attrs'));
}
/**
* This function will return the friendly name of an attribute, if it exists.
* If the friendly name doesnt exist, the attribute name will be returned.
*
* @param attribute
* @return string friendly name|attribute
*/
public function getFriendlyName($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
static $friendly_attrs;
if (! $friendly_attrs)
$friendly_attrs = $this->getFriendlyAttrs();
if (! is_object($attr))
if (isset($friendly_attrs[$attr]))
return $friendly_attrs[$attr];
else
return $attr;
if (isset($friendly_attrs[$attr->getName()]))
return $friendly_attrs[$attr->getName()];
else
return $attr->getName(false);
}
/**
* This function will return true if a friendly name exists for an attribute.
* If the friendly name doesnt exist, it will return false.
*
* @param attribute
* @return boolean true|false
*/
public function haveFriendlyName($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $attr->getName(false) != $this->getFriendlyName($attr);
}
/**
* This function will return the <ancronym> html for a friendly name attribute.
*
* @param attribute
* @return string html for the friendly name.
*/
public function getFriendlyHTML($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->haveFriendlyName($attr))
return sprintf('<acronym title="%s %s">%s</acronym>',
_('Alias for'),$attr->getName(false),$this->getFriendlyName($attr));
else
return $attr->getName(false);
}
public function setServers($servers) {
$this->servers = $servers;
}
public function getServer($index=null) {
return $this->servers->Instance($index);
}
/**
* Return a list of our servers
* @param boolean $visible - Only return visible servers
*/
public function getServerList($visible=true) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',3,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $this->servers->getServerList($visible);
}
}
?>

381
phpldapadmin/lib/createlm.php Executable file
View File

@ -0,0 +1,381 @@
<?php
/*
$Id$
This code is part of LDAP Account Manager (https://www.sourceforge.net/projects/lam)
Copyright (C) 2004 - 2006 Roland Gruber
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This class provides functions to calculate Samba NT and LM hashes.
*
* The code is a conversion from createntlm.pl (Benjamin Kuit) and smbdes.c/md4.c (Andrew Tridgell).
*
* @author Roland Gruber
* @package lam
*/
/**
* Calculates NT and LM hashes.
*
* The important functions are lmhash($password) and nthash($password).
*
* @package lam
*/
class smbHash {
# Contants used in lanlam hash calculations
# Ported from SAMBA/source/libsmb/smbdes.c:perm1[56]
private $perm1 = array(57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4);
# Ported from SAMBA/source/libsmb/smbdes.c:perm2[48]
private $perm2 = array(14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32);
# Ported from SAMBA/source/libsmb/smbdes.c:perm3[64]
private $perm3 = array(58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7);
# Ported from SAMBA/source/libsmb/smbdes.c:perm4[48]
private $perm4 = array(32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1);
# Ported from SAMBA/source/libsmb/smbdes.c:perm5[32]
private $perm5 = array(16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25);
# Ported from SAMBA/source/libsmb/smbdes.c:perm6[64]
private $perm6 = array(40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25);
# Ported from SAMBA/source/libsmb/smbdes.c:sc[16]
private $sc = array(1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1);
# Ported from SAMBA/source/libsmb/smbdes.c:sbox[8][4][16]
# Side note, I used cut and paste for all these numbers, I did NOT
# type them all in =)
private $sbox = array(array(array(14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7),
array( 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8),
array( 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0),
array(15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13)),
array(array(15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10),
array( 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5),
array( 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15),
array(13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9)),
array(array(10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8),
array(13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1),
array(13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7),
array( 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12)),
array(array( 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15),
array(13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9),
array(10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4),
array( 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14)),
array(array( 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9),
array(14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6),
array( 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14),
array(11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3)),
array(array(12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11),
array(10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8),
array( 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6),
array( 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13)),
array(array( 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1),
array(13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6),
array( 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2),
array( 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12)),
array(array(13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7),
array( 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2),
array( 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8),
array( 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11)));
/**
* Fixes too large numbers
*/
private function x($i) {
if ($i < 0) return 4294967296 - $i;
else return $i;
}
/**
* @param integer count
* @param array $data
* @return array
*/
private function lshift($count, $data) {
$ret = array();
for ($i = 0; $i < sizeof($data); $i++) {
$ret[$i] = $data[($i + $count)%sizeof($data)];
}
return $ret;
}
/**
* @param array in input data
* @param array p permutation
* @return array
*/
private function permute($in, $p, $n) {
$ret = array();
for ($i = 0; $i < $n; $i++) {
$ret[$i] = $in[$p[$i] - 1]?1:0;
}
return $ret;
}
/**
* @param array $in1
* @param array $in2
* @return array
*/
private function mxor($in1, $in2) {
$ret = array();
for ($i = 0; $i < sizeof($in1); $i++) {
$ret[$i] = $in1[$i] ^ $in2[$i];
}
return $ret;
}
/**
* @param array $in
* @param array $key
* @param boolean $forw
* @return array
*/
function doHash($in, $key, $forw) {
$ki = array();
$pk1 = $this->permute($key, $this->perm1, 56);
$c = array();
$d = array();
for ($i = 0; $i < 28; $i++) {
$c[$i] = $pk1[$i];
$d[$i] = $pk1[28 + $i];
}
for ($i = 0; $i < 16; $i++) {
$c = $this->lshift($this->sc[$i], $c);
$d = $this->lshift($this->sc[$i], $d);
$cd = $c;
for ($k = 0; $k < sizeof($d); $k++) $cd[] = $d[$k];
$ki[$i] = $this->permute($cd, $this->perm2, 48);
}
$pd1 = $this->permute($in, $this->perm3, 64);
$l = array();
$r = array();
for ($i = 0; $i < 32; $i++) {
$l[$i] = $pd1[$i];
$r[$i] = $pd1[32 + $i];
}
for ($i = 0; $i < 16; $i++) {
$er = $this->permute($r, $this->perm4, 48);
if ($forw) $erk = $this->mxor($er, $ki[$i]);
else $erk = $this->mxor($er, $ki[15 - $i]);
for ($j = 0; $j < 8; $j++) {
for ($k = 0; $k < 6; $k++) {
$b[$j][$k] = $erk[($j * 6) + $k];
}
}
for ($j = 0; $j < 8; $j++) {
$m = array();
$n = array();
$m = ($b[$j][0] << 1) | $b[$j][5];
$n = ($b[$j][1] << 3) | ($b[$j][2] << 2) | ($b[$j][3] << 1) | $b[$j][4];
for ($k = 0; $k < 4; $k++) {
$b[$j][$k]=($this->sbox[$j][$m][$n] & (1 << (3-$k)))?1:0;
}
}
for ($j = 0; $j < 8; $j++) {
for ($k = 0; $k < 4; $k++) {
$cb[($j * 4) + $k] = $b[$j][$k];
}
}
$pcb = $this->permute($cb, $this->perm5, 32);
$r2 = $this->mxor($l, $pcb);
for ($k = 0; $k < 32; $k++) $l[$k] = $r[$k];
for ($k = 0; $k < 32; $k++) $r[$k] = $r2[$k];
}
$rl = $r;
for ($i = 0; $i < sizeof($l); $i++) $rl[] = $l[$i];
return $this->permute($rl, $this->perm6, 64);
}
/**
* str_to_key
*
* @param string $str
* @return string key
*/
private function str_to_key($str) {
$key[0] = $this->unsigned_shift_r($str[0], 1);
$key[1] = (($str[0]&0x01)<<6) | $this->unsigned_shift_r($str[1], 2);
$key[2] = (($str[1]&0x03)<<5) | $this->unsigned_shift_r($str[2], 3);
$key[3] = (($str[2]&0x07)<<4) | $this->unsigned_shift_r($str[3], 4);
$key[4] = (($str[3]&0x0F)<<3) | $this->unsigned_shift_r($str[4], 5);
$key[5] = (($str[4]&0x1F)<<2) | $this->unsigned_shift_r($str[5], 6);
$key[6] = (($str[5]&0x3F)<<1) | $this->unsigned_shift_r($str[6], 7);
$key[7] = $str[6]&0x7F;
for ($i = 0; $i < 8; $i++) {
$key[$i] = ($key[$i] << 1);
}
return $key;
}
/**
* smb_hash
*
* @param unknown_type $in
* @param unknown_type $key
* @param unknown_type $forw
* @return unknown
*/
private function smb_hash($in, $key, $forw){
$key2 = $this->str_to_key($key);
for ($i = 0; $i < 64; $i++) {
$inb[$i] = ($in[$i/8] & (1<<(7-($i%8)))) ? 1:0;
$keyb[$i] = ($key2[$i/8] & (1<<(7-($i%8)))) ? 1:0;
$outb[$i] = 0;
}
$outb = $this->doHash($inb, $keyb, $forw);
for ($i = 0; $i < 8; $i++) {
$out[$i] = 0;
}
for ($i = 0; $i < 64; $i++) {
if ( $outb[$i] ) {
$out[$i/8] |= (1<<(7-($i%8)));
}
}
return $out;
}
/**
* E_P16
*
* @param unknown_type $in
* @return unknown
*/
private function E_P16($in) {
$p14 = array_values(unpack("C*",$in));
$sp8 = array(0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25);
$p14_1 = array();
$p14_2 = array();
for ($i = 0; $i < 7; $i++) {
$p14_1[$i] = $p14[$i];
$p14_2[$i] = $p14[$i + 7];
}
$p16_1 = $this->smb_hash($sp8, $p14_1, true);
$p16_2 = $this->smb_hash($sp8, $p14_2, true);
$p16 = $p16_1;
for ($i = 0; $i < sizeof($p16_2); $i++) {
$p16[] = $p16_2[$i];
}
return $p16;
}
/**
* Calculates the LM hash of a given password.
*
* @param string $password password
* @return string hash value
*/
public function lmhash($password = "") {
$password = strtoupper($password);
$password = substr($password,0,14);
$password = str_pad($password, 14, chr(0));
$p16 = $this->E_P16($password);
for ($i = 0; $i < sizeof($p16); $i++) {
$p16[$i] = sprintf("%02X", $p16[$i]);
}
return join("", $p16);
}
/**
* Calculates the NT hash of a given password.
*
* @param string $password password
* @return string hash value
*/
public function nthash($password = "") {
if (function_exists('mhash'))
if (defined('MHASH_MD4'))
return strtoupper(bin2hex(mhash(MHASH_MD4,iconv('UTF-8','UTF-16LE',$password))));
else
return strtoupper(hash('md4', iconv("UTF-8","UTF-16LE",$password)));
else
error(_('Your PHP install does not have the mhash() function. Cannot do hashes.'),'error','index.php');
}
/**
* Unsigned shift operation for 32bit values.
*
* PHP 4 only supports signed shifts by default.
*/
private function unsigned_shift_r($a, $b) {
$z = 0x80000000;
if ($z & $a) {
$a = ($a >> 1);
$a &= (~$z);
$a |= 0x40000000;
$a = ($a >> ($b - 1));
}
else {
$a = ($a >> $b);
}
return $a;
}
}
?>

731
phpldapadmin/lib/ds.php Executable file
View File

@ -0,0 +1,731 @@
<?php
/**
* Classes and functions for communication of Data Stores
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* This abstract class provides the basic variables and methods.
*
* @package phpLDAPadmin
* @subpackage DataStore
*/
abstract class DS {
# ID of this db.
protected $index;
# Configuration paramters.
protected $default;
protected $custom;
protected $type;
abstract function __construct($index);
/**
* This will make the connection to the datasource
*/
abstract protected function connect($method,$debug=false);
/**
* Login to the datastore
* method: default = anon, connect to ds using bind_id not auth_id.
* method: 'user', connect with auth_id
* method: '<freetext>', any custom extra connection to ds.
*/
abstract public function login($user=null,$pass=null,$method=null);
/**
* Query the datasource
*/
abstract public function query($query,$method,$index=null,$debug=false);
/**
* Return error details from previous operation
*/
abstract protected function getErrorMessage();
abstract protected function getErrorNum();
/**
* Functions that set and verify object configuration details
*/
public function setDefaults($defaults) {
foreach ($defaults as $key => $details)
foreach ($details as $setting => $value)
$this->default->{$key}[$setting] = $value;
}
public function isDefaultKey($key) {
return isset($this->default->$key);
}
public function isDefaultSetting($key,$setting) {
return array_key_exists($setting,$this->default->{$key});
}
/**
* Return a configuration value
*/
public function getValue($key,$setting,$fatal=true) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,1,__FILE__,__LINE__,__METHOD__,$fargs);
if (isset($this->custom->{$key}[$setting]))
return $this->custom->{$key}[$setting];
elseif (isset($this->default->{$key}[$setting]) && array_key_exists('default',$this->default->{$key}[$setting]))
return $this->default->{$key}[$setting]['default'];
elseif ($fatal)
debug_dump_backtrace("Error trying to get a non-existant value ($key,$setting)",1);
else
return null;
}
/**
* Set a configuration value
*/
public function setValue($key,$setting,$value) {
if (isset($this->custom->{$key}[$setting]))
system_message(array(
'title'=>_('Configuration setting already defined.'),
'body'=>sprintf('A call has been made to reset a configuration value (%s,%s,%s)',
$key,$setting,$value),
'type'=>'info'));
$this->custom->{$key}[$setting] = $value;
}
/**
* Return the untested config items
*/
public function untested() {
$result = array();
foreach ($this->default as $option => $details)
foreach ($details as $param => $values)
if (isset($values['untested']) && $values['untested'])
array_push($result,sprintf('%s.%s',$option,$param));
return $result;
}
/**
* Get the name of this datastore
*/
public function getName() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $this->getValue('server','name');
}
/**
* Functions that enable login and logout of the application
*/
/**
* Return the authentication type for this object
*/
public function getAuthType() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
switch ($this->getValue('login','auth_type')) {
case 'cookie':
case 'config':
case 'http':
case 'proxy':
case 'session':
case 'sasl':
return $this->getValue('login','auth_type');
default:
die(sprintf('Error: <b>%s</b> hasnt been configured for auth_type <b>%s</b>',__METHOD__,
$this->getValue('login','auth_type')));
}
}
/**
* Get the login name of the user logged into this datastore's connection method
* If this returns null, we are not logged in.
* If this returns '', we are logged in with anonymous
*/
public function getLogin($method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$method = $this->getMethod($method);
# For anonymous binds
if ($method == 'anon')
if (isset($_SESSION['USER'][$this->index][$method]['name']))
return '';
else
return null;
switch ($this->getAuthType()) {
case 'cookie':
if (! isset($_COOKIE[$method.'-USER']))
# If our bind_id is set, we'll pass that back for logins.
return (! is_null($this->getValue('login','bind_id')) && $method == 'login') ? $this->getValue('login','bind_id') : null;
else
return blowfish_decrypt($_COOKIE[$method.'-USER']);
case 'config':
if (! isset($_SESSION['USER'][$this->index][$method]['name']))
return $this->getValue('login','bind_id');
else
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['name']);
case 'proxy':
if (! isset($_SESSION['USER'][$this->index][$method]['proxy']))
return $this->getValue('login','bind_id');
else
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['proxy']);
case 'http':
case 'session':
case 'sasl':
if (! isset($_SESSION['USER'][$this->index][$method]['name']))
# If our bind_id is set, we'll pass that back for logins.
return (! is_null($this->getValue('login','bind_id')) && $method == 'login') ? $this->getValue('login','bind_id') : null;
else
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['name']);
default:
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Set the login details of the user logged into this datastore's connection method
*/
protected function setLogin($user,$pass,$method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$method = $this->getMethod($method);
switch ($this->getAuthType()) {
case 'cookie':
set_cookie($method.'-USER',blowfish_encrypt($user),NULL,'/');
set_cookie($method.'-PASS',blowfish_encrypt($pass),NULL,'/');
return true;
case 'config':
return true;
case 'proxy':
if (isset($_SESSION['USER'][$this->index][$method]['proxy']))
unset($_SESSION['USER'][$this->index][$method]['proxy']);
case 'http':
case 'session':
case 'sasl':
$_SESSION['USER'][$this->index][$method]['name'] = blowfish_encrypt($user);
$_SESSION['USER'][$this->index][$method]['pass'] = blowfish_encrypt($pass);
return true;
default:
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Get the login password of the user logged into this datastore's connection method
*/
protected function getPassword($method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$method = $this->getMethod($method);
# For anonymous binds
if ($method == 'anon')
if (isset($_SESSION['USER'][$this->index][$method]['name']))
return '';
else
return null;
switch ($this->getAuthType()) {
case 'cookie':
if (! isset($_COOKIE[$method.'-PASS']))
# If our bind_id is set, we'll pass that back for logins.
return (! is_null($this->getValue('login','bind_pass')) && $method == 'login') ? $this->getValue('login','bind_pass') : null;
else
return blowfish_decrypt($_COOKIE[$method.'-PASS']);
case 'config':
case 'proxy':
if (! isset($_SESSION['USER'][$this->index][$method]['pass']))
return $this->getValue('login','bind_pass');
else
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['pass']);
case 'http':
case 'session':
case 'sasl':
if (! isset($_SESSION['USER'][$this->index][$method]['pass']))
# If our bind_pass is set, we'll pass that back for logins.
return (! is_null($this->getValue('login','bind_pass')) && $method == 'login') ? $this->getValue('login','bind_pass') : null;
else
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['pass']);
default:
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Return if this datastore's connection method has been logged into
*/
public function isLoggedIn($method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
static $CACHE = array();
$method = $this->getMethod($method);
if (isset($CACHE[$this->index][$method]) && ! is_null($CACHE[$this->index][$method]))
return $CACHE[$this->index][$method];
$CACHE[$this->index][$method] = null;
# For some authentication types, we need to do the login here
switch ($this->getAuthType()) {
case 'config':
if (! $CACHE[$this->index][$method] = $this->login($this->getLogin($method),$this->getPassword($method),$method))
system_message(array(
'title'=>_('Unable to login.'),
'body'=>_('Your configuration file has authentication set to CONFIG based authentication, however, the userid/password failed to login'),
'type'=>'error'));
break;
case 'http':
# If our auth vars are not set, throw up a login box.
if (! isset($_SERVER['PHP_AUTH_USER'])) {
# If this server is not in focus, skip the basic auth prompt.
if (get_request('server_id','REQUEST') != $this->getIndex()) {
$CACHE[$this->index][$method] = false;
break;
}
header(sprintf('WWW-Authenticate: Basic realm="%s %s"',app_name(),_('login')));
if ($_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.0')
header('HTTP/1.0 401 Unauthorized'); // http 1.0 method
else
header('Status: 401 Unauthorized'); // http 1.1 method
# If we still dont have login details...
if (! isset($_SERVER['PHP_AUTH_USER'])) {
system_message(array(
'title'=>_('Unable to login.'),
'body'=>_('Your configuration file has authentication set to HTTP based authentication, however, there was none presented'),
'type'=>'error'));
$CACHE[$this->index][$method] = false;
}
# Check our auth vars are valid.
} else {
if (! $this->login($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW'],$method)) {
system_message(array(
'title'=>_('Unable to login.'),
'body'=>_('Your HTTP based authentication is not accepted by the LDAP server'),
'type'=>'error'));
$CACHE[$this->index][$method] = false;
} else
$CACHE[$this->index][$method] = true;
}
break;
case 'proxy':
$CACHE[$this->index][$method] = $this->login($this->getValue('login','bind_id'),$this->getValue('login','bind_pass'),$method);
break;
case 'sasl':
# Propogate any given Kerberos credential cache location
if (isset($_ENV['REDIRECT_KRB5CCNAME']))
putenv(sprintf('KRB5CCNAME=%s',$_ENV['REDIRECT_KRB5CCNAME']));
elseif (isset($_SERVER['KRB5CCNAME']))
putenv(sprintf('KRB5CCNAME=%s',$_SERVER['KRB5CCNAME']));
# Map the SASL auth ID to a DN
$regex = $this->getValue('login', 'sasl_dn_regex');
$replacement = $this->getValue('login', 'sasl_dn_replacement');
if ($regex && $replacement) {
$userDN = preg_replace($regex, $replacement, $_SERVER['REMOTE_USER']);
$CACHE[$this->index][$method] = $this->login($userDN, '', $method);
# Otherwise, use the user name as is
# For GSSAPI Authentication + mod_auth_kerb and Basic Authentication
} else
$CACHE[$this->index][$method] = $this->login(isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : '', '', $method);
break;
default:
$CACHE[$this->index][$method] = is_null($this->getLogin($method)) ? false : true;
}
return $CACHE[$this->index][$method];
}
/**
* Logout of this datastore's connection method
*/
public function logout($method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$method = $this->getMethod($method);
unset ($_SESSION['cache'][$this->index]);
switch ($this->getAuthType()) {
case 'cookie':
set_cookie($method.'-USER','',time()-3600,'/');
set_cookie($method.'-PASS','',time()-3600,'/');
case 'config':
return true;
case 'http':
case 'proxy':
case 'session':
case 'sasl':
if (isset($_SESSION['USER'][$this->index][$method]))
unset($_SESSION['USER'][$this->index][$method]);
return true;
default:
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
}
}
/**
* Functions that return the condition of the datasource
*/
public function isVisible() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $this->getValue('server','visible');
}
public function isReadOnly() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! trim($this->getLogin(null)) && $_SESSION[APPCONFIG]->getValue('appearance','anonymous_bind_implies_read_only'))
return true;
else
return $this->getValue('server','read_only');
}
public function getIndex() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->index);
return $this->index;
}
/**
* Work out which connection method to use.
* If a method is passed, then it will be passed back. If no method is passed, then we'll
* check to see if the user is logged in. If they are, then 'user' is used, otherwise
* 'anon' is used.
*
* @param int Server ID
* @return string Connection Method
*/
protected function getMethod($method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
static $CACHE = array();
# Immediately return if method is set.
if (! is_null($method))
return $method;
# If we have been here already, then return our result
if (isset($CACHE[$this->index]) && ! is_null($CACHE))
return $CACHE[$this->index];
$CACHE[$this->index] = 'anon';
if ($this->isLoggedIn('user'))
$CACHE[$this->index] = 'user';
return $CACHE[$this->index];
}
/**
* This method should be overridden in application specific ds files
*/
public function isSessionValid() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,1,__FILE__,__LINE__,__METHOD__,$fargs,true);
return true;
}
/**
* Return the time left in seconds until this connection times out. If there is not timeout,
* this function will return null.
*/
public function inactivityTime() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
if ($this->isLoggedIn() && ! in_array($this->getAuthType(),array('config','http')))
return time()+($this->getValue('login','timeout')*60);
else
return null;
}
}
/**
* The list of database sources
*
* @package phpLDAPadmin
* @subpackage DataStore
*/
class Datastore {
# Out DS index id
private $index;
# List of all the objects
private $objects = array();
# Default settings
private $default;
public function __construct() {
$this->default = new StdClass;
$this->default->server['id'] = array(
'desc'=>'Server ID',
'default'=>null);
$this->default->server['name'] = array(
'desc'=>'Server name',
'default'=>null);
# Connectivity Info
$this->default->server['host'] = array(
'desc'=>'Host Name',
'default'=>'127.0.0.1');
$this->default->server['port'] = array(
'desc'=>'Port Number',
'default'=>null);
# Read or write only access
$this->default->server['read_only'] = array(
'desc'=>'Server is in READ ONLY mode',
'default'=>false);
$this->default->server['visible'] = array(
'desc'=>'Whether this server is visible',
'default'=>true);
$this->default->server['hide_noaccess_base'] = array(
'desc'=>'If base DNs are not accessible, hide them instead of showing create',
'default'=>false);
# Authentication Information
$this->default->login['auth_type'] = array(
'desc'=>'Authentication Type',
'default'=>'session');
/*
/* ID to login to this application, this assumes that there is
* application authentication on top of authentication required to
* access the data source **
$this->default->login['auth_id'] = array(
'desc'=>'User Login ID to login to this DS',
'untested'=>true,
'default'=>null);
$this->default->login['auth_pass'] = array(
'desc'=>'User Login Password to login to this DS',
'untested'=>true,
'default'=>null);
*/
$this->default->login['auth_text'] = array(
'desc'=>'Text to show at the login prompt',
'default'=>null);
$this->default->login['bind_id'] = array(
'desc'=>'User Login ID to bind to this DS',
'default'=>null);
$this->default->login['bind_pass'] = array(
'desc'=>'User Login Password to bind to this DS',
'default'=>null);
$this->default->login['timeout'] = array(
'desc'=>'Session timout in seconds',
'default'=>session_cache_expire()-1);
$this->default->login['sasl_dn_regex'] = array(
'desc'=>'SASL authorization id to user dn PCRE regular expression',
'untested'=>true,
'default'=>null);
$this->default->login['sasl_dn_replacement'] = array(
'desc'=>'SASL authorization id to user dn PCRE regular expression replacement string',
'untested'=>true,
'default'=>null);
# Prefix for custom pages
$this->default->custom['pages_prefix'] = array(
'desc'=>'Prefix name for custom pages',
'default'=>'custom_');
}
/**
* Create a new database object
*/
public function newServer($type) {
if (class_exists($type)) {
$this->index = count($this->objects)+1;
$this->objects[$this->index] = new $type($this->index);
$this->objects[$this->index]->setDefaults($this->default);
return $this->index;
} else {
printf('ERROR: Class [%s] doesnt exist',$type);
die();
}
}
/**
* Set values for a database object.
*/
public function setValue($key,$setting,$value) {
if (! $this->objects[$this->index]->isDefaultKey($key))
error("ERROR: Setting a key [$key] that isnt predefined.",'error',true);
if (! $this->objects[$this->index]->isDefaultSetting($key,$setting))
error("ERROR: Setting a index [$key,$setting] that isnt predefined.",'error',true);
# Test if its should be an array or not.
if (is_array($this->objects[$this->index]->getValue($key,$setting)) && ! is_array($value))
error("Error in configuration file, {$key}['$setting'] SHOULD be an array of values.",'error',true);
if (! is_array($this->objects[$this->index]->getValue($key,$setting)) && is_array($value))
error("Error in configuration file, {$key}['$setting'] should NOT be an array of values.",'error',true);
# Store the value in the object.
$this->objects[$this->index]->setValue($key,$setting,$value);
}
/**
* Get a list of all the configured servers.
*
* @param boolean Only show visible servers.
* @return array list of all configured servers.
*/
public function getServerList($isVisible=true) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
static $CACHE;
if (isset($CACHE[$isVisible]))
return $CACHE[$isVisible];
$CACHE[$isVisible] = array();
# Debugging incase objects is not set.
if (! $this->objects) {
print "<PRE>";
debug_print_backtrace();
die();
}
foreach ($this->objects as $id => $server)
if (! $isVisible || ($isVisible && $server->getValue('server','visible')))
$CACHE[$isVisible][$id] = $server;
masort($CACHE[$isVisible],'name');
return $CACHE[$isVisible];
}
/**
* Return an object Instance of a configured database.
*
* @param int Index
* @return object Datastore instance object.
*/
public function Instance($index=null) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
# If no index defined, then pick the lowest one.
if (is_null($index) || ! trim($index) || ! is_numeric($index))
$index = min($this->GetServerList())->getIndex();
if (! isset($this->objects[$index]))
debug_dump_backtrace(sprintf('Error: Datastore instance [%s] doesnt exist?',htmlspecialchars($index)),1);
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Returning instance of database (%s)',3,0,__FILE__,__LINE__,__METHOD__,$index);
return $this->objects[$index];
}
/**
* Return an object Instance of a configured database.
*
* @param string Name of the instance to retrieve
* @return object Datastore instance object.
*/
public function InstanceName($name=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
foreach ($this->getServerList(false) as $index)
if ($this->objects[$index]->getName() == $name)
return $this->objects[$index];
# If we get here, then no object with the name exists.
return null;
}
/**
* Return an object Instance of a configured database.
*
* @param string ID of the instance to retrieve
* @return object Datastore instance object.
*/
public function InstanceId($id=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
foreach ($this->getServerList(false) as $index)
if ($this->objects[$index->getIndex()]->getValue('server','id') == $id)
return $this->objects[$index->getIndex()];
# If we get here, then no object with the name exists.
return null;
}
}
?>

2414
phpldapadmin/lib/ds_ldap.php Executable file

File diff suppressed because it is too large Load Diff

659
phpldapadmin/lib/ds_ldap_pla.php Executable file
View File

@ -0,0 +1,659 @@
<?php
/**
* Classes and functions for communication of Data Stores
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* This abstract class provides variables and methods for LDAP datastores for use by PLA.
*
* @package phpLDAPadmin
* @subpackage DataStore
*/
class ldap_pla extends ldap {
function __construct($index) {
parent::__construct($index);
$this->default->appearance['password_hash_custom'] = array(
'desc'=>'Default HASH to use for passwords',
'default'=>'md5');
$this->default->appearance['show_create'] = array(
'desc'=>'Whether to show the "Create new Entry here" in the tree browser',
'default'=>true);
$this->default->appearance['open_tree'] = array(
'desc'=>'Whether to initially open each tree',
'default'=>false);
$this->default->login['fallback_dn'] = array(
'desc'=>'If the attribute base login fails, see if a DN was entered',
'default'=>false);
$this->default->query['disable_default'] = array(
'desc'=>'Configuration to disable the default query template',
'default'=>false);
$this->default->query['custom_only'] = array(
'desc'=>'Configuration to force the usage of custom query templates',
'default'=>false);
$this->default->server['branch_rename'] = array(
'desc'=>'Enable renaming of branches',
'default'=>false);
$this->default->server['custom_attrs'] = array(
'desc'=>'Custom operational attributes to be treated as regular attributes',
'default'=>array(''));
$this->default->server['custom_sys_attrs'] = array(
'desc'=>'Custom operational attributes to be treated as internal attributes',
'default'=>array('+'));
$this->default->server['jpeg_attributes'] = array(
'desc'=>'Additional attributes to treat as Jpeg Attributes',
'default'=>array());
# This was added in case the LDAP server doesnt provide them with a base +,* query.
$this->default->server['root_dse_attributes'] = array(
'desc'=>'RootDSE attributes for use when displaying server info',
'default'=>array(
'namingContexts',
'subschemaSubentry',
'altServer',
'supportedExtension',
'supportedControl',
'supportedSASLMechanisms',
'supportedLDAPVersion',
'currentTime',
'dsServiceName',
'defaultNamingContext',
'schemaNamingContext',
'configurationNamingContext',
'rootDomainNamingContext',
'supportedLDAPPolicies',
'highestCommittedUSN',
'dnsHostName',
'ldapServiceName',
'serverName',
'supportedCapabilities',
'changeLog',
'tlsAvailableCipherSuites',
'tlsImplementationVersion',
'supportedSASLMechanisms',
'dsaVersion',
'myAccessPoint',
'dseType',
'+',
'*'
));
$this->default->server['force_may'] = array(
'desc'=>'Force server MUST attributes as MAY attributes',
'default'=>array(
));
# Settings for auto_number
$this->default->auto_number['enable'] = array(
'desc'=>'Enable the AUTO UID feature',
'default'=>true);
$this->default->auto_number['mechanism'] = array(
'desc'=>'Mechanism to use to search for automatic numbers',
'default'=>'search');
$this->default->auto_number['search_base'] = array(
'desc'=>'Base DN to use for search mechanisms',
'default'=>null);
$this->default->auto_number['min'] = array(
'desc'=>'Minimum number to start with',
'default'=>array('uidNumber'=>1000,'gidNumber'=>500));
$this->default->auto_number['dn'] = array(
'desc'=>'DN to use when evaluating numbers',
'default'=>null);
$this->default->auto_number['pass'] = array(
'desc'=>'Password for DN to use when evaluating numbers',
'default'=>null);
$this->default->unique['attrs'] = array(
'desc'=>'Attributes to check for uniqueness before allowing updates',
'default'=>array('mail','uid','uidNumber'));
$this->default->unique['dn'] = array(
'desc'=>'DN to use when evaluating attribute uniqueness',
'default'=>null);
$this->default->unique['pass'] = array(
'desc'=>'Password for DN to use when evaluating attribute uniqueness',
'default'=>null);
}
public function __get($key) {
switch ($key) {
case 'name':
return $this->getValue('server','name');
default:
system_message(array(
'title'=>_('Unknown request for Object value.'),
'body'=>sprintf(_('Attempt to obtain value %s from %s'),$key,get_class($this)),
'type'=>'error'));
}
}
/**
* Gets whether the admin has configured phpLDAPadmin to show the "Create New" link in the tree viewer.
* <code>
* $servers->setValue('appearance','show_create',true|false);
* </code>
* If NOT set, then default to show the Create New item.
* If IS set, then return the value (it should be true or false).
*
* The entry creation command must be available.
* <code>
* $config->custom->commands['script'] = array('create' => true);
* </code>
*
* @return boolean true if the feature is enabled and false otherwise.
*/
function isShowCreateEnabled() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','create'))
return false;
else
return $this->getValue('appearance','show_create');
}
/**
* Fetch whether the user has configured a certain server login to be non anonymous
*
* <code>
* $servers->setValue('login','anon_bind',true|false);
* </code>
*
* @return boolean
*/
public function isAnonBindAllowed() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
# If only_login_allowed_dns is set, then we cant have anonymous.
if (count($this->getValue('login','allowed_dns')) > 0)
$return = false;
else
$return = $this->getValue('login','anon_bind');
if (DEBUG_ENABLED)
debug_log('Returning (%s)',17,0,__FILE__,__LINE__,__METHOD__,$return);
return $return;
}
/**
* Returns true if the user has configured the specified server to enable branch (non-leaf) renames.
*
* This is configured in config.php thus:
* <code>
* $servers->setValue('server','branch_rename',true|false);
* </code>
*
* @return boolean
*/
function isBranchRenameEnabled() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
return $this->getValue('server','branch_rename');
}
/**
* Determines if an attribute's value can contain multiple lines. Attributes that fall
* in this multi-line category may be configured in config.php. Hence, this function
* accesses the global variable $_SESSION[APPCONFIG]->custom->appearance['multi_line_attributes'];
*
* Usage example:
* <code>
* if ($ldapserver->isMultiLineAttr('postalAddress'))
* echo '<textarea name="postalAddress"></textarea>';
* else
* echo '<input name="postalAddress" type="text">';
* </code>
*
* @param string The name of the attribute of interested (case insensivite)
* @param string (optional) The current value of the attribute (speeds up the process by searching for carriage returns already in the attribute value)
* @return boolean
*/
function isMultiLineAttr($attr_name,$val=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
# Set default return
$return = false;
# First, check the optional val param for a \n or a \r
if (! is_null($val) && (strpos($val,"\n") || strpos($val,"\r")))
$return = true;
# Next, compare strictly by name first
else
foreach ($_SESSION[APPCONFIG]->getValue('appearance','multi_line_attributes') as $multi_line_attr_name)
if (strcasecmp($multi_line_attr_name,$attr_name) == 0) {
$return = true;
break;
}
# If unfound, compare by syntax OID
if (! $return) {
$sattr = $this->getSchemaAttribute($attr_name);
if ($sattr) {
$syntax_oid = $sattr->getSyntaxOID();
if ($syntax_oid)
foreach ($_SESSION[APPCONFIG]->getValue('appearance','multi_line_syntax_oids') as $multi_line_syntax_oid)
if ($multi_line_syntax_oid == $syntax_oid) {
$return = true;
break;
}
}
}
if (DEBUG_ENABLED)
debug_log('Returning (%s)',17,0,__FILE__,__LINE__,__METHOD__,$return);
return $return;
}
/**
* Returns true if the specified attribute is configured according to
* the test enabled in config.php
*
* @param string The name of the attribute to test.
* @param array The attributes to test against.
* @param dn A DN that is exempt from these tests.
* @return boolean
*/
private function isAttrTest($attr,$attrs,$except_dn) {
$attr = trim($attr);
if (! trim($attr) || ! count($attrs))
return false;
# Is the user excluded?
if ($except_dn && $this->userIsMember($this->getLogin(),$except_dn))
return false;
foreach ($attrs as $attr_name)
if (strcasecmp($attr,trim($attr_name)) == 0)
return true;
return false;
}
/**
* Returns true if the specified attribute is configured as read only
* in config.php.
* Attributes are configured as read-only in config.php thus:
* <code>
* $config->custom->appearance['readonly_attrs'] = array('objectClass');
* </code>
*
* @param string The name of the attribute to test.
* @return boolean
*/
public function isAttrReadOnly($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$attrs = $_SESSION[APPCONFIG]->getValue('appearance','readonly_attrs');
$except_dn = $_SESSION[APPCONFIG]->getValue('appearance','readonly_attrs_exempt');
return $this->isAttrTest($attr,$attrs,$except_dn);
}
/**
* Returns true if the specified attribute is configured as hidden
* in config.php.
* Attributes are configured as hidden in config.php thus:
* <code>
* $config->custom->appearance['hide_attrs'] = array('objectClass');
* </code>
*
* @param string The name of the attribute to test.
* @return boolean
*/
public function isAttrHidden($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$attrs = $_SESSION[APPCONFIG]->getValue('appearance','hide_attrs');
$except_dn = $_SESSION[APPCONFIG]->getValue('appearance','hide_attrs_exempt');
return $this->isAttrTest($attr,$attrs,$except_dn);
}
/**
* Add objects
*/
public function add($dn,$entry_array,$method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
foreach ($entry_array as $attr => $val)
$entry_array[$attr] = dn_unescape($val);
$result = false;
# Check our unique attributes.
if (! $this->checkUniqueAttrs($dn,$entry_array))
return false;
if (run_hook('pre_entry_create',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attrs'=>$entry_array))) {
$result = @ldap_add($this->connect($method),dn_escape($dn),$entry_array);
if ($result) {
# Update the tree
$tree = get_cached_item($this->index,'tree');
# If we created the base, delete it, then add it back
if (get_request('create_base'))
$tree->delEntry($dn);
$tree->addEntry($dn);
set_cached_item($this->index,'tree','null',$tree);
run_hook('post_entry_create',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attrs'=>$entry_array));
} else {
system_message(array(
'title'=>_('Could not add the object to the LDAP server.'),
'body'=>ldap_error_msg($this->getErrorMessage(null),$this->getErrorNum(null)),
'type'=>'error'));
}
}
return $result;
}
/**
* Delete objects
*/
public function delete($dn,$method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = false;
if (run_hook('pre_entry_delete',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn))) {
$result = @ldap_delete($this->connect($method),dn_escape($dn));
if ($result) {
# Update the tree
$tree = get_cached_item($this->index,'tree');
$tree->delEntry($dn);
set_cached_item($this->index,'tree','null',$tree);
run_hook('post_entry_delete',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn));
}
}
return $result;
}
/**
* Rename objects
*/
public function rename($dn,$new_rdn,$container,$deleteoldrdn,$method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = false;
if (run_hook('pre_entry_rename',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'rdn'=>$new_rdn,'container'=>$container))) {
$result = @ldap_rename($this->connect($method),$dn,$new_rdn,$container,$deleteoldrdn);
if ($result) {
# Update the tree
$tree = get_cached_item($this->index,'tree');
$newdn = sprintf('%s,%s',$new_rdn,$container);
$tree->renameEntry($dn,$newdn);
set_cached_item($this->index,'tree','null',$tree);
run_hook('post_entry_rename',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'rdn'=>$new_rdn,'container'=>$container));
}
}
return $result;
}
/**
* Modify objects
*/
public function modify($dn,$attrs,$method=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
# Check our unique attributes.
if (! $this->checkUniqueAttrs($dn,$attrs))
return false;
$result = false;
$summary = array();
$current_attrs = $this->getDNAttrValues($dn,$method,LDAP_DEREF_NEVER,array('*'));
# Go through our attributes and call our hooks for each attribute changing its value
foreach ($attrs as $attr => $values) {
# For new attributes
if (count($values) && ! isset($current_attrs[$attr])) {
if (! run_hook('pre_attr_add',
array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attr'=>$attr,'newvalue'=>$values))) {
unset($attrs[$attr]);
system_message(array(
'title'=>_('Attribute not added'),
'body'=>sprintf('%s (<b>%s</b>)',_('Hook pre_attr_add prevented attribute from being added'),$attr),
'type'=>'warn'));
} else
$summary['add'][$attr]['new'] = $values;
# For modify attributes
} elseif (count($values)) {
if (! run_hook('pre_attr_modify',
array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attr'=>$attr,'oldvalue'=>$current_attrs[$attr],'newvalue'=>$values))) {
unset($attrs[$attr]);
system_message(array(
'title'=>_('Attribute not modified'),
'body'=>sprintf('%s (<b>%s</b>)',_('Hook pre_attr_modify prevented attribute from being modified'),$attr),
'type'=>'warn'));
} else {
$summary['modify'][$attr]['new'] = $values;
$summary['modify'][$attr]['old'] = $current_attrs[$attr];
}
# For delete attributes
} else {
if (! run_hook('pre_attr_delete',
array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attr'=>$attr,'oldvalue'=>$current_attrs[$attr]))) {
unset($attrs[$attr]);
system_message(array(
'title'=>_('Attribute not deleted'),
'body'=>sprintf('%s (<b>%s</b>)',_('Hook pre_attr_delete prevented attribute from being deleted'),$attr),
'type'=>'warn'));
} else
$summary['delete'][$attr]['old'] = $current_attrs[$attr];
}
}
if (! count($attrs))
return false;
if (run_hook('pre_entry_modify',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attrs'=>$attrs))) {
$result = @ldap_modify($this->connect($method),$dn,$attrs);
if ($result) {
run_hook('post_entry_modify',array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attrs'=>$attrs));
foreach (array('add','modify','delete') as $mode)
if (isset($summary[$mode]))
foreach ($summary[$mode] as $attr => $values)
switch ($mode) {
case 'add':
run_hook(sprintf('post_attr_%s',$mode),
array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attr'=>$attr,'newvalue'=>$values['new']));
break;
case 'modify':
run_hook(sprintf('post_attr_%s',$mode),
array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attr'=>$attr,'oldvalue'=>$values['old'],'newvalue'=>$values['new']));
break;
case 'delete':
run_hook(sprintf('post_attr_%s',$mode),
array('server_id'=>$this->index,'method'=>$method,'dn'=>$dn,'attr'=>$attr,'oldvalue'=>$values['old']));
break;
default:
debug_dump_backtrace(sprintf('Unkown mode %s',$mode),1);
}
} else {
system_message(array(
'title'=>_('Could not perform ldap_modify operation.'),
'body'=>ldap_error_msg($this->getErrorMessage($method),$this->getErrorNum($method)),
'type'=>'error'));
}
}
return $result;
}
/**
* Returns true if the specified attribute is configured as unique
* in config.php.
* Attributes are configured as hidden in config.php thus:
* <code>
* $servers->setValue('unique','attrs',array('mail','uid','uidNumber'));
* </code>
*
* @param string $attr The name of the attribute to test.
* @return boolean
*/
public function isAttrUnique($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
# Should this attribute value be unique
if (in_array_ignore_case($attr,$this->getValue('unique','attrs')))
return true;
else
return false;
}
/**
* This function will check whether the value for an attribute being changed
* is already assigned to another DN.
*
* Returns the bad value, or null if all values are OK
*
* @param dn DN that is being changed
* @param string Attribute being changed
* @param string|array New values for the attribute
*/
public function checkUniqueAttrs($dn,$attrs) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
# If none of the attributes are defined unique, we'll return immediately;
if (! $checkattrs = array_intersect(arrayLower($this->getValue('unique','attrs')),array_keys(array_change_key_case($attrs))))
return true;
# Check see and use our alternate uid_dn and password if we have it.
if (! $this->login($this->getValue('unique','dn'),$this->getValue('unique','pass'),'unique')) {
system_message(array(
'title'=>_('UNIQUE invalid login/password'),
'body'=>sprintf('%s (<b>%s</b>)',_('Unable to connect to LDAP server with the unique login/password, please check your configuration.'),
$this->getName()),
'type'=>'warn'));
return false;
}
$query = array();
# Build our search filter to double check each attribute.
$query['filter'] = '(|';
foreach ($checkattrs as $attr)
foreach ($attrs[$attr] as $val)
if ($val)
$query['filter'] .= sprintf('(%s=%s)',$attr,$val);
$query['filter'] .= ')';
$query['attrs'] = $checkattrs;
# Search through our bases and see if we have match
foreach ($this->getBaseDN() as $base) {
$query['base'] = $base;
# Do the search
$results = $this->query($query,'unique');
# If we have a match.
if (count($results))
foreach ($results as $values)
# If one of the attributes is owned to somebody else, then we may as well die here.
if ($values['dn'] != $dn) {
$href = sprintf('cmd.php?cmd=query_engine&server_id=%s&filter=%s&scope=sub&query=none&format=list&search=true',$this->index,$query['filter']);
system_message(array(
'title'=>_('Attribute value would not be unique'),
'body'=>sprintf('%s (<b><a href="%s">%s</a></b>)',
_('This update has been or will be cancelled, it would result in an attribute value not being unique. You might like to search the LDAP server for the offending entry.'),
htmlspecialchars($href),
_('Search')),
'type'=>'warn'));
return false;
}
}
# If we get here, then it must be OK?
return true;
}
/**
* Check if the session timeout has occured for this LDAP server.
*/
public function isSessionValid() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
# If inactiveTime() returns a value, we need to check that it has not expired.
if (is_null($this->inactivityTime()) || ! $this->isLoggedIn())
return true;
# If session has expired
if ((isset($_SESSION['ACTIVITY'][$this->getIndex()])) && ($_SESSION['ACTIVITY'][$this->getIndex()] < time())) {
$this->logout();
unset($_SESSION['ACTIVITY'][$this->getIndex()]);
return false;
}
$_SESSION['ACTIVITY'][$this->getIndex()] = $this->inactivityTime();
return true;
}
}
?>

View File

@ -0,0 +1,112 @@
<?php
/*******************************************************************************
* @package default
* emuhash - partly emulates the php mhash functions
* version: 2004040701
*
* (c) 2004 - Simon Matter <simon.matter@invoca.ch>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
******************************************************************************/
/******************************************************************************/
/* Do we have builtin mhash support in this PHP version ? */
/******************************************************************************/
if (! function_exists('mhash') && ! function_exists('mhash_keygen_s2k')) {
$emuhash_emu = array();
if (! isset($emuhash_emu['openssl']))
$emuhash_emu['openssl'] = '/usr/bin/openssl';
# Don't create mhash functions if we don't have a working openssl
if (! file_exists($emuhash_emu['openssl']))
unset($emuhash_emu['openssl']);
elseif (function_exists('is_executable') && ! is_executable($emuhash_emu['openssl']))
unset($emuhash_emu['openssl']);
else {
if (! isset($emuhash_emu['tmpdir']))
$emuhash_emu['tmpdir'] = '/tmp';
/******************************************************************************/
/* Define constants used in the mhash emulation code. */
/******************************************************************************/
define('MHASH_MD5','md5');
define('MHASH_SHA1','sha1');
define('MHASH_RIPEMD160','rmd160');
/******************************************************************************/
/* Functions to emulate parts of php-mash. */
/******************************************************************************/
function openssl_hash($openssl_hash_id,$password_clear) {
global $emuhash_emu;
if (PHP_VERSION < 6) {
$current_magic_quotes = @get_magic_quotes_runtime();
@set_magic_quotes_runtime(0);
}
$tmpfile = tempnam($emuhash_emu['tmpdir'],'emuhash');
$pwhandle = fopen($tmpfile,'w');
if (! $pwhandle)
error(sprintf('Unable to create a temporary file %s to create hashed password',$tmpfile) ,'error','index.php');
fwrite($pwhandle,$password_clear);
fclose($pwhandle);
$cmd = sprintf('%s %s -binary <%s',$emuhash_emu['openssl'],$openssl_hash_id,$tmpfile);
$prog = popen($cmd,'r');
$pass = fread($prog,1024);
pclose($prog);
unlink($tmpfile);
if (PHP_VERSION < 6)
@set_magic_quotes_runtime($current_magic_quotes);
return $pass;
}
function mhash($hash_id,$password_clear) {
switch($hash_id) {
case MHASH_MD5:
$emuhash = openssl_hash(MHASH_MD5,$password_clear);
break;
case MHASH_SHA1:
$emuhash = openssl_hash(MHASH_SHA1,$password_clear);
break;
case MHASH_RIPEMD160:
$emuhash = openssl_hash(MHASH_RIPEMD160,$password_clear);
break;
default:
$emuhash = FALSE;
}
return $emuhash;
}
function mhash_keygen_s2k($hash_id,$password_clear,$salt,$bytes) {
return substr(pack('H*',bin2hex(mhash($hash_id,($salt.$password_clear)))),0,$bytes);
}
}
}
?>

View File

@ -0,0 +1,643 @@
<?php
/**
* Classes and functions for export data from LDAP
*
* These classes provide differnet export formats.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
* @see export.php and export_form.php
*/
/**
* Exporter Class
*
* This class serves as a top level exporter class, which will return
* the correct Export class.
*
* @package phpLDAPadmin
* @subpackage Export
*/
class Exporter {
# Server ID that the export is linked to
private $server_id;
# Exporter Type
private $template_id;
private $template;
public function __construct($server_id,$template_id) {
$this->server_id = $server_id;
$this->template_id = $template_id;
$this->accept();
}
static function types() {
$type = array();
$details = ExportCSV::getType();
$type[$details['type']] = $details;
$details = ExportDSML::getType();
$type[$details['type']] = $details;
$details = ExportLDIF::getType();
$type[$details['type']] = $details;
$details = ExportVCARD::getType();
$type[$details['type']] = $details;
return $type;
}
private function accept() {
switch($this->template_id) {
case 'CSV':
$this->template = new ExportCSV();
break;
case 'DSML':
$this->template = new ExportDSML();
break;
case 'LDIF':
$this->template = new ExportLDIF();
break;
case 'VCARD':
$this->template = new ExportVCARD();
break;
default:
system_message(array(
'title'=>sprintf('%s %s',_('Unknown Export Type'),$this->template_id),
'body'=>_('phpLDAPadmin has not been configured for that export type'),
'type'=>'warn'),'index.php');
die();
}
$this->template->accept();
}
public function getTemplate() {
return $this->template;
}
}
/**
* Export Class
*
* This abstract classes provides all the common methods and variables for the
* custom export classes.
*
* @package phpLDAPadmin
* @subpackage Export
*/
abstract class Export {
# Line Break
protected $br;
# Compress the output
protected $compress;
# Export Results
protected $results;
protected $resultsdata;
protected $items = 0;
/**
* Return this LDAP Server object
*
* @return object DataStore Server
*/
protected function getServer() {
return $_SESSION[APPCONFIG]->getServer($this->getServerID());
}
/**
* Return the LDAP server ID
*
* @return int Server ID
*/
protected function getServerID() {
return get_request('server_id','REQUEST');
}
public function accept() {
$server = $this->getServer();
# Get the data to be exported
$query = array();
$base = get_request('dn','REQUEST');
$query['baseok'] = true;
$query['filter'] = get_request('filter','REQUEST',false,'objectclass=*');
$query['scope'] = get_request('scope','REQUEST',false,'base');
$query['deref'] = $_SESSION[APPCONFIG]->getValue('deref','export');
$query['size_limit'] = 0;
$attrs = get_request('attributes','REQUEST');
$attrs = preg_replace('/\s+/','',$attrs);
if ($attrs)
$query['attrs'] = explode(',',$attrs);
else
$query['attrs'] = array('*');
if (get_request('sys_attr')) {
if (! in_array('*',$query['attrs']))
array_push($query['attrs'],'*');
array_push($query['attrs'],'+');
}
if (! $base)
$bases = $server->getBaseDN();
else
$bases = array($base);
foreach ($bases as $base) {
$query['base'] = $base;
$time_start = utime();
$this->results[$base] = $server->query($query,null);
$time_end = utime();
usort($this->results[$base],'pla_compare_dns');
$this->resultsdata[$base]['time'] = round($time_end-$time_start,2);
# If no result, there is a something wrong
if (! $this->results[$base] && $server->getErrorNum(null))
system_message(array(
'title'=>_('Encountered an error while performing search.'),
'body'=>ldap_error_msg($server->getErrorMessage(null),$server->getErrorNum(null)),
'type'=>'error'));
$this->items += count($this->results[$base]);
}
$this->resultsdata['scope'] = $query['scope'];
$this->resultsdata['filter'] = $query['filter'];
$this->resultsdata['attrs'] = $query['attrs'];
# Other settings
switch (get_request('format','POST',false,'unix')) {
case 'win':
$this->br = "\r\n";
break;
case 'mac':
$this->br = "\r";
break;
case 'unix':
default:
$this->br = "\n";
}
if (get_request('compress','REQUEST') == 'on')
$this->compress = true;
}
public function isCompressed() {
return $this->compress;
}
protected function getHeader() {
$server = $this->getServer();
$type = $this->getType();
$output = '';
$output .= sprintf('# %s %s %s%s',$type['description'],_('for'),implode('|',array_keys($this->results)),$this->br);
$output .= sprintf('# %s: %s (%s)%s',_('Server'),$server->getName(),$server->getValue('server','host'),$this->br);
$output .= sprintf('# %s: %s%s',_('Search Scope'),$this->resultsdata['scope'],$this->br);
$output .= sprintf('# %s: %s%s',_('Search Filter'),$this->resultsdata['filter'],$this->br);
$output .= sprintf('# %s: %s%s',_('Total Entries'),$this->items,$this->br);
$output .= sprintf('#%s',$this->br);
$output .= sprintf('# Generated by %s (%s) on %s%s',app_name(),get_href('web'),date('F j, Y g:i a'),$this->br);
$output .= sprintf('# Version: %s%s',app_version(),$this->br);
$output .= $this->br;
return $output;
}
/**
* Helper method to check if the attribute value should be base 64 encoded.
*
* @param The string to check.
* @return boolean true if the string is safe ascii, false otherwise.
*/
protected function isSafeAscii($str) {
for ($i=0;$i<strlen($str);$i++)
if (ord($str{$i}) < 32 || ord($str{$i}) > 127)
return false;
return true;
}
}
/**
* Export entries to CSV
*
* @package phpLDAPadmin
* @subpackage Export
*/
class ExportCSV extends Export {
private $separator = ',';
private $qualifier = '"';
private $multivalue_separator = ' | ';
private $escapeCode = '"';
static public function getType() {
return array('type'=>'CSV','description' => 'CSV (Spreadsheet)','extension'=>'csv');
}
function export() {
$server = $this->getServer();
/* Go thru and find all the attribute names first. This is needed, because, otherwise we have
* no idea as to which search attributes were actually populated with data */
$headers = array('dn');
$entries = array();
foreach ($this->results as $base => $results) {
foreach ($results as $dndetails) {
array_push($entries,$dndetails);
unset($dndetails['dn']);
foreach (array_keys($dndetails) as $key)
if (! in_array($key,$headers))
array_push($headers,$key);
}
}
$output = '';
$num_headers = count($headers);
# Print out the headers
for ($i=0; $i<$num_headers; $i++) {
$output .= sprintf('%s%s%s',$this->qualifier,$headers[$i],$this->qualifier);
if ($i < $num_headers-1)
$output .= $this->separator;
}
# Drop out our DN header.
array_shift($headers);
$num_headers--;
$output .= $this->br;
# Loop on every entry
foreach ($entries as $index => $entry) {
$dn = $entry['dn'];
unset($entry['dn']);
$output .= sprintf('%s%s%s%s',$this->qualifier,$this->LdapEscape($dn),$this->qualifier,$this->separator);
# Print the attributes
for ($j=0; $j<$num_headers; $j++) {
$attr = $headers[$j];
$output .= $this->qualifier;
if (array_key_exists($attr,$entry)) {
$binary_attribute = $server->isAttrBinary($attr) ? 1 : 0;
if (! is_array($entry[$attr]))
$attr_values = array($entry[$attr]);
else
$attr_values = $entry[$attr];
$num_attr_values = count($attr_values);
for ($i=0; $i<$num_attr_values; $i++) {
if ($binary_attribute)
$output .= base64_encode($attr_values[$i]);
else
$output .= $this->LdapEscape($attr_values[$i]);
if ($i < $num_attr_values-1)
$output .= $this->multivalue_separator;
}
}
$output .= $this->qualifier;
if ($j < $num_headers-1)
$output .= $this->separator;
}
$output .= $this->br;
}
if ($this->compress)
return gzencode($output);
else
return $output;
}
/**
* Function to escape data, where the qualifier happens to also
* be in the data.
*/
private function LdapEscape ($var) {
return str_replace($this->qualifier,$this->escapeCode.$this->qualifier,$var);
}
}
/**
* Export entries to DSML v.1
*
* @package phpLDAPadmin
* @subpackage Export
*/
class ExportDSML extends Export {
static public function getType() {
return array('type'=>'DSML','description' => _('DSML V.1 Export'),'extension'=>'xml');
}
/**
* Export entries to DSML format
*/
function export() {
$server = $this->getServer();
# Not very elegant, but do the job for the moment as we have just 4 level
$indent = array();
$indent['dir'] = ' ';
$indent['ent'] = ' ';
$indent['att'] = ' ';
$indent['val'] = ' ';
# Print declaration
$output = sprintf('<?xml version="1.0"?>%s',$this->br);
# Print root element
$output .= sprintf('<dsml>%s',$this->br);
# Print info related to this export
$output .= sprintf('<!--%s',$this->br);
$output .= $this->getHeader();
$output .= sprintf('-->%s',$this->br);
$output .= $this->br;
$output .= sprintf('%s<directory-entries>%s',$indent['dir'],$this->br);
# Sift through the entries.
$counter = 0;
foreach ($this->results as $base => $results) {
foreach ($results as $dndetails) {
$counter++;
$dn = $dndetails['dn'];
unset($dndetails['dn']);
ksort($dndetails);
# Display DN
$output .= sprintf('%s<entry dn="%s">%s',$indent['ent'],htmlspecialchars($dn),$this->br);
# Display the objectClass attributes first
if (isset($dndetails['objectClass'])) {
if (! is_array($dndetails['objectClass']))
$dndetails['objectClass'] = array($dndetails['objectClass']);
$output .= sprintf('%s<objectClass>%s',$indent['att'],$this->br);
foreach ($dndetails['objectClass'] as $ocValue)
$output .= sprintf('%s<oc-value>%s</oc-value>%s',$indent['val'],$ocValue,$this->br);
$output .= sprintf('%s</objectClass>%s',$indent['att'],$this->br);
unset($dndetails['objectClass']);
}
# Display the attributes
foreach ($dndetails as $key => $attr) {
if (! is_array($attr))
$attr = array($attr);
$output .= sprintf('%s<attr name="%s">%s',$indent['att'],$key,$this->br);
# If the attribute is binary, set the flag $binary_mode to true
$binary_mode = $server->isAttrBinary($key) ? 1 : 0;
foreach ($attr as $value)
$output .= sprintf('%s<value>%s</value>%s',
$indent['val'],($binary_mode ? base64_encode($value) : htmlspecialchars($value)),$this->br);
$output .= sprintf('%s</attr>%s',$indent['att'],$this->br);
}
$output .= sprintf('%s</entry>%s',$indent['ent'],$this->br);
}
}
$output .= sprintf('%s</directory-entries>%s',$indent['dir'],$this->br);
$output .= sprintf('</dsml>%s',$this->br);
if ($this->compress)
return gzencode($output);
else
return $output;
}
}
/**
* Export from LDAP using an LDIF format
*
* @package phpLDAPadmin
* @subpackage Export
*/
class ExportLDIF extends Export {
# The maximum length of the ldif line
private $line_length = 76;
static public function getType() {
return array('type'=>'LDIF','description' => _('LDIF Export'),'extension'=>'ldif');
}
/**
* Export entries to LDIF format
*/
public function export() {
if (! $this->results) {
echo _('Nothing to export');
return;
}
$server = $this->getServer();
$output = $this->getHeader();
# Add our version.
$output .= 'version: 1';
$output .= $this->br;
$output .= $this->br;
# Sift through the entries.
$counter = 0;
foreach ($this->results as $base => $results) {
foreach ($results as $dndetails) {
$counter++;
$dn = $dndetails['dn'];
unset($dndetails['dn']);
ksort($dndetails);
$title_string = sprintf('# %s %s: %s%s',_('Entry'),$counter,$dn,$this->br);
if (strlen($title_string) > $this->line_length-3)
$title_string = substr($title_string,0,$this->line_length-3).'...'.$this->br;
$output .= $title_string;
# Display dn
if ($this->isSafeAscii($dn))
$output .= $this->multiLineDisplay(sprintf('dn: %s',$dn));
else
$output .= $this->multiLineDisplay(sprintf('dn:: %s',base64_encode($dn)));
# display the attributes
foreach ($dndetails as $key => $attr) {
if (! is_array($attr))
$attr = array($attr);
foreach ($attr as $value)
if (! $this->isSafeAscii($value) || $server->isAttrBinary($key))
$output .= $this->multiLineDisplay(sprintf('%s:: %s',$key,base64_encode($value)));
else
$output .= $this->multiLineDisplay(sprintf('%s: %s',$key,$value));
}
$output .= $this->br;
}
}
if ($this->compress)
return gzencode($output);
else
return $output;
}
/**
* Helper method to wrap ldif lines
*
* @param The line to be wrapped if needed.
*/
private function multiLineDisplay($str) {
$length_string = strlen($str);
$length_max = $this->line_length;
$output = '';
while ($length_string > $length_max) {
$output .= substr($str,0,$length_max).$this->br.' ';
$str = substr($str,$length_max,$length_string);
$length_string = strlen($str);
/* Need to do minus one to align on the right
* the first line with the possible following lines
* as these will have an extra space. */
$length_max = $this->line_length-1;
}
$output .= $str.$this->br;
return $output;
}
}
/**
* Export entries to VCARD v2.1
*
* @package phpLDAPadmin
* @subpackage Export
*/
class ExportVCARD extends Export {
static public function getType() {
return array('type'=>'VCARD','description' => _('VCARD 2.1 Export'),'extension'=>'vcf');
}
# Mappping one to one attribute
private $mapping = array(
'cn' => 'FN',
'title' => 'TITLE',
'homephone' => 'TEL;HOME',
'mobile' => 'TEL;CELL',
'mail' => 'EMAIL;Internet',
'labeleduri' =>'URL',
'o' => 'ORG',
'audio' => 'SOUND',
'facsmiletelephoneNumber' =>'TEL;WORK;HOME;VOICE;FAX',
'jpegphoto' => 'PHOTO;ENCODING=BASE64',
'businesscategory' => 'ROLE',
'description' => 'NOTE'
);
private $deliveryAddress = array(
'postofficebox',
'street',
'l',
'st',
'postalcode',
'c');
/**
* Export entries to VCARD format
*/
function export() {
$server = $this->getServer();
$output = '';
# Sift through the entries.
foreach ($this->results as $base => $results) {
foreach ($results as $dndetails) {
$dndetails = array_change_key_case($dndetails);
# Check the attributes needed for the delivery address field
$addr = 'ADR:';
foreach ($this->deliveryAddress as $attr) {
if (isset($dndetails[$attr])) {
$addr .= $dndetails[$attr];
unset($dndetails[$attr]);
}
$addr .= ';';
}
$output .= sprintf('BEGIN:VCARD%s',$this->br);
# Loop for the attributes
foreach ($dndetails as $key => $attr) {
if (! is_array($attr))
$attr = array($attr);
# If an attribute of the ldap entry exist in the mapping array for vcard
if (isset($this->mapping[$key])) {
# Case of organisation. Need to append the possible ou attribute
if ($key == 'o') {
$output .= sprintf('%s:%s',$this->mapping[$key],$attr[0]);
if (isset($entry['ou']))
foreach ($entry['ou'] as $ou_value)
$output .= sprintf(';%s',$ou_value);
# The attribute is binary. (to do : need to fold the line)
} elseif (in_array($key,array('audio','jpegphoto'))) {
$output .= $this->mapping[$key].':'.$this->br;
$output .= ' '.base64_encode($attr[0]);
} else {
$output .= $this->mapping[$key].':'.$attr[0];
}
$output .= $this->br;
}
}
$output .= sprintf('UID:%s%s',isset($dndetails['entryUUID']) ? $dndetails['entryUUID'] : $dndetails['dn'],$this->br);
$output .= sprintf('VERSION:2.1%s',$this->br);
$output .= sprintf('%s%s',$addr,$this->br);
$output .= sprintf('END:VCARD%s',$this->br);
}
}
if ($this->compress)
return gzencode($output);
else
return $output;
}
}
?>

3142
phpldapadmin/lib/functions.php Executable file

File diff suppressed because it is too large Load Diff

201
phpldapadmin/lib/hooks.php Executable file
View File

@ -0,0 +1,201 @@
<?php
/**
* Functions related to hooks management.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* @author Benjamin Drieu <benjamin.drieu@fr.alcove.com> and AlcÃ?ve
* @package phpLDAPadmin
*/
/**
* Compares two arrays by numerically comparing their 'prority'
* value. Standard `cmp-like' function.
*
* @param a First element to compare.
* @param b Second element to compare.
*
* @return -1 if priority of first element is smaller than second
* element priority. 1 otherwise.
*/
function sort_array_by_priority($a,$b) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',257,0,__FILE__,__LINE__,__METHOD__,$fargs);
return (($a['priority'] < $b['priority']) ? -1 : 1 );
}
/**
* Runs procedures attached to a hook.
*
* @param hook_name Name of hook to run.
* @param args Array of optional arguments set by phpldapadmin. It is normally in a form known by call_user_func_array() :
*
* <pre>[ 'server_id' => 0,
* 'dn' => 'uid=epoussa,ou=tech,o=corp,o=fr' ]</pre>
*
* @return true if all procedures returned true, false otherwise.
*/
function run_hook($hook_name,$args) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',257,0,__FILE__,__LINE__,__METHOD__,$fargs);
$hooks = isset($_SESSION[APPCONFIG]) ? $_SESSION[APPCONFIG]->hooks : array();
if (! count($hooks) || ! array_key_exists($hook_name,$hooks)) {
if (DEBUG_ENABLED)
debug_log('Returning, HOOK not defined (%s)',257,0,__FILE__,__LINE__,__METHOD__,$hook_name);
return true;
}
$rollbacks = array();
reset($hooks[$hook_name]);
/* Execution of procedures attached is done using a numeric order
* since all procedures have been attached to the hook with a
* numerical weight. */
while (list($key,$hook) = each($hooks[$hook_name])) {
if (DEBUG_ENABLED)
debug_log('Calling HOOK Function (%s)(%s)',257,0,__FILE__,__LINE__,__METHOD__,
$hook['hook_function'],$args);
array_push($rollbacks,$hook['rollback_function']);
$result = call_user_func_array($hook['hook_function'],$args);
if (DEBUG_ENABLED)
debug_log('Called HOOK Function (%s)',257,0,__FILE__,__LINE__,__METHOD__,
$hook['hook_function']);
/* If a procedure fails (identified by a false return), its optional rollback is executed with
* the same arguments. After that, all rollbacks from
* previously executed procedures are executed in the reverse
* order. */
if (! is_null($result) && $result == false) {
if (DEBUG_ENABLED)
debug_log('HOOK Function [%s] return (%s)',257,0,__FILE__,__LINE__,__METHOD__,
$hook['hook_function'],$result);
while ($rollbacks) {
$rollback = array_pop($rollbacks);
if ($rollback != false) {
if (DEBUG_ENABLED)
debug_log('HOOK Function Rollback (%s)',257,0,__FILE__,__LINE__,__METHOD__,
$rollback);
call_user_func_array($rollback,$args);
}
}
return false;
}
}
return true;
}
/**
* Adds a procedure to a hook for later execution.
*
* @param hook_name Name of the hook.
* @param hook_function Name of the php function called upon hook trigger.
* @param priority Numeric priority. Lowest means procedure will be executed before.
* @param rollback_function Name of the php rollback function called upon failure.
*/
function add_hook($hook_name,$hook_function,$priority=0,$rollback_function=null) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',257,0,__FILE__,__LINE__,__METHOD__,$fargs);
# First, see if the hook function exists.
if (! function_exists($hook_function)) {
system_message(array(
'title'=>_('Hook function does not exist'),
'body'=>sprintf('Hook name: %s<br/>Hook function: %s',$hook_name,$hook_function),
'type'=>'warn'));
return;
}
if (! array_key_exists($hook_name,$_SESSION[APPCONFIG]->hooks))
$_SESSION[APPCONFIG]->hooks[$hook_name] = array();
remove_hook($hook_name,$hook_function,-1,null);
array_push($_SESSION[APPCONFIG]->hooks[$hook_name],array(
'priority' => $priority,
'hook_function' => $hook_function,
'rollback_function' => $rollback_function));
uasort($_SESSION[APPCONFIG]->hooks[$hook_name],'sort_array_by_priority');
}
/**
* Removes a procedure from a hook, based on a filter.
*
* @param hook_name Name of the hook.
* @param priority Numeric priority. If set, all procedures of that priority will be removed.
* @param hook_function Name of the procedure function. If set, all procedures that call this function will be removed.
* @param rollback_function Name of the php rollback function called upon failure. If set, all
* procedures that call this function as a rollback will be removed.
*/
function remove_hook($hook_name,$hook_function,$priority,$rollback_function) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',257,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (array_key_exists($hook_name,$_SESSION[APPCONFIG]->hooks)) {
reset($_SESSION[APPCONFIG]->hooks[$hook_name]);
while (list($key,$hook) = each($_SESSION[APPCONFIG]->hooks[$hook_name])) {
if (($priority >= 0 && $priority == $hook['priority']) ||
($hook_function && $hook_function == $hook['hook_function']) ||
($rollback_function && $rollback_function == $hook['rollback_function'])) {
unset($_SESSION[APPCONFIG]->hooks[$hook_name][$key]);
}
}
}
}
/**
* Removes all procedures from a hook.
*
* @param hook_name Name of hook to clear.
*/
function clear_hooks($hook_name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',257,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (array_key_exists($hook_name,$_SESSION[APPCONFIG]->hooks))
unset($_SESSION[APPCONFIG]->hooks[$hook_name]);
}
$hooks = array();
# Evaluating user-made hooks
if (is_dir(HOOKSDIR.'functions')) {
$hooks['dir'] = dir(HOOKSDIR.'functions');
while ($hooks['file'] = $hooks['dir']->read()) {
$script = sprintf('%s/%s/%s',HOOKSDIR,'functions',$hooks['file']);
if (is_file($script) && preg_match('/php[0-9]?$/',$hooks['file']))
require_once $script;
}
$hooks['dir']->close();
}
?>

View File

@ -0,0 +1,609 @@
<?php
/**
* Classes and functions for importing data to LDAP
*
* These classes provide differnet import formats.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
* @see import.php and import_form.php
*/
/**
* Importer Class
*
* This class serves as a top level importer class, which will return
* the correct Import class.
*
* @package phpLDAPadmin
* @subpackage Import
*/
class Importer {
# Server ID that the export is linked to
private $server_id;
# Import Type
private $template_id;
private $template;
public function __construct($server_id,$template_id) {
$this->server_id = $server_id;
$this->template_id = $template_id;
$this->accept();
}
static function types() {
$type = array();
$details = ImportLDIF::getType();
$type[$details['type']] = $details;
return $type;
}
private function accept() {
switch($this->template_id) {
case 'LDIF':
$this->template = new ImportLDIF($this->server_id);
break;
default:
system_message(array(
'title'=>sprintf('%s %s',_('Unknown Import Type'),$this->template_id),
'body'=>_('phpLDAPadmin has not been configured for that import type'),
'type'=>'warn'),'index.php');
die();
}
$this->template->accept();
}
public function getTemplate() {
return $this->template;
}
}
/**
* Import Class
*
* This abstract classes provides all the common methods and variables for the
* custom import classes.
*
* @package phpLDAPadmin
* @subpackage Import
*/
abstract class Import {
protected $server_id = null;
protected $input = null;
protected $source = array();
public function __construct($server_id) {
$this->server_id = $server_id;
}
public function accept() {
if (get_request('ldif','REQUEST')) {
$this->input = explode("\n",get_request('ldif','REQUEST'));
$this->source['name'] = 'STDIN';
$this->source['size'] = strlen(get_request('ldif','REQUEST'));
} elseif (isset($_FILES['ldif_file']) && is_array($_FILES['ldif_file']) && ! $_FILES['ldif_file']['error']) {
$input = file_get_contents($_FILES['ldif_file']['tmp_name']);
$this->input = preg_split("/\n|\r\n|\r/",$input);
$this->source['name'] = $_FILES['ldif_file']['name'];
$this->source['size'] = $_FILES['ldif_file']['size'];
} else {
system_message(array(
'title'=>_('No import input'),
'body'=>_('You must either upload a file or provide an import in the text box.'),
'type'=>'error'),sprintf('cmd.php?cmd=import_form&server_id=%s',get_request('server_id','REQUEST')));
die();
}
}
public function getSource($attr) {
if (isset($this->source[$attr]))
return $this->source[$attr];
else
return null;
}
# @todo integrate hooks
public function LDAPimport() {
$template = $this->getTemplate();
$server = $this->getServer();
switch ($template->getType()) {
case 'add':
return $server->add($template->getDN(),$template->getLDAPadd());
case 'modify':
return $server->modify($template->getDN(),$template->getLDAPmodify());
case 'moddn':
case 'modrdn':
return $server->rename($template->getDN(),$template->modrdn['newrdn'],$template->modrdn['newsuperior'],$template->modrdn['deleteoldrdn']);
default:
debug_dump_backtrace(sprintf('Unknown template type %s',$template->getType()),1);
}
return true;
}
}
/**
* Import entries from LDIF
*
* The LDIF spec is described by RFC2849
* https://www.ietf.org/rfc/rfc2849.txt
*
* @package phpLDAPadmin
* @subpackage Import
*/
class ImportLDIF extends Import {
private $_currentLineNumber = 0;
private $_currentLine = '';
private $template;
public $error = array();
static public function getType() {
return array('type'=>'LDIF','description' => _('LDIF Import'),'extension'=>'ldif');
}
protected function getTemplate() {
return $this->template;
}
protected function getServer() {
return $_SESSION[APPCONFIG]->getServer($this->server_id);
}
public function readEntry() {
static $haveVersion = false;
if ($lines = $this->nextLines()) {
# If we have a version line.
if (! $haveVersion && preg_match('/^version:/',$lines[0])) {
list($text,$version) = $this->getAttrValue(array_shift($lines));
if ($version != 1)
return $this->error(sprintf('%s %s',_('LDIF import only suppports version 1'),$version),$lines);
$haveVersion = true;
$lines = $this->nextLines();
}
$server = $this->getServer();
# The first line should be the DN
if (preg_match('/^dn:/',$lines[0])) {
list($text,$dn) = $this->getAttrValue(array_shift($lines));
# The second line should be our changetype
if (preg_match('/^changetype:[ ]*(delete|add|modrdn|moddn|modify)/i',$lines[0])) {
$attrvalue = $this->getAttrValue($lines[0]);
$changetype = $attrvalue[1];
array_shift($lines);
} else
$changetype = 'add';
$this->template = new Template($this->server_id,null,null,$changetype);
switch ($changetype) {
case 'add':
$rdn = get_rdn($dn);
$container = $server->getContainer($dn);
$this->template->setContainer($container);
$this->template->accept();
$this->getAddDetails($lines);
$this->template->setRDNAttributes($rdn);
return $this->template;
break;
case 'modify':
if (! $server->dnExists($dn))
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
$this->template->setDN($dn);
$this->template->accept(false,true);
return $this->getModifyDetails($lines);
break;
case 'moddn':
case 'modrdn':
if (! $server->dnExists($dn))
return $this->error(sprintf('%s %s',_('DN does not exist'),$dn),$lines);
$this->template->setDN($dn);
$this->template->accept();
return $this->getModRDNAttributes($lines);
break;
default:
if (! $server->dnExists($dn))
return $this->error(_('Unkown change type'),$lines);
}
} else
return $this->error(_('A valid dn line is required'),$lines);
} else
return false;
}
/**
* Get the Attribute and Decoded Value
*/
private function getAttrValue($line) {
list($attr,$value) = explode(':',$line,2);
# Get the DN
if (substr($value,0,1) == ':')
$value = base64_decode(trim(substr($value,1)));
else
$value = trim($value);
return array($attr,$value);
}
/**
* Get the lines of the next entry
*
* @return The lines (unfolded) of the next entry
*/
private function nextLines() {
$current = array();
$endEntryFound = false;
if ($this->hasMoreEntries() && ! $this->eof()) {
# The first line is the DN one
$current[0]= trim($this->_currentLine);
# While we end on a blank line, fetch the attribute lines
$count = 0;
while (! $this->eof() && ! $endEntryFound) {
# Fetch the next line
$this->nextLine();
/* If the next line begin with a space, we append it to the current row
* else we push it into the array (unwrap)*/
if ($this->isWrappedLine())
$current[$count] .= trim($this->_currentLine);
elseif ($this->isCommentLine()) {}
# Do nothing
elseif (! $this->isBlankLine())
$current[++$count] = trim($this->_currentLine);
else
$endEntryFound = true;
}
# Return the LDIF entry array
return $current;
} else
return array();
}
/**
* Private method to check if there is more entries in the input.
*
* @return boolean true if an entry was found, false otherwise.
*/
private function hasMoreEntries() {
$entry_found = false;
while (! $this->eof() && ! $entry_found) {
# If it's a comment or blank line, switch to the next line
if ($this->isCommentLine() || $this->isBlankLine()) {
# Do nothing
$this->nextLine();
} else {
$this->_currentDnLine = $this->_currentLine;
$this->dnLineNumber = $this->_currentLineNumber;
$entry_found = true;
}
}
return $entry_found;
}
/**
* Helper method to switch to the next line
*/
private function nextLine() {
$this->_currentLineNumber++;
$this->_currentLine = array_shift($this->input);
}
/**
* Check if it's a comment line.
*
* @return boolean true if it's a comment line,false otherwise
*/
private function isCommentLine() {
return substr(trim($this->_currentLine),0,1) == '#' ? true : false;
}
/**
* Check if it's a wrapped line.
*
* @return boolean true if it's a wrapped line,false otherwise
*/
private function isWrappedLine() {
return substr($this->_currentLine,0,1) == ' ' ? true : false;
}
/**
* Check if is the current line is a blank line.
*
* @return boolean if it is a blank line,false otherwise.
*/
private function isBlankLine() {
return(trim($this->_currentLine) == '') ? true : false;
}
/**
* Returns true if we reached the end of the input.
*
* @return boolean true if it's the end of file, false otherwise.
*/
public function eof() {
return count($this->input) > 0 ? false : true;
}
private function error($msg,$data) {
$this->error['message'] = sprintf('%s [%s]',$msg,$this->template ? $this->template->getDN() : '');
$this->error['line'] = $this->_currentLineNumber;
$this->error['data'] = $data;
$this->error['changetype'] = $this->template ? $this->template->getType() : 'Not set';
return false;
}
/**
* Method to retrieve the attribute value of a ldif line,
* and get the base 64 decoded value if it is encoded
*/
private function getAttributeValue($value) {
$return = '';
if (substr($value,0,1) == '<') {
$url = trim(substr($value,1));
if (preg_match('^file://',$url)) {
$filename = substr(trim($url),7);
if ($fh = @fopen($filename,'rb')) {
if (! $return = @fread($fh,filesize($filename)))
return $this->error(_('Unable to read file for'),$value);
@fclose($fh);
} else
return $this->error(_('Unable to open file for'),$value);
} else
return $this->error(_('The url attribute value should begin with file:// for'),$value);
# It's a string
} else
$return = $value;
return trim($return);
}
/**
* Build the attributes array when the change type is add.
*/
private function getAddDetails($lines) {
foreach ($lines as $line) {
list($attr,$value) = $this->getAttrValue($line);
if (is_null($attribute = $this->template->getAttribute($attr))) {
$attribute = $this->template->addAttribute($attr,array('values'=>array($value)));
$attribute->justModified();
} else
if ($attribute->hasBeenModified())
$attribute->addValue($value);
else
$attribute->setValue(array($value));
}
}
/**
* Build the attributes array for the entry when the change type is modify
*/
private function getModifyDetails($lines) {
if (! count($lines))
return $this->error(_('Missing attributes for'),$lines);
# While the array is not empty
while (count($lines)) {
$processline = false;
$deleteattr = false;
# Get the current line with the action
$currentLine = array_shift($lines);
$attrvalue = $this->getAttrValue($currentLine);
$action_attribute = $attrvalue[0];
$action_attribute_value = $attrvalue[1];
if (! in_array($action_attribute,array('add','delete','replace')))
return $this->error(_('Missing modify command add, delete or replace'),array_merge(array($currentLine),$lines));
$processline = true;
switch ($action_attribute) {
case 'add':
break;
case 'delete':
$attribute = $this->template->getAttribute($action_attribute_value);
if (is_null($attribute))
return $this->error(sprintf('%s %s',_('Attempting to delete a non existant attribute'),$action_attribute_value),
array_merge(array($currentLine),$lines));
$deleteattr = true;
break;
case 'replace':
$attribute = $this->template->getAttribute($action_attribute_value);
if (is_null($attribute))
return $this->error(sprintf('%s %s',_('Attempting to replace a non existant attribute'),$action_attribute_value),
array_merge(array($currentLine),$lines));
break;
default:
debug_dump_backtrace(sprintf('Unknown action %s',$action_attribute),1);
}
# Fetch the attribute for the following line
$currentLine = array_shift($lines);
while ($processline && trim($currentLine) && (trim($currentLine) != '-')) {
$processline = false;
# If there is a valid line
if (preg_match('/:/',$currentLine)) {
$attrvalue = $this->getAttrValue($currentLine);
$attr = $attrvalue[0];
$attribute_value_part = $attrvalue[1];
# Check that it correspond to the one specified before
if ($attr == $action_attribute_value) {
# Get the value part of the attribute
$attribute_value = $this->getAttributeValue($attribute_value_part);
$attribute = $this->template->getAttribute($attr);
# This should be a add/replace operation
switch ($action_attribute) {
case 'add':
if (is_null($attribute))
$attribute = $this->template->addAttribute($attr,array('values'=>array($attribute_value_part)));
else
$attribute->addValue($attribute_value_part,-1);
$attribute->justModified();
break;
case 'delete':
$deleteattr = false;
if (($key = array_search($attribute_value_part,$attribute->getValues())) !== false)
$attribute->delValue($key);
else
return $this->error(sprintf('%s %s',_('Delete value doesnt exist in DN'),$attribute_value_part),
array_merge(array($currentLine),$lines));
break;
case 'replace':
if ($attribute->hasBeenModified())
$attribute->addValue($attribute_value_part,-1);
else
$attribute->setValue(array($attribute_value_part));
break;
default:
debug_dump_backtrace(sprintf('Unexpected operation %s',$action_attribute));
}
} else
return $this->error(sprintf('%s %s',_('The attribute to modify doesnt match the one specified by'),$action_attribute),
array_merge(array($currentLine),$lines));
} else
return $this->error(sprintf('%s %s',_('Attribute not valid'),$currentLine),
array_merge(array($currentLine),$lines));
$currentLine = array_shift($lines);
if (trim($currentLine))
$processline = true;
}
if ($action_attribute == 'delete' && $deleteattr)
$attribute->setValue(array());
}
return $this->template;
}
/**
* Build the attributes for the entry when the change type is modrdn
*/
function getModRDNAttributes($lines) {
$server = $this->getServer();
$attrs = array();
# MODRDN MODDN should only be 2 or 3 lines.
if (count($lines) != 2 && count($lines) !=3)
return $this->error(_('Invalid entry'),$lines);
else {
$currentLine = array_shift($lines);
# First we need to check if there is an new rdn specified
if (preg_match('/^newrdn:(:?)/',$currentLine)) {
$attrvalue = $this->getAttrValue($currentLine);
$attrs['newrdn'] = $attrvalue[1];
$currentLine = array_shift($lines);
if (preg_match('/^deleteoldrdn:[ ]*(0|1)/',$currentLine)) {
$attrvalue = $this->getAttrValue($currentLine);
$attrs['deleteoldrdn'] = $attrvalue[1];
# Switch to the possible new superior attribute
if (count($lines)) {
$currentLine = array_shift($lines);
# then the possible new superior attribute
if (preg_match('/^newsuperior:/',$currentLine)) {
$attrvalue = $this->getAttrValue($currentLine);
$attrs['newsuperior'] = $attrvalue[1];
} else
return $this->error(_('A valid newsuperior attribute should be specified'),$lines);
} else
$attrs['newsuperior'] = $server->getContainer($this->template->getDN());
} else
return $this->error(_('A valid deleteoldrdn attribute should be specified'),$lines);
} else
return $this->error(_('A valid newrdn attribute should be specified'),$lines);
}
# Well do something out of the ordinary here, since our template doesnt handle mod[r]dn yet.
$this->template->modrdn = $attrs;
return $this->template;
}
}
?>

View File

@ -0,0 +1,94 @@
0x00 LDAP_SUCCESS "The operation completed successfully."
0x01 LDAP_OPERATIONS_ERROR "An operations error occurred. This is
typically the result of an internal error on your LDAP server."
0x02 LDAP_PROTOCOL_ERROR "A protocol violation was detected."
0x03 LDAP_TIMELIMIT_EXCEEDED "The operation timed out waiting to complete."
0x04 LDAP_SIZELIMIT_EXCEEDED "The LDAP server refused to serve such a large result set."
0x05 LDAP_COMPARE_FALSE "A compare operation returned false."
0x06 LDAP_COMPARE_TRUE "A compare operation returned true."
0x07 LDAP_AUTH_METHOD_NOT_SUPPORTED "The authentication method you specified is not supported by
the LDAP server."
0x08 LDAP_STRONG_AUTH_REQUIRED "This LDAP server requires strong (encrypted) authentication,
not clear text."
0x09 LDAP_PARTIAL_RESULTS "The result set received is a partial result set."
0x0a LDAP_REFERRAL ""
0x0b LDAP_ADMINLIMIT_EXCEEDED ""
0x0c LDAP_UNAVAILABLE_CRITICAL_EXTENSION ""
0x0d LDAP_CONFIDENTIALITY_REQUIRED ""
0x0e LDAP_SASL_BIND_INPROGRESS ""
0x10 LDAP_NO_SUCH_ATTRIBUTE "That entry does not contain the attribute specified."
0x11 LDAP_UNDEFINED_TYPE "The attribute type specified is invalid."
0x12 LDAP_INAPPROPRIATE_MATCHING "This usually means that your LDAP server has not defined an equality rule
for the attribute you are trying to alter. This is not phpLDAPadmin's fault as the
LDAP server has refused to perform the operation (as well it should if there is
no equality rule for it to use for the operation). This generally applies when
adding a new value to a binary attribute, or removing a single value from a
multi-valued binary attribute."
0x13 LDAP_CONSTRAINT_VIOLATION "Some constraint would be violated by performing the action. This can happen when
you try to add a second value to a single-valued attribute, for example."
0x14 LDAP_TYPE_OR_VALUE_EXISTS "An attribute type or attribute value
specified already exists in the entry"
0x15 LDAP_INVALID_SYNTAX "An invalid attribute value was specified."
0x20 LDAP_NO_SUCH_OBJECT "That object does not exist."
0x21 LDAP_ALIAS_PROBLEM "An alias in the directory points to a
non-existent entry."
0x22 LDAP_INVALID_DN_SYNTAX "You used an invalid syntax in the specified DN."
0x23 LDAP_IS_LEAF "The object specified is a leaf"
0x24 LDAP_ALIAS_DEREF_PROBLEM "A problem was encountereed when
dereferencing an alias"
0x30 LDAP_INAPPROPRIATE_AUTH "Inappropriate authentication was
specified (e.g. LDAP_AUTH_SIMPLE was
specified and the entry does not have
a userPassword attribute)."
0x31 LDAP_INVALID_CREDENTIALS "Incorrect login DN and/or password."
0x32 LDAP_INSUFFICIENT_ACCESS "You do not have sufficient permissions
to perform that operation."
0x33 LDAP_BUSY "The LDAP server is busy."
0x34 LDAP_UNAVAILABLE "The LDAP server is unavailable."
0x35 LDAP_UNWILLING_TO_PERFORM "The LDAP server refused to perform the operation."
0x36 LDAP_LOOP_DETECT "A loop was detected."
0x3C LDAP_SORT_CONTROL_MISSING ""
0x3D LDAP_INDEX_RANGE_ERROR ""
0x40 LDAP_NAMING_VIOLATION "A naming violation occurred. This usually
means that you tried to change the value of an attribute that is used in the
DN. For example, if you change the 'cn' value of an entry whose DN is 'cn=Bob
Jones,dc=example,dc=com', you must also rename the entry to reflect the
change."
0x41 LDAP_OBJECT_CLASS_VIOLATION "You tried to perform an operation that would cause an undefined attribute
to exist or that would remove a required attribute, given the current list
of ObjectClasses. This can also occur if you do not
specify a structural objectClass when creating an entry, or if you specify
more than one structural objectClass."
0x42 LDAP_NOT_ALLOWED_ON_NONLEAF "The entry you tried to operate on has children. Usually this means you
tried to delete or rename the entry, which you cannot do to an entry
with children."
0x43 LDAP_NOT_ALLOWED_ON_RDN "You cannot preform that operation on a the relative distinguished name
(RDN) of an object."
0x44 LDAP_ALREADY_EXISTS "The object already exists. Usually you are trying to create a new object
on top of an existing one."
0x45 LDAP_NO_OBJECT_CLASS_MODS "ObjectClass modifications are not allowed."
0x46 LDAP_RESULTS_TOO_LARGE ""
0x47 LDAP_AFFECTS_MULTIPLE_DSAS ""
0x50 LDAP_OTHER ""
0x51 LDAP_SERVER_DOWN "The LDAP server is down."
0x52 LDAP_LOCAL_ERROR ""
0x53 LDAP_ENCODING_ERROR ""
0x54 LDAP_DECODING_ERROR ""
0x55 LDAP_TIMEOUT ""
0x56 LDAP_AUTH_UNKNOWN ""
0x57 LDAP_FILTER_ERROR "The LDAP search filter specified is inavlid."
0x58 LDAP_USER_CANCELLED "The user cancelled the LDAP operation."
0x59 LDAP_PARAM_ERROR "An ldap routine was called with a bad
parameter."
0x5a LDAP_NO_MEMORY "A memory allocation (e.g., malloc(3)
or other dynamic memory allocator)
call failed in an ldap library rou-
tine."
0x5b LDAP_CONNECT_ERROR ""
0x5c LDAP_NOT_SUPPORTED "The requested operation is not supported by the LDAP server."
0x5d LDAP_CONTROL_NOT_FOUND ""
0x5e LDAP_NO_RESULTS_RETURNED "The search came back empty."
0x5f LDAP_MORE_RESULTS_TO_RETURN "The LDAP server has more results that it would like to return."
0x60 LDAP_CLIENT_LOOP ""
0x61 LDAP_REFERRAL_LIMIT_EXCEEDED "This means that a search was performed that required the LDAP
server to follow a chain of referrals that was too lengthy."

View File

@ -0,0 +1,187 @@
# If you find some reliable and more meaningful descriptions to this OIDS,
# then please let the phpldapadmin development know so that this file can be
# more descriptive.
1.2.826.0.1.334810.2.3 "LDAP_CONTROL_VALUESRETURNFILTER"
1.2.826.0.1.3344810.2.3 "Matched Values Control" "RFC 3876" "Describes a control for the LDAP v3 that is used to return a subset of attribute values from an entry. Specifically, only those values that match a 'values return' filter. Without support for this control, a client must retrieve all of an attribute's values and search for specific values locally."
1.2.826.0.1050.11.1.1 "Read-Only LDAP Server"
1.2.826.0.1050.11.2.1 "Read-Write LDAP Server"
1.2.826.0.1050.11.3.1 "White Pages Application LDAP Server"
1.2.826.0.1050.11.4.1 "Certificate Application LDAP Server"
1.2.826.0.1050.11.5.1 "Single Sign On Application LDAP Server"
1.2.840.113549.6.0.0 "Signed Operation"
1.2.840.113549.6.0.1 "Demand Signed Result"
1.2.840.113549.6.0.2 "Signed Result RFC 2649"
1.2.840.113556.1.4.319 "Simple Paged Results Manipulation Control Extension" "RFC 2696" "This control extension allows a client to control the rate at which an LDAP server returns the results of an LDAP search operation. This control may be useful when the LDAP client has limited resources and may not be able to process the entire result set from a given LDAP query, or when the LDAP client is connected over a low-bandwidth connection."
1.2.840.113556.1.4.417 "Show deleted control" "" "The LDAP_SERVER_SHOW_DELETED_OID control is used with an extended LDAP search function to specify that the search results include any deleted objects that match the search filter."
1.2.840.113556.1.4.473 "LDAP Server Sort Result extension" "draft-ietf-ldapext-sorting-01" "This control is included in the searchRequest message as part of the controls field of the LDAPMessage."
1.2.840.113556.1.4.474 "LDAP Server Sort Result extension response control" "" "This control is included in the searchResultDone message as part of the controls field of the LDAPMessage"
1.2.840.113556.1.4.521 "Cross-domain move control" "" "The LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID control is used with an extended LDAP rename function to move an LDAP object from one domain to another. The control specifies the DNS hostname of the domain controller in the destination domain."
1.2.840.113556.1.4.528 "Server search notification control" "" "The LDAP_SERVER_NOTIFICATION_OID control is used with an extended LDAP asynchronous search function to register the client to be notified when changes are made to an object in Active Directory."
1.2.840.113556.1.4.529 "Extended DN control" "" "The LDAP_SERVER_EXTENDED_DN_OID control is used with an extended LDAP search function to request an extended form of an Active Directory object distinguished name. The extended form includes a string representation of the object objectGUID property. For security principal objects such as users, groups, and computers, the extended form also includes a string representation of the object objectSID property."
1.2.840.113556.1.4.616 "LDAP_CONTROL_REFERRALS"
1.2.840.113556.1.4.619 "Lazy commit control" "" "The LDAP_SERVER_LAZY_COMMIT_OID control is used to instruct the server to return the results of a DS modification command, such as add, delete, or replace, after it has been completed in memory, but before it has been committed to disk. The server can then return results quickly, and save the data to disk without holding the client."
1.2.840.113556.1.4.800 "LDAP_CAP_ACTIVE_DIRECTORY_OID" "" "This is an Actrive Directory Server (Win2k and later)."
1.2.840.113556.1.4.801 "Security descriptor flags control" "" "The LDAP_SERVER_SD_FLAGS_OID control is used to pass flags to the server to control various security descriptor results."
1.2.840.113556.1.4.802 "Attribute Range Option" "" "Server supports the Range property enabling clients to incremental retrieve values from multivalue attributes."
1.2.840.113556.1.4.803 "LDAP_MATCHING_RULE_BIT_AND"
1.2.840.113556.1.4.804 "LDAP_MATCHING_RULE_BIT_OR"
1.2.840.113556.1.4.805 "Tree Delete" "" "The LDAP_SERVER_TREE_DELETE_OID control is used with an extended LDAP delete function to delete an entire subtree in the directory."
1.2.840.113556.1.4.841 "Directory synchronization control" "" "The LDAP_SERVER_DIRSYNC_OID control enables an application to search the directory for objects changed from a previous state. It is also used with the extended LDAP search functions such as ldap_search_ext."
1.2.840.113556.1.4.906 "Microsoft Large Integer"
1.2.840.113556.1.4.970 "Get stats control (Stateless)"
1.2.840.113556.1.4.1302 "Microsoft OID used with DEN Attributes"
1.2.840.113556.1.4.1338 "Verify name control" "" "The LDAP_SERVER_VERIFY_NAME_OID control is used with extended LDAP add and modify requests to instruct the DC accepting the update which DC it should verify with, the existence of any DN attribute values."
1.2.840.113556.1.4.1339 "LDAP_SERVER_DOMAIN_SCOPE_OID" "" "The LDAP_SERVER_DOMAIN_SCOPE_OID control is used to instruct the LDAP server not to generate any referrals when completing a request. This control also limits any search using it to a single naming context."
1.2.840.113556.1.4.1340 "Search options control" "" " The LDAP_SERVER_SEARCH_OPTIONS_OID control is used to pass flags to the server to control various search behaviors."
1.2.840.113556.1.4.1413 "LDAP ease modify restrictions" "" "Allows an LDAP modify to work under less restrictive conditions. Without it, a delete will fail if an attribute does not exist, and an add will fail if an attribute already exists."
1.2.840.113556.1.4.1504 "Attribute scoped query control" "" "The LDAP_SERVER_ASQ_OID control is used with an extended LDAP search function to force the query to be based on a specific DN-valued attribute. Only one source attribute can be specified with this control and the search request is limited to base object scoped queries."
1.2.840.113556.1.4.1670 "LDAP_CAP_ACTIVE_DIRECTORY_V51_OID" "" "This server is a Whistler Active Directory server (Win2k3 and later)."
1.2.840.113556.1.4.1781 "Fast concurrent bind extended operation" "" "The Microsoft LDAP API will send an extended request with this name to Active Directory to request that all binds on this connection be processed as 'fast' binds."
1.2.840.113556.1.4.1791 "LDAP_CAP_ACTIVE_DIRECTORY_LDAP_INTEG_OID" "" "LDAP server is capable of doing signing and sealing on an NTLM authenticated connection, and that the server is capable of performing subsequent binds on a signed or sealed connection."
1.2.840.113556.1.4.1852 "LDAP_SERVER_QUOTA_CONTROL_OID" "" "The LDAP_SERVER_QUOTA_CONTROL_OID control is used to pass the SID of a security principal, whose quota is being queried, to the server in a LDAP search operation."
1.3.6.1.1.7.1 "LCUP Sync Request Control. RFC 3928 control"
1.3.6.1.1.7.2 "LCUP Sync Update Control. RFC 3928 control"
1.3.6.1.1.7.3 "LCUP Sync Done Control. RFC 3928 control"
1.3.6.1.1.8 "Cancel Operation. RFC 3909 extension"
1.3.6.1.1.12 "Assertion Control" "RFC 4511" "The assertion control allows the client to specify a condition that must be true for the operation to be processed normally."
1.3.6.1.1.13.1 "Pre-Read Controls" "" "The Pre-Read request control, indicates that a copy of the entry before application of update is to be returned."
1.3.6.1.1.13.2 "Post-Read Controls" "" "The Pre-Read request control, indicates that a copy of the entry before application of update is to be returned."
1.3.6.1.1.14 "Modify-Increment Extension" "RFC 4525" "An extension to the Lightweight Directory Access Protocol (LDAP) Modify operation to support an increment capability."
1.3.6.1.4.1.42.2.27.8.5.1 "passwordPolicyRequest"
1.3.6.1.4.1.42.2.27.9.5.2 "GetEffectiveRights control" "" "May be used to determine what operations a given user may perform on a specified entry."
1.3.6.1.4.1.1466.101.119.1 "Dynamic Directory Services Refresh Request" "RFC 2589"
1.3.6.1.4.1.1466.20036 "LDAP_NOTICE_OF_DISCONNECTION"
1.3.6.1.4.1.1466.20037 "Transport Layer Security Extension" "RFC 2830" "This operation provides for TLS establishment in an LDAP association and is defined in terms of an LDAP extended request."
1.3.6.1.4.1.1466.29539.1 "LDAP_CONTROL_ATTR_SIZELIMIT"
1.3.6.1.4.1.1466.29539.2 "LDAP_CONTROL_NO_COPY"
1.3.6.1.4.1.1466.29539.3 "LDAP_CONTROL_PARTIAL_COPY"
1.3.6.1.4.1.1466.29539.5 "LDAP_CONTROL_NO_CHAINING"
1.3.6.1.4.1.1466.29539.7 "LDAP_CONTROL_ALIAS_ON_UPDATE"
1.3.6.1.4.1.1466.29539.10 "LDAP_CONTROL_TRIGGER"
1.3.6.1.4.1.1466.29539.12 "nsTransmittedControl"
1.3.6.1.4.1.4203.1.5.1 "All Operational Attribute" "RFC 3673" "An LDAP extension which clients may use to request the return of all operational attributes."
1.3.6.1.4.1.4203.1.5.2 "Requesting Attributes by Object Class" "draft-zeilenga-ldap-adlist-10.txt" "Extends LDAP to support a mechanism that LDAP clients may use to request the return of all attributes of an object class."
1.3.6.1.4.1.4203.1.5.3 "LDAP Absolute True and False Filters" "draft-zeilenga-ldap-t-f-10.txt" "Implementations of this extension SHALL allow 'and' and 'or' choices with zero filter elements."
1.3.6.1.4.1.4203.1.5.4 "Language Tags" "RFC 3866" "Supports storing attributes with language tag options in the DIT"
1.3.6.1.4.1.4203.1.5.5 "Language Ranges" "RFC 3866" "Supports language range matching of attributes with language tag options stored in the DIT"
1.3.6.1.4.1.4203.1.9.1.1 "LDAP Content Synchronization Control" "draft=zeilenga-ldup-sync-06.txt" "The operation allows a client to maintain a copy of a fragment of directory information tree. It supports both polling for changes and listening for changes. The operation is defined as an extension of the LDAP Search Operation."
1.3.6.1.4.1.4203.1.10.1 "Subentries in LDAP" "RFC 3672" "The subentries control MAY be sent with a searchRequest to control the visibility of entries and subentries which are within scope. Non-visible entries or subentries are not returned in response to the request."
1.3.6.1.4.1.4203.1.10.2 "LDAP No-Op Control" "draft-zeilenga-ldap-noop-02.txt" "The No-Op control can be used to disable the normal effect of an operation. The control can be used to discover how a server might react to a particular update request without updating the directory."
1.3.6.1.4.1.4203.1.11.1 "LDAP Password Modify Extended Operation" "RFC 3062" "An LDAP extended operation to allow modification of user passwords which is not dependent upon the form of the authentication identity nor the password storage mechanism used."
1.3.6.1.4.1.4203.1.11.2 "LDAP Cancel Extended Operation"
1.3.6.1.4.1.4203.1.11.3 "Who Am I? Extended Operation" "draft-zeilenga-ldap-authzid-10.txt" "This specification provides a mechanism for Lightweight Directory Access Protocol (LDAP) clients to obtain the authorization identity which the server has associated with the user or application entity."
1.3.6.1.4.1.4203.666.5.1 "Subentries Control"
1.3.6.1.4.1.4203.666.5.2 "NO OP Control"
1.3.18.0.2.12.1 "The ACL credential controls provide a method to flow a subject's credentials associated with a bind."
1.3.18.0.2.12.5 "tranExtOpInit"
1.3.18.0.2.12.6 "tranExtOpInit"
2.16.840.1.113531.18.2.1 "LDAP_C_SETOPTIONS_OID"
2.16.840.1.113531.18.2.2 "LDAP_C_SETDONTUSECOPY_OID"
2.16.840.1.113531.18.2.3 "LDAP_C_SETLOCALSCOPE_OID"
2.16.840.1.113531.18.2.4 "Return operational attributes as well as user attributes"
2.16.840.1.113531.18.2.5 "Return only subentries"
2.16.840.1.113531.18.2.6 "LDAP_C_SETUSEALIAS_OID"
2.16.840.1.113531.18.2.7 "LDAP_C_SETPREFERCHAIN_OID"
2.16.840.1.113531.18.2.8 "LDAP_C_SETX500DN_OID"
2.16.840.1.113531.18.2.9 "LDAP_C_SETCOPYSHALLDO_OID"
2.16.840.1.113531.18.2.10 "LDAP_C_SETDONTMAPATTRS_OID"
2.16.840.1.113531.18.2.11 "Return normal entries as well as sub-entries"
2.16.840.1.113719.1.27.99.1 "Superior References"
2.16.840.1.113719.1.27.100.1 "ndsToLdapResponse"
2.16.840.1.113719.1.27.100.2 "ndsToLdapRequest"
2.16.840.1.113719.1.27.100.3 "createNamingContextRequest"
2.16.840.1.113719.1.27.100.4 "createNamingContextResponse"
2.16.840.1.113719.1.27.100.5 "mergeNamingContextRequest"
2.16.840.1.113719.1.27.100.6 "mergeNamingContextResponse"
2.16.840.1.113719.1.27.100.7 "addReplicaRequest"
2.16.840.1.113719.1.27.100.8 "addReplicaResponse"
2.16.840.1.113719.1.27.100.9 "refreshLDAPServerRequest"
2.16.840.1.113719.1.27.100.10 "refreshLDAPServerResponse"
2.16.840.1.113719.1.27.100.11 "removeReplicaRequest"
2.16.840.1.113719.1.27.100.12 "removeReplicaResponse"
2.16.840.1.113719.1.27.100.13 "namingContextEntryCountRequest"
2.16.840.1.113719.1.27.100.14 "namingContextEntryCountResponse"
2.16.840.1.113719.1.27.100.15 "changeReplicaTypeRequest"
2.16.840.1.113719.1.27.100.16 "changeReplicaTypeResponse"
2.16.840.1.113719.1.27.100.17 "getReplicaInfoRequest"
2.16.840.1.113719.1.27.100.18 "getReplicaInfoResponse"
2.16.840.1.113719.1.27.100.19 "listReplicaRequest"
2.16.840.1.113719.1.27.100.20 "listReplicaResponse"
2.16.840.1.113719.1.27.100.21 "receiveAllUpdatesRequest"
2.16.840.1.113719.1.27.100.22 "receiveAllUpdatesResponse"
2.16.840.1.113719.1.27.100.23 "sendAllUpdatesRequest"
2.16.840.1.113719.1.27.100.24 "sendAllUpdatesResponse"
2.16.840.1.113719.1.27.100.25 "requestNamingContextSyncRequest"
2.16.840.1.113719.1.27.100.26 "requestNamingContextSyncResponse"
2.16.840.1.113719.1.27.100.27 "requestSchemaSyncRequest"
2.16.840.1.113719.1.27.100.28 "requestSchemaSyncResponse"
2.16.840.1.113719.1.27.100.29 "abortNamingContextOperationRequest"
2.16.840.1.113719.1.27.100.30 "abortNamingContextOperationResponse"
2.16.840.1.113719.1.27.100.31 "Get Bind DN Request"
2.16.840.1.113719.1.27.100.32 "Get Bind DN Response"
2.16.840.1.113719.1.27.100.33 "Get Effective Privileges Request"
2.16.840.1.113719.1.27.100.34 "Get Effective Privileges Response"
2.16.840.1.113719.1.27.100.35 "Set Replication Filter Request"
2.16.840.1.113719.1.27.100.36 "Set Replication Filter Response"
2.16.840.1.113719.1.27.100.37 "Get Replication Filter Request"
2.16.840.1.113719.1.27.100.38 "Get Replication Filter Response"
2.16.840.1.113719.1.27.100.39 "Create Orphan Partition Request"
2.16.840.1.113719.1.27.100.40 "Create Orphan Partition Response"
2.16.840.1.113719.1.27.100.41 "Remove Orphan Partition Request"
2.16.840.1.113719.1.27.100.42 "Remove Orphan Partition Response"
2.16.840.1.113719.1.27.100.43 "Trigger Backlinker Request"
2.16.840.1.113719.1.27.100.44 "Trigger Backlinker Response"
2.16.840.1.113719.1.27.100.47 "Trigger Janitor Request"
2.16.840.1.113719.1.27.100.48 "Trigger Janitor Response"
2.16.840.1.113719.1.27.100.49 "Trigger Limber Request"
2.16.840.1.113719.1.27.100.50 "Trigger Limber Response"
2.16.840.1.113719.1.27.100.51 "Trigger Skulker Request"
2.16.840.1.113719.1.27.100.52 "Trigger Skulker Response"
2.16.840.1.113719.1.27.100.53 "Trigger Schema Synch Request"
2.16.840.1.113719.1.27.100.54 "Trigger Schema Synch Response"
2.16.840.1.113719.1.27.100.55 "Trigger Partition Purge Request"
2.16.840.1.113719.1.27.100.56 "Trigger Partition Purge Response"
2.16.840.1.113719.1.27.100.79 "Monitor Events Request"
2.16.840.1.113719.1.27.100.80 "Monitor Events Response"
2.16.840.1.113719.1.27.100.81 "Event Notification"
2.16.840.1.113719.1.27.101.1 "Duplicate Entry Request"
2.16.840.1.113719.1.27.101.2 "DuplicateSearchResult"
2.16.840.1.113719.1.27.101.3 "DuplicateEntryResponseDone"
2.16.840.1.113719.1.27.101.5 "Simple Password"
2.16.840.1.113719.1.27.101.6 "Forward Reference"
2.16.840.1.113719.1.142.100.1 "startFramedProtocolRequest"
2.16.840.1.113719.1.142.100.2 "startFramedProtocolResponse"
2.16.840.1.113719.1.142.100.3 "ReplicationUpdate"
2.16.840.1.113719.1.142.100.4 "endFramedProtocolRequest"
2.16.840.1.113719.1.142.100.5 "endFramedProtocolResponse"
2.16.840.1.113719.1.142.100.6 "lburpOperationRequest"
2.16.840.1.113719.1.142.100.7 "lburpOperationResponse"
2.16.840.1.113730.3.4 "Netscape LDAPv3 controls"
2.16.840.1.113730.3.4.2 "ManageDsaIT Control" "RFC 3296" "The client may provide the ManageDsaIT control with an operation to indicate that the operation is intended to manage objects within the DSA (server) Information Tree. The control causes Directory-specific entries (DSEs), regardless of type, to be treated as normal entries allowing clients to interrogate and update these entries using LDAP operations."
2.16.840.1.113730.3.4.3 "Persistent Search LDAPv3 control"
2.16.840.1.113730.3.4.4 "Netscape Password Expired LDAPv3 control"
2.16.840.1.113730.3.4.5 "Netscape Password Expiring LDAPv3 control"
2.16.840.1.113730.3.4.6 "Netscape NT Synchronization Client LDAPv3 control"
2.16.840.1.113730.3.4.7 "Entry Change Notification LDAPv3 control"
2.16.840.1.113730.3.4.8 "Transaction ID Request Control"
2.16.840.1.113730.3.4.9 "VLV Request LDAPv3 control" "" "As defined in the 'LDAPv3 Extensions for Virtual List View' IETF document."
2.16.840.1.113730.3.4.10 "VLV Response LDAPv3 control" "" "As defined in the 'LDAPv3 Extensions for Virtual List View' IETF document."
2.16.840.1.113730.3.4.11 "Transaction ID Response Control"
2.16.840.1.113730.3.4.12 "Proxied Authorization (version 1) control" "draft-weltman-ldapv3-proxy-05" "For assuming the identity of another entry for the duration of a request. This has been replaced by a new 'version 2' Proxied Authorization control."
2.16.840.1.113730.3.4.13 "iPlanet Directory Server Replication Update Information Control"
2.16.840.1.113730.3.4.14 "iPlanet Directory Server 'search on specific backend' control"
2.16.840.1.113730.3.4.15 "Authentication Response Control"
2.16.840.1.113730.3.4.16 "Authentication Request Control"
2.16.840.1.113730.3.4.17 "Real Attributes Only Request Control"
2.16.840.1.113730.3.4.18 "LDAP Proxied Authorization Control" "draft-weltman-ldapv3-proxy-06.txt" "The Proxied Authorization Control allows a client to request that an operation be processed under a provided authorization identity [AUTH] instead of as the current authorization identity associated with the connection."
2.16.840.1.113730.3.4.19 "Virtual Attributes Only Request Control"
2.16.840.1.113730.3.4.20 "Use One Backend"
2.16.840.1.113730.3.4.999 "iPlanet Replication Modrdn Extra Mods Control"
2.16.840.1.113730.3.5.3 "iPlanet Start Replication Request Extended Operation"
2.16.840.1.113730.3.5.4 "iPlanet Replication Response Extended Operation"
2.16.840.1.113730.3.5.5 "iPlanet End Replication Request Extended Operation"
2.16.840.1.113730.3.5.6 "iPlanet Replication Entry Request Extended Operation"
2.16.840.1.113730.3.5.7 "iPlanet Bulk Import Start Extended Operation"
2.16.840.1.113730.3.5.8 "iPlanet Bulk Import Finished Extended Operation"
2.16.840.1.113730.3.5.9 "iPlanet Digest authentication calculation"

519
phpldapadmin/lib/page.php Executable file
View File

@ -0,0 +1,519 @@
<?php
/**
* Page Rendering Functions
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* This class controls the final output to the browser.
*
* @package phpLDAPadmin
* @subpackage Page
*/
class page {
# pre-HTML headers
protected $_pageheader;
# Items to get into the <head>
protected $_head;
# Settings for this application
protected $_app;
# Default values array.
protected $_default;
public function __construct($index=null) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
# If we done have a configuration, then our IMGDIR and CSS are not defined
if (! defined('IMGDIR'))
define('IMGDIR','images/default');
if (! defined('CSSDIR'))
define('CSSDIR','css/default');
$this->index = $index;
# To be defined in a configuration file.
$this->_app['title'] = app_name();
$this->_app['logo'] = IMGDIR.'/logo-small.png';
if (! is_null($index))
$this->_app['urlcss'] = sprintf('%s/%s',CSSDIR,$_SESSION[APPCONFIG]->getValue('appearance','stylesheet'));
else
$this->_app['urlcss'] = sprintf('%s/%s',CSSDIR,'style.css');
# Default Values for configurable items.
$this->_default['sysmsg']['error'] = IMGDIR.'/error-big.png';
$this->_default['sysmsg']['warn'] = IMGDIR.'/warn-big.png';
$this->_default['sysmsg']['info'] = IMGDIR.'/info-big.png';
# Capture any output so far (in case we send some headers below) - there shouldnt be any output anyway.
$preOutput = '';
# Try and work around if php compression is on, or the user has set compression in the config.
# type = 1 for user gzip, 0 for php.ini gzip.
$obStatus = ob_get_status();
if (isset($obStatus['type']) && $obStatus['type'] && $obStatus['status']) {
$preOutput = ob_get_contents();
ob_end_clean();
}
header('Content-type: text/html; charset="UTF-8"');
if (isCompress()) {
header('Content-Encoding: gzip');
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Sent COMPRESSED header to browser and discarded (%s)',129,0,__FILE__,__LINE__,__METHOD__,$preOutput);
}
if (isset($_SESSION[APPCONFIG])
&& $_SESSION[APPCONFIG]->getValue('appearance','compress')
&& ini_get('zlib.output_compression'))
$this->setsysmsg(array('title'=>_('Warning'),'body'=>_('WARNING: You cannot have PHP compression and application compression enabled at the same time. Please unset zlib.output_compression or set $config->custom->appearance[\'compress\']=false'),'type'=>'warn'));
# Turn back on output buffering.
ob_start();
# Initial Values
$this->_pageheader[] = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
$this->_pageheader[] .= '<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="auto">'."\n";
}
/* Add to the HTML Header */
public function head_add($html) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->_head[] .= $html;
}
/* Print out the HTML header */
private function pageheader_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
# HTML prepage requirements.
foreach ($this->_pageheader as $line)
echo $line."\n";
# Page Title
echo '<head>';
printf('<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />');
$DNs = get_request('dn','REQUEST');
if (is_array($DNs))
$DNs = '';
if (isset($_SESSION[APPCONFIG]))
printf('<title>%s (%s) - %s%s</title>',
$this->_app['title'],
app_version(),
$DNs ? htmlspecialchars($DNs).' ' : '',
$_SESSION[APPCONFIG]->getValue('appearance','page_title'));
else
printf('<title>%s - %s</title>',$this->_app['title'],app_version());
echo '<link rel="shortcut icon" href="images/favicon.ico" type="image/vnd.microsoft.icon" />';
# Style sheet.
printf('<link type="text/css" rel="stylesheet" href="%s" />',$this->_app['urlcss']);
if (defined('JSDIR')) {
printf('<link type="text/css" rel="stylesheet" media="all" href="%sjscalendar/calendar-blue.css" title="blue" />',JSDIR);
echo "\n";
printf('<script type="text/javascript" src="%sajax_functions.js"></script>',JSDIR);
printf('<script type="text/javascript" src="%sjscalendar/calendar.js"></script>',JSDIR);
echo "\n";
}
# HTML head requirements.
if (is_array($this->_head) && count($this->_head))
foreach ($this->_head as $line)
echo $line."\n";
echo '</head>';
echo "\n";
}
private function head_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (isset($_SESSION[APPCONFIG]))
$pagetitle = $_SESSION[APPCONFIG]->getValue('appearance','page_title') ? ' - '.$_SESSION[APPCONFIG]->getValue('appearance','page_title') : '';
else
$pagetitle = '';
echo '<tr class="pagehead">';
echo '<td colspan="3"><div id="ajHEAD"><table width="100%" border="0"><tr>';
printf('<td style="text-align: left;"><a href="%s" onclick="target=\'_blank\';"><img src="%s" alt="Logo" class="logo" /></a></td>',get_href('sf'),$this->_app['logo']);
echo '<td class="imagetop">';
$empty = true;
if (function_exists('cmd_control_pane'))
foreach (cmd_control_pane('top') as $cmddetails)
if ((isset($cmddetails['enable']) && $cmddetails['enable']) || ! isset($cmddetails['enable'])) {
if (! $empty)
echo ' ';
printf('<a %s>%s</a>',$cmddetails['link'],$cmddetails['image']);
$empty = false;
}
if ($empty)
echo '&nbsp;';
echo '</td>';
echo '</tr></table></div></td>';
echo '</tr>';
echo "\n";
}
private function control_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
echo '<table class="control" width="100%" border="0">';
echo '<tr><td>';
$empty = true;
if (function_exists('cmd_control_pane'))
foreach (cmd_control_pane('main') as $cmddetails)
if ((isset($cmddetails['enable']) && trim($cmddetails['enable'])) || ! isset($cmddetails['enable'])) {
if (! $empty)
echo ' | ';
printf('<a %s>%s</a>',$cmddetails['link'],
(isset($_SESSION[APPCONFIG]) && $_SESSION[APPCONFIG]->getValue('appearance','control_icons')) ? $cmddetails['image'] : $cmddetails['title']);
$empty = false;
}
echo '</td>';
if ($empty)
echo '<td>&nbsp;</td>';
echo '</tr>';
echo '</table>';
}
protected function tree() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! isset($_SESSION[APPCONFIG]))
return;
if (is_null($this->index))
$this->index = min(array_keys($_SESSION[APPCONFIG]->getServerList()));
if (count($_SESSION[APPCONFIG]->getServerList()) > 1) {
echo '<form id="server_select" action="cmd.php" method="post">';
echo '<table class="server_select"><tr><td>';
printf('%s:<br />%s',_('Server Select'),
server_select_list($this->index,false,'index',true,sprintf("onchange=\"tree_unhide('index',%s)\"",$this->index)));
echo '</td></tr></table>';
echo '</form>';
echo "\n\n";
}
foreach ($_SESSION[APPCONFIG]->getServerList() as $index => $server) {
printf('<div id="ajSID_%s" style="display: %s">',$server->getIndex(),($server->getIndex() == $this->index) ? 'block' : 'none');
$tree = Tree::getInstance($server->getIndex());
$tree->draw();
echo '</div>';
echo "\n\n";
}
}
public function block_add($side,$object) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! is_object($object))
error(sprintf('block_add called with [%s], but it is not an object',serialize($object)));
$this->_block[$side][] = $object;
}
private function block_print($side) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! isset($this->_block[$side]))
return;
printf('<td class="%s" colspan="2">',$side);
foreach ($this->_block[$side] as $object)
echo $object->draw($side);
echo '</td>';
}
private function sysmsg() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (isset($this->sysmsg)) {
foreach ($this->sysmsg as $index => $details) {
switch ($details['type']) {
case 'error':
$icon = $this->_default['sysmsg']['error'];
break;
case 'warn':
$icon = $this->_default['sysmsg']['warn'];
break;
case 'info':
default:
$icon = $this->_default['sysmsg']['info'];
break;
}
if (isset($details['title']))
printf('<tr><td class="icon" rowspan="2"><img src="%s" alt="%s" /></td><td class="head">%s</td></tr>',
$icon,$details['type'],$details['title']);
if (isset($details['body']))
if (is_array($details['body'])) {
echo '<tr><td class="body">';
foreach ($details['body'] as $line)
printf('%s<br />',$line);
echo '</td></tr>';
} else
printf('<tr><td class="body">%s</td></tr>',$details['body']);
}
}
}
private function body($raw=false) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
# Add the Session System Messages
if (isset($_SESSION['sysmsg']) && is_array($_SESSION['sysmsg'])) {
foreach ($_SESSION['sysmsg'] as $msg)
$this->setsysmsg($msg);
unset($_SESSION['sysmsg']);
}
if (isset($this->sysmsg)) {
echo '<table class="sysmsg">';
$this->sysmsg();
echo '</table>';
echo "\n";
}
if (isset($this->_block['body']))
foreach ($this->_block['body'] as $object)
echo $object->draw('body',$raw);
}
private function footer_print() {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
printf('<tr class="foot"><td><small>%s</small></td><td colspan="2"><div id="ajFOOT">%s</div>%s</td></tr>',
isCompress() ? '[C]' : '&nbsp;',
app_version(),
get_href('logo') ? sprintf('<a href="%s"><img src="%s" alt="SourceForge.net Logo" style="border: 0px;" /></a>',get_href('sf'),get_href('logo')) : '&nbsp;');
}
/**
* Only show a particular page frame - used by an AJAX call
*/
public function show($frame,$compress=false,$raw=false) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
# If the body is called via AJAX, and compression is enable, we need to compress the output
if ($compress && ob_get_level() && isCompress()) {
ob_end_clean();
ob_start();
}
switch ($frame) {
case 'BODY':
$this->body($raw);
break;
case 'TREE':
$this->tree();
break;
default:
error(sprintf('show called with unknown frame [%s]',$frame),'error','index.php');
}
if ($compress && ob_get_level() && isCompress()) {
$output = ob_get_contents();
ob_end_clean();
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Sending COMPRESSED output to browser[(%s),%s]',129,0,__FILE__,__LINE__,__METHOD__,
strlen($output),$output);
print gzencode($output);
}
}
public function display($filter=array()) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
# Control what is displayed.
$display = array(
'HEAD'=>true,
'CONTROL'=>true,
'TREE'=>true,
'FOOT'=>true
);
if ($_SESSION[APPCONFIG]->getValue('appearance','minimalMode')) {
$display = array(
'HEAD'=>false,
'CONTROL'=>false,
'TREE'=>true,
'FOOT'=>false
);
}
$display = array_merge($display,$filter);
# HTML Header
$this->pageheader_print();
# Start of body
# Page Header
echo '<body>';
echo "\n";
echo '<table class="page" border="0" width="100%">';
if ($display['HEAD'])
$this->head_print();
# Control Line
if ($display['CONTROL']) {
echo '<tr class="control"><td colspan="3">';
echo '<div id="ajCONTROL">';
$this->control_print();
echo '</div></td></tr>';
echo "\n";
}
# Left Block
echo '<tr>';
if ($display['TREE']) {
echo '<td class="tree" colspan="2">';
printf('<acronym title="%s"><img src="%s/plus.png" alt="" style="float: right;" onclick="if (document.getElementById(\'ajTREE\').style.display == \'none\') { document.getElementById(\'ajTREE\').style.display = \'block\' } else { document.getElementById(\'ajTREE\').style.display = \'none\' };"/></acronym>',_('Hide/Unhide the tree'),IMGDIR);
echo '<div id="ajTREE">';
$this->tree();
echo '</div>';
echo '</td>';
}
echo '<td class="body" style="width: 80%;">';
echo '<div id="ajBODY">';
echo "\n";
$this->body();
echo '</div>';
echo '</td>';
echo '</tr>';
echo "\n";
# Page Footer
if ($display['FOOT'])
$this->footer_print();
# Finish HTML
echo '</table>';
echo '</body>';
echo '</html>';
# compress output
if (ob_get_level() && isCompress()) {
$output = ob_get_contents();
ob_end_clean();
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED)
debug_log('Sending COMPRESSED output to browser[(%s),%s]',129,0,__FILE__,__LINE__,__METHOD__,
strlen($output),$output);
print gzencode($output);
}
}
public function setsysmsg($data) {
if (defined('DEBUG_ENABLED') && DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! is_array($data))
return;
if (isset($this->sysmsg))
$msgnum = count($this->sysmsg) + 1;
else
$msgnum = 1;
foreach (array('title','body','type') as $index)
if (isset($data[$index]))
$this->sysmsg[$msgnum][$index] = $data[$index];
}
}
/**
* This class draws a block.
*
* @package phpLDAPadmin
* @subpackage Page
*/
class block {
private $title;
private $body;
private $foot;
public function setTitle($html) {
$this->title = $html;
}
public function setBody($html) {
$this->body = $html;
}
public function setFooter($html) {
$this->foot = $html;
}
public function draw($side,$raw=false) {
$output = '';
if ($raw)
$output .= $this->body;
else {
$output .= sprintf('<table class="%s">',$side);
if (isset($this->title))
$output .= sprintf('<tr><td class="head">%s</td></tr>',$this->title);
if (isset($this->body))
$output .= sprintf('<tr><td>%s</td></tr>',$this->body);
if (isset($this->footer))
$output .= sprintf('<tr><td class="foot">%s</td></tr>',$this->foot);
$output .= '</table>';
}
return $output;
}
}
?>

View File

@ -0,0 +1,22 @@
<?php
/**
* Classes and functions for searching the LDAP server
*
* These classes and functions will read our XML search files, for defined
* search reports.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Query Class
*
* This class will store all our pre-defined search definitions.
*
* @package phpLDAPadmin
* @subpackage Queries
*/
class Queries extends xmlTemplates {
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,176 @@
<?php
/**
* A collection of functions to handle sessions.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
* @subpackage Session
*/
/** The session ID that this application will use for all sessions */
define('APP_SESSION_ID',md5(app_name()));
/** Enables session paranoia, which causes SIDs to change each page load (EXPERIMENTAL!) */
define('app_session_id_paranoid', false);
/** Flag to indicate whether the session has already been initialized (this constant gets stored in $_SESSION) */
define('app_session_id_init', 'app_initialized');
/** The minimum first char value IP in hex for IP hashing. */
define('app_session_id_ip_min', 8);
/** The maximum first char value of the IP in hex for IP hashing. */
define('app_session_id_ses_max', 36);
/**
* Creates a new session id, which includes an IP hash.
*
* @return string the new session ID string
*/
function app_session_get_id() {
$id_md5 = md5(rand(1,1000000));
$ip_md5 = md5($_SERVER['REMOTE_ADDR']);
$id_hex = hexdec($id_md5[0]) + 1;
$ip_hex = hexdec($ip_md5[0]);
if ($ip_hex <= app_session_id_ip_min)
$ip_len = app_session_id_ip_min;
else
$ip_len = $ip_hex - 1;
$new_id = substr($id_md5, 0, $id_hex) .
substr($ip_md5, $ip_hex, $ip_len) .
substr($id_md5, $id_hex, app_session_id_ses_max - ($id_hex + $ip_len));
return $new_id;
}
/**
* Checks if the session belongs to an IP
*
* @return boolean True, if the session is valid
*/
function app_session_verify_id() {
$check_id = session_id();
$ip_md5 = md5($_SERVER['REMOTE_ADDR']);
$id_hex = hexdec($check_id[0]) + 1;
$ip_hex = hexdec($ip_md5[0]);
if ($ip_hex <= app_session_id_ip_min)
$ip_len = app_session_id_ip_min;
else
$ip_len = $ip_hex - 1;
$ip_ses = substr($check_id, $id_hex, $ip_len);
$ip_ver = substr($ip_md5, $ip_hex, $ip_len);
return ($ip_ses == $ip_ver);
}
function app_session_param() {
/* If cookies were disabled, build the url parameter for the session id.
* It will be append to the url to be redirect */
return (SID != '') ? sprintf('&%s=%s',session_name(),session_id()) : '';
}
/**
* The only function which should be called by a user
*
* @see common.php
* @see APP_SESSION_ID
* @return boolean Returns true if the session was started the first time
*/
function app_session_start() {
$sysmsg = null;
# If we have a sysmsg before our session has started, then preserve it.
if (isset($_SESSION['sysmsg']))
$sysmsg = $_SESSION['sysmsg'];
/* If session.auto_start is on in the server's PHP configuration (php.ini), then
* we will have problems loading our schema cache since the session will have started
* prior to loading the SchemaItem (and descedants) class. Destroy the auto-started
* session to prevent this problem.
*/
if (ini_get('session.auto_start') && ! array_key_exists(app_session_id_init,$_SESSION))
@session_destroy();
# Do we already have a session?
if (@session_id())
return;
@session_name(APP_SESSION_ID);
@session_start();
# Do we have a valid session?
$is_initialized = is_array($_SESSION) && array_key_exists(app_session_id_init,$_SESSION);
if (! $is_initialized) {
if (app_session_id_paranoid) {
ini_set('session.use_trans_sid',0);
@session_destroy();
@session_id(app_session_get_id());
@session_start();
ini_set('session.use_trans_sid',1);
}
$_SESSION[app_session_id_init]['name'] = app_name();
$_SESSION[app_session_id_init]['version'] = app_version();
$_SESSION[app_session_id_init]['config'] = filemtime(CONFDIR.'config.php');
}
@header('Cache-control: private'); // IE 6 Fix
if (app_session_id_paranoid && ! app_session_verify_id())
error('Session inconsistent or session timeout','error','index.php');
# Check we have the correct version of the SESSION cache
if (isset($_SESSION['cache']) || isset($_SESSION[app_session_id_init])) {
if (! is_array($_SESSION[app_session_id_init])) $_SESSION[app_session_id_init] = array();
if (! isset($_SESSION[app_session_id_init]['version']) || ! isset($_SESSION[app_session_id_init]['config']) || ! isset($_SESSION[app_session_id_init]['name'])
|| $_SESSION[app_session_id_init]['name'] !== app_name()
|| $_SESSION[app_session_id_init]['version'] !== app_version()
|| $_SESSION[app_session_id_init]['config'] != filemtime(CONFDIR.'config.php')) {
$_SESSION[app_session_id_init]['name'] = app_name();
$_SESSION[app_session_id_init]['version'] = app_version();
$_SESSION[app_session_id_init]['config'] = filemtime(CONFDIR.'config.php');
unset($_SESSION['cache']);
unset($_SESSION[APPCONFIG]);
# Our configuration information has changed, so we'll redirect to index.php to get it reloaded again.
system_message(array(
'title'=>_('Configuration cache stale.'),
'body'=>_('Your configuration has been automatically refreshed.'),
'type'=>'info','special'=>true));
$config_file = CONFDIR.'config.php';
$config = check_config($config_file);
if (! $config)
debug_dump_backtrace('config is empty?',1);
} else {
# Sanity check, specially when upgrading from a previous release.
if (isset($_SESSION['cache']))
foreach (array_keys($_SESSION['cache']) as $id)
if (isset($_SESSION['cache'][$id]['tree']['null']) && ! is_object($_SESSION['cache'][$id]['tree']['null']))
unset($_SESSION['cache'][$id]);
}
}
# If we came via index.php, then set our $config.
if (! isset($_SESSION[APPCONFIG]) && isset($config))
$_SESSION[APPCONFIG] = $config;
# Restore our sysmsg's if there were any.
if ($sysmsg) {
if (! isset($_SESSION['sysmsg']) || ! is_array($_SESSION['sysmsg']))
$_SESSION['sysmsg'] = array();
$_SESSION['sysmsg'] = array_merge($_SESSION['sysmsg'],$sysmsg);
}
}
/**
* Stops the current session.
*/
function app_session_close() {
@session_write_close();
}
?>

88
phpldapadmin/lib/syslog.php Executable file
View File

@ -0,0 +1,88 @@
<?php
/**
* Functions related to syslog logging.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* @author Benjamin Drieu <benjamin.drieu@fr.alcove.com> and Alcôve
* @package phpLDAPadmin
*/
# If config_default.php hasnt been called yet, then return.
if (! defined('APPCONFIG') || ! isset($_SESSION[APPCONFIG]))
return;
# Initialize syslog
if ($_SESSION[APPCONFIG]->getValue('debug','syslog') && function_exists('syslog')) {
openlog('phpldapadmin',LOG_ODELAY,LOG_DAEMON);
}
/**
* Verify that syslog logging is activated in the config via the
* debug->syslog variable and does a call to the syslog() function is it
* is true.
*
* @param emergency Syslog emergency.
* @param log_string String to log.
*/
function syslog_msg($emergency,$log_string) {
if (! function_exists('syslog') || ! isset($_SESSION[APPCONFIG]) || ! $_SESSION[APPCONFIG]->getValue('debug','syslog'))
return;
return syslog($emergency,$log_string);
}
/**
* Issue an error message via syslog.
*
* @param log_string Log message to send to syslog.
* @return true on success.
*/
function syslog_err($log_string) {
return syslog_msg(LOG_ERR,$log_string);
}
/**
* Issue a warning message via syslog.
*
* @param log_string Log message to send to syslog.
* @return true on success.
*/
function syslog_warning($log_string) {
return syslog_msg(LOG_WARNING,$log_string);
}
/**
* Issue a notice message via syslog.
*
* @param log_string Log message to send to syslog.
* @return true on success.
*/
function syslog_notice($log_string) {
return syslog_msg(LOG_NOTICE,$log_string);
}
/**
* Issue a debug message via syslog, only if $log_level is set to
* 'debug' from the config file.
*
* @param log_string Log message to send to syslog.
* @return true on success or if debug log is not activated.
*/
function syslog_debug($log_string) {
return syslog_msg(LOG_DEBUG,$log_string);
}
?>

View File

@ -0,0 +1,23 @@
<?php
/**
* Classes and functions for the template engine.
*
* These classes and functions will read our XML template files, as well as
* query the LDAP server and build a template object that can be used for user
* input.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* Templates Class
*
* This class will store all our templates.
*
* @package phpLDAPadmin
* @subpackage Templates
*/
class Templates extends xmlTemplates {
}
?>

144
phpldapadmin/lib/xml2array.php Executable file
View File

@ -0,0 +1,144 @@
<?php
/**
* Classes and functions for manipulating XML templates.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* XML Parser
*
* This will read our XML file and convert it into variables for us to parse.
*
* @package phpLDAPadmin
* @subpackage XML
*/
class xml2array {
var $stack = array();
var $stack_ref;
var $arrOutput = array();
var $resParser;
var $strXmlData;
private function push_pos(&$pos) {
$this->stack[count($this->stack)] = &$pos;
$this->stack_ref = &$pos;
}
private function pop_pos() {
unset($this->stack[count($this->stack) - 1]);
$this->stack_ref = &$this->stack[count($this->stack) - 1];
}
public function parseXML($strInputXML,$filename) {
$this->resParser = xml_parser_create();
xml_set_object($this->resParser,$this);
xml_set_element_handler($this->resParser,'tagOpen','tagClosed');
xml_set_character_data_handler($this->resParser,'tagData');
$this->push_pos($this->arrOutput);
$this->strXmlData = xml_parse($this->resParser,$strInputXML);
if (! $this->strXmlData)
die(sprintf('XML error: %s at line %d in file %s',
xml_error_string(xml_get_error_code($this->resParser)),
xml_get_current_line_number($this->resParser),
$filename));
xml_parser_free($this->resParser);
$output = array();
foreach ($this->arrOutput as $key => $values)
$output[$key] = $this->cleanXML($values);
#return $this->arrOutput;
return $output;
}
private function tagOpen($parser,$name,$attrs) {
$name = strtolower($name);
if (isset($this->stack_ref[$name])) {
if (! isset($this->stack_ref[$name][0])) {
$tmp = $this->stack_ref[$name];
unset($this->stack_ref[$name]);
$this->stack_ref[$name][0] = $tmp;
}
$cnt = count($this->stack_ref[$name]);
$this->stack_ref[$name][$cnt] = array();
if (isset($attrs))
$this->stack_ref[$name][$cnt] = $attrs;
$this->push_pos($this->stack_ref[$name][$cnt]);
} else {
$this->stack_ref[$name]=array();
if (isset($attrs))
$this->stack_ref[$name]=$attrs;
$this->push_pos($this->stack_ref[$name]);
}
}
private function tagData($parser,$tagData) {
if (trim($tagData) != '') {
if (isset($this->stack_ref['#text']))
$this->stack_ref['#text'] .= $tagData;
else
$this->stack_ref['#text'] = $tagData;
}
}
private function tagClosed($parser,$name) {
$this->pop_pos();
}
/**
* This function will parse an XML array and make a normal array.
*
* @return array - Clean XML data
*/
private function cleanXML($details) {
# Quick processing for the final branch of the XML array.
if (is_array($details) && isset($details['#text']))
return $details['#text'];
elseif (is_array($details) && isset($details['ID']) && count($details) == 1)
return $details['ID'];
$cleanXML = array();
# Quick processing for the final branch, when it holds the ID and values.
if (is_array($details) && isset($details['ID']) && count($details) > 1) {
$key = $details['ID'];
unset($details['ID']);
$cleanXML[$key] = $this->cleanXML($details);
$details = array();
}
# More detailed processing...
if (is_array($details))
foreach ($details as $key => $values)
if (is_numeric($key) && isset($values['ID']) && count($values) > 1) {
$key = $values['ID'];
unset($values['ID']);
$cleanXML[$key] = $this->cleanXML($values);
} elseif (isset($values['#text']))
$cleanXML[$key] = $this->cleanXML($values);
elseif (is_array($values))
$cleanXML[$key] = $this->cleanXML($values);
if (! $cleanXML)
return $details;
else
return $cleanXML;
}
}

496
phpldapadmin/lib/xmlTemplates.php Executable file
View File

@ -0,0 +1,496 @@
<?php
/**
* Classes and functions for XML based templates.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* XML Templates Class
*
* @package phpLDAPadmin
* @subpackage Templates
*/
abstract class xmlTemplates {
# The server ID that these templates are configured for.
protected $server_id;
# Our array of the available templates.
protected $templates = array();
function __construct($server_id) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->server_id = $server_id;
$server = $_SESSION[APPCONFIG]->getServer($this->server_id);
$custom_prefix = $server->getValue('custom','pages_prefix');
$class = $this->getClassVars();
$changed = false;
# Try to get the templates from our CACHE.
if ($this->templates = get_cached_item($server_id,$class['item'])) {
if (DEBUG_ENABLED)
debug_log('Using CACHED templates',4,0,__FILE__,__LINE__,__METHOD__);
# See if the template_time has expired to see if we should reload the templates.
foreach ($this->templates as $index => $template) {
# If the file no longer exists, we'll delete the template.
if (! file_exists($template->getFileName())) {
unset($this->templates[$index]);
$changed = true;
system_message(array(
'title'=>_('Template XML file removed.'),
'body'=>sprintf('%s %s (%s)',_('Template XML file has removed'),$template->getName(false),$template->getType()),
'type'=>'info','special'=>true));
continue;
}
if (($template->getReadTime() < (time()-$class['cachetime']))
&& (filectime($template->getFileName()) > $template->getReadTime())) {
system_message(array(
'title'=>_('Template XML file changed.'),
'body'=>sprintf('%s %s (%s)',_('Template XML file has changed and been reread'),$template->getName(false),$template->getType()),
'type'=>'info','special'=>true));
$changed = true;
$this->templates[$index] = new $class['name']($this->server_id,$template->getName(false),$template->getFileName(),$template->getType(),$index);
}
}
if (DEBUG_ENABLED)
debug_log('Templates refreshed',4,0,__FILE__,__LINE__,__METHOD__);
# See if there are any new template files
$index = max(array_keys($this->templates))+1;
foreach ($class['types'] as $type) {
$dir = $class['dir'].$type;
$dh = opendir($dir);
if (! $type)
$type = 'template';
while ($file = readdir($dh)) {
# Ignore any files that are not XML files.
if (! preg_match('/.xml$/',$file))
continue;
# Ignore any files that are not the predefined custom files.
if ($_SESSION[APPCONFIG]->getValue('appearance','custom_templates_only')
&& ! preg_match("/^${custom_prefix}/",$file))
continue;
$filename = sprintf('%s/%s',$dir,$file);
if (! in_array($filename,$this->getTemplateFiles())) {
$templatename = preg_replace('/.xml$/','',$file);
$this->templates[$index] = new $class['name']($this->server_id,$templatename,$filename,$type,$index);
$index++;
$changed = true;
system_message(array(
'title'=>_('New Template XML found.'),
'body'=>sprintf('%s %s (%s)',_('A new template XML file has been loaded'),$file,$type),
'type'=>'info','special'=>true));
}
}
}
} else {
if (DEBUG_ENABLED)
debug_log('Parsing templates',4,0,__FILE__,__LINE__,__METHOD__);
# Need to reset this, as get_cached_item() returns null if nothing cached.
$this->templates = array();
$changed = true;
$counter = 0;
foreach ($class['types'] as $type) {
$dir = $class['dir'].$type;
$dh = opendir($class['dir'].$type);
if (! $type)
$type = 'template';
while ($file = readdir($dh)) {
# Ignore any files that are not XML files.
if (! preg_match('/.xml$/',$file))
continue;
# Ignore any files that are not the predefined custom files.
if ($_SESSION[APPCONFIG]->getValue('appearance','custom_templates_only')
&& ! preg_match("/^${custom_prefix}/",$file))
continue;
$filename = sprintf('%s/%s',$dir,$file);
# Store the template
$templatename = preg_replace('/.xml$/','',$file);
$this->templates[$counter] = new $class['name']($this->server_id,$templatename,$filename,$type,$counter);
$counter++;
}
}
}
if (DEBUG_ENABLED)
debug_log('Templates loaded',4,0,__FILE__,__LINE__,__METHOD__);
if ($changed) {
masort($this->templates,'title');
set_cached_item($server_id,$class['item'],'null',$this->templates);
}
}
/**
* This will return our custom class variables, used by the parent to create objects.
*/
private function getClassVars() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$class = array();
switch (get_class($this)) {
case 'Queries':
$class['item'] = 'query';
$class['name'] = 'Query';
$class['cachetime'] = $_SESSION[APPCONFIG]->getValue('cache','query_time');
$class['types'] = array('');
$class['dir'] = QUERYDIR;
break;
case 'Templates':
$class['item'] = 'template';
$class['name'] = 'Template';
$class['cachetime'] = $_SESSION[APPCONFIG]->getValue('cache','template_time');
$class['types'] = array('creation','modification');
$class['dir'] = TMPLDIR;
break;
default:
debug_dump_backtrace(sprintf('Unknown class %s',get_class($this)),1);
}
return $class;
}
/**
* Return a list of templates by their type
* This function should return a sorted list, as the array is built sorted.
*
* @param string Type of template, eg: creation, modification
* @param boolean Exclude templates purposely disabled.
* @return array List of templates of the type
*/
public function getTemplates($type=null,$container=null,$disabled=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = array();
if (is_array($this->templates))
foreach ($this->templates as $details) {
# Clone this, as we'll disable some templates, as a result of the container being requested.
$template = clone $details;
if (! is_null($container) && ($regexp = $template->getRegExp()) && (! @preg_match('/'.$regexp.'/i',$container))) {
$template->setInvalid(_('This template is not valid in this container'),true);
if ($_SESSION[APPCONFIG]->getValue('appearance','hide_template_regexp'))
$template->setInvisible();
}
if ($template->isVisible() && (! $disabled || ! $template->isAdminDisabled()))
if (is_null($type) || (! is_null($type) && $template->isType($type)))
array_push($result,$template);
}
return $result;
}
/**
* Return a template by its ID
*
* @param string The template ID as it was when it was generated (normally used in $_REQUEST vars).
* @return object Template (or default template if the ID doesnt exist)
*/
function getTemplate($templateid) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$class = $this->getClassVars();
foreach ($this->templates as $template)
if ($template->getID() === $templateid)
return clone $template;
# If we get here, the template ID didnt exist, so return a blank template, which be interpreted as the default template
$object = new $class['name']($this->server_id,null,null,'default');
return $object;
}
/**
* Get a list of template filenames.
*/
private function getTemplateFiles() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = array();
foreach ($this->templates as $template)
array_push($result,$template->getFileName());
return $result;
}
}
/**
* XML Template Class
*
* @package phpLDAPadmin
* @subpackage Templates
*/
abstract class xmlTemplate {
# Server ID that the template is linked to
protected $server_id;
# Template unique ID
protected $id;
# Template name - as extracted from the filename
protected $name;
# Template type - creation/modification
protected $type;
# Time this object was created
protected $readtime;
# Template file name
protected $filename;
# The TEMPLATE attributes as per the template definition, or the DN entry
protected $attributes = array();
public function __construct($server_id,$name=null,$filename=null,$type=null,$id=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$this->server_id = $server_id;
$this->name = $name;
$this->type = $type;
$this->filename = $filename;
$this->readtime = time();
$this->id = $id;
# If there is no filename, then this template is a default template.
if (is_null($filename))
return;
# If we have a filename, parse the template file and build the object.
$objXML = new xml2array();
$xmldata = $objXML->parseXML(file_get_contents($filename),$filename);
$this->storeTemplate($xmldata);
}
/**
* Get an attribute ID
*
* @param string The Attribute being searched.
* @return int Attribute ID in the array
*/
protected function getAttrID($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
foreach ($this->attributes as $index => $attribute)
if (strtolower($attr) == $attribute->getName() || in_array(strtolower($attr),$attribute->getAliases()))
return $index;
return null;
}
/**
* Get the Template filename.
*/
public function getFileName() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->filename);
return $this->filename;
}
/**
* Return the template by ID
*/
public function getID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs,$this->id);
if ($this->name)
return sprintf('%s:%s',$this->getName(false),$this->id);
else
return 'none';
}
/**
* Return the template name
*
* @param boolean Force the name to be lowercase (default)
*/
public function getName($lower=true) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->name);
if ($lower)
return strtolower($this->name);
else
return $this->name;
}
/**
* Get the Template read time.
*/
public function getReadTime() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->readtime);
return $this->readtime;
}
/**
* Return this LDAP Server object
*
* @return object DataStore Server
*/
protected function getServer() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs);
return $_SESSION[APPCONFIG]->getServer($this->getServerID());
}
/**
* Return the LDAP server ID
*
* @return int Server ID
*/
protected function getServerID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->server_id);
return $this->server_id;
}
/**
* Test if a template is of a type
*
* @return boolean
*/
public function isType($type) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs,$this->type);
if ($this->type == $type)
return true;
else
return false;
}
/**
* Return the template type
*/
public function getType() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,1,__FILE__,__LINE__,__METHOD__,$fargs,$this->type);
return $this->type;
}
/**
* Get template title
*/
public function getTitle() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! isset($this->title) && ! isset($this->description))
return '';
return isset($this->title) ? $this->title : $this->description;
}
/**
* Add another attribute to this template
*
* @return int Attribute ID
*/
public function addAttribute($name,$value,$source=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! is_array($value))
debug_dump_backtrace('Value should be an array()',1);
$server = $this->getServer();
# Initialise the Attribute Factory.
$attribute_factory = new AttributeFactory();
if (preg_match('/;/',$name))
system_message(array(
'title'=>'phpLDAPadmin doesnt support RFC3866.',
'body'=>sprintf('%s {%s} (%s)','PLA might not do what you expect...',$name,(is_array($value) ? serialize($value) : $value)),
'type'=>'warn'));
# If there isnt a schema item for this attribute
$attribute = $attribute_factory->newAttribute($name,$value,$server->getIndex(),$source);
$attrid = $this->getAttrID($attribute->getName());
if (is_null($attrid))
array_push($this->attributes,$attribute);
return $attribute;
}
/**
* Get the attribute names
*
* @return array Array of attributes Names
*/
public function getAttributeNames() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
$result = array();
foreach ($this->attributes as $attribute)
array_push($result,$attribute->getName());
return $result;
}
/**
* Get a specific Attribute
*
* @param string Name of attribute to retrieve
* @return object Attribute
*/
public function getAttribute($name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
foreach ($this->attributes as $attribute)
if (($attribute->getName() == strtolower($name)) || in_array(strtolower($name),$attribute->getAliases()))
return $attribute;
return null;
}
/**
* May be overloaded in other classes
*/
public function isAdminDisabled() {}
}
?>