summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--python/samba/join.py151
-rw-r--r--python/samba/tests/samba_tool/join.py29
-rwxr-xr-xsource4/selftest/tests.py1
3 files changed, 119 insertions, 62 deletions
diff --git a/python/samba/join.py b/python/samba/join.py
index 103e4d93a8b..3532a7f1e8f 100644
--- a/python/samba/join.py
+++ b/python/samba/join.py
@@ -170,6 +170,7 @@ class dc_join(object):
ctx.managedby = None
ctx.subdomain = False
ctx.adminpass = None
+ ctx.partition_dn = None
def del_noerror(ctx, dn, recursive=False):
if recursive:
@@ -185,71 +186,97 @@ class dc_join(object):
except Exception:
pass
+ def cleanup_old_accounts(ctx):
+ res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
+ expression='sAMAccountName=%s' % ldb.binary_encode(ctx.samname),
+ attrs=["msDS-krbTgtLink", "objectSID"])
+ if len(res) == 0:
+ return
+
+ creds = Credentials()
+ creds.guess(ctx.lp)
+ try:
+ creds.set_machine_account(ctx.lp)
+ machine_samdb = SamDB(url="ldap://%s" % ctx.server,
+ session_info=system_session(),
+ credentials=creds, lp=ctx.lp)
+ except:
+ pass
+ else:
+ token_res = machine_samdb.search(scope=ldb.SCOPE_BASE, base="", attrs=["tokenGroups"])
+ if token_res[0]["tokenGroups"][0] \
+ == res[0]["objectSID"][0]:
+ raise DCJoinException("Not removing account %s which "
+ "looks like a Samba DC account "
+ "maching the password we already have. "
+ "To override, remove secrets.ldb and secrets.tdb"
+ % ctx.samname)
+
+ ctx.del_noerror(res[0].dn, recursive=True)
+
+ if "msDS-Krbtgtlink" in res[0]:
+ new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0]
+ del_noerror(ctx.new_krbtgt_dn)
+
+ res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
+ expression='(&(sAMAccountName=%s)(servicePrincipalName=%s))' %
+ (ldb.binary_encode("dns-%s" % ctx.myname),
+ ldb.binary_encode("dns/%s" % ctx.dnshostname)),
+ attrs=[])
+ if res:
+ ctx.del_noerror(res[0].dn, recursive=True)
+
+ res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
+ expression='(sAMAccountName=%s)' % ldb.binary_encode("dns-%s" % ctx.myname),
+ attrs=[])
+ if res:
+ raise DCJoinException("Not removing account %s which looks like "
+ "a Samba DNS service account but does not "
+ "have servicePrincipalName=%s" %
+ (ldb.binary_encode("dns-%s" % ctx.myname),
+ ldb.binary_encode("dns/%s" % ctx.dnshostname)))
+
+
def cleanup_old_join(ctx):
"""Remove any DNs from a previous join."""
- try:
- # find the krbtgt link
- print("checking sAMAccountName")
- if ctx.subdomain:
- res = None
- else:
- res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
- expression='sAMAccountName=%s' % ldb.binary_encode(ctx.samname),
- attrs=["msDS-krbTgtLink"])
- if res:
- ctx.del_noerror(res[0].dn, recursive=True)
-
- res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
- expression='(&(sAMAccountName=%s)(servicePrincipalName=%s))' % (ldb.binary_encode("dns-%s" % ctx.myname), ldb.binary_encode("dns/%s" % ctx.dnshostname)),
- attrs=[])
- if res:
- ctx.del_noerror(res[0].dn, recursive=True)
-
- res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
- expression='(sAMAccountName=%s)' % ldb.binary_encode("dns-%s" % ctx.myname),
- attrs=[])
- if res:
- raise RuntimeError("Not removing account %s which looks like a Samba DNS service account but does not have servicePrincipalName=%s" % (ldb.binary_encode("dns-%s" % ctx.myname), ldb.binary_encode("dns/%s" % ctx.dnshostname)))
-
- if ctx.connection_dn is not None:
- ctx.del_noerror(ctx.connection_dn)
- if ctx.krbtgt_dn is not None:
- ctx.del_noerror(ctx.krbtgt_dn)
- ctx.del_noerror(ctx.ntds_dn)
- ctx.del_noerror(ctx.server_dn, recursive=True)
- if ctx.topology_dn:
- ctx.del_noerror(ctx.topology_dn)
- if ctx.partition_dn:
- ctx.del_noerror(ctx.partition_dn)
- if res:
- ctx.new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0]
- ctx.del_noerror(ctx.new_krbtgt_dn)
-
- if ctx.subdomain:
- binding_options = "sign"
- lsaconn = lsa.lsarpc("ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options),
- ctx.lp, ctx.creds)
-
- objectAttr = lsa.ObjectAttribute()
- objectAttr.sec_qos = lsa.QosInfo()
-
- pol_handle = lsaconn.OpenPolicy2(''.decode('utf-8'),
- objectAttr, security.SEC_FLAG_MAXIMUM_ALLOWED)
-
- name = lsa.String()
- name.string = ctx.realm
- info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
-
- lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)
-
- name = lsa.String()
- name.string = ctx.forest_domain_name
- info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
-
- lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)
+ # find the krbtgt link
+ if not ctx.subdomain:
+ ctx.cleanup_old_accounts()
+
+ if ctx.connection_dn is not None:
+ ctx.del_noerror(ctx.connection_dn)
+ if ctx.krbtgt_dn is not None:
+ ctx.del_noerror(ctx.krbtgt_dn)
+ ctx.del_noerror(ctx.ntds_dn)
+ ctx.del_noerror(ctx.server_dn, recursive=True)
+ if ctx.topology_dn:
+ ctx.del_noerror(ctx.topology_dn)
+ if ctx.partition_dn:
+ ctx.del_noerror(ctx.partition_dn)
+
+ if ctx.subdomain:
+ binding_options = "sign"
+ lsaconn = lsa.lsarpc("ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options),
+ ctx.lp, ctx.creds)
+
+ objectAttr = lsa.ObjectAttribute()
+ objectAttr.sec_qos = lsa.QosInfo()
+
+ pol_handle = lsaconn.OpenPolicy2(''.decode('utf-8'),
+ objectAttr, security.SEC_FLAG_MAXIMUM_ALLOWED)
+
+ name = lsa.String()
+ name.string = ctx.realm
+ info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
+
+ lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)
+
+ name = lsa.String()
+ name.string = ctx.forest_domain_name
+ info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
+
+ lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)
- except Exception:
- pass
def promote_possible(ctx):
"""confirm that the account is just a bare NT4 BDC or a member server, so can be safely promoted"""
diff --git a/python/samba/tests/samba_tool/join.py b/python/samba/tests/samba_tool/join.py
new file mode 100644
index 00000000000..1cc688f75dd
--- /dev/null
+++ b/python/samba/tests/samba_tool/join.py
@@ -0,0 +1,29 @@
+# Unix SMB/CIFS implementation.
+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2016
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os, ldb
+from samba.tests.samba_tool.base import SambaToolCmdTest
+
+class JoinCmdTestCase(SambaToolCmdTest):
+ """Test for samba-tool fsmo show subcommand"""
+
+ def test_rejoin(self):
+ """Run domain join to confirm it errors because we are already joined"""
+ (result, out, err) = self.runsubcmd("domain", "join", os.environ["REALM"], "dc", "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"]))
+
+ self.assertCmdFail(result)
+ self.assertTrue("Not removing account" in err,"Should fail with exception")
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 8e92da345e6..cebdab7d889 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -540,6 +540,7 @@ planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.bare")
planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix")
planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc")
planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd")
+planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.join")
# test fsmo show
for env in ["ad_dc_ntvfs", "fl2000dc", "fl2003dc", "fl2008r2dc"]: