ldap_servers.tokens.inc in Lightweight Directory Access Protocol (LDAP) 7.2
Same filename and directory in other branches
Collection of functions related to ldap tokens.
File
ldap_servers/ldap_servers.tokens.incView source
<?php
/**
* @file
* Collection of functions related to ldap tokens.
*/
/**
* @param string $attr_name
* such 'field_user_lname', 'name', 'mail', 'dn'.
* @param string $attr_type
* such as 'field', 'property', etc. NULL for ldap attributes.
* @param string $attr_ordinal
* 0, 1, 2, etc. not used in general.
*
* @return string such as 'field.field_user_lname', 'samaccountname', etc.
*/
function ldap_servers_make_token($attr_name, $attr_type = NULL, $ordinal = NULL) {
$inner_token = $attr_name;
if ($attr_type) {
$inner_token .= '.' . $attr_type;
}
if ($ordinal) {
$inner_token .= ':' . $ordinal;
}
$token = LDAP_SERVERS_TOKEN_PRE . $inner_token . LDAP_SERVERS_TOKEN_POST;
return $token;
}
/**
* @param $user_attr_key
* of form <attr_type>.<attr_name>[:<instance>]
* such as field.lname, property.mail, field.aliases:2
*
* @return array array($attr_type, $attr_name, $attr_ordinal) such as array('field','field_user_lname', NULL)
*/
function ldap_servers_parse_user_attr_name($user_attr_key) {
// Make sure no [] are on attribute.
$user_attr_key = trim($user_attr_key, LDAP_SERVERS_TOKEN_PRE . LDAP_SERVERS_TOKEN_POST);
$parts = explode('.', $user_attr_key);
$attr_type = $parts[0];
$attr_name = isset($parts[1]) ? $parts[1] : FALSE;
$attr_ordinal = FALSE;
if ($attr_name) {
$attr_name_parts = explode(':', $attr_name);
if (isset($attr_name_parts[1])) {
$attr_name = $attr_name_parts[0];
$attr_ordinal = $attr_name_parts[1];
}
}
return [
$attr_type,
$attr_name,
$attr_ordinal,
];
}
/**
* @param array
* @param string $text
*
* @return string
*/
/**
* User_account.
*
* @param $resource
* $ldap_entry
* @param $text
* such as "[dn]", "[cn]@my.org", "[displayName] [sn]", "Drupal Provisioned"
* @param string $resource_type
*
* @return string|string[]|null
* $text with tokens replaced or NULL if replacement not available
*/
function ldap_servers_token_replace($resource, $text, $resource_type = 'ldap_entry') {
// Desired tokens are of form "cn","mail", etc.
$desired_tokens = ldap_servers_token_tokens_needed_for_template($text);
if (empty($desired_tokens)) {
// If no tokens exist in text, return text itself. It is literal value.
return $text;
}
$tokens = [];
// @TODO: Should really be if/else if only those two exist.
switch ($resource_type) {
case 'ldap_entry':
$tokens = ldap_servers_token_tokenize_entry($resource, $desired_tokens, LDAP_SERVERS_TOKEN_PRE, LDAP_SERVERS_TOKEN_POST);
break;
case 'user_account':
$tokens = ldap_servers_token_tokenize_user_account($resource, $desired_tokens, LDAP_SERVERS_TOKEN_PRE, LDAP_SERVERS_TOKEN_POST);
break;
}
// Add lowercase tokens to avoid case sensitivity.
foreach ($tokens as $attribute => $value) {
$tokens[drupal_strtolower($attribute)] = $value;
}
// If $text is not present as an attribute key, insert it and set the key's value to an empty string.
if (!array_key_exists(drupal_strtolower($text), $tokens)) {
$tokens[$text] = '';
$tokens[drupal_strtolower($text)] = '';
}
// Array of attributes (sn, givenname, etc)
$attributes = array_keys($tokens);
// Array of attribute values (Lincoln, Abe, etc)
$values = array_values($tokens);
$result = str_replace($attributes, $values, $text);
// Strip out any unreplaced tokens.
$result = preg_replace('/\\[[^\\]]*]/', '', $result);
// Return NULL if $result is empty, else $result.
return $result == '' ? NULL : $result;
}
/**
* @param array $attributes
* array of attributes passed by reference.
* @param string $text
* with tokens in it
*
* by reference return add ldap attribute triplet $attribute_maps[<attr_name>] = (<attr_name>, <ordinal>, <data_type>) to $attributes.
*/
function ldap_servers_token_extract_attributes(&$attribute_maps, $text) {
$tokens = ldap_servers_token_tokens_needed_for_template($text);
foreach ($tokens as $token) {
$token = str_replace([
LDAP_SERVERS_TOKEN_PRE,
LDAP_SERVERS_TOKEN_POST,
], [
'',
'',
], $token);
$parts = explode(LDAP_SERVERS_TOKEN_DEL, $token);
$ordinal = isset($parts[1]) && $parts[1] ? $parts[1] : 0;
$attr_name = $parts[0];
$source_data_type = NULL;
$parts2 = explode(LDAP_SERVERS_TOKEN_MODIFIER_DEL, $attr_name);
if (count($parts2) > 1) {
$attr_name = $parts2[0];
$conversion = $parts2[1];
}
else {
$conversion = NULL;
}
$attribute_maps[$attr_name] = ldap_servers_set_attribute_map(@$attribute_maps[$attr_name], $conversion, [
$ordinal => NULL,
]);
}
}
/**
* @param string $token
* or token expression with singular token in it, eg. [dn], [dn;binary], [titles:0;binary] [cn]@mycompany.com.
*
* @return array(<attr_name>, <ordinal>, <conversion>)
*/
function ldap_servers_token_extract_parts($token) {
$attributes = [];
ldap_servers_token_extract_attributes($attributes, $token);
if (is_array($attributes)) {
$keys = array_keys($attributes);
$attr_name = $keys[0];
$attr_data = $attributes[$attr_name];
$ordinals = array_keys($attr_data['values']);
$ordinal = $ordinals[0];
return [
$attr_name,
$ordinal,
$attr_data['conversion'],
];
}
else {
return [
NULL,
NULL,
NULL,
];
}
}
/**
* Turn an ldap entry into a token array suitable for the t() function.
*
* @param ldap entry array $ldap_entry
* @param string prefix token prefix such as !,%,[
* @param string suffix token suffix such as ]
* @param $token_keys
* either an array of key names such as array('cn', 'dn') or string 'all' to return all tokens.
*
* @return token array suitable for t() functions of with lowercase keys as exemplified below
*
* $ldap_entry should be in form of single entry returned from ldap_search() function:
*
* 'dn' => 'cn=jdoe,ou=campus accounts,ou=toledo campus,dc=ad,dc=myuniversity,dc=edu',
* 'mail' => array( 0 => 'jdoe@myuniversity.edu', 'count' => 1),
* 'sAMAccountName' => array( 0 => 'jdoe', 'count' => 1),
* should return tokens such as:
*
* -- from dn attribute
* [cn] = jdoe
* [cn:0] = jdoe
* [cn:last] => jdoe
* [cn:reverse:0] = jdoe
* [ou] = campus accounts
* [ou:0] = campus accounts
* [ou:1] = toledo campus
* [ou:last] = toledo campus
* [ou:reverse:0] = toledo campus
* [ou:reverse:1] = campus accounts
* [dc] = ad
* [dc:0] = ad
* [dc:1] = myuniversity
* [dc:2] = edu
* [dc:last] = edu
* [dc:reverse:0] = edu
* [dc:reverse:1] = myuniversity
* [dc:reverse:2] = ad
*
* -- from other attributes
* [mail] = jdoe@myuniversity.edu
* [mail:0] = jdoe@myuniversity.edu
* [mail:last] = jdoe@myuniversity.edu
* [samaccountname] = jdoe
* [samaccountname:0] = jdoe
* [samaccountname:last] = jdoe
*
* [guid:0;base64_encode] = apply base64_encode() function to value
* [guid:0;bin2hex] = apply bin2hex() function to value
* [guid:0;msguid] = apply ldap_servers_msguid() function to value
* [guid:0;binary] = apply ldap_servers_binary() function to value. this is the most generic binary function
*/
function ldap_servers_token_tokenize_entry($ldap_entry, $token_keys = 'all', $pre = LDAP_SERVERS_TOKEN_PRE, $post = LDAP_SERVERS_TOKEN_POST) {
$detailed_watchdog_log = variable_get('ldap_help_watchdog_detail', 0);
$tokens = [];
$watchdog_tokens = [];
if (function_exists('debug_backtrace') && ($backtrace = debug_backtrace())) {
$watchdog_tokens['%calling_function'] = $backtrace[1]['function'];
}
if (!is_array($ldap_entry)) {
if ($detailed_watchdog_log) {
watchdog('ldap_servers', 'skipped tokenization of ldap entry because no ldap entry provided when called from %calling_function.', $watchdog_tokens, WATCHDOG_DEBUG);
}
// Empty array.
return $tokens;
}
// Add lowercase keyed entries to ldap array.
foreach ($ldap_entry as $key => $values) {
$ldap_entry[drupal_strtolower($key)] = $values;
}
// 1. tokenize dn
// escapes attribute values, need to be unescaped later.
$dn_parts = ldap_explode_dn($ldap_entry['dn'], 0);
unset($dn_parts['count']);
$parts_count = [];
$parts_last_value = [];
foreach ($dn_parts as $pair) {
list($attr_name, $attr_value) = explode('=', $pair);
$attr_value = ldap_pear_unescape_dn_value($attr_value);
try {
$attr_value = check_plain($attr_value);
} catch (Exception $e) {
if ($detailed_watchdog_log) {
$watchdog_tokens['%attr_name'] = $attr_name;
watchdog('ldap_servers', 'skipped tokenization of attribute %attr_name because the value would not pass check_plain function.', $watchdog_tokens, WATCHDOG_DEBUG);
}
// don't tokenize data that can't pass check_plain.
continue;
}
if (!isset($parts_count[$attr_name])) {
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . $post] = $attr_value;
$parts_count[$attr_name] = 0;
}
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . (int) $parts_count[$attr_name] . $post] = $attr_value;
$parts_last_value[$attr_name] = $attr_value;
$parts_count[$attr_name]++;
}
// Add the parts in reverse order to reflect the hierarchy.
foreach ($parts_count as $part => $count) {
$part = strtolower($part);
for ($i = 0; $i < $count; $i++) {
$reverse_position = $count - $i - 1;
$tokens[$pre . $part . LDAP_SERVERS_TOKEN_DEL . 'reverse' . LDAP_SERVERS_TOKEN_DEL . $reverse_position . $post] = $tokens[$pre . $part . LDAP_SERVERS_TOKEN_DEL . $i . $post];
}
}
foreach ($parts_count as $attr_name => $count) {
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . 'last' . $post] = $parts_last_value[$attr_name];
}
// Tokenize other attributes.
if ($token_keys == 'all') {
$token_keys = array_keys($ldap_entry);
$token_keys = array_filter($token_keys, "is_string");
foreach ($token_keys as $attr_name) {
$attr_value = $ldap_entry[$attr_name];
if (is_array($attr_value) && is_scalar($attr_value[0]) && $attr_value['count'] == 1) {
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . $post] = check_plain($attr_value[0]);
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . '0' . $post] = check_plain($attr_value[0]);
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . 'last' . $post] = check_plain($attr_value[0]);
}
elseif (is_array($attr_value) && $attr_value['count'] > 1) {
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . 'last' . $post] = check_plain($attr_value[$attr_value['count'] - 1]);
for ($i = 0; $i < $attr_value['count']; $i++) {
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . $i . $post] = check_plain($attr_value[$i]);
}
}
elseif (is_scalar($attr_value)) {
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . $post] = check_plain($attr_value);
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . '0' . $post] = check_plain($attr_value);
$tokens[$pre . ldap_server_massage_text($attr_name, 'attr_name', LDAP_SERVER_MASSAGE_TOKEN_REPLACE) . LDAP_SERVERS_TOKEN_DEL . 'last' . $post] = check_plain($attr_value);
}
}
}
else {
foreach ($token_keys as $full_token_key) {
// Token key = 'dn', 'mail', 'mail:0', 'mail:last', 'dept:1', 'guid:0' etc.
$value = NULL;
$conversion = FALSE;
$parts = explode(';', $full_token_key);
if (count($parts) == 2) {
$conversion = $parts[1];
$token_key = $parts[0];
}
else {
$token_key = $full_token_key;
}
$parts = explode(LDAP_SERVERS_TOKEN_DEL, $token_key);
$attr_name = drupal_strtolower($parts[0]);
$ordinal_key = isset($parts[1]) ? $parts[1] : 0;
$i = NULL;
// don't use empty() since a 0, "", etc value may be a desired value.
if ($attr_name == 'dn' || !isset($ldap_entry[$attr_name])) {
continue;
}
else {
$count = $ldap_entry[$attr_name]['count'];
if ($ordinal_key === 'last') {
$i = $count > 0 ? $count - 1 : 0;
$value = $ldap_entry[$attr_name][$i];
}
elseif (is_numeric($ordinal_key) || $ordinal_key == '0') {
$value = $ldap_entry[$attr_name][$ordinal_key];
}
else {
// don't add token if case not covered.
continue;
}
}
if ($conversion) {
switch ($conversion) {
case 'base64_encode':
$value = base64_encode($value);
break;
case 'bin2hex':
$value = bin2hex($value);
break;
case 'msguid':
$value = ldap_servers_msguid($value);
break;
case 'binary':
$value = ldap_servers_binary($value);
break;
}
}
$tokens[$pre . $full_token_key . $post] = $value;
if ($full_token_key != drupal_strtolower($full_token_key)) {
$tokens[$pre . drupal_strtolower($full_token_key) . $post] = $value;
}
}
}
// Include the dn. it will not be handled correctly by previous loops.
$tokens[$pre . 'dn' . $post] = check_plain($ldap_entry['dn']);
return $tokens;
}
/**
*
* @param drupal user object $user_account
* @param array or 'all' $token_keys
* 'all' signifies return
* all token/value pairs available; otherwise array lists
* token keys (e.g. property.name ...NOT [property.name])
* @param string $pre
* prefix of token.
* @param string $post
* suffix of token.
*
*
* @return should return token/value pairs in array such as
* 'status' => 1
* 'uid' => 17
*/
function ldap_servers_token_tokenize_user_account($user_account, $token_keys = 'all', $pre = LDAP_SERVERS_TOKEN_PRE, $post = LDAP_SERVERS_TOKEN_POST) {
$detailed_watchdog_log = variable_get('ldap_help_watchdog_detail', 0);
$tokens = [];
$user_entered_password_available = (bool) ldap_user_ldap_provision_pwd('get');
if ($token_keys == 'all') {
// Add lowercase keyed entries to ldap array.
foreach ((array) $user_account as $property_name => $value) {
if (is_scalar($value) && $property_name != 'password') {
$token_keys[] = 'property.' . $property_name;
if (drupal_strtolower($property_name) != $property_name) {
$token_keys[] = 'property.' . drupal_strtolower($property_name);
}
}
elseif (isset($user_account->{$attr_name}[LANGUAGE_NONE][0]['value']) && is_scalar($user_account->{$attr_name}[LANGUAGE_NONE][0]['value'])) {
$token_keys[] = 'field.' . $property_name;
if (drupal_strtolower($property_name) != $property_name) {
$token_keys[] = 'field.' . drupal_strtolower($property_name);
}
}
else {
// Field or property with no value, so no token can be generated.
}
}
$ldap_user_conf_admin = new LdapUserConfAdmin();
if ($ldap_user_conf_admin->setsLdapPassword) {
$token_keys[] = 'password.random';
$token_keys[] = 'password.user-random';
}
}
foreach ($token_keys as $token_key) {
$parts = explode('.', $token_key);
$attr_type = $parts[0];
$attr_name = $parts[1];
$attr_conversion = isset($parts[2]) ? $parts[2] : 'none';
$value = FALSE;
$skip = FALSE;
switch ($attr_type) {
case 'field':
$value = @is_scalar($user_account->{$attr_name}[LANGUAGE_NONE][0]['value']) ? $user_account->{$attr_name}[LANGUAGE_NONE][0]['value'] : '';
break;
case 'property':
$value = @is_scalar($user_account->{$attr_name}) ? $user_account->{$attr_name} : '';
break;
case 'password':
switch ($attr_name) {
case 'user':
case 'user-only':
$pwd = ldap_user_ldap_provision_pwd('get');
$value = $pwd ? $pwd : NULL;
break;
case 'user-random':
$pwd = ldap_user_ldap_provision_pwd('get');
$value = $pwd ? $pwd : user_password();
break;
case 'random':
$value = user_password();
break;
}
if (empty($value)) {
$skip = TRUE;
}
break;
}
if (!$skip) {
switch ($attr_conversion) {
case 'none':
break;
case 'to-md5':
$value = "{MD5}" . base64_encode(pack("H*", md5($value)));
break;
case 'to-lowercase':
$value = drupal_strtolower($value);
break;
}
$tokens[$pre . $token_key . $post] = $attr_type == 'password' ? $value : check_plain($value);
if ($token_key != drupal_strtolower($token_key)) {
$tokens[$pre . drupal_strtolower($token_key) . $post] = $attr_type == 'password' ? $value : check_plain($value);
}
}
}
return $tokens;
}
/**
* @param string $template
* in form [cn]@myuniversity.edu.
* @return array of all tokens in the template such as array('cn')
*/
function ldap_servers_token_tokens_needed_for_template($template, $pre = LDAP_SERVERS_TOKEN_PRE, $post = LDAP_SERVERS_TOKEN_POST) {
preg_match_all('/
\\[ # [ - pattern start
([^\\[\\]]*) # match $type not containing whitespace : [ or ]
\\] # ] - pattern end
/x', $template, $matches);
return @$matches[1];
}
/**
*
*/
function ldap_servers_token_show_sample_user_tokens($sid) {
$ldap_server = ldap_servers_get_servers($sid, 'all', TRUE);
$test_username = $ldap_server->testingDrupalUsername;
if (!$test_username || !($ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_SERVICE_ACCT || $ldap_server->bind_method == LDAP_SERVERS_BIND_METHOD_ANON)) {
return FALSE;
}
if ($ldap_user = $ldap_server
->userUserNameToExistingLdapEntry($test_username)) {
$table = theme('ldap_server_ldap_entry_table', [
'entry' => $ldap_user['attr'],
'username' => $test_username,
'dn' => $ldap_user['dn'],
]);
}
else {
$table = '<p>' . t('No sample user data found') . '</p>';
}
return $table;
}
Functions
Name | Description |
---|---|
ldap_servers_make_token | |
ldap_servers_parse_user_attr_name | |
ldap_servers_token_extract_attributes | |
ldap_servers_token_extract_parts | |
ldap_servers_token_replace | User_account. |
ldap_servers_token_show_sample_user_tokens | |
ldap_servers_token_tokenize_entry | Turn an ldap entry into a token array suitable for the t() function. |
ldap_servers_token_tokenize_user_account | |
ldap_servers_token_tokens_needed_for_template |