Subversion Repositories Applications.papyrus

Compare Revisions

Ignore whitespace Rev 1712 → Rev 1713

/trunk/api/pear/Auth/Container/LDAP.php
14,12 → 14,12
*
* @category Authentication
* @package Auth
* @author Jan Wagner <wagner@netsols.de>
* @author Jan Wagner <wagner@netsols.de>
* @author Adam Ashley <aashley@php.net>
* @author Hugues Peeters <hugues.peeters@claroline.net>
* @copyright 2001-2006 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: LDAP.php,v 1.2 2006-12-14 15:04:28 jp_milcent Exp $
* @version CVS: $Id: LDAP.php,v 1.3 2007-11-19 15:11:00 jp_milcent Exp $
* @link http://pear.php.net/package/Auth
*/
 
103,7 → 103,7
* or the value of userattr (usually uid)
* group: the name of group to search for
* groupscope: Scope for group searching: one, sub (default), or base
* start_tls: enable/disable the use of START_TLS encrypted connection
* start_tls: enable/disable the use of START_TLS encrypted connection
* (default: false)
* debug: Enable/Disable debugging output (default: false)
* try_all: Whether to try all user accounts returned from the search
177,14 → 177,14
* It seems that binding anonymously to an Active Directory
* is not allowed, so you have to set binddn and bindpw for
* user searching.
*
*
* LDAP Referrals need to be set to false for AD to work sometimes.
*
* Example a3 shows a full blown and tested example for connection to
* Example a3 shows a full blown and tested example for connection to
* Windows 2000 Active Directory with group mebership checking
*
* Note also that if you want an encrypted connection to an MS LDAP
* server, then, on your webserver, you must specify
* Note also that if you want an encrypted connection to an MS LDAP
* server, then, on your webserver, you must specify
* TLS_REQCERT never
* in /etc/ldap/ldap.conf or in the webserver user's ~/.ldaprc (which
* may or may not be read depending on your configuration).
197,7 → 197,7
* @author Hugues Peeters <hugues.peeters@claroline.net>
* @copyright 2001-2006 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version Release: 1.4.3 File: $Revision: 1.2 $
* @version Release: 1.5.4 File: $Revision: 1.3 $
* @link http://pear.php.net/package/Auth
*/
class Auth_Container_LDAP extends Auth_Container
275,29 → 275,34
*/
function _connect()
{
$this->log('Auth_Container_LDAP::_connect() called.', AUTH_LOG_DEBUG);
// connect
if (isset($this->options['url']) && $this->options['url'] != '') {
$this->_debug('Connecting with URL', __LINE__);
$this->log('Connecting with URL', AUTH_LOG_DEBUG);
$conn_params = array($this->options['url']);
} else {
$this->_debug('Connecting with host:port', __LINE__);
$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->_debug('Successfully connected to server', __LINE__);
$this->log('Successfully connected to server', AUTH_LOG_DEBUG);
 
// switch LDAP version
if (is_numeric($this->options['version']) && $this->options['version'] > 2) {
$this->_debug("Switching to LDAP version {$this->options['version']}", __LINE__);
$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->_debug("Starting TLS session", __LINE__);
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);
}
}
305,26 → 310,30
 
// switch LDAP referrals
if (is_bool($this->options['referrals'])) {
$this->_debug("Switching LDAP referrals to " . (($this->options['referrals']) ? 'true' : 'false'), __LINE__);
@ldap_set_option($this->conn_id, LDAP_OPT_REFERRALS, $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->_debug('Binding with credentials', __LINE__);
$this->log('Binding with credentials', AUTH_LOG_DEBUG);
$bind_params = array($this->conn_id, $this->options['binddn'], $this->options['bindpw']);
} else {
$this->_debug('Binding anonymously', __LINE__);
$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->_debug();
$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->_debug('Binding was successful', __LINE__);
$this->log('Binding was successful', AUTH_LOG_DEBUG);
 
return true;
}
339,8 → 348,9
*/
function _disconnect()
{
$this->log('Auth_Container_LDAP::_disconnect() called.', AUTH_LOG_DEBUG);
if ($this->_isValidLink()) {
$this->_debug('disconnecting from server');
$this->log('disconnecting from server');
@ldap_unbind($this->conn_id);
}
}
355,6 → 365,7
*/
function _getBaseDN()
{
$this->log('Auth_Container_LDAP::_getBaseDN() called.', AUTH_LOG_DEBUG);
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
361,13 → 372,13
}
 
if ($this->options['basedn'] == "" && $this->_isValidLink()) {
$this->_debug("basedn not set, searching via namingContexts.", __LINE__);
$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->_debug("got result for namingContexts", __LINE__);
$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);
374,7 → 385,7
$basedn = $attrs['namingContexts'][0];
 
if ($basedn != "") {
$this->_debug("result for namingContexts was $basedn", __LINE__);
$this->log("result for namingContexts was $basedn", AUTH_LOG_DEBUG);
$this->options['basedn'] = $basedn;
}
}
430,7 → 441,6
$this->options['userattr'] = 'uid';
$this->options['userfilter'] = '(objectClass=posixAccount)';
$this->options['attributes'] = array(''); // no attributes
// $this->options['attrformat'] = 'LDAP'; // returns attribute array as PHP LDAP functions return it
$this->options['attrformat'] = 'AUTH'; // returns attribute like other Auth containers
$this->options['group'] = '';
$this->options['groupdn'] = '';
477,7 → 487,7
 
