conn = $conn; $this->userClass = $userClass; $this->userNameAttribute = $userNameAttribute; } /** * Create query * * @param string $username * * @return \Icinga\Protocol\Ldap\Query **/ protected function createQuery($username) { return $this->conn->select() ->from( $this->userClass, array($this->userNameAttribute) ) ->where( $this->userNameAttribute, str_replace('*', '', $username) ); } /** * Probe the backend to test if authentication is possible * * Try to bind to the backend and query all available users to check if: * * * @throws AuthenticationException When authentication is not possible */ public function assertAuthenticationPossible() { $q = $this->conn->select()->from($this->userClass); $result = $q->fetchRow(); if (! isset($result)) { throw new AuthenticationException( 'No objects with objectClass="%s" in DN="%s" found.', $this->userClass, $this->conn->getDN() ); } if (! isset($result->{$this->userNameAttribute})) { throw new AuthenticationException( 'UserNameAttribute "%s" not existing in objectClass="%s"', $this->userNameAttribute, $this->userClass ); } } /** * Test whether the given user exists * * @param User $user * * @return bool * @throws AuthenticationException */ public function hasUser(User $user) { $username = $user->getUsername(); return $this->conn->fetchOne($this->createQuery($username)) === $username; } /** * Authenticate the given user and return true on success, false on failure and null on error * * @param User $user * @param string $password * @param boolean $healthCheck Perform additional health checks to generate more useful exceptions in case * of a configuration or backend error * * @return bool True when the authentication was successful, false when the username * or password was invalid * @throws AuthenticationException When an error occurred during authentication and authentication is not possible */ public function authenticate(User $user, $password, $healthCheck = true) { if ($healthCheck) { try { $this->assertAuthenticationPossible(); } catch (AuthenticationException $e) { // Authentication not possible throw new AuthenticationException( 'Authentication against backend "%s" not possible: ', $this->getName(), $e ); } } if (! $this->hasUser($user)) { return false; } try { return $this->conn->testCredentials( $this->conn->fetchDN($this->createQuery($user->getUsername())), $password ); } catch (LdapException $e) { // Error during authentication of this specific user throw new AuthenticationException( 'Failed to authenticate user "%s" against backend "%s". An exception was thrown:', $user->getUsername(), $this->getName(), $e ); } } /** * Get the number of users available * * @return int */ public function count() { return $this->conn->count( $this->conn->select()->from( $this->userClass, array( $this->userNameAttribute ) ) ); } }