Author: Andreas Aakre Solberg, UNINETT AS. (andreas.solberg@uninett.no)
Author: Anders Lund, UNINETT AS. (anders.lund@uninett.no)
 /**
  * Construct
  *
  * @param array $authSourceconfig Configuration array for the selected authsource
  * @param array $ldapWriteConfig Configuration array for the selected catalogue backend
  * @param array $attributes The user attributes to be saved
  */
 public function __construct($authSourceConfig, $ldapWriteConfig, $attributes)
 {
     $asc = SimpleSAML_Configuration::loadFromArray($authSourceConfig);
     parent::__construct($asc->getString('hostname'), $asc->getBoolean('enable_tls', FALSE), $asc->getBoolean('debug', FALSE), $asc->getInteger('timeout', 0));
     $this->searchBase = $asc->getArrayize('search.base');
     $this->dnPattern = $asc->getString('dnpattern');
     $this->searchDn = $asc->getString('search.username', NULL);
     $this->searchPw = $asc->getString('search.password', NULL);
     $lwc = SimpleSAML_Configuration::loadFromArray($ldapWriteConfig);
     $this->adminDn = $lwc->getString('admin.dn');
     $this->adminPw = $lwc->getString('admin.pw');
     $this->objectClass = $lwc->getArray('objectClass');
     $this->userIdAttr = $lwc->getString('user.id.param', 'uid');
     $this->pswEncrypt = $lwc->getString('psw.encrypt', 'sha1');
     $this->attributes = $attributes;
 }
