mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
sudorule runAs: allow to add users and groups from trusted domains directly
Allow specifying AD users and groups from trusted Active Directory forests in `ipa sudorule-add/remove-runasuser/runasgroup` family of commands. IPA provides 'ipasudorunasextuser' and 'ipasudorunasextusergroup' LDAP attributes to record 'external' objects referenced in SUDO rules for specifying the target user and group to run the commands allowed in the SUDO rule. Use member type validators to 'ipa sudorule-add/remove-runasuser/runasgroup' family of 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 IPA SUDOERs schema attributes is supported in SSSD 2.4 or later. RN: IPA now supports users and groups from trusted Active Directory RN: domains in SUDO rules to specify runAsUser/runAsGroup properties RN: without an intermediate non-POSIX 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
a37db297f0
commit
349322e3fb
@ -789,7 +789,7 @@ class sudorule_add_runasuser(LDAPAddMember):
|
||||
member_attributes = ['ipasudorunas']
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
def check_validity(runas):
|
||||
@ -826,37 +826,39 @@ class sudorule_add_runasuser(LDAPAddMember):
|
||||
"'%(name)s' as a group name")) %
|
||||
dict(name=name))
|
||||
|
||||
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(
|
||||
'ipasudorunas', 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)
|
||||
|
||||
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, ext_attr) in (('user', 'ipasudorunasextuser'),
|
||||
('group', 'ipasudorunasextusergroup')):
|
||||
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=0,
|
||||
memberattr='ipasudorunas',
|
||||
membertype=o_type,
|
||||
externalattr=ext_attr,
|
||||
)
|
||||
|
||||
(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='group',
|
||||
externalattr='ipasudorunasextusergroup',
|
||||
)
|
||||
|
||||
return (completed + completed_ex_users + completed_ex_groups, dn)
|
||||
return (completed + sum(completed_ex.values()), dn)
|
||||
|
||||
|
||||
@register()
|
||||
@ -866,35 +868,42 @@ class sudorule_remove_runasuser(LDAPRemoveMember):
|
||||
member_attributes = ['ipasudorunas']
|
||||
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(
|
||||
'ipasudorunas', 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)
|
||||
|
||||
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 remove_external_post_callback)
|
||||
# (once in each call of add_external_post_callback)
|
||||
for (o_type, ext_attr) in (('user', 'ipasudorunasextuser'),
|
||||
('group', 'ipasudorunasextusergroup')):
|
||||
if o_type not in options:
|
||||
continue
|
||||
(completed_ex[o_type], dn) = \
|
||||
remove_external_post_callback(ldap, dn,
|
||||
entry_attrs=entry_attrs,
|
||||
failed=failed,
|
||||
completed=0,
|
||||
memberattr='ipasudorunas',
|
||||
membertype=o_type,
|
||||
externalattr=ext_attr,
|
||||
)
|
||||
|
||||
(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)
|
||||
return (completed + sum(completed_ex.values()), dn)
|
||||
|
||||
|
||||
@register()
|
||||
@ -904,7 +913,7 @@ class sudorule_add_runasgroup(LDAPAddMember):
|
||||
member_attributes = ['ipasudorunasgroup']
|
||||
member_count_out = ('%i object added.', '%i objects added.')
|
||||
|
||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
def check_validity(runas):
|
||||
@ -931,18 +940,21 @@ class sudorule_add_runasgroup(LDAPAddMember):
|
||||
"'%(name)s' as a group name")) %
|
||||
dict(name=name))
|
||||
|
||||
return add_external_pre_callback('group', ldap, dn, keys, options)
|
||||
return pre_callback_process_external_objects(
|
||||
'ipasudorunasgroup', GROUP_OBJ_SPEC,
|
||||
ldap, dn, found, not_found, *keys, **options)
|
||||
|
||||
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,
|
||||
failed=failed,
|
||||
completed=completed,
|
||||
memberattr='ipasudorunasgroup',
|
||||
membertype='group',
|
||||
externalattr='ipasudorunasextgroup',
|
||||
)
|
||||
return add_external_post_callback(
|
||||
ldap, dn, entry_attrs,
|
||||
failed=failed,
|
||||
completed=completed,
|
||||
memberattr='ipasudorunasgroup',
|
||||
membertype='group',
|
||||
externalattr='ipasudorunasextgroup',
|
||||
)
|
||||
|
||||
|
||||
@register()
|
||||
@ -952,16 +964,24 @@ class sudorule_remove_runasgroup(LDAPRemoveMember):
|
||||
member_attributes = ['ipasudorunasgroup']
|
||||
member_count_out = ('%i object removed.', '%i objects removed.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
return pre_callback_process_external_objects(
|
||||
'ipasudorunasgroup', GROUP_OBJ_SPEC,
|
||||
ldap, dn, found, not_found, *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='ipasudorunasgroup',
|
||||
membertype='group',
|
||||
externalattr='ipasudorunasextgroup',
|
||||
)
|
||||
return remove_external_post_callback(
|
||||
ldap, dn, entry_attrs,
|
||||
failed=failed,
|
||||
completed=completed,
|
||||
memberattr='ipasudorunasgroup',
|
||||
membertype='group',
|
||||
externalattr='ipasudorunasextgroup',
|
||||
)
|
||||
|
||||
|
||||
@register()
|
||||
|
Loading…
Reference in New Issue
Block a user