ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
Auth_Container_LDAP Class Reference
+ Inheritance diagram for Auth_Container_LDAP:
+ Collaboration diagram for Auth_Container_LDAP:

Public Member Functions

 Auth_Container_LDAP ($params)
 Constructor of the container class.
 _prepare ()
 Prepare LDAP connection.
 _connect ()
 Connect to the LDAP server using the global options.
 _disconnect ()
 Disconnects (unbinds) from ldap server.
 _getBaseDN ()
 Tries to find Basedn via namingContext Attribute.
 _isValidLink ()
 determines whether there is a valid ldap conenction or not
 _setDefaults ()
 Set some default options.
 _parseOptions ($array)
 Parse options passed to the container class.
 _setV12OptionsToV13 ($array)
 Adapt deprecated options from Auth 1.2 LDAP to Auth 1.3 LDAP.
 _scope2function ($scope)
 Get search function for scope.
 fetchData ($username, $password)
 Fetch data from LDAP server.
 checkGroup ($user)
 Validate group membership.
 _quoteFilterString ($filter_str)
 Escapes LDAP filter special characters as defined in RFC 2254.
- Public Member Functions inherited from Auth_Container
 Auth_Container ()
 Constructor.
 fetchData ($username, $password, $isChallengeResponse=false)
 Fetch data from storage container.
 verifyPassword ($password1, $password2, $cryptType="md5")
 Crypt and verfiy the entered password.
 supportsChallengeResponse ()
 Returns true if the container supports Challenge Response password authentication.
 getCryptType ()
 Returns the crypt current crypt type of the container.
 listUsers ()
 List all users that are available from the storage container.
 getUser ($username)
 Returns a user assoc array.
 addUser ($username, $password, $additional=null)
 Add a new user to the storage container.
 removeUser ($username)
 Remove user from the storage container.
 changePassword ($username, $password)
 Change password for user in the storage container.
 log ($message, $level=AUTH_LOG_DEBUG)
 Log a message to the Auth log.
- Public Member Functions inherited from ilAuthContainerBase
 loginObserver ($a_username, $a_auth)
 Called after successful login.
 failedLoginObserver ($a_username, $a_auth)
 Called after failed login.
 checkAuthObserver ($a_username, $a_auth)
 Called after check auth requests.
 logoutObserver ($a_username, $a_auth)
 Called after logout.

Data Fields

 $options = array()
 $conn_id = false
- Data Fields inherited from Auth_Container
 $activeUser = ""
 User that is currently selected from the storage container.
 $_auth_obj = null
 The Auth object this container is attached to.

Detailed Description

Definition at line 203 of file LDAP.php.

Member Function Documentation

Auth_Container_LDAP::_connect ( )

Connect to the LDAP server using the global options.

private

Returns
object Returns a PEAR error object if an error occurs.

Definition at line 276 of file LDAP.php.

References _disconnect(), AUTH_LOG_DEBUG, Auth_Container\log(), and PEAR\raiseError().

Referenced by _prepare().

