summaryrefslogtreecommitdiffstats
path: root/modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php')
-rw-r--r--modules/ldap/lib/Auth/Process/AttributeAddUsersGroups.php591
1 files changed, 308 insertions, 283 deletions
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;
+ }
}