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)) { $call .= '('; for ($i = 0; $i < count($args); $i++) { if ($i == 0) { $call .= sprintf('$args[%s]', $i); } else { $call .= sprintf(',$args[%s]', $i); } } $call .= ');'; if (defined('DEBUGTMP') && DEBUGTMP) { printf('<font size=-2><b>Invoking Method: $this->%s</b></font><br />', $call); } eval('$r = $this->' . $call); 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)); }
protected function getNoteRequiredAttribute($attribute) { 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__); } $required_by = ''; $sattr_required = ''; # Is this attribute required by an objectClass ? $sattr = $this->getServer()->getSchemaAttribute($attribute->getName()); if ($sattr) { $sattr_required = $sattr->getRequiredByObjectClasses(); } if ($sattr_required) { $oc = $this->template->getAttribute('objectclass'); if ($oc) { foreach ($oc->getValues() as $objectclass) { # If this objectclass is in our required list if (in_array_ignore_case($objectclass, $sattr_required)) { $required_by .= sprintf('%s ', $objectclass); continue; } # If not, see if it is in our parent. $sattr = $this->getServer()->getSchemaObjectClass($objectclass); if (array_intersect($sattr->getParents(), $sattr_required)) { $required_by .= sprintf('%s ', $objectclass); } } } else { debug_dump_backtrace('How can there be no objectclasses?', 1); } } if ($required_by) { return sprintf('<acronym title="%s %s">%s</acronym>', _('Required attribute for objectClass(es)'), $required_by, _('required')); } else { return ''; } }
/** * 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); } }
/** * 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; }
/** * 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()); }
/** * 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)) { $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]; }
/** * Given a DN string and a path like syntax, this returns the parent container portion of the string. * * @param string The DN whose container string to return. * @param string Either '/', '.' or something like '../../<rdn>' * @return string The container */ public function getContainerPath($dn, $path = '..') { if (DEBUG_ENABLED && (($fargs = func_get_args()) || ($fargs = 'NOARGS'))) { debug_log('Entered (%%)', 17, 0, __FILE__, __LINE__, __METHOD__, $fargs); } $top = $this->getContainerTop($dn); if ($path[0] == '/') { $dn = $top; $path = substr($path, 1); } elseif ($path == '.') { return $dn; } $parenttree = explode('/', $path); foreach ($parenttree as $key => $value) { if ($value == '..') { if ($this->getContainer($dn)) { $dn = $this->getContainer($dn); } if ($dn == $top) { break; } } elseif ($value) { $dn = sprintf('%s,%s', $value, $dn); } else { break; } } if (!$dn) { debug_dump(array(__METHOD__, 'dn' => $dn, 'path' => $path)); debug_dump_backtrace('Container is empty?', 1); } return $dn; }
/** * 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; }
/** * 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); } }
/** * Record a system message. * This function can be used as an alternative to generate a system message, if page hasnt yet been defined. */ function system_message($msg, $redirect = null) { if (!is_array($msg)) { return null; } if (!isset($msg['title']) && !isset($msg['body'])) { return null; } if (!isset($msg['type'])) { $msg['type'] = 'info'; } if (!isset($_SESSION['sysmsg']) || !is_array($_SESSION['sysmsg'])) { $_SESSION['sysmsg'] = array(); } # Try and detect if we are in a redirect loop if (get_request('redirect', 'GET') && $msg['type'] != 'debug') { foreach ($_SESSION['sysmsg'] as $detail) { if ($msg == $detail && !isset($detail['special'])) { debug_dump(array('Incoming MSG' => $msg, 'existing' => $_SESSION['sysmsg'])); debug_dump_backtrace('Redirect Loop Detected', true); } } } array_push($_SESSION['sysmsg'], $msg); if ($redirect) { if (preg_match('/\\?/', $redirect)) { $redirect .= '&'; } else { $redirect .= '?'; } $redirect .= 'redirect=true'; # Check if we were an ajax request, and only render the ajax message if (get_request('meth', 'REQUEST') == 'ajax') { $redirect .= '&meth=ajax'; } header("Location: {$redirect}"); die; } }
/** * 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 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); } else { debug_dump_backtrace(sprintf('There was a request to add an attribute (%s), but it was already defined? (%s)', $attrid, __METHOD__), true); } if ($this->getID() == 'none') { usort($this->attributes, 'sortAttrs'); } return $attribute; }
/** * 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; }
/** * This function will setup our template object (read LDAP for current values, read $_REQUEST for new values, etc) * so that it can be rendered. */ private function visitStart() { 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 we have a DN, then we are an editing template if ($this->dn) { $this->template->setDN($this->dn); } elseif ($this->container || get_request('create_base')) { $this->template->setContainer($this->container); } else { debug_dump_backtrace('Dont know what type of template we are - no DN or CONTAINER?', 1); } # Header $this->drawHeader(); }
/** * Copy a DN */ public function copy($template, $rdn, $asnew = false) { if (DEBUG_ENABLED && (($fargs = func_get_args()) || ($fargs = 'NOARGS'))) { debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs); } $rdnarray = rdn_explode($rdn); $counter = 1; foreach ($template->getAttributes(true) as $sattribute) { $attribute = $this->addAttribute($sattribute->getName(false), array('values' => $sattribute->getValues())); # Set our new RDN, and its values if (is_null($attribute)) { debug_dump_backtrace('Attribute is null, it probably doesnt exist in the destination server?'); } else { # Mark our internal attributes. if ($sattribute->isInternal()) { $attribute->setInternal(); } $modified = false; foreach ($rdnarray as $index => $rdnattr) { list($attr, $value) = explode('=', $rdnattr); if (strtolower($attr) == $attribute->getName()) { # If this is already marked as an RDN, then this multivalue RDN was updated on a previous loop if (!$modified) { $attribute->setValue(array($value)); $attribute->setRDN($counter++); $modified = true; } else { $attribute->addValue($value); } # This attribute has been taken care of, we'll drop it from our list. unset($rdnarray[$index]); } } } // @todo If this is a Jpeg Attribute, we need to mark it read only, since it cant be deleted like text attributes can if (strcasecmp(get_class($attribute), 'jpegAttribute') == 0) { $attribute->setReadOnly(); } } # If we have any RDN values left over, there werent in the original entry and need to be added. foreach ($rdnarray as $rdnattr) { list($attr, $value) = explode('=', $rdnattr); $attribute = $this->addAttribute($attr, array('values' => array($value))); if (is_null($attribute)) { debug_dump_backtrace('Attribute is null, it probably doesnt exist in the destination server?'); } else { $attribute->setRDN($counter++); } } # If we are copying into a new entry, we need to discard all the "old values" if ($asnew) { foreach ($this->getAttributes(true) as $sattribute) { $sattribute->setOldValue(array()); } } }