}
/**
- * Find the user dn.
- *
- * @param string $userId The userId to find.
- *
- * @return string The user's full DN
- * @throws Horde_Auth_Exception
- */
- protected function _findDN($userId)
- {
- /* Search for the user's full DN. */
- $filter = $this->_getParamFilter();
- $filter = '(&(' . $this->_params['uid'] . '=' . $userId . ')' .
- $filter . ')';
-
- try {
- $search = $this->_ldap->search(null, $filter, array('attributes' => array($this->_params['uid'])));
- } catch (Horde_Ldap_Exception $e) {
- throw new Horde_Auth_Exception('Could not search the LDAP server.');
- }
-
- if (!$search->count()) {
- throw new Horde_Auth_Exception('Empty result.');
- }
-
- $entry = $search->shiftEntry();
-
- return $entry->currentDN();
- }
-
- /**
* Checks for shadowLastChange and shadowMin/Max support and returns their
* values. We will also check for pwdLastSet if Active Directory is
* support is requested. For this check to succeed we need to be bound
{
/* Search for the user's full DN. */
$this->_ldap->bind();
- $dn = $this->_findDN($userId);
+ try {
+ $dn = $this->_ldap->findUserDN($userId);
+ } catch (Horde_Exception_NotFound $e) {
+ throw new Horde_Auth_Exception('', Horde_Auth::REASON_BADLOGIN);
+ } catch (Horde_Exception_Ldap $e) {
+ throw new Horde_Auth_Exception($e->getMessage(), Horde_Auth::REASON_MESSAGE);
+ }
/* Attempt to bind to the LDAP server as the user. */
try {
if (is_null($dn)) {
/* Search for the user's full DN. */
- $dn = $this->_findDN($userId);
+ try {
+ $dn = $this->_ldap->findUserDN($userId);
+ } catch (Horde_Exception_Ldap $e) {
+ throw new Horde_Auth_Exception($e);
+ }
}
try {
if (is_null($olddn)) {
/* Search for the user's full DN. */
- $dn = $this->_findDN($oldID);
+ try {
+ $dn = $this->_ldap->findUserDN($oldID);
+ } catch (Horde_Exception_Ldap $e) {
+ throw new Horde_Auth_Exception($e);
+ }
$olddn = $dn;
$newdn = preg_replace('/uid=.*?,/', 'uid=' . $newID . ',', $dn, 1);
*/
public function listUsers()
{
- $filter = $this->_getParamFilter();
-
$params = array(
'attributes' => array($this->_params['uid']),
'scope' => $this->_params['scope'],
* Note: You cannot override a server-side limit with this. */
$userlist = array();
try {
- $search = $this->_ldap->search($this->_params['basedn'], $filter, $params)->as_struct();
+ $search = $this->_ldap->search(
+ $this->_params['basedn'],
+ Horde_Ldap_Filter::build($this->_params),
+ $params)
+ ->as_struct();
$uid = Horde_String::lower($this->_params['uid']);
foreach ($search as $val) {
$userlist[] = $val[$uid][0];
return $userlist;
}
-
- /**
- * Return a formatted LDAP filter as configured within the parameters.
- *
- * @return string LDAP search filter
- */
- protected function _getParamFilter()
- {
- if (!empty($this->_params['filter'])) {
- $filter = $this->_params['filter'];
- } elseif (!is_array($this->_params['objectclass'])) {
- $filter = 'objectclass=' . $this->_params['objectclass'];
- } else {
- $filter = '';
- if (count($this->_params['objectclass']) > 1) {
- $filter = '(&' . $filter;
- foreach ($this->_params['objectclass'] as $objectclass) {
- $filter .= '(objectclass=' . $objectclass . ')';
- }
- $filter .= ')';
- } elseif (count($this->_params['objectclass']) == 1) {
- $filter = '(objectClass=' . $this->_params['objectclass'][0] . ')';
- }
- }
- return $filter;
- }
-
}
$config = $this->getConfig($type);
- /* Determine if we are using the base LDAP config. */
- if (isset($config['driverconfig']) &&
- ($config['driverconfig'] == 'horde')) {
- $this->_instances[$sig] = $this->getLdap();
- return $this->_instances[$sig];
+ /* BC check for old configuration without 'user' setting, so that
+ administrators can still log in through LDAP and update the
+ configuration. */
+ if (!isset($config['user'])) {
+ $config['user'] = $config;
}
try {
$this->_instances[$sig] = new Horde_Ldap($config);
- // Establish the connection so it is available when searching later
- $this->_instances[$sig]->bind();
} catch (Horde_Exception $e) {
if ($pushed) {
$GLOBALS['registry']->popApp();
* - options: hash of LDAP options to set.
* - filter: default search filter.
* - scope: default search scope.
+ * - user: configuration parameters for {@link findUserDN()},
+ * must contain 'uid', and 'filter' or 'objectclass'
+ * entries.
* - auto_reconnect: if true, the class will automatically
* attempt to reconnect to the LDAP server in certain
* failure conditions when attempting a search, or other
'port' => 389,
'version' => 3,
'starttls' => false,
- 'binddn' => '',
- 'bindpw' => '',
+ 'binddn' => '',
+ 'bindpw' => '',
'basedn' => '',
'options' => array(),
'filter' => '(objectClass=*)',
'scope' => 'sub',
+ 'user' => array(),
'auto_reconnect' => false,
'min_backoff' => 1,
'current_backoff' => 1,
}
/**
+ * Returns the DN of a user.
+ *
+ * The purpose is to quickly find the full DN of a user so it can be used
+ * to re-bind as this user. This method requires the 'user' configuration
+ * parameter to be set.
+ *
+ * @param string $user The user to find.
+ *
+ * @return string The user's full DN.
+ * @throws Horde_Ldap_Exception
+ * @throws Horde_Exception_NotFound
+ */
+ public function findUserDN($user)
+ {
+ $filter = Horde_Ldap_Filter::combine(
+ 'and',
+ array(Horde_Ldap_Filter::build($this->_config['user']),
+ Horde_Ldap_Filter::create($this->_config['user']['uid'], 'equals', $user)));
+ $search = $this->search(
+ null,
+ $filter,
+ array('attributes' => array($this->_config['user']['uid'])));
+ if (!$search->count()) {
+ throw new Horde_Exception_NotFound();
+ }
+ $entry = $search->shiftEntry();
+ return $entry->currentDN();
+ }
+
+ /**
* Sets an LDAP option.
*
* @param string $option Option to set.