1
0
mirror of https://github.com/samba-team/samba.git synced 2025-09-02 01:49:29 +03:00

python:provision: run adprep as part of provision

With the default of base_schema=2019 we'll adprep to 2016.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Stefan Metzmacher
2023-03-17 16:48:26 +01:00
committed by Andrew Bartlett
parent f6d9f3760f
commit 4bba26579d
6 changed files with 109 additions and 9 deletions

View File

@ -320,6 +320,10 @@ class cmd_domain_provision(Command):
choices=["2008_R2", "2008_R2_old", "2012", "2012_R2", "2016", "2019"], choices=["2008_R2", "2008_R2_old", "2012", "2012_R2", "2016", "2019"],
help="The base schema files to use. Default is (Windows) 2019.", help="The base schema files to use. Default is (Windows) 2019.",
default="2019"), default="2019"),
Option("--adprep-level", type="choice", metavar="FUNCTION_LEVEL",
choices=["SKIP", "2008_R2", "2012", "2012_R2", "2016"],
help="The highest functional level to prepare for. Default is based on --base-schema",
default=None),
Option("--next-rid", type="int", metavar="NEXTRID", default=1000, Option("--next-rid", type="int", metavar="NEXTRID", default=1000,
help="The initial nextRid value (only needed for upgrades). Default is 1000."), help="The initial nextRid value (only needed for upgrades). Default is 1000."),
Option("--partitions-only", Option("--partitions-only",
@ -369,6 +373,7 @@ class cmd_domain_provision(Command):
blank=None, blank=None,
server_role=None, server_role=None,
function_level=None, function_level=None,
adprep_level=None,
next_rid=None, next_rid=None,
partitions_only=None, partitions_only=None,
targetdir=None, targetdir=None,
@ -471,6 +476,32 @@ class cmd_domain_provision(Command):
elif function_level == "2008_R2": elif function_level == "2008_R2":
dom_for_fun_level = DS_DOMAIN_FUNCTION_2008_R2 dom_for_fun_level = DS_DOMAIN_FUNCTION_2008_R2
if adprep_level is None:
# Select the adprep_level default based
# on what the base schema premits
if base_schema in ["2008_R2", "2008_R2_old"]:
# without explicit --adprep-level=2008_R2
# we will skip the adprep step on
# provision
adprep_level = "SKIP"
elif base_schema in ["2012"]:
adprep_level = "2012"
elif base_schema in ["2012_R2"]:
adprep_level = "2012_R2"
else:
adprep_level = "2016"
if adprep_level == "SKIP":
provision_adprep_level = None
elif adprep_level == "2008R2":
provision_adprep_level = DS_DOMAIN_FUNCTION_2008_R2
elif adprep_level == "2012":
provision_adprep_level = DS_DOMAIN_FUNCTION_2012
elif adprep_level == "2012_R2":
provision_adprep_level = DS_DOMAIN_FUNCTION_2012_R2
elif adprep_level == "2016":
provision_adprep_level = DS_DOMAIN_FUNCTION_2016
if dns_backend == "SAMBA_INTERNAL" and dns_forwarder is None: if dns_backend == "SAMBA_INTERNAL" and dns_forwarder is None:
dns_forwarder = suggested_forwarder dns_forwarder = suggested_forwarder
@ -537,6 +568,7 @@ class cmd_domain_provision(Command):
useeadb=eadb, next_rid=next_rid, lp=lp, use_ntvfs=use_ntvfs, useeadb=eadb, next_rid=next_rid, lp=lp, use_ntvfs=use_ntvfs,
use_rfc2307=use_rfc2307, skip_sysvolacl=False, use_rfc2307=use_rfc2307, skip_sysvolacl=False,
base_schema=base_schema, base_schema=base_schema,
adprep_level=provision_adprep_level,
plaintext_secrets=plaintext_secrets, plaintext_secrets=plaintext_secrets,
backend_store=backend_store, backend_store=backend_store,
backend_store_size=backend_store_size) backend_store_size=backend_store_size)

View File