/**
* Adapt deprecated options from Auth 1.2 LDAP to Auth 1.3 LDAP
*
*
* @author Hugues Peeters <hugues.peeters@claroline.net>
* @access private
* @param array
536,6 → 546,7
*/
function fetchData($username, $password)
{
$this->log('Auth_Container_LDAP::fetchData() called.', AUTH_LOG_DEBUG);
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
548,7 → 559,7
 
// UTF8 Encode username for LDAPv3
if (@ldap_get_option($this->conn_id, LDAP_OPT_PROTOCOL_VERSION, $ver) && $ver == 3) {
$this->_debug('UTF8 encoding username for LDAPv3', __LINE__);
$this->log('UTF8 encoding username for LDAPv3', AUTH_LOG_DEBUG);
$username = utf8_encode($username);
}
 
566,28 → 577,28
$search_basedn .= $this->options['basedn'];
 
// attributes
$attributes = $this->options['attributes'];
$searchAttributes = $this->options['attributes'];
 
// make functions params array
$func_params = array($this->conn_id, $search_basedn, $filter, $attributes);
$func_params = array($this->conn_id, $search_basedn, $filter, $searchAttributes);
 
// search function to use
$func_name = $this->_scope2function($this->options['userscope']);
 
$this->_debug("Searching with $func_name and filter $filter in $search_basedn", __LINE__);
$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->_debug('User not found', __LINE__);
$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->_debug('User(s) found', __LINE__);
$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);
600,11 → 611,11
$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($attributes) && in_array('dn', $attributes)) {
$this->_debug('Saving DN to AuthData', __LINE__);
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)) {
 
625,7 → 636,7
// eg. $this->options['attrformat'] = 'AUTH'
 
if ( strtoupper($this->options['attrformat']) == 'AUTH' ) {
$this->_debug('Saving attributes to Auth data in AUTH format', __LINE__);
$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;
633,12 → 644,13
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->_debug('Saving attributes to Auth data in LDAP format', __LINE__);
$this->log('Saving attributes to Auth data in LDAP format', AUTH_LOG_DEBUG);
$this->_auth_obj->setAuthData('attributes', $attributes);
}
}
648,21 → 660,21
// need to catch an empty password as openldap seems to return TRUE
// if anonymous binding is allowed
if ($password != "") {
$this->_debug("Bind as $user_dn", __LINE__);
$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->_debug('Bind successful', __LINE__);
$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->_debug('Checking group membership', __LINE__);
$this->log('Checking group membership', AUTH_LOG_DEBUG);
$return = $this->checkGroup(($this->options['memberisdn']) ? $user_dn : $username);
$this->_disconnect();
return $return;
} else {
$this->_debug('Authenticated', __LINE__);
$this->log('Authenticated', AUTH_LOG_DEBUG);
$this->_disconnect();
return true; // user authenticated
} // checkGroup
671,7 → 683,7
} while ($this->options['try_all'] == true); // interate through entries
} // get results
// default
$this->_debug('NOT authenticated!', __LINE__);
$this->log('NOT authenticated!', AUTH_LOG_DEBUG);
$this->_disconnect();
return false;
}
691,6 → 703,7
*/
function checkGroup($user)
{
$this->log('Auth_Container_LDAP::checkGroup() called.', AUTH_LOG_DEBUG);
$err = $this->_prepare();
if ($err !== true) {
return PEAR::raiseError($err->getMessage(), $err->getCode());
715,42 → 728,22
array($this->options['memberattr']));
$func_name = $this->_scope2function($this->options['groupscope']);
 
$this->_debug("Searching with $func_name and filter $filter in $search_basedn", __LINE__);
$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->_debug('User is member of group', __LINE__);
$this->log('User is member of group', AUTH_LOG_DEBUG);
return true;
}
}
// default
$this->_debug('User is NOT member of group', __LINE__);
$this->log('User is NOT member of group', AUTH_LOG_DEBUG);
return false;
}
 
// }}}
// {{{ _debug()
 
/**
* Outputs debugging messages
*
* @access private
* @param string Debugging Message
* @param integer Line number
*/
function _debug($msg = '', $line = 0)
{
if ($this->options['debug'] == true) {
if ($msg == '' && $this->_isValidLink()) {
$msg = 'LDAP_Error: ' . @ldap_err2str(@ldap_errno($this->_conn_id));
}
print("$line: $msg <br />");
}
}
 
// }}}
// {{{ _quoteFilterString()
 
/**