ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
SimpleSAML_Auth_LDAP Class Reference
+ Collaboration diagram for SimpleSAML_Auth_LDAP:

Public Member Functions

 __construct ($hostname, $enable_tls=true, $debug=false, $timeout=0, $port=389, $referrals=true)
 Private constructor restricts instantiation to getInstance(). More...
 
 searchfordn ($base, $attribute, $value, $allowZeroHits=false, $searchFilter=null, $scope='subtree')
 Search for a DN. More...
 
 searchformultiple ($bases, $filters, $attributes=array(), $and=true, $escape=true, $scope='subtree')
 This method was created specifically for the ldap:AttributeAddUsersGroups->searchActiveDirectory() method, but could be used for other LDAP search needs. More...
 
 bind ($dn, $password, array $sasl_args=null)
 Bind to LDAP with a specific DN and password. More...
 
 setOption ($option, $value)
 Applies an LDAP option to the current connection. More...
 
 getAttributes ($dn, $attributes=null, $maxsize=null)
 Search a given DN for attributes, and return the resulting associative array. More...
 
 validate ($config, $username, $password=null)
 Enter description here... More...
 
 whoami ($searchBase, $searchAttributes)
 ldap_exop_whoami accessor, if available. More...
 

Static Public Member Functions

static escape_filter_value ($values=array(), $singleValue=true)
 Borrowed function from PEAR:LDAP. More...
 
static asc2hex32 ($string)
 Borrowed function from PEAR:LDAP. More...
 

Protected Attributes

 $ldap = null
 
 $authz_id = null
 LDAP user: authz_id if SASL is in use, binding dn otherwise. More...
 
 $timeout = 0
 

Private Member Functions

 makeException ($description, $type=null)
 Convenience method to create an LDAPException as well as log the description. More...
 
 search ($base, $attribute, $value, $searchFilter=null, $scope="subtree")
 Search for DN from a single base. More...
 
 authzid_to_dn ($searchBase, $searchAttributes, $authz_id)
 Convert SASL authz_id into a DN. More...
 

Detailed Description

Definition at line 25 of file LDAP.php.

Constructor & Destructor Documentation

◆ __construct()

SimpleSAML_Auth_LDAP::__construct (   $hostname,
  $enable_tls = true,
  $debug = false,
  $timeout = 0,
  $port = 389,
  $referrals = true 
)

Private constructor restricts instantiation to getInstance().

Parameters
string$hostname
bool$enable_tls
bool$debug
int$timeout
int$port
bool$referrals

Definition at line 56 of file LDAP.php.

References $timeout, SimpleSAML\Logger\debug(), ERR_INTERNAL, makeException(), and SimpleSAML\Logger\warning().

57  {
58  // Debug
59  SimpleSAML\Logger::debug('Library - LDAP __construct(): Setup LDAP with '.
60  'host=\''.$hostname.
61  '\', tls='.var_export($enable_tls, true).
62  ', debug='.var_export($debug, true).
63  ', timeout='.var_export($timeout, true).
64  ', referrals='.var_export($referrals, true));
65 
66  /*
67  * Set debug level before calling connect. Note that this passes
68  * NULL to ldap_set_option, which is an undocumented feature.
69  *
70  * OpenLDAP 2.x.x or Netscape Directory SDK x.x needed for this option.
71  */
72  if ($debug && !ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7)) {
73  SimpleSAML\Logger::warning('Library - LDAP __construct(): Unable to set debug level (LDAP_OPT_DEBUG_LEVEL) to 7');
74  }
75 
76  /*
77  * Prepare a connection for to this LDAP server. Note that this function
78  * doesn't actually connect to the server.
79  */
80  $this->ldap = @ldap_connect($hostname, $port);
81  if ($this->ldap === false) {
82  throw $this->makeException('Library - LDAP __construct(): Unable to connect to \''.$hostname.'\'', ERR_INTERNAL);
83  }
84 
85  // Enable LDAP protocol version 3
86  if (!@ldap_set_option($this->ldap, LDAP_OPT_PROTOCOL_VERSION, 3)) {
87  throw $this->makeException('Library - LDAP __construct(): Failed to set LDAP Protocol version (LDAP_OPT_PROTOCOL_VERSION) to 3', ERR_INTERNAL);
88  }
89 
90  // Set referral option
91  if (!@ldap_set_option($this->ldap, LDAP_OPT_REFERRALS, $referrals)) {
92  throw $this->makeException('Library - LDAP __construct(): Failed to set LDAP Referrals (LDAP_OPT_REFERRALS) to '.$referrals, ERR_INTERNAL);
93  }
94 
95  // Set timeouts, if supported
96  // (OpenLDAP 2.x.x or Netscape Directory SDK x.x needed)
97  $this->timeout = $timeout;
98  if ($timeout > 0) {
99  if (!@ldap_set_option($this->ldap, LDAP_OPT_NETWORK_TIMEOUT, $timeout)) {
100  SimpleSAML\Logger::warning('Library - LDAP __construct(): Unable to set timeouts (LDAP_OPT_NETWORK_TIMEOUT) to '.$timeout);
101  }
102  if (!@ldap_set_option($this->ldap, LDAP_OPT_TIMELIMIT, $timeout)) {
103  SimpleSAML\Logger::warning('Library - LDAP __construct(): Unable to set timeouts (LDAP_OPT_TIMELIMIT) to '.$timeout);
104  }
105  }
106 
107  // Enable TLS, if needed
108  if (stripos($hostname, "ldaps:") === false && $enable_tls) {
109  if (!@ldap_start_tls($this->ldap)) {
110  throw $this->makeException('Library - LDAP __construct(): Unable to force TLS', ERR_INTERNAL);
111  }
112  }
113  }
static debug($string)
Definition: Logger.php:211
static warning($string)
Definition: Logger.php:177
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
__construct($hostname, $enable_tls=true, $debug=false, $timeout=0, $port=389, $referrals=true)
Private constructor restricts instantiation to getInstance().
Definition: LDAP.php:56
const ERR_INTERNAL
Constants defining possible errors.
Definition: LDAP.php:6
+ Here is the call graph for this function:

