choices=["2008_R2", "2008_R2_old", "2012", "2012_R2", "2016", "2019"],
help="The base schema files to use. Default is (Windows) 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,
help="The initial nextRid value (only needed for upgrades). Default is 1000."),
Option("--partitions-only",
blank=None,
server_role=None,
function_level=None,
+ adprep_level=None,
next_rid=None,
partitions_only=None,
targetdir=None,
elif function_level == "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:
dns_forwarder = suggested_forwarder
useeadb=eadb, next_rid=next_rid, lp=lp, use_ntvfs=use_ntvfs,
use_rfc2307=use_rfc2307, skip_sysvolacl=False,
base_schema=base_schema,
+ adprep_level=provision_adprep_level,
plaintext_secrets=plaintext_secrets,
backend_store=backend_store,
backend_store_size=backend_store_size)
from samba import auth
from samba.samba3 import smbd, passdb
from samba.samba3 import param as s3param
-from samba.dsdb import DS_DOMAIN_FUNCTION_2000
from samba import (
Ldb,
MAX_NETBIOS_NAME_LEN,
SEC_CHAN_WKSTA,
)
from samba.dsdb import (
+ DS_DOMAIN_FUNCTION_2000,
DS_DOMAIN_FUNCTION_2003,
+ DS_DOMAIN_FUNCTION_2008,
DS_DOMAIN_FUNCTION_2008_R2,
+ DS_DOMAIN_FUNCTION_2012,
+ DS_DOMAIN_FUNCTION_2012_R2,
+ DS_DOMAIN_FUNCTION_2016,
ENC_ALL_TYPES,
)
from samba.idmap import IDmapDB
sitename=None, serverrole=None, dom_for_fun_level=None,
useeadb=False, am_rodc=False, lp=None, use_ntvfs=False,
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,
backend_store_size=None, batch_mode=False):
"""Provision samba4
except ValueError:
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:
# Make a new, random password between Samba and it's LDAP server
ldapadminpass = samba.generate_random_password(128, 255)
backend_store=backend_store,
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():
create_kdc_conf(paths.kdcconf, realm, domain, os.path.dirname(lp.get("log file")))
logger.info("The Kerberos KDC configuration for Samba AD is "
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.
This provision will be the reference for knowing what has changed in the
nobody=None, users=None,
serverrole="domain controller",
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):