|
|
9991ea |
From 7c4828f3eb0e7b1f246f6263bdf22592d51824df Mon Sep 17 00:00:00 2001
|
|
|
9991ea |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
9991ea |
Date: Wed, 27 Nov 2013 12:17:43 +0200
|
|
|
9991ea |
Subject: [PATCH 08/10] subdomains: Use AD admin credentials when trust is
|
|
|
9991ea |
being established
|
|
|
9991ea |
|
|
|
9991ea |
When AD administrator credentials passed, they stored in realm_passwd,
|
|
|
9991ea |
not realm_password in the options.
|
|
|
9991ea |
|
|
|
9991ea |
When passing credentials to ipaserver.dcerpc.fetch_domains(), make sure
|
|
|
9991ea |
to normalize them.
|
|
|
9991ea |
|
|
|
9991ea |
Additionally, force Samba auth module to use NTLMSSP in case we have
|
|
|
9991ea |
credentials because at the point when trust is established, KDC is not
|
|
|
9991ea |
yet ready to issue tickets to a service in the other realm due to
|
|
|
9991ea |
MS-PAC information caching effects. The logic is a bit fuzzy because
|
|
|
9991ea |
credentials code makes decisions on what to use based on the smb.conf
|
|
|
9991ea |
parameters and Python bindings to set parameters to smb.conf make it so
|
|
|
9991ea |
that auth module believes these parameters were overidden by the user
|
|
|
9991ea |
through the command line and ignore some of options. We have to do calls
|
|
|
9991ea |
in the right order to force NTLMSSP use instead of Kerberos.
|
|
|
9991ea |
|
|
|
9991ea |
Fixes https://fedorahosted.org/freeipa/ticket/4046
|
|
|
9991ea |
---
|
|
|
9991ea |
ipalib/plugins/trust.py | 13 ++++++++++---
|
|
|
9991ea |
ipaserver/dcerpc.py | 42 ++++++++++++++++++++++++++++--------------
|
|
|
9991ea |
2 files changed, 38 insertions(+), 17 deletions(-)
|
|
|
9991ea |
|
|
|
9991ea |
diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
|
|
|
9991ea |
index 5ba0905030c700c7f63003eef25891c52330934b..3b1b2fc67ce333751556a5c3a59a7f89efc608f9 100644
|
|
|
9991ea |
--- a/ipalib/plugins/trust.py
|
|
|
9991ea |
+++ b/ipalib/plugins/trust.py
|
|
|
9991ea |
@@ -1231,10 +1231,17 @@ def execute(self, *keys, **options):
|
|
|
9991ea |
def fetch_domains_from_trust(self, trustinstance, trust_entry, **options):
|
|
|
9991ea |
trust_name = trust_entry['cn'][0]
|
|
|
9991ea |
creds = None
|
|
|
9991ea |
- password = options.get('realm_password', None)
|
|
|
9991ea |
+ password = options.get('realm_passwd', None)
|
|
|
9991ea |
if password:
|
|
|
9991ea |
- creds = u"%s%%%s" % (options.get('realm_admin'), password)
|
|
|
9991ea |
- domains = ipaserver.dcerpc.fetch_domains(self.api, trustinstance.local_flatname, trust_name, creds=creds)
|
|
|
9991ea |
+ admin_name = options.get('realm_admin')
|
|
|
9991ea |
+ sp = admin_name.split('\\')
|
|
|
9991ea |
+ if len(sp) == 1:
|
|
|
9991ea |
+ sp.insert(0, trustinstance.remote_domain.info['name'])
|
|
|
9991ea |
+ creds = u"{name}%{password}".format(name="\\".join(sp),
|
|
|
9991ea |
+ password=password)
|
|
|
9991ea |
+ domains = ipaserver.dcerpc.fetch_domains(self.api,
|
|
|
9991ea |
+ trustinstance.local_flatname,
|
|
|
9991ea |
+ trust_name, creds=creds)
|
|
|
9991ea |
result = []
|
|
|
9991ea |
if not domains:
|
|
|
9991ea |
return None
|
|
|
9991ea |
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
|
|
|
9991ea |
index 0dde3473b12b857ff269a936ad9a07d098405c45..d809c416baac072a2489fbd3c167f08665b7a24e 100644
|
|
|
9991ea |
--- a/ipaserver/dcerpc.py
|
|
|
9991ea |
+++ b/ipaserver/dcerpc.py
|
|
|
9991ea |
@@ -655,7 +655,7 @@ def __gen_lsa_connection(self, binding):
|
|
|
9991ea |
except RuntimeError, (num, message):
|
|
|
9991ea |
raise assess_dcerpc_exception(num=num, message=message)
|
|
|
9991ea |
|
|
|
9991ea |
- def __init_lsa_pipe(self, remote_host):
|
|
|
9991ea |
+ def init_lsa_pipe(self, remote_host):
|
|
|
9991ea |
"""
|
|
|
9991ea |
Try to initialize connection to the LSA pipe at remote host.
|
|
|
9991ea |
This method tries consequently all possible transport options
|
|
|
9991ea |
@@ -692,7 +692,7 @@ def __gen_lsa_bindings(self, remote_host):
|
|
|
9991ea |
"""
|
|
|
9991ea |
There are multiple transports to issue LSA calls. However, depending on a
|
|
|
9991ea |
system in use they may be blocked by local operating system policies.
|
|
|
9991ea |
- Generate all we can use. __init_lsa_pipe() will try them one by one until
|
|
|
9991ea |
+ Generate all we can use. init_lsa_pipe() will try them one by one until
|
|
|
9991ea |
there is one working.
|
|
|
9991ea |
|
|
|
9991ea |
We try NCACN_NP before NCACN_IP_TCP and signed sessions before unsigned.
|
|
|
9991ea |
@@ -753,7 +753,7 @@ def parse_naming_context(self, context):
|
|
|
9991ea |
return naming_ref.match(context).group(1)
|
|
|
9991ea |
|
|
|
9991ea |
def retrieve(self, remote_host):
|
|
|
9991ea |
- self.__init_lsa_pipe(remote_host)
|
|
|
9991ea |
+ self.init_lsa_pipe(remote_host)
|
|
|
9991ea |
|
|
|
9991ea |
objectAttribute = lsa.ObjectAttribute()
|
|
|
9991ea |
objectAttribute.sec_qos = lsa.QosInfo()
|
|
|
9991ea |
@@ -964,34 +964,48 @@ def fetch_domains(api, mydomain, trustdomain, creds=None):
|
|
|
9991ea |
NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL = 0x00000040)
|
|
|
9991ea |
|
|
|
9991ea |
def communicate(td):
|
|
|
9991ea |
- td.creds.guess(td.parm)
|
|
|
9991ea |
- netrc = net.Net(creds=td.creds, lp=td.parm)
|
|
|
9991ea |
- try:
|
|
|
9991ea |
- result = netrc.finddc(domain=trustdomain, flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS)
|
|
|
9991ea |
- except RuntimeError, e:
|
|
|
9991ea |
- raise assess_dcerpc_exception(message=str(e))
|
|
|
9991ea |
- if not result:
|
|
|
9991ea |
- return None
|
|
|
9991ea |
- td.retrieve(unicode(result.pdc_dns_name))
|
|
|
9991ea |
-
|
|
|
9991ea |
+ td.init_lsa_pipe(td.info['dc'])
|
|
|
9991ea |
netr_pipe = netlogon.netlogon(td.binding, td.parm, td.creds)
|
|
|
9991ea |
domains = netr_pipe.netr_DsrEnumerateDomainTrusts(td.binding, 1)
|
|
|
9991ea |
return domains
|
|
|
9991ea |
|
|
|
9991ea |
domains = None
|
|
|
9991ea |
+ domain_validator = DomainValidator(api)
|
|
|
9991ea |
+ configured = domain_validator.is_configured()
|
|
|
9991ea |
+ if not configured:
|
|
|
9991ea |
+ return None
|
|
|
9991ea |
+
|
|
|
9991ea |
td = TrustDomainInstance('')
|
|
|
9991ea |
td.parm.set('workgroup', mydomain)
|
|
|
9991ea |
- td.creds = credentials.Credentials()
|
|
|
9991ea |
+ cr = credentials.Credentials()
|
|
|
9991ea |
+ cr.set_kerberos_state(credentials.DONT_USE_KERBEROS)
|
|
|
9991ea |
+ cr.guess(td.parm)
|
|
|
9991ea |
+ cr.set_anonymous()
|
|
|
9991ea |
+ cr.set_workstation(domain_validator.flatname)
|
|
|
9991ea |
+ netrc = net.Net(creds=cr, lp=td.parm)
|
|
|
9991ea |
+ try:
|
|
|
9991ea |
+ result = netrc.finddc(domain=trustdomain,
|
|
|
9991ea |
+ flags=nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS)
|
|
|
9991ea |
+ except RuntimeError, e:
|
|
|
9991ea |
+ raise assess_dcerpc_exception(message=str(e))
|
|
|
9991ea |
+
|
|
|
9991ea |
+ td.info['dc'] = unicode(result.pdc_dns_name)
|
|
|
9991ea |
if creds is None:
|
|
|
9991ea |
domval = DomainValidator(api)
|
|
|
9991ea |
(ccache_name, principal) = domval.kinit_as_http(trustdomain)
|
|
|
9991ea |
+ td.creds = credentials.Credentials()
|
|
|
9991ea |
td.creds.set_kerberos_state(credentials.MUST_USE_KERBEROS)
|
|
|
9991ea |
if ccache_name:
|
|
|
9991ea |
with installutils.private_ccache(path=ccache_name):
|
|
|
9991ea |
+ td.creds.guess(td.parm)
|
|
|
9991ea |
+ td.creds.set_workstation(domain_validator.flatname)
|
|
|
9991ea |
domains = communicate(td)
|
|
|
9991ea |
else:
|
|
|
9991ea |
+ td.creds = credentials.Credentials()
|
|
|
9991ea |
td.creds.set_kerberos_state(credentials.DONT_USE_KERBEROS)
|
|
|
9991ea |
+ td.creds.guess(td.parm)
|
|
|
9991ea |
td.creds.parse_string(creds)
|
|
|
9991ea |
+ td.creds.set_workstation(domain_validator.flatname)
|
|
|
9991ea |
domains = communicate(td)
|
|
|
9991ea |
|
|
|
9991ea |
if domains is None:
|
|
|
9991ea |
--
|
|
|
9991ea |
1.8.3.1
|
|
|
9991ea |
|