Member Function Documentation

◆ asc2hex32()

static SimpleSAML_Auth_LDAP::asc2hex32 (   $string)
static

Borrowed function from PEAR:LDAP.

Converts all ASCII chars < 32 to "\HEX"

Parameters
string$stringString to convert
Returns
string

Definition at line 704 of file LDAP.php.

References $i.

705  {
706  for ($i = 0; $i < strlen($string); $i++) {
707  $char = substr($string, $i, 1);
708  if (ord($char) < 32) {
709  $hex = dechex(ord($char));
710  if (strlen($hex) == 1) {
711  $hex = '0'.$hex;
712  }
713  $string = str_replace($char, '\\'.$hex, $string);
714  }
715  }
716  return $string;
717  }
$i
Definition: disco.tpl.php:19

◆ authzid_to_dn()

SimpleSAML_Auth_LDAP::authzid_to_dn (   $searchBase,
  $searchAttributes,
  $authz_id 
)
private

Convert SASL authz_id into a DN.

Definition at line 722 of file LDAP.php.

References $authz_id, and searchfordn().

Referenced by whoami().

723  {
724  if (preg_match("/^dn:/", $authz_id)) {
725  return preg_replace("/^dn:/", "", $authz_id);
726  }
727 
728  if (preg_match("/^u:/", $authz_id)) {
729  return $this->searchfordn(
730  $searchBase,
731  $searchAttributes,
732  preg_replace("/^u:/", "", $authz_id)
733  );
734  }
735  return $authz_id;
736  }
searchfordn($base, $attribute, $value, $allowZeroHits=false, $searchFilter=null, $scope='subtree')
Search for a DN.
Definition: LDAP.php:291
$authz_id
LDAP user: authz_id if SASL is in use, binding dn otherwise.
Definition: LDAP.php:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ bind()

SimpleSAML_Auth_LDAP::bind (   $dn,
  $password,
array  $sasl_args = null 
)

Bind to LDAP with a specific DN and password.

Simple wrapper around ldap_bind() with some additional logging.

Parameters
string$dnThe DN used.
string$passwordThe password used.
array$sasl_argsArray of SASL options for SASL bind
Returns
bool Returns TRUE if successful, FALSE if LDAP_INVALID_CREDENTIALS, LDAP_X_PROXY_AUTHZ_FAILURE, LDAP_INAPPROPRIATE_AUTH, LDAP_INSUFFICIENT_ACCESS
Exceptions
SimpleSAML_Error_Exceptionon other errors

Definition at line 446 of file LDAP.php.

References $authz_id, $password, SimpleSAML\Logger\debug(), and makeException().

Referenced by validate().