Exemple #2
0
if (!array_key_exists('RelayState', $_REQUEST)) {
    SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NORELAYSTATE');
}
if (isset($_POST['username'])) {
    try {
        $ldapconfig = $ldapmulti[$_POST['org']];
        if ($ldapconfig['search.enable'] === TRUE) {
            if (!$ldap->bind($ldapconfig['search.username'], $ldapconfig['search.password'])) {
                throw new Exception('Error authenticating using search username & password.');
            }
            $dn = $ldap->searchfordn($ldapconfig['search.base'], $ldapconfig['search.attributes'], $_POST['username']);
        } else {
            $dn = str_replace('%username%', $_POST['username'], $ldapconfig['dnpattern']);
        }
        $pwd = $_POST['password'];
        $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['hostname'], $ldapconfig['enable_tls']);
        if ($pwd == "" or !$ldap->bind($dn, $pwd)) {
            SimpleSAML_Logger::info('AUTH - ldap-multi: ' . $_POST['username'] . ' failed to authenticate. DN=' . $dn);
            throw new Exception('Wrong username or password');
        }
        $attributes = $ldap->getAttributes($dn, $ldapconfig['attributes']);
        SimpleSAML_Logger::info('AUTH - ldap-multi: ' . $_POST['username'] . ' successfully authenticated');
        $session->doLogin('login-ldapmulti');
        $session->setAttributes($attributes);
        $session->setNameID(array('value' => SimpleSAML_Utilities::generateID(), 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'));
        /**
         * Create a statistics log entry for every successfull login attempt.
         * Also log a specific attribute as set in the config: statistics.authlogattr
         */
        $authlogattr = $config->getValue('statistics.authlogattr', null);
        if ($authlogattr && array_key_exists($authlogattr, $attributes)) {
    }
    $ldapconfig = $casldapconfig[$idpentityid]['ldap'];
} catch (Exception $exception) {
    throw new SimpleSAML_Error_Error('METADATA', $exception);
}
/*
 * Load the RelayState argument. The RelayState argument contains the address
 * we should redirect the user to after a successful authentication.
 */
if (!array_key_exists('RelayState', $_REQUEST)) {
    throw new SimpleSAML_Error_Error('NORELAYSTATE');
}
$relaystate = SimpleSAML_Utilities::checkURLAllowed($_REQUEST['RelayState']);
if ($username = $_POST['username']) {
    try {
        $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['servers'], $ldapconfig['enable_tls']);
        $attributes = $ldap->validate($ldapconfig, $username, $_POST['password']);
        if ($attributes === FALSE) {
            $error = "LDAP_INVALID_CREDENTIALS";
        } else {
            $session->doLogin('login-wayf-ldap');
            $session->setAttributes($attributes);
            $session->setNameID(array('value' => SimpleSAML_Utilities::generateID(), 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'));
            SimpleSAML_Utilities::redirectTrustedURL($relaystate);
        }
    } catch (Exception $e) {
        throw new SimpleSAML_Error_Error('LDAPERROR', $e);
    }
}
$t = new SimpleSAML_XHTML_Template($config, $ldapconfig['template']);
$t->data['header'] = 'simpleSAMLphp: Enter username and password';
 /**
  * Add attributes from an LDAP server.
  *
  * @param array &$request The current request
  */
 public function process(&$request)
 {
     assert('is_array($request)');
     assert('array_key_exists("Attributes", $request)');
     $attributes =& $request['Attributes'];
     // perform a merge on the ldap_search_filter
     // loop over the attributes and build the search and replace arrays
     foreach ($attributes as $attr => $val) {
         $arrSearch[] = '%' . $attr . '%';
         if (strlen($val[0]) > 0) {
             $arrReplace[] = SimpleSAML_Auth_LDAP::escape_filter_value($val[0]);
         } else {
             $arrReplace[] = '';
         }
     }
     // merge the attributes into the ldap_search_filter
     $filter = str_replace($arrSearch, $arrReplace, $this->search_filter);
     if (strpos($filter, '%') !== FALSE) {
         SimpleSAML_Logger::info('AttributeAddFromLDAP: There are non-existing attributes in the search filter. (' . $this->search_filter . ')');
         return;
     }
     if (!in_array($this->attr_policy, array('merge', 'replace', 'add'))) {
         SimpleSAML_Logger::warning("AttributeAddFromLDAP: 'attribute.policy' must be one of 'merge'," . "'replace' or 'add'.");
         return;
     }
     // search for matching entries
     try {
         $entries = $this->getLdap()->searchformultiple($this->base_dn, $filter, array_values($this->search_attributes), TRUE, FALSE);
     } catch (Exception $e) {
         return;
         // silent fail, error is still logged by LDAP search
     }
     // handle [multiple] values
     foreach ($entries as $entry) {
         foreach ($this->search_attributes as $target => $name) {
             if (is_numeric($target)) {
                 $target = $name;
             }
             if (isset($attributes[$target]) && $this->attr_policy === 'replace') {
                 unset($attributes[$target]);
             }
             $name = strtolower($name);
             if (isset($entry[$name])) {
                 unset($entry[$name]['count']);
                 if (isset($attributes[$target])) {
                     foreach (array_values($entry[$name]) as $value) {
                         if ($this->attr_policy === 'merge') {
                             if (!in_array($value, $attributes[$target])) {
                                 $attributes[$target][] = $value;
                             }
                         } else {
                             $attributes[$target][] = $value;
                         }
                     }
                 } else {
                     $attributes[$target] = array_values($entry[$name]);
                 }
             }
         }
     }
 }
 public function getAttributes($dn, $attributes = NULL)
 {
     if ($attributes == NULL) {
         $attributes = $this->attributes;
     }
     $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout, $this->port, $this->referrals);
     /* 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, $attributes);
 }
                }
                $casusername = $success->item(0)->textContent;
                return array($casusername, $attributes);
            }
        } else {
            throw new Exception("validate or serviceValidate not specified");
        }
        /**
         * First request, will redirect the user to the CAS server for authentication.
         */
    } else {
        SimpleSAML_Logger::info("AUTH - cas-ldap: redirecting to {$cas['login']}");
        SimpleSAML_Utilities::redirectTrustedURL($cas['login'], array('service' => $service));
    }
}
try {
    list($username, $casattributes) = casValidate($casconfig);
    SimpleSAML_Logger::info('AUTH - cas-ldap: ' . $username . ' authenticated by ' . $casconfig['validate']);
    $ldapattributes = array();
    if ($ldapconfig['servers']) {
        $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['servers'], $ldapconfig['enable_tls']);
        $ldapattributes = $ldap->validate($ldapconfig, $username);
    }
    $attributes = array_merge_recursive($casattributes, $ldapattributes);
    $session->doLogin('login-cas-ldap');
    $session->setAttributes($attributes);
    $session->setNameID(array('value' => SimpleSAML_Utilities::generateID(), 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'));
    SimpleSAML_Utilities::redirectUntrustedURL($_REQUEST['RelayState']);
} catch (Exception $exception) {
    throw new SimpleSAML_Error_Error('CASERROR', $exception);
}
Exemple #7
0
 public function getAttributes($dn, $attributes = NULL)
 {
     if ($attributes == NULL) {
         $attributes = $this->attributes;
     }
     $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout);
     return $ldap->getAttributes($dn, $attributes);
 }
 /**
  * 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, $this->port, $this->referrals);
     if (!$this->searchEnable) {
         $ldapusername = addcslashes($username, ',+"\\<>;*');
         $dn = str_replace('%username%', $ldapusername, $this->dnPattern);
     } else {
         if ($this->searchUsername !== NULL) {
             if (!$ldap->bind($this->searchUsername, $this->searchPassword)) {
                 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');
         }
     }
     $qaLogin = SimpleSAML_Auth_Source::getById('auth2factor');
     if (!$ldap->bind($dn, $password, $sasl_args)) {
         SimpleSAML_Logger::info($this->location . ': ' . $username . ' failed to authenticate. DN=' . $dn);
         /* Account lockout feature */
         // we need mail attributes so that we can notify user of locked account
         $attributes = $ldap->getAttributes($dn, $this->searchAttributes);
         // TODO what if these attributes are not available for search or not set in config?
         $qaLogin->failedLoginAttempt($username, 'login_count', array('name' => $attributes['givenName'][0], 'mail' => $attributes['mail'][0], 'uid' => $attributes['uid'][0]));
         $failedAttempts = $qaLogin->getFailedAttempts($username);
         $loginCount = (int) (!empty($failedAttempts)) ? $failedAttempts[0]['login_count'] : 0;
         $answerCount = (int) (!empty($failedAttempts)) ? $failedAttempts[0]['answer_count'] : 0;
         $failCount = $loginCount + $answerCount;
         // TODO this is bad! what if maxFailLogin is not set (i.e 0) or less than 3? instant lock?
         $firstFailCount = $qaLogin->getmaxFailLogin() - 2;
         $secondFailCount = $qaLogin->getmaxFailLogin() - 1;
         if ($failCount == $firstFailCount) {
             throw new SimpleSAML_Error_Error('2FAILEDATTEMPTWARNING');
         }
         if ($failCount == $secondFailCount) {
             throw new SimpleSAML_Error_Error('1FAILEDATTEMPTWARNING');
         }
         if ($qaLogin->isLocked($username)) {
             throw new SimpleSAML_Error_Error('ACCOUNTLOCKED');
         }
         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.');
         }
     }
     // if we are here - we must have logged in successfully .. therefore reset login attempts
     $qaLogin->resetFailedLoginAttempts($username, 'login_count');
     return $ldap->getAttributes($dn, $this->attributes);
 }
