summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipa-admintools/ipa-findgroup2
-rw-r--r--ipa-python/ipaclient.py4
-rw-r--r--ipa-python/rpcclient.py4
-rw-r--r--ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js13
-rw-r--r--ipa-server/ipa-gui/ipagui/subcontrollers/group.py33
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupeditform.kid13
-rw-r--r--ipa-server/ipa-gui/ipagui/templates/groupshow.kid25
-rw-r--r--ipa-server/xmlrpc-server/funcs.py48
8 files changed, 126 insertions, 16 deletions
diff --git a/ipa-admintools/ipa-findgroup b/ipa-admintools/ipa-findgroup
index 54a8ce525..706e77ae9 100644
--- a/ipa-admintools/ipa-findgroup
+++ b/ipa-admintools/ipa-findgroup
@@ -74,7 +74,7 @@ def main():
for ent in groups:
try:
- members = client.group_members(ent.dn, ['dn','cn'])
+ members = client.group_members(ent.dn, ['dn','cn'], 0)
except ipa.ipaerror.IPAError, e:
print "Error getting members for " + ent.dn
print str(e)
diff --git a/ipa-python/ipaclient.py b/ipa-python/ipaclient.py
index b685be38c..4fc836953 100644
--- a/ipa-python/ipaclient.py
+++ b/ipa-python/ipaclient.py
@@ -326,11 +326,11 @@ class IPAClient:
return self.transport.get_all_attrs()
- def group_members(self, groupdn, attr_list):
+ def group_members(self, groupdn, attr_list, membertype):
"""Do a memberOf search of groupdn and return the attributes in
attr_list (an empty list returns everything)."""
- results = self.transport.group_members(groupdn, attr_list)
+ results = self.transport.group_members(groupdn, attr_list, membertype)
counter = results[0]
diff --git a/ipa-python/rpcclient.py b/ipa-python/rpcclient.py
index 7fa075b1d..1c8e751b5 100644
--- a/ipa-python/rpcclient.py
+++ b/ipa-python/rpcclient.py
@@ -611,7 +611,7 @@ class RPCClient:
return ipautil.unwrap_binary_data(result)
- def group_members(self, groupdn, attr_list=None):
+ def group_members(self, groupdn, attr_list=None, memberstype=0):
"""Do a memberOf search of groupdn and return the attributes in
attr_list (an empty list returns everything)."""
@@ -620,7 +620,7 @@ class RPCClient:
server = self.setup_server()
try:
- result = server.group_members(groupdn, attr_list)
+ result = server.group_members(groupdn, attr_list, memberstype)
except xmlrpclib.Fault, fault:
raise ipaerror.gen_exception(fault.faultCode, fault.faultString)
except socket.error, (value, msg):
diff --git a/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js b/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js
index 4d73711e6..b670c457f 100644
--- a/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js
+++ b/ipa-server/ipa-gui/ipagui/static/javascript/dynamicedit.js
@@ -88,10 +88,23 @@ var dn_to_member_div_id = new Hash();
*/
function renderMemberInfo(newdiv, info) {
if (info.type == "user") {
+ bold = document.createElement('b');
+ bold.appendChild(document.createTextNode(
+ info.name + " " + info.descr + " "));
+ newdiv.appendChild(bold);
+ } else if (info.type == "iuser") {
newdiv.appendChild(document.createTextNode(
info.name + " " + info.descr + " "));
} else if (info.type == "group") {
ital = document.createElement('i');
+ bold = document.createElement('b');
+ ital.appendChild(bold);
+ bold.appendChild(document.createTextNode(
+ info.name + " " +
+ info.descr + " "));
+ newdiv.appendChild(ital);
+ } else if (info.type == "igroup") {
+ ital = document.createElement('i');
ital.appendChild(document.createTextNode(
info.name + " " +
info.descr + " "));
diff --git a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py
index 08ecf32ad..eac5cb0bd 100644
--- a/ipa-server/ipa-gui/ipagui/subcontrollers/group.py
+++ b/ipa-server/ipa-gui/ipagui/subcontrollers/group.py
@@ -208,7 +208,7 @@ class GroupController(IPAController):
# convert members to users, for easier manipulation on the page
#
- members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'])
+ members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 1)
members = members[1:]
members.sort(self.sort_group_member)
@@ -216,6 +216,20 @@ class GroupController(IPAController):
# (so we don't have to do this on each round trip)
member_dicts = map(lambda member: member.toDict(), members)
+ indirect_members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 2)
+ indirect_members = indirect_members[1:]
+ indirect_members.sort(self.sort_group_member)
+
+ # add our own flag
+ for i in range(len(indirect_members)):
+ indirect_members[i].setValue('inherited', True)
+
+ # Map users into an array of dicts, which can be serialized
+ # (so we don't have to do this on each round trip)
+ indirect_members_dicts = map(lambda member: member.toDict(), indirect_members)
+
+ member_dicts = member_dicts + indirect_members_dicts
+
# store a copy of the original group for the update later
group_data = b64encode(dumps(group_dict))
member_data = b64encode(dumps(member_dicts))
@@ -411,11 +425,26 @@ class GroupController(IPAController):
# convert members to users, for display on the page
#
- members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'])
+ members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 1)
members = members[1:]
members.sort(self.sort_group_member)
member_dicts = map(lambda member: member.toDict(), members)
+ indirect_members = client.group_members(group.dn, ['dn', 'givenname', 'sn', 'uid', 'cn'], 2)
+ indirect_members = indirect_members[1:]
+ indirect_members.sort(self.sort_group_member)
+
+ # add our own flag
+ for i in range(len(indirect_members)):
+ indirect_members[i].setValue('inherited', True)
+
+ # Map users into an array of dicts, which can be serialized
+ # (so we don't have to do this on each round trip)
+ indirect_members_dicts = map(lambda member: member.toDict(), indirect_members)
+
+ member_dicts = member_dicts + indirect_members_dicts
+ logging.info("%s" % member_dicts)
+
return dict(group=group_dict, fields=ipagui.forms.group.GroupFields(),
members = member_dicts)
except ipaerror.IPAError, e:
diff --git a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid
index 7f446b036..78f76b0a1 100644
--- a/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid
+++ b/ipa-server/ipa-gui/ipagui/templates/groupeditform.kid
@@ -158,15 +158,22 @@ from ipagui.helpers import ipahelper
member_dn_esc = ipahelper.javascript_string_escape(member_dn)
member_uid = member.get('uid')
+ member_inherited = member.get('inherited')
if member_uid:
member_name = "%s %s" % (member.get('givenName', ''),
member.get('sn', ''))
member_descr = "(%s)" % member.get('uid')
- member_type = "user"
+ if member_inherited:
+ member_type = "iuser"
+ else:
+ member_type = "user"
else:
member_name = member.get('cn')
member_descr = "[group]"
- member_type = "group"
+ if member_inherited:
+ member_type = "igroup"
+ else:
+ member_type = "group"
member_name_esc = ipahelper.javascript_string_escape(member_name)
member_descr_esc = ipahelper.javascript_string_escape(member_descr)
member_type_esc = ipahelper.javascript_string_escape(member_type)
@@ -178,7 +185,7 @@ from ipagui.helpers import ipahelper
'${member_descr_esc}',
'${member_type_esc}'));
</script>
- <a href="#"
+ <a py:if="member_inherited != True" href="#"
onclick="removememberHandler(this, '${member_dn_esc}',
new MemberDisplayInfo('${member_name_esc}',
'${member_descr_esc}',
diff --git a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid
index 0ddb93851..d0ca6982a 100644
--- a/ipa-server/ipa-gui/ipagui/templates/groupshow.kid
+++ b/ipa-server/ipa-gui/ipagui/templates/groupshow.kid
@@ -73,10 +73,14 @@ from ipagui.helpers import userhelper
<?python
member_uid = member.get('uid')
+ member_inherited = member.get('inherited')
if member_uid:
member_cn = "%s %s" % (member.get('givenName', ''), member.get('sn', ''))
member_desc = "(%s)" % member_uid
- member_type = "user"
+ if member_inherited:
+ member_type = "iuser"
+ else:
+ member_type = "user"
view_url = tg.url('/user/show', uid=member_uid)
else:
mem = member.get('cn')
@@ -84,14 +88,31 @@ from ipagui.helpers import userhelper
mem = mem[0]
member_cn = "%s" % mem
member_desc = "[group]"
- member_type = "group"
+ if member_inherited:
+ member_type = "igroup"
+ else:
+ member_type = "group"
view_url = tg.url('/group/show', cn=member_cn)
?>
<span py:if='member_type == "user"'>
+ <b>
+ <a href="${view_url}"
+ >${member_cn}</a> ${member_desc}
+ </b>
+ </span>
+ <span py:if='member_type == "iuser"'>
<a href="${view_url}"
>${member_cn}</a> ${member_desc}
</span>
<span py:if='member_type == "group"'>
+ <b>
+ <i>
+ <a href="${view_url}"
+ >${member_cn}</a> ${member_desc}
+ </i>
+ </b>
+ </span>
+ <span py:if='member_type == "igroup"'>
<i>
<a href="${view_url}"
>${member_cn}</a> ${member_desc}
diff --git a/ipa-server/xmlrpc-server/funcs.py b/ipa-server/xmlrpc-server/funcs.py
index 43bcf9869..4c346698c 100644
--- a/ipa-server/xmlrpc-server/funcs.py
+++ b/ipa-server/xmlrpc-server/funcs.py
@@ -1725,22 +1725,42 @@ class IPAServer:
return attrs.attr_label_list
- def group_members(self, groupdn, attr_list, opts=None):
+ def group_members(self, groupdn, attr_list, membertype, opts=None):
"""Do a memberOf search of groupdn and return the attributes in
- attr_list (an empty list returns everything)."""
+ attr_list (an empty list returns all attributes).
+
+ membertype = 0 all members returned
+ membertype = 1 only direct members are returned
+ membertype = 2 only inherited members are returned
+
+ Members may be included in a group as a result of being a member
+ of a group that is a member of the group being queried.
+ """
if not isinstance(groupdn,basestring) or len(groupdn) == 0:
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
if attr_list is not None and not isinstance(attr_list,list):
raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
+ if membertype is not None and not isinstance(membertype,int):
+ raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
+ if membertype is None:
+ membertype = 0
+ if membertype < 0 or membertype > 3:
+ raise ipaerror.gen_exception(ipaerror.INPUT_INVALID_PARAMETER)
config = self.get_ipa_config(opts)
timelimit = float(config.get('ipasearchtimelimit'))
+ logging.debug("IPA: group_members: %s %s %s" % (groupdn, attr_list, membertype))
+
searchlimit = float(config.get('ipasearchrecordslimit'))
groupdn = self.__safe_filter(groupdn)
searchfilter = "(memberOf=%s)" % groupdn
+ if attr_list is None:
+ attr_list = []
+ attr_list.append("member")
+
conn = self.getConnection(opts)
try:
try:
@@ -1755,9 +1775,29 @@ class IPAServer:
counter = results[0]
results = results[1:]
- entries = [counter]
+ if membertype == 0:
+ entries = [counter]
+ for e in results:
+ entries.append(self.convert_entry(e))
+
+ return entries
+
+ group = self.get_entry_by_dn(groupdn, ['dn', 'member'], opts)
+ real_members = group.get('member')
+ if isinstance(real_members, basestring):
+ real_members = [real_members]
+
+ entries = [0]
for e in results:
- entries.append(self.convert_entry(e))
+ if e.dn not in real_members:
+ if membertype == 2:
+ entries.append(self.convert_entry(e))
+ else:
+ if membertype == 1:
+ entries.append(self.convert_entry(e))
+
+ if len(entries) > 1:
+ entries[0] = len(entries) - 1
return entries