summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Babej <tbabej@redhat.com>2013-02-04 08:33:53 -0500
committerMartin Kosek <mkosek@redhat.com>2013-02-18 16:37:07 +0100
commit559a87017a2776f4a615b1bdab43728c6851de99 (patch)
treee9675501a8722b009d4b129dd4d3ddcc74ad2dbb
parent3f8778890e1a62d251f7069ead981d088c014b16 (diff)
downloadfreeipa.git-559a87017a2776f4a615b1bdab43728c6851de99.tar.gz
freeipa.git-559a87017a2776f4a615b1bdab43728c6851de99.tar.xz
freeipa.git-559a87017a2776f4a615b1bdab43728c6851de99.zip
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
-rw-r--r--API.txt6
-rw-r--r--ipalib/plugins/idrange.py94
-rw-r--r--ipaserver/dcerpc.py10
3 files changed, 95 insertions, 15 deletions
diff --git a/API.txt b/API.txt
index d1913022..5219c51b 100644
--- a/API.txt
+++ b/API.txt
@@ -1885,13 +1885,14 @@ command: i18n_messages
args: 0,0,1
output: Output('messages', <type 'dict'>, None)
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)
option: Str('addattr*', cli_name='addattr', 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('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: 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('iparangetype', attribute=True, cli_name='iparangetype', 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('truncated', <type 'bool'>, None)
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)
option: Str('addattr*', cli_name='addattr', 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('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: 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('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)
diff --git a/ipalib/plugins/idrange.py b/ipalib/plugins/idrange.py
index 84e1057a..44547339 100644
--- a/ipalib/plugins/idrange.py
+++ b/ipalib/plugins/idrange.py
@@ -57,7 +57,7 @@ Additionally an ID range of the local domain may set
and an ID range of a trusted domain must set
- 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',
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?',
label=_('Range type'),
flags=['no_option'],
@@ -265,17 +270,42 @@ class idrange(LDAPObject):
error=_('range modification leaving objects with ID out '
'of the defined range is not allowed'))
- def validate_trusted_domain_sid(self, sid):
+ def get_domain_validator(self):
if not _dcerpc_bindings_installed:
- raise errors.NotFound(reason=_('Cannot perform SID validation without Samba 4 support installed. '
- 'Make sure you have installed server-trust-ad sub-package of IPA on the server'))
+ raise errors.NotFound(reason=_('Cannot perform SID validation '
+ '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)
+
if not domain_validator.is_configured():
- raise errors.NotFound(reason=_('Cross-realm trusts are not configured. '
- 'Make sure you have run ipa-adtrust-install on the IPA server first'))
+ raise errors.NotFound(reason=_('Cross-realm trusts are not '
+ '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):
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
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)
+ # 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('ipasecondarybaserid'):
raise errors.ValidationError(name='ID Range setup',
- error=_('Options dom_sid and secondary_rid_base cannot '
- 'be used together'))
+ error=_('Options dom-sid/dom-name and secondary-rid-base '
+ 'cannot be used together'))
if not is_set('ipabaserid'):
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'))
# 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
entry_attrs['objectclass'].append('ipatrustedaddomainrange')
else:
if is_set('ipasecondarybaserid') != is_set('ipabaserid'):
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'))
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)
+ # 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:
(old_dn, old_attrs) = ldap.get_entry(dn,
['ipabaseid',
@@ -447,7 +515,7 @@ class idrange_mod(LDAPUpdate):
if is_set('ipanttrusteddomainsid'):
# 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
if all((base in entry_attrs) or (base in old_attrs)
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index 6243ebbb..b471bcce 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -204,6 +204,16 @@ class DomainValidator(object):
else:
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="",
attrs=None, scope=_ldap.SCOPE_SUBTREE, basedn=None):
"""