summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2009-02-25 13:50:43 -0500
committerRob Crittenden <rcritten@redhat.com>2009-02-27 12:57:21 -0500
commit3fdf9abfce71e0d32f6fc8e5a3b699b663fc5ead (patch)
tree6f541f3dfebfd4e9e7d14a44b28600b556df92b7
parentaf0c0c309dc506b7642f94a9dfcc8359b47f077d (diff)
downloadfreeipa-3fdf9abfce71e0d32f6fc8e5a3b699b663fc5ead.tar.gz
freeipa-3fdf9abfce71e0d32f6fc8e5a3b699b663fc5ead.tar.xz
freeipa-3fdf9abfce71e0d32f6fc8e5a3b699b663fc5ead.zip
Enforce netgroup uniqueness, allow netgroups to be members of netgroups
When adding an entry, convert a constraint violation of "already exists" into a DuplicateEntry exception so the user gets a useful response
-rw-r--r--install/share/unique-attributes.ldif18
-rw-r--r--ipalib/plugins/f_netgroup.py32
-rw-r--r--ipaserver/ipaldap.py6
3 files changed, 51 insertions, 5 deletions
diff --git a/install/share/unique-attributes.ldif b/install/share/unique-attributes.ldif
index 82ec52d1c..764c6320d 100644
--- a/install/share/unique-attributes.ldif
+++ b/install/share/unique-attributes.ldif
@@ -16,6 +16,24 @@ nsslapd-pluginVersion: 1.1.0
nsslapd-pluginVendor: Fedora Project
nsslapd-pluginDescription: Enforce unique attribute values
+dn: cn=netgroup uniqueness,cn=plugins,cn=config
+changetype: add
+objectClass: top
+objectClass: nsSlapdPlugin
+objectClass: extensibleObject
+cn: netgroup uniqueness
+nsslapd-pluginPath: libattr-unique-plugin
+nsslapd-pluginInitfunc: NSUniqueAttr_Init
+nsslapd-pluginType: preoperation
+nsslapd-pluginEnabled: on
+nsslapd-pluginarg0: cn
+nsslapd-pluginarg1: cn=ng,cn=alt,$SUFFIX
+nsslapd-plugin-depends-on-type: database
+nsslapd-pluginId: NSUniqueAttr
+nsslapd-pluginVersion: 1.1.0
+nsslapd-pluginVendor: Fedora Project
+nsslapd-pluginDescription: Enforce unique attribute values
+
#dn: cn=uid uniqueness,cn=plugins,cn=config
#objectClass: top
#objectClass: nsSlapdPlugin
diff --git a/ipalib/plugins/f_netgroup.py b/ipalib/plugins/f_netgroup.py
index 3fa81c7e3..126908559 100644
--- a/ipalib/plugins/f_netgroup.py
+++ b/ipalib/plugins/f_netgroup.py
@@ -43,7 +43,7 @@ def get_members(members):
return members
-def find_members(ldap, failed, members, attribute, filter=None):
+def find_members(ldap, failed, members, attribute, filter=None, base=None):
"""
Return 2 lists: one a list of DNs found, one a list of errors
"""
@@ -51,7 +51,7 @@ def find_members(ldap, failed, members, attribute, filter=None):
for m in members:
if not m: continue
try:
- member_dn = ldap.find_entry_dn(attribute, m, filter)
+ member_dn = ldap.find_entry_dn(attribute, m, filter, base)
found.append(member_dn)
except errors2.NotFound:
failed.append(m)
@@ -315,6 +315,7 @@ class netgroup_add_member(Command):
Str('hostgroups?', doc='comma-separated list of host groups to add'),
Str('users?', doc='comma-separated list of users to add'),
Str('groups?', doc='comma-separated list of groups to add'),
+ Str('netgroups?', doc='comma-separated list of netgroups to add'),
)
def execute(self, cn, **kw):
@@ -327,7 +328,8 @@ class netgroup_add_member(Command):
:param kw: hosts is a comma-separated list of hosts to add
:param kw: hostgroups is a comma-separated list of host groups to add
:param kw: users is a comma-separated list of users to add
- :param kw: groups is a comma-separated list of host to add
+ :param kw: groups is a comma-separated list of groups to add
+ :param kw: netgroups is a comma-separated list of netgroups to add
"""
ldap = self.api.Backend.ldap
dn = ldap.find_entry_dn("cn", cn, netgroup_filter, netgroup_base)
@@ -366,6 +368,15 @@ class netgroup_add_member(Command):
(completed, failed) = add_members(ldap, completed, to_add, dn, 'memberuser')
add_failed+=failed
+ # Netgroups
+ members = get_members(kw.get('netgroups', ''))
+ (to_add, add_failed) = find_members(ldap, add_failed, members, "cn", netgroup_filter, netgroup_base)
+ (completed, failed) = add_members(ldap, completed, to_add, dn, 'member')
+ add_failed+=failed
+
+ if completed == 0 and len(add_failed) == 0:
+ return 0
+
return add_failed
def output_for_cli(self, textui, result, *args, **options):
@@ -377,7 +388,10 @@ class netgroup_add_member(Command):
for a in result:
print "\t'%s'" % a
else:
- textui.print_plain("netgroup membership updated.")
+ if not type(result) in (list, tuple) and result == 0:
+ textui.print_plain("nothing to do.")
+ else:
+ textui.print_plain("netgroup membership updated.")
api.register(netgroup_add_member)
@@ -395,6 +409,7 @@ class netgroup_remove_member(Command):
Str('hostgroups?', doc='comma-separated list of groups to remove'),
Str('users?', doc='comma-separated list of users to remove'),
Str('groups?', doc='comma-separated list of groups to remove'),
+ Str('netgroups?', doc='comma-separated list of netgroups to add'),
)
def execute(self, cn, **kw):
"""
@@ -406,7 +421,8 @@ class netgroup_remove_member(Command):
:param kw: hosts is a comma-separated list of hosts to remove
:param kw: hostgroups is a comma-separated list of host groups to remove
:param kw: users is a comma-separated list of users to remove
- :param kw: groups is a comma-separated list of host to remove
+ :param kw: groups is a comma-separated list of groups to remove
+ :param kw: netgroups is a comma-separated list of netgroups to add
"""
ldap = self.api.Backend.ldap
dn = ldap.find_entry_dn("cn", cn, netgroup_filter, netgroup_base)
@@ -445,6 +461,12 @@ class netgroup_remove_member(Command):
(completed, failed) = remove_members(ldap, completed, to_remove, dn, 'memberuser')
remove_failed+=failed
+ # Netgroups
+ members = get_members(kw.get('netgroups', ''))
+ (to_add, remove_failed) = find_members(ldap, remove_failed, members, "cn", netgroup_filter, netgroup_base)
+ (completed, failed) = remove_members(ldap, completed, to_remove, dn, 'member')
+ remove_failed+=failed
+
return remove_failed
def output_for_cli(self, textui, result, *args, **options):
diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index a490c3407..af17988be 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -381,6 +381,12 @@ class IPAdmin(SimpleLDAPObject):
self.add_s(*args)
except ldap.ALREADY_EXISTS, e:
raise errors2.DuplicateEntry
+ except ldap.CONSTRAINT_VIOLATION, e:
+ # This error gets thrown by the uniqueness plugin
+ if e.args[0].get('info','') == 'Another entry with the same attribute value already exists':
+ raise errors2.DuplicateEntry
+ else:
+ raise errors.DatabaseError, e
except ldap.LDAPError, e:
raise errors.DatabaseError, e
return True