447  {
448  if ($sasl_args != null) {
449  if (!function_exists('ldap_sasl_bind')) {
450  $ex_msg = 'Library - missing SASL support';
451  throw $this->makeException($ex_msg);
452  }
453 
454  // SASL Bind, with error handling
455  $authz_id = $sasl_args['authz_id'];
456  $error = @ldap_sasl_bind(
457  $this->ldap,
458  $dn,
459  $password,
460  $sasl_args['mech'],
461  $sasl_args['realm'],
462  $sasl_args['authc_id'],
463  $sasl_args['authz_id'],
464  $sasl_args['props']
465  );
466  } else {
467  // Simple Bind, with error handling
468  $authz_id = $dn;
469  $error = @ldap_bind($this->ldap, $dn, $password);
470  }
471 
472  if ($error === true) {
473  // Good
474  $this->authz_id = $authz_id;
475  SimpleSAML\Logger::debug('Library - LDAP bind(): Bind successful with DN \''.$dn.'\'');
476  return true;
477  }
478 
479  /* Handle errors
480  * LDAP_INVALID_CREDENTIALS
481  * LDAP_INSUFFICIENT_ACCESS */
482  switch (ldap_errno($this->ldap)) {
483  case 32: // LDAP_NO_SUCH_OBJECT
484  // no break
485  case 47: // LDAP_X_PROXY_AUTHZ_FAILURE
486  // no break
487  case 48: // LDAP_INAPPROPRIATE_AUTH
488  // no break
489  case 49: // LDAP_INVALID_CREDENTIALS
490  // no break
491  case 50: // LDAP_INSUFFICIENT_ACCESS
492  return false;
493  default:
494  break;
495  }
496 
497  // Bad
498  throw $this->makeException('Library - LDAP bind(): Bind failed with DN \''.$dn.'\'');
499  }
static debug($string)
Definition: Logger.php:211
$authz_id
LDAP user: authz_id if SASL is in use, binding dn otherwise.
Definition: LDAP.php:37
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
$password
Definition: cron.php:14
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ escape_filter_value()

static SimpleSAML_Auth_LDAP::escape_filter_value (   $values = array(),
  $singleValue = true 
)
static

Borrowed function from PEAR:LDAP.

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.

Parameters
string | array$valuesArray of values to escape
Returns
array Array $values, but escaped

Definition at line 666 of file LDAP.php.

References $key, $values, and SimpleSAML\Utils\Arrays\arrayize().

Referenced by sspmod_ldap_Auth_Process_AttributeAddFromLDAP\process(), and searchformultiple().

667  {
668  // Parameter validation
670 
671  foreach ($values as $key => $val) {
672  // Escaping of filter meta characters
673  $val = str_replace('\\', '\5c', $val);
674  $val = str_replace('*', '\2a', $val);
675  $val = str_replace('(', '\28', $val);
676  $val = str_replace(')', '\29', $val);
677 
678  // ASCII < 32 escaping
679  $val = self::asc2hex32($val);
680 
681  if (null === $val) {
682  $val = '\0'; // apply escaped "null" if string is empty
683  }
684 
685  $values[$key] = $val;
686  }
687  if ($singleValue) {
688  return $values[0];
689  }
690  return $values;
691  }
static arrayize($data, $index=0)
Put a non-array variable into an array.
Definition: Arrays.php:24
$values
$key
Definition: croninfo.php:18
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getAttributes()

SimpleSAML_Auth_LDAP::getAttributes (   $dn,
  $attributes = null,
  $maxsize = null 
)

Search a given DN for attributes, and return the resulting associative array.

Parameters
string$dnThe DN of an element.
string | array$attributesThe names of the attribute(s) to retrieve. Defaults to NULL; that is, all available attributes. Note that this is not very effective.
int$maxsizeThe maximum size of any attribute's value(s). If exceeded, the attribute will not be returned.
Returns
array The array of attributes and their values.
See also
http://no.php.net/manual/en/function.ldap-read.php

Definition at line 545 of file LDAP.php.

References $attributes, $description, $i, $name, $result, $values, SimpleSAML\Logger\debug(), makeException(), size, and SimpleSAML\Logger\warning().

Referenced by validate().

