/** * Bind to a directory. * $binddn string directory to bind (optional) * $password string (optional) */ function bind($binddn = null, $password = null) { if (isset($this->settings['sasl'])) { // FIXME ldap_sasl_bind requires PHP5, haven't tested this return @ldap_sasl_bind($this->conn, $binddn, $password, $this->settings['saslmech'], $this->settings['saslrealm'], $this->settings['saslauthzid'], $this->settings['saslprop']); } return @ldap_bind($this->conn, $binddn, $password); }
/** * Validate a user's login credentials * * @param string $username A user's AD username * @param string $password A user's AD password * @param bool optional $preventRebind * @return bool */ public function authenticate($username, $password, $preventRebind = false) { // Prevent null binding if ($username === NULL || $password === NULL) { return false; } if (empty($username) || empty($password)) { return false; } // Allow binding over SSO for Kerberos if ($this->useSSO && $_SERVER['REMOTE_USER'] && $_SERVER['REMOTE_USER'] == $username && $this->adminUsername === NULL && $_SERVER['KRB5CCNAME']) { putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']); $this->ldapBind = @ldap_sasl_bind($this->ldapConnection, NULL, NULL, "GSSAPI"); if (!$this->ldapBind) { throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError()); } else { return true; } } // Bind as the user $ret = true; $this->ldapBind = @ldap_bind($this->ldapConnection, $username . $this->accountSuffix, $password); if (!$this->ldapBind) { $ret = false; } // Cnce we've checked their details, kick back into admin mode if we have it if ($this->adminUsername !== NULL && !$preventRebind) { $this->ldapBind = @ldap_bind($this->ldapConnection, $this->adminUsername . $this->accountSuffix, $this->adminPassword); if (!$this->ldapBind) { // This should never happen in theory throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError()); } } return $ret; }
/** * Bind connection with (SASL-) user and password * * @param string $authc Authentication user * @param string $pass Bind password * @param string $authz Autorization user * * @return boolean True on success, False on error */ public function sasl_bind($authc, $pass, $authz = null) { if (!$this->conn) { return false; } if (!function_exists('ldap_sasl_bind')) { raise_error(array('code' => 100, 'type' => 'ldap', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Unable to bind: ldap_sasl_bind() not exists"), true, true); } if (!empty($authz)) { $authz = 'u:' . $authz; } if (!empty($this->prop['auth_method'])) { $method = $this->prop['auth_method']; } else { $method = 'DIGEST-MD5'; } $this->_debug("C: Bind [mech: {$method}, authc: {$authc}, authz: {$authz}] [pass: {$pass}]"); if (ldap_sasl_bind($this->conn, NULL, $pass, $method, NULL, $authc, $authz)) { $this->_debug("S: OK"); return true; } $this->_debug("S: " . ldap_error($this->conn)); raise_error(array('code' => ldap_errno($this->conn), 'type' => 'ldap', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Bind failed for authcid={$authc} " . ldap_error($this->conn)), true); return false; }
<?php require "connect.inc"; $link = ldap_connect($host, $port); ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version); // Invalid parameter count var_dump(ldap_sasl_bind()); // Invalid DN var_dump(ldap_sasl_bind($link, "Invalid DN", $passwd, 'DIGEST-MD5', 'realm', $sasl_user)); // Invalid user var_dump(ldap_sasl_bind($link, null, "ThisIsNotCorrect{$passwd}", 'DIGEST-MD5', "realm", "invalid{$sasl_user}")); // Invalid password var_dump(ldap_sasl_bind($link, null, "ThisIsNotCorrect{$passwd}", 'DIGEST-MD5', "realm", $sasl_user)); var_dump(ldap_sasl_bind($link, null, $passwd, 'DIGEST-MD5', "realm", "Manager", "test")); // Invalid DN syntax var_dump(ldap_sasl_bind($link, "unexistingProperty=weirdValue,{$user}", $passwd)); ?> ===DONE===
/** * @param string $dn * @param string $password * @param string $saslMech * @param string $saslRealm * @param string $saslAuthcId * @param string $saslAuthzId * @param string $props * @throws UnavailableException * @throws BindFailureException */ public function saslBind($dn = null, $password = null, $saslMech = null, $saslRealm = null, $saslAuthcId = null, $saslAuthzId = null, $props = null) { $this->checkConnected(); if (!ldap_sasl_bind($this->link, $dn, $password, $saslMech, $saslRealm, $saslAuthcId, $saslAuthzId, $props)) { throw new BindFailureException(ldap_error($this->link), ldap_errno($this->link)); } $this->bound = true; }
/** * Bind connection with (SASL-) user and password * * @param string $authc Authentication user * @param string $pass Bind password * @param string $authz Autorization user * * @return boolean True on success, False on error */ public function sasl_bind($authc, $pass, $authz = null) { if (!$this->conn) { return false; } if (!function_exists('ldap_sasl_bind')) { $this->_error("LDAP: Unable to bind. ldap_sasl_bind() not exists"); return false; } if (!empty($authz)) { $authz = 'u:' . $authz; } $method = $this->config_get('auth_method'); if (empty($method)) { $method = 'DIGEST-MD5'; } $this->_debug("C: Bind [mech: {$method}, authc: {$authc}, authz: {$authz}]"); if (ldap_sasl_bind($this->conn, null, $pass, $method, null, $authc, $authz)) { $this->_debug("S: OK"); return true; } $this->_debug("S: " . ldap_error($this->conn)); $this->_error("LDAP: Bind failed for authcid={$authc}. " . ldap_error($this->conn)); return false; }
/** * If SASL is configured, then start it * To be able to use SASL, PHP should have been compliled with --with-ldap-sasl=DIR * * @todo This has not been tested, please let the developers know if this function works as expected. */ private function startSASL($resource, $method) { if (DEBUG_ENABLED && (($fargs = func_get_args()) || ($fargs = 'NOARGS'))) { debug_log('Entered (%%)', 17, 0, __FILE__, __LINE__, __METHOD__, $fargs); } static $CACHE = array(); switch (strtolower($this->getValue('sasl', 'mech'))) { case 'gssapi': if (isset($_ENV['REDIRECT_KRB5CCNAME'])) { putenv(sprintf('KRB5CCNAME={%s}', $_ENV['REDIRECT_KRB5CCNAME'])); } break; } if (!$this->getValue('server', 'sasl') || !function_exists('ldap_start_tls')) { return false; } if (!isset($CACHE['login_dn'])) { $CACHE['login_dn'] = is_null($this->getLogin($method)) ? $this->getLogin('user') : $this->getLogin($method); $CACHE['login_pass'] = is_null($this->getPassword($method)) ? $this->getPassword('user') : $this->getPassword($method); } # Do we need to rewrite authz_id? if (!isset($CACHE['authz_id'])) { if (!trim($this->getValue('sasl', 'authz_id'))) { if (DEBUG_ENABLED) { debug_log('Rewriting bind DN [%s] -> authz_id with regex [%s] and replacement [%s].', 9, 0, __FILE__, __LINE__, __METHOD__, $CACHE['login_dn'], $this->getValue('sasl', 'authz_id_regex'), $this->getValue('sasl', 'authz_id_replacement')); } $CACHE['authz_id'] = @preg_replace($this->getValue('sasl', 'authz_id_regex'), $this->getValue('sasl', 'authz_id_replacement'), $CACHE['login_dn']); # Invalid regex? if (is_null($CACHE['authz_id'])) { error(sprintf(_('It seems that sasl_authz_id_regex "%s" contains invalid PCRE regular expression. The error is "%s".'), $this->getValue('sasl', 'authz_id_regex'), isset($php_errormsg) ? $php_errormsg : ''), 'error', 'index.php'); } if (DEBUG_ENABLED) { debug_log('Resource [%s], SASL OPTIONS: mech [%s], realm [%s], authz_id [%s], props [%s]', 9, 0, __FILE__, __LINE__, __METHOD__, $resource, $this->getValue('sasl', 'mech'), $this->getValue('sasl', 'realm'), $CACHE['authz_id'], $this->getValue('sasl', 'props')); } } else { $CACHE['authz_id'] = $this->getValue('sasl', 'authz_id'); } } # @todo this function is different in PHP5.1 and PHP5.2 return @ldap_sasl_bind($resource, $CACHE['login_dn'], $CACHE['login_pass'], $this->getValue('sasl', 'mech'), $this->getValue('sasl', 'realm'), $CACHE['authz_id'], $this->getValue('sasl', 'props')); }
/** * Setup LDAP connection * * @param string $user * @param string $pass * * @return bool * * @throws \Comodojo\Exception\LdaphException */ private function setupConnection($user = null, $pass = null) { $this->ldaph = $this->ssl ? ldap_connect("ldaps://" . $this->server, $this->port) : ldap_connect($this->server, $this->port); if (!$this->ldaph) { throw new LdaphException(ldap_error($this->ldaph), 1403); } ldap_set_option($this->ldaph, LDAP_OPT_PROTOCOL_VERSION, $this->version); ldap_set_option($this->ldaph, LDAP_OPT_REFERRALS, 0); if ($this->tls) { $tls = @ldap_start_tls($this->ldaph); if ($tls === false) { throw new LdaphException(ldap_error($this->ldaph), 1403); } } if ($this->sso and $_SERVER['REMOTE_USER'] and $_SERVER["REMOTE_USER"] == $user and $_SERVER["KRB5CCNAME"]) { putenv("KRB5CCNAME=" . $_SERVER["KRB5CCNAME"]); $bind = @ldap_sasl_bind($this->ldaph, null, null, "GSSAPI"); } elseif (is_null($user) or is_null($pass)) { $bind = @ldap_bind($this->ldaph); } else { $user_dn = str_replace('USERNAME', $user, $this->dn); $bind = @ldap_bind($this->ldaph, $user_dn, $pass); } if (!$bind) { throw new LdaphException(ldap_error($this->ldaph), 1402); } return true; }
/** * Bind to LDAP directory using SASL * * @param string $bindDn * @param string $bindPassword * @param string $saslMech * @param string $saslRealm * @param string $saslAuthcId * @param string $saslAuthzId * @param string $props * @return self */ public function saslBind($bindDn = null, $bindPassword = null, $saslMech = null, $saslRealm = null, $saslAuthcId = null, $saslAuthzId = null, $props = null) { @ldap_sasl_bind($this->resource, $bindDn, $bindPassword, $saslMech, $saslRealm, $saslAuthcId, $saslAuthzId, $props); $this->verifyOperation(); return $this; }
/** * Tries to bind using SASL. * * @param string $userDN DN to bind as * @param string $password password to use * @param string $saslMech optionally selected SASL mech * @param string $saslRealm optionally selected SASL realm * @return server current instance */ public function bindAs($dn, $password, $saslMech, $saslRealm) { $this->boundAs = @ldap_sasl_bind($this->link, $dn, $password, $saslMech, $saslRealm) ? $dn : false; return $this; }
/** * Validate a user's login credentials * * @param string $username A user's AD username * @param string $password A user's AD password * @param bool optional $preventRebind * @return bool */ public function authenticate($username, $password, $preventRebind = false) { // Prevent null binding if ($username === NULL || $password === NULL) { return false; } if (empty($username) || empty($password)) { return false; } try { $user = \App\User::where('uid', $username)->firstOrFail(); } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) { $user = null; } if ($user != null) { if (password_verify($password, $user->password)) { // Password is correct return true; } else { // Password is incorrect $passwordMismatch = true; } } if ($user == null || $passwordMismatch) { // If user's not in our database // or the passwords didn't match, check LDAP // Allow binding over SSO for Kerberos if ($this->useSSO && $_SERVER['REMOTE_USER'] && $_SERVER['REMOTE_USER'] == $username && $this->adminUsername === NULL && $_SERVER['KRB5CCNAME']) { putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']); $this->ldapBind = @ldap_sasl_bind($this->ldapConnection, NULL, NULL, "GSSAPI"); if (!$this->ldapBind) { throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError()); } else { return true; } } // Bind as the user $ret = true; $groups = explode(',', env("LDAP_GROUPS")); $baseDN = $this->getBaseDn(); foreach ($groups as $group) { // Check all groups for a binding $this->ldapBind = @ldap_bind($this->ldapConnection, "cn=" . $username . ",cn=" . $group . "," . $baseDN . $this->accountSuffix, $password); if ($this->ldapBind) { // If we find a match, break out of the loop break; } } if (!$this->ldapBind) { $ret = false; } // Cnce we've checked their details, kick back into admin mode if we have it if ($this->adminUsername !== NULL && !$preventRebind) { $this->ldapBind = @ldap_bind($this->ldapConnection, $this->adminUsername . $this->accountSuffix, $this->adminPassword); if (!$this->ldapBind) { // This should never happen in theory throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError()); } } return $ret; } }
/** * Initializes a new connection to CIF LDAP. * This method is protected to ensure that new CifLdap instances * can't be created with the `new` keyword. */ protected function __construct() { if (!putenv('LDAPTLS_CACERT=' . self::TLS_CERT)) { trigger_error('Unable to set TLS certificate', E_USER_WARNING); } $this->log('Connecting to CIF LDAP.'); self::$connection = ldap_connect(self::LDAP_SERVER); if (!self::$connection) { $this->log_and_except('Unable to open connection to CIF LDAP.'); } if (self::DEBUG) { ldap_set_option(self::$connection, LDAP_OPT_DEBUG_LEVEL, 7); } if (!ldap_start_tls(self::$connection)) { $this->log_and_except('Unable to secure CIF LDAP connection.'); } ldap_set_option(self::$connection, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option(self::$connection, LDAP_OPT_REFERRALS, 0); // Don't follow referals from the server $this->log('Binding to CIF LDAP.'); if (!ldap_sasl_bind(self::$connection, null, null, 'GSSAPI', null, null, null, 'maxssf=1')) { $this->log_and_except('Unable to perform SASL bind to CIF LDAP.'); } }
/** * @link http://php.net/manual/en/function.ldap-sasl-bind.php * @param $link * @param null $binddn * @param null $password * @param null $saslMech * @param null $saslRealm * @param null $saslAuthcId * @param null $saslAuthzId * @param null $props * @return bool */ public function saslBind($link, $binddn = null, $password = null, $saslMech = null, $saslRealm = null, $saslAuthcId = null, $saslAuthzId = null, $props = null) { return ldap_sasl_bind($link, $binddn, $password, $saslMech, $saslRealm, $saslAuthcId, $saslAuthzId, $props); }
/** * Binds to the current LDAP connection. If SASL * is true, we'll set up a SASL bind instead. * * @param string $username * @param string $password * @param bool $sasl * * @return bool */ public function bind($username, $password, $sasl = false) { if ($sasl) { if ($this->suppressErrors) { return $this->bound = @ldap_sasl_bind($this->getConnection(), null, null, 'GSSAPI'); } return $this->bound = ldap_sasl_bind($this->getConnection(), null, null, 'GSSAPI'); } else { if ($this->suppressErrors) { return $this->bound = @ldap_bind($this->getConnection(), $username, $password); } return $this->bound = ldap_bind($this->getConnection(), $username, $password); } }
/** * Validate a user's login credentials * * @param string $username A user's AD username * @param string $password A user's AD password * @param bool optional $preventRebind * @return bool */ public function authenticate($username, $password, $preventRebind = false) { $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": Auth as {$username}"; // Prevent null binding if ($username === NULL || $password === NULL) { $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": username or password is null... [" . basename(__FILE__) . "]"; return false; } if (empty($username) || empty($password)) { $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": username or password is empty... [" . basename(__FILE__) . "]"; return false; } // Allow binding over SSO for Kerberos if ($this->useSSO && $_SERVER['REMOTE_USER'] && $_SERVER['REMOTE_USER'] == $username && $this->adminUsername === NULL && $_SERVER['KRB5CCNAME']) { putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']); $this->ldapBind = @ldap_sasl_bind($this->ldapConnection, NULL, NULL, "GSSAPI"); if (!$this->ldapBind) { $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ":Rebind to Active Directory failed. AD said: " . $this->getLastError(); throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError()); } else { $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ":useSSO -> TRUE"; return true; } } // Bind as the user $ret = true; $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": ->ldap_bind({$username}{$this->accountSuffix},{$password})"; $this->ldapBind = @ldap_bind($this->ldapConnection, $username . $this->accountSuffix, $password); if (!$this->ldapBind) { $ret = false; $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": ->ldap_bind(.. FAILED [" . basename(__FILE__) . "]"; $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": " . $this->getLastError() . " [" . basename(__FILE__) . "]"; } // Cnce we've checked their details, kick back into admin mode if we have it if ($this->adminUsername !== NULL && !$preventRebind) { $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": ->ldap_bind({$this->adminUsername},{$this->adminPassword})"; $this->ldapBind = @ldap_bind($this->ldapConnection, $this->adminUsername . $this->accountSuffix, $this->adminPassword); if (!$this->ldapBind) { $GLOBALS["CLASS_ACTV"][] = __FUNCTION__ . ": LINE:" . __LINE__ . ": -> Rebind to Active Directory failed [" . basename(__FILE__) . "]"; throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError()); } } return $ret; }
<?php require "connect.inc"; $link = ldap_connect($host, $port); ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version); var_dump(ldap_sasl_bind($link, null, $passwd, 'DIGEST-MD5', 'realm', $sasl_user)); ?> ===DONE===
/** * {@inheritdoc} */ public function bind($username, $password, $sasl = false) { if ($this->isUsingTLS()) { $this->startTLS(); } if ($sasl) { return $this->bound = ldap_sasl_bind($this->getConnection(), null, null, 'GSSAPI'); } return $this->bound = ldap_bind($this->getConnection(), $username, $password); }
/** * 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::debug('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 . '\''); }
/** * If SASL is configured, then start it * To be able to use SASL, PHP should have been compliled with --with-ldap-sasl=DIR * * @todo This has not been tested, please let the developers know if this function works as expected. */ private function startSASL($resource, $method) { if (DEBUG_ENABLED && (($fargs = func_get_args()) || ($fargs = 'NOARGS'))) { debug_log('Entered (%%)', 17, 0, __FILE__, __LINE__, __METHOD__, $fargs); } static $CACHE = array(); # We shouldnt be doing SASL binds for anonymous queries? if ($method == 'anon') { return false; } # At the moment, we have only implemented GSSAPI if (!in_array(strtolower($this->getValue('sasl', 'mech')), array('gssapi'))) { system_message(array('title' => _('SASL Method not implemented'), 'body' => sprintf('<b>%s</b>: %s %s', _('Error'), $this->getValue('sasl', 'mech'), _('has not been implemented yet')), 'type' => 'error')); return false; } if (!isset($CACHE['login_dn'])) { $CACHE['login_dn'] = is_null($this->getLogin($method)) ? $this->getLogin('user') : $this->getLogin($method); } $CACHE['authz_id'] = ''; /* # Do we need to rewrite authz_id? if (! isset($CACHE['authz_id'])) if (! trim($this->getValue('sasl','authz_id')) && strtolower($this->getValue('sasl','mech')) != 'gssapi') { if (DEBUG_ENABLED) debug_log('Rewriting bind DN [%s] -> authz_id with regex [%s] and replacement [%s].',9,0,__FILE__,__LINE__,__METHOD__, $CACHE['login_dn'], $this->getValue('sasl','authz_id_regex'), $this->getValue('sasl','authz_id_replacement')); $CACHE['authz_id'] = @preg_replace($this->getValue('sasl','authz_id_regex'), $this->getValue('sasl','authz_id_replacement'),$CACHE['login_dn']); # Invalid regex? if (is_null($CACHE['authz_id'])) error(sprintf(_('It seems that sasl_authz_id_regex "%s" contains invalid PCRE regular expression. The error is "%s".'), $this->getValue('sasl','authz_id_regex'),(isset($php_errormsg) ? $php_errormsg : '')), 'error','index.php'); if (DEBUG_ENABLED) debug_log('Resource [%s], SASL OPTIONS: mech [%s], realm [%s], authz_id [%s], props [%s]',9,0,__FILE__,__LINE__,__METHOD__, $resource, $this->getValue('sasl','mech'), $this->getValue('sasl','realm'), $CACHE['authz_id'], $this->getValue('sasl','props')); } else $CACHE['authz_id'] = $this->getValue('sasl','authz_id'); */ # @todo this function is different in PHP5.1 and PHP5.2 return @ldap_sasl_bind($resource, NULL, '', $this->getValue('sasl', 'mech'), $this->getValue('sasl', 'realm'), $CACHE['authz_id'], $this->getValue('sasl', 'props')); }