Add a simple script to change dc password
authorMatthieu Patou <mat@matws.net>
Mon, 28 Jun 2010 09:49:08 +0000 (13:49 +0400)
committerMatthieu Patou <mat@matws.net>
Mon, 28 Jun 2010 09:49:45 +0000 (13:49 +0400)
source4/scripting/devel/chgtdcpass [new file with mode: 0755]

diff --git a/source4/scripting/devel/chgtdcpass b/source4/scripting/devel/chgtdcpass
new file mode 100755 (executable)
index 0000000..ae1c7e4
--- /dev/null
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+# vim: expandtab
+#
+# Copyright (C) Matthieu Patou <mat@matws.net> 2009 - 2010
+#
+# Based on provision a Samba4 server by
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
+#
+#
+# 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 optparse
+import sys
+# Allow to run from s4 source directory (without installing samba)
+sys.path.insert(0, "bin/python")
+
+import samba
+import samba.getopt as options
+from samba.credentials import DONT_USE_KERBEROS
+from samba.auth import system_session
+from samba import param
+from samba.upgradehelpers import (get_paths, 
+                                 find_provision_key_parameters, get_ldbs)
+from samba.dcerpc.misc import SEC_CHAN_BDC
+from ldb import Message, MessageElement, FLAG_MOD_REPLACE
+from samba.provision import secretsdb_self_join
+
+# Will be modified during provision to tell if default sd has been modified
+# somehow ...
+
+#Errors are always logged
+
+__docformat__ = "restructuredText"
+
+
+
+
+parser = optparse.OptionParser("provision [options]")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+parser.add_option_group(options.VersionOptions(parser))
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+
+opts = parser.parse_args()[0]
+
+SIMPLE = -1
+
+def message(what, text):
+    """Print a message if this message type has been selected to be printed
+
+    :param what: Category of the message
+    :param text: Message to print """
+    print text
+
+if len(sys.argv) == 1:
+    opts.interactive = True
+lp = sambaopts.get_loadparm()
+smbconf = lp.configfile
+
+creds = credopts.get_credentials(lp)
+creds.set_kerberos_state(DONT_USE_KERBEROS)
+
+def update_machine_account_password(samdb, secrets_ldb, names):
+    """Update (change) the password of the current DC 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"""
+
+    message(SIMPLE, "Update machine account")
+    expression = "samAccountName=%s$" % names.netbiosname
+    secrets_msg = secrets_ldb.search(expression=expression,
+                                        attrs=["secureChannelType"])
+    if int(secrets_msg[0]["secureChannelType"][0]) == SEC_CHAN_BDC:
+        res = samdb.search(expression=expression, attrs=[])
+        assert(len(res) == 1)
+
+        msg = Message(res[0].dn)
+        machinepass = samba.generate_random_password(128, 255)
+        msg["userPassword"] = MessageElement(machinepass, FLAG_MOD_REPLACE,
+                                                "userPassword")
+        samdb.modify(msg)
+
+        res = samdb.search(expression=("samAccountName=%s$" % names.netbiosname),
+                     attrs=["msDs-keyVersionNumber"])
+        assert(len(res) == 1)
+        kvno = int(str(res[0]["msDs-keyVersionNumber"]))
+        secChanType = int(secrets_msg[0]["secureChannelType"][0])
+
+        secretsdb_self_join(secrets_ldb, domain=names.domain,
+                    realm=names.realm or sambaopts._lp.get('realm'),
+                    domainsid=names.domainsid,
+                    dnsdomain=names.dnsdomain,
+                    netbiosname=names.netbiosname,
+                    machinepass=machinepass,
+                    key_version_number=kvno,
+                    secure_channel_type=secChanType)
+
+
+
+
+
+if __name__ == '__main__':
+    global defSDmodified
+    defSDmodified = 0
+    # From here start the big steps of the program
+    # 1) First get files paths
+    paths = get_paths(param, smbconf=smbconf)
+    # Get ldbs with the system session, it is needed for searching
+    # provision parameters
+    session = system_session()
+
+    # This variable will hold the last provision USN once if it exists.
+    minUSN = 0
+    # 2)
+    ldbs = get_ldbs(paths, creds, session, lp)
+    ldbs.startTransactions()
+
+    # 3) Guess all the needed names (variables in fact) from the current
+    # provision.
+    names = find_provision_key_parameters(ldbs.sam, ldbs.secrets, ldbs.idmap,
+                                            paths, smbconf, lp)
+
+    update_machine_account_password(ldbs.sam, ldbs.secrets, names)
+    ldbs.groupedCommit()
+