summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Babej <tbabej@redhat.com>2013-03-06 12:17:28 +0100
committerMartin Kosek <mkosek@redhat.com>2013-03-14 15:20:30 +0100
commit04a17f00b7a991297cc4f7441512a4f5ca436271 (patch)
treeaa497d1601251b2a32f5aa274d267a0bc0f4959f
parent354a5db38e46aaf7ff4ecb0b6ee54a18194c376e (diff)
downloadfreeipa-04a17f00b7a991297cc4f7441512a4f5ca436271.tar.gz
freeipa-04a17f00b7a991297cc4f7441512a4f5ca436271.tar.xz
freeipa-04a17f00b7a991297cc4f7441512a4f5ca436271.zip
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
-rw-r--r--ipalib/plugins/idrange.py2
-rw-r--r--ipaserver/dcerpc.py50
2 files changed, 38 insertions, 14 deletions
diff --git a/ipalib/plugins/idrange.py b/ipalib/plugins/idrange.py
index d8989327a..54f6fbb3e 100644
--- a/ipalib/plugins/idrange.py
+++ b/ipalib/plugins/idrange.py
@@ -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'))
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index 150f72709..5d052ea4a 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -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."""