summaryrefslogtreecommitdiff
path: root/source4/scripting
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-07-15 14:03:11 +1000
committerAndrew Bartlett <abartlet@samba.org>2010-07-15 22:08:22 +1000
commit299057d8d97cce349af2ff931396fae1f09493a5 (patch)
tree574a4f04ca8c515375c5c6d5e05194da2026eb87 /source4/scripting
parent3e8dba17030544a389611814e47521ceafa1ae8a (diff)
downloadsamba-299057d8d97cce349af2ff931396fae1f09493a5.tar.gz
samba-299057d8d97cce349af2ff931396fae1f09493a5.tar.bz2
samba-299057d8d97cce349af2ff931396fae1f09493a5.zip
s4:provision Handle machine account password changes while keeping keytab
The challenge here is to update the existing record if it already exists, rather than deleting the old record. This ensures that the secrets.keytab handling code keeps the previous password in the keytab. Andrew Bartlett
Diffstat (limited to 'source4/scripting')
-rw-r--r--source4/scripting/python/samba/provision.py38
1 files changed, 23 insertions, 15 deletions
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 5ede869015..8be3f655d2 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -680,17 +680,16 @@ def secretsdb_self_join(secretsdb, domain,
"krb5Keytab",
"privateKeytab"]
-
+ #We don't need to set msg["flatname"] here, because rdn_name will handle it, and it causes problems for modifies anyway
msg = ldb.Message(ldb.Dn(secretsdb, "flatname=%s,cn=Primary Domains" % domain))
- msg["secureChannelType"] = str(secure_channel_type)
- msg["flatname"] = [domain]
+ msg["secureChannelType"] = [str(secure_channel_type)]
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["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"]
@@ -701,30 +700,39 @@ def secretsdb_self_join(secretsdb, domain,
if domainsid is not None:
msg["objectSid"] = [ndr_pack(domainsid)]
+ # This complex expression tries to ensure that we don't have more
+ # than one record for this SID, realm or netbios domain at a time,
+ # but we don't delete the old record that we are about to modify,
+ # because that would delete the keytab and previous password.
res = secretsdb.search(base="cn=Primary Domains",
attrs=attrs,
- expression=("(&(|(flatname=%s)(realm=%s)(objectSid=%s))(objectclass=primaryDomain))" % (domain, realm, str(domainsid))),
+ expression=("(&(|(flatname=%s)(realm=%s)(objectSid=%s))(objectclass=primaryDomain)(!(dn=%s)))" % (domain, realm, str(domainsid), str(msg.dn))),
scope=ldb.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=ldb.SCOPE_BASE)
if len(res) == 1:
- msg["priorSecret"] = res[0]["secret"]
- msg["priorWhenChanged"] = res[0]["whenChanged"]
+ msg["priorSecret"] = [res[0]["secret"][0]]
+ msg["priorWhenChanged"] = [res[0]["whenChanged"][0]]
- if res["privateKeytab"] is not None:
- msg["privateKeytab"] = res[0]["privateKeytab"]
+ try:
+ msg["privateKeytab"] = [res[0]["privateKeytab"][0]]
+ except KeyError:
+ pass
- if res["krb5Keytab"] is not None:
- msg["krb5Keytab"] = res[0]["krb5Keytab"]
+ try:
+ msg["krb5Keytab"] = [res[0]["krb5Keytab"][0]]
+ except KeyError:
+ pass
for el in msg:
- el.set_flags(ldb.FLAG_MOD_REPLACE)
- secretsdb.modify(msg)
+ if el != 'dn':
+ msg[el].set_flags(ldb.FLAG_MOD_REPLACE)
+ secretsdb.modify(msg)
+ secretsdb.rename(res[0].dn, msg.dn)
else:
secretsdb.add(msg)