mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
scripting/join.py: Handle creating the dns-NAME account during a DC join
This will ensure that the DLZ plugin works out of the box when joining a second Samba DC to the domain. Andrew Bartlett Reviewed-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
bdab6f9431
commit
b106d9090e
@ -26,9 +26,12 @@ from samba.ndr import ndr_pack
|
||||
from samba.dcerpc import security, drsuapi, misc, nbt, lsa, drsblobs
|
||||
from samba.credentials import Credentials, DONT_USE_KERBEROS
|
||||
from samba.provision import secretsdb_self_join, provision, provision_fill, FILL_DRS, FILL_SUBDOMAIN
|
||||
from samba.provision.common import setup_path
|
||||
from samba.schema import Schema
|
||||
from samba.net import Net
|
||||
from samba.provision.sambadns import setup_bind9_dns
|
||||
from samba import read_and_sub_file
|
||||
from base64 import b64encode
|
||||
import logging
|
||||
import talloc
|
||||
import random
|
||||
@ -179,6 +182,19 @@ class dc_join(object):
|
||||
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:
|
||||
@ -579,6 +595,56 @@ class dc_join(object):
|
||||
"userAccountControl")
|
||||
ctx.samdb.modify(m)
|
||||
|
||||
if ctx.dns_backend.startswith("BIND9_"):
|
||||
ctx.dnspass = samba.generate_random_password(128, 255)
|
||||
|
||||
recs = ctx.samdb.parse_ldif(read_and_sub_file(setup_path("provision_dns_add_samba.ldif"),
|
||||
{"DNSDOMAIN": ctx.dnsdomain,
|
||||
"DOMAINDN": ctx.base_dn,
|
||||
"HOSTNAME" : ctx.myname,
|
||||
"DNSPASS_B64": b64encode(ctx.dnspass),
|
||||
"DNSNAME" : ctx.dnshostname}))
|
||||
for changetype, msg in recs:
|
||||
assert changetype == ldb.CHANGETYPE_NONE
|
||||
print "Adding DNS account %s with dns/ SPN" % msg["dn"]
|
||||
|
||||
# Remove dns password (we will set it as a modify, as we can't do clearTextPassword over LDAP)
|
||||
del msg["clearTextPassword"]
|
||||
# Remove isCriticalSystemObject for similar reasons, it cannot be set over LDAP
|
||||
del msg["isCriticalSystemObject"]
|
||||
try:
|
||||
ctx.samdb.add(msg)
|
||||
dns_acct_dn = msg["dn"]
|
||||
except ldb.LdbError, (num, _):
|
||||
if num != ldb.ERR_ENTRY_ALREADY_EXISTS:
|
||||
raise
|
||||
|
||||
# The account password set operation should normally be done over
|
||||
# LDAP. Windows 2000 DCs however allow this only with SSL
|
||||
# connections which are hard to set up and otherwise refuse with
|
||||
# ERR_UNWILLING_TO_PERFORM. In this case we fall back to libnet
|
||||
# over SAMR.
|
||||
print "Setting account password for %s" % ctx.samname
|
||||
try:
|
||||
ctx.samdb.setpassword("(&(objectClass=user)(samAccountName=dns-%s))"
|
||||
% ldb.binary_encode(ctx.myname),
|
||||
ctx.dnspass,
|
||||
force_change_at_next_login=False,
|
||||
username=ctx.samname)
|
||||
except ldb.LdbError, (num, _):
|
||||
if num != ldb.ERR_UNWILLING_TO_PERFORM:
|
||||
pass
|
||||
ctx.net.set_password(account_name="dns-" % ctx.myname,
|
||||
domain_name=ctx.domain_name,
|
||||
newpassword=ctx.dnspass)
|
||||
|
||||
res = ctx.samdb.search(base=dns_acct_dn, scope=ldb.SCOPE_BASE,
|
||||
attrs=["msDS-KeyVersionNumber"])
|
||||
if "msDS-KeyVersionNumber" in res[0]:
|
||||
ctx.dns_key_version_number = int(res[0]["msDS-KeyVersionNumber"][0])
|
||||
else:
|
||||
ctx.dns_key_version_number = None
|
||||
|
||||
def join_add_objects2(ctx):
|
||||
"""add the various objects needed for the join, for subdomains post replication"""
|
||||
|
||||
@ -861,13 +927,12 @@ class dc_join(object):
|
||||
key_version_number=ctx.key_version_number)
|
||||
|
||||
if ctx.dns_backend.startswith("BIND9_"):
|
||||
dnspass = samba.generate_random_password(128, 255)
|
||||
|
||||
setup_bind9_dns(ctx.local_samdb, secrets_ldb, security.dom_sid(ctx.domsid),
|
||||
ctx.names, ctx.paths, ctx.lp, logger,
|
||||
dns_backend=ctx.dns_backend,
|
||||
dnspass=dnspass, os_level=ctx.behavior_version,
|
||||
targetdir=ctx.targetdir)
|
||||
dnspass=ctx.dnspass, os_level=ctx.behavior_version,
|
||||
targetdir=ctx.targetdir,
|
||||
key_version_number=ctx.dns_key_version_number)
|
||||
|
||||
def join_setup_trusts(ctx):
|
||||
"""provision the local SAM."""
|
||||
|
@ -620,7 +620,7 @@ def add_dc_msdcs_records(samdb, forestdn, prefix, site, dnsforest, hostname,
|
||||
|
||||
|
||||
def secretsdb_setup_dns(secretsdb, names, private_dir, realm,
|
||||
dnsdomain, dns_keytab_path, dnspass):
|
||||
dnsdomain, dns_keytab_path, dnspass, key_version_number):
|
||||
"""Add DNS specific bits to a secrets database.
|
||||
|
||||
:param secretsdb: Ldb Handle to the secrets database
|
||||
@ -632,11 +632,15 @@ def secretsdb_setup_dns(secretsdb, names, private_dir, realm,
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if key_version_number is None:
|
||||
key_version_number = 1
|
||||
|
||||
setup_ldb(secretsdb, setup_path("secrets_dns.ldif"), {
|
||||
"REALM": realm,
|
||||
"DNSDOMAIN": dnsdomain,
|
||||
"DNS_KEYTAB": dns_keytab_path,
|
||||
"DNSPASS_B64": b64encode(dnspass),
|
||||
"KEY_VERSION_NUMBER": str(key_version_number),
|
||||
"HOSTNAME": names.hostname,
|
||||
"DNSNAME" : '%s.%s' % (
|
||||
names.netbiosname.lower(), names.dnsdomain.lower())
|
||||
@ -1074,7 +1078,7 @@ def setup_ad_dns(samdb, secretsdb, domainsid, names, paths, lp, logger,
|
||||
|
||||
def setup_bind9_dns(samdb, secretsdb, domainsid, names, paths, lp, logger,
|
||||
dns_backend, os_level, site=None, dnspass=None, hostip=None,
|
||||
hostip6=None, targetdir=None):
|
||||
hostip6=None, targetdir=None, key_version_number=None):
|
||||
"""Provision DNS information (assuming BIND9 backend in DC role)
|
||||
|
||||
:param samdb: LDB object connected to sam.ldb file
|
||||
@ -1107,7 +1111,8 @@ def setup_bind9_dns(samdb, secretsdb, domainsid, names, paths, lp, logger,
|
||||
secretsdb_setup_dns(secretsdb, names,
|
||||
paths.private_dir, realm=names.realm,
|
||||
dnsdomain=names.dnsdomain,
|
||||
dns_keytab_path=paths.dns_keytab, dnspass=dnspass)
|
||||
dns_keytab_path=paths.dns_keytab, dnspass=dnspass,
|
||||
key_version_number=key_version_number)
|
||||
|
||||
create_dns_dir(logger, paths)
|
||||
|
||||
|
@ -436,10 +436,19 @@ if __name__ == '__main__':
|
||||
"DNSNAME" : dnsname }
|
||||
)
|
||||
|
||||
res = ldbs.sam.search(base=domaindn, scope=ldb.SCOPE_DEFAULT,
|
||||
expression='(sAMAccountName=dns-%s)' % (hostname),
|
||||
attrs=["msDS-KeyVersionNumber"])
|
||||
if "msDS-KeyVersionNumber" in res[0]:
|
||||
dns_key_version_number = int(res[0]["msDS-KeyVersionNumber"][0])
|
||||
else:
|
||||
dns_key_version_number = None
|
||||
|
||||
secretsdb_setup_dns(ldbs.secrets, names,
|
||||
paths.private_dir, realm=names.realm,
|
||||
dnsdomain=names.dnsdomain,
|
||||
dns_keytab_path=paths.dns_keytab, dnspass=dnspass)
|
||||
dns_keytab_path=paths.dns_keytab, dnspass=dnspass,
|
||||
key_version_number=dns_key_version_number)
|
||||
else:
|
||||
logger.info("dns-%s account already exists" % hostname)
|
||||
|
||||
|
@ -5,7 +5,7 @@ objectClass: secret
|
||||
objectClass: kerberosSecret
|
||||
realm: ${REALM}
|
||||
servicePrincipalName: DNS/${DNSNAME}
|
||||
msDS-KeyVersionNumber: 1
|
||||
msDS-KeyVersionNumber: ${KEY_VERSION_NUMBER}
|
||||
privateKeytab: ${DNS_KEYTAB}
|
||||
secret:: ${DNSPASS_B64}
|
||||
samAccountName: dns-${HOSTNAME}
|
||||
|
Loading…
Reference in New Issue
Block a user