546  {
547  // Preparations, including a pretty debug message...
548  $description = 'all attributes';
549  if (is_array($attributes)) {
550  $description = '\''.join(',', $attributes).'\'';
551  } else {
552  // Get all attributes...
553  // TODO: Verify that this originally was the intended behaviour. Could $attributes be a string?
554  $attributes = array();
555  }
556  SimpleSAML\Logger::debug('Library - LDAP getAttributes(): Getting '.$description.' from DN \''.$dn.'\'');
557 
558  // Attempt to get attributes
559  // TODO: Should aliases be dereferenced?
560  $result = @ldap_read($this->ldap, $dn, 'objectClass=*', $attributes, 0, 0, $this->timeout);
561  if ($result === false) {
562  throw $this->makeException('Library - LDAP getAttributes(): Failed to get attributes from DN \''.$dn.'\'');
563  }
564  $entry = @ldap_first_entry($this->ldap, $result);
565  if ($entry === false) {
566  throw $this->makeException('Library - LDAP getAttributes(): Could not get first entry from DN \''.$dn.'\'');
567  }
568  $attributes = @ldap_get_attributes($this->ldap, $entry); // Recycling $attributes... Possibly bad practice.
569  if ($attributes === false) {
570  throw $this->makeException('Library - LDAP getAttributes(): Could not get attributes of first entry from DN \''.$dn.'\'');
571  }
572 
573  // Parsing each found attribute into our result set
574  $result = array(); // Recycling $result... Possibly bad practice.
575  for ($i = 0; $i < $attributes['count']; $i++) {
576  // Ignore attributes that exceed the maximum allowed size
577  $name = $attributes[$i];
578  $attribute = $attributes[$name];
579 
580  // Deciding whether to base64 encode
581  $values = array();
582  for ($j = 0; $j < $attribute['count']; $j++) {
583  $value = $attribute[$j];
584 
585  if (!empty($maxsize) && strlen($value) > $maxsize) {
586  // Ignoring and warning
587  SimpleSAML\Logger::warning('Library - LDAP getAttributes(): Attribute \''.
588  $name.'\' exceeded maximum allowed size by '.(strlen($value) - $maxsize));
589  continue;
590  }
591 
592  // Base64 encode binary attributes
593  if (strtolower($name) === 'jpegphoto' || strtolower($name) === 'objectguid' || strtolower($name) === 'ms-ds-consistencyguid') {
594  $values[] = base64_encode($value);
595  } else {
596  $values[] = $value;
597  }
598  }
599 
600  // Adding
601  $result[$name] = $values;
602  }
603 
604  // We're done
605  SimpleSAML\Logger::debug('Library - LDAP getAttributes(): Found attributes \'('.join(',', array_keys($result)).')\'');
606  return $result;
607  }
$result
static debug($string)
Definition: Logger.php:211
Attribute-related utility methods.
static warning($string)
Definition: Logger.php:177
$values
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
if(array_key_exists('yes', $_REQUEST)) $attributes
Definition: getconsent.php:85
font size
Definition: langcheck.php:162
$i
Definition: disco.tpl.php:19
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ makeException()

SimpleSAML_Auth_LDAP::makeException (   $description,
  $type = null 
)
private

Convenience method to create an LDAPException as well as log the description.

Parameters
string$descriptionThe exception's description
Returns
Exception

Definition at line 124 of file LDAP.php.

References $description, $type, SimpleSAML\Logger\error(), SimpleSAML\Logger\info(), and SimpleSAML\Logger\warning().

Referenced by __construct(), bind(), getAttributes(), search(), searchfordn(), searchformultiple(), setOption(), and whoami().

125  {
126  $errNo = 0x00;
127 
128  // Log LDAP code and description, if possible
129  if (empty($this->ldap)) {
131  } else {
132  $errNo = @ldap_errno($this->ldap);
133  }
134 
135  // Decide exception type and return
136  if ($type) {
137  if ($errNo !== 0) {
138  // Only log real LDAP errors; not success
139  SimpleSAML\Logger::error($description.'; cause: \''.ldap_error($this->ldap).'\' (0x'.dechex($errNo).')');
140  } else {
141  SimpleSAML\Logger::error($description);
142  }
143 
144  switch ($type) {
145  case ERR_INTERNAL:// 1 - ExInternal
146  return new SimpleSAML_Error_Exception($description, $errNo);
147  case ERR_NO_USER:// 2 - ExUserNotFound
148  return new SimpleSAML_Error_UserNotFound($description, $errNo);
149  case ERR_WRONG_PW:// 3 - ExInvalidCredential
150  return new SimpleSAML_Error_InvalidCredential($description, $errNo);
151  case ERR_AS_DATA_INCONSIST:// 4 - ExAsDataInconsist
152  return new SimpleSAML_Error_AuthSource('ldap', $description);
153  case ERR_AS_INTERNAL:// 5 - ExAsInternal
154  return new SimpleSAML_Error_AuthSource('ldap', $description);
155  }
156  } else {
157  if ($errNo !== 0) {
158  $description .= '; cause: \''.ldap_error($this->ldap).'\' (0x'.dechex($errNo).')';
159  if (@ldap_get_option($this->ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extendedError) && !empty($extendedError)) {
160  $description .= '; additional: \''.$extendedError.'\'';
161  }
162  }
163  switch ($errNo) {
164  case 0x20://LDAP_NO_SUCH_OBJECT
166  return new SimpleSAML_Error_UserNotFound($description, $errNo);
167  case 0x31://LDAP_INVALID_CREDENTIALS
170  case -1://NO_SERVER_CONNECTION
172  return new SimpleSAML_Error_AuthSource('ldap', $description);
173  default:
175  return new SimpleSAML_Error_AuthSource('ldap', $description);
176  }
177  }
178  }
$type
static info($string)
Definition: Logger.php:199
static warning($string)
Definition: Logger.php:177
static error($string)
Definition: Logger.php:166
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ search()

