/** * Bind to LDAP with a specific DN and password. Simple wrapper around * ldap_bind() with some additional logging. * * @param string $dn * The DN used. * @param string $password * The password used. * @param array $sasl_args * Array of SASL options for SASL bind * @return bool * Returns TRUE if successful, FALSE if * LDAP_INVALID_CREDENTIALS, LDAP_X_PROXY_AUTHZ_FAILURE, * LDAP_INAPPROPRIATE_AUTH, LDAP_INSUFFICIENT_ACCESS * @throws SimpleSAML_Error_Exception on other errors */ public function bind($dn, $password, array $sasl_args = NULL) { $authz_id = null; if ($sasl_args != NULL) { if (!function_exists(ldap_sasl_bind)) { $ex_msg = 'Library - missing SASL support'; throw $this->makeException($ex_msg); } // SASL Bind, with error handling. $authz_id = $sasl_args['authz_id']; $error = @ldap_sasl_bind($this->ldap, $dn, $password, $sasl_args['mech'], $sasl_args['realm'], $sasl_args['authc_id'], $sasl_args['authz_id'], $sasl_args['props']); } else { // Simple Bind, with error handling. $authz_id = $dn; $error = @ldap_bind($this->ldap, $dn, $password); } if ($error === TRUE) { // Good. $this->authz_id = $authz_id; SimpleSAML_Logger::NOTICE('Library -----> LDAP bind(): Bind successful with DN \'' . $dn . '\''); return TRUE; } /* Handle errors * LDAP_INVALID_CREDENTIALS * LDAP_INSUFFICIENT_ACCESS */ switch (ldap_errno($this->ldap)) { case 32: /* LDAP_NO_SUCH_OBJECT */ /* LDAP_NO_SUCH_OBJECT */ case 47: /* LDAP_X_PROXY_AUTHZ_FAILURE */ /* LDAP_X_PROXY_AUTHZ_FAILURE */ case 48: /* LDAP_INAPPROPRIATE_AUTH */ /* LDAP_INAPPROPRIATE_AUTH */ case 49: /* LDAP_INVALID_CREDENTIALS */ /* LDAP_INVALID_CREDENTIALS */ case 50: /* LDAP_INSUFFICIENT_ACCESS */ return FALSE; break; default: break; } // Bad. throw $this->makeException('Library - LDAP bind(): Bind failed with DN \'' . $dn . '\''); }
/** * Attempt to log in using the given username and password. * * Will throw a SimpleSAML_Error_Error('WRONGUSERPASS') if the username or password is wrong. * If there is a configuration problem, an Exception will be thrown. * * @param string $username The username the user wrote. * @param string $password The password the user wrote. * @param arrray $sasl_args Array of SASL options for LDAP bind. * @return array Associative array with the users attributes. */ public function login($username, $password, array $sasl_args = NULL) { assert('is_string($username)'); assert('is_string($password)'); if (empty($password)) { SimpleSAML_Logger::info($this->location . ': Login with empty password disallowed.'); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout); if (!$this->searchEnable) { $ldapusername = addcslashes($username, ',+"\\<>;*'); $dn = str_replace('%username%', $ldapusername, $this->dnPattern); } else { if ($this->searchUsername !== NULL) { SimpleSAML_Logger::NOTICE(" --------------- searchUsername: {$username}, searchPassword: {$password}"); if (!$ldap->bind('promodo\\' . $username, $password)) { throw new SimpleSAML_Error_Error('WRONGUSERPASS'); // throw new Exception('Error authenticating using search username & password.'); } } $dn = $ldap->searchfordn($this->searchBase, $this->searchAttributes, $username, TRUE); if ($dn === NULL) { /* User not found with search. */ SimpleSAML_Logger::info($this->location . ': Unable to find users DN. username=\'' . $username . '\''); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } } // if (!$ldap->bind($dn, $password, $sasl_args)) { // SimpleSAML_Logger::info($this->location . ': '. $username . ' failed to authenticate. DN=' . $dn); // throw new SimpleSAML_Error_Error('WRONGUSERPASS'); // } /* In case of SASL bind, authenticated and authorized DN may differ */ if (isset($sasl_args)) { $dn = $ldap->whoami($this->searchBase, $this->searchAttributes); } /* Are privs needed to get the attributes? */ if ($this->privRead) { /* Yes, rebind with privs */ if (!$ldap->bind($this->privUsername, $this->privPassword)) { throw new Exception('Error authenticating using privileged DN & password.'); } } return $ldap->getAttributes($dn, $this->attributes); }