<?php namespace Kanboard\Core\Ldap; use LogicException; /** * LDAP Client * * @package ldap * @author Frederic Guillot */ class Client { /** * LDAP resource * * @access protected * @var resource */ protected $ldap; /** * Establish LDAP connection * * @static * @access public * @param string $username * @param string $password * @return Client */ public static function connect($username = null, $password = null) { $client = new static; $client->open($client->getLdapServer()); $username = $username ?: $client->getLdapUsername(); $password = $password ?: $client->getLdapPassword(); if (empty($username) && empty($password)) { $client->useAnonymousAuthentication(); } else { $client->authenticate($username, $password); } return $client; } /** * Get server connection * * @access public * @return resource */ public function getConnection() { return $this->ldap; } /** * Establish server connection * * @access public * @throws ClientException * @param string $server LDAP server hostname or IP * @param integer $port LDAP port * @param boolean $tls Start TLS * @param boolean $verify Skip SSL certificate verification * @return Client */ public function open($server, $port = LDAP_PORT, $tls = LDAP_START_TLS, $verify = LDAP_SSL_VERIFY) { if (! function_exists('ldap_connect')) { throw new ClientException('LDAP: The PHP LDAP extension is required'); } if (! $verify) { putenv('LDAPTLS_REQCERT=never'); } $this->ldap = ldap_connect($server, $port); if ($this->ldap === false) { throw new ClientException('LDAP: Unable to connect to the LDAP server'); } ldap_set_option($this->ldap, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($this->ldap, LDAP_OPT_REFERRALS, 0); ldap_set_option($this->ldap, LDAP_OPT_NETWORK_TIMEOUT, 1); ldap_set_option($this->ldap, LDAP_OPT_TIMELIMIT, 1); if ($tls && ! @ldap_start_tls($this->ldap)) { throw new ClientException('LDAP: Unable to start TLS'); } return $this; } /** * Anonymous authentication * * @access public * @throws ClientException * @return boolean */ public function useAnonymousAuthentication() { if (! @ldap_bind($this->ldap)) { throw new ClientException('Unable to perform anonymous binding'); } return true; } /** * Authentication with username/password * * @access public * @throws ClientException * @param string $bind_rdn * @param string $bind_password * @return boolean */ public function authenticate($bind_rdn, $bind_password) { if (! @ldap_bind($this->ldap, $bind_rdn, $bind_password)) { throw new ClientException('LDAP authentication failure for "'.$bind_rdn.'"'); } return true; } /** * Get LDAP server name * * @access public * @return string */ public function getLdapServer() { if (! LDAP_SERVER) { throw new LogicException('LDAP server not configured, check the parameter LDAP_SERVER'); } return LDAP_SERVER; } /** * Get LDAP username (proxy auth) * * @access public * @return string */ public function getLdapUsername() { return LDAP_USERNAME; } /** * Get LDAP password (proxy auth) * * @access public * @return string */ public function getLdapPassword() { return LDAP_PASSWORD; } }