SimpleSAML_Auth_LDAP::search (   $base,
  $attribute,
  $value,
  $searchFilter = null,
  $scope = "subtree" 
)
private

Search for DN from a single base.

Parameters
string$baseIndication of root of subtree to search
string | array$attributeThe attribute name(s) to search for.
string$valueThe attribute value to search for. Additional search filter
string | null$searchFilterThe scope of the search
string$scope
Returns
string The DN of the resulting found element.
Exceptions
SimpleSAML_Error_Exceptionif:
  • Attribute parameter is wrong type
SimpleSAML_Error_AuthSourceif:
  • Not able to connect to LDAP server
  • False search result
  • Count return false
  • Searche found more than one result
  • Failed to get first entry from result
  • Failed to get DN for entry
SimpleSAML_Error_UserNotFoundif:
  • Zero entries were found

Definition at line 208 of file LDAP.php.

References $base, $result, SimpleSAML\Logger\debug(), ERR_AS_DATA_INCONSIST, ERR_NO_USER, and makeException().

Referenced by searchfordn().

209  {
210  // Create the search filter
211  $attribute = self::escape_filter_value($attribute, false);
212  $value = self::escape_filter_value($value, true);
213  $filter = '';
214  foreach ($attribute as $attr) {
215  $filter .= '('.$attr.'='.$value.')';
216  }
217  $filter = '(|'.$filter.')';
218 
219  // Append LDAP filters if defined
220  if ($searchFilter != null) {
221  $filter = "(&".$filter."".$searchFilter.")";
222  }
223 
224  // Search using generated filter
225  SimpleSAML\Logger::debug('Library - LDAP search(): Searching base ('.$scope.') \''.$base.'\' for \''.$filter.'\'');
226  if ($scope === 'base') {
227  $result = @ldap_read($this->ldap, $base, $filter, array(), 0, 0, $this->timeout, LDAP_DEREF_NEVER);
228  } else if ($scope === 'onelevel') {
229  $result = @ldap_list($this->ldap, $base, $filter, array(), 0, 0, $this->timeout, LDAP_DEREF_NEVER);
230  } else {
231  $result = @ldap_search($this->ldap, $base, $filter, array(), 0, 0, $this->timeout, LDAP_DEREF_NEVER);
232  }
233 
234  if ($result === false) {
235  throw $this->makeException('Library - LDAP search(): Failed search on base \''.$base.'\' for \''.$filter.'\'');
236  }
237 
238  // Sanity checks on search results
239  $count = @ldap_count_entries($this->ldap, $result);
240  if ($count === false) {
241  throw $this->makeException('Library - LDAP search(): Failed to get number of entries returned');
242  } elseif ($count > 1) {
243  // More than one entry is found. External error
244  throw $this->makeException('Library - LDAP search(): Found '.$count.' entries searching base \''.$base.'\' for \''.$filter.'\'', ERR_AS_DATA_INCONSIST);
245  } elseif ($count === 0) {
246  // No entry is fond => wrong username is given (or not registered in the catalogue). User error
247  throw $this->makeException('Library - LDAP search(): Found no entries searching base \''.$base.'\' for \''.$filter.'\'', ERR_NO_USER);
248  }
249 
250 
251  // Resolve the DN from the search result
252  $entry = @ldap_first_entry($this->ldap, $result);
253  if ($entry === false) {
254  throw $this->makeException('Library - LDAP search(): Unable to retrieve result after searching base \''.$base.'\' for \''.$filter.'\'');
255  }
256  $dn = @ldap_get_dn($this->ldap, $entry);
257  if ($dn === false) {
258  throw $this->makeException('Library - LDAP search(): Unable to get DN after searching base \''.$base.'\' for \''.$filter.'\'');
259  }
260  return $dn;
261  }
$result
const ERR_NO_USER
Definition: LDAP.php:7
static debug($string)
Definition: Logger.php:211
const ERR_AS_DATA_INCONSIST
Definition: LDAP.php:9
$base
Definition: index.php:4
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ searchfordn()

