From 646253044028b86291430680981a40bef2bff1e6 Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Wed, 29 Apr 2015 08:16:13 +0200 Subject: idviews: Fallback to AD DC LDAP only if specifically allowed https://fedorahosted.org/freeipa/ticket/4524 Reviewed-By: Martin Babinsky --- API.txt | 30 ++++++++++++++++++++---------- ipalib/plugins/idviews.py | 27 ++++++++++++++++++++++++--- ipaserver/dcerpc.py | 7 ++++++- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/API.txt b/API.txt index bccebe55d..17a1afe01 100644 --- a/API.txt +++ b/API.txt @@ -2347,13 +2347,14 @@ args: 0,1,1 option: Str('version?', exclude='webui') output: Output('texts', , None) command: idoverridegroup_add -args: 2,8,3 +args: 2,9,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', 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: Str('cn', attribute=True, cli_name='group_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', required=False) option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Int('gidnumber', attribute=True, cli_name='gid', minvalue=1, multivalue=False, required=False) option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') option: Str('setattr*', cli_name='setattr', exclude='webui') @@ -2362,21 +2363,23 @@ output: Entry('result', , Gettext('A dictionary representing an LDA output: Output('summary', (, ), None) output: PrimaryKey('value', None, None) command: idoverridegroup_del -args: 2,2,3 +args: 2,3,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=True, primary_key=True, query=True, required=True) option: Flag('continue', autofill=True, cli_name='continue', default=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Str('version?', exclude='webui') output: Output('result', , None) output: Output('summary', (, ), None) output: ListOfPrimaryKeys('value', None, None) command: idoverridegroup_find -args: 2,10,4 +args: 2,11,4 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('criteria?', noextrawhitespace=False) option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') option: Str('cn', attribute=True, autofill=False, cli_name='group_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', query=True, required=False) option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Int('gidnumber', attribute=True, autofill=False, cli_name='gid', minvalue=1, multivalue=False, query=True, required=False) option: Str('ipaanchoruuid', attribute=True, autofill=False, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=False) option: Flag('pkey_only?', autofill=True, default=False) @@ -2389,7 +2392,7 @@ output: ListOfEntries('result', (, ), Gettext('A list output: Output('summary', (, ), None) output: Output('truncated', , None) command: idoverridegroup_mod -args: 2,11,3 +args: 2,12,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=True) option: Str('addattr*', cli_name='addattr', exclude='webui') @@ -2397,6 +2400,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui option: Str('cn', attribute=True, autofill=False, cli_name='group_name', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', required=False) option: Str('delattr*', cli_name='delattr', exclude='webui') option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Int('gidnumber', attribute=True, autofill=False, cli_name='gid', minvalue=1, multivalue=False, required=False) option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') option: Str('rename', cli_name='rename', multivalue=False, primary_key=True, required=False) @@ -2407,10 +2411,11 @@ output: Entry('result', , Gettext('A dictionary representing an LDA output: Output('summary', (, ), None) output: PrimaryKey('value', None, None) command: idoverridegroup_show -args: 2,4,3 +args: 2,5,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=True) option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') option: Flag('rights', autofill=True, default=False) option: Str('version?', exclude='webui') @@ -2418,12 +2423,13 @@ output: Entry('result', , Gettext('A dictionary representing an LDA output: Output('summary', (, ), None) output: PrimaryKey('value', None, None) command: idoverrideuser_add -args: 2,14,3 +args: 2,15,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', 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: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Str('gecos', attribute=True, cli_name='gecos', multivalue=False, required=False) option: Int('gidnumber', attribute=True, cli_name='gidnumber', minvalue=1, multivalue=False, required=False) option: Str('homedirectory', attribute=True, cli_name='homedir', multivalue=False, required=False) @@ -2439,20 +2445,22 @@ output: Entry('result', , Gettext('A dictionary representing an LDA output: Output('summary', (, ), None) output: PrimaryKey('value', None, None) command: idoverrideuser_del -args: 2,2,3 +args: 2,3,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=True, primary_key=True, query=True, required=True) option: Flag('continue', autofill=True, cli_name='continue', default=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Str('version?', exclude='webui') output: Output('result', , None) output: Output('summary', (, ), None) output: ListOfPrimaryKeys('value', None, None) command: idoverrideuser_find -args: 2,15,4 +args: 2,16,4 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('criteria?', noextrawhitespace=False) option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Str('gecos', attribute=True, autofill=False, cli_name='gecos', multivalue=False, query=True, required=False) option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, query=True, required=False) option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, query=True, required=False) @@ -2471,13 +2479,14 @@ output: ListOfEntries('result', (, ), Gettext('A list output: Output('summary', (, ), None) output: Output('truncated', , None) command: idoverrideuser_mod -args: 2,17,3 +args: 2,18,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', 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') option: Str('delattr*', cli_name='delattr', exclude='webui') option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False) +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Str('gecos', attribute=True, autofill=False, cli_name='gecos', multivalue=False, required=False) option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, required=False) option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, required=False) @@ -2495,10 +2504,11 @@ output: Entry('result', , Gettext('A dictionary representing an LDA output: Output('summary', (, ), None) output: PrimaryKey('value', None, None) command: idoverrideuser_show -args: 2,4,3 +args: 2,5,3 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True) arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=True) option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui') +option: Flag('fallback_to_ldap?', autofill=True, default=False) option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui') option: Flag('rights', autofill=True, default=False) option: Str('version?', exclude='webui') diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py index 3bd5ad67f..67f52f886 100644 --- a/ipalib/plugins/idviews.py +++ b/ipalib/plugins/idviews.py @@ -56,6 +56,14 @@ protected_default_trust_view_error = errors.ProtectedEntryError( reason=_('system ID View') ) +fallback_to_ldap_option = Flag( + 'fallback_to_ldap?', + default=False, + label=_('Fallback to AD DC LDAP'), + doc=_("Allow falling back to AD DC LDAP when resolving AD " + "trusted objects. For two-way trusts only."), +) + DEFAULT_TRUST_VIEW_NAME = "default trust view" ANCHOR_REGEX = re.compile( @@ -64,6 +72,7 @@ ANCHOR_REGEX = re.compile( r':SID:S-[0-9\-]+' ) + @register() class idview(LDAPObject): """ @@ -423,7 +432,7 @@ class idview_unapply(baseidview_apply): # ID overrides helper methods -def resolve_object_to_anchor(ldap, obj_type, obj): +def resolve_object_to_anchor(ldap, obj_type, obj, fallback_to_ldap): """ Resolves the user/group name to the anchor uuid: - first it tries to find the object as user or group in IPA (depending @@ -470,7 +479,8 @@ def resolve_object_to_anchor(ldap, obj_type, obj): if _dcerpc_bindings_installed: domain_validator = ipaserver.dcerpc.DomainValidator(api) if domain_validator.is_configured(): - sid = domain_validator.get_trusted_domain_object_sid(obj) + sid = domain_validator.get_trusted_domain_object_sid(obj, + fallback_to_ldap=fallback_to_ldap) # There is no domain prefix since SID contains information # about the domain @@ -602,7 +612,8 @@ class baseidoverride(LDAPObject): anchor = resolve_object_to_anchor( self.backend, self.override_object, - keys[-1] + keys[-1], + fallback_to_ldap=options['fallback_to_ldap'] ) keys = keys[:-1] + (anchor, ) @@ -645,6 +656,8 @@ class baseidoverride_add(LDAPCreate): __doc__ = _('Add a new ID override.') msg_summary = _('Added ID override "%(value)s"') + takes_options = LDAPCreate.takes_options + (fallback_to_ldap_option,) + def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): self.obj.set_anchoruuid_from_dn(dn, entry_attrs) self.obj.prohibit_ipa_users_in_default_view(dn, entry_attrs) @@ -659,11 +672,15 @@ class baseidoverride_del(LDAPDelete): __doc__ = _('Delete an ID override.') msg_summary = _('Deleted ID override "%(value)s"') + takes_options = LDAPDelete.takes_options + (fallback_to_ldap_option,) + class baseidoverride_mod(LDAPUpdate): __doc__ = _('Modify an ID override.') msg_summary = _('Modified an ID override "%(value)s"') + takes_options = LDAPUpdate.takes_options + (fallback_to_ldap_option,) + def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): if 'rename' in options: raise errors.ValidationError( @@ -684,6 +701,8 @@ class baseidoverride_find(LDAPSearch): msg_summary = ngettext('%(count)d ID override matched', '%(count)d ID overrides matched', 0) + takes_options = LDAPSearch.takes_options + (fallback_to_ldap_option,) + def post_callback(self, ldap, entries, truncated, *args, **options): for entry in entries: try: @@ -698,6 +717,8 @@ class baseidoverride_find(LDAPSearch): class baseidoverride_show(LDAPRetrieve): __doc__ = _('Display information about an ID override.') + takes_options = LDAPRetrieve.takes_options + (fallback_to_ldap_option,) + def post_callback(self, ldap, dn, entry_attrs, *keys, **options): try: self.obj.convert_anchor_to_human_readable_form(entry_attrs, **options) diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py index 9525c7458..725b2cd90 100644 --- a/ipaserver/dcerpc.py +++ b/ipaserver/dcerpc.py @@ -326,12 +326,17 @@ class DomainValidator(object): return entries - def get_trusted_domain_object_sid(self, object_name): + def get_trusted_domain_object_sid(self, object_name, fallback_to_ldap=True): result = pysss_nss_idmap.getsidbyname(object_name) if object_name in result and (pysss_nss_idmap.SID_KEY in result[object_name]): object_sid = result[object_name][pysss_nss_idmap.SID_KEY] return object_sid + # If fallback to AD DC LDAP is not allowed, bail out + if not fallback_to_ldap: + raise errors.ValidationError(name=_('trusted domain object'), + error= _('SSSD was unable to resolve the object to a valid SID')) + # Else, we are going to contact AD DC LDAP components = normalize_name(object_name) if not ('domain' in components or 'flatname' in components): -- cgit