@ -48,7 +48,6 @@ import samba
from samba import auth from samba import auth
from samba.samba3 import smbd, passdb from samba.samba3 import smbd, passdb
from samba.samba3 import param as s3param from samba.samba3 import param as s3param
from samba.dsdb import DS_DOMAIN_FUNCTION_2000
from samba import ( from samba import (
Ldb, Ldb,
MAX_NETBIOS_NAME_LEN, MAX_NETBIOS_NAME_LEN,
@ -66,8 +65,13 @@ from samba.dcerpc.misc import (
SEC_CHAN_WKSTA, SEC_CHAN_WKSTA,
) )
from samba.dsdb import ( from samba.dsdb import (
DS_DOMAIN_FUNCTION_2000,
DS_DOMAIN_FUNCTION_2003, DS_DOMAIN_FUNCTION_2003,
DS_DOMAIN_FUNCTION_2008,
DS_DOMAIN_FUNCTION_2008_R2, DS_DOMAIN_FUNCTION_2008_R2,
DS_DOMAIN_FUNCTION_2012,
DS_DOMAIN_FUNCTION_2012_R2,
DS_DOMAIN_FUNCTION_2016,
ENC_ALL_TYPES, ENC_ALL_TYPES,
) )
from samba.idmap import IDmapDB from samba.idmap import IDmapDB
@ -2146,7 +2150,7 @@ def provision(logger, session_info, smbconf=None,
sitename=None, serverrole=None, dom_for_fun_level=None, sitename=None, serverrole=None, dom_for_fun_level=None,
useeadb=False, am_rodc=False, lp=None, use_ntvfs=False, useeadb=False, am_rodc=False, lp=None, use_ntvfs=False,
use_rfc2307=False, maxuid=None, maxgid=None, skip_sysvolacl=True, use_rfc2307=False, maxuid=None, maxgid=None, skip_sysvolacl=True,
base_schema="2019", base_schema="2019", adprep_level=DS_DOMAIN_FUNCTION_2016,
plaintext_secrets=False, backend_store=None, plaintext_secrets=False, backend_store=None,
backend_store_size=None, batch_mode=False): backend_store_size=None, batch_mode=False):
"""Provision samba4 """Provision samba4
@ -2159,6 +2163,30 @@ def provision(logger, session_info, smbconf=None,
except ValueError: except ValueError:
raise ProvisioningError('server role (%s) should be one of "active directory domain controller", "member server", "standalone server"' % serverrole) raise ProvisioningError('server role (%s) should be one of "active directory domain controller", "member server", "standalone server"' % serverrole)
if dom_for_fun_level is None:
dom_for_fun_level = DS_DOMAIN_FUNCTION_2008_R2
if base_schema in ["2008_R2", "2008_R2_old"]:
max_adprep_level = DS_DOMAIN_FUNCTION_2008_R2
elif base_schema in ["2012"]:
max_adprep_level = DS_DOMAIN_FUNCTION_2012
elif base_schema in ["2012_R2"]:
max_adprep_level = DS_DOMAIN_FUNCTION_2012_R2
else:
max_adprep_level = DS_DOMAIN_FUNCTION_2016
if max_adprep_level < dom_for_fun_level:
raise ProvisioningError('dom_for_fun_level[%u] incompatible with base_schema[%s]' %
(dom_for_fun_level, base_schema))
if adprep_level is not None and max_adprep_level < adprep_level:
raise ProvisioningError('base_schema[%s] incompatible with adprep_level[%u]' %
(base_schema, adprep_level))
if adprep_level is not None and adprep_level < dom_for_fun_level:
raise ProvisioningError('dom_for_fun_level[%u] incompatible with adprep_level[%u]' %
(dom_for_fun_level, adprep_level))
if ldapadminpass is None: if ldapadminpass is None:
# Make a new, random password between Samba and it's LDAP server # Make a new, random password between Samba and it's LDAP server
ldapadminpass = samba.generate_random_password(128, 255) ldapadminpass = samba.generate_random_password(128, 255)
@ -2337,6 +2365,45 @@ def provision(logger, session_info, smbconf=None,
backend_store=backend_store, backend_store=backend_store,
backend_store_size=backend_store_size) backend_store_size=backend_store_size)
if adprep_level is not None:
updates_allowed_overridden = False
if lp.get("dsdb:schema update allowed") is None:
lp.set("dsdb:schema update allowed", "yes")
print("Temporarily overriding 'dsdb:schema update allowed' setting")
updates_allowed_overridden = True
samdb.transaction_start()
try:
from samba.forest_update import ForestUpdate
forest = ForestUpdate(samdb, fix=True)
forest.check_updates_iterator([11, 54, 79, 80, 81, 82, 83])
forest.check_updates_functional_level(adprep_level,
DS_DOMAIN_FUNCTION_2008_R2,
update_revision=True)
samdb.transaction_commit()
except Exception as e:
samdb.transaction_cancel()
raise e
samdb.transaction_start()
try:
from samba.domain_update import DomainUpdate
domain = DomainUpdate(samdb, fix=True)
domain.check_updates_functional_level(adprep_level,
DS_DOMAIN_FUNCTION_2008,
update_revision=True)
samdb.transaction_commit()
except Exception as e:
samdb.transaction_cancel()
raise e
if updates_allowed_overridden:
lp.set("dsdb:schema update allowed", "no")
if not is_heimdal_built(): if not is_heimdal_built():
create_kdc_conf(paths.kdcconf, realm, domain, os.path.dirname(lp.get("log file"))) create_kdc_conf(paths.kdcconf, realm, domain, os.path.dirname(lp.get("log file")))
logger.info("The Kerberos KDC configuration for Samba AD is " logger.info("The Kerberos KDC configuration for Samba AD is "

View File

@ -233,7 +233,7 @@ def update_policyids(names, samdb):
names.policyid_dc = None names.policyid_dc = None
def newprovision(names, session, smbconf, provdir, logger, base_schema=None): def newprovision(names, session, smbconf, provdir, logger, base_schema=None, adprep_level=None):
"""Create a new provision. """Create a new provision.
This provision will be the reference for knowing what has changed in the This provision will be the reference for knowing what has changed in the
@ -261,7 +261,8 @@ def newprovision(names, session, smbconf, provdir, logger, base_schema=None):
nobody=None, users=None, nobody=None, users=None,
serverrole="domain controller", serverrole="domain controller",
dom_for_fun_level=names.domainlevel, dns_backend=names.dns_backend, dom_for_fun_level=names.domainlevel, dns_backend=names.dns_backend,
useeadb=True, use_ntvfs=True, base_schema=base_schema) useeadb=True, use_ntvfs=True, base_schema=base_schema,
adprep_level=adprep_level)
def dn_sort(x, y): def dn_sort(x, y):