SimpleSAML_Auth_LDAP::searchfordn (   $base,
  $attribute,
  $value,
  $allowZeroHits = false,
  $searchFilter = null,
  $scope = 'subtree' 
)

Search for a DN.

Parameters
string | array$baseThe base, or bases, which to search from.
string | array$attributeThe attribute name(s) searched for.
string$valueThe attribute value searched for.
bool$allowZeroHitsDetermines if the method will throw an exception if no hits are found. Defaults to FALSE.
string | null$searchFilterAdditional searchFilter to be added to the (attribute=value) filter
string$scopeThe scope of the search
Returns
string The DN of the matching element, if found. If no element was found and $allowZeroHits is set to FALSE, an exception will be thrown; otherwise NULL will be returned.
Exceptions
SimpleSAML_Error_AuthSourceif:
  • LDAP search encounter some problems when searching cataloge
  • Not able to connect to LDAP server
SimpleSAML_Error_UserNotFoundif:
  • $allowZeroHits is FALSE and no result is found

Definition at line 291 of file LDAP.php.

References $base, $current, $result, SimpleSAML\Utils\Arrays\arrayize(), SimpleSAML\Logger\debug(), makeException(), and search().

Referenced by authzid_to_dn(), and validate().

292  {
293  // Traverse all search bases, returning DN if found
295  foreach ($bases as $current) {
296  try {
297  // Single base search
298  $result = $this->search($current, $attribute, $value, $searchFilter, $scope);
299 
300  // We don't hawe to look any futher if user is found
301  if (!empty($result)) {
302  return $result;
303  }
304  // If search failed, attempt the other base DNs
305  } catch (SimpleSAML_Error_UserNotFound $e) {
306  // Just continue searching
307  }
308  }
309  // Decide what to do for zero entries
310  SimpleSAML\Logger::debug('Library - LDAP searchfordn(): No entries found');
311  if ($allowZeroHits) {
312  // Zero hits allowed
313  return null;
314  } else {
315  // Zero hits not allowed
316  throw $this->makeException('Library - LDAP searchfordn(): LDAP search returned zero entries for filter \'('.
317  join(' | ', $attribute).' = '.$value.')\' on base(s) \'('.join(' & ', $bases).')\'', 2);
318  }
319  }
$result
static arrayize($data, $index=0)
Put a non-array variable into an array.
Definition: Arrays.php:24
static debug($string)
Definition: Logger.php:211
$base
Definition: index.php:4
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
search($base, $attribute, $value, $searchFilter=null, $scope="subtree")
Search for DN from a single base.
Definition: LDAP.php:208
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ searchformultiple()

SimpleSAML_Auth_LDAP::searchformultiple (   $bases,
  $filters,
  $attributes = array(),
  $and = true,
  $escape = true,
  $scope = 'subtree' 
)

This method was created specifically for the ldap:AttributeAddUsersGroups->searchActiveDirectory() method, but could be used for other LDAP search needs.

It will search LDAP and return all the entries.

Exceptions
Exception
Parameters
string | array$bases
string | array$filtersArray of 'attribute' => 'values' to be combined into the filter, or a raw filter string
string | array$attributesArray of attributes requested from LDAP
bool$andIf multiple filters defined, then either bind them with & or |
bool$escapeWeather to escape the filter values or not
string$scopeThe scope of the search
Returns
array

Definition at line 335 of file LDAP.php.

References $attributes, $base, $i, $name, $result, $results, ERR_INTERNAL, ERR_NO_USER, escape_filter_value(), and makeException().

