/** * Create an instance of the tree - this is used when we call this class directly * Tree::getInstance($index) * * @return object Tree */ public static 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; }
# If cancel was selected, we'll redirect if (get_request('cancel', 'REQUEST')) { header('Location: index.php'); die; } $request = array(); $request['redirect'] = get_request('redirect', 'POST', false, false); $request['page'] = new PageRender($app['server']->getIndex(), get_request('template', 'REQUEST', false, 'none')); $request['page']->setContainer(get_request('container', 'REQUEST', true)); $request['page']->accept(); $request['template'] = $request['page']->getTemplate(); if ((!$request['template']->getContainer() || !$app['server']->dnExists($request['template']->getContainer())) && !get_request('create_base')) { error(sprintf(_('The container you specified (%s) does not exist. Please try again.'), $request['template']->getContainer()), 'error', 'index.php'); } # Check if the container is a leaf - we shouldnt really return a hit here, the template engine shouldnt have allowed a user to attempt to create an entry... $tree = get_cached_item($app['server']->getIndex(), 'tree'); $request['container'] = $tree->getEntry($request['template']->getContainer()); if (!$request['container'] && !get_request('create_base')) { $tree->addEntry($request['template']->getContainer()); $request['container'] = $tree->getEntry($request['template']->getContainer()); } # Check our RDN if (!count($request['template']->getRDNAttrs())) { error(_('The were no attributes marked as an RDN attribute.'), 'error', 'index.php'); } if (!$request['template']->getRDN()) { error(_('The RDN field is empty?'), 'error', 'index.php'); } # Some other attribute checking... foreach ($request['template']->getAttributes() as $attribute) { # Check that our Required Attributes have a value - we shouldnt really return a hit here, the template engine shouldnt have allowed this to slip through.
/** * 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; }
/** * Returns an array of Syntax objects that this LDAP server uses mapped to * their descriptions. The key of each entry is the OID of the Syntax. */ public function SchemaSyntaxes($method = null, $dn = '') { if (DEBUG_ENABLED && (($fargs = func_get_args()) || ($fargs = 'NOARGS'))) { debug_log('Entered (%%)', 25, 0, __FILE__, __LINE__, __METHOD__, $fargs); } # Set default return $return = null; if ($return = get_cached_item($this->index, 'schema', 'syntaxes')) { if (DEBUG_ENABLED) { debug_log('Returning CACHED [%s] (%s).', 25, 0, __FILE__, __LINE__, __METHOD__, $this->index, 'syntaxes'); } return $return; } $raw = $this->getRawSchema($method, 'ldapSyntaxes', $dn); if ($raw) { # build the array of attributes $return = array(); foreach ($raw as $line) { if (is_null($line) || !strlen($line)) { continue; } $syntax = new Syntax($line); $key = strtolower(trim($syntax->getOID())); if (!$key) { continue; } $return[$key] = $syntax; } ksort($return); # cache the schema to prevent multiple schema fetches from LDAP server set_cached_item($this->index, 'schema', 'syntaxes', $return); } if (DEBUG_ENABLED) { debug_log('Returning (%s)', 25, 0, __FILE__, __LINE__, __METHOD__, $return); } return $return; }
/** * Gets a list of child entries for an entry. Given a DN, this function fetches the list of DNs of * child entries one level beneath the parent. For example, for the following tree: * * <code> * dc=example,dc=com * ou=People * cn=Dave * cn=Fred * cn=Joe * ou=More People * cn=Mark * cn=Bob * </code> * * Calling <code>getContainerContents("ou=people,dc=example,dc=com")</code> * would return the following list: * * <code> * cn=Dave * cn=Fred * cn=Joe * ou=More People * </code> * * @param string $dn The DN of the entry whose children to return. * @param int $size_limit (optional) The maximum number of entries to return. * If unspecified, no limit is applied to the number of entries in the returned. * @param string $filter (optional) An LDAP filter to apply when fetching children, example: "(objectClass=inetOrgPerson)" * @return array An array of DN strings listing the immediate children of the specified entry. */ function getContainerContents($dn, $size_limit = 0, $filter = '(objectClass=*)', $deref = LDAP_DEREF_ALWAYS) { $tree = get_cached_item($this->server_id, 'tree'); if (isset($tree['browser'][$dn]['children']) && $filter == '(objectClass=*)') { if (!isset($tree['browser'][$dn]['size_limited']) || !$tree['browser'][$dn]['size_limited']) { return $tree['browser'][$dn]['children']; } } $return = array(); $search = $this->search(null, dn_escape($dn), $filter, array('dn'), 'one', true, $deref, $size_limit > 0 ? $size_limit + 1 : $size_limit); if (!$search) { $tree['browser'][$dn]['children'] = array(); } else { foreach ($search as $searchdn => $entry) { $child_dn = dn_unescape($entry['dn']); $tree['browser'][$child_dn]['icon'] = get_icon($this, $child_dn); $return[] = $child_dn; } usort($return, 'pla_compare_dns'); $tree['browser'][$dn]['children'] = $return; if ($size_limit > 0 && count($tree['browser'][$dn]['children']) > $size_limit) { $tree['browser'][$dn]['size_limited'] = true; } else { if (isset($tree['browser'][$dn]['size_limited'])) { unset($tree['browser'][$dn]['size_limited']); } } } set_cached_item($this->server_id, 'tree', 'null', $tree); if (DEBUG_ENABLED) { debug_log('%s::getContainerContents(): Entered with (%s,%s,%s,%s), Returning (%s)', 17, get_class($this), $dn, $size_limit, $filter, $deref, $return); } return $tree['browser'][$dn]['children']; }
* Note: this script is equal and opposite to collapse.php * @package phpLDAPadmin * @see collapse.php */ /** */ require './common.php'; no_expire_header(); if (!$ldapserver->haveAuthInfo()) { pla_error(_('Not enough information to login to server. Please check your configuration.')); } # This allows us to display large sub-trees without running out of time. @set_time_limit(0); $dn = $_GET['dn']; # We dont need this result, as we'll use the SESSION value when we call tree.php $ldapserver->getContainerContents($dn, 0, '(objectClass=*)', $config->GetValue('deref', 'tree')); $tree = get_cached_item($ldapserver->server_id, 'tree'); $tree['browser'][$dn]['open'] = true; set_cached_item($ldapserver->server_id, 'tree', 'null', $tree); /* This is for Opera. By putting "random junk" in the query string, it thinks that it does not have a cached version of the page, and will thus fetch the page rather than display the cached version */ $time = gettimeofday(); $random_junk = md5(strtotime('now') . $time['usec']); /* If cookies were disabled, build the url parameter for the session id. It will be append to the url to be redirect */ $id_session_param = ''; if (SID != '') { $id_session_param = sprintf('&%s=%s', session_name(), session_id()); } header(sprintf('Location:tree.php?foo=%s#%s_%s%s', $random_junk, $ldapserver->server_id, rawurlencode($dn), $id_session_param));
function Templates($server_id) { if (DEBUG_ENABLED) { debug_log('%s::__construct(): Entered with ()', 5, get_class($this)); } if ($this->_template = get_cached_item($server_id, 'template', 'all')) { if (DEBUG_ENABLED) { debug_log('%s::init(): Using CACHED [%s]', 5, get_class($this), 'templates'); } } else { $dir = opendir(TMPLDIR); $this->template_num = 0; while (($file = readdir($dir)) !== false) { if (!preg_match('/.xml$/', $file)) { continue; } $objXML = new xml2array(); $xmldata = $objXML->parse(TMPLDIR . $file); $template_name = preg_replace('/.xml$/', '', $file); $this->storeTemplate($template_name, $xmldata); } masort($this->_template, 'title'); set_cached_item($server_id, 'template', 'all', $this->_template); } }
/** * Recursively descend on the given dn and draw the tree in plm * * @param dn $dn Current dn. * @param object $LDAPServer LDAPServer object * @param int $level Level to start drawing (defaults to 2) * @todo: Currently draw PLM only shows the first 50 entries of the base children - possibly the childrens children too. Have disabed the size_limit on the base - need to check that it doesnt affect non PLM tree viewer and children where size > size_limit. */ function draw_tree_plm($dn, $ldapserver, $level = 2) { if (DEBUG_ENABLED) { debug_log('draw_tree_plm(): Entered with (%s,%s,%s)', 33, $dn, $ldapserver, $level); } global $config; $tree = get_cached_item($ldapserver->server_id, 'tree'); $encoded_dn = rawurlencode($dn); #$expand_href = sprintf('expand.php?server_id=%s&dn=%s',$ldapserver->server_id,$encoded_dn); $edit_href = sprintf('template_engine.php?server_id=%s&dn=%s', $ldapserver->server_id, $encoded_dn); #$img_src = sprintf('images/%s',$tree['browser'][$dn]['icon']); $rdn = get_rdn($dn); $dots = ''; for ($i = 1; $i <= $level; $i++) { $dots .= '.'; } # Have we tranversed this part of the tree yet? if (isset($tree['browser'][$dn]['open'])) { $tree_plm = sprintf("%s|%s|%s|%s|%s|%s|%s\n", $dots, $rdn . ' (' . number_format(count($tree['browser'][$dn]['children'])) . ')', $edit_href, $dn, $tree['browser'][$dn]['icon'], 'right_frame', isset($tree['browser'][$dn]['open']) ? $tree['browser'][$dn]['open'] : 0); foreach ($tree['browser'][$dn]['children'] as $dn) { $tree_plm .= draw_tree_plm($dn, $ldapserver, $level + 1); } } else { $size_limit = $config->GetValue('search', 'size_limit'); $child_count = count($ldapserver->getContainerContents($dn, $size_limit + 1, '(objectClass=*)', $config->GetValue('deref', 'tree'))); if ($child_count > $size_limit) { $child_count = $size_limit . '+'; } if ($child_count) { $tree_plm = sprintf("%s|%s|%s|%s|%s|%s|%s|%s\n", $dots, $rdn . ' (' . $child_count . ')', $edit_href, $dn, $tree['browser'][$dn]['icon'], 'right_frame', isset($tree['browser'][$dn]['open']) ? $tree['browser'][$dn]['open'] : 0, $child_count); } else { $tree_plm = sprintf("%s|%s|%s|%s|%s|%s|%s|%s\n", $dots, $rdn . ' (0)', $edit_href, $dn, $tree['browser'][$dn]['icon'], 'right_frame', isset($tree['browser'][$dn]['open']) ? $tree['browser'][$dn]['open'] : 0, $child_count); } } if (DEBUG_ENABLED) { debug_log('draw_tree_plm(): Returning (%s)', 33, $tree_plm); } return $tree_plm; }
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; eval(sprintf('$this->templates[$index] = new %s($this->server_id,$template->getName(false),$template->getFileName(),$template->getType(),$index);', $class['name'])); } } 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); eval(sprintf('$this->templates[$index] = new %s($this->server_id,$templatename,$filename,$type,$index);', $class['name'])); $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); eval(sprintf('$this->templates[$counter] = new %s($this->server_id,$templatename,$filename,$type,$counter);', $class['name'])); $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); } }
/** PAGE ENTRY MENU ITEMS **/ private function getMenuItem($i) { 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 (%s)</font><br />', __METHOD__, $i); } switch ($i) { case 'entryrefresh': if ($_SESSION[APPCONFIG]->isCommandAvailable('cmd', 'entry_refresh')) { return $this->getMenuItemRefresh(); } else { return ''; } case 'switchtemplate': if ($_SESSION[APPCONFIG]->isCommandAvailable('cmd', 'switch_template')) { return $this->getMenuItemSwitchTemplate(); } else { return ''; } case 'entryexport': if ($_SESSION[APPCONFIG]->isCommandAvailable('script', 'export_form') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'export')) { return $this->getMenuItemExportBase(); } else { return ''; } case 'entrycopy': if ($_SESSION[APPCONFIG]->isCommandAvailable('script', 'copy_form') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'copy') && !$this->template->isReadOnly()) { return $this->getMenuItemMove(); } else { return ''; } case 'showinternal': if ($_SESSION[APPCONFIG]->isCommandAvailable('cmd', 'entry_internal_attributes_show')) { return $this->getMenuItemInternalAttributes(); } else { return ''; } case 'entrydelete': if ($_SESSION[APPCONFIG]->isCommandAvailable('script', 'delete_form') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'delete') && !$this->template->isReadOnly()) { return $this->getMenuItemDelete(); } else { return ''; } case 'entryrename': if ($_SESSION[APPCONFIG]->isCommandAvailable('script', 'rename_form') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'rename') && !$this->template->isReadOnly()) { # Check if any of the RDN's are read only. $rdnro = false; foreach ($this->template->getRDNAttributeName() as $attr) { $attribute = $this->template->getAttribute($attr); if ($attribute && $attribute->isVisible() && !$attribute->isReadOnly()) { $rdnro = true; break; } } if (!$rdnro) { return $this->getMenuItemRename(); } } return ''; case 'msgdel': if ($_SESSION[APPCONFIG]->getValue('appearance', 'show_hints') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'delete_form') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'delete') && !$this->template->isReadOnly()) { return array('', $this->getDeleteAttributeMessage()); } else { return ''; } case 'entrycompare': if ($_SESSION[APPCONFIG]->isCommandAvailable('script', 'compare_form') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'compare') && !$this->template->isReadOnly()) { return $this->getMenuItemCompare(); } else { return ''; } case 'childcreate': if ($_SESSION[APPCONFIG]->isCommandAvailable('script', 'create') && !$this->template->isReadOnly() && !$this->template->isNoLeaf()) { return $this->getMenuItemCreate(); } else { return ''; } case 'addattr': if ($_SESSION[APPCONFIG]->isCommandAvailable('script', 'add_attr_form') && !$this->template->isReadOnly()) { return $this->getMenuItemAddAttribute(); } else { return ''; } case 'childview': case 'childexport': static $children_count = false; static $more_children = false; $tree = get_cached_item($this->getServerID(), 'tree'); $tree_item = $tree->getEntry($this->template->getDN()); if (!$tree_item) { $tree->addEntry($this->template->getDN()); $tree_item = $tree->getEntry($this->template->getDN()); } if ($children_count === false) { # Visible children in the tree $children_count = count($tree_item->getChildren()); # Is there filtered children ? $more_children = $tree_item->isSizeLimited(); if (!$children_count || !$more_children) { # All children in ldap $all_children = $this->getServer()->getContainerContents($this->template->getDN(), null, $children_count + 1, '(objectClass=*)', $_SESSION[APPCONFIG]->getValue('deref', 'view'), null); $more_children = count($all_children) > $children_count; } } if ($children_count > 0 || $more_children) { if ($children_count <= 0) { $children_count = ''; } if ($more_children) { $children_count .= '+'; } if ($i == 'childview') { return $this->getMenuItemShowChildren($children_count); } elseif ($i == 'childexport' && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'export_form') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'export')) { return $this->getMenuItemExportSub(); } else { return ''; } } else { return ''; } case 'msgschema': if ($_SESSION[APPCONFIG]->getValue('appearance', 'show_hints') && $_SESSION[APPCONFIG]->isCommandAvailable('script', 'schema')) { return array('', $this->getViewSchemaMessage()); } else { return array(); } case 'msgro': if ($this->template->isReadOnly()) { return array('', $this->getReadOnlyMessage()); } else { return array(); } case 'msgmodattr': $modified_attrs = array(); $modified = get_request('modified_attrs', 'REQUEST', false, array()); foreach ($this->template->getAttributes(true) as $attribute) { if (in_array($attribute->getName(), $modified)) { array_push($modified_attrs, $attribute->getFriendlyName()); } } if (count($modified_attrs)) { return array('', $this->getModifiedAttributesMessage($modified_attrs)); } else { return array(); } default: return false; } }