mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 07:33:27 -06:00
sudorule-add-user: allow to reference users and groups from trusted domains directly
Allow specifying AD users and groups from trusted Active Directory forests in `ipa sudorule-add/remove-user` family of commands. SSSD uses single attribute 'externalUser' for IPA to pull 'external' objects referenced in SUDO rules. This means both users and groups are represented within the same attribute, with groups prefixed with '%', as described in sudoers(5) man page. Add member type validators to 'ipa sudorule-add/remove-user' family commands and rely on member type validators from 'idviews' plugin to resolve trusted objects. Referencing fully qualified names for users and groups from trusted Active Directory domains in 'externalUser' attribute of SUDO rules is supported in SSSD 2.4 or later. RN: IPA now supports adding users and groups from trusted Active RN: Directory domains in SUDO rules without an intermediate non-POSIX RN: group membership Fixes: https://pagure.io/freeipa/issue/3226 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Christian Heimes <cheimes@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com> Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
parent
0ffdfc70f2
commit
a37db297f0
@ -27,6 +27,7 @@ from .baseldap import (LDAPObject, LDAPCreate, LDAPDelete,
|
||||
LDAPUpdate, LDAPSearch, LDAPRetrieve,
|
||||
LDAPQuery, LDAPAddMember, LDAPRemoveMember,
|
||||
add_external_pre_callback,
|
||||
pre_callback_process_external_objects,
|
||||
add_external_post_callback,
|
||||
remove_external_post_callback,
|
||||
output, entry_to_dict, pkey_to_value,
|
||||
@ -98,6 +99,11 @@ register = Registry()
|
||||
|
||||
topic = 'sudo'
|
||||
|
||||
# used to process external object references in SUDO rules
|
||||
USER_OBJ_SPEC = ('user', None)
|
||||
GROUP_OBJ_SPEC = ('group', '%')
|
||||
|
||||
|
||||
|
||||
def deprecated(attribute):
|
||||
raise errors.ValidationError(
|
||||
@ -592,17 +598,40 @@ class sudorule_add_user(LDAPAddMember):
|
||||
raise errors.MutuallyExclusiveError(
|
||||
reason=_("users cannot be added when user category='all'"))
|
||||
|
||||
return add_external_pre_callback('user', ldap, dn, keys, options)
|
||||
for o_desc in (USER_OBJ_SPEC, GROUP_OBJ_SPEC):
|
||||
dn = pre_callback_process_external_objects(
|
||||
'memberuser', o_desc,
|
||||
ldap, dn, found, not_found, *keys, **options)
|
||||
return dn
|
||||
|
||||
def post_callback(self, ldap, completed, failed, dn, entry_attrs,
|
||||
*keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
return add_external_post_callback(ldap, dn, entry_attrs,
|
||||
|
||||
completed_ex = {}
|
||||
completed_ex['user'] = 0
|
||||
completed_ex['group'] = 0
|
||||
|
||||
# Since external_post_callback returns the total number of completed
|
||||
# entries yet (that is, any external users it added plus the value of
|
||||
# passed variable 'completed', we need to pass 0 as completed,
|
||||
# so that the entries added by the framework are not counted twice
|
||||
# (once in each call of add_external_post_callback)
|
||||
for o_type in ('user', 'group'):
|
||||
if o_type not in options:
|
||||
continue
|
||||
|
||||
(completed_ex[o_type], dn) = \
|
||||
add_external_post_callback(ldap, dn,
|
||||
entry_attrs=entry_attrs,
|
||||
failed=failed,
|
||||
completed=completed,
|
||||
completed=0,
|
||||
memberattr='memberuser',
|
||||
membertype='user',
|
||||
externalattr='externaluser')
|
||||
membertype=o_type,
|
||||
externalattr='externaluser',
|
||||
)
|
||||
|
||||
return (completed + sum(completed_ex.values()), dn)
|
||||
|
||||
|
||||
@register()
|
||||
@ -612,16 +641,42 @@ class sudorule_remove_user(LDAPRemoveMember):
|
||||
member_attributes = ['memberuser']
|
||||
member_count_out = ('%i object removed.', '%i objects removed.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
for o_desc in (USER_OBJ_SPEC, GROUP_OBJ_SPEC):
|
||||
dn = pre_callback_process_external_objects(
|
||||
'memberuser', o_desc,
|
||||
ldap, dn, found, not_found, *keys, **options)
|
||||
return dn
|
||||
|
||||
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,
|
||||
|
||||
# Since external_post_callback returns the total number of completed
|
||||
# entries yet (that is, any external users it removed plus the value of
|
||||
# passed variable 'completed', we need to pass 0 as completed,
|
||||
# so that the entries removed by the framework are not counted twice
|
||||
# (once in each call of remove_external_post_callback)
|
||||
(completed_ex_users, dn) = remove_external_post_callback(
|
||||
ldap, dn, entry_attrs,
|
||||
failed=failed,
|
||||
completed=completed,
|
||||
completed=0,
|
||||
memberattr='memberuser',
|
||||
membertype='user',
|
||||
externalattr='externaluser')
|
||||
|
||||
(completed_ex_groups, dn) = remove_external_post_callback(
|
||||
ldap, dn, entry_attrs,
|
||||
failed=failed,
|
||||
completed=0,
|
||||
memberattr='memberuser',
|
||||
membertype='group',
|
||||
externalattr='externaluser')
|
||||
|
||||
return (completed + completed_ex_users + completed_ex_groups, dn)
|
||||
|
||||
|
||||
@register()
|
||||
class sudorule_add_host(LDAPAddMember):
|
||||
|
Loading…
Reference in New Issue
Block a user