{
$this->log('Auth_Container_LDAP::_connect() called.', AUTH_LOG_DEBUG);
// connect
if (isset($this->options['url']) && $this->options['url'] != '') {
$this->log('Connecting with URL', AUTH_LOG_DEBUG);
$conn_params = array($this->options['url']);
} else {
$this->log('Connecting with host:port', AUTH_LOG_DEBUG);
$conn_params = array($this->options['host'], $this->options['port']);
}
if (($this->conn_id = @call_user_func_array('ldap_connect', $conn_params)) === false) {
$this->log('Connection to server failed.', AUTH_LOG_DEBUG);
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
return PEAR::raiseError('Auth_Container_LDAP: Could not connect to server.', 41);
}
$this->log('Successfully connected to server', AUTH_LOG_DEBUG);
// switch LDAP version
if (is_numeric($this->options['version']) && $this->options['version'] > 2) {
$this->log("Switching to LDAP version {$this->options['version']}", AUTH_LOG_DEBUG);
@ldap_set_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $this->options['version']);
// start TLS if available
if (isset($this->options['start_tls']) && $this->options['start_tls']) {
$this->log("Starting TLS session", AUTH_LOG_DEBUG);
if (@ldap_start_tls($this->conn_id) === false) {
$this->log('Could not start TLS session', AUTH_LOG_DEBUG);
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
return PEAR::raiseError('Auth_Container_LDAP: Could not start tls.', 41);
}
}
}
// switch LDAP referrals
if (is_bool($this->options['referrals'])) {
$this->log("Switching LDAP referrals to " . (($this->options['referrals']) ? 'true' : 'false'), AUTH_LOG_DEBUG);
if (@ldap_set_option($this->conn_id, LDAP_OPT_REFERRALS, $this->options['referrals']) === false) {
$this->log('Could not change LDAP referrals options', AUTH_LOG_DEBUG);
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
}
}
// bind with credentials or anonymously
if (strlen($this->options['binddn']) && strlen($this->options['bindpw'])) {
$this->log('Binding with credentials', AUTH_LOG_DEBUG);
$bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']);
} else {
$this->log('Binding anonymously', AUTH_LOG_DEBUG);
$bind_params = array($this->conn_id);
}
// bind for searching
if ((@call_user_func_array('ldap_bind', $bind_params)) === false) {
$this->log('Bind failed', AUTH_LOG_DEBUG);
$this->log('LDAP ERROR: '.ldap_errno($this->conn_id).': '.ldap_error($this->conn_id), AUTH_LOG_DEBUG);
$this->_disconnect();
return PEAR::raiseError("Auth_Container_LDAP: Could not bind to LDAP server.", 41);
}
$this->log('Binding was successful', AUTH_LOG_DEBUG);
return true;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_Container_LDAP::_disconnect ( )

Disconnects (unbinds) from ldap server.

private

Definition at line 349 of file LDAP.php.

References _isValidLink(), AUTH_LOG_DEBUG, and Auth_Container\log().

Referenced by _connect(), and fetchData().

