--- html/includes/authentication/ldap.inc.php 2014-11-04 17:14:27.000000000 +0100
+++ html/includes/authentication/ldap.inc.php 2015-02-09 23:11:12.319931939 +0100
@@ -39,6 +39,41 @@
}
}
+function search_user($ldap_group, $userdn, $depth)
+{
+ global $ds, $config;
+
+ $compare = ldap_compare($ds, $ldap_group, $config['auth_ldap_groupmemberattr'], $userdn);
+
+ if ($compare === TRUE)
+ {
+ return TRUE;
+ }
+ elseif (($config['auth_ldap_recursive'] === true) && ($depth < $config['auth_ldap_recursive_maxdepth']))
+ {
+ $depth = $depth + 1;
+
+ $filter = "(&(objectCategory=group)(objectclass=group)(memberOf=". $ldap_group ."))";
+ $ldap_search = ldap_search($ds, trim($config['auth_ldap_suffix'], ', '), $filter, array("distinguishedname"));
+ $ldap_results = ldap_get_entries($ds, $ldap_search);
+
+ array_shift($ldap_results);
+
+ foreach($ldap_results as $element)
+ {
+ $result = search_user($element['distinguishedname'][0], $userdn, $depth);
+ if ($result === TRUE)
+ {
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
// DOCME needs phpdoc block
function ldap_init()
{
@@ -108,8 +143,8 @@
foreach ($config['auth_ldap_group'] as $ldap_group)
{
print_debug("LDAP[Authenticate][Comparing: " . $ldap_group . "][".$config['auth_ldap_groupmemberattr']."=$userdn]");
- $compare = ldap_compare($ds, $ldap_group, $config['auth_ldap_groupmemberattr'], $userdn);
-
+ $compare = search_user($ldap_group, $userdn, 0);
+
if ($compare === -1)
{
print_debug("LDAP[Authenticate][Compare LDAP error: " . ldap_error($ds) . "]");
@@ -120,7 +155,7 @@
// $compare === TRUE
print_debug("LDAP[Authenticate][Processing group: $ldap_group][Matched]");
return 1;
- } // FIXME does not support nested groups
+ }
}
}
}
@@ -216,8 +251,8 @@
// So, we foreach our locally known groups instead.
foreach ($config['auth_ldap_groups'] as $ldap_group => $ldap_group_info)
{
- $compare = ldap_compare($ds, 'cn=' . $ldap_group . ',' . $config['auth_ldap_groupbase'], $config['auth_ldap_groupmemberattr'], $userdn);
-
+ $compare = search_user('cn=' . $ldap_group . ',' . $config['auth_ldap_groupbase'], $userdn, 0);
+
if ($compare === -1)
{
print_debug("LDAP[UserLevel][Compare LDAP error: " . ldap_error($ds) . "]");
@@ -311,14 +346,14 @@
$user_id = ldap_internal_auth_user_id($entries[$i]);
$userdn = ($config['auth_ldap_groupmembertype'] == 'fulldn' ? $entries[$i]['dn'] : $username);
-
print_debug("LDAP[UserList][Compare: " . implode('|',$config['auth_ldap_group']) . "][".$config['auth_ldap_groupmemberattr']."][$userdn]");
foreach ($config['auth_ldap_group'] as $ldap_group)
{
$authorized = 0;
- $compare = ldap_compare($ds, $ldap_group, $config['auth_ldap_groupmemberattr'], $userdn);
-
+
+ $compare = search_user($ldap_group, $userdn, 0);
+
if ($compare === -1)
{
print_debug("LDAP[UserList][Compare LDAP error: " . ldap_error($ds) . "]");
@@ -330,7 +365,7 @@
print_debug("LDAP[UserList][Authorized: $userdn for group $ldap_group]");
$authorized = 1;
break;
- } // FIXME does not support nested groups
+ }
}
if (!isset($config['auth_ldap_group']) || $authorized)
--- includes/defaults.inc.php 2014-11-21 13:33:07.000000000 +0100
+++ includes/defaults.inc.php 2015-02-09 22:48:21.459927476 +0100
@@ -542,6 +542,8 @@
#$config['auth_ldap_ad_domain'] = "ad.yourcorp.com"; // AD domain name (fqdn form), used to determine DCs if server list is unset
$config['auth_ldap_port'] = 389; // LDAP server port
$config['auth_ldap_starttls'] = 'no'; // Use STARTTLS ('no', 'optional' or 'require')
+$config['auth_ldap_recursive'] = TRUE; // Active Directory recursive lookup for nested groups
+$config['auth_ldap_recursive_maxdepth'] = 3; // Max depth for recursive lookup
$config['auth_ldap_prefix'] = "uid=";
$config['auth_ldap_suffix'] = ",ou=People,dc=example,dc=com";
#$config['auth_ldap_group'] = array("cn=observium,ou=groups,dc=example,dc=com");