ldap_servers.functions.inc in Lightweight Directory Access Protocol (LDAP) 8.2
Same filename and directory in other branches
collection of functions that don't belong in server object
File
ldap_servers/ldap_servers.functions.incView source
<?php
/**
* @file
* collection of functions that don't belong in server object
*/
/**
* Modify an LDAP Entry
*
* this has been depracated in favor or $ldap_server->modifyLdapEntry($dn, $attributes)
* which handles empty attributes better.
*
*/
function ldap_user_modify($dn, $attributes, $ldap_server) {
$result = ldap_modify($ldap_server->connection, $dn, $attributes);
if (!$result) {
$error = "LDAP Server ldap_modify(%dn) in ldap_user_modify() Error Server ID = %sid, LDAP Err No: %ldap_errno LDAP Err Message: %ldap_err2str ";
$tokens = array(
'%dn' => $dn,
'%sid' => $this->sid,
'%ldap_errno' => ldap_errno($this->connection),
'%ldap_err2str' => ldap_err2str(ldap_errno($this->connection)),
);
watchdog('ldap_servers', $error, $tokens, WATCHDOG_ERROR);
}
return $result;
}
/**
* Modify a password
*/
function ldap_password_modify($userdn, $new_password, $ldap_server) {
$new_password = "\"" . $new_password . "\"";
$len = drupal_strlen($new_password);
$new_pass = NULL;
for ($i = 0; $i < $len; $i++) {
$new_pass .= "{$new_password[$i]}\0";
}
$status = ldap_mod_replace($ldap_server->connection, $userdn, array(
'unicodePwd' => $new_pass,
));
if (!$status) {
watchdog('ldap_servers', 'Error: password_modify() failed to modify ldap password w/ base DN "!dn"', array(
'!dn' => $userdn,
), WATCHDOG_ERROR);
}
return $status;
}
/**
*
* this attempts to find bad dns, but should only be used as warningswe
* as the ldap spec allows for any old character to be escaped and ldap
* implementations may not follow the spec.
*
* http://www.ietf.org/rfc/rfc2253.txt
*
*/
function ldap_baddn($dn, $dn_name) {
$result = array();
$valid_attr_name = '[_a-zA-Z\\d\\s]';
$valid_attr_values = '[_\\-a-zA-Z\\d\\s]';
$regex = '/^(' . $valid_attr_name . '*\\=' . $valid_attr_values . '*[,]{1})*(' . $valid_attr_name . '*\\=' . $valid_attr_values . '*){1}$/';
$match = preg_match($regex, $dn) ? TRUE : FALSE;
$result['boolean'] = $match;
if (!$match) {
$tokens = array(
'%dn' => htmlspecialchars($dn),
'%dn_name' => $dn_name,
);
$result['text'] = t('Possible invalid format for:', $tokens) . '<em>' . $tokens['%dn'] . '</em>.<br/> ' . t('The format may be correct for your ldap, but please double check.', $tokens);
}
return $result;
}
/**
*
* this attempts to find bad dns, but should only be used as warningswe
* as the ldap spec allows for any old character to be escaped and ldap
* implementations may not follow the spec.
*
* http://www.ietf.org/rfc/rfc2253.txt
*
*/
function ldap_badattr($attr, $attr_name) {
$result = array();
$valid_attr_name = '[_a-zA-Z\\d\\s]';
$regex = '/^(' . $valid_attr_name . '){1,}$/';
$match = preg_match($regex, $attr) ? TRUE : FALSE;
$result['boolean'] = $match;
if (!$match) {
$tokens = array(
'%attr' => htmlspecialchars($attr),
'%attr_name' => $attr_name,
);
$result['text'] = t('Possible invalid format for %attr_name:', $tokens) . ' <code><em>' . $tokens['%attr'] . '</em></code><br/>' . t('The format may be correct for your ldap, but please double check.', $tokens);
}
return $result;
}
/**
* get array of required attributes for an ldap query
* @param string $sid server id or ldap server object being used
* @param string $direction LDAP_USER_PROV_DIRECTION_* constant
* @param string $ldap_context
* @param boolean $reset cache
*
*/
function ldap_servers_attributes_needed($sid, $ldap_context = 'all', $reset = TRUE) {
static $attributes;
$sid = is_object($sid) ? $sid->sid : $sid;
$static_cache_id = $sid ? $ldap_context . '__' . $sid : $ldap_context;
if (!is_array($attributes)) {
$attributes = array();
}
if (!isset($attributes[$static_cache_id]) || $reset) {
$params = array(
'sid' => $sid,
'ldap_context' => $ldap_context,
);
drupal_alter('ldap_attributes_needed', $attributes[$static_cache_id], $params);
}
$return = $attributes[$static_cache_id];
return $return;
}
/**
* function to massage (change case, escape, unescape) ldap attribute names
* and values. The primary purpose of this is to articulate and ensure consistency
* across ldap modules.
*
* @param mixed $value to be massaged
* @param enum $value_type = 'attr_name' or 'attr_value;
* @param enum $context...see LDAP_SERVER_MASSAGE_* constants
*
* .e.g. ldap_server_massage_text($value, 'attr_value', LDAP_SERVER_MASSAGE_QUERY_LDAP)
*/
function ldap_server_massage_text($value, $value_type, $context) {
$scalar = is_scalar($value);
if ($value_type == 'attr_value') {
if ($context == LDAP_SERVER_MASSAGE_QUERY_LDAP) {
$value = ldap_pear_escape_filter_value($value);
}
elseif ($context == LDAP_SERVER_MASSAGE_STORE_LDAP) {
$value = ldap_pear_escape_dn_value($value);
}
switch ($context) {
case LDAP_SERVER_MASSAGE_DISPLAY:
case LDAP_SERVER_MASSAGE_TOKEN_REPLACE:
case LDAP_SERVER_MASSAGE_QUERY_LDAP:
case LDAP_SERVER_MASSAGE_QUERY_DB:
case LDAP_SERVER_MASSAGE_QUERY_ARRAY:
case LDAP_SERVER_MASSAGE_QUERY_PROPERTY:
case LDAP_SERVER_MASSAGE_STORE_LDAP:
case LDAP_SERVER_MASSAGE_STORE_DB:
case LDAP_SERVER_MASSAGE_STORE_ARRAY:
case LDAP_SERVER_MASSAGE_STORE_PROPERTY:
break;
}
}
elseif ($value_type == 'attr_name') {
// attr_name
switch ($context) {
case LDAP_SERVER_MASSAGE_DISPLAY:
break;
case LDAP_SERVER_MASSAGE_TOKEN_REPLACE:
case LDAP_SERVER_MASSAGE_QUERY_LDAP:
case LDAP_SERVER_MASSAGE_QUERY_DB:
case LDAP_SERVER_MASSAGE_QUERY_ARRAY:
case LDAP_SERVER_MASSAGE_QUERY_PROPERTY:
case LDAP_SERVER_MASSAGE_STORE_LDAP:
case LDAP_SERVER_MASSAGE_STORE_DB:
case LDAP_SERVER_MASSAGE_STORE_ARRAY:
case LDAP_SERVER_MASSAGE_STORE_PROPERTY:
if ($scalar) {
$value = drupal_strtolower($value);
}
elseif (is_array($value)) {
foreach ($value as $i => $val) {
$value[$i] = drupal_strtolower($val);
}
}
else {
// neither scalar nor array $value
}
break;
}
}
return $value;
}
/**
* from pear net_ldap2-2.0.11
*
* Escapes the given VALUES according to RFC 2254 so that they can be safely used in LDAP filters.
*
* Any control characters with an ACII code < 32 as well as the characters with special meaning in
* LDAP filters "*", "(", ")", and "\" (the backslash) are converted into the representation of a
* backslash followed by two hex digits representing the hexadecimal value of the character.
*
* @param array $values Array of values to escape
*
* @static
* @return array Array $values, but escaped
*/
function ldap_pear_escape_filter_value($values = array()) {
// Parameter validation
$is_scalar = is_scalar($values);
if (!is_array($values)) {
$values = array(
$values,
);
}
foreach ($values as $key => $val) {
// Escaping of filter meta characters
$val = str_replace('\\', '\\5c', $val);
$val = str_replace('*', '\\2a', $val);
$val = str_replace('(', '\\28', $val);
$val = str_replace(')', '\\29', $val);
// ASCII < 32 escaping
$val = ldap_pear_asc2hex32($val);
if (null === $val) {
$val = '\\0';
}
// apply escaped "null" if string is empty
$values[$key] = $val;
}
return $is_scalar ? $values[0] : $values;
}
/**
* Undoes the conversion done by {@link escape_filter_value()}.
*
* Converts any sequences of a backslash followed by two hex digits into the corresponding character.
*
* @param array $values Array of values to escape
*
* @static
* @return array Array $values, but unescaped
*/
function ldap_pear_unescape_filter_value($values = array()) {
// Parameter validation
$is_scalar = is_scalar($values);
if (!is_array($values)) {
$values = array(
$values,
);
}
foreach ($values as $key => $value) {
// Translate hex code into ascii
$values[$key] = ldap_pear_hex2asc($value);
}
return $is_scalar ? $values[0] : $values;
}
/**
* Escapes a DN value according to RFC 2253
*
* Escapes the given VALUES according to RFC 2253 so that they can be safely used in LDAP DNs.
* The characters ",", "+", """, "\", "<", ">", ";", "#", "=" with a special meaning in RFC 2252
* are preceeded by ba backslash. Control characters with an ASCII code < 32 are represented as \hexpair.
* Finally all leading and trailing spaces are converted to sequences of \20.
*
* @param array $values An array containing the DN values that should be escaped
*
* @static
* @return array The array $values, but escaped
*/
function ldap_pear_escape_dn_value($values = array()) {
// Parameter validation
$is_scalar = is_scalar($values);
if (!is_array($values)) {
$values = array(
$values,
);
}
foreach ($values as $key => $val) {
// Escaping of filter meta characters
$val = str_replace('\\', '\\\\', $val);
$val = str_replace(',', '\\,', $val);
$val = str_replace('+', '\\+', $val);
$val = str_replace('"', '\\"', $val);
$val = str_replace('<', '\\<', $val);
$val = str_replace('>', '\\>', $val);
$val = str_replace(';', '\\;', $val);
$val = str_replace('#', '\\#', $val);
$val = str_replace('=', '\\=', $val);
// ASCII < 32 escaping
$val = ldap_pear_asc2hex32($val);
// Convert all leading and trailing spaces to sequences of \20.
if (preg_match('/^(\\s*)(.+?)(\\s*)$/', $val, $matches)) {
$val = $matches[2];
for ($i = 0; $i < strlen($matches[1]); $i++) {
$val = '\\20' . $val;
}
for ($i = 0; $i < strlen($matches[3]); $i++) {
$val = $val . '\\20';
}
}
if (null === $val) {
$val = '\\0';
}
// apply escaped "null" if string is empty
$values[$key] = $val;
}
return $is_scalar ? $values[0] : $values;
}
/**
* Undoes the conversion done by escape_dn_value().
*
* Any escape sequence starting with a baskslash - hexpair or special character -
* will be transformed back to the corresponding character.
*
* @param array $values Array of DN Values
*
* @return array Same as $values, but unescaped
* @static
*/
function ldap_pear_unescape_dn_value($values = array()) {
$is_scalar = is_scalar($values);
// Parameter validation
if (!is_array($values)) {
$values = array(
$values,
);
}
foreach ($values as $key => $val) {
// strip slashes from special chars
$val = str_replace('\\\\', '\\', $val);
$val = str_replace('\\,', ',', $val);
$val = str_replace('\\+', '+', $val);
$val = str_replace('\\"', '"', $val);
$val = str_replace('\\<', '<', $val);
$val = str_replace('\\>', '>', $val);
$val = str_replace('\\;', ';', $val);
$val = str_replace('\\#', '#', $val);
$val = str_replace('\\=', '=', $val);
// Translate hex code into ascii
$values[$key] = ldap_pear_hex2asc($val);
}
return $is_scalar ? $values[0] : $values;
}
/**
* Converts all Hex expressions ("\HEX") to their original ASCII characters
*
* @param string $string String to convert
*
* @static
* @author beni@php.net, heavily based on work from DavidSmith@byu.net
* @return string
*/
function ldap_pear_hex2asc($string) {
$string = preg_replace("/\\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\1')).''", $string);
return $string;
}
/**
* Converts all ASCII chars < 32 to "\HEX"
*
* @param string $string String to convert
*
* @static
* @return string
*/
function ldap_pear_asc2hex32($string) {
for ($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
if (ord($char) < 32) {
$hex = dechex(ord($char));
if (strlen($hex) == 1) {
$hex = '0' . $hex;
}
$string = str_replace($char, '\\' . $hex, $string);
}
}
return $string;
}
Functions
Name | Description |
---|---|
ldap_badattr | this attempts to find bad dns, but should only be used as warningswe as the ldap spec allows for any old character to be escaped and ldap implementations may not follow the spec. |
ldap_baddn | this attempts to find bad dns, but should only be used as warningswe as the ldap spec allows for any old character to be escaped and ldap implementations may not follow the spec. |
ldap_password_modify | Modify a password |
ldap_pear_asc2hex32 | Converts all ASCII chars < 32 to "\HEX" |
ldap_pear_escape_dn_value | Escapes a DN value according to RFC 2253 |
ldap_pear_escape_filter_value | from pear net_ldap2-2.0.11 |
ldap_pear_hex2asc | Converts all Hex expressions ("\HEX") to their original ASCII characters |
ldap_pear_unescape_dn_value | Undoes the conversion done by escape_dn_value(). |
ldap_pear_unescape_filter_value | Undoes the conversion done by {@link escape_filter_value()}. |
ldap_servers_attributes_needed | get array of required attributes for an ldap query |
ldap_server_massage_text | function to massage (change case, escape, unescape) ldap attribute names and values. The primary purpose of this is to articulate and ensure consistency across ldap modules. |
ldap_user_modify | Modify an LDAP Entry |