summaryrefslogtreecommitdiffstats
path: root/python/samba/netcmd/domain/classicupgrade.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/samba/netcmd/domain/classicupgrade.py')
-rw-r--r--python/samba/netcmd/domain/classicupgrade.py189
1 files changed, 189 insertions, 0 deletions
diff --git a/python/samba/netcmd/domain/classicupgrade.py b/python/samba/netcmd/domain/classicupgrade.py
new file mode 100644
index 0000000..5b6a8a8
--- /dev/null
+++ b/python/samba/netcmd/domain/classicupgrade.py
@@ -0,0 +1,189 @@
+# domain management - domain classicupgrade
+#
+# Copyright Matthias Dieter Wallnoefer 2009
+# Copyright Andrew Kroeger 2009
+# Copyright Jelmer Vernooij 2007-2012
+# Copyright Giampaolo Lauria 2011
+# Copyright Matthieu Patou <mat@matws.net> 2011
+# Copyright Andrew Bartlett 2008-2015
+# Copyright Stefan Metzmacher 2012
+#
+# 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 os
+import tempfile
+import subprocess
+
+import samba
+import samba.getopt as options
+from samba.auth import system_session
+from samba.auth_util import system_session_unix
+from samba.common import get_string
+from samba.netcmd import Command, CommandError, Option
+from samba.samba3 import Samba3
+from samba.samba3 import param as s3param
+from samba.upgrade import upgrade_from_samba3
+
+from .common import common_ntvfs_options
+
+
+def get_testparm_var(testparm, smbconf, varname):
+ errfile = open(os.devnull, 'w')
+ p = subprocess.Popen([testparm, '-s', '-l',
+ '--parameter-name=%s' % varname, smbconf],
+ stdout=subprocess.PIPE, stderr=errfile)
+ (out, err) = p.communicate()
+ errfile.close()
+ lines = out.split(b'\n')
+ if lines:
+ return get_string(lines[0]).strip()
+ return ""
+
+
+class cmd_domain_classicupgrade(Command):
+ """Upgrade from Samba classic (NT4-like) database to Samba AD DC database.
+
+ Specify either a directory with all Samba classic DC databases and state files (with --dbdir) or
+ the testparm utility from your classic installation (with --testparm).
+ """
+
+ synopsis = "%prog [options] <classic_smb_conf>"
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions
+ }
+
+ takes_options = [
+ Option("--dbdir", type="string", metavar="DIR",
+ help="Path to samba classic DC database directory"),
+ Option("--testparm", type="string", metavar="PATH",
+ help="Path to samba classic DC testparm utility from the previous installation. This allows the default paths of the previous installation to be followed"),
+ Option("--targetdir", type="string", metavar="DIR",
+ help="Path prefix where the new Samba 4.0 AD domain should be initialised"),
+ Option("-q", "--quiet", help="Be quiet", action="store_true"),
+ Option("-v", "--verbose", help="Be verbose", action="store_true"),
+ Option("--dns-backend", type="choice", metavar="NAMESERVER-BACKEND",
+ choices=["SAMBA_INTERNAL", "BIND9_FLATFILE", "BIND9_DLZ", "NONE"],
+ help="The DNS server backend. SAMBA_INTERNAL is the builtin name server (default), "
+ "BIND9_FLATFILE uses bind9 text database to store zone information, "
+ "BIND9_DLZ uses samba4 AD to store zone information, "
+ "NONE skips the DNS setup entirely (this DC will not be a DNS server)",
+ default="SAMBA_INTERNAL")
+ ]
+
+ ntvfs_options = [
+ Option("--use-xattrs", type="choice", choices=["yes", "no", "auto"],
+ metavar="[yes|no|auto]",
+ help="Define if we should use the native fs capabilities or a tdb file for "
+ "storing attributes likes ntacl when --use-ntvfs is set. "
+ "auto tries to make an intelligent guess based on the user rights and system capabilities",
+ default="auto")
+ ]
+ if samba.is_ntvfs_fileserver_built():
+ takes_options.extend(common_ntvfs_options)
+ takes_options.extend(ntvfs_options)
+
+ takes_args = ["smbconf"]
+
+ def run(self, smbconf=None, targetdir=None, dbdir=None, testparm=None,
+ quiet=False, verbose=False, use_xattrs="auto", sambaopts=None, versionopts=None,
+ dns_backend=None, use_ntvfs=False):
+
+ if not os.path.exists(smbconf):
+ raise CommandError("File %s does not exist" % smbconf)
+
+ if testparm and not os.path.exists(testparm):
+ raise CommandError("Testparm utility %s does not exist" % testparm)
+
+ if dbdir and not os.path.exists(dbdir):
+ raise CommandError("Directory %s does not exist" % dbdir)
+
+ if not dbdir and not testparm:
+ raise CommandError("Please specify either dbdir or testparm")
+
+ logger = self.get_logger(verbose=verbose, quiet=quiet)
+
+ if dbdir and testparm:
+ logger.warning("both dbdir and testparm specified, ignoring dbdir.")
+ dbdir = None
+
+ lp = sambaopts.get_loadparm()
+
+ s3conf = s3param.get_context()
+
+ if sambaopts.realm:
+ s3conf.set("realm", sambaopts.realm)
+
+ if targetdir is not None:
+ if not os.path.isdir(targetdir):
+ os.mkdir(targetdir)
+
+ eadb = True
+ if use_xattrs == "yes":
+ eadb = False
+ elif use_xattrs == "auto" and not use_ntvfs:
+ eadb = False
+ elif not use_ntvfs:
+ raise CommandError("--use-xattrs=no requires --use-ntvfs (not supported for production use). "
+ "Please re-run with --use-xattrs omitted.")
+ elif use_xattrs == "auto" and not s3conf.get("posix:eadb"):
+ if targetdir:
+ tmpfile = tempfile.NamedTemporaryFile(dir=os.path.abspath(targetdir))
+ else:
+ tmpfile = tempfile.NamedTemporaryFile(dir=os.path.abspath(os.path.dirname(lp.get("private dir"))))
+ try:
+ try:
+ samba.ntacls.setntacl(lp, tmpfile.name,
+ "O:S-1-5-32G:S-1-5-32",
+ "S-1-5-32",
+ system_session_unix(),
+ "native")
+ eadb = False
+ except Exception:
+ # FIXME: Don't catch all exceptions here
+ logger.info("You are not root or your system does not support xattr, using tdb backend for attributes. "
+ "If you intend to use this provision in production, rerun the script as root on a system supporting xattrs.")
+ finally:
+ tmpfile.close()
+
+ # Set correct default values from dbdir or testparm
+ paths = {}
+ if dbdir:
+ paths["state directory"] = dbdir
+ paths["private dir"] = dbdir
+ paths["lock directory"] = dbdir
+ paths["smb passwd file"] = dbdir + "/smbpasswd"
+ else:
+ paths["state directory"] = get_testparm_var(testparm, smbconf, "state directory")
+ paths["private dir"] = get_testparm_var(testparm, smbconf, "private dir")
+ paths["smb passwd file"] = get_testparm_var(testparm, smbconf, "smb passwd file")
+ paths["lock directory"] = get_testparm_var(testparm, smbconf, "lock directory")
+ # "testparm" from Samba 3 < 3.4.x is not aware of the parameter
+ # "state directory", instead make use of "lock directory"
+ if len(paths["state directory"]) == 0:
+ paths["state directory"] = paths["lock directory"]
+
+ for p in paths:
+ s3conf.set(p, paths[p])
+
+ # load smb.conf parameters
+ logger.info("Reading smb.conf")
+ s3conf.load(smbconf)
+ samba3 = Samba3(smbconf, s3conf)
+
+ logger.info("Provisioning")
+ upgrade_from_samba3(samba3, logger, targetdir, session_info=system_session(),
+ useeadb=eadb, dns_backend=dns_backend, use_ntvfs=use_ntvfs)