/** * 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; }
} $page = isset($_GET['page']) ? $_GET['page'] : 0; $time_start = utime(); $time_elapsed = 0; foreach ($base_dns as $base_dn) { if (!$ldapserver->dnExists($base_dn)) { if (DEBUG_ENABLED) { debug_log('BaseDN [%s] skipped as it doesnt exist in [%s].', 64, $base_dn, $ldapserver->server_id); } continue; } else { if (DEBUG_ENABLED) { debug_log('Search with base DN [%s]', 64, $base_dn); } } $results = $ldapserver->search(null, dn_escape($base_dn), $filter, $search_result_attributes, $scope, true, $config->GetValue('deref', 'search')); if (!$results && $ldapserver->errno()) { pla_error(_('Encountered an error while performing search.'), $ldapserver->error(), $ldapserver->errno()); } $errno = $ldapserver->errno(); $time_end = utime(); $time_elapsed += round($time_end - $time_start, 2); $count = count($results); $start_entry = $page * $size_limit; $end_entry = min($start_entry + $size_limit + 1, $count + 1); ?> <table class="search_header"> <tr> <td style="vertical-align: top"> <nobr><?php
/** * Explode a DN into an array of its RDN parts. * @param string $dn The DN to explode. * @param int $with_attriutes (optional) Whether to include attribute names (see http://php.net/ldap_explode_dn for details) * * @return array An array of RDN parts of this format: * <code> * Array * ( * [0] => uid=ppratt * [1] => ou=People * [2] => dc=example * [3] => dc=com * ) * </code> */ function pla_explode_dn($dn, $with_attributes = 0) { $dn = addcslashes(dn_escape($dn), '<>'); # split the dn $result = ldap_explode_dn($dn, $with_attributes); if (!$result) { return null; } # Remove our count value that ldap_explode_dn returns us. unset($result['count']); # translate hex code into ascii for display foreach ($result as $key => $value) { $result[$key] = preg_replace('/\\\\([0-9A-Fa-f]{2})/e', "''.chr(hexdec('\\1')).''", $value); } if (DEBUG_ENABLED) { debug_log('pla_explode_dn(): Entered with (%s,%s), Returning (%s)', 1, $dn, $with_attributes, $result); } return $result; }
/** * Gets the attributes/values of an entry. Returns an associative array whose * keys are attribute value names and whose values are arrays of values for * said attribute. Optionally, callers may specify true for the parameter * $lower_case_attr_names to force all keys in the associate array (attribute * names) to be lower case. * * Sample return value of <code>getDNAttrs( 0, "cn=Bob,ou=pepole,dc=example,dc=com" )</code> * * <code> * Array * ( * [objectClass] => Array * ( * [0] => person * [1] => top * ) * [cn] => Array * ( * [0] => Bob * ) * [sn] => Array * ( * [0] => Jones * ) * [dn] => Array * ( * [0] => cn=Bob,ou=pepole,dc=example,dc=com * ) * ) * </code> * * @param string $dn The distinguished name (DN) of the entry whose attributes/values to fetch. * @param bool $lower_case_attr_names (optional) If true, all keys of the returned associative * array will be lower case. Otherwise, they will be cased as the LDAP server returns * them. * @param int $deref For aliases and referrals, this parameter specifies whether to * follow references to the referenced DN or to fetch the attributes for * the referencing DN. See http://php.net/ldap_search for the 4 valid * options. * @return array * @see getDNSysAttrs * @see getDNAttr */ function getDNAttrs($dn, $lower_case_attr_names = false, $deref = LDAP_DEREF_NEVER) { if (DEBUG_ENABLED) { debug_log('%s:getDNAttrs(): Entered with (%s,%s,%s)', 17, get_class($this), $dn, $lower_case_attr_names, $deref); } $attrs = array_pop($this->search(null, dn_escape($dn), '(objectClass=*)', array(), 'base', false, $deref)); if (is_array($attrs)) { if ($lower_case_attr_names) { $attrs = array_change_key_case($attrs); } ksort($attrs); } return $attrs; }
/** * Explode a DN into an array of its RDN parts. * * NOTE: When a multivalue RDN is passed to ldap_explode_dn, the results returns with 'value + value'; * * <code> * Array ( * [0] => uid=ppratt * [1] => ou=People * [2] => dc=example * [3] => dc=com * ) * </code> * * @param string The DN to explode. * @param int (optional) Whether to include attribute names (see http://php.net/ldap_explode_dn for details) * @return array An array of RDN parts of this format: */ function pla_explode_dn($dn, $with_attributes = 0) { if (DEBUG_ENABLED && (($fargs = func_get_args()) || ($fargs = 'NOARGS'))) { debug_log('Entered (%%)', 1, 0, __FILE__, __LINE__, __METHOD__, $fargs); } global $CACHE; if (isset($CACHE['explode'][$dn][$with_attributes])) { if (DEBUG_ENABLED) { debug_log('Return CACHED result (%s) for (%s)', 1, 0, __FILE__, __LINE__, __METHOD__, $CACHE['explode'][$dn][$with_attributes], $dn); } return $CACHE['explode'][$dn][$with_attributes]; } $dn = addcslashes($dn, '<>+";'); # split the dn $result[0] = ldap_explode_dn(dn_escape($dn), 0); $result[1] = ldap_explode_dn(dn_escape($dn), 1); if (!$result[$with_attributes]) { if (DEBUG_ENABLED) { debug_log('Returning NULL - NO result.', 1, 0, __FILE__, __LINE__, __METHOD__); } return array(); } # Remove our count value that ldap_explode_dn returns us. unset($result[0]['count']); unset($result[1]['count']); # Record the forward and reverse entries in the cache. foreach ($result as $key => $value) { # translate hex code into ascii for display $result[$key] = dn_unescape($value); $CACHE['explode'][implode(',', $result[0])][$key] = $result[$key]; $CACHE['explode'][implode(',', array_reverse($result[0]))][$key] = array_reverse($result[$key]); } if (DEBUG_ENABLED) { debug_log('Returning (%s)', 1, 0, __FILE__, __LINE__, __METHOD__, $result[$with_attributes]); } return $result[$with_attributes]; }
if (!$ldapserver->haveAuthInfo()) { pla_error(_('Not enough information to login to server. Please check your configuration.')); } $dn = $_GET['dn']; $children = $ldapserver->getContainerContents($dn, 0, '(objectClass=*)', LDAP_DEREF_NEVER); $has_children = count($children) > 0 ? true : false; include './header.php'; echo '<body>'; printf('<h3 class="title">' . _('Delete %s') . '</h3>', htmlspecialchars(get_rdn($dn))); printf('<h3 class="subtitle">%s: <b>%s</b> %s: <b>%s</b></h3>', _('Server'), $ldapserver->name, _('Distinguished Name'), htmlspecialchars($dn)); if ($has_children) { echo '<center>'; printf('<b>%s</b><br /><br />', _('Permanently delete all children also?')); flush(); # get the total number of child objects (whole sub-tree) $s = $ldapserver->search(null, dn_escape($dn), 'objectClass=*', array('dn')); $sub_tree_count = count($s); ?> <table class="delete_confirm"> <tr> <td> <p> <?php printf(_('This entry is the root of a sub-tree containing %s entries.'), $sub_tree_count); ?> <small>(<a href="search.php?search=true&server_id=<?php echo $ldapserver->server_id; ?> &filter=<?php echo rawurlencode('objectClass=*');
/** * This function will perform the following intialisation steps: * + If a DN is set, query the ldap and load the object * + Read our $_REQUEST variable and set the values * After this action, the template should self describe as to whether it is an update, create * or delete. * (OLD values are IGNORED, we will have got them when we build this object from the LDAP server DN.) */ public function accept($makeVisible = false, $nocache = false) { if (DEBUG_ENABLED && (($fargs = func_get_args()) || ($fargs = 'NOARGS'))) { debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs); } $server = $this->getServer(); # If a DN is set, then query the LDAP server for the details. if ($this->dn) { if (!$server->dnExists($this->dn)) { system_message(array('title' => __METHOD__, 'body' => sprintf('DN (%s) didnt exist in LDAP?', $this->dn), 'type' => 'info')); } $rdnarray = rdn_explode(strtolower(get_rdn(dn_escape($this->dn)))); $counter = 1; foreach ($server->getDNAttrValues($this->dn, null, LDAP_DEREF_NEVER, array_merge(array('*'), $server->getValue('server', 'custom_attrs')), $nocache) as $attr => $values) { # We ignore DNs. if ($attr == 'dn') { continue; } $attribute = $this->getAttribute($attr); if (is_null($attribute)) { $attribute = $this->addAttribute($attr, array('values' => $values)); } else { if ($attribute->getValues()) { # Override values to those that are defined in the XML file. if ($attribute->getSource() != 'XML') { $attribute->setValue(array_values($values)); } else { $attribute->setOldValue(array_values($values)); } } else { $attribute->initValue(array_values($values)); } } # Work out the RDN attributes foreach ($attribute->getValues() as $index => $value) { if (in_array(sprintf('%s=%s', $attribute->getName(), strtolower($attribute->getValue($index))), $rdnarray)) { $attribute->setRDN($counter++); } } if ($makeVisible) { $attribute->show(); } } # Get the Internal Attributes foreach ($server->getDNAttrValues($this->dn, null, LDAP_DEREF_NEVER, array_merge(array('+'), $server->getValue('server', 'custom_sys_attrs'))) as $attr => $values) { $attribute = $this->getAttribute($attr); if (is_null($attribute)) { $attribute = $this->addAttribute($attr, array('values' => $values)); } else { if ($attribute->getValues()) { $attribute->setValue(array_values($values)); } else { $attribute->initValue(array_values($values)); } } if (!in_array_ignore_case($attribute->getName(), $server->getValue('server', 'custom_attrs'))) { $attribute->setInternal(); } } # If this is the default template, and our $_REQUEST has defined our objectclass, then query the schema to get the attributes } elseif ($this->container) { if ($this->isType('default') && !count($this->getAttributes(true)) && isset($_REQUEST['new_values']['objectclass'])) { $attribute = $this->addAttribute('objectclass', array('values' => $_REQUEST['new_values']['objectclass'])); $attribute->justModified(); $this->rebuildTemplateAttrs(); unset($_REQUEST['new_values']['objectclass']); } } elseif (get_request('create_base')) { if (get_request('rdn')) { $rdn = explode('=', get_request('rdn')); $attribute = $this->addAttribute($rdn[0], array('values' => array($rdn[1]))); $attribute->setRDN(1); } } else { debug_dump_backtrace('No DN or CONTAINER?', 1); } # Read in our new values. foreach (array('new_values') as $key) { if (isset($_REQUEST[$key])) { foreach ($_REQUEST[$key] as $attr => $values) { # If it isnt an array, silently ignore it. if (!is_array($values)) { continue; } # If _REQUEST['skip_array'] with this attr set, we'll ignore this new_value if (isset($_REQUEST['skip_array'][$attr]) && $_REQUEST['skip_array'][$attr] == 'on') { continue; } # Prune out entries with a blank value. foreach ($values as $index => $value) { if (!strlen(trim($value))) { unset($values[$index]); } } $attribute = $this->getAttribute($attr); # If the attribute is null, then no attribute exists, silently ignore it (unless this is the default template) if (is_null($attribute) && (!$this->isType('default') && !$this->isType(null))) { continue; } # If it is a binary attribute, the post should have base64 encoded the value, we'll need to reverse that if ($server->isAttrBinary($attr)) { foreach ($values as $index => $value) { $values[$index] = base64_decode($value); } } if (is_null($attribute)) { $attribute = $this->addAttribute($attr, array('values' => $values)); if (count($values)) { $attribute->justModified(); } } else { $attribute->setValue(array_values($values)); } } } # Read in our new binary values if (isset($_FILES[$key]['name'])) { foreach ($_FILES[$key]['name'] as $attr => $values) { $new_values = array(); foreach ($values as $index => $details) { # Ignore empty files if (!$_FILES[$key]['size'][$attr][$index]) { continue; } if (!is_uploaded_file($_FILES[$key]['tmp_name'][$attr][$index])) { if (isset($_FILES[$key]['error'][$attr][$index])) { switch ($_FILES[$key]['error'][$attr][$index]) { # No error; possible file attack! case 0: $msg = _('Security error: The file being uploaded may be malicious.'); break; # Uploaded file exceeds the upload_max_filesize directive in php.ini # Uploaded file exceeds the upload_max_filesize directive in php.ini case 1: $msg = _('The file you uploaded is too large. Please check php.ini, upload_max_size setting'); break; # Uploaded file exceeds the MAX_FILE_SIZE directive specified in the html form # Uploaded file exceeds the MAX_FILE_SIZE directive specified in the html form case 2: $msg = _('The file you uploaded is too large. Please check php.ini, upload_max_size setting'); break; # Uploaded file was only partially uploaded # Uploaded file was only partially uploaded case 3: $msg = _('The file you selected was only partially uploaded, likley due to a network error.'); break; # No file was uploaded # No file was uploaded case 4: $msg = _('You left the attribute value blank. Please go back and try again.'); break; # A default error, just in case! :) # A default error, just in case! :) default: $msg = _('Security error: The file being uploaded may be malicious.'); break; } } else { $msg = _('Security error: The file being uploaded may be malicious.'); } system_message(array('title' => _('Upload Binary Attribute Error'), 'body' => $msg, 'type' => 'warn')); } else { $binaryfile = array(); $binaryfile['name'] = $_FILES[$key]['tmp_name'][$attr][$index]; $binaryfile['handle'] = fopen($binaryfile['name'], 'r'); $binaryfile['data'] = fread($binaryfile['handle'], filesize($binaryfile['name'])); fclose($binaryfile['handle']); $new_values[$index] = $binaryfile['data']; } } if (count($new_values)) { $attribute = $this->getAttribute($attr); if (is_null($attribute)) { $attribute = $this->addAttribute($attr, array('values' => $new_values)); } else { foreach ($new_values as $value) { $attribute->addValue($value); } } $attribute->justModified(); } } } } # If there are any single item additions (from the add_attr form for example) if (isset($_REQUEST['single_item_attr'])) { if (isset($_REQUEST['single_item_value'])) { if (!is_array($_REQUEST['single_item_value'])) { $values = array($_REQUEST['single_item_value']); } else { $values = $_REQUEST['single_item_value']; } } elseif (isset($_REQUEST['binary'])) { /* Special case for binary attributes (like jpegPhoto and userCertificate): * we must go read the data from the file and override $_REQUEST['single_item_value'] with the * binary data. Secondly, we must check if the ";binary" option has to be appended to the name * of the attribute. */ if ($_FILES['single_item_value']['size'] === 0) { system_message(array('title' => _('Upload Binary Attribute Error'), 'body' => sprintf('%s %s', _('The file you chose is either empty or does not exist.'), _('Please go back and try again.')), 'type' => 'warn')); } else { if (!is_uploaded_file($_FILES['single_item_value']['tmp_name'])) { if (isset($_FILES['single_item_value']['error'])) { switch ($_FILES['single_item_value']['error']) { # No error; possible file attack! case 0: $msg = _('Security error: The file being uploaded may be malicious.'); break; # Uploaded file exceeds the upload_max_filesize directive in php.ini # Uploaded file exceeds the upload_max_filesize directive in php.ini case 1: $msg = _('The file you uploaded is too large. Please check php.ini, upload_max_size setting'); break; # Uploaded file exceeds the MAX_FILE_SIZE directive specified in the html form # Uploaded file exceeds the MAX_FILE_SIZE directive specified in the html form case 2: $msg = _('The file you uploaded is too large. Please check php.ini, upload_max_size setting'); break; # Uploaded file was only partially uploaded # Uploaded file was only partially uploaded case 3: $msg = _('The file you selected was only partially uploaded, likley due to a network error.'); break; # No file was uploaded # No file was uploaded case 4: $msg = _('You left the attribute value blank. Please go back and try again.'); break; # A default error, just in case! :) # A default error, just in case! :) default: $msg = _('Security error: The file being uploaded may be malicious.'); break; } } else { $msg = _('Security error: The file being uploaded may be malicious.'); } system_message(array('title' => _('Upload Binary Attribute Error'), 'body' => $msg, 'type' => 'warn'), 'index.php'); } $binaryfile = array(); $binaryfile['name'] = $_FILES['single_item_value']['tmp_name']; $binaryfile['handle'] = fopen($binaryfile['name'], 'r'); $binaryfile['data'] = fread($binaryfile['handle'], filesize($binaryfile['name'])); fclose($binaryfile['handle']); $values = array($binaryfile['data']); } } if (count($values)) { $attribute = $this->getAttribute($_REQUEST['single_item_attr']); if (is_null($attribute)) { $attribute = $this->addAttribute($_REQUEST['single_item_attr'], array('values' => $values)); } else { $attribute->setValue(array_values($values)); } $attribute->justModified(); } } # If this is the default creation template, we need to set some additional values if ($this->isType('default') && $this->getContext() == 'create') { # Load our schema, based on the objectclasses that may have already been defined. if (!get_request('create_base')) { $this->rebuildTemplateAttrs(); } # Set the RDN attribute $counter = 1; foreach (get_request('rdn_attribute', 'REQUEST', false, array()) as $key => $value) { $attribute = $this->getAttribute($value); if (!is_null($attribute)) { $attribute->setRDN($counter++); } else { system_message(array('title' => _('No RDN attribute'), 'body' => _('No RDN attribute was selected'), 'type' => 'warn'), 'index.php'); die; } } } }