diff --git a/lib/SimpleSAML/Auth/LDAP.php b/lib/SimpleSAML/Auth/LDAP.php new file mode 100644 index 0000000000000000000000000000000000000000..a159f3e99ae0f6bf265b055304fa916a71345a8e --- /dev/null +++ b/lib/SimpleSAML/Auth/LDAP.php @@ -0,0 +1,130 @@ +<?php + +require_once('SimpleSAML/Configuration.php'); +require_once('SimpleSAML/Utilities.php'); + +/** + * The LDAP class holds helper functions to access an LDAP database. + * + * @author Andreas Ĺkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @author Anders Lund, UNINETT AS. <anders.lund@uninett.no> + * @package simpleSAMLphp + * @version $Id: Session.php 244 2008-02-04 08:36:24Z andreassolberg $ + */ +class SimpleSAML_Auth_LDAP { + + + /** + * LDAP link + */ + private static $ldap = null; + + + /** + * Logger class. + */ + private static $logger = null; + + /** + * private constructor restricts instantiaton to getInstance() + */ + public function __construct($hostname) { + + if (!isset($this->logger)) $this->logger = new SimpleSAML_Logger(); + + + $this->ldap = @ldap_connect($hostname); + if (empty($this->ldap)) + throw new Exception('Could not connect to LDAP server. Please try again, and if the problem persists, please report the error.'); + + $this->setV3(); + + } + + /** + * Set LDAP version 3 option on the connection handler. Will throw an error if not possible. + */ + private function setV3() { + // Give error if LDAPv3 is not supported + if (!@ldap_set_option($this->ldap, LDAP_OPT_PROTOCOL_VERSION, 3)) + throw new Exception('Failed to set LDAP Protocol version to 3: ' . ldap_error($this->ldap) ); + } + + + public function searchfordn($searchbase, $searchattr, $searchvalue) { + // Search for ePPN + $search = '(' . $searchattr . '=' . $searchvalue. ')'; + $search_result = @ldap_search($this->ldap, $searchbase, $search); + + if ($search_result === false) { + throw new Exception('Failed performing a LDAP search: ' . ldap_error($this->ldap) . ' search:' . $search); + } + + // Check number of entries. ePPN should be unique! + if (@ldap_count_entries($this->ldap, $search_result) > 1 ) + throw new Exception("Found multiple entries in LDAP search: " . $search . ' base: ' . $searchbase); + + if (@ldap_count_entries($this->ldap, $search_result) == 0) + throw new Exception('LDAP search returned zero entries: ' . $search . ' base: ' . $searchbase); + + // Authenticate user and fetch attributes + $entry = ldap_first_entry($this->ldap, $search_result); + + if (empty($entry)) + throw new Exception('Could not retrieve result of LDAP search: ' . $search); + + $dn = @ldap_get_dn($this->ldap, $entry); + + if (empty($dn)) + throw new Exception('Error retrieving DN from search result.'); + + return $dn; + + } + + /** + * Bind to LDAP with a specific DN and password. + */ + public function bind($dn, $password) { + if (@ldap_bind($this->ldap, $dn, $password)) { + return true; + } + return false; + } + + + /** + * Search DN for attributes, and return associative array. + */ + public function getAttributes($dn, $search) { + + + $sr = @ldap_read($this->ldap, $dn, $search ); + + if ($sr === false) + throw new Exception('Could not retrieve attribtues for user:' . ldap_error($this->ldap)); + + $ldapentries = @ldap_get_entries($this->ldap, $sr); + + if ($ldapentries === false) + throw new Exception('Could not retrieve results from attribute retrieval for user:' . ldap_error($this->ldap)); + + + $attributes = array(); + for ($i = 0; $i < $ldapentries[0]['count']; $i++) { + $values = array(); + if ($ldapentries[0][$i] == 'jpegphoto') continue; + for ($j = 0; $j < $ldapentries[0][$ldapentries[0][$i]]['count']; $j++) { + $values[] = $ldapentries[0][$ldapentries[0][$i]][$j]; + } + + $attributes[$ldapentries[0][$i]] = $values; + } + return $attributes; + + } + + +} + +?> \ No newline at end of file diff --git a/www/auth/login-feide.php b/www/auth/login-feide.php index 8ee5a78bacbcbb719ec3004dfff220bf1789bfac..394ac3ad9a70b1f2a62e2e60df19649533a37604 100644 --- a/www/auth/login-feide.php +++ b/www/auth/login-feide.php @@ -8,6 +8,8 @@ require_once('SimpleSAML/Logger.php'); require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); require_once('SimpleSAML/XHTML/Template.php'); +require_once('SimpleSAML/Auth/LDAP.php'); + $config = SimpleSAML_Configuration::getInstance(); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $session = SimpleSAML_Session::getInstance(); @@ -89,87 +91,27 @@ if (isset($_REQUEST['username'])) { /* * Connecting to LDAP */ - - $search_eppn = "(eduPersonPrincipalName=".$requestedUser."@".$requestedOrg.")"; - - $ds = @ldap_connect($ldapconfig['hostname']); - - if (empty($ds)) { - throw new Exception('Could not connect to LDAP server. Please try again, and if the problem persists, please report the error.'); - } - - - // Give error if LDAPv3 is not supported - if (!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) { - $logger->log(LOG_CRIT, $session->getTrackID(), 'AUTH', 'ldap-feide', 'LDAP_OPT_PROTOCOL_VERSION', '3', - 'Error setting LDAP prot version to 3'); - throw new Exception('Failed to set LDAP Protocol version to 3: ' . ldap_error($ds) ); - } - - // Search for ePPN - $eppn_result = @ldap_search($ds, $ldapconfig['searchbase'], $search_eppn); + $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['hostname']); - if ($eppn_result === false) - throw new Exception('Failed performing a LDAP search: ' . ldap_error($ds) . ' search:' . $search_eppn); + /** + * Search for edupersonprincipalname + */ + $eppn = $requestedUser."@".$requestedOrg; + $dn = $ldap->searchfordn($ldapconfig['searchbase'],'eduPersonPrincipalName', $eppn); - // Check number of entries. ePPN should be unique! - if (ldap_count_entries($ds, $eppn_result) > 1 ) { - throw new Exception("Din organisasjon (".$requestedOrg.") har feilregistrert flere like FEIDE-navn."); + /** + * Bind as user + */ + if (!$ldap->bind($dn, $password)) { + $logger->log(LOG_NOTICE, $session->getTrackID(), 'AUTH', 'ldap-feide', 'Fail', $username, $username . ' failed to authenticate. DN=' . $dn); + throw new Exception('Wrong username or password'); } - if (ldap_count_entries($ds, $eppn_result) == 0) { - throw new Exception('User could not be found.'); - } - - // Authenticate user and fetch attributes - $entry = ldap_first_entry($ds, $eppn_result); - - if (empty($entry)) - throw new Exception('Could not retrieve result of LDAP search for Feide name.'); - + // Retrieve attributes from LDAP + $attributes = $ldap->getAttributes($dn, $ldapconfig['attributes']); - $dn = @ldap_get_dn($ds, $entry); - - if (empty($dn)) - throw new Exception('Error retrieving DN from search result.'); - - - - if (!@ldap_bind($ds, $dn, $password)) { - - $logger->log(LOG_NOTICE, $session->getTrackID(), 'AUTH', 'ldap-feide', 'Fail', $username, $username . ' failed to authenticate'); - throw new Exception('Bind failed, wrong username or password. ' . - ' Tried with DN=[' . $dn . '] DNPattern=[' . - $ldapconfig['dnpattern'] . '] Error=[' . - ldap_error($ds) . '] ErrNo=[' . - ldap_errno($ds) . ']'); - - } - - $sr = @ldap_read($ds, $dn, $ldapconfig['attributes'] ); - - if ($sr === false) - throw new Exception('Could not retrieve attribtues for user:' . ldap_error($ds)); - - $ldapentries = @ldap_get_entries($ds, $sr); - - if ($ldapentries === false) - throw new Exception('Could not retrieve results from attribute retrieval for user:' . ldap_error($ds)); - - - for ($i = 0; $i < $ldapentries[0]['count']; $i++) { - $values = array(); - if ($ldapentries[0][$i] == 'jpegphoto') continue; - for ($j = 0; $j < $ldapentries[0][$ldapentries[0][$i]]['count']; $j++) { - $values[] = $ldapentries[0][$ldapentries[0][$i]][$j]; - } - - $attributes[$ldapentries[0][$i]] = $values; - } - $logger->log(LOG_NOTICE, $session->getTrackID(), 'AUTH', 'ldap-feide', 'OK', $username, $username . ' successfully authenticated'); - $session->setAuthenticated(true, 'login-feide'); $session->setAttributes($attributes); @@ -182,6 +124,7 @@ if (isset($_REQUEST['username'])) { } catch (Exception $e) { + $logger->log(LOG_ERR, $session->getTrackID(), 'AUTH', 'ldap-feide', 'ERROR', $username, $e->getMessage()); $error = $e->getMessage(); }