diff --git a/lam/HISTORY b/lam/HISTORY
index 6bad22e6..bf27d7b0 100644
--- a/lam/HISTORY
+++ b/lam/HISTORY
@@ -1,3 +1,9 @@
+September 2016
+ - Windows: allow to show effective members of a group
+ - LAM Pro:
+ -> Group of names/members + roles: allow to show effective members of a group
+
+
21.06.2016 5.4
- Unix: support magic numbers for UIDs/GIDs (e.g. 389 server DNA plugin)
- Samba 3: support for Samba password history (RFE 133)
diff --git a/lam/docs/manual-sources/howto.xml b/lam/docs/manual-sources/howto.xml
index 904d0583..49270185 100644
--- a/lam/docs/manual-sources/howto.xml
+++ b/lam/docs/manual-sources/howto.xml
@@ -4574,6 +4574,10 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
+ With "Show effective members" you can show a list of all members
+ of this group including members of subgroups and their
+ subgroups.
+
@@ -5005,6 +5009,10 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
You can add any accounts as members. This includes other groups
which leads to nested groups.
+ To show members of nested groups click on "Show effective
+ members". Please note that for large groups this will run lots of
+ queries against your LDAP server.
+
@@ -5070,6 +5078,10 @@ mysql> GRANT ALL PRIVILEGES ON lam_cron.* TO 'lam_cron'@'localhost';
which leads to nested roles (needs to be supported by LDAP client
applications).
+ To show members of nested roles click on "Show effective members".
+ Please note that for large roles this will run lots of queries against
+ your LDAP server.
+
diff --git a/lam/docs/manual-sources/images/groupOfNames1.png b/lam/docs/manual-sources/images/groupOfNames1.png
index 32684b49..bb06538f 100644
Binary files a/lam/docs/manual-sources/images/groupOfNames1.png and b/lam/docs/manual-sources/images/groupOfNames1.png differ
diff --git a/lam/docs/manual-sources/images/mod_organizationalRole5.png b/lam/docs/manual-sources/images/mod_organizationalRole5.png
index 34f71f3f..44a0147a 100644
Binary files a/lam/docs/manual-sources/images/mod_organizationalRole5.png and b/lam/docs/manual-sources/images/mod_organizationalRole5.png differ
diff --git a/lam/docs/manual-sources/images/mod_windowsGroup2.png b/lam/docs/manual-sources/images/mod_windowsGroup2.png
index a99f4f21..781bc6cc 100644
Binary files a/lam/docs/manual-sources/images/mod_windowsGroup2.png and b/lam/docs/manual-sources/images/mod_windowsGroup2.png differ
diff --git a/lam/lib/modules/windowsGroup.inc b/lam/lib/modules/windowsGroup.inc
index e84897b5..64539b70 100644
--- a/lam/lib/modules/windowsGroup.inc
+++ b/lam/lib/modules/windowsGroup.inc
@@ -386,7 +386,13 @@ class windowsGroup extends baseModule {
// group members
$container->addElement(new htmlSpacer(null, '10px'), true);
$container->addElement(new htmlOutputText(_("Group members")));
- $container->addElement(new htmlAccountPageButton(get_class($this), 'user', 'open', _('Edit members')));
+ $memberButtons = new htmlGroup();
+ $memberButtons->addElement(new htmlAccountPageButton(get_class($this), 'user', 'open', _('Edit')));
+ if (!empty($this->attributes['member'])) {
+ $memberButtons->addElement(new htmlSpacer('10px', null));
+ $memberButtons->addElement(new htmlAccountPageButton(get_class($this), 'effectiveMembers', 'open', _('Show effective members')));
+ }
+ $container->addElement($memberButtons);
$container->addElement(new htmlHelpLink('member'), true);
$memberList = array();
if (isset($this->attributes['member'])) {
@@ -408,7 +414,7 @@ class windowsGroup extends baseModule {
// member of
$container->addVerticalSpace('10px');
$container->addElement(new htmlOutputText(_("Member of")));
- $container->addElement(new htmlAccountPageButton(get_class($this), 'memberof', 'open', _('Edit member of')));
+ $container->addElement(new htmlAccountPageButton(get_class($this), 'memberof', 'open', _('Edit')));
$container->addElement(new htmlHelpLink('memberOf'), true);
$memberList = array();
if (isset($this->attributes['memberOf'])) {
@@ -765,6 +771,39 @@ class windowsGroup extends baseModule {
return $return;
}
+ /**
+ * This function will create the meta HTML code to show a page to list effective members.
+ *
+ * @return htmlElement HTML meta data
+ */
+ function display_html_effectiveMembers() {
+ $return = new htmlTable();
+ $effectiveMembers = $this->getEffectiveMembers();
+ $entryTable = new htmlTable();
+ // sort by DN, align right
+ usort($effectiveMembers, 'compareDN');
+ $entryTable->alignment = htmlElement::ALIGN_RIGHT;
+ foreach ($effectiveMembers as $member) {
+ $entry = new htmlOutputText(getAbstractDN($member));
+ $entry->alignment = htmlElement::ALIGN_RIGHT;
+ $entryTable->addElement($entry, true);
+ }
+ $return->addElement($entryTable, true);
+ $return->addVerticalSpace('10px');
+ $return->addElement(new htmlAccountPageButton(get_class($this), 'attributes', 'membersEffectiveBack', _('Back')));
+ return $return;
+ }
+
+ /**
+ * Processes user input of the effective members page.
+ *
+ * @return array list of info/error messages
+ */
+ function process_effectiveMembers() {
+ // no processing, page is read-only
+ return array();
+ }
+
/**
* In this function the LDAP account is built up.
*
@@ -1043,6 +1082,29 @@ class windowsGroup extends baseModule {
return $messages;
}
+ /**
+ * Recursively gets the members of this group and its subgroups.
+ *
+ * @return list of DNs
+ */
+ private function getEffectiveMembers() {
+ $membersToCheck = $this->attributes['member'];
+ $effectiveMembers = $membersToCheck;
+ while (!empty($membersToCheck)) {
+ $member = array_pop($membersToCheck);
+ $attrs = ldapGetDN($member, array('member'));
+ if (!empty($attrs['member'])) {
+ foreach ($attrs['member'] as $newMember) {
+ if (!in_array($newMember, $effectiveMembers)) {
+ $effectiveMembers[] = $newMember;
+ $membersToCheck[] = $newMember;
+ }
+ }
+ }
+ }
+ return $effectiveMembers;
+ }
+
}