summaryrefslogtreecommitdiff
path: root/source4/scripting
diff options
context:
space:
mode:
authorNadezhda Ivanova <nadezhda.ivanova@postpath.com>2009-09-21 14:26:15 -0700
committerNadezhda Ivanova <nadezhda.ivanova@postpath.com>2009-09-21 14:26:15 -0700
commit13b979b03d86f3ae43dc5fd539fa5d3f22f579a0 (patch)
tree40e15be25f6b975e7c5b91f00fdf6030726e25e7 /source4/scripting
parent025590e7a4758e86e7942642971b92fc6bab7a8e (diff)
parent1afc7c453c1d5f7e761e46cdc69900305a149820 (diff)
downloadsamba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.tar.gz
samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.tar.bz2
samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.zip
Merge branch 'master' of git://git.samba.org/samba
Diffstat (limited to 'source4/scripting')
-rw-r--r--source4/scripting/python/samba/provision.py117
-rw-r--r--source4/scripting/python/samba/samdb.py4
2 files changed, 92 insertions, 29 deletions
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 25cec4b143..2d3e04eac1 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -44,7 +44,7 @@ from credentials import Credentials, DONT_USE_KERBEROS
from auth import system_session, admin_session
from samba import version, Ldb, substitute_var, valid_netbios_name
from samba import check_all_substituted
-from samba import DS_DOMAIN_FUNCTION_2000, DS_DC_FUNCTION_2008_R2
+from samba import DS_DOMAIN_FUNCTION_2000, DS_DOMAIN_FUNCTION_2008, DS_DC_FUNCTION_2008, DS_DC_FUNCTION_2008_R2
from samba.samdb import SamDB
from samba.idmap import IDmapDB
from samba.dcerpc import security
@@ -54,14 +54,10 @@ from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, timestring
from ms_schema import read_ms_schema
from ms_display_specifiers import read_ms_ldif
from signal import SIGTERM
+from dcerpc.misc import SEC_CHAN_BDC, SEC_CHAN_WKSTA
__docformat__ = "restructuredText"
-
-class ProvisioningError(ValueError):
- pass
-
-
def find_setup_dir():
"""Find the setup directory used by provision."""
dirname = os.path.dirname(__file__)
@@ -113,6 +109,11 @@ def get_config_descriptor(domain_sid):
DEFAULTSITE = "Default-First-Site-Name"
+# Exception classes
+
+class ProvisioningError(Exception):
+ """A generic provision error."""
+
class InvalidNetbiosName(Exception):
"""A specified name was not a valid NetBIOS name."""
def __init__(self, name):
@@ -355,7 +356,6 @@ def provision_paths_from_lp(lp, dnsdomain):
"""
paths = ProvisionPaths()
paths.private_dir = lp.get("private dir")
- paths.keytab = "secrets.keytab"
paths.dns_keytab = "dns.keytab"
paths.shareconf = os.path.join(paths.private_dir, "share.ldb")
@@ -695,26 +695,83 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
samdb.transaction_commit()
+def secretsdb_self_join(secretsdb, domain,
+ netbiosname, domainsid, machinepass,
+ realm=None, dnsdomain=None,
+ keytab_path=None,
+ key_version_number=1,
+ secure_channel_type=SEC_CHAN_WKSTA):
+ """Add domain join-specific bits to a secrets database.
+
+ :param secretsdb: Ldb Handle to the secrets database
+ :param machinepass: Machine password
+ """
+ attrs=["whenChanged",
+ "secret",
+ "priorSecret",
+ "priorChanged",
+ "krb5Keytab",
+ "privateKeytab"]
+
+
+ msg = ldb.Message(ldb.Dn(secretsdb, "flatname=%s,cn=Primary Domains" % domain));
+ msg["secureChannelType"] = str(secure_channel_type)
+ msg["flatname"] = [domain]
+ msg["objectClass"] = ["top", "primaryDomain"]
+ if realm is not None:
+ if dnsdomain is None:
+ dnsdomain = realm.lower()
+ msg["objectClass"] = ["top", "primaryDomain", "kerberosSecret"]
+ msg["realm"] = realm
+ msg["saltPrincipal"] = "host/%s.%s@%s" % (netbiosname.lower(), dnsdomain.lower(), realm.upper())
+ msg["msDS-KeyVersionNumber"] = [str(key_version_number)]
+ msg["privateKeytab"] = ["secrets.keytab"];
+
+
+ msg["secret"] = [machinepass]
+ msg["samAccountName"] = ["%s$" % netbiosname]
+ msg["secureChannelType"] = [str(secure_channel_type)]
+ msg["objectSid"] = [ndr_pack(domainsid)]
+
+ res = secretsdb.search(base="cn=Primary Domains",
+ attrs=attrs,
+ expression=("(&(|(flatname=%s)(realm=%s)(objectSid=%s))(objectclass=primaryDomain))" % (domain, realm, str(domainsid))),
+ scope=SCOPE_ONELEVEL)
+
+ for del_msg in res:
+ if del_msg.dn is not msg.dn:
+ secretsdb.delete(del_msg.dn)
+
+ res = secretsdb.search(base=msg.dn, attrs=attrs, scope=SCOPE_BASE)
+ if len(res) == 1:
+ msg["priorSecret"] = res[0]["secret"]
+ msg["priorWhenChanged"] = res[0]["whenChanged"]
-def secretsdb_become_dc(secretsdb, setup_path, domain, realm, dnsdomain,
- netbiosname, domainsid, keytab_path, samdb_url,
- dns_keytab_path, dnspass, machinepass):
- """Add DC-specific bits to a secrets database.
+ if res["privateKeytab"] is not None:
+ msg["privateKeytab"] = res[0]["privateKeytab"]
+
+ if res["krb5Keytab"] is not None:
+ msg["krb5Keytab"] = res[0]["krb5Keytab"]
+
+ for el in msg:
+ el.set_flags(ldb.FLAG_MOD_REPLACE)
+ secretsdb.modify(msg)
+ else:
+ secretsdb.add(msg)
+
+
+def secretsdb_setup_dns(secretsdb, setup_path, realm, dnsdomain,
+ dns_keytab_path, dnspass):
+ """Add DNS specific bits to a secrets database.
:param secretsdb: Ldb Handle to the secrets database
:param setup_path: Setup path function
:param machinepass: Machine password
"""
- setup_ldb(secretsdb, setup_path("secrets_dc.ldif"), {
- "MACHINEPASS_B64": b64encode(machinepass),
- "DOMAIN": domain,
+ setup_ldb(secretsdb, setup_path("secrets_dns.ldif"), {
"REALM": realm,
"DNSDOMAIN": dnsdomain,
- "DOMAINSID": str(domainsid),
- "SECRETS_KEYTAB": keytab_path,
- "NETBIOSNAME": netbiosname,
- "SAM_LDB": samdb_url,
"DNS_KEYTAB": dns_keytab_path,
"DNSPASS_B64": b64encode(dnspass),
})
@@ -738,6 +795,7 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp):
secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif"))
secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials,
lp=lp)
+ secrets_ldb.transaction_start()
secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif"))
if credentials is not None and credentials.authentication_requested():
@@ -873,9 +931,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
:note: This will wipe the main SAM database file!
"""
- domainFunctionality = DS_DOMAIN_FUNCTION_2000
- forestFunctionality = DS_DOMAIN_FUNCTION_2000
- domainControllerFunctionality = DS_DC_FUNCTION_2008_R2
+ # Do NOT change these default values without discussion with the team and reslease manager.
+ domainFunctionality = DS_DOMAIN_FUNCTION_2008
+ forestFunctionality = DS_DOMAIN_FUNCTION_2008
+ domainControllerFunctionality = DS_DC_FUNCTION_2008
# Also wipes the database
setup_samdb_partitions(path, setup_path, message=message, lp=lp,
@@ -1275,16 +1334,18 @@ def provision(setup_dir, message, session_info,
# Only make a zone file on the first DC, it should be replicated with DNS replication
if serverrole == "domain controller":
- secrets_ldb = Ldb(paths.secrets, session_info=session_info,
- credentials=credentials, lp=lp)
- secretsdb_become_dc(secrets_ldb, setup_path, domain=domain,
+ secretsdb_self_join(secrets_ldb, domain=domain,
realm=names.realm,
+ dnsdomain=names.dnsdomain,
netbiosname=names.netbiosname,
domainsid=domainsid,
- keytab_path=paths.keytab, samdb_url=paths.samdb,
+ machinepass=machinepass,
+ secure_channel_type=SEC_CHAN_BDC)
+
+ secretsdb_setup_dns(secrets_ldb, setup_path,
+ realm=names.realm, dnsdomain=names.dnsdomain,
dns_keytab_path=paths.dns_keytab,
- dnspass=dnspass, machinepass=machinepass,
- dnsdomain=names.dnsdomain)
+ dnspass=dnspass)
domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
assert isinstance(domainguid, str)
@@ -1309,6 +1370,8 @@ def provision(setup_dir, message, session_info,
realm=names.realm)
message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf)
+ #Now commit the secrets.ldb to disk
+ secrets_ldb.transaction_commit()
if provision_backend is not None:
if ldap_backend_type == "fedora-ds":
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index 239dd6a6ea..39cf1d6c40 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -202,8 +202,8 @@ userPassword:: %s
self.transaction_start()
try:
res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE,
- expression=filter,
- attrs=["userAccountControl", "accountExpires"])
+ expression=filter,
+ attrs=["userAccountControl", "accountExpires"])
assert(len(res) == 1)
user_dn = res[0].dn