The branch, master has been updated via 0ef8083cca0 WHATSNEW: Mention new default schema and Functional Level prep via a9d543cdfce s4:kdc: Gate claims, auth policies and NTLM restrctions behind 2012/2016 FLs via c95813374a4 testprogs/blackbox: also raise the levels to 2012_R2/2016 in functionalprep.sh via d2777d47d1e testprogs/blackbox: also prepare for to 2016 (schema=2019) in functionalprep.sh via 205ee77c2fe samba-tool: let 'domain level raise' call check_and_update_fl() in a transaction via 3724ae3e108 samba-tool: move some parts of 'domain level [show|raise]' in to subfunctions via e92988ec946 samba-tool: move some parts of 'domain level [show|raise]' in to try/except via ea2712336b2 samba-tool: let 'domain level raise --domain-level' use the correct crossRef dn via f9f9771a55f samba-tool: check for invalid 'domain level' subcommands first via 1b1895a0d84 samba-tool: Fix missing import for "domain level raise --forest-level=2016" via 48cc2862c28 docs-xml/smbdotconf: also allow 2012[_R2] for 'ad dc functional level' from ad98643fbd9 s4:kdc: Replace FAST cookie with dummy string
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 0ef8083cca0ffdf20d98545fb7e3aa576e661222 Author: Andrew Bartlett <abart...@samba.org> Date: Wed Jun 14 16:14:51 2023 +1200 WHATSNEW: Mention new default schema and Functional Level prep Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Wed Jun 21 20:01:06 UTC 2023 on atb-devel-224 commit a9d543cdfce1d0ff2976a20bb8f15f68d9de0a41 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Mon Apr 3 16:49:50 2023 +1200 s4:kdc: Gate claims, auth policies and NTLM restrctions behind 2012/2016 FLs Samba security features like AD claims, Authentication Policies and Authentication Silos are enabled once the DC is at the required functional level. We comment at the callers of of dsdb_dc_functional_level() to explain why we do this. Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit c95813374a4fa92b446041696baf617d7b19a7f2 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 10:21:32 2023 +0200 testprogs/blackbox: also raise the levels to 2012_R2/2016 in functionalprep.sh Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit d2777d47d1e3beda4295ece6d1c438fab2621925 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 10:21:32 2023 +0200 testprogs/blackbox: also prepare for to 2016 (schema=2019) in functionalprep.sh Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 205ee77c2fe812b71138bbf72ce5b17f238696f1 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 12:07:08 2023 +0200 samba-tool: let 'domain level raise' call check_and_update_fl() in a transaction This makes it possible to raise the levels without starting 'samba' first, which is very useful for blackbox tests. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 3724ae3e1089136e7d3d3f111ab3420be71a7730 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 12:07:08 2023 +0200 samba-tool: move some parts of 'domain level [show|raise]' in to subfunctions This will make it easier to use transactions in the following changes... Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit e92988ec9467e603e5c1aa7f8d337deebbf282dd Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 12:07:08 2023 +0200 samba-tool: move some parts of 'domain level [show|raise]' in to try/except This just adds indentation for now, the following changes will add transactions... Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit ea2712336b28ffda938b4d0b1b17d8eaafb7714d Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 11:57:12 2023 +0200 samba-tool: let 'domain level raise --domain-level' use the correct crossRef dn We should not rely on lp.get('workgroup')... Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit f9f9771a55ffa5cd99b8c3d9228bae6f73938b5d Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 11:07:17 2023 +0200 samba-tool: check for invalid 'domain level' subcommands first This will simplify further changes... Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 1b1895a0d84fb9fc07411adc648527180476bacd Author: Andrew Bartlett <abart...@samba.org> Date: Wed Jun 21 11:43:01 2023 +1200 samba-tool: Fix missing import for "domain level raise --forest-level=2016" Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 48cc2862c289f2b3cf027037fe071fe2e5d81202 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 21 10:31:34 2023 +0200 docs-xml/smbdotconf: also allow 2012[_R2] for 'ad dc functional level' We may not jump to 2016 directly... Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andrew Bartlett <abart...@samba.org> ----------------------------------------------------------------------- Summary of changes: WHATSNEW.txt | 46 +++++++ .../smbdotconf/protocol/addcfunctionallevel.xml | 8 ++ lib/param/param_table.c | 2 + python/samba/netcmd/domain/level.py | 148 +++++++++++++-------- source4/kdc/ad_claims.c | 15 +++ source4/kdc/ad_claims.h | 2 + source4/kdc/authn_policy_util.c | 12 ++ testprogs/blackbox/functionalprep.sh | 41 +++++- 8 files changed, 217 insertions(+), 57 deletions(-) Changeset truncated at 500 lines: diff --git a/WHATSNEW.txt b/WHATSNEW.txt index f760b24ef22..b348217e995 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -45,6 +45,52 @@ trace records belonging to the same request. Field 'depth' allows to track the request nesting level. A new tool samba-log-parser is added for better log parsing. +AD database prepared to FL 2016 standards for new domains +--------------------------------------------------------- + +While Samba still provides only Functional Level 2008R2 by default, +Samba as an AD DC will now, in provision ensure that the blank +database is already prepared for Functional Level 2016, with AD Schema +2019. + +This preparation is of the default objects in the database, adding +containers for Authentication Policies, Authentication Silos and AD +claims in particular. These DB objects must be updated to allow +operation of the new features found in higher functional levels. + +Kerberos Claims, Authentication Silos and NTLM authentication policies +---------------------------------------------------------------------- + +An initial, partial implementation of Active Directory Functional +Level 2012, 2012R2 and 2016 is available in this release. + +While we continue to develop these features, existing domains can +test the feature by selecting the functional level in provision or +raising the DC functional level by setting + + ad dc functional level = 2016 + +in the smb.conf + +The smb.conf file on each DC must have 'ad dc functional level = 2016' +set to have the partially complete feature available. This will also, +at first startup, update the server's own AD entry with the configured +functional level. + +For new domains, add these parameters to 'samba-tool provision' + +--option="ad dc functional level = 2016" --function-level=2016 + +The second option, setting the overall domain functional level +indicates that all DCs should be at this functional level. + +To raise the domain functional level of an existing domain, after +updating the smb.conf and restarting Samba run +samba-tool domain schemaupgrade --schema=2019 +samba-tool domain functionalprep --function-level=2016 +samba-tool domain level raise --domain-level=2016 --forest-level=2016 + + REMOVED FEATURES ================ diff --git a/docs-xml/smbdotconf/protocol/addcfunctionallevel.xml b/docs-xml/smbdotconf/protocol/addcfunctionallevel.xml index 1bec654bfe3..ed2b76bf5d0 100644 --- a/docs-xml/smbdotconf/protocol/addcfunctionallevel.xml +++ b/docs-xml/smbdotconf/protocol/addcfunctionallevel.xml @@ -15,6 +15,14 @@ <para><constant>2008_R2</constant>: Similar to Windows 2008 R2 Functional Level</para> </listitem> + <listitem> + <para><constant>2012</constant>: Similar to Windows + 2012 Functional Level</para> + </listitem> + <listitem> + <para><constant>2012_R2</constant>: Similar to Windows + 2012 R2 Functional Level</para> + </listitem> <listitem> <para><constant>2016</constant>: Similar to Windows 2016 Functional Level</para> diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 820c8abae16..948550e6171 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -433,6 +433,8 @@ static const struct enum_list enum_debug_syslog_format[] = { static const struct enum_list enum_ad_functional_level[] = { {DS_DOMAIN_FUNCTION_2008_R2, "2008_R2"}, + {DS_DOMAIN_FUNCTION_2012, "2012"}, + {DS_DOMAIN_FUNCTION_2012_R2, "2012_R2"}, {DS_DOMAIN_FUNCTION_2016, "2016"}, {-1, NULL} }; diff --git a/python/samba/netcmd/domain/level.py b/python/samba/netcmd/domain/level.py index 4a12a46dff2..c4361eed342 100644 --- a/python/samba/netcmd/domain/level.py +++ b/python/samba/netcmd/domain/level.py @@ -25,7 +25,7 @@ import ldb import samba.getopt as options from samba.auth import system_session -from samba.dsdb import DS_DOMAIN_FUNCTION_2000 +from samba.dsdb import check_and_update_fl, DS_DOMAIN_FUNCTION_2000 from samba.netcmd import Command, CommandError, Option from samba.samdb import SamDB @@ -57,6 +57,9 @@ class cmd_domain_level(Command): def run(self, subcommand, H=None, forest_level=None, domain_level=None, quiet=False, credopts=None, sambaopts=None, versionopts=None): + if subcommand not in ["show", "raise"]: + raise CommandError("invalid argument: '%s' (choose from 'show', 'raise')" % subcommand) + lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) @@ -65,49 +68,70 @@ class cmd_domain_level(Command): domain_dn = samdb.domain_dn() - res_forest = samdb.search("CN=Partitions,%s" % samdb.get_config_basedn(), - scope=ldb.SCOPE_BASE, attrs=["msDS-Behavior-Version"]) - assert len(res_forest) == 1 - - res_domain = samdb.search(domain_dn, scope=ldb.SCOPE_BASE, - attrs=["msDS-Behavior-Version", "nTMixedDomain"]) - assert len(res_domain) == 1 - - res_dc_s = samdb.search("CN=Sites,%s" % samdb.get_config_basedn(), - scope=ldb.SCOPE_SUBTREE, expression="(objectClass=nTDSDSA)", - attrs=["msDS-Behavior-Version"]) - assert len(res_dc_s) >= 1 - - # default values, since "msDS-Behavior-Version" does not exist on Windows 2000 AD - level_forest = DS_DOMAIN_FUNCTION_2000 - level_domain = DS_DOMAIN_FUNCTION_2000 - - if "msDS-Behavior-Version" in res_forest[0]: - level_forest = int(res_forest[0]["msDS-Behavior-Version"][0]) - if "msDS-Behavior-Version" in res_domain[0]: - level_domain = int(res_domain[0]["msDS-Behavior-Version"][0]) - level_domain_mixed = int(res_domain[0]["nTMixedDomain"][0]) - - min_level_dc = None - for msg in res_dc_s: - if "msDS-Behavior-Version" in msg: - if min_level_dc is None or int(msg["msDS-Behavior-Version"][0]) < min_level_dc: - min_level_dc = int(msg["msDS-Behavior-Version"][0]) - else: - min_level_dc = DS_DOMAIN_FUNCTION_2000 - # well, this is the least - break - - if level_forest < DS_DOMAIN_FUNCTION_2000 or level_domain < DS_DOMAIN_FUNCTION_2000: - raise CommandError("Domain and/or forest function level(s) is/are invalid. Correct them or reprovision!") - if min_level_dc < DS_DOMAIN_FUNCTION_2000: - raise CommandError("Lowest function level of a DC is invalid. Correct this or reprovision!") - if level_forest > level_domain: - raise CommandError("Forest function level is higher than the domain level(s). Correct this or reprovision!") - if level_domain > min_level_dc: - raise CommandError("Domain function level is higher than the lowest function level of a DC. Correct this or reprovision!") - - if subcommand == "show": + in_transaction = False + if subcommand == "raise" and not H.startswith("ldap"): + samdb.transaction_start() + in_transaction = True + try: + check_and_update_fl(samdb, lp) + except Exception as e: + samdb.transaction_cancel() + raise e + + try: + res_forest = samdb.search("CN=Partitions,%s" % samdb.get_config_basedn(), + scope=ldb.SCOPE_BASE, attrs=["msDS-Behavior-Version"]) + assert len(res_forest) == 1 + + res_domain = samdb.search(domain_dn, scope=ldb.SCOPE_BASE, + attrs=["msDS-Behavior-Version", "nTMixedDomain"]) + assert len(res_domain) == 1 + + res_domain_cross = samdb.search("CN=Partitions,%s" % samdb.get_config_basedn(), + scope=ldb.SCOPE_SUBTREE, + expression="(&(objectClass=crossRef)(nCName=%s))" % domain_dn, + attrs=["msDS-Behavior-Version"]) + assert len(res_domain_cross) == 1 + + res_dc_s = samdb.search("CN=Sites,%s" % samdb.get_config_basedn(), + scope=ldb.SCOPE_SUBTREE, expression="(objectClass=nTDSDSA)", + attrs=["msDS-Behavior-Version"]) + assert len(res_dc_s) >= 1 + + # default values, since "msDS-Behavior-Version" does not exist on Windows 2000 AD + level_forest = DS_DOMAIN_FUNCTION_2000 + level_domain = DS_DOMAIN_FUNCTION_2000 + + if "msDS-Behavior-Version" in res_forest[0]: + level_forest = int(res_forest[0]["msDS-Behavior-Version"][0]) + if "msDS-Behavior-Version" in res_domain[0]: + level_domain = int(res_domain[0]["msDS-Behavior-Version"][0]) + level_domain_mixed = int(res_domain[0]["nTMixedDomain"][0]) + + min_level_dc = None + for msg in res_dc_s: + if "msDS-Behavior-Version" in msg: + if min_level_dc is None or int(msg["msDS-Behavior-Version"][0]) < min_level_dc: + min_level_dc = int(msg["msDS-Behavior-Version"][0]) + else: + min_level_dc = DS_DOMAIN_FUNCTION_2000 + # well, this is the least + break + + if level_forest < DS_DOMAIN_FUNCTION_2000 or level_domain < DS_DOMAIN_FUNCTION_2000: + raise CommandError("Domain and/or forest function level(s) is/are invalid. Correct them or reprovision!") + if min_level_dc < DS_DOMAIN_FUNCTION_2000: + raise CommandError("Lowest function level of a DC is invalid. Correct this or reprovision!") + if level_forest > level_domain: + raise CommandError("Forest function level is higher than the domain level(s). Correct this or reprovision!") + if level_domain > min_level_dc: + raise CommandError("Domain function level is higher than the lowest function level of a DC. Correct this or reprovision!") + except Exception as e: + if in_transaction: + samdb.transaction_cancel() + raise e + + def do_show(): self.message("Domain and forest function level for domain '%s'" % domain_dn) if level_forest == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed != 0: self.message("\nATTENTION: You run SAMBA 4 on a forest function level lower than Windows 2000 (Native). This isn't supported! Please raise!") @@ -129,10 +153,13 @@ class cmd_domain_level(Command): outstr = functional_level.level_to_string(min_level_dc) self.message("Lowest function level of a DC: (Windows) " + outstr) + return - elif subcommand == "raise": + def do_raise(): msgs = [] + current_level_domain = level_domain + if domain_level is not None: try: new_level_domain = functional_level.string_to_level(domain_level) @@ -154,7 +181,7 @@ class cmd_domain_level(Command): samdb.modify(m) # Under partitions m = ldb.Message() - m.dn = ldb.Dn(samdb, "CN=" + lp.get("workgroup") + ",CN=Partitions,%s" % samdb.get_config_basedn()) + m.dn = res_domain_cross[0].dn m["nTMixedDomain"] = ldb.MessageElement("0", ldb.FLAG_MOD_REPLACE, "nTMixedDomain") try: @@ -173,8 +200,7 @@ class cmd_domain_level(Command): samdb.modify(m) # Under partitions m = ldb.Message() - m.dn = ldb.Dn(samdb, "CN=" + lp.get("workgroup") - + ",CN=Partitions,%s" % samdb.get_config_basedn()) + m.dn = res_domain_cross[0].dn m["msDS-Behavior-Version"] = ldb.MessageElement( str(new_level_domain), ldb.FLAG_MOD_REPLACE, "msDS-Behavior-Version") @@ -185,15 +211,15 @@ class cmd_domain_level(Command): if enum != ldb.ERR_UNWILLING_TO_PERFORM: raise - level_domain = new_level_domain + current_level_domain = new_level_domain msgs.append("Domain function level changed!") if forest_level is not None: - new_level_forest = string_to_level(forest_level) + new_level_forest = functional_level.string_to_level(forest_level) if new_level_forest <= level_forest: raise CommandError("Forest function level can't be smaller than or equal to the actual one!") - if new_level_forest > level_domain: + if new_level_forest > current_level_domain: raise CommandError("Forest function level can't be higher than the domain function level(s). Please raise it/them first!") m = ldb.Message() @@ -205,5 +231,21 @@ class cmd_domain_level(Command): msgs.append("Forest function level changed!") msgs.append("All changes applied successfully!") self.message("\n".join(msgs)) - else: - raise CommandError("invalid argument: '%s' (choose from 'show', 'raise')" % subcommand) + return + + if subcommand == "show": + assert not in_transaction + do_show() + return + elif subcommand == "raise": + try: + do_raise() + except Exception as e: + if in_transaction: + samdb.transaction_cancel() + raise e + if in_transaction: + samdb.transaction_commit() + return + + raise AssertionError("Internal Error subcommand[%s] not handled" % subcommand) diff --git a/source4/kdc/ad_claims.c b/source4/kdc/ad_claims.c index 8cc8d75472d..109bb8a529b 100644 --- a/source4/kdc/ad_claims.c +++ b/source4/kdc/ad_claims.c @@ -37,6 +37,17 @@ #undef strcasecmp +bool ad_claims_are_issued(struct ldb_context *samdb) +{ + /* + * Claims aren’t issued by Samba unless the DC is at + * FL2012. This is to match Windows, which will offer + * this feature as soon as the DC is upgraded. + */ + const int functional_level = dsdb_dc_functional_level(samdb); + return functional_level >= DS_DOMAIN_FUNCTION_2012; +} + static int acl_attr_cmp_fn(const char *a, const char * const *b) { return ldb_attr_cmp(a, *b); @@ -1238,6 +1249,10 @@ int get_claims_for_principal(struct ldb_context *ldb, *claims_blob = data_blob_null; + if (!ad_claims_are_issued(ldb)) { + return LDB_SUCCESS; + } + principal_class_el = ldb_msg_find_element(principal, "objectClass"); if (principal_class_el == NULL) { diff --git a/source4/kdc/ad_claims.h b/source4/kdc/ad_claims.h index 383d25f76aa..bd728ab523b 100644 --- a/source4/kdc/ad_claims.h +++ b/source4/kdc/ad_claims.h @@ -24,6 +24,8 @@ #include "lib/util/data_blob.h" #include "ldb.h" +bool ad_claims_are_issued(struct ldb_context *samdb); + int get_claims_for_principal(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *principal, diff --git a/source4/kdc/authn_policy_util.c b/source4/kdc/authn_policy_util.c index cb53ac209a3..bcbe14804d9 100644 --- a/source4/kdc/authn_policy_util.c +++ b/source4/kdc/authn_policy_util.c @@ -32,12 +32,24 @@ bool authn_policy_silos_and_policies_in_effect(struct ldb_context *samdb) { + /* + * Authentication Silos and Authentication Policies are not + * honoured by Samba unless the DC is at FL 2012 R2. This is + * to match Windows, which will offer these features as soon + * as the DC is upgraded. + */ const int functional_level = dsdb_dc_functional_level(samdb); return functional_level >= DS_DOMAIN_FUNCTION_2012_R2; } bool authn_policy_allowed_ntlm_network_auth_in_effect(struct ldb_context *samdb) { + /* + * The allowed NTLM network authentication Policies are not + * honoured by Samba unless the DC is at FL2016. This + * is to match Windows, which will enforce these restrictions + * as soon as the DC is upgraded. + */ const int functional_level = dsdb_dc_functional_level(samdb); return functional_level >= DS_DOMAIN_FUNCTION_2016; } diff --git a/testprogs/blackbox/functionalprep.sh b/testprogs/blackbox/functionalprep.sh index 477c9c0b972..94099f46d12 100755 --- a/testprogs/blackbox/functionalprep.sh +++ b/testprogs/blackbox/functionalprep.sh @@ -93,16 +93,37 @@ functional_prep_2016() $PYTHON $BINDIR/samba-tool domain functionalprep -H tdb://$PREFIX_ABS/2019_schema/private/sam.ldb --function-level=2016 } +level_raise_2012R2() +{ + $PYTHON $BINDIR/samba-tool domain level raise \ + -H tdb://$PREFIX_ABS/2019_schema/private/sam.ldb \ + --option="ad dc functional level = 2012_R2" \ + --domain-level=2012_R2 --forest-level=2012_R2 +} + +level_raise_2016() +{ + $PYTHON $BINDIR/samba-tool domain level raise \ + -H tdb://$PREFIX_ABS/2019_schema/private/sam.ldb \ + --option="ad dc functional level = 2016" \ + --domain-level=2016 --forest-level=2016 +} + functional_prep_2012R2() { $PYTHON $BINDIR/samba-tool domain functionalprep -H tdb://$PREFIX_ABS/2012R2_schema/private/sam.ldb --function-level=2012_R2 } -functional_prep_old() +functional_prep_2012R2_old() { $PYTHON $BINDIR/samba-tool domain functionalprep -H tdb://$PREFIX_ABS/$OLD_RELEASE/private/sam.ldb --function-level=2012_R2 } +functional_prep_2016_old() +{ + $PYTHON $BINDIR/samba-tool domain functionalprep -H tdb://$PREFIX_ABS/$OLD_RELEASE/private/sam.ldb --function-level=2016 +} + steal_roles() { # Must steal schema master and infrastructure roles first @@ -110,11 +131,16 @@ steal_roles() $PYTHON $BINDIR/samba-tool fsmo seize --role=infrastructure -H tdb://$PREFIX_ABS/$OLD_RELEASE/private/sam.ldb --force } -schema_upgrade() +schema_upgrade_2012R2_old() { $PYTHON $BINDIR/samba-tool domain schemaupgrade -H tdb://$PREFIX_ABS/$OLD_RELEASE/private/sam.ldb --schema=2012_R2 } +schema_upgrade_2019_old() +{ + $PYTHON $BINDIR/samba-tool domain schemaupgrade -H tdb://$PREFIX_ABS/$OLD_RELEASE/private/sam.ldb --schema=2019 +} + # double-check we cleaned up from the last test run cleanup_output_directories @@ -133,9 +159,11 @@ testit $OLD_RELEASE undump_old || failed=$(expr $failed + 1) testit "steal_roles" steal_roles || failed=$(expr $failed + 1) -testit "schema_upgrade" schema_upgrade || failed=$(expr $failed + 1) +testit "schema_upgrade_2012R2_old" schema_upgrade_2012R2_old || failed=$(expr $failed + 1) +testit "functional_prep_2012R2_old" functional_prep_2012R2_old || failed=$(expr $failed + 1) -testit "functional_prep_old" functional_prep_old || failed=$(expr $failed + 1) +testit "schema_upgrade_2019_old" schema_upgrade_2019_old || failed=$(expr $failed + 1) +testit "functional_prep_2016_old" functional_prep_2016_old || failed=$(expr $failed + 1) cleanup_output_directories @@ -145,6 +173,11 @@ testit "provision_schema_2019_prep_skip" provision_schema_2019_prep_skip || fail # Perform functional prep up to 2016 level testit "functional_prep_2016" functional_prep_2016 || failed=$(expr $failed + 1) +# raise the levels to 2012_R2 +testit "level_raise_2012R2" level_raise_2012R2 || failed=$(expr $failed + 1) +# raise the levels to 2016 +testit "level_raise_2016" level_raise_2016 || failed=$(expr $failed + 1) + cleanup_output_directories exit $failed -- Samba Shared Repository