1
0
mirror of https://github.com/samba-team/samba.git synced 2025-06-11 19:17:08 +03:00
samba-mirror/python/samba/netcmd/domain/classicupgrade.py
Andreas Schneider e046986d04 python:samba:netcmd: Fix code spelling
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-06-23 13:44:31 +00:00

190 lines
7.9 KiB
Python

# 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)