Enforce exact SID match when adding or modifying a ID range

SID validation in idrange.py now enforces exact match on SIDs, thus
one can no longer use SID of an object in a trusted domain as a
trusted domain SID.

https://fedorahosted.org/freeipa/ticket/3432
This commit is contained in:
Tomas Babej 2013-03-06 12:17:28 +01:00 committed by Martin Kosek
parent 354a5db38e
commit 04a17f00b7
2 changed files with 38 additions and 14 deletions

View File

@ -289,7 +289,7 @@ class idrange(LDAPObject):
domain_validator = self.get_domain_validator()
if not domain_validator.is_trusted_sid_valid(sid):
if not domain_validator.is_trusted_domain_sid_valid(sid):
raise errors.ValidationError(name='domain SID',
error=_('SID is not recognized as a valid SID for a '
'trusted domain'))

View File

@ -184,37 +184,53 @@ class DomainValidator(object):
except errors.NotFound, e:
return []
def get_domain_by_sid(self, sid):
def get_domain_by_sid(self, sid, exact_match=False):
if not self.domain:
# our domain is not configured or self.is_configured() never run
# reject SIDs as we can't check correctness of them
raise errors.ValidationError(name='sid',
error=_('domain is not configured'))
# Parse sid string to see if it is really in a SID format
try:
test_sid = security.dom_sid(sid)
except TypeError, e:
except TypeError:
raise errors.ValidationError(name='sid',
error=_('SID is not valid'))
# At this point we have SID_NT_AUTHORITY family SID and really need to
# check it against prefixes of domain SIDs we trust to
if not self._domains:
self._domains = self.get_trusted_domains()
if len(self._domains) == 0:
# Our domain is configured but no trusted domains are configured
# This means we can't check the correctness of a trusted domain SIDs
# This means we can't check the correctness of a trusted
# domain SIDs
raise errors.ValidationError(name='sid',
error=_('no trusted domain is configured'))
# We have non-zero list of trusted domains and have to go through them
# one by one and check their sids as prefixes
test_sid_subauths = test_sid.sub_auths
for domain in self._domains:
domsid = self._domains[domain][1]
sub_auths = domsid.sub_auths
num_auths = min(test_sid.num_auths, domsid.num_auths)
if test_sid_subauths[:num_auths] == sub_auths[:num_auths]:
return domain
raise errors.NotFound(reason=_('SID does not match any trusted domain'))
# We have non-zero list of trusted domains and have to go through
# them one by one and check their sids as prefixes / exact match
# depending on the value of exact_match flag
if exact_match:
# check exact match of sids
for domain in self._domains:
if sid == str(self._domains[domain][1]):
return domain
raise errors.NotFound(reason=_("SID does not match exactly"
"with any trusted domain's SID"))
else:
# check as prefixes
test_sid_subauths = test_sid.sub_auths
for domain in self._domains:
domsid = self._domains[domain][1]
sub_auths = domsid.sub_auths
num_auths = min(test_sid.num_auths, domsid.num_auths)
if test_sid_subauths[:num_auths] == sub_auths[:num_auths]:
return domain
raise errors.NotFound(reason=_('SID does not match any '
'trusted domain'))
def is_trusted_sid_valid(self, sid):
try:
@ -224,6 +240,14 @@ class DomainValidator(object):
else:
return True
def is_trusted_domain_sid_valid(self, sid):
try:
self.get_domain_by_sid(sid, exact_match=True)
except (errors.ValidationError, errors.NotFound):
return False
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."""