View File

@ -1649,7 +1649,7 @@ if __name__ == '__main__':
provisiondir = tempfile.mkdtemp(dir=paths.private_dir, provisiondir = tempfile.mkdtemp(dir=paths.private_dir,
prefix="referenceprovision") prefix="referenceprovision")
result = newprovision(names, session, smbconf, provisiondir, result = newprovision(names, session, smbconf, provisiondir,
provision_logger, base_schema="2008_R2") provision_logger, base_schema="2008_R2", adprep_level=None)
result.report_logger(provision_logger) result.report_logger(provision_logger)
# TODO # TODO

View File

@ -64,9 +64,9 @@ undump_old()
PROVISION_OPTS="--use-ntvfs --host-ip6=::1 --host-ip=127.0.0.1" PROVISION_OPTS="--use-ntvfs --host-ip6=::1 --host-ip=127.0.0.1"
provision_2019() provision_schema_2019_prep_skip()
{ {
$PYTHON $BINDIR/samba-tool domain provision $PROVISION_OPTS --domain=REALM --realm=REALM.COM --targetdir=$PREFIX_ABS/2019_schema --base-schema=2019 --host-name=FLPREP $PYTHON $BINDIR/samba-tool domain provision $PROVISION_OPTS --domain=REALM --realm=REALM.COM --targetdir=$PREFIX_ABS/2019_schema --base-schema=2019 --adprep-level=SKIP --host-name=FLPREP
} }
provision_2012r2() provision_2012r2()
@ -140,7 +140,7 @@ testit "functional_prep_old" functional_prep_old || failed=$(expr $failed + 1)
cleanup_output_directories cleanup_output_directories
# Provision a DC based on 2019 schema # Provision a DC based on 2019 schema
testit "provision_2019_schema" provision_2019 || failed=$(expr $failed + 1) testit "provision_schema_2019_prep_skip" provision_schema_2019_prep_skip || failed=$(expr $failed + 1)
# Perform functional prep up to 2016 level # Perform functional prep up to 2016 level
testit "functional_prep_2016" functional_prep_2016 || failed=$(expr $failed + 1) testit "functional_prep_2016" functional_prep_2016 || failed=$(expr $failed + 1)

View File

@ -27,7 +27,7 @@ PROVISION_OPTS="--use-ntvfs --host-ip6=::1 --host-ip=127.0.0.1"
provision_2012r2() provision_2012r2()
{ {
$PYTHON $BINDIR/samba-tool domain provision $PROVISION_OPTS --domain=SAMBA --realm=w2012r2.samba.corp --targetdir=$PREFIX_ABS/2012R2_schema --base-schema=2012_R2 $PYTHON $BINDIR/samba-tool domain provision $PROVISION_OPTS --domain=SAMBA --realm=w2012r2.samba.corp --targetdir=$PREFIX_ABS/2012R2_schema --base-schema=2012_R2 --adprep-level=SKIP
} }
provision_2008r2() provision_2008r2()