From af4518b72882f88a01de0e5c23d423898ba894b4 Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Fri, 13 Jun 2014 12:06:07 +0200 Subject: sudorule: Refactor add and remove external_post_callback Reviewed-By: Petr Viktorin --- ipalib/plugins/baseldap.py | 56 +++++++++++++++++---- ipalib/plugins/group.py | 33 ++++++------ ipalib/plugins/netgroup.py | 30 +++++++---- ipalib/plugins/sudorule.py | 122 +++++++++++++++++++++++++++------------------ 4 files changed, 156 insertions(+), 85 deletions(-) (limited to 'ipalib') diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py index 9f31afd45..44302c9a7 100644 --- a/ipalib/plugins/baseldap.py +++ b/ipalib/plugins/baseldap.py @@ -322,6 +322,7 @@ def add_external_pre_callback(membertype, ldap, dn, keys, options): membertype is the type of member """ assert isinstance(dn, DN) + # validate hostname with allowed underscore characters, non-fqdn # hostnames are allowed def validate_host(hostname): @@ -341,19 +342,30 @@ def add_external_pre_callback(membertype, ldap, dn, keys, options): raise errors.ValidationError(name=membertype, error=e) return dn -def add_external_post_callback(memberattr, membertype, externalattr, ldap, completed, failed, dn, entry_attrs, *keys, **options): - """ - Post callback to add failed members as external members. - - This should be called by a commands post callback directly. - memberattr is one of memberuser, - membertype is the type of member: user, - externalattr is one of externaluser, +def add_external_post_callback(ldap, dn, entry_attrs, failed, completed, + memberattr, membertype, externalattr, + normalize=True): + """ + Takes the following arguments: + failed - the list of failed entries, these are candidates for possible + external entries to add + completed - the number of successfully added entries so far + memberattr - the attribute name that IPA uses for membership natively + (e.g. memberhost) + membertype - the object type of the member (e.g. host) + externalattr - the attribute name that IPA uses to store the membership + of the entries that are not managed by IPA + (e.g externalhost) + + Returns the number of completed entries so far (the number of entries + handled by IPA incremented by the number of handled external entries) and + dn. """ assert isinstance(dn, DN) + completed_external = 0 - normalize = options.get('external_callback_normalize', True) + # Sift through the failures. We assume that these are all # entries that aren't stored in IPA, aka external entries. if memberattr in failed and membertype in failed[memberattr]: @@ -362,11 +374,13 @@ def add_external_post_callback(memberattr, membertype, externalattr, ldap, compl members = entry_attrs.get(memberattr, []) external_entries = entry_attrs_.get(externalattr, []) lc_external_entries = set(e.lower() for e in external_entries) + failed_entries = [] for entry in failed[memberattr][membertype]: membername = entry[0].lower() member_dn = api.Object[membertype].get_dn(membername) assert isinstance(member_dn, DN) + if (membername not in lc_external_entries and member_dn not in members): # Not an IPA entry, assume external @@ -399,8 +413,28 @@ def add_external_post_callback(memberattr, membertype, externalattr, ldap, compl return (completed + completed_external, dn) -def remove_external_post_callback(memberattr, membertype, externalattr, ldap, completed, failed, dn, entry_attrs, *keys, **options): + +def remove_external_post_callback(ldap, dn, entry_attrs, failed, completed, + memberattr, membertype, externalattr): + """ + Takes the following arguments: + failed - the list of failed entries, these are candidates for possible + external entries to remove + completed - the number of successfully removed entries so far + memberattr - the attribute name that IPA uses for membership natively + (e.g. memberhost) + membertype - the object type of the member (e.g. host) + externalattr - the attribute name that IPA uses to store the membership + of the entries that are not managed by IPA + (e.g externalhost) + + Returns the number of completed entries so far (the number of entries + handled by IPA incremented by the number of handled external entries) and + dn. + """ + assert isinstance(dn, DN) + # Run through the failures and gracefully remove any member defined # as an external member. if memberattr in failed and membertype in failed[memberattr]: @@ -409,6 +443,7 @@ def remove_external_post_callback(memberattr, membertype, externalattr, ldap, co external_entries = entry_attrs_.get(externalattr, []) failed_entries = [] completed_external = 0 + for entry in failed[memberattr][membertype]: membername = entry[0].lower() if membername in external_entries or entry[0] in external_entries: @@ -435,6 +470,7 @@ def remove_external_post_callback(memberattr, membertype, externalattr, ldap, co return (completed + completed_external, dn) + def host_is_master(ldap, fqdn): """ Check to see if this host is a master. diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py index 126294700..af5d4b6bf 100644 --- a/ipalib/plugins/group.py +++ b/ipalib/plugins/group.py @@ -115,6 +115,7 @@ register = Registry() PROTECTED_GROUPS = (u'admins', u'trust admins', u'default smb group') + @register() class group(LDAPObject): """ @@ -238,6 +239,7 @@ ipaexternalmember_param = Str('ipaexternalmember*', flags=['no_create', 'no_update', 'no_search'], ) + @register() class group_add(LDAPCreate): __doc__ = _('Create a new group.') @@ -273,8 +275,6 @@ class group_add(LDAPCreate): return dn - - @register() class group_del(LDAPDelete): __doc__ = _('Delete group.') @@ -308,7 +308,6 @@ class group_del(LDAPDelete): return True - @register() class group_mod(LDAPUpdate): __doc__ = _('Modify a group.') @@ -380,7 +379,6 @@ class group_mod(LDAPUpdate): raise exc - @register() class group_find(LDAPSearch): __doc__ = _('Search for groups.') @@ -450,7 +448,6 @@ class group_find(LDAPSearch): return (filter, base_dn, scope) - @register() class group_show(LDAPRetrieve): __doc__ = _('Display information about a named group.') @@ -505,15 +502,18 @@ class group_add_member(LDAPAddMember): restore = [] if 'member' in failed and 'group' in failed['member']: restore = failed['member']['group'] - failed['member']['group'] = list((id,id) for id in sids) - result = add_external_post_callback('member', 'group', 'ipaexternalmember', - ldap, completed, failed, dn, entry_attrs, - keys, options, external_callback_normalize=False) + failed['member']['group'] = list((id, id) for id in sids) + result = add_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='member', + membertype='group', + externalattr='ipaexternalmember', + normalize=False) failed['member']['group'] += restore + failed_sids return result - @register() class group_remove_member(LDAPRemoveMember): __doc__ = _('Remove members from a group.') @@ -559,15 +559,18 @@ class group_remove_member(LDAPRemoveMember): restore = [] if 'member' in failed and 'group' in failed['member']: restore = failed['member']['group'] - failed['member']['group'] = list((id,id) for id in sids) - result = remove_external_post_callback('member', 'group', 'ipaexternalmember', - ldap, completed, failed, dn, entry_attrs, - keys, options) + failed['member']['group'] = list((id, id) for id in sids) + result = remove_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='member', + membertype='group', + externalattr='ipaexternalmember', + ) failed['member']['group'] += restore + failed_sids return result - @register() class group_detach(LDAPQuery): __doc__ = _('Detach a managed group from a user.') diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py index 2d9fdebd0..a7cad1dcb 100644 --- a/ipalib/plugins/netgroup.py +++ b/ipalib/plugins/netgroup.py @@ -75,6 +75,7 @@ output_params = ( ), ) + @register() class netgroup(LDAPObject): """ @@ -206,7 +207,6 @@ class netgroup(LDAPObject): ) - @register() class netgroup_add(LDAPCreate): __doc__ = _('Add a new netgroup.') @@ -243,7 +243,6 @@ class netgroup_add(LDAPCreate): return dn - @register() class netgroup_del(LDAPDelete): __doc__ = _('Delete a netgroup.') @@ -273,7 +272,6 @@ class netgroup_mod(LDAPUpdate): return dn - @register() class netgroup_find(LDAPSearch): __doc__ = _('Search for a netgroup.') @@ -311,7 +309,6 @@ class netgroup_find(LDAPSearch): return (filter, base_dn, scope) - @register() class netgroup_show(LDAPRetrieve): __doc__ = _('Display information about a netgroup.') @@ -319,21 +316,26 @@ class netgroup_show(LDAPRetrieve): has_output_params = LDAPRetrieve.has_output_params + output_params - @register() class netgroup_add_member(LDAPAddMember): __doc__ = _('Add members to a netgroup.') member_attributes = ['memberuser', 'memberhost', 'member'] has_output_params = LDAPAddMember.has_output_params + output_params + def pre_callback(self, ldap, dn, found, not_found, *keys, **options): assert isinstance(dn, DN) return add_external_pre_callback('host', ldap, dn, keys, options) - def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options): + def post_callback(self, ldap, completed, failed, dn, entry_attrs, + *keys, **options): assert isinstance(dn, DN) - return add_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options) - + return add_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='memberhost', + membertype='host', + externalattr='externalhost') @register() @@ -342,7 +344,13 @@ class netgroup_remove_member(LDAPRemoveMember): member_attributes = ['memberuser', 'memberhost', 'member'] has_output_params = LDAPRemoveMember.has_output_params + output_params - def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options): - assert isinstance(dn, DN) - return remove_external_post_callback('memberhost', 'host', 'externalhost', ldap, completed, failed, dn, entry_attrs, keys, options) + def post_callback(self, ldap, completed, failed, dn, entry_attrs, + *keys, **options): + assert isinstance(dn, DN) + return remove_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='memberhost', + membertype='host', + externalattr='externalhost') diff --git a/ipalib/plugins/sudorule.py b/ipalib/plugins/sudorule.py index 59beed4e8..d2d30a148 100644 --- a/ipalib/plugins/sudorule.py +++ b/ipalib/plugins/sudorule.py @@ -594,10 +594,12 @@ class sudorule_add_user(LDAPAddMember): def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) - return add_external_post_callback('memberuser', 'user', 'externaluser', - ldap, completed, failed, dn, - entry_attrs, keys, options) - + return add_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='memberuser', + membertype='user', + externalattr='externaluser') @register() @@ -610,11 +612,12 @@ class sudorule_remove_user(LDAPRemoveMember): def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) - return remove_external_post_callback('memberuser', 'user', - 'externaluser', ldap, completed, - failed, dn, entry_attrs, keys, - options) - + return remove_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='memberuser', + membertype='user', + externalattr='externaluser') @register() @@ -666,10 +669,12 @@ class sudorule_add_host(LDAPAddMember): pass completed = completed + num_added - return add_external_post_callback('memberhost', 'host', 'externalhost', - ldap, completed, failed, dn, - entry_attrs, keys, options) - + return add_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='memberhost', + membertype='host', + externalattr='externalhost') @register() @@ -683,6 +688,7 @@ class sudorule_remove_host(LDAPRemoveMember): for option in super(sudorule_remove_host, self).get_options(): yield option yield hostmask_membership_param + def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) @@ -708,10 +714,12 @@ class sudorule_remove_host(LDAPRemoveMember): pass completed = completed + num_added - return remove_external_post_callback('memberhost', 'host', - 'externalhost', ldap, completed, - failed, dn, entry_attrs, keys, - options) + return remove_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='memberhost', + membertype='host', + externalattr='externalhost') @register() @@ -770,17 +778,23 @@ class sudorule_add_runasuser(LDAPAddMember): # so that the entries added by the framework are not counted twice # (once in each call of add_external_post_callback) - (completed_ex_users, dn) = add_external_post_callback( - 'ipasudorunas', 'user', - 'ipasudorunasextuser', - ldap, 0, failed, dn, entry_attrs, - keys, options) - - (completed_ex_groups, dn) = add_external_post_callback( - 'ipasudorunas', 'group', - 'ipasudorunasextusergroup', - ldap, 0, failed, dn, entry_attrs, - keys, options) + (completed_ex_users, dn) = add_external_post_callback(ldap, dn, + entry_attrs, + failed=failed, + completed=0, + memberattr='ipasudorunas', + membertype='user', + externalattr='ipasudorunasextuser', + ) + + (completed_ex_groups, dn) = add_external_post_callback(ldap, dn, + entry_attrs=entry_attrs, + failed=failed, + completed=0, + memberattr='ipasudorunas', + membertype='user', + externalattr='ipasudorunasextuser', + ) return (completed + completed_ex_users + completed_ex_groups, dn) @@ -802,17 +816,23 @@ class sudorule_remove_runasuser(LDAPRemoveMember): # so that the entries added by the framework are not counted twice # (once in each call of remove_external_post_callback) - (completed_ex_users, dn) = remove_external_post_callback( - 'ipasudorunas', 'user', - 'ipasudorunasextuser', - ldap, 0, failed, dn, entry_attrs, - keys, options) - - (completed_ex_groups, dn) = remove_external_post_callback( - 'ipasudorunas', 'group', - 'ipasudorunasextusergroup', - ldap, 0, failed, dn, entry_attrs, - keys, options) + (completed_ex_users, dn) = remove_external_post_callback(ldap, dn, + entry_attrs=entry_attrs, + failed=failed, + completed=0, + memberattr='ipasudorunas', + membertype='user', + externalattr='ipasudorunasextuser', + ) + + (completed_ex_groups, dn) = remove_external_post_callback(ldap, dn, + entry_attrs=entry_attrs, + failed=failed, + completed=0, + memberattr='ipasudorunas', + membertype='group', + externalattr='ipasudorunasextusergroup', + ) return (completed + completed_ex_users + completed_ex_groups, dn) @@ -856,11 +876,13 @@ class sudorule_add_runasgroup(LDAPAddMember): def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) - return add_external_post_callback('ipasudorunasgroup', 'group', - 'ipasudorunasextgroup', ldap, - completed, failed, dn, entry_attrs, - keys, options) - + return add_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='ipasudorunasgroup', + membertype='group', + externalattr='ipasudorunasextgroup', + ) @register() @@ -873,11 +895,13 @@ class sudorule_remove_runasgroup(LDAPRemoveMember): def post_callback(self, ldap, completed, failed, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) - return remove_external_post_callback('ipasudorunasgroup', 'group', - 'ipasudorunasextgroup', ldap, - completed, failed, dn, - entry_attrs, keys, options) - + return remove_external_post_callback(ldap, dn, entry_attrs, + failed=failed, + completed=completed, + memberattr='ipasudorunasgroup', + membertype='group', + externalattr='ipasudorunasextgroup', + ) @register() -- cgit