upgradeprovision: fix pb with dns-hostname, regenerate a correct keytab
authorMatthieu Patou <mat@matws.net>
Tue, 26 Oct 2010 12:37:50 +0000 (16:37 +0400)
committerMatthieu Patou <mat@samba.org>
Fri, 12 Nov 2010 19:40:21 +0000 (19:40 +0000)
source4/scripting/bin/upgradeprovision
source4/scripting/python/samba/upgradehelpers.py

index e1ef57193d6c6ac6b4a720af830bd10e3b6e8687..d2cc7abae72b5d40969aec0bf32164826597ddac 100755 (executable)
@@ -60,7 +60,7 @@ from samba.upgradehelpers import (dn_sort, get_paths, newprovision,
                                  delta_update_basesamdb, update_policyids,
                                  update_machine_account_password,
                                  search_constructed_attrs_stored,
-                                 int64range2str,
+                                 int64range2str, update_dns_account_password,
                                  increment_calculated_keyversion_number)
 
 replace=2**FLAG_MOD_REPLACE
@@ -1723,8 +1723,34 @@ if __name__ == '__main__':
             # as the delta_upgrade
             schemareloadclosure()
             sync_calculated_attributes(ldbs.sam, names)
+            res = ldbs.sam.search(expression="(samaccountname=dns)",
+                                scope=SCOPE_SUBTREE, attrs=["dn"],
+                                controls=["search_options:1:2"])
+            if len(res) > 0:
+                message(SIMPLE, "You still have the old dns object for managing"
+                                "dynamic DNS, but you didn't supply --full so "
+                                "correct update can't be done")
+                ldbs.groupedRollback()
+                new_ldbs.groupedRollback()
+                shutil.rmtree(provisiondir)
+                sys.exit(1)
         # 14)
         update_secrets(new_ldbs.secrets, ldbs.secrets, message)
+        # 14bis)
+        res = ldbs.sam.search(expression="(samaccountname=dns)",
+                                  scope=SCOPE_SUBTREE, attrs=["dn"],
+                                  controls=["search_options:1:2"])
+
+        if (len(res) == 1):
+            ldbs.sam.delete(res[0]["dn"])
+            res2 = ldbs.secrets.search(expression="(samaccountname=dns)",
+                                  scope=SCOPE_SUBTREE, attrs=["dn"])
+            update_dns_account_password(ldbs.sam, ldbs.secrets, names)
+            message(SIMPLE, "IMPORTANT !!! "
+                            "If you were using Dynmaic DNS before you need"
+                            " to update your configuration, so that the "
+                            "tkey-gssapi-credential has the following value:"
+                            "DNS/%s.%s" % (names.netbiosname.lower(), names.realm.lower()))
         # 15)
         message(SIMPLE, "Update machine account")
         update_machine_account_password(ldbs.sam, ldbs.secrets, names)
index b1258d2a53304ba89f8e363898dfcb56d517a2c6..b2bb66c5ea32b11cfcdbb70cfaeebf6aab300107 100755 (executable)
@@ -632,6 +632,13 @@ def update_secrets(newsecrets_ldb, secrets_ldb, messagefunc):
         delta.dn = current[0].dn
         secrets_ldb.modify(delta)
 
+    res2 = secrets_ldb.search(expression="(samaccountname=dns)",
+                                scope=SCOPE_SUBTREE, attrs=["dn"])
+
+    if (len(res2) == 1):
+            messagefunc(SIMPLE, "Remove old dns account")
+            secrets_ldb.delete(res2[0]["dn"])
+
 def getOEMInfo(samdb, rootdn):
     """Return OEM Information on the top level
     Samba4 use to store version info in this field
@@ -855,6 +862,47 @@ clearTextPassword:: """ + base64.b64encode(machinepass.encode('utf-16-le')) + ""
         raise ProvisioningError("Unable to find a Secure Channel"
                                 "of type SEC_CHAN_BDC")
 
+def update_dns_account_password(samdb, secrets_ldb, names):
+    """Update (change) the password of the dns both in the SAM db and in
+       secret one
+
+    :param samdb: An LDB object related to the sam.ldb file of a given provision
+    :param secrets_ldb: An LDB object related to the secrets.ldb file of a given
+                        provision
+    :param names: List of key provision parameters"""
+
+    expression = "samAccountName=dns-%s" % names.netbiosname
+    secrets_msg = secrets_ldb.search(expression=expression)
+    if len(secrets_msg) == 1:
+        res = samdb.search(expression=expression, attrs=[])
+        assert(len(res) == 1)
+
+        msg = ldb.Message(res[0].dn)
+        machinepass = samba.generate_random_password(128, 255)
+        mputf16 = machinepass.encode('utf-16-le')
+        msg["clearTextPassword"] = ldb.MessageElement(mputf16,
+                                                ldb.FLAG_MOD_REPLACE,
+                                                "clearTextPassword")
+
+        samdb.modify(msg)
+
+        res = samdb.search(expression=expression,
+                     attrs=["msDs-keyVersionNumber"])
+        assert(len(res) == 1)
+        kvno = str(res[0]["msDs-keyVersionNumber"])
+
+        msg = ldb.Message(secrets_msg[0].dn)
+        msg["secret"] = ldb.MessageElement(machinepass,
+                                                ldb.FLAG_MOD_REPLACE,
+                                                "secret")
+        msg["msDS-KeyVersionNumber"] = ldb.MessageElement(kvno,
+                                                ldb.FLAG_MOD_REPLACE,
+                                                "msDS-KeyVersionNumber")
+
+        secrets_ldb.modify(msg)
+    else:
+        raise ProvisioningError("Unable to find an object"
+                                " with %s" % expression )
 
 def search_constructed_attrs_stored(samdb, rootdn, attrs):
     """Search a given sam DB for calculated attributes that are