summaryrefslogtreecommitdiffstats
path: root/modules/ldap/lib
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ldap/lib')
-rw-r--r--modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php16
-rw-r--r--modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php591
-rw-r--r--modules/ldap/lib/Auth/Process/BaseFilter.php533
-rw-r--r--modules/ldap/lib/Auth/Source/LDAP.php83
-rw-r--r--modules/ldap/lib/Auth/Source/LDAPMulti.php219
-rw-r--r--modules/ldap/lib/ConfigHelper.php543
6 files changed, 1012 insertions, 973 deletions
diff --git a/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php b/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php
index 38c85c0..b1c5910 100644
--- a/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php
+++ b/modules/ldap/lib/Auth/Process/AttributeAddFromLDAP.php
@@ -29,7 +29,8 @@
* @author Ryan Panning
* @package SimpleSAMLphp
*/
-class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Process_BaseFilter {
+class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Process_BaseFilter
+{
/**
* LDAP attribute to add to the request attributes
@@ -60,8 +61,8 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
* @param array $config Configuration information about this filter.
* @param mixed $reserved For future use.
*/
- public function __construct($config, $reserved) {
-
+ public function __construct($config, $reserved)
+ {
/*
* For backwards compatibility, check for old config names
* @TODO Remove after 2.0
@@ -119,7 +120,7 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
$new_attribute = $this->config->getString('attribute.new', '');
$this->search_attributes[$new_attribute] = $this->config->getString('search.attribute');
}
- $this->search_filter = $this->config->getString('search.filter');
+ $this->search_filter = $this->config->getString('search.filter');
// get the attribute policy
$this->attr_policy = $this->config->getString('attribute.policy', 'merge');
@@ -131,7 +132,8 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
*
* @param array &$request The current request
*/
- public function process(&$request) {
+ public function process(&$request)
+ {
assert('is_array($request)');
assert('array_key_exists("Attributes", $request)');
@@ -153,7 +155,7 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
// merge the attributes into the ldap_search_filter
$filter = str_replace($arrSearch, $arrReplace, $this->search_filter);
- if (strpos($filter, '%') !== FALSE) {
+ if (strpos($filter, '%') !== false) {
SimpleSAML\Logger::info('AttributeAddFromLDAP: There are non-existing attributes in the search filter. ('.
$this->search_filter.')');
return;
@@ -168,7 +170,7 @@ class sspmod_ldap_Auth_Process_AttributeAddFromLDAP extends sspmod_ldap_Auth_Pro
// search for matching entries
try {
$entries = $this->getLdap()->searchformultiple($this->base_dn, $filter,
- array_values($this->search_attributes), TRUE, FALSE);
+ array_values($this->search_attributes), true, false);
} catch (Exception $e) {
return; // silent fail, error is still logged by LDAP search
}
diff --git a/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php b/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php
index 6364efe..ada4932 100644
--- a/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php
+++ b/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php
@@ -8,287 +8,312 @@
* @author Ryan Panning <panman@traileyes.com>
* @package SimpleSAMLphp
*/
-class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_Process_BaseFilter {
-
-
- /**
- * This is run when the filter is processed by SimpleSAML.
- * It will attempt to find the current users groups using
- * the best method possible for the LDAP product. The groups
- * are then added to the request attributes.
- *
- * @throws SimpleSAML_Error_Exception
- * @param $request
- */
- public function process(&$request) {
- assert('is_array($request)');
- assert('array_key_exists("Attributes", $request)');
-
- // Log the process
- SimpleSAML\Logger::debug(
- $this->title . 'Attempting to get the users groups...'
- );
-
- // Reference the attributes, just to make the names shorter
- $attributes =& $request['Attributes'];
- $map =& $this->attribute_map;
-
- // Get the users groups from LDAP
- $groups = $this->getGroups($attributes);
-
- // Make the array if it is not set already
- if (!isset($attributes[$map['groups']])) {
- $attributes[$map['groups']] = array();
- }
-
- // Must be an array, else cannot merge groups
- if (!is_array($attributes[$map['groups']])) {
- throw new SimpleSAML_Error_Exception(
- $this->title . 'The group attribute [' . $map['groups'] .
- '] is not an array of group DNs. ' . $this->var_export($attributes[$map['groups']])
- );
- }
-
- // Add the users group(s)
- $group_attribute =& $attributes[$map['groups']];
- $group_attribute = array_merge($group_attribute, $groups);
- $group_attribute = array_unique($group_attribute);
-
- // All done
- SimpleSAML\Logger::debug(
- $this->title . 'Added users groups to the group attribute [' .
- $map['groups'] . ']: ' . implode('; ', $groups)
- );
- }
-
-
- /**
- * This section of code was broken out because the child
- * filter AuthorizeByGroup can use this method as well.
- * Based on the LDAP product, it will do an optimized search
- * using the required attribute values from the user to
- * get their group membership, recursively.
- *
- * @throws SimpleSAML_Error_Exception
- * @param array $attributes
- * @return array
- */
- protected function getGroups(array $attributes) {
-
- // Reference the map, just to make the name shorter
- $map =& $this->attribute_map;
-
- // Log the request
- SimpleSAML\Logger::debug(
- $this->title . 'Checking for groups based on the best method for the LDAP product.'
- );
-
- // Based on the directory service, search LDAP for groups
- // If any attributes are needed, prepare them before calling search method
- switch ($this->product) {
-
- case 'ACTIVEDIRECTORY':
-
- // Log the AD specific search
- SimpleSAML\Logger::debug(
- $this->title . 'Searching LDAP using ActiveDirectory specific method.'
- );
-
- // Make sure the defined dn attribute exists
- if (!isset($attributes[$map['dn']])) {
- throw new SimpleSAML_Error_Exception(
- $this->title . 'The DN attribute [' . $map['dn'] .
- '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
- );
- }
-
- // DN attribute must have a value
- if (!isset($attributes[$map['dn']][0]) || !$attributes[$map['dn']][0]) {
- throw new SimpleSAML_Error_Exception(
- $this->title . 'The DN attribute [' . $map['dn'] .
- '] does not have a [0] value defined. ' . $this->var_export($attributes[$map['dn']])
- );
- }
-
- // Pass to the AD specific search
- $groups = $this->searchActiveDirectory($attributes[$map['dn']][0]);
- break;
-
- default:
-
- // Log the general search
- SimpleSAML\Logger::debug(
- $this->title . 'Searching LDAP using the default search method.'
- );
-
- // Make sure the defined memberOf attribute exists
- if (!isset($attributes[$map['memberof']])) {
- throw new SimpleSAML_Error_Exception(
- $this->title . 'The memberof attribute [' . $map['memberof'] .
- '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
- );
- }
-
- // MemberOf must be an array of group DN's
- if (!is_array($attributes[$map['memberof']])) {
- throw new SimpleSAML_Error_Exception(
- $this->title . 'The memberof attribute [' . $map['memberof'] .
- '] is not an array of group DNs. ' . $this->var_export($attributes[$map['memberof']])
- );
- }
-
- // Search for the users group membership, recursively
- $groups = $this->search($attributes[$map['memberof']]);
- }
-
- // All done
- SimpleSAML\Logger::debug(
- $this->title . 'User found to be a member of the groups:' . implode('; ', $groups)
- );
- return $groups;
- }
-
-
- /**
- * Looks for groups from the list of DN's passed. Also
- * recursively searches groups for further membership.
- * Avoids loops by only searching a DN once. Returns
- * the list of groups found.
- *
- * @param array $memberof
- * @return array
- */
- protected function search($memberof) {
- assert('is_array($memberof)');
-
- // Used to determine what DN's have already been searched
- static $searched = array();
-
- // Init the groups variable
- $groups = array();
-
- // Shorten the variable name
- $map =& $this->attribute_map;
-
- // Log the search
- SimpleSAML\Logger::debug(
- $this->title . 'Checking DNs for groups.' .
- ' DNs: '. implode('; ', $memberof) .
- ' Attributes: ' . $map['memberof'] . ', ' . $map['type'] .
- ' Group Type: ' . $this->type_map['group']
- );
-
- // Check each DN of the passed memberOf
- foreach ($memberof as $dn) {
-
- // Avoid infinite loops, only need to check a DN once
- if (isset($searched[$dn])) {
- continue;
- }
-
- // Track all DN's that are searched
- // Use DN for key as well, isset() is faster than in_array()
- $searched[$dn] = $dn;
-
- // Query LDAP for the attribute values for the DN
- try {
- $attributes = $this->getLdap()->getAttributes($dn, array($map['memberof'], $map['type']));
- } catch (SimpleSAML_Error_AuthSource $e) {
- continue; // DN must not exist, just continue. Logged by the LDAP object
- }
-
- // Only look for groups
- if (!in_array($this->type_map['group'], $attributes[$map['type']])) {
- continue;
- }
-
- // Add to found groups array
- $groups[] = $dn;
-
- // Recursively search "sub" groups
- $groups = array_merge($groups, $this->search($attributes[$map['memberof']]));
- }
-
- // Return only the unique group names
- return array_unique($groups);
- }
-
-
- /**
- * Searches LDAP using a ActiveDirectory specific filter,
- * looking for group membership for the users DN. Returns
- * the list of group DNs retrieved.
- *
- * @param string $dn
- * @return array
- */
- protected function searchActiveDirectory($dn) {
- assert('is_string($dn) && $dn != ""');
-
- // Shorten the variable name
- $map =& $this->attribute_map;
-
- // Log the search
- SimpleSAML\Logger::debug(
- $this->title . 'Searching ActiveDirectory group membership.' .
- ' DN: ' . $dn .
- ' DN Attribute: ' . $map['dn'] .
- ' Member Attribute: ' . $map['member'] .
- ' Type Attribute: ' . $map['type'] .
- ' Type Value: ' . $this->type_map['group'] .
- ' Base: ' . implode('; ', $this->base_dn)
- );
-
- // AD connections should have this set
- $this->getLdap()->setOption(LDAP_OPT_REFERRALS, 0);
-
- // Search AD with the specific recursive flag
- try {
- $entries = $this->getLdap()->searchformultiple(
- $this->base_dn,
- array($map['type'] => $this->type_map['group'], $map['member'] . ':1.2.840.113556.1.4.1941:' => $dn),
- array($map['dn'])
- );
-
- // The search may throw an exception if no entries
- // are found, unlikely but possible.
- } catch (SimpleSAML_Error_UserNotFound $e) {
- return array();
- }
-
- //Init the groups
- $groups = array();
-
- // Check each entry..
- foreach ($entries as $entry) {
-
- // Check for the DN using the original attribute name
- if (isset($entry[$map['dn']][0])) {
- $groups[] = $entry[$map['dn']][0];
- continue;
- }
-
- // Sometimes the returned attribute names are lowercase
- if (isset($entry[strtolower($map['dn'])][0])) {
- $groups[] = $entry[strtolower($map['dn'])][0];
- continue;
- }
-
- // AD queries also seem to return the objects dn by default
- if (isset($entry['dn'])) {
- $groups[] = $entry['dn'];
- continue;
- }
-
- // Could not find DN, log and continue
- SimpleSAML\Logger::notice(
- $this->title . 'The DN attribute [' .
- implode(', ', array($map['dn'], strtolower($map['dn']), 'dn')) .
- '] could not be found in the entry. ' . $this->var_export($entry)
- );
- }
-
- // All done
- return $groups;
- }
+class sspmod_ldap_Auth_Process_AttributeAddUsersGroups extends sspmod_ldap_Auth_Process_BaseFilter
+{
+ /**
+ * This is run when the filter is processed by SimpleSAML.
+ * It will attempt to find the current users groups using
+ * the best method possible for the LDAP product. The groups
+ * are then added to the request attributes.
+ *
+ * @throws SimpleSAML_Error_Exception
+ * @param $request
+ */
+ public function process(&$request)
+ {
+ assert('is_array($request)');
+ assert('array_key_exists("Attributes", $request)');
+
+ // Log the process
+ SimpleSAML\Logger::debug(
+ $this->title . 'Attempting to get the users groups...'
+ );
+
+ // Reference the attributes, just to make the names shorter
+ $attributes =& $request['Attributes'];
+ $map =& $this->attribute_map;
+
+ // Get the users groups from LDAP
+ $groups = $this->getGroups($attributes);
+
+ // Make the array if it is not set already
+ if (!isset($attributes[$map['groups']])) {
+ $attributes[$map['groups']] = array();
+ }
+
+ // Must be an array, else cannot merge groups
+ if (!is_array($attributes[$map['groups']])) {
+ throw new SimpleSAML_Error_Exception(
+ $this->title . 'The group attribute [' . $map['groups'] .
+ '] is not an array of group DNs. ' . $this->var_export($attributes[$map['groups']])
+ );
+ }
+
+ // Add the users group(s)
+ $group_attribute =& $attributes[$map['groups']];
+ $group_attribute = array_merge($group_attribute, $groups);
+ $group_attribute = array_unique($group_attribute);
+
+ // All done
+ SimpleSAML\Logger::debug(
+ $this->title . 'Added users groups to the group attribute [' .
+ $map['groups'] . ']: ' . implode('; ', $groups)
+ );
+ }
+
+
+ /**
+ * This section of code was broken out because the child
+ * filter AuthorizeByGroup can use this method as well.
+ * Based on the LDAP product, it will do an optimized search
+ * using the required attribute values from the user to
+ * get their group membership, recursively.
+ *
+ * @throws SimpleSAML_Error_Exception
+ * @param array $attributes
+ * @return array
+ */
+ protected function getGroups(array $attributes)
+ {
+ // Reference the map, just to make the name shorter
+ $map =& $this->attribute_map;
+
+ // Log the request
+ SimpleSAML\Logger::debug(
+ $this->title . 'Checking for groups based on the best method for the LDAP product.'
+ );
+
+ // Based on the directory service, search LDAP for groups
+ // If any attributes are needed, prepare them before calling search method
+ switch ($this->product) {
+
+ case 'ACTIVEDIRECTORY':
+
+ // Log the AD specific search
+ SimpleSAML\Logger::debug(
+ $this->title . 'Searching LDAP using ActiveDirectory specific method.'
+ );
+
+ // Make sure the defined dn attribute exists
+ if (!isset($attributes[$map['dn']])) {
+ throw new SimpleSAML_Error_Exception(
+ $this->title . 'The DN attribute [' . $map['dn'] .
+ '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
+ );
+ }
+
+ // DN attribute must have a value
+ if (!isset($attributes[$map['dn']][0]) || !$attributes[$map['dn']][0]) {
+ throw new SimpleSAML_Error_Exception(
+ $this->title . 'The DN attribute [' . $map['dn'] .
+ '] does not have a [0] value defined. ' . $this->var_export($attributes[$map['dn']])
+ );
+ }
+
+ // Pass to the AD specific search
+ $groups = $this->searchActiveDirectory($attributes[$map['dn']][0]);
+ break;
+
+ case 'OPENLDAP':
+ // Log the OpenLDAP specific search
+ SimpleSAML\Logger::debug(
+ $this->title . 'Searching LDAP using OpenLDAP specific method.'
+ );
+ // Print group search string and search for all group names
+ $openldap_base = $this->config->getString('ldap.basedn','ou=groups,dc=example,dc=com');
+ SimpleSAML\Logger::debug(
+ $this->title . "Searching for groups in ldap.basedn ".$openldap_base." with filter (".$map['memberof']."=".$attributes['uid'][0].") and attributes ".$map['member']
+ );
+ $groups = array();
+ try {
+ // Intention is to filter in 'ou=groups,dc=example,dc=com' for '(memberUid = <UID>)' and take only the attributes 'cn' (=name of the group)
+ $all_groups = $this->getLdap()->searchformultiple( $openldap_base, array($map['memberof'] => $attributes['uid'][0]) , array($map['member']));
+ } catch (SimpleSAML_Error_UserNotFound $e) {
+ break; // if no groups found return with empty (still just initialized) groups array
+ }
+ // run through all groups and add each to our groups array
+ foreach ($all_groups as $group_entry) {
+ $groups[] .= $group_entry[$map['member']][0];
+ }
+ break;
+
+ default:
+
+ // Log the general search
+ SimpleSAML\Logger::debug(
+ $this->title . 'Searching LDAP using the default search method.'
+ );
+
+ // Make sure the defined memberOf attribute exists
+ if (!isset($attributes[$map['memberof']])) {
+ throw new SimpleSAML_Error_Exception(
+ $this->title . 'The memberof attribute [' . $map['memberof'] .
+ '] is not defined in the users Attributes: ' . implode(', ', array_keys($attributes))
+ );
+ }
+
+ // MemberOf must be an array of group DN's
+ if (!is_array($attributes[$map['memberof']])) {
+ throw new SimpleSAML_Error_Exception(
+ $this->title . 'The memberof attribute [' . $map['memberof'] .
+ '] is not an array of group DNs. ' . $this->var_export($attributes[$map['memberof']])
+ );
+ }
+
+ // Search for the users group membership, recursively
+ $groups = $this->search($attributes[$map['memberof']]);
+ }
+
+ // All done
+ SimpleSAML\Logger::debug(
+ $this->title . 'User found to be a member of the groups:' . implode('; ', $groups)
+ );
+ return $groups;
+ }
+
+
+ /**
+ * Looks for groups from the list of DN's passed. Also
+ * recursively searches groups for further membership.
+ * Avoids loops by only searching a DN once. Returns
+ * the list of groups found.
+ *
+ * @param array $memberof
+ * @return array
+ */
+ protected function search($memberof)
+ {
+ assert('is_array($memberof)');
+
+ // Used to determine what DN's have already been searched
+ static $searched = array();
+
+ // Init the groups variable
+ $groups = array();
+
+ // Shorten the variable name
+ $map =& $this->attribute_map;
+
+ // Log the search
+ SimpleSAML\Logger::debug(
+ $this->title . 'Checking DNs for groups.' .
+ ' DNs: '. implode('; ', $memberof) .
+ ' Attributes: ' . $map['memberof'] . ', ' . $map['type'] .
+ ' Group Type: ' . $this->type_map['group']
+ );
+
+ // Check each DN of the passed memberOf
+ foreach ($memberof as $dn) {
+
+ // Avoid infinite loops, only need to check a DN once
+ if (isset($searched[$dn])) {
+ continue;
+ }
+
+ // Track all DN's that are searched
+ // Use DN for key as well, isset() is faster than in_array()
+ $searched[$dn] = $dn;
+
+ // Query LDAP for the attribute values for the DN
+ try {
+ $attributes = $this->getLdap()->getAttributes($dn, array($map['memberof'], $map['type']));
+ } catch (SimpleSAML_Error_AuthSource $e) {
+ continue; // DN must not exist, just continue. Logged by the LDAP object
+ }
+
+ // Only look for groups
+ if (!in_array($this->type_map['group'], $attributes[$map['type']])) {
+ continue;
+ }
+
+ // Add to found groups array
+ $groups[] = $dn;
+
+ // Recursively search "sub" groups
+ $groups = array_merge($groups, $this->search($attributes[$map['memberof']]));
+ }
+
+ // Return only the unique group names
+ return array_unique($groups);
+ }
+
+
+ /**
+ * Searches LDAP using a ActiveDirectory specific filter,
+ * looking for group membership for the users DN. Returns
+ * the list of group DNs retrieved.
+ *
+ * @param string $dn
+ * @return array
+ */
+ protected function searchActiveDirectory($dn)
+ {
+ assert('is_string($dn) && $dn != ""');
+
+ // Shorten the variable name
+ $map =& $this->attribute_map;
+
+ // Log the search
+ SimpleSAML\Logger::debug(
+ $this->title . 'Searching ActiveDirectory group membership.' .
+ ' DN: ' . $dn .
+ ' DN Attribute: ' . $map['dn'] .
+ ' Member Attribute: ' . $map['member'] .
+ ' Type Attribute: ' . $map['type'] .
+ ' Type Value: ' . $this->type_map['group'] .
+ ' Base: ' . implode('; ', $this->base_dn)
+ );
+
+ // AD connections should have this set
+ $this->getLdap()->setOption(LDAP_OPT_REFERRALS, 0);
+
+ // Search AD with the specific recursive flag
+ try {
+ $entries = $this->getLdap()->searchformultiple(
+ $this->base_dn,
+ array($map['type'] => $this->type_map['group'], $map['member'] . ':1.2.840.113556.1.4.1941:' => $dn),
+ array($map['dn'])
+ );
+
+ // The search may throw an exception if no entries
+ // are found, unlikely but possible.
+ } catch (SimpleSAML_Error_UserNotFound $e) {
+ return array();
+ }
+
+ //Init the groups
+ $groups = array();
+
+ // Check each entry..
+ foreach ($entries as $entry) {
+
+ // Check for the DN using the original attribute name
+ if (isset($entry[$map['dn']][0])) {
+ $groups[] = $entry[$map['dn']][0];
+ continue;
+ }
+
+ // Sometimes the returned attribute names are lowercase
+ if (isset($entry[strtolower($map['dn'])][0])) {
+ $groups[] = $entry[strtolower($map['dn'])][0];
+ continue;
+ }
+
+ // AD queries also seem to return the objects dn by default
+ if (isset($entry['dn'])) {
+ $groups[] = $entry['dn'];
+ continue;
+ }
+
+ // Could not find DN, log and continue
+ SimpleSAML\Logger::notice(
+ $this->title . 'The DN attribute [' .
+ implode(', ', array($map['dn'], strtolower($map['dn']), 'dn')) .
+ '] could not be found in the entry. ' . $this->var_export($entry)
+ );
+ }
+
+ // All done
+ return $groups;
+ }
}
diff --git a/modules/ldap/lib/Auth/Process/BaseFilter.php b/modules/ldap/lib/Auth/Process/BaseFilter.php
index 3d328e4..22aa197 100644
--- a/modules/ldap/lib/Auth/Process/BaseFilter.php
+++ b/modules/ldap/lib/Auth/Process/BaseFilter.php
@@ -8,270 +8,271 @@
* @author Ryan Panning <panman@traileyes.com>
* @package SimpleSAMLphp
*/
-abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_ProcessingFilter {
-
- /**
- * List of attribute "alias's" linked to the real attribute
- * name. Used for abstraction / configuration of the LDAP
- * attribute names, which may change between dir service.
- *
- * @var array
- */
- protected $attribute_map;
-
-
- /**
- * The base DN of the LDAP connection. Used when searching
- * the LDAP server.
- *
- * @var string|array
- */
- protected $base_dn;
-
-
- /**
- * The construct method will change the filter config into
- * a SimpleSAML_Configuration object and store it here for
- * later use, if needed.
- *
- * @var SimpleSAML_Configuration
- */
- protected $config;
-
-
- /**
- * Instance, object of the ldap connection. Stored here to
- * be access later during processing.
- *
- * @var sspmod_ldap_LdapConnection
- */
- private $ldap;
-
-
- /**
- * Many times a LDAP product specific query can be used to
- * speed up or reduce the filter process. This helps the
- * child classes determine the product used to optimize
- * those queries.
- *
- * @var string
- */
- protected $product;
-
-
- /**
- * The class "title" used in logging and exception messages.
- * This should be prepended to the beginning of the message.
- *
- * @var string
- */
- protected $title = 'ldap:BaseFilter : ';
-
-
- /**
- * List of LDAP object types, used to determine the type of
- * object that a DN references.
- *
- * @var array
- */
- protected $type_map;
-
-
- /**
- * Checks the authsource, if defined, for configuration values
- * to the LDAP server. Then sets up the LDAP connection for the
- * instance/object and stores everything in class members.
- *
- * @throws SimpleSAML_Error_Exception
- * @param array $config
- * @param $reserved
- */
- public function __construct(&$config, $reserved) {
- parent::__construct($config, $reserved);
-
- // Change the class $title to match it's true name
- // This way if the class is extended the proper name is used
- $classname = get_class($this);
- $classname = explode('_', $classname);
- $this->title = 'ldap:' . end($classname) . ' : ';
-
- // Log the construction
- SimpleSAML\Logger::debug(
- $this->title . 'Creating and configuring the filter.'
- );
-
- // If an authsource was defined (an not empty string)...
- if (isset($config['authsource']) && $config['authsource']) {
-
- // Log the authsource request
- SimpleSAML\Logger::debug(
- $this->title . 'Attempting to get configuration values from authsource [' .
- $config['authsource'] . ']'
- );
-
- // Get the authsources file, which should contain the config
- $authsource = SimpleSAML_Configuration::getConfig('authsources.php');
-
- // Verify that the authsource config exists
- if (!$authsource->hasValue($config['authsource'])) {
- throw new SimpleSAML_Error_Exception(
- $this->title . 'Authsource [' . $config['authsource'] .
- '] defined in filter parameters not found in authsources.php'
- );
- }
-
- // Get just the specified authsource config values
- $authsource = $authsource->getConfigItem($config['authsource']);
- $authsource = $authsource->toArray();
-
- // Make sure it is an ldap source
- // TODO: Support ldap:LDAPMulti, if possible
- if (@$authsource[0] != 'ldap:LDAP') {
- throw new SimpleSAML_Error_Exception(
- $this->title . 'Authsource [' . $config['authsource'] .
- '] specified in filter parameters is not an ldap:LDAP type'
- );
- }
-
- // Build the authsource config
- $authconfig = array();
- $authconfig['ldap.hostname'] = @$authsource['hostname'];
- $authconfig['ldap.enable_tls'] = @$authsource['enable_tls'];
- $authconfig['ldap.port'] = @$authsource['port'];
- $authconfig['ldap.timeout'] = @$authsource['timeout'];
- $authconfig['ldap.debug'] = @$authsource['debug'];
- $authconfig['ldap.basedn'] = (@$authsource['search.enable'] ? @$authsource['search.base'] : NULL);
- $authconfig['ldap.username'] = (@$authsource['search.enable'] ? @$authsource['search.username'] : NULL);
- $authconfig['ldap.password'] = (@$authsource['search.enable'] ? @$authsource['search.password'] : NULL);
- $authconfig['ldap.username'] = (@$authsource['priv.read'] ? @$authsource['priv.username'] : $authconfig['ldap.username']);
- $authconfig['ldap.password'] = (@$authsource['priv.read'] ? @$authsource['priv.password'] : $authconfig['ldap.password']);
-
- // Only set the username attribute if the authsource specifies one attribute
- if (@$authsource['search.enable'] && is_array(@$authsource['search.attributes'])
- && count($authsource['search.attributes']) == 1) {
- $authconfig['attribute.username'] = reset($authsource['search.attributes']);
- }
-
- // Merge the authsource config with the filter config,
- // but have the filter config override the authsource config
- $config = array_merge($authconfig, $config);
-
- // Authsource complete
- SimpleSAML\Logger::debug(
- $this->title . 'Retrieved authsource [' . $config['authsource'] .
- '] configuration values: ' . $this->var_export($authconfig)
- );
- }
-
- // Convert the config array to a config class,
- // that way we can verify type and define defaults.
- // Store in the instance in-case needed later, by a child class.
- $this->config = SimpleSAML_Configuration::loadFromArray($config, 'ldap:AuthProcess');
-
- // Set all the filter values, setting defaults if needed
- $this->base_dn = $this->config->getArrayizeString('ldap.basedn', '');
- $this->product = $this->config->getString('ldap.product', '');
-
- // Cleanup the directory service, so that it is easier for
- // child classes to determine service name consistently
- $this->product = trim($this->product);
- $this->product = strtoupper($this->product);
-
- // Log the member values retrieved above
- SimpleSAML\Logger::debug(
- $this->title . 'Configuration values retrieved;' .
- ' BaseDN: ' . $this->var_export($this->base_dn) .
- ' Product: ' . $this->var_export($this->product)
- );
-
- // Setup the attribute map which will be used to search LDAP
- $this->attribute_map = array(
- 'dn' => $this->config->getString('attribute.dn', 'distinguishedName'),
- 'groups' => $this->config->getString('attribute.groups', 'groups'),
- 'member' => $this->config->getString('attribute.member', 'member'),
- 'memberof' => $this->config->getString('attribute.memberof', 'memberOf'),
- 'name' => $this->config->getString('attribute.groupname', 'name'),
- 'type' => $this->config->getString('attribute.type', 'objectClass'),
- 'username' => $this->config->getString('attribute.username', 'sAMAccountName')
- );
-
- // Log the attribute map
- SimpleSAML\Logger::debug(
- $this->title . 'Attribute map created: ' . $this->var_export($this->attribute_map)
- );
-
- // Setup the object type map which is used to determine a DNs' type
- $this->type_map = array(
- 'group' => $this->config->getString('type.group', 'group'),
- 'user' => $this->config->getString('type.user', 'user')
- );
-
- // Log the type map
- SimpleSAML\Logger::debug(
- $this->title . 'Type map created: ' . $this->var_export($this->type_map)
- );
- }
-
-
- /**
- * Getter for the LDAP connection object. Created this getter
- * rather than setting in the constructor to avoid unnecessarily
- * connecting to LDAP when it might not be needed.
- *
- * @return sspmod_ldap_LdapConnection
- */
- protected function getLdap() {
-
- // Check if already connected
- if ($this->ldap) {
- return $this->ldap;
- }
-
- // Get the connection specific options
- $hostname = $this->config->getString('ldap.hostname');
- $port = $this->config->getInteger('ldap.port', 389);
- $enable_tls = $this->config->getBoolean('ldap.enable_tls', FALSE);
- $debug = $this->config->getBoolean('ldap.debug', FALSE);
- $timeout = $this->config->getInteger('ldap.timeout', 0);
- $username = $this->config->getString('ldap.username', NULL);
- $password = $this->config->getString('ldap.password', NULL);
-
- // Log the LDAP connection
- SimpleSAML\Logger::debug(
- $this->title . 'Connecting to LDAP server;' .
- ' Hostname: ' . $hostname .
- ' Port: ' . $port .
- ' Enable TLS: ' . ($enable_tls ? 'Yes' : 'No') .
- ' Debug: ' . ($debug ? 'Yes' : 'No') .
- ' Timeout: ' . $timeout .
- ' Username: ' . $username .
- ' Password: ' . str_repeat('*', strlen($password))
- );
-
- // Connect to the LDAP server to be queried during processing
- $this->ldap = new SimpleSAML_Auth_LDAP($hostname, $enable_tls, $debug, $timeout, $port);
- $this->ldap->bind($username, $password);
-
- // All done
- return $this->ldap;
- }
-
-
- /**
- * Local utility function to get details about a variable,
- * basically converting it to a string to be used in a log
- * message. The var_export() function returns several lines
- * so this will remove the new lines and trim each line.
- *
- * @param mixed $value
- * @return string
- */
- protected function var_export($value) {
- $export = var_export($value, TRUE);
- $lines = explode("\n", $export);
- foreach ($lines as &$line) {
- $line = trim($line);
- }
- return implode(' ', $lines);
- }
+abstract class sspmod_ldap_Auth_Process_BaseFilter extends SimpleSAML_Auth_ProcessingFilter
+{
+
+ /**
+ * List of attribute "alias's" linked to the real attribute
+ * name. Used for abstraction / configuration of the LDAP
+ * attribute names, which may change between dir service.
+ *
+ * @var array
+ */
+ protected $attribute_map;
+
+
+ /**
+ * The base DN of the LDAP connection. Used when searching
+ * the LDAP server.
+ *
+ * @var string|array
+ */
+ protected $base_dn;
+
+
+ /**
+ * The construct method will change the filter config into
+ * a SimpleSAML_Configuration object and store it here for
+ * later use, if needed.
+ *
+ * @var SimpleSAML_Configuration
+ */
+ protected $config;
+
+
+ /**
+ * Instance, object of the ldap connection. Stored here to
+ * be access later during processing.
+ *
+ * @var sspmod_ldap_LdapConnection
+ */
+ private $ldap;
+
+
+ /**
+ * Many times a LDAP product specific query can be used to
+ * speed up or reduce the filter process. This helps the
+ * child classes determine the product used to optimize
+ * those queries.
+ *
+ * @var string
+ */
+ protected $product;
+
+
+ /**
+ * The class "title" used in logging and exception messages.
+ * This should be prepended to the beginning of the message.
+ *
+ * @var string
+ */
+ protected $title = 'ldap:BaseFilter : ';
+
+
+ /**
+ * List of LDAP object types, used to determine the type of
+ * object that a DN references.
+ *
+ * @var array
+ */
+ protected $type_map;
+
+
+ /**
+ * Checks the authsource, if defined, for configuration values
+ * to the LDAP server. Then sets up the LDAP connection for the
+ * instance/object and stores everything in class members.
+ *
+ * @throws SimpleSAML_Error_Exception
+ * @param array $config
+ * @param $reserved
+ */
+ public function __construct(&$config, $reserved)
+ {
+ parent::__construct($config, $reserved);
+
+ // Change the class $title to match it's true name
+ // This way if the class is extended the proper name is used
+ $classname = get_class($this);
+ $classname = explode('_', $classname);
+ $this->title = 'ldap:' . end($classname) . ' : ';
+
+ // Log the construction
+ SimpleSAML\Logger::debug(
+ $this->title . 'Creating and configuring the filter.'
+ );
+
+ // If an authsource was defined (an not empty string)...
+ if (isset($config['authsource']) && $config['authsource']) {
+
+ // Log the authsource request
+ SimpleSAML\Logger::debug(
+ $this->title . 'Attempting to get configuration values from authsource [' .
+ $config['authsource'] . ']'
+ );
+
+ // Get the authsources file, which should contain the config
+ $authsource = SimpleSAML_Configuration::getConfig('authsources.php');
+
+ // Verify that the authsource config exists
+ if (!$authsource->hasValue($config['authsource'])) {
+ throw new SimpleSAML_Error_Exception(
+ $this->title . 'Authsource [' . $config['authsource'] .
+ '] defined in filter parameters not found in authsources.php'
+ );
+ }
+
+ // Get just the specified authsource config values
+ $authsource = $authsource->getConfigItem($config['authsource']);
+ $authsource = $authsource->toArray();
+
+ // Make sure it is an ldap source
+ // TODO: Support ldap:LDAPMulti, if possible
+ if (@$authsource[0] != 'ldap:LDAP') {
+ throw new SimpleSAML_Error_Exception(
+ $this->title . 'Authsource [' . $config['authsource'] .
+ '] specified in filter parameters is not an ldap:LDAP type'
+ );
+ }
+
+ // Build the authsource config
+ $authconfig = array();
+ $authconfig['ldap.hostname'] = @$authsource['hostname'];
+ $authconfig['ldap.enable_tls'] = @$authsource['enable_tls'];
+ $authconfig['ldap.port'] = @$authsource['port'];
+ $authconfig['ldap.timeout'] = @$authsource['timeout'];
+ $authconfig['ldap.debug'] = @$authsource['debug'];
+ $authconfig['ldap.basedn'] = (@$authsource['search.enable'] ? @$authsource['search.base'] : null);
+ $authconfig['ldap.username'] = (@$authsource['search.enable'] ? @$authsource['search.username'] : null);
+ $authconfig['ldap.password'] = (@$authsource['search.enable'] ? @$authsource['search.password'] : null);
+ $authconfig['ldap.username'] = (@$authsource['priv.read'] ? @$authsource['priv.username'] : $authconfig['ldap.username']);
+ $authconfig['ldap.password'] = (@$authsource['priv.read'] ? @$authsource['priv.password'] : $authconfig['ldap.password']);
+
+ // Only set the username attribute if the authsource specifies one attribute
+ if (@$authsource['search.enable'] && is_array(@$authsource['search.attributes'])
+ && count($authsource['search.attributes']) == 1) {
+ $authconfig['attribute.username'] = reset($authsource['search.attributes']);
+ }
+
+ // Merge the authsource config with the filter config,
+ // but have the filter config override the authsource config
+ $config = array_merge($authconfig, $config);
+
+ // Authsource complete
+ SimpleSAML\Logger::debug(
+ $this->title . 'Retrieved authsource [' . $config['authsource'] .
+ '] configuration values: ' . $this->var_export($authconfig)
+ );
+ }
+
+ // Convert the config array to a config class,
+ // that way we can verify type and define defaults.
+ // Store in the instance in-case needed later, by a child class.
+ $this->config = SimpleSAML_Configuration::loadFromArray($config, 'ldap:AuthProcess');
+
+ // Set all the filter values, setting defaults if needed
+ $this->base_dn = $this->config->getArrayizeString('ldap.basedn', '');
+ $this->product = $this->config->getString('ldap.product', '');
+
+ // Cleanup the directory service, so that it is easier for
+ // child classes to determine service name consistently
+ $this->product = trim($this->product);
+ $this->product = strtoupper($this->product);
+
+ // Log the member values retrieved above
+ SimpleSAML\Logger::debug(
+ $this->title . 'Configuration values retrieved;' .
+ ' BaseDN: ' . $this->var_export($this->base_dn) .
+ ' Product: ' . $this->var_export($this->product)
+ );
+
+ // Setup the attribute map which will be used to search LDAP
+ $this->attribute_map = array(
+ 'dn' => $this->config->getString('attribute.dn', 'distinguishedName'),
+ 'groups' => $this->config->getString('attribute.groups', 'groups'),
+ 'member' => $this->config->getString('attribute.member', 'member'),
+ 'memberof' => $this->config->getString('attribute.memberof', 'memberOf'),
+ 'name' => $this->config->getString('attribute.groupname', 'name'),
+ 'type' => $this->config->getString('attribute.type', 'objectClass'),
+ 'username' => $this->config->getString('attribute.username', 'sAMAccountName')
+ );
+
+ // Log the attribute map
+ SimpleSAML\Logger::debug(
+ $this->title . 'Attribute map created: ' . $this->var_export($this->attribute_map)
+ );
+
+ // Setup the object type map which is used to determine a DNs' type
+ $this->type_map = array(
+ 'group' => $this->config->getString('type.group', 'group'),
+ 'user' => $this->config->getString('type.user', 'user')
+ );
+
+ // Log the type map
+ SimpleSAML\Logger::debug(
+ $this->title . 'Type map created: ' . $this->var_export($this->type_map)
+ );
+ }
+
+ /**
+ * Getter for the LDAP connection object. Created this getter
+ * rather than setting in the constructor to avoid unnecessarily
+ * connecting to LDAP when it might not be needed.
+ *
+ * @return sspmod_ldap_LdapConnection
+ */
+ protected function getLdap()
+ {
+ // Check if already connected
+ if ($this->ldap) {
+ return $this->ldap;
+ }
+
+ // Get the connection specific options
+ $hostname = $this->config->getString('ldap.hostname');
+ $port = $this->config->getInteger('ldap.port', 389);
+ $enable_tls = $this->config->getBoolean('ldap.enable_tls', false);
+ $debug = $this->config->getBoolean('ldap.debug', false);
+ $timeout = $this->config->getInteger('ldap.timeout', 0);
+ $username = $this->config->getString('ldap.username', null);
+ $password = $this->config->getString('ldap.password', null);
+
+ // Log the LDAP connection
+ SimpleSAML\Logger::debug(
+ $this->title . 'Connecting to LDAP server;' .
+ ' Hostname: ' . $hostname .
+ ' Port: ' . $port .
+ ' Enable TLS: ' . ($enable_tls ? 'Yes' : 'No') .
+ ' Debug: ' . ($debug ? 'Yes' : 'No') .
+ ' Timeout: ' . $timeout .
+ ' Username: ' . $username .
+ ' Password: ' . str_repeat('*', strlen($password))
+ );
+
+ // Connect to the LDAP server to be queried during processing
+ $this->ldap = new SimpleSAML_Auth_LDAP($hostname, $enable_tls, $debug, $timeout, $port);
+ $this->ldap->bind($username, $password);
+
+ // All done
+ return $this->ldap;
+ }
+
+ /**
+ * Local utility function to get details about a variable,
+ * basically converting it to a string to be used in a log
+ * message. The var_export() function returns several lines
+ * so this will remove the new lines and trim each line.
+ *
+ * @param mixed $value
+ * @return string
+ */
+ protected function var_export($value)
+ {
+ $export = var_export($value, true);
+ $lines = explode("\n", $export);
+ foreach ($lines as &$line) {
+ $line = trim($line);
+ }
+ return implode(' ', $lines);
+ }
}
diff --git a/modules/ldap/lib/Auth/Source/LDAP.php b/modules/ldap/lib/Auth/Source/LDAP.php
index 83b35fa..7bf979a 100644
--- a/modules/ldap/lib/Auth/Source/LDAP.php
+++ b/modules/ldap/lib/Auth/Source/LDAP.php
@@ -10,45 +10,48 @@
*
* @package SimpleSAMLphp
*/
-class sspmod_ldap_Auth_Source_LDAP extends sspmod_core_Auth_UserPassBase {
-
- /**
- * A LDAP configuration object.
- */
- private $ldapConfig;
-
-
- /**
- * Constructor for this authentication source.
- *
- * @param array $info Information about this authentication source.
- * @param array $config Configuration.
- */
- public function __construct($info, $config) {
- assert('is_array($info)');
- assert('is_array($config)');
-
- // Call the parent constructor first, as required by the interface
- parent::__construct($info, $config);
-
- $this->ldapConfig = new sspmod_ldap_ConfigHelper($config,
- 'Authentication source ' . var_export($this->authId, TRUE));
- }
-
-
- /**
- * Attempt to log in using the given username and password.
- *
- * @param string $username The username the user wrote.
- * @param string $password The password the user wrote.
- * param array $sasl_arg Associative array of SASL options
- * @return array Associative array with the users attributes.
- */
- protected function login($username, $password, array $sasl_args = NULL) {
- assert('is_string($username)');
- assert('is_string($password)');
-
- return $this->ldapConfig->login($username, $password, $sasl_args);
- }
+class sspmod_ldap_Auth_Source_LDAP extends sspmod_core_Auth_UserPassBase
+{
+
+ /**
+ * A LDAP configuration object.
+ */
+ private $ldapConfig;
+
+
+ /**
+ * Constructor for this authentication source.
+ *
+ * @param array $info Information about this authentication source.
+ * @param array $config Configuration.
+ */
+ public function __construct($info, $config)
+ {
+ assert('is_array($info)');
+ assert('is_array($config)');
+
+ // Call the parent constructor first, as required by the interface
+ parent::__construct($info, $config);
+
+ $this->ldapConfig = new sspmod_ldap_ConfigHelper($config,
+ 'Authentication source ' . var_export($this->authId, true));
+ }
+
+
+ /**
+ * Attempt to log in using the given username and password.
+ *
+ * @param string $username The username the user wrote.
+ * @param string $password The password the user wrote.
+ * param array $sasl_arg Associative array of SASL options
+ * @return array Associative array with the users attributes.
+ */
+ protected function login($username, $password, array $sasl_args = null)
+ {
+ assert('is_string($username)');
+ assert('is_string($password)');
+
+ return $this->ldapConfig->login($username, $password, $sasl_args);
+ }
}
diff --git a/modules/ldap/lib/Auth/Source/LDAPMulti.php b/modules/ldap/lib/Auth/Source/LDAPMulti.php
index 4f5adaf..e38118e 100644
--- a/modules/ldap/lib/Auth/Source/LDAPMulti.php
+++ b/modules/ldap/lib/Auth/Source/LDAPMulti.php
@@ -10,112 +10,115 @@
*
* @package SimpleSAMLphp
*/
-class sspmod_ldap_Auth_Source_LDAPMulti extends sspmod_core_Auth_UserPassOrgBase {
-
- /**
- * An array with descriptions for organizations.
- */
- private $orgs;
-
- /**
- * An array of organization IDs to LDAP configuration objects.
- */
- private $ldapOrgs;
-
- /**
- * Whether we should include the organization as part of the username.
- */
- private $includeOrgInUsername;
-
-
- /**
- * Constructor for this authentication source.
- *
- * @param array $info Information about this authentication source.
- * @param array $config Configuration.
- */
- public function __construct($info, $config) {
- assert('is_array($info)');
- assert('is_array($config)');
-
- // Call the parent constructor first, as required by the interface
- parent::__construct($info, $config);
-
- $cfgHelper = SimpleSAML_Configuration::loadFromArray($config,
- 'Authentication source ' . var_export($this->authId, TRUE));
-
-
- $this->orgs = array();
- $this->ldapOrgs = array();
- foreach ($config as $name => $value) {
-
- if ($name === 'username_organization_method') {
- $usernameOrgMethod = $cfgHelper->getValueValidate(
- 'username_organization_method',
- array('none', 'allow', 'force'));
- $this->setUsernameOrgMethod($usernameOrgMethod);
- continue;
- }
-
- if ($name === 'include_organization_in_username') {
- $this->includeOrgInUsername = $cfgHelper->getBoolean(
- 'include_organization_in_username', FALSE);
- continue;
- }
-
- $orgCfg = $cfgHelper->getArray($name);
- $orgId = $name;
-
- if (array_key_exists('description', $orgCfg)) {
- $this->orgs[$orgId] = $orgCfg['description'];
- } else {
- $this->orgs[$orgId] = $orgId;
- }
-
- $orgCfg = new sspmod_ldap_ConfigHelper($orgCfg,
- 'Authentication source ' . var_export($this->authId, TRUE) .
- ', organization ' . var_export($orgId, TRUE));
- $this->ldapOrgs[$orgId] = $orgCfg;
- }
- }
-
-
- /**
- * Attempt to log in using the given username and password.
- *
- * @param string $username The username the user wrote.
- * @param string $password The password the user wrote.
- * @param string $org The organization the user chose.
- * @return array Associative array with the users attributes.
- */
- protected function login($username, $password, $org, array $sasl_args = NULL) {
- assert('is_string($username)');
- assert('is_string($password)');
- assert('is_string($org)');
-
- if (!array_key_exists($org, $this->ldapOrgs)) {
- // The user has selected an organization which doesn't exist anymore.
- SimpleSAML\Logger::warning('Authentication source ' . var_export($this->authId, TRUE) .
- ': Organization seems to have disappeared while the user logged in.' .
- ' Organization was ' . var_export($org, TRUE));
- throw new SimpleSAML_Error_Error('WRONGUSERPASS');
- }
-
- if ($this->includeOrgInUsername) {
- $username = $username . '@' . $org;
- }
-
- return $this->ldapOrgs[$org]->login($username, $password, $sasl_args);
- }
-
-
- /**
- * Retrieve list of organizations.
- *
- * @return array Associative array with the organizations.
- */
- protected function getOrganizations() {
- return $this->orgs;
- }
-
+class sspmod_ldap_Auth_Source_LDAPMulti extends sspmod_core_Auth_UserPassOrgBase
+{
+
+ /**
+ * An array with descriptions for organizations.
+ */
+ private $orgs;
+
+ /**
+ * An array of organization IDs to LDAP configuration objects.
+ */
+ private $ldapOrgs;
+
+ /**
+ * Whether we should include the organization as part of the username.
+ */
+ private $includeOrgInUsername;
+
+
+ /**
+ * Constructor for this authentication source.
+ *
+ * @param array $info Information about this authentication source.
+ * @param array $config Configuration.
+ */
+ public function __construct($info, $config)
+ {
+ assert('is_array($info)');
+ assert('is_array($config)');
+
+ // Call the parent constructor first, as required by the interface
+ parent::__construct($info, $config);
+
+ $cfgHelper = SimpleSAML_Configuration::loadFromArray($config,
+ 'Authentication source ' . var_export($this->authId, true));
+
+
+ $this->orgs = array();
+ $this->ldapOrgs = array();
+ foreach ($config as $name => $value) {
+
+ if ($name === 'username_organization_method') {
+ $usernameOrgMethod = $cfgHelper->getValueValidate(
+ 'username_organization_method',
+ array('none', 'allow', 'force'));
+ $this->setUsernameOrgMethod($usernameOrgMethod);
+ continue;
+ }
+
+ if ($name === 'include_organization_in_username') {
+ $this->includeOrgInUsername = $cfgHelper->getBoolean(
+ 'include_organization_in_username', false);
+ continue;
+ }
+
+ $orgCfg = $cfgHelper->getArray($name);
+ $orgId = $name;
+
+ if (array_key_exists('description', $orgCfg)) {
+ $this->orgs[$orgId] = $orgCfg['description'];
+ } else {
+ $this->orgs[$orgId] = $orgId;
+ }
+
+ $orgCfg = new sspmod_ldap_ConfigHelper($orgCfg,
+ 'Authentication source ' . var_export($this->authId, true) .
+ ', organization ' . var_export($orgId, true));
+ $this->ldapOrgs[$orgId] = $orgCfg;
+ }
+ }
+
+
+ /**
+ * Attempt to log in using the given username and password.
+ *
+ * @param string $username The username the user wrote.
+ * @param string $password The password the user wrote.
+ * @param string $org The organization the user chose.
+ * @return array Associative array with the users attributes.
+ */
+ protected function login($username, $password, $org, array $sasl_args = null)
+ {
+ assert('is_string($username)');
+ assert('is_string($password)');
+ assert('is_string($org)');
+
+ if (!array_key_exists($org, $this->ldapOrgs)) {
+ // The user has selected an organization which doesn't exist anymore.
+ SimpleSAML\Logger::warning('Authentication source ' . var_export($this->authId, true) .
+ ': Organization seems to have disappeared while the user logged in.' .
+ ' Organization was ' . var_export($org, true));
+ throw new SimpleSAML_Error_Error('WRONGUSERPASS');
+ }
+
+ if ($this->includeOrgInUsername) {
+ $username = $username . '@' . $org;
+ }
+
+ return $this->ldapOrgs[$org]->login($username, $password, $sasl_args);
+ }
+
+
+ /**
+ * Retrieve list of organizations.
+ *
+ * @return array Associative array with the organizations.
+ */
+ protected function getOrganizations()
+ {
+ return $this->orgs;
+ }
}
diff --git a/modules/ldap/lib/ConfigHelper.php b/modules/ldap/lib/ConfigHelper.php
index 7c8802d..28e4151 100644
--- a/modules/ldap/lib/ConfigHelper.php
+++ b/modules/ldap/lib/ConfigHelper.php
@@ -8,292 +8,297 @@
*
* @package SimpleSAMLphp
*/
-class sspmod_ldap_ConfigHelper {
+class sspmod_ldap_ConfigHelper
+{
+ /**
+ * String with the location of this configuration.
+ * Used for error reporting.
+ */
+ private $location;
- /**
- * String with the location of this configuration.
- * Used for error reporting.
- */
- private $location;
+ /**
+ * The hostname of the LDAP server.
+ */
+ private $hostname;
- /**
- * The hostname of the LDAP server.
- */
- private $hostname;
+ /**
+ * Whether we should use TLS/SSL when contacting the LDAP server.
+ */
+ private $enableTLS;
- /**
- * Whether we should use TLS/SSL when contacting the LDAP server.
- */
- private $enableTLS;
+ /**
+ * Whether debug output is enabled.
+ *
+ * @var bool
+ */
+ private $debug;
- /**
- * Whether debug output is enabled.
- *
- * @var bool
- */
- private $debug;
+ /**
+ * The timeout for accessing the LDAP server.
+ *
+ * @var int
+ */
+ private $timeout;
+ /**
+ * The port used when accessing the LDAP server.
+ *
+ * @var int
+ */
+ private $port;
- /**
- * The timeout for accessing the LDAP server.
- *
- * @var int
- */
- private $timeout;
+ /**
+ * Whether to follow referrals
+ */
+ private $referrals;
- /**
- * The port used when accessing the LDAP server.
- *
- * @var int
- */
- private $port;
- /**
- * Whether to follow referrals
- */
- private $referrals;
+ /**
+ * Whether we need to search for the users DN.
+ */
+ private $searchEnable;
- /**
- * Whether we need to search for the users DN.
- */
- private $searchEnable;
+ /**
+ * The username we should bind with before we can search for the user.
+ */
+ private $searchUsername;
- /**
- * The username we should bind with before we can search for the user.
- */
- private $searchUsername;
+ /**
+ * The password we should bind with before we can search for the user.
+ */
+ private $searchPassword;
- /**
- * The password we should bind with before we can search for the user.
- */
- private $searchPassword;
-
-
- /**
- * Array with the base DN(s) for the search.
- */
- private $searchBase;
-
- /**
- * Additional LDAP filter fields for the search
- */
- private $searchFilter;
-
- /**
- * The attributes which should match the username.
- */
- private $searchAttributes;
-
-
- /**
- * The DN pattern we should use to create the DN from the username.
- */
- private $dnPattern;
-
-
- /**
- * The attributes we should fetch. Can be NULL in which case we will fetch all attributes.
- */
- private $attributes;
-
-
- /**
- * The user cannot get all attributes, privileged reader required
- */
- private $privRead;
-
-
- /**
- * The DN we should bind with before we can get the attributes.
- */
- private $privUsername;
-
-
- /**
- * The password we should bind with before we can get the attributes.
- */
- private $privPassword;
-
-
- /**
- * Constructor for this configuration parser.
- *
- * @param array $config Configuration.
- * @param string $location The location of this configuration. Used for error reporting.
- */
- public function __construct($config, $location) {
- assert('is_array($config)');
- assert('is_string($location)');
-
- $this->location = $location;
-
- // Parse configuration
- $config = SimpleSAML_Configuration::loadFromArray($config, $location);
-
- $this->hostname = $config->getString('hostname');
- $this->enableTLS = $config->getBoolean('enable_tls', FALSE);
- $this->debug = $config->getBoolean('debug', FALSE);
- $this->timeout = $config->getInteger('timeout', 0);
- $this->port = $config->getInteger('port', 389);
- $this->referrals = $config->getBoolean('referrals', TRUE);
- $this->searchEnable = $config->getBoolean('search.enable', FALSE);
- $this->privRead = $config->getBoolean('priv.read', FALSE);
-
- if ($this->searchEnable) {
- $this->searchUsername = $config->getString('search.username', NULL);
- if ($this->searchUsername !== NULL) {
- $this->searchPassword = $config->getString('search.password');
- }
-
- $this->searchBase = $config->getArrayizeString('search.base');
- $this->searchFilter = $config->getString('search.filter',NULL);
- $this->searchAttributes = $config->getArray('search.attributes');
-
- } else {
- $this->dnPattern = $config->getString('dnpattern');
- }
-
- // Are privs needed to get to the attributes?
- if ($this->privRead) {
- $this->privUsername = $config->getString('priv.username');
- $this->privPassword = $config->getString('priv.password');
- }
-
- $this->attributes = $config->getArray('attributes', NULL);
- }
-
-
- /**
- * 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, $this->searchFilter);
- 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);
- }
-
-
- /**
- * Search for a DN.
- *
- * @param string|array $attribute
- * The attribute name(s) searched for. If set to NULL, values from
- * configuration is used.
- * @param string $value
- * The attribute value searched for.
- * @param bool $allowZeroHits
- * Determines if the method will throw an exception if no
- * hits are found. Defaults to FALSE.
- * @return string
- * The DN of the matching element, if found. If no element was
- * found and $allowZeroHits is set to FALSE, an exception will
- * be thrown; otherwise NULL will be returned.
- * @throws SimpleSAML_Error_AuthSource if:
- * - LDAP search encounter some problems when searching cataloge
- * - Not able to connect to LDAP server
- * @throws SimpleSAML_Error_UserNotFound if:
- * - $allowZeroHits er TRUE and no result is found
- *
- */
- public function searchfordn($attribute, $value, $allowZeroHits) {
- $ldap = new SimpleSAML_Auth_LDAP($this->hostname,
- $this->enableTLS,
- $this->debug,
- $this->timeout,
- $this->port,
- $this->referrals);
-
- if ($attribute == NULL)
- $attribute = $this->searchAttributes;
-
- if ($this->searchUsername !== NULL) {
- if(!$ldap->bind($this->searchUsername, $this->searchPassword)) {
- throw new Exception('Error authenticating using search username & password.');
- }
- }
-
- return $ldap->searchfordn($this->searchBase, $attribute,
- $value, $allowZeroHits);
- }
-
- 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);
- }
+ /**
+ * Array with the base DN(s) for the search.
+ */
+ private $searchBase;
+
+ /**
+ * Additional LDAP filter fields for the search
+ */
+ private $searchFilter;
+
+ /**
+ * The attributes which should match the username.
+ */
+ private $searchAttributes;
+
+
+ /**
+ * The DN pattern we should use to create the DN from the username.
+ */
+ private $dnPattern;
+
+
+ /**
+ * The attributes we should fetch. Can be NULL in which case we will fetch all attributes.
+ */
+ private $attributes;
+
+
+ /**
+ * The user cannot get all attributes, privileged reader required
+ */
+ private $privRead;
+
+
+ /**
+ * The DN we should bind with before we can get the attributes.
+ */
+ private $privUsername;
+
+
+ /**
+ * The password we should bind with before we can get the attributes.
+ */
+ private $privPassword;
+
+
+ /**
+ * Constructor for this configuration parser.
+ *
+ * @param array $config Configuration.
+ * @param string $location The location of this configuration. Used for error reporting.
+ */
+ public function __construct($config, $location)
+ {
+ assert('is_array($config)');
+ assert('is_string($location)');
+
+ $this->location = $location;
+
+ // Parse configuration
+ $config = SimpleSAML_Configuration::loadFromArray($config, $location);
+
+ $this->hostname = $config->getString('hostname');
+ $this->enableTLS = $config->getBoolean('enable_tls', false);
+ $this->debug = $config->getBoolean('debug', false);
+ $this->timeout = $config->getInteger('timeout', 0);
+ $this->port = $config->getInteger('port', 389);
+ $this->referrals = $config->getBoolean('referrals', true);
+ $this->searchEnable = $config->getBoolean('search.enable', false);
+ $this->privRead = $config->getBoolean('priv.read', false);
+
+ if ($this->searchEnable) {
+ $this->searchUsername = $config->getString('search.username', null);
+ if ($this->searchUsername !== null) {
+ $this->searchPassword = $config->getString('search.password');
+ }
+
+ $this->searchBase = $config->getArrayizeString('search.base');
+ $this->searchFilter = $config->getString('search.filter', null);
+ $this->searchAttributes = $config->getArray('search.attributes');
+
+ } else {
+ $this->dnPattern = $config->getString('dnpattern');
+ }
+
+ // Are privs needed to get to the attributes?
+ if ($this->privRead) {
+ $this->privUsername = $config->getString('priv.username');
+ $this->privPassword = $config->getString('priv.password');
+ }
+
+ $this->attributes = $config->getArray('attributes', null);
+ }
+
+
+ /**
+ * 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, $this->searchFilter);
+ 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);
+ }
+
+
+ /**
+ * Search for a DN.
+ *
+ * @param string|array $attribute
+ * The attribute name(s) searched for. If set to NULL, values from
+ * configuration is used.
+ * @param string $value
+ * The attribute value searched for.
+ * @param bool $allowZeroHits
+ * Determines if the method will throw an exception if no
+ * hits are found. Defaults to FALSE.
+ * @return string
+ * The DN of the matching element, if found. If no element was
+ * found and $allowZeroHits is set to FALSE, an exception will
+ * be thrown; otherwise NULL will be returned.
+ * @throws SimpleSAML_Error_AuthSource if:
+ * - LDAP search encounter some problems when searching cataloge
+ * - Not able to connect to LDAP server
+ * @throws SimpleSAML_Error_UserNotFound if:
+ * - $allowZeroHits is FALSE and no result is found
+ *
+ */
+ public function searchfordn($attribute, $value, $allowZeroHits)
+ {
+ $ldap = new SimpleSAML_Auth_LDAP($this->hostname,
+ $this->enableTLS,
+ $this->debug,
+ $this->timeout,
+ $this->port,
+ $this->referrals);
+
+ if ($attribute == null) {
+ $attribute = $this->searchAttributes;
+ }
+
+ if ($this->searchUsername !== null) {
+ if (!$ldap->bind($this->searchUsername, $this->searchPassword)) {
+ throw new Exception('Error authenticating using search username & password.');
+ }
+ }
+
+ return $ldap->searchfordn($this->searchBase, $attribute,
+ $value, $allowZeroHits);
+ }
+
+ 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);
+ }
}