{
$this->log('Auth_Container_LDAP::_disconnect() called.', AUTH_LOG_DEBUG);
if ($this->_isValidLink()) {
$this->log('disconnecting from server');
@ldap_unbind($this->conn_id);
}
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_Container_LDAP::_getBaseDN ( )

Tries to find Basedn via namingContext Attribute.

private

Definition at line 366 of file LDAP.php.

References _isValidLink(), _prepare(), AUTH_LOG_DEBUG, Auth_Container\log(), and PEAR\raiseError().

Referenced by fetchData().

{
$this->log('Auth_Container_LDAP::_getBaseDN() called.', AUTH_LOG_DEBUG);
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
if ($this->options['basedn'] == "" && $this->_isValidLink()) {
$this->log("basedn not set, searching via namingContexts.", AUTH_LOG_DEBUG);
$result_id = @ldap_read($this->conn_id, "", "(objectclass=*)", array("namingContexts"));
if (@ldap_count_entries($this->conn_id, $result_id) == 1) {
$this->log("got result for namingContexts", AUTH_LOG_DEBUG);
$entry_id = @ldap_first_entry($this->conn_id, $result_id);
$attrs = @ldap_get_attributes($this->conn_id, $entry_id);
$basedn = $attrs['namingContexts'][0];
if ($basedn != "") {
$this->log("result for namingContexts was $basedn", AUTH_LOG_DEBUG);
$this->options['basedn'] = $basedn;
}
}
@ldap_free_result($result_id);
}
// if base ist still not set, raise error
if ($this->options['basedn'] == "") {
return PEAR::raiseError("Auth_Container_LDAP: LDAP search base not specified!", 41);
}
return true;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_Container_LDAP::_isValidLink ( )

determines whether there is a valid ldap conenction or not

private

Returns
boolean

Definition at line 411 of file LDAP.php.

Referenced by _disconnect(), _getBaseDN(), and _prepare().

{
if (is_resource($this->conn_id)) {
if (get_resource_type($this->conn_id) == 'ldap link') {
return true;
}
}
return false;
}

+ Here is the caller graph for this function:

Auth_Container_LDAP::_parseOptions (   $array)

Parse options passed to the container class.

private

Parameters
array

Definition at line 466 of file LDAP.php.

References _setV12OptionsToV13().

Referenced by Auth_Container_LDAP().

{
$array = $this->_setV12OptionsToV13($array);
foreach ($array as $key => $value) {
if (array_key_exists($key, $this->options)) {
if ($key == 'attributes') {
if (is_array($value)) {
$this->options[$key] = $value;
} else {
$this->options[$key] = explode(',', $value);
}
} else {
$this->options[$key] = $value;
}
}
}
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_Container_LDAP::_prepare ( )

Prepare LDAP connection.

This function checks if we have already opened a connection to the LDAP server. If that's not the case, a new connection is opened.

private

Returns
mixed True or a PEAR error object.

Definition at line 256 of file LDAP.php.

References $res, _connect(), _isValidLink(), and PEAR\isError().

Referenced by _getBaseDN(), checkGroup(), and fetchData().

{
if (!$this->_isValidLink()) {
$res = $this->_connect();
return $res;
}
}
return true;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_Container_LDAP::_quoteFilterString (   $filter_str)

Escapes LDAP filter special characters as defined in RFC 2254.

private

Parameters
stringFilter String

Definition at line 755 of file LDAP.php.

Referenced by checkGroup(), and fetchData().

{
$metas = array( '\\', '*', '(', ')', "\x00");
$quoted_metas = array('\\\\', '\*', '\(', '\)', "\\\x00");
return str_replace($metas, $quoted_metas, $filter_str);
}

+ Here is the caller graph for this function:

Auth_Container_LDAP::_scope2function (   $scope)

Get search function for scope.

Parameters
stringscope
Returns
string ldap search function

Definition at line 517 of file LDAP.php.

Referenced by checkGroup(), and fetchData().

{
switch($scope) {
case 'one':
$function = 'ldap_list';
break;
case 'base':
$function = 'ldap_read';
break;
default:
$function = 'ldap_search';
break;
}
return $function;
}

+ Here is the caller graph for this function:

Auth_Container_LDAP::_setDefaults ( )

Set some default options.

private

Definition at line 429 of file LDAP.php.

Referenced by Auth_Container_LDAP().

{
$this->options['url'] = '';
$this->options['host'] = 'localhost';
$this->options['port'] = '389';
$this->options['version'] = 2;
$this->options['referrals'] = true;
$this->options['binddn'] = '';
$this->options['bindpw'] = '';
$this->options['basedn'] = '';
$this->options['userdn'] = '';
$this->options['userscope'] = 'sub';
$this->options['userattr'] = 'uid';
$this->options['userfilter'] = '(objectClass=posixAccount)';
$this->options['attributes'] = array(''); // no attributes
$this->options['attrformat'] = 'AUTH'; // returns attribute like other Auth containers
$this->options['group'] = '';
$this->options['groupdn'] = '';
$this->options['groupscope'] = 'sub';
$this->options['groupattr'] = 'cn';
$this->options['groupfilter'] = '(objectClass=groupOfUniqueNames)';
$this->options['memberattr'] = 'uniqueMember';
$this->options['memberisdn'] = true;
$this->options['start_tls'] = false;
$this->options['debug'] = false;
$this->options['try_all'] = false; // Try all user ids returned not just the first one
}

+ Here is the caller graph for this function:

Auth_Container_LDAP::_setV12OptionsToV13 (   $array)

Adapt deprecated options from Auth 1.2 LDAP to Auth 1.3 LDAP.

Author
Hugues Peeters hugue.nosp@m.s.pe.nosp@m.eters.nosp@m.@cla.nosp@m.rolin.nosp@m.e.ne.nosp@m.t private
Parameters
array
Returns
array

Definition at line 496 of file LDAP.php.

Referenced by _parseOptions().

{
if (isset($array['useroc']))
$array['userfilter'] = "(objectClass=".$array['useroc'].")";
if (isset($array['groupoc']))
$array['groupfilter'] = "(objectClass=".$array['groupoc'].")";
if (isset($array['scope']))
$array['userscope'] = $array['scope'];
return $array;
}

+ Here is the caller graph for this function:

Auth_Container_LDAP::Auth_Container_LDAP (   $params)

Constructor of the container class.

Parameters
$params,associativehash with host,port,basedn and userattr key
Returns
object Returns an error object if something went wrong

Definition at line 230 of file LDAP.php.

References _parseOptions(), _setDefaults(), PEAR_ERROR_DIE, and PEAR\raiseError().

{
if (false === extension_loaded('ldap')) {
return PEAR::raiseError('Auth_Container_LDAP: LDAP Extension not loaded',
}
$this->_setDefaults();
if (is_array($params)) {
$this->_parseOptions($params);
}
}

+ Here is the call graph for this function:

Auth_Container_LDAP::checkGroup (   $user)

Validate group membership.

Searches the LDAP server for group membership of the supplied username. Quotes all LDAP filter meta characters in the user name before querying the LDAP server.

Parameters
stringDistinguished Name of the authenticated User
Returns
boolean

Reimplemented in ilAuthContainerLDAP.

Definition at line 704 of file LDAP.php.

References _prepare(), _quoteFilterString(), _scope2function(), AUTH_LOG_DEBUG, Auth_Container\log(), and PEAR\raiseError().

Referenced by fetchData().

{
$this->log('Auth_Container_LDAP::checkGroup() called.', AUTH_LOG_DEBUG);
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
// make filter
$filter = sprintf('(&(%s=%s)(%s=%s)%s)',
$this->options['groupattr'],
$this->options['group'],
$this->options['memberattr'],
$this->_quoteFilterString($user),
$this->options['groupfilter']);
// make search base dn
$search_basedn = $this->options['groupdn'];
if ($search_basedn != '' && substr($search_basedn, -1) != ',') {
$search_basedn .= ',';
}
$search_basedn .= $this->options['basedn'];
$func_params = array($this->conn_id, $search_basedn, $filter,
array($this->options['memberattr']));
$func_name = $this->_scope2function($this->options['groupscope']);
$this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG);
// search
if (($result_id = @call_user_func_array($func_name, $func_params)) != false) {
if (@ldap_count_entries($this->conn_id, $result_id) == 1) {
@ldap_free_result($result_id);
$this->log('User is member of group', AUTH_LOG_DEBUG);
return true;
}
}
// default
$this->log('User is NOT member of group', AUTH_LOG_DEBUG);
return false;
}

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Auth_Container_LDAP::fetchData (   $username,
  $password 
)

Fetch data from LDAP server.

Searches the LDAP server for the given username/password combination. Escapes all LDAP meta characters in username before performing the query.

Parameters
stringUsername
stringPassword
Returns
boolean

Reimplemented in ilAuthContainerLDAP.

Definition at line 547 of file LDAP.php.

References _disconnect(), _getBaseDN(), _prepare(), _quoteFilterString(), _scope2function(), AUTH_LOG_DEBUG, checkGroup(), Auth_Container\log(), and PEAR\raiseError().

{
$this->log('Auth_Container_LDAP::fetchData() called.', AUTH_LOG_DEBUG);
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
$err = $this->_getBaseDN();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
}
// UTF8 Encode username for LDAPv3
if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver == 3) {
$this->log('UTF8 encoding username for LDAPv3', AUTH_LOG_DEBUG);
$username = utf8_encode($username);
}
// make search filter
$filter = sprintf('(&(%s=%s)%s)',
$this->options['userattr'],
$this->_quoteFilterString($username),
$this->options['userfilter']);
// make search base dn
$search_basedn = $this->options['userdn'];
if ($search_basedn != '' && substr($search_basedn, -1) != ',') {
$search_basedn .= ',';
}
$search_basedn .= $this->options['basedn'];
// attributes
$searchAttributes = $this->options['attributes'];
// make functions params array
$func_params = array($this->conn_id, $search_basedn, $filter, $searchAttributes);
// search function to use
$func_name = $this->_scope2function($this->options['userscope']);
$this->log("Searching with $func_name and filter $filter in $search_basedn", AUTH_LOG_DEBUG);
// search
if (($result_id = @call_user_func_array($func_name, $func_params)) === false) {
$this->log('User not found', AUTH_LOG_DEBUG);
} elseif (@ldap_count_entries($this->conn_id, $result_id) >= 1) { // did we get some possible results?
$this->log('User(s) found', AUTH_LOG_DEBUG);
$first = true;
$entry_id = null;
do {
// then get the user dn
if ($first) {
$entry_id = @ldap_first_entry($this->conn_id, $result_id);
$first = false;
} else {
$entry_id = @ldap_next_entry($this->conn_id, $entry_id);
if ($entry_id === false)
break;
}
$user_dn = @ldap_get_dn($this->conn_id, $entry_id);
// as the dn is not fetched as an attribute, we save it anyway
if (is_array($searchAttributes) && in_array('dn', $searchAttributes)) {
$this->log('Saving DN to AuthData', AUTH_LOG_DEBUG);
$this->_auth_obj->setAuthData('dn', $user_dn);
}
// fetch attributes
if ($attributes = @ldap_get_attributes($this->conn_id, $entry_id)) {
if (is_array($attributes) && isset($attributes['count']) &&
$attributes['count'] > 0) {
// ldap_get_attributes() returns a specific multi dimensional array
// format containing all the attributes and where each array starts
// with a 'count' element providing the number of attributes in the
// entry, or the number of values for attribute. For compatibility
// reasons, it remains the default format returned by LDAP container
// setAuthData().
// The code below optionally returns attributes in another format,
// more compliant with other Auth containers, where each attribute
// element are directly set in the 'authData' list. This option is
// enabled by setting 'attrformat' to
// 'AUTH' in the 'options' array.
// eg. $this->options['attrformat'] = 'AUTH'
if ( strtoupper($this->options['attrformat']) == 'AUTH' ) {
$this->log('Saving attributes to Auth data in AUTH format', AUTH_LOG_DEBUG);
unset ($attributes['count']);
foreach ($attributes as $attributeName => $attributeValue ) {
if (is_int($attributeName)) continue;
if (is_array($attributeValue) && isset($attributeValue['count'])) {
unset ($attributeValue['count']);
}
if (count($attributeValue)<=1) $attributeValue = $attributeValue[0];
$this->log('Storing additional field: '.$attributeName, AUTH_LOG_DEBUG);
$this->_auth_obj->setAuthData($attributeName, $attributeValue);
}
}
else
{
$this->log('Saving attributes to Auth data in LDAP format', AUTH_LOG_DEBUG);
$this->_auth_obj->setAuthData('attributes', $attributes);
}
}
}
@ldap_free_result($result_id);
// need to catch an empty password as openldap seems to return TRUE
// if anonymous binding is allowed
if ($password != "") {
$this->log("Bind as $user_dn", AUTH_LOG_DEBUG);
// try binding as this user with the supplied password
if (@ldap_bind($this->conn_id, $user_dn, $password)) {
$this->log('Bind successful', AUTH_LOG_DEBUG);
// check group if appropiate
if (strlen($this->options['group'])) {
// decide whether memberattr value is a dn or the username
$this->log('Checking group membership', AUTH_LOG_DEBUG);
$return = $this->checkGroup(($this->options['memberisdn']) ? $user_dn : $username);
$this->_disconnect();
return $return;
} else {
$this->log('Authenticated', AUTH_LOG_DEBUG);
$this->_disconnect();
return true; // user authenticated
} // checkGroup
} // bind
} // non-empty password
} while ($this->options['try_all'] == true); // interate through entries
} // get results
// default
$this->log('NOT authenticated!', AUTH_LOG_DEBUG);
$this->_disconnect();
return false;
}

+ Here is the call graph for this function:

Field Documentation

Auth_Container_LDAP::$conn_id = false

Definition at line 218 of file LDAP.php.

Auth_Container_LDAP::$options = array()

Definition at line 212 of file LDAP.php.


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