Exemple #9
0
 /**
  * Called by linkback, to finish validate/ finish logging in.
  * @param state $state
  * @return list username, casattributes/ldap attributes
  */
 public function finalStep(&$state)
 {
     $ticket = $state['cas:ticket'];
     $stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT);
     $service = SimpleSAML_Module::getModuleURL('cas/linkback.php', array('stateID' => $stateID));
     list($username, $casattributes) = $this->casValidation($ticket, $service);
     $ldapattributes = array();
     if ($this->_ldapConfig['servers']) {
         $ldap = new SimpleSAML_Auth_LDAP($this->_ldapConfig['servers'], $this->_ldapConfig['enable_tls']);
         $ldapattributes = $ldap->validate($this->_ldapConfig, $username);
     }
     $attributes = array_merge_recursive($casattributes, $ldapattributes);
     $state['Attributes'] = $attributes;
     SimpleSAML_Auth_Source::completeAuth($state);
 }
Exemple #10
0
 /**
  * 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) {
             if (!$ldap->bind($this->searchUsername, $this->searchPassword)) {
                 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);
 }
 if (!array_key_exists('password', $_POST)) {
     $error = 'error_nopassword';
     continue;
 }
 $username = $_POST['username'];
 $password = $_POST['password'];
 /* Escape any characters with a special meaning in LDAP. The following
  * characters have a special meaning (according to RFC 2253):
  * ',', '+', '"', '\', '<', '>', ';', '*'
  * These characters are escaped by prefixing them with '\'.
  */
 $ldapusername = addcslashes($username, ',+"\\<>;*');
 /*
  * Connecting to LDAP.
  */
 $ldap = new SimpleSAML_Auth_LDAP($ldapconfig->getValue('auth.ldap.hostname'), $ldapconfig->getValue('auth.ldap.enable_tls'));
 if ($ldapconfig->getValue('auth.ldap.search.enable', FALSE)) {
     /* We are configured to search for the users dn. */
     $searchUsername = $ldapconfig->getValue('auth.ldap.search.username', NULL);
     if ($searchUsername !== NULL) {
         /* Log in with username & password for searching. */
         $searchPassword = $ldapconfig->getValue('auth.ldap.search.password', NULL);
         if ($searchPassword === NULL) {
             throw new Exception('"auth.ldap.search.username" is configured, but not' . ' "auth.ldap.search.password".');
         }
         if (!$ldap->bind($searchUsername, $searchPassword)) {
             throw new Exception('Error authenticating using search username & password.');
         }
     }
     $searchBase = $ldapconfig->getValue('auth.ldap.search.base', NULL);
     $searchAttributes = $ldapconfig->getValue('auth.ldap.search.attributes', NULL);
 /**
  * Add attributes from an LDAP server.
  *
  * @param array &$request  The current request
  */
 public function process(&$request)
 {
     assert('is_array($request)');
     assert('array_key_exists("Attributes", $request)');
     $attributes =& $request['Attributes'];
     $map =& $this->attribute_map;
     if (!isset($attributes[$map['username']])) {
         throw new Exception('The user\'s identity does not have an attribute called "' . $map['username'] . '"');
     }
     // perform a merge on the ldap_search_filter
     // loop over the attributes and build the search and replace arrays
     foreach ($attributes as $attr => $val) {
         $arrSearch[] = '%' . $attr . '%';
         if (strlen($val[0]) > 0) {
             $arrReplace[] = SimpleSAML_Auth_LDAP::escape_filter_value($val[0]);
         } else {
             $arrReplace[] = '';
         }
     }
     // merge the attributes into the ldap_search_filter
     $filter = str_replace($arrSearch, $arrReplace, $this->search_filter);
     // search for matching entries
     $entries = $this->getLdap()->searchformultiple($this->base_dn, $filter, (array) $this->search_attribute, TRUE, FALSE);
     // handle [multiple] values
     if (is_array($entries) && is_array($entries[0])) {
         $results = array();
         foreach ($entries as $entry) {
             $entry = $entry[strtolower($this->search_attribute)];
             for ($i = 0; $i < $entry['count']; $i++) {
                 $results[] = $entry[$i];
             }
         }
         $attributes[$this->new_attribute] = array_values($results);
     }
 }
 /**
  * Add attributes from an LDAP server.
  *
  * @param array &$request  The current request
  */
 public function process(&$request)
 {
     assert('is_array($request)');
     assert('array_key_exists("Attributes", $request)');
     $attributes =& $request['Attributes'];
     if (!isset($attributes[$this->config['userid_attribute']])) {
         throw new Exception('The user\'s identity does not have an attribute called "' . $this->config['userid_attribute'] . '"');
     }
     // perform a merge on the ldap_search_filter
     // loop over the attributes and build the search and replace arrays
     foreach ($attributes as $attr => $val) {
         $arrSearch[] = '%' . $attr . '%';
         if (strlen($val[0]) > 0) {
             $arrReplace[] = SimpleSAML_Auth_LDAP::escape_filter_value($val[0]);
         } else {
             $arrReplace[] = '';
         }
     }
     // merge the attributes into the ldap_search_filter
     $merged_ldap_search_filter = str_replace($arrSearch, $arrReplace, $this->config['ldap_search_filter']);
     // connect to the LDAP directory
     $ds = ldap_connect($this->config['ldap_host'], $this->config['ldap_port']);
     if (!$ds) {
         throw new Exception('Failed to initialize LDAP connection parameters (' . ldap_error(NULL) . ')');
     }
     ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
     // if we're supposed to bind as a specified user
     if (isset($this->config['ldap_bind_user']) && $this->config['ldap_bind_user'] && (isset($this->config['ldap_bind_pwd']) && $this->config['ldap_bind_pwd'])) {
         // bind to the directory as the specified user
         if (!ldap_bind($ds, $this->config['ldap_bind_user'], $this->config['ldap_bind_pwd'])) {
             throw new Exception($this->config['ldap_bind_user'] . ' failed to bind against ' . $this->config['ldap_host'] . ' (' . ldap_error($ds) . ')');
         }
     } else {
         // bind to the directory anonymously
         if (!ldap_bind($ds)) {
             throw new Exception('Failed to anonymously bind against ' . $this->config['ldap_host'] . ' (' . ldap_error($ds) . ')');
         }
     }
     // search for matching entries
     $sr = ldap_search($ds, $this->config['ldap_search_base_dn'], $merged_ldap_search_filter, array($this->config['ldap_search_attribute']));
     $entries = ldap_get_entries($ds, $sr);
     // handle [multiple] values
     if (is_array($entries) && is_array($entries[0])) {
         $entry = $entries[0][strtolower($this->config['ldap_search_attribute'])];
         $results = array();
         for ($i = 0; $i < $entry['count']; $i++) {
             $results[] = $entry[$i];
         }
         $attributes[$this->config['new_attribute_name']] = array_values($results);
     }
     ldap_unbind($ds);
 }
Exemple #14
0
 }
 $orgconfig = $ldaporgconfig[$requestedOrg];
 /*
  * Checking password parameter.
  */
 if (empty($_REQUEST['password'])) {
     throw new Exception('The password field was left empty. Please fill in a valid password.');
 }
 $password = $_REQUEST['password'];
 if (!preg_match('/^[a-zA-Z0-9.]+$/', $password)) {
     throw new Exception('Illegal characters in password.');
 }
 /*
  * Connecting to LDAP.
  */
 $ldap = new SimpleSAML_Auth_LDAP($orgconfig['hostname'], $orgconfig['enable_tls']);
 /*
  * Search for eduPersonPrincipalName.
  */
 if (isset($orgconfig['adminUser'])) {
     $ldap->bind($orgconfig['adminUser'], $orgconfig['adminPassword']);
 }
 $eppn = $requestedUser . "@" . $requestedOrg;
 $dn = $ldap->searchfordn($orgconfig['searchbase'], 'eduPersonPrincipalName', $eppn);
 /*
  * Do LDAP bind using DN found from the search on ePPN.
  */
 if (!$ldap->bind($dn, $password)) {
     SimpleSAML_Logger::info('AUTH - ldap-feide: ' . $requestedUser . ' failed to authenticate. DN=' . $dn);
     throw new Exception('Wrong username or password');
 }