336  {
337  // Escape the filter values, if requested
338  if ($escape) {
339  $filters = $this->escape_filter_value($filters, false);
340  }
341 
342  // Build search filter
343  $filter = '';
344  if (is_array($filters)) {
345  foreach ($filters as $attribute => $value) {
346  $filter .= "($attribute=$value)";
347  }
348  if (count($filters) > 1) {
349  $filter = ($and ? '(&' : '(|').$filter.')';
350  }
351  } elseif (is_string($filters)) {
352  $filter = $filters;
353  }
354 
355  // Verify filter was created
356  if ($filter == '' || $filter == '(=)') {
357  throw $this->makeException('ldap:LdapConnection->search_manual : No search filters defined', ERR_INTERNAL);
358  }
359 
360  // Verify at least one base was passed
361  $bases = (array) $bases;
362  if (empty($bases)) {
363  throw $this->makeException('ldap:LdapConnection->search_manual : No base DNs were passed', ERR_INTERNAL);
364  }
365 
366  // Search each base until result is found
367  $result = false;
368  foreach ($bases as $base) {
369  if ($scope === 'base') {
370  $result = @ldap_read($this->ldap, $base, $filter, $attributes, 0, 0, $this->timeout);
371  } else if ($scope === 'onelevel') {
372  $result = @ldap_list($this->ldap, $base, $filter, $attributes, 0, 0, $this->timeout);
373  } else {
374  $result = @ldap_search($this->ldap, $base, $filter, $attributes, 0, 0, $this->timeout);
375  }
376 
377  if ($result !== false && @ldap_count_entries($this->ldap, $result) > 0) {
378  break;
379  }
380  }
381 
382  // Verify that a result was found in one of the bases
383  if ($result === false) {
384  throw $this->makeException(
385  'ldap:LdapConnection->search_manual : Failed to search LDAP using base(s) ['.
386  implode('; ', $bases).'] with filter ['.$filter.']. LDAP error ['.
387  ldap_error($this->ldap).']'
388  );
389  } elseif (@ldap_count_entries($this->ldap, $result) < 1) {
390  throw $this->makeException(
391  'ldap:LdapConnection->search_manual : No entries found in LDAP using base(s) ['.
392  implode('; ', $bases).'] with filter ['.$filter.']',
394  );
395  }
396 
397  // Get all results
398  $results = ldap_get_entries($this->ldap, $result);
399  if ($results === false) {
400  throw $this->makeException(
401  'ldap:LdapConnection->search_manual : Unable to retrieve entries from search results'
402  );
403  }
404 
405  // parse each entry and process its attributes
406  for ($i = 0; $i < $results['count']; $i++) {
407  $entry = $results[$i];
408 
409  // iterate over the attributes of the entry
410  for ($j = 0; $j < $entry['count']; $j++) {
411  $name = $entry[$j];
412  $attribute = $entry[$name];
413 
414  // decide whether to base64 encode or not
415  for ($k = 0; $k < $attribute['count']; $k++) {
416  // base64 encode binary attributes
417  if (strtolower($name) === 'jpegphoto' || strtolower($name) === 'objectguid') {
418  $results[$i][$name][$k] = base64_encode($attribute[$k]);
419  }
420  }
421  }
422  }
423 
424  // Remove the count and return
425  unset($results['count']);
426  return $results;
427  }
$result
const ERR_NO_USER
Definition: LDAP.php:7
static escape_filter_value($values=array(), $singleValue=true)
Borrowed function from PEAR:LDAP.
Definition: LDAP.php:666
$base
Definition: index.php:4
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
if(array_key_exists('yes', $_REQUEST)) $attributes
Definition: getconsent.php:85
$results
Definition: svg-scanner.php:47
$i
Definition: disco.tpl.php:19
const ERR_INTERNAL
Constants defining possible errors.
Definition: LDAP.php:6
+ Here is the call graph for this function:

◆ setOption()

SimpleSAML_Auth_LDAP::setOption (   $option,
  $value 
)

Applies an LDAP option to the current connection.

Exceptions
Exception
Parameters
$option
$value
Returns
void

Definition at line 510 of file LDAP.php.

References SimpleSAML\Logger\debug(), ERR_INTERNAL, and makeException().

511  {
512  // Attempt to set the LDAP option
513  if (!@ldap_set_option($this->ldap, $option, $value)) {
514  throw $this->makeException(
515  'ldap:LdapConnection->setOption : Failed to set LDAP option ['.
516  $option.'] with the value ['.$value.'] error: '.ldap_error($this->ldap),
518  );
519  }
520 
521  // Log debug message
523  'ldap:LdapConnection->setOption : Set the LDAP option ['.
524  $option.'] with the value ['.$value.']'
525  );
526  }
static debug($string)
Definition: Logger.php:211
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
const ERR_INTERNAL
Constants defining possible errors.
Definition: LDAP.php:6
+ Here is the call graph for this function:

◆ validate()

SimpleSAML_Auth_LDAP::validate (   $config,
  $username,
  $password = null 
)

Enter description here...

Parameters
array$config
string$username
string$password
Returns
array|bool

Definition at line 618 of file LDAP.php.

References $attributes, $config, $password, bind(), getAttributes(), SimpleSAML\Logger\info(), and searchfordn().

Referenced by sspmod_cas_Auth_Source_CAS\finalStep().

619  {
620  /* Escape any characters with a special meaning in LDAP. The following
621  * characters have a special meaning (according to RFC 2253):
622  * ',', '+', '"', '\', '<', '>', ';', '*'
623  * These characters are escaped by prefixing them with '\'.
624  */
625  $username = addcslashes($username, ',+"\\<>;*');
626 
627  if (isset($config['priv_user_dn'])) {
628  $this->bind($config['priv_user_dn'], $config['priv_user_pw']);
629  }
630  if (isset($config['dnpattern'])) {
631  $dn = str_replace('%username%', $username, $config['dnpattern']);
632  } else {
633  $dn = $this->searchfordn($config['searchbase'], $config['searchattributes'], $username);
634  }
635 
636  if ($password !== null) { // checking users credentials ... assuming below that she may read her own attributes ...
637  // escape characters with a special meaning, also in the password
638  $password = addcslashes($password, ',+"\\<>;*');
639  if (!$this->bind($dn, $password)) {
640  SimpleSAML\Logger::info('Library - LDAP validate(): Failed to authenticate \''.$username.'\' using DN \''.$dn.'\'');
641  return false;
642  }
643  }
644 
645  /*
646  * Retrieve attributes from LDAP
647  */
648  $attributes = $this->getAttributes($dn, $config['attributes']);
649  return $attributes;
650  }
$config
Definition: bootstrap.php:15
static info($string)
Definition: Logger.php:199
searchfordn($base, $attribute, $value, $allowZeroHits=false, $searchFilter=null, $scope='subtree')
Search for a DN.
Definition: LDAP.php:291
if(array_key_exists('yes', $_REQUEST)) $attributes
Definition: getconsent.php:85
getAttributes($dn, $attributes=null, $maxsize=null)
Search a given DN for attributes, and return the resulting associative array.
Definition: LDAP.php:545
$password
Definition: cron.php:14
bind($dn, $password, array $sasl_args=null)
Bind to LDAP with a specific DN and password.
Definition: LDAP.php:446
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ whoami()

SimpleSAML_Auth_LDAP::whoami (   $searchBase,
  $searchAttributes 
)

ldap_exop_whoami accessor, if available.

Use requested authz_id otherwise.

ldap_exop_whoami() has been provided as a third party patch that waited several years to get its way upstream: http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/databases/php-ldap/files

When it was integrated into PHP repository, the function prototype was changed, The new prototype was used in third party patch for PHP 7.0 and 7.1, hence the version test below.

Definition at line 750 of file LDAP.php.

References $authz_id, authzid_to_dn(), and makeException().

751  {
752  $authz_id = '';
753  if (function_exists('ldap_exop_whoami')) {
754  if (version_compare(phpversion(), '7', '<')) {
755  if (ldap_exop_whoami($this->ldap, $authz_id) !== true) {
756  throw $this->makeException('LDAP whoami exop failure');
757  }
758  } else {
759  if (($authz_id = ldap_exop_whoami($this->ldap)) === false) {
760  throw $this->makeException('LDAP whoami exop failure');
761  }
762  }
763  } else {
765  }
766 
767  $dn = $this->authzid_to_dn($searchBase, $searchAttributes, $authz_id);
768 
769  if (!isset($dn) || ($dn == '')) {
770  throw $this->makeException('Cannot figure userID');
771  }
772 
773  return $dn;
774  }
authzid_to_dn($searchBase, $searchAttributes, $authz_id)
Convert SASL authz_id into a DN.
Definition: LDAP.php:722
$authz_id
LDAP user: authz_id if SASL is in use, binding dn otherwise.
Definition: LDAP.php:37
makeException($description, $type=null)
Convenience method to create an LDAPException as well as log the description.
Definition: LDAP.php:124
+ Here is the call graph for this function:

Field Documentation

◆ $authz_id

SimpleSAML_Auth_LDAP::$authz_id = null
protected

LDAP user: authz_id if SASL is in use, binding dn otherwise.

Definition at line 37 of file LDAP.php.

Referenced by authzid_to_dn(), bind(), and whoami().

◆ $ldap

SimpleSAML_Auth_LDAP::$ldap = null
protected

Definition at line 32 of file LDAP.php.

◆ $timeout

SimpleSAML_Auth_LDAP::$timeout = 0
protected

Definition at line 44 of file LDAP.php.

Referenced by __construct().


The documentation for this class was generated from the following file: