mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add option to specify SID using domain name to idrange-add/mod
When adding/modifying an ID range for a trusted domain, the newly added option --dom-name can be used. This looks up SID of the trusted domain in LDAP and therefore the user is not required to write it down in CLI. If the lookup fails, error message asking the user to specify the SID manually is shown. https://fedorahosted.org/freeipa/ticket/3133
This commit is contained in:
committed by
Martin Kosek
parent
3f8778890e
commit
559a87017a
6
API.txt
6
API.txt
@@ -1885,13 +1885,14 @@ command: i18n_messages
|
|||||||
args: 0,0,1
|
args: 0,0,1
|
||||||
output: Output('messages', <type 'dict'>, None)
|
output: Output('messages', <type 'dict'>, None)
|
||||||
command: idrange_add
|
command: idrange_add
|
||||||
args: 1,11,3
|
args: 1,12,3
|
||||||
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
|
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, required=True)
|
||||||
option: Str('addattr*', cli_name='addattr', exclude='webui')
|
option: Str('addattr*', cli_name='addattr', exclude='webui')
|
||||||
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
|
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
|
||||||
option: Int('ipabaseid', attribute=True, cli_name='base_id', multivalue=False, required=True)
|
option: Int('ipabaseid', attribute=True, cli_name='base_id', multivalue=False, required=True)
|
||||||
option: Int('ipabaserid', attribute=True, cli_name='rid_base', multivalue=False, required=False)
|
option: Int('ipabaserid', attribute=True, cli_name='rid_base', multivalue=False, required=False)
|
||||||
option: Int('ipaidrangesize', attribute=True, cli_name='range_size', multivalue=False, required=True)
|
option: Int('ipaidrangesize', attribute=True, cli_name='range_size', multivalue=False, required=True)
|
||||||
|
option: Str('ipanttrusteddomainname', attribute=False, cli_name='dom_name', multivalue=False, required=False)
|
||||||
option: Str('ipanttrusteddomainsid', attribute=True, cli_name='dom_sid', multivalue=False, required=False)
|
option: Str('ipanttrusteddomainsid', attribute=True, cli_name='dom_sid', multivalue=False, required=False)
|
||||||
option: Str('iparangetype', attribute=True, cli_name='iparangetype', multivalue=False, required=False)
|
option: Str('iparangetype', attribute=True, cli_name='iparangetype', multivalue=False, required=False)
|
||||||
option: Int('ipasecondarybaserid', attribute=True, cli_name='secondary_rid_base', multivalue=False, required=False)
|
option: Int('ipasecondarybaserid', attribute=True, cli_name='secondary_rid_base', multivalue=False, required=False)
|
||||||
@@ -1929,7 +1930,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
|
|||||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
|
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
|
||||||
output: Output('truncated', <type 'bool'>, None)
|
output: Output('truncated', <type 'bool'>, None)
|
||||||
command: idrange_mod
|
command: idrange_mod
|
||||||
args: 1,13,3
|
args: 1,14,3
|
||||||
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
|
arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
|
||||||
option: Str('addattr*', cli_name='addattr', exclude='webui')
|
option: Str('addattr*', cli_name='addattr', exclude='webui')
|
||||||
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
|
option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
|
||||||
@@ -1937,6 +1938,7 @@ option: Str('delattr*', cli_name='delattr', exclude='webui')
|
|||||||
option: Int('ipabaseid', attribute=True, autofill=False, cli_name='base_id', multivalue=False, required=False)
|
option: Int('ipabaseid', attribute=True, autofill=False, cli_name='base_id', multivalue=False, required=False)
|
||||||
option: Int('ipabaserid', attribute=True, autofill=False, cli_name='rid_base', multivalue=False, required=False)
|
option: Int('ipabaserid', attribute=True, autofill=False, cli_name='rid_base', multivalue=False, required=False)
|
||||||
option: Int('ipaidrangesize', attribute=True, autofill=False, cli_name='range_size', multivalue=False, required=False)
|
option: Int('ipaidrangesize', attribute=True, autofill=False, cli_name='range_size', multivalue=False, required=False)
|
||||||
|
option: Str('ipanttrusteddomainname', attribute=False, autofill=False, cli_name='dom_name', multivalue=False, required=False)
|
||||||
option: Str('ipanttrusteddomainsid', attribute=True, autofill=False, cli_name='dom_sid', multivalue=False, required=False)
|
option: Str('ipanttrusteddomainsid', attribute=True, autofill=False, cli_name='dom_sid', multivalue=False, required=False)
|
||||||
option: Str('iparangetype', attribute=True, autofill=False, cli_name='iparangetype', multivalue=False, required=False)
|
option: Str('iparangetype', attribute=True, autofill=False, cli_name='iparangetype', multivalue=False, required=False)
|
||||||
option: Int('ipasecondarybaserid', attribute=True, autofill=False, cli_name='secondary_rid_base', multivalue=False, required=False)
|
option: Int('ipasecondarybaserid', attribute=True, autofill=False, cli_name='secondary_rid_base', multivalue=False, required=False)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ Additionally an ID range of the local domain may set
|
|||||||
|
|
||||||
and an ID range of a trusted domain must set
|
and an ID range of a trusted domain must set
|
||||||
- rid-base: the first RID of the corresponding RID range
|
- rid-base: the first RID of the corresponding RID range
|
||||||
- dom_sid: domain SID of the trusted domain
|
- sid: domain SID of the trusted domain
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -197,6 +197,11 @@ class idrange(LDAPObject):
|
|||||||
cli_name='dom_sid',
|
cli_name='dom_sid',
|
||||||
label=_('Domain SID of the trusted domain'),
|
label=_('Domain SID of the trusted domain'),
|
||||||
),
|
),
|
||||||
|
Str('ipanttrusteddomainname?',
|
||||||
|
cli_name='dom_name',
|
||||||
|
flags=('no_search', 'virtual_attribute'),
|
||||||
|
label=_('Name of the trusted domain'),
|
||||||
|
),
|
||||||
Str('iparangetype?',
|
Str('iparangetype?',
|
||||||
label=_('Range type'),
|
label=_('Range type'),
|
||||||
flags=['no_option'],
|
flags=['no_option'],
|
||||||
@@ -265,17 +270,42 @@ class idrange(LDAPObject):
|
|||||||
error=_('range modification leaving objects with ID out '
|
error=_('range modification leaving objects with ID out '
|
||||||
'of the defined range is not allowed'))
|
'of the defined range is not allowed'))
|
||||||
|
|
||||||
def validate_trusted_domain_sid(self, sid):
|
def get_domain_validator(self):
|
||||||
if not _dcerpc_bindings_installed:
|
if not _dcerpc_bindings_installed:
|
||||||
raise errors.NotFound(reason=_('Cannot perform SID validation without Samba 4 support installed. '
|
raise errors.NotFound(reason=_('Cannot perform SID validation '
|
||||||
'Make sure you have installed server-trust-ad sub-package of IPA on the server'))
|
'without Samba 4 support installed. Make sure you have '
|
||||||
|
'installed server-trust-ad sub-package of IPA on the server'))
|
||||||
|
|
||||||
domain_validator = ipaserver.dcerpc.DomainValidator(self.api)
|
domain_validator = ipaserver.dcerpc.DomainValidator(self.api)
|
||||||
|
|
||||||
if not domain_validator.is_configured():
|
if not domain_validator.is_configured():
|
||||||
raise errors.NotFound(reason=_('Cross-realm trusts are not configured. '
|
raise errors.NotFound(reason=_('Cross-realm trusts are not '
|
||||||
'Make sure you have run ipa-adtrust-install on the IPA server first'))
|
'configured. Make sure you have run ipa-adtrust-install '
|
||||||
|
'on the IPA server first'))
|
||||||
|
|
||||||
|
return domain_validator
|
||||||
|
|
||||||
|
def validate_trusted_domain_sid(self, sid):
|
||||||
|
|
||||||
|
domain_validator = self.get_domain_validator()
|
||||||
|
|
||||||
if not domain_validator.is_trusted_sid_valid(sid):
|
if not domain_validator.is_trusted_sid_valid(sid):
|
||||||
raise errors.ValidationError(name='domain SID',
|
raise errors.ValidationError(name='domain SID',
|
||||||
error=_('SID is not recognized as a valid SID for a trusted domain'))
|
error=_('SID is not recognized as a valid SID for a '
|
||||||
|
'trusted domain'))
|
||||||
|
|
||||||
|
def get_trusted_domain_sid_from_name(self, name):
|
||||||
|
""" Returns unicode string representation for given trusted domain name
|
||||||
|
or None if SID forthe given trusted domain name could not be found."""
|
||||||
|
|
||||||
|
domain_validator = self.get_domain_validator()
|
||||||
|
|
||||||
|
sid = domain_validator.get_sid_from_domain_name(name)
|
||||||
|
|
||||||
|
if sid is not None:
|
||||||
|
sid = unicode(sid)
|
||||||
|
|
||||||
|
return sid
|
||||||
|
|
||||||
# checks that primary and secondary rid ranges do not overlap
|
# checks that primary and secondary rid ranges do not overlap
|
||||||
def are_rid_ranges_overlapping(self, rid_base, secondary_rid_base, size):
|
def are_rid_ranges_overlapping(self, rid_base, secondary_rid_base, size):
|
||||||
@@ -336,26 +366,45 @@ class idrange_add(LDAPCreate):
|
|||||||
|
|
||||||
is_set = lambda x: (x in entry_attrs) and (x is not None)
|
is_set = lambda x: (x in entry_attrs) and (x is not None)
|
||||||
|
|
||||||
|
# This needs to stay in options since there is no
|
||||||
|
# ipanttrusteddomainname attribute in LDAP
|
||||||
|
if 'ipanttrusteddomainname' in options:
|
||||||
|
if is_set('ipanttrusteddomainsid'):
|
||||||
|
raise errors.ValidationError(name='ID Range setup',
|
||||||
|
error=_('Options dom-sid and dom-name '
|
||||||
|
'cannot be used together'))
|
||||||
|
|
||||||
|
sid = self.obj.get_trusted_domain_sid_from_name(
|
||||||
|
options['ipanttrusteddomainname'])
|
||||||
|
|
||||||
|
if sid is not None:
|
||||||
|
entry_attrs['ipanttrusteddomainsid'] = sid
|
||||||
|
else:
|
||||||
|
raise errors.ValidationError(name='ID Range setup',
|
||||||
|
error=_('SID for the specified trusted domain name could '
|
||||||
|
'not be found. Please specify the SID directly '
|
||||||
|
'using dom-sid option.'))
|
||||||
|
|
||||||
if is_set('ipanttrusteddomainsid'):
|
if is_set('ipanttrusteddomainsid'):
|
||||||
if is_set('ipasecondarybaserid'):
|
if is_set('ipasecondarybaserid'):
|
||||||
raise errors.ValidationError(name='ID Range setup',
|
raise errors.ValidationError(name='ID Range setup',
|
||||||
error=_('Options dom_sid and secondary_rid_base cannot '
|
error=_('Options dom-sid/dom-name and secondary-rid-base '
|
||||||
'be used together'))
|
'cannot be used together'))
|
||||||
|
|
||||||
if not is_set('ipabaserid'):
|
if not is_set('ipabaserid'):
|
||||||
raise errors.ValidationError(name='ID Range setup',
|
raise errors.ValidationError(name='ID Range setup',
|
||||||
error=_('Options dom_sid and rid_base must '
|
error=_('Options dom-sid/dom-name and rid-base must '
|
||||||
'be used together'))
|
'be used together'))
|
||||||
|
|
||||||
# Validate SID as the one of trusted domains
|
# Validate SID as the one of trusted domains
|
||||||
self.obj.validate_trusted_domain_sid(options['ipanttrusteddomainsid'])
|
self.obj.validate_trusted_domain_sid(entry_attrs['ipanttrusteddomainsid'])
|
||||||
# Finally, add trusted AD domain range object class
|
# Finally, add trusted AD domain range object class
|
||||||
entry_attrs['objectclass'].append('ipatrustedaddomainrange')
|
entry_attrs['objectclass'].append('ipatrustedaddomainrange')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if is_set('ipasecondarybaserid') != is_set('ipabaserid'):
|
if is_set('ipasecondarybaserid') != is_set('ipabaserid'):
|
||||||
raise errors.ValidationError(name='ID Range setup',
|
raise errors.ValidationError(name='ID Range setup',
|
||||||
error=_('Options secondary_rid_base and rid_base must '
|
error=_('Options secondary-rid-base and rid-base must '
|
||||||
'be used together'))
|
'be used together'))
|
||||||
|
|
||||||
if is_set('ipabaserid') and is_set('ipasecondarybaserid'):
|
if is_set('ipabaserid') and is_set('ipasecondarybaserid'):
|
||||||
@@ -436,6 +485,25 @@ class idrange_mod(LDAPUpdate):
|
|||||||
|
|
||||||
is_set = lambda x: (x in entry_attrs) and (x is not None)
|
is_set = lambda x: (x in entry_attrs) and (x is not None)
|
||||||
|
|
||||||
|
# This needs to stay in options since there is no
|
||||||
|
# ipanttrusteddomainname attribute in LDAP
|
||||||
|
if 'ipanttrusteddomainname' in options:
|
||||||
|
if is_set('ipanttrusteddomainsid'):
|
||||||
|
raise errors.ValidationError(name='ID Range setup',
|
||||||
|
error=_('Options dom-sid and dom-name '
|
||||||
|
'cannot be used together'))
|
||||||
|
|
||||||
|
sid = self.obj.get_trusted_domain_sid_from_name(
|
||||||
|
options['ipanttrusteddomainname'])
|
||||||
|
|
||||||
|
if sid is not None:
|
||||||
|
entry_attrs['ipanttrusteddomainsid'] = sid
|
||||||
|
else:
|
||||||
|
raise errors.ValidationError(name='ID Range setup',
|
||||||
|
error=_('SID for the specified trusted domain name could '
|
||||||
|
'not be found. Please specify the SID directly '
|
||||||
|
'using dom-sid option.'))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(old_dn, old_attrs) = ldap.get_entry(dn,
|
(old_dn, old_attrs) = ldap.get_entry(dn,
|
||||||
['ipabaseid',
|
['ipabaseid',
|
||||||
@@ -447,7 +515,7 @@ class idrange_mod(LDAPUpdate):
|
|||||||
|
|
||||||
if is_set('ipanttrusteddomainsid'):
|
if is_set('ipanttrusteddomainsid'):
|
||||||
# Validate SID as the one of trusted domains
|
# Validate SID as the one of trusted domains
|
||||||
self.obj.validate_trusted_domain_sid(options['ipanttrusteddomainsid'])
|
self.obj.validate_trusted_domain_sid(entry_attrs['ipanttrusteddomainsid'])
|
||||||
|
|
||||||
# ensure that primary and secondary rid ranges do not overlap
|
# ensure that primary and secondary rid ranges do not overlap
|
||||||
if all((base in entry_attrs) or (base in old_attrs)
|
if all((base in entry_attrs) or (base in old_attrs)
|
||||||
|
|||||||
@@ -204,6 +204,16 @@ class DomainValidator(object):
|
|||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_sid_from_domain_name(self, name):
|
||||||
|
"""Returns binary representation of SID for the trusted domain name
|
||||||
|
or None if name is not in the list of trusted domains."""
|
||||||
|
|
||||||
|
domains = self.get_trusted_domains()
|
||||||
|
if name in domains:
|
||||||
|
return domains[name][1]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_trusted_domain_objects(self, domain=None, flatname=None, filter="",
|
def get_trusted_domain_objects(self, domain=None, flatname=None, filter="",
|
||||||
attrs=None, scope=_ldap.SCOPE_SUBTREE, basedn=None):
|
attrs=None, scope=_ldap.SCOPE_SUBTREE, basedn=None):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user