summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2014-08-19 16:21:21 +0300
committerMartin Kosek <mkosek@redhat.com>2014-09-01 08:42:52 +0200
commit23e0bc411eb213fbdfe2e5436d82afe6fcbf0989 (patch)
tree6c48722905bdaadb6e442a6ec735f008a913e01a
parent3a8eeefe032fe6e532a367e69b3fbf26614c11b7 (diff)
downloadfreeipa-23e0bc411eb213fbdfe2e5436d82afe6fcbf0989.tar.gz
freeipa-23e0bc411eb213fbdfe2e5436d82afe6fcbf0989.tar.xz
freeipa-23e0bc411eb213fbdfe2e5436d82afe6fcbf0989.zip
ipaserver/dcerpc.py: make PDC discovery more robust
Certain operations against AD domain controller can only be done if its FSMO role is primary domain controller. We need to use writable DC and PDC when creating trust and updating name suffix routing information. https://fedorahosted.org/freeipa/ticket/4479 Reviewed-By: Sumit Bose <sbose@redhat.com>
-rw-r--r--ipaserver/dcerpc.py21
1 files changed, 16 insertions, 5 deletions
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index 599326719..495c380b0 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -707,16 +707,19 @@ class TrustDomainInstance(object):
binding_template=lambda x,y,z: u'%s:%s[%s]' % (x, y, z)
return [binding_template(t, remote_host, o) for t in transports for o in options]
- def retrieve_anonymously(self, remote_host, discover_srv=False):
+ def retrieve_anonymously(self, remote_host, discover_srv=False, search_pdc=False):
"""
When retrieving DC information anonymously, we can't get SID of the domain
"""
netrc = net.Net(creds=self.creds, lp=self.parm)
+ flags = nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS | nbt.NBT_SERVER_WRITABLE
+ if search_pdc:
+ flags = flags | nbt.NBT_SERVER_PDC
try:
if discover_srv:
- result = netrc.finddc(domain=remote_host, flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS)
+ result = netrc.finddc(domain=remote_host, flags=flags)
else:
- result = netrc.finddc(address=remote_host, flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS)
+ result = netrc.finddc(address=remote_host, flags=flags)
except RuntimeError, e:
raise assess_dcerpc_exception(message=str(e))
@@ -727,6 +730,7 @@ class TrustDomainInstance(object):
self.info['dns_forest'] = unicode(result.forest)
self.info['guid'] = unicode(result.domain_uuid)
self.info['dc'] = unicode(result.pdc_dns_name)
+ self.info['is_pdc'] = (result.server_type & nbt.NBT_SERVER_PDC) != 0
# Netlogon response doesn't contain SID of the domain.
# We need to do rootDSE search with LDAP_SERVER_EXTENDED_DN_OID control to reveal the SID
@@ -775,6 +779,13 @@ class TrustDomainInstance(object):
self.info['sid'] = unicode(result.sid)
self.info['dc'] = remote_host
+ try:
+ result = self._pipe.QueryInfoPolicy2(self._policy_handle, lsa.LSA_POLICY_INFO_ROLE)
+ except RuntimeError, (num, message):
+ raise assess_dcerpc_exception(num=num, message=message)
+
+ self.info['is_pdc'] = (result.role == lsa.LSA_ROLE_PRIMARY)
+
def generate_auth(self, trustdom_secret):
def arcfour_encrypt(key, data):
c = RC4.RC4(key)
@@ -1070,9 +1081,9 @@ class TrustDomainJoins(object):
rd.creds.set_anonymous()
rd.creds.set_workstation(self.local_domain.hostname)
if realm_server is None:
- rd.retrieve_anonymously(realm, discover_srv=True)
+ rd.retrieve_anonymously(realm, discover_srv=True, search_pdc=True)
else:
- rd.retrieve_anonymously(realm_server, discover_srv=False)
+ rd.retrieve_anonymously(realm_server, discover_srv=False, search_pdc=True)
rd.read_only = True
if realm_admin and realm_passwd:
if 'name' in rd.info: