[Freeipa-devel] [PATCHES 0351-0353] Improvements to ID override type validation
Alexander Bokovoy
abokovoy at redhat.com
Thu Jul 23 13:08:01 UTC 2015
On Thu, 23 Jul 2015, Tomas Babej wrote:
>Hi,
>
>this patchset deals mainly with the ticket:
>
>https://fedorahosted.org/freeipa/ticket/5029
>
>Details in the commit messages.
>
>Tomas
>From 83defa7e286b9e65a147598b4056abc47b4647bf Mon Sep 17 00:00:00 2001
>From: Tomas Babej <tbabej at redhat.com>
>Date: Wed, 22 Jul 2015 14:00:37 +0200
>Subject: [PATCH] dcerpc: Add get_trusted_domain_object_type method
>
>https://fedorahosted.org/freeipa/ticket/5029
>---
> ipaserver/dcerpc.py | 29 +++++++++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
>diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
>index 7220c440d16816abf5c022c840e9744f321878c4..be6313e1586cb9e3296361a8d07041d496d3223f 100644
>--- a/ipaserver/dcerpc.py
>+++ b/ipaserver/dcerpc.py
>@@ -107,6 +107,14 @@ dcerpc_error_messages = {
> errors.RequirementError(name=_('At least the domain or IP address should be specified')),
> }
>
>+pysss_type_key_translation_dict = {
>+ pysss_nss_idmap.ID_USER: 'user',
>+ pysss_nss_idmap.ID_GROUP: 'group',
>+ # Used for users with magic private groups
>+ pysss_nss_idmap.ID_BOTH: 'both',
>+}
>+
>+
> def assess_dcerpc_exception(num=None,message=None):
> """
> Takes error returned by Samba bindings and converts it into
>@@ -368,6 +376,27 @@ class DomainValidator(object):
> raise errors.ValidationError(name=_('trusted domain object'),
> error= _('Trusted domain did not return a valid SID for the object'))
>
>+ def get_trusted_domain_object_type(self, name_or_sid):
>+ """
>+ Return the type of the object corresponding to the given name in
>+ the trusted domain, which is either 'user', 'group' or 'both'.
>+ The 'both' types is used for users with magic private groups.
>+ """
>+
>+ object_type = None
>+
>+ if is_sid_valid(name_or_sid):
>+ result = pysss_nss_idmap.getnamebysid(name_or_sid)
>+ else:
>+ result = pysss_nss_idmap.getsidbyname(name_or_sid)
>+
>+ if name_or_sid in result:
>+ object_type = result[name_or_sid].get(pysss_nss_idmap.TYPE_KEY)
If user or group not found, pysss_nss_idmap.getsidbyname() will return
empty dict and the line above will fail:
>>> import pysss_nss_idmap
>>> pysss_nss_idmap.getsidbyname('some-name')
{}
>+
>+ # Do the translation to hide pysss_nss_idmap constants
>+ # from higher-level code
>+ return pysss_type_key_translation_dict.get(object_type)
>+
> def get_trusted_domain_object_from_sid(self, sid):
> root_logger.debug("Converting SID to object name: %s" % sid)
>
>--
>2.1.0
>
>From b331e08905db1deb90e1188e62a51620c3f187b3 Mon Sep 17 00:00:00 2001
>From: Tomas Babej <tbabej at redhat.com>
>Date: Thu, 23 Jul 2015 12:36:53 +0200
>Subject: [PATCH] idviews: Restrict anchor to name and name to anchor
> conversions
>
>When converting the ID override anchor from AD SID representation to
>the object name, we need to properly restrict the type of the object
>that is being resolved.
>
>The same restriction applies for the opposite direction, when
>converting the object name to it's SID.
>
>https://fedorahosted.org/freeipa/ticket/5029
>---
> ipalib/plugins/idviews.py | 50 +++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 46 insertions(+), 4 deletions(-)
>
>diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
>index 48f646b812c424435233327e8fcfa363e17104f2..4d1aefef2cc8e8259d6b62315eb266c61f5cc5fb 100644
>--- a/ipalib/plugins/idviews.py
>+++ b/ipalib/plugins/idviews.py
>@@ -434,6 +434,36 @@ class idview_unapply(baseidview_apply):
>
>
> # ID overrides helper methods
>+def verify_trusted_domain_object_type(validator, desired_type, name_or_sid):
>+
>+ object_type = validator.get_trusted_domain_object_type(name_or_sid)
>+
>+ if object_type == desired_type:
>+ # In case SSSD returns the same type as the type being
>+ # searched, no problems here.
>+ return True
>+
>+ elif desired_type == 'user' and object_type == 'both':
>+ # Type both denotes users with magic private groups.
>+ # Overriding attributes for such users is OK.
>+ return True
>+
>+ elif desired_type == 'group' and object_type == 'both':
>+ # However, overriding attributes for magic private groups
>+ # does not make sense. One should override the GID of
>+ # the user itself.
>+
>+ raise errors.ConversionError(
>+ name='identifier',
>+ error=_('You are trying to reference a magic private group '
>+ 'which is not allowed to be overriden. '
>+ 'Try overriding the GID attribute of the '
>+ 'corresponding user instead.')
>+ )
>+
>+ return False
>+
>+
> def resolve_object_to_anchor(ldap, obj_type, obj, fallback_to_ldap):
> """
> Resolves the user/group name to the anchor uuid:
>@@ -484,9 +514,15 @@ def resolve_object_to_anchor(ldap, obj_type, obj, fallback_to_ldap):
> 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
>- return SID_ANCHOR_PREFIX + sid
>+ # We need to verify that the object type is correct
>+ type_correct = verify_trusted_domain_object_type(
>+ domain_validator, obj_type, sid)
>+
>+ if type_correct:
>+ # There is no domain prefix since SID contains information
>+ # about the domain
>+ return SID_ANCHOR_PREFIX + sid
>+
> except errors.ValidationError:
> # Domain validator raises Validation Error if object name does not
> # contain domain part (either NETBIOS\ prefix or @domain.name suffix)
>@@ -541,7 +577,13 @@ def resolve_anchor_to_object_name(ldap, obj_type, anchor):
> domain_validator = ipaserver.dcerpc.DomainValidator(api)
> if domain_validator.is_configured():
> name = domain_validator.get_trusted_domain_object_from_sid(sid)
>- return name
>+
>+ # We need to verify that the object type is correct
>+ type_correct = verify_trusted_domain_object_type(
>+ domain_validator, obj_type, name)
>+
>+ if type_correct:
>+ return name
>
> # No acceptable object was found
> raise errors.NotFound(
>--
>2.1.0
>
>From 1086f33dda3b5b92793ad6fb710be59703a186ac Mon Sep 17 00:00:00 2001
>From: Tomas Babej <tbabej at redhat.com>
>Date: Thu, 23 Jul 2015 14:00:06 +0200
>Subject: [PATCH] idviews: Enforce objectclass check in idoverride*-del
>
>Even with anchor to sid type checking, it would be still
>possible to delete a user ID override by specifying a group
>raw anchor and vice versa.
>
>This patch introduces a objectclass check in idoverride*-del
>commands to prevent that.
>
>https://fedorahosted.org/freeipa/ticket/5029
>---
> ipalib/plugins/idviews.py | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
>diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
>index 4d1aefef2cc8e8259d6b62315eb266c61f5cc5fb..cf5c9b5e8371c89e89a4cf1d334ac0e6b514653a 100644
>--- a/ipalib/plugins/idviews.py
>+++ b/ipalib/plugins/idviews.py
>@@ -718,6 +718,25 @@ class baseidoverride_del(LDAPDelete):
>
> takes_options = LDAPDelete.takes_options + (fallback_to_ldap_option,)
>
>+ def pre_callback(self, ldap, dn, *keys, **options):
>+ assert isinstance(dn, DN)
>+
>+ # Make sure the entry we're deleting has all the objectclasses
>+ # this object requires
>+ try:
>+ entry = ldap.get_entry(dn, ['objectclass'])
>+ except errors.NotFound:
>+ self.obj.handle_not_found(*keys)
>+
>+ required_object_classes = set(self.obj.object_class)
>+ actual_object_classes = set(entry['objectclass'])
>+
>+ # If not, treat it as a failed search
>+ if not required_object_classes.issubset(actual_object_classes):
>+ self.obj.handle_not_found(*keys)
>+
>+ return dn
>+
>
> class baseidoverride_mod(LDAPUpdate):
> __doc__ = _('Modify an ID override.')
>--
>2.1.0
>
--
/ Alexander Bokovoy
More information about the Freeipa-devel
mailing list