mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Support adding user ID overrides as group and role members
Second part of adding support to manage IPA as a user from a trusted Active Directory forest. Treat user ID overrides as members of groups and roles. For example, adding an Active Directory user ID override as a member of 'admins' group would make it equivalent to built-in FreeIPA 'admin' user. We already support self-service operations by Active Directory users if their user ID override does exist. When Active Directory user authenticates with GSSAPI against the FreeIPA LDAP server, its Kerberos principal is automatically mapped to the user's ID override in the Default Trust View. LDAP server's access control plugin uses membership information of the corresponding LDAP entry to decide how access can be allowed. With the change, users from trusted Active Directory forests can manage FreeIPA resources if the groups are part of appropriate roles or their ID overrides are members of the roles themselves. Fixes: https://pagure.io/freeipa/issue/7255 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
parent
973e0c04e4
commit
bee4204039
2
ACI.txt
2
ACI.txt
@ -179,7 +179,7 @@ aci: (targetfilter = "(objectclass=ipahostgroup)")(version 3.0;acl "permission:S
|
||||
dn: cn=views,cn=accounts,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || description || entryusn || gidnumber || ipaanchoruuid || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaGroupOverride)")(version 3.0;acl "permission:System: Read Group ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=views,cn=accounts,dc=ipa,dc=example
|
||||
aci: (targetattr = "createtimestamp || description || entryusn || gecos || gidnumber || homedirectory || ipaanchoruuid || ipaoriginaluid || ipasshpubkey || loginshell || modifytimestamp || objectclass || uid || uidnumber || usercertificate")(targetfilter = "(objectclass=ipaUserOverride)")(version 3.0;acl "permission:System: Read User ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
aci: (targetattr = "createtimestamp || description || entryusn || gecos || gidnumber || homedirectory || ipaanchoruuid || ipaoriginaluid || ipasshpubkey || loginshell || memberof || modifytimestamp || objectclass || uid || uidnumber || usercertificate")(targetfilter = "(objectclass=ipaUserOverride)")(version 3.0;acl "permission:System: Read User ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=ranges,cn=etc,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || entryusn || ipabaseid || ipabaserid || ipaidrangesize || ipanttrusteddomainsid || iparangetype || ipasecondarybaserid || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaidrange)")(version 3.0;acl "permission:System: Read ID Ranges";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=views,cn=accounts,dc=ipa,dc=example
|
||||
|
34
API.txt
34
API.txt
@ -1959,10 +1959,11 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: group_add_member/1
|
||||
args: 1,8,3
|
||||
args: 1,9,3
|
||||
arg: Str('cn', cli_name='group_name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('group*', alwaysask=True, cli_name='groups')
|
||||
option: Str('idoverrideuser*', alwaysask=True, cli_name='idoverrideusers')
|
||||
option: Str('ipaexternalmember*', cli_name='external')
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
@ -2000,7 +2001,7 @@ output: Output('result', type=[<type 'bool'>])
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: group_find/1
|
||||
args: 1,34,4
|
||||
args: 1,36,4
|
||||
arg: Str('criteria?')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('cn?', autofill=False, cli_name='group_name')
|
||||
@ -2008,6 +2009,7 @@ option: Str('description?', autofill=False, cli_name='desc')
|
||||
option: Flag('external', autofill=True, cli_name='external', default=False)
|
||||
option: Int('gidnumber?', autofill=False, cli_name='gid')
|
||||
option: Str('group*', cli_name='groups')
|
||||
option: Str('idoverrideuser*', cli_name='idoverrideusers')
|
||||
option: Str('in_group*', cli_name='in_groups')
|
||||
option: Str('in_hbacrule*', cli_name='in_hbacrules')
|
||||
option: Str('in_netgroup*', cli_name='in_netgroups')
|
||||
@ -2016,6 +2018,7 @@ option: Str('in_sudorule*', cli_name='in_sudorules')
|
||||
option: Str('membermanager_group*', cli_name='membermanager_groups')
|
||||
option: Str('membermanager_user*', cli_name='membermanager_users')
|
||||
option: Str('no_group*', cli_name='no_groups')
|
||||
option: Str('no_idoverrideuser*', cli_name='no_idoverrideusers')
|
||||
option: Flag('no_members', autofill=True, default=True)
|
||||
option: Principal('no_service*', cli_name='no_services')
|
||||
option: Str('no_user*', cli_name='no_users')
|
||||
@ -2060,10 +2063,11 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: group_remove_member/1
|
||||
args: 1,8,3
|
||||
args: 1,9,3
|
||||
arg: Str('cn', cli_name='group_name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('group*', alwaysask=True, cli_name='groups')
|
||||
option: Str('idoverrideuser*', alwaysask=True, cli_name='idoverrideusers')
|
||||
option: Str('ipaexternalmember*', cli_name='external')
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
@ -2920,7 +2924,7 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: idoverrideuser_add/1
|
||||
args: 2,16,3
|
||||
args: 2,17,3
|
||||
arg: Str('idviewcn', cli_name='idview')
|
||||
arg: Str('ipaanchoruuid', cli_name='anchor')
|
||||
option: Str('addattr*', cli_name='addattr')
|
||||
@ -2933,6 +2937,7 @@ option: Str('homedirectory?', cli_name='homedir')
|
||||
option: Str('ipaoriginaluid?')
|
||||
option: Str('ipasshpubkey*', cli_name='sshpubkey')
|
||||
option: Str('loginshell?', cli_name='shell')
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('setattr*', cli_name='setattr')
|
||||
option: Str('uid?', cli_name='login')
|
||||
@ -2943,11 +2948,12 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: idoverrideuser_add_cert/1
|
||||
args: 2,5,3
|
||||
args: 2,6,3
|
||||
arg: Str('idviewcn', cli_name='idview')
|
||||
arg: Str('ipaanchoruuid', cli_name='anchor')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('fallback_to_ldap?', autofill=True, default=False)
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Certificate('usercertificate+', alwaysask=True, cli_name='certificate')
|
||||
option: Str('version?')
|
||||
@ -2965,7 +2971,7 @@ output: Output('result', type=[<type 'dict'>])
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: ListOfPrimaryKeys('value')
|
||||
command: idoverrideuser_find/1
|
||||
args: 2,16,4
|
||||
args: 2,17,4
|
||||
arg: Str('idviewcn', cli_name='idview')
|
||||
arg: Str('criteria?')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
@ -2977,6 +2983,7 @@ option: Str('homedirectory?', autofill=False, cli_name='homedir')
|
||||
option: Str('ipaanchoruuid?', autofill=False, cli_name='anchor')
|
||||
option: Str('ipaoriginaluid?', autofill=False)
|
||||
option: Str('loginshell?', autofill=False, cli_name='shell')
|
||||
option: Flag('no_members', autofill=True, default=True)
|
||||
option: Flag('pkey_only?', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Int('sizelimit?', autofill=False)
|
||||
@ -2989,7 +2996,7 @@ output: ListOfEntries('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: Output('truncated', type=[<type 'bool'>])
|
||||
command: idoverrideuser_mod/1
|
||||
args: 2,19,3
|
||||
args: 2,20,3
|
||||
arg: Str('idviewcn', cli_name='idview')
|
||||
arg: Str('ipaanchoruuid', cli_name='anchor')
|
||||
option: Str('addattr*', cli_name='addattr')
|
||||
@ -3003,6 +3010,7 @@ option: Str('homedirectory?', autofill=False, cli_name='homedir')
|
||||
option: Str('ipaoriginaluid?', autofill=False)
|
||||
option: Str('ipasshpubkey*', autofill=False, cli_name='sshpubkey')
|
||||
option: Str('loginshell?', autofill=False, cli_name='shell')
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('rename?', cli_name='rename')
|
||||
option: Flag('rights', autofill=True, default=False)
|
||||
@ -3015,11 +3023,12 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: idoverrideuser_remove_cert/1
|
||||
args: 2,5,3
|
||||
args: 2,6,3
|
||||
arg: Str('idviewcn', cli_name='idview')
|
||||
arg: Str('ipaanchoruuid', cli_name='anchor')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('fallback_to_ldap?', autofill=True, default=False)
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Certificate('usercertificate+', alwaysask=True, cli_name='certificate')
|
||||
option: Str('version?')
|
||||
@ -3027,11 +3036,12 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: idoverrideuser_show/1
|
||||
args: 2,5,3
|
||||
args: 2,6,3
|
||||
arg: Str('idviewcn', cli_name='idview')
|
||||
arg: Str('ipaanchoruuid', cli_name='anchor')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Flag('fallback_to_ldap?', autofill=True, default=False)
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Flag('rights', autofill=True, default=False)
|
||||
option: Str('version?')
|
||||
@ -4147,12 +4157,13 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: role_add_member/1
|
||||
args: 1,9,3
|
||||
args: 1,10,3
|
||||
arg: Str('cn', cli_name='name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('group*', alwaysask=True, cli_name='groups')
|
||||
option: Str('host*', alwaysask=True, cli_name='hosts')
|
||||
option: Str('hostgroup*', alwaysask=True, cli_name='hostgroups')
|
||||
option: Str('idoverrideuser*', alwaysask=True, cli_name='idoverrideusers')
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('service*', alwaysask=True, cli_name='services')
|
||||
@ -4213,12 +4224,13 @@ output: Entry('result')
|
||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||
output: PrimaryKey('value')
|
||||
command: role_remove_member/1
|
||||
args: 1,9,3
|
||||
args: 1,10,3
|
||||
arg: Str('cn', cli_name='name')
|
||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||
option: Str('group*', alwaysask=True, cli_name='groups')
|
||||
option: Str('host*', alwaysask=True, cli_name='hosts')
|
||||
option: Str('hostgroup*', alwaysask=True, cli_name='hostgroups')
|
||||
option: Str('idoverrideuser*', alwaysask=True, cli_name='idoverrideusers')
|
||||
option: Flag('no_members', autofill=True, default=False)
|
||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||
option: Str('service*', alwaysask=True, cli_name='services')
|
||||
|
@ -86,8 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
|
||||
# #
|
||||
########################################################
|
||||
define(IPA_API_VERSION_MAJOR, 2)
|
||||
define(IPA_API_VERSION_MINOR, 238)
|
||||
# Last change: permission ipapermbindruletype=self
|
||||
define(IPA_API_VERSION_MINOR, 239)
|
||||
# Last change: allow ID overrides for users to be members of groups and roles
|
||||
|
||||
|
||||
########################################################
|
||||
|
@ -120,6 +120,10 @@ global_output_params = (
|
||||
Str('memberof_hbacrule?',
|
||||
label='Member of HBAC rule',
|
||||
),
|
||||
Str('member_idoverrideuser?',
|
||||
label=_('Member ID user overrides'),),
|
||||
Str('memberindirect_idoverrideuser?',
|
||||
label=_('Indirect Member ID user overrides'),),
|
||||
Str('memberindirect_user?',
|
||||
label=_('Indirect Member users'),
|
||||
),
|
||||
|
@ -40,7 +40,7 @@ from .baseldap import (
|
||||
LDAPRemoveMember,
|
||||
LDAPQuery,
|
||||
)
|
||||
from .idviews import remove_ipaobject_overrides
|
||||
from .idviews import remove_ipaobject_overrides, handle_idoverride_memberof
|
||||
from . import baseldap
|
||||
from ipalib import _, ngettext
|
||||
from ipalib import errors
|
||||
@ -204,10 +204,10 @@ class group(LDAPObject):
|
||||
]
|
||||
uuid_attribute = 'ipauniqueid'
|
||||
attribute_members = {
|
||||
'member': ['user', 'group', 'service'],
|
||||
'member': ['user', 'group', 'service', 'idoverrideuser'],
|
||||
'membermanager': ['user', 'group'],
|
||||
'memberof': ['group', 'netgroup', 'role', 'hbacrule', 'sudorule'],
|
||||
'memberindirect': ['user', 'group', 'service'],
|
||||
'memberindirect': ['user', 'group', 'service', 'idoverrideuser'],
|
||||
'memberofindirect': ['group', 'netgroup', 'role', 'hbacrule',
|
||||
'sudorule'],
|
||||
}
|
||||
@ -593,6 +593,12 @@ class group_add_member(LDAPAddMember):
|
||||
|
||||
takes_options = (ipaexternalmember_param,)
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
handle_idoverride_memberof(self, 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)
|
||||
result = (completed, dn)
|
||||
|
@ -32,6 +32,8 @@ from .baseldap import (
|
||||
LDAPRemoveReverseMember)
|
||||
from ipalib import api, Str, _, ngettext
|
||||
from ipalib import output
|
||||
from ipapython.dn import DN
|
||||
from .idviews import handle_idoverride_memberof
|
||||
|
||||
__doc__ = _("""
|
||||
Roles
|
||||
@ -86,7 +88,8 @@ class role(LDAPObject):
|
||||
# 'memberindirect', 'memberofindirect',
|
||||
|
||||
attribute_members = {
|
||||
'member': ['user', 'group', 'host', 'hostgroup', 'service'],
|
||||
'member': ['user', 'group', 'host', 'hostgroup', 'service',
|
||||
'idoverrideuser'],
|
||||
'memberof': ['privilege'],
|
||||
}
|
||||
reverse_members = {
|
||||
@ -198,6 +201,12 @@ class role_show(LDAPRetrieve):
|
||||
class role_add_member(LDAPAddMember):
|
||||
__doc__ = _('Add members to a role.')
|
||||
|
||||
def pre_callback(self, ldap, dn, found, not_found, *keys, **options):
|
||||
assert isinstance(dn, DN)
|
||||
handle_idoverride_memberof(self, ldap, dn, found, not_found,
|
||||
*keys, **options)
|
||||
return dn
|
||||
|
||||
|
||||
|
||||
@register()
|
||||
|
Loading…
Reference in New Issue
Block a user