From: Jelmer Vernooij Date: Mon, 28 Dec 2009 15:48:07 +0000 (+0100) Subject: s4/net: Add domainlevel subcommand. X-Git-Tag: samba-4.0.0alpha11~354 X-Git-Url: http://git.samba.org/samba.git/?p=kai%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=e60a40e287a1febdab98cc6cf81a80a8cb6bcfb2 s4/net: Add domainlevel subcommand. --- diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh index c25b052ddef..31ca7e645de 100755 --- a/source4/script/installmisc.sh +++ b/source4/script/installmisc.sh @@ -49,7 +49,7 @@ cp setup/ad-schema/*.txt $SETUPDIR/ad-schema || exit 1 cp setup/display-specifiers/*.txt $SETUPDIR/display-specifiers || exit 1 echo "Installing sbin scripts from setup/*" -for p in domainlevel enableaccount newuser provision setexpiry setpassword pwsettings +for p in domainlevel enableaccount newuser provision setexpiry setpassword do cp setup/$p $SBINDIR || exit 1 chmod a+x $SBINDIR/$p diff --git a/source4/scripting/python/samba/netcmd/__init__.py b/source4/scripting/python/samba/netcmd/__init__.py index 4be8977b452..5c18d29fc3a 100644 --- a/source4/scripting/python/samba/netcmd/__init__.py +++ b/source4/scripting/python/samba/netcmd/__init__.py @@ -39,8 +39,9 @@ class Command(object): name = property(_get_name) - def usage(self): - self.parser.print_usage() + def usage(self, args): + parser, _ = self._create_parser() + parser.print_usage() description = property(_get_description) @@ -54,20 +55,34 @@ class Command(object): takes_args = [] takes_options = [] - takes_optiongroups = [] - - def __init__(self): - self.parser = optparse.OptionParser(self.synopsis) - self.parser.add_options(self.takes_options) - for optiongroup in self.takes_optiongroups: - self.parser.add_option_group(optiongroup(self.parser)) + takes_optiongroups = {} + + def _create_parser(self): + parser = optparse.OptionParser(self.synopsis) + parser.prog = "net" + parser.add_options(self.takes_options) + optiongroups = {} + for name, optiongroup in self.takes_optiongroups.iteritems(): + optiongroups[name] = optiongroup(parser) + parser.add_option_group(optiongroups[name]) + return parser, optiongroups def message(self, text): print text def _run(self, *argv): - opts, args = self.parser.parse_args(list(argv)) - return self.run(*args, **opts.__dict__) + parser, optiongroups = self._create_parser() + opts, args = parser.parse_args(list(argv)) + # Filter out options from option groups + kwargs = dict(opts.__dict__) + for option_group in parser.option_groups: + for option in option_group.option_list: + del kwargs[option.dest] + kwargs.update(optiongroups) + if len(args) < len(self.takes_args): + self.usage(args) + return -1 + return self.run(*args, **kwargs) def run(self): """Run the command. This should be overriden by all subclasses.""" @@ -107,3 +122,5 @@ class CommandError(Exception): commands = {} from samba.netcmd.pwsettings import cmd_pwsettings commands["pwsettings"] = cmd_pwsettings() +from samba.netcmd.domainlevel import cmd_domainlevel +commands["domainlevel"] = cmd_domainlevel() diff --git a/source4/scripting/python/samba/netcmd/domainlevel.py b/source4/scripting/python/samba/netcmd/domainlevel.py new file mode 100644 index 00000000000..1c12bde0c67 --- /dev/null +++ b/source4/scripting/python/samba/netcmd/domainlevel.py @@ -0,0 +1,229 @@ +#!/usr/bin/python +# +# Raises domain and forest function levels +# +# Copyright Matthias Dieter Wallnoefer 2009 +# Copyright Jelmer Vernooij 2009 +# +# 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 . +# + +# Notice: At the moment we have some more checks to do here on the special +# attributes (consider attribute "msDS-Behavior-Version). This is due to the +# fact that we on s4 LDB don't implement their change policy (only certain +# values, only increments possible...) yet. + +import samba.getopt as options +import ldb + +from samba.auth import system_session +from samba.netcmd import ( + Command, + CommandError, + Option, + ) +from samba.samdb import SamDB +from samba import ( + DS_DOMAIN_FUNCTION_2000, + DS_DOMAIN_FUNCTION_2003, + DS_DOMAIN_FUNCTION_2003_MIXED, + DS_DOMAIN_FUNCTION_2008, + DS_DOMAIN_FUNCTION_2008_R2, + DS_DC_FUNCTION_2000, + DS_DC_FUNCTION_2003, + DS_DC_FUNCTION_2008, + DS_DC_FUNCTION_2008_R2, + ) + +class cmd_domainlevel(Command): + """Raises domain and forest function levels.""" + + synopsis = "(show | raise )" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "credopts": options.CredentialsOptions, + "versionopts": options.VersionOptions, + } + + takes_options = [ + Option("-H", help="LDB URL for database or target server", type=str), + Option("--quiet", help="Be quiet", action="store_true"), + Option("--forest", type="choice", choices=["2003", "2008", "2008_R2"], + help="The forest function level (2003 | 2008 | 2008_R2)"), + Option("--domain", type="choice", choices=["2003", "2008", "2008_R2"], + help="The domain function level (2003 | 2008 | 2008_R2)"), + ] + + takes_args = ["subcommand"] + + def run(self, subcommand, H=None, forest=None, domain=None, quiet=False, + credopts=None, sambaopts=None, versionopts=None): + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + + if H is not None: + url = H + else: + url = lp.get("sam database") + + samdb = SamDB(url=url, session_info=system_session(), + credentials=creds, lp=lp) + + domain_dn = SamDB.domain_dn(samdb) + + res_forest = samdb.search("CN=Partitions,CN=Configuration," + domain_dn, + 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,CN=Configuration," + domain_dn, + scope=ldb.SCOPE_SUBTREE, expression="(objectClass=nTDSDSA)", + attrs=["msDS-Behavior-Version"]) + assert(len(res_dc_s) >= 1) + + try: + level_forest = int(res_forest[0]["msDS-Behavior-Version"][0]) + level_domain = int(res_domain[0]["msDS-Behavior-Version"][0]) + level_domain_mixed = int(res_domain[0]["nTMixedDomain"][0]) + + min_level_dc = int(res_dc_s[0]["msDS-Behavior-Version"][0]) # Init value + for msg in res_dc_s: + if int(msg["msDS-Behavior-Version"][0]) < min_level_dc: + min_level_dc = int(msg["msDS-Behavior-Version"][0]) + + if level_forest < 0 or level_domain < 0: + raise CommandError("Domain and/or forest function level(s) is/are invalid. Correct them or reprovision!") + if min_level_dc < 0: + 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 KeyError: + raise CommandError("Could not retrieve the actual domain, forest level and/or lowest DC function level!") + + if subcommand == "show": + self.message("Domain and forest function level for domain '" + domain_dn + "'") + if level_forest < DS_DOMAIN_FUNCTION_2003: + self.message("\nATTENTION: You run SAMBA 4 on a forest function level lower than Windows 2003 (Native). This isn't supported! Please raise!") + if level_domain < DS_DOMAIN_FUNCTION_2003: + self.message("\nATTENTION: You run SAMBA 4 on a domain function level lower than Windows 2003 (Native). This isn't supported! Please raise!") + if min_level_dc < DS_DC_FUNCTION_2003: + self.message("\nATTENTION: You run SAMBA 4 on a lowest function level of a DC lower than Windows 2003. This isn't supported! Please step-up or upgrade the concerning DC(s)!") + + self.message("") + + if level_forest == DS_DOMAIN_FUNCTION_2000: + outstr = "2000" + elif level_forest == DS_DOMAIN_FUNCTION_2003_MIXED: + outstr = "2003 with mixed domains/interim (NT4 DC support)" + elif level_forest == DS_DOMAIN_FUNCTION_2003: + outstr = "2003" + elif level_forest == DS_DOMAIN_FUNCTION_2008: + outstr = "2008" + elif level_forest == DS_DOMAIN_FUNCTION_2008_R2: + outstr = "2008 R2" + else: + outstr = "higher than 2008 R2" + self.message("Forest function level: (Windows) " + outstr) + + if level_domain == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed != 0: + outstr = "2000 mixed (NT4 DC support)" + elif level_domain == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed == 0: + outstr = "2000" + elif level_domain == DS_DOMAIN_FUNCTION_2003_MIXED: + outstr = "2003 with mixed domains/interim (NT4 DC support)" + elif level_domain == DS_DOMAIN_FUNCTION_2003: + outstr = "2003" + elif level_domain == DS_DOMAIN_FUNCTION_2008: + outstr = "2008" + elif level_domain == DS_DOMAIN_FUNCTION_2008_R2: + outstr = "2008 R2" + else: + outstr = "higher than 2008 R2" + self.message("Domain function level: (Windows) " + outstr) + + if min_level_dc == DS_DC_FUNCTION_2000: + outstr = "2000" + elif min_level_dc == DS_DC_FUNCTION_2003: + outstr = "2003" + elif min_level_dc == DS_DC_FUNCTION_2008: + outstr = "2008" + elif min_level_dc == DS_DC_FUNCTION_2008_R2: + outstr = "2008 R2" + else: + outstr = "higher than 2008 R2" + self.message("Lowest function level of a DC: (Windows) " + outstr) + + elif subcommand == "raise": + msgs = [] + + if domain is not None: + if domain == "2003": + new_level_domain = DS_DOMAIN_FUNCTION_2003 + elif domain == "2008": + new_level_domain = DS_DOMAIN_FUNCTION_2008 + elif domain == "2008_R2": + new_level_domain = DS_DOMAIN_FUNCTION_2008_R2 + + if new_level_domain <= level_domain and level_domain_mixed == 0: + raise CommandError("Domain function level can't be smaller equal to the actual one!") + + if new_level_domain > min_level_dc: + raise CommandError("Domain function level can't be higher than the lowest function level of a DC!") + + # Deactivate mixed/interim domain support + if level_domain_mixed != 0: + m = ldb.Message() + m.dn = ldb.Dn(samdb, domain_dn) + m["nTMixedDomain"] = ldb.MessageElement("0", + ldb.FLAG_MOD_REPLACE, "nTMixedDomain") + samdb.modify(m) + m = ldb.Message() + m.dn = ldb.Dn(samdb, domain_dn) + m["msDS-Behavior-Version"]= ldb.MessageElement( + str(new_level_domain), ldb.FLAG_MOD_REPLACE, + "msDS-Behavior-Version") + samdb.modify(m) + level_domain = new_level_domain + msgs.append("Domain function level changed!") + + if forest is not None: + if forest == "2003": + new_level_forest = DS_DOMAIN_FUNCTION_2003 + elif forest == "2008": + new_level_forest = DS_DOMAIN_FUNCTION_2008 + elif forest == "2008_R2": + new_level_forest = DS_DOMAIN_FUNCTION_2008_R2 + if new_level_forest <= level_forest: + raise CommandError("Forest function level can't be smaller equal to the actual one!") + if new_level_forest > 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() + m.dn = ldb.Dn(samdb, "CN=Partitions,CN=Configuration," + + domain_dn) + m["msDS-Behavior-Version"]= ldb.MessageElement( + str(new_level_forest), ldb.FLAG_MOD_REPLACE, + "msDS-Behavior-Version") + samdb.modify(m) + msgs.append("Forest function level changed!") + msgs.append("All changes applied successfully!") + self.message("\n".join(msgs)) + else: + raise CommandError("Wrong argument '%s'!" % subcommand) diff --git a/source4/scripting/python/samba/netcmd/pwsettings.py b/source4/scripting/python/samba/netcmd/pwsettings.py old mode 100755 new mode 100644 index 724c28e5f95..0568ea78e60 --- a/source4/scripting/python/samba/netcmd/pwsettings.py +++ b/source4/scripting/python/samba/netcmd/pwsettings.py @@ -42,11 +42,11 @@ class cmd_pwsettings(Command): synopsis = "(show | set )" - takes_optiongroups = [ - options.SambaOptions, - options.VersionOptions, - options.CredentialsOptions, - ] + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "versionopts": options.VersionOptions, + "credopts": options.CredentialsOptions, + } takes_options = [ Option("-H", help="LDB URL for database or target server", type=str), @@ -63,10 +63,12 @@ class cmd_pwsettings(Command): help="The maximum password age ( | default). Default is 43.", type=str), ] - def run(self, H=None, min_pwd_age=None, max_pwd_age=None, quiet=False, - complexity=None, history_length=None, min_pwd_length=None, - username=None, simple_bind_dn=None, no_pass=None, workgroup=None, - kerberos=None, configfile=None, password=None): + takes_args = ["subcommand"] + + def run(self, subcommand, H=None, min_pwd_age=None, max_pwd_age=None, + quiet=False, complexity=None, history_length=None, + min_pwd_length=None, credopts=None, sambaopts=None, + versionopts=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) @@ -75,12 +77,13 @@ class cmd_pwsettings(Command): else: url = lp.get("sam database") - samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) + samdb = SamDB(url=url, session_info=system_session(), + credentials=creds, lp=lp) domain_dn = SamDB.domain_dn(samdb) res = samdb.search(domain_dn, scope=ldb.SCOPE_BASE, - attrs=["pwdProperties", "pwdHistoryLength", "minPwdLength", "minPwdAge", - "maxPwdAge"]) + attrs=["pwdProperties", "pwdHistoryLength", "minPwdLength", + "minPwdAge", "maxPwdAge"]) assert(len(res) == 1) try: pwd_props = int(res[0]["pwdProperties"][0]) @@ -92,7 +95,7 @@ class cmd_pwsettings(Command): except KeyError: raise CommandError("Could not retrieve password properties!") - if args[0] == "show": + if subcommand == "show": self.message("Password informations for domain '%s'" % domain_dn) self.message("") if pwd_props & DOMAIN_PASSWORD_COMPLEX != 0: @@ -103,7 +106,7 @@ class cmd_pwsettings(Command): self.message("Minimum password length: %d" % min_pwd_len) self.message("Minimum password age (days): %d" % min_pwd_age) self.message("Maximum password age (days): %d" % max_pwd_age) - elif args[0] == "set": + elif subcommand == "set": msgs = [] m = ldb.Message() m.dn = ldb.Dn(samdb, domain_dn) @@ -184,4 +187,4 @@ class cmd_pwsettings(Command): msgs.append("All changes applied successfully!") self.message("\n".join(msgs)) else: - raise CommandError("Wrong argument '" + args[0] + "'!") + raise CommandError("Wrong argument '%s'!" % subcommand) diff --git a/source4/setup/domainlevel b/source4/setup/domainlevel deleted file mode 100755 index c37d811dd83..00000000000 --- a/source4/setup/domainlevel +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/python -# -# Raises domain and forest function levels -# -# Copyright Matthias Dieter Wallnoefer 2009 -# -# 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 . -# - -# Notice: At the moment we have some more checks to do here on the special -# attributes (consider attribute "msDS-Behavior-Version). This is due to the -# fact that we on s4 LDB don't implement their change policy (only certain -# values, only increments possible...) yet. - -import sys - -# Find right directory when running from source tree -sys.path.insert(0, "bin/python") - -import samba.getopt as options -import optparse -import ldb - -from samba.auth import system_session -from samba.samdb import SamDB -from samba import DS_DOMAIN_FUNCTION_2000, DS_DOMAIN_FUNCTION_2003 -from samba import DS_DOMAIN_FUNCTION_2003_MIXED, DS_DOMAIN_FUNCTION_2008 -from samba import DS_DOMAIN_FUNCTION_2008_R2 -from samba import DS_DC_FUNCTION_2000, DS_DC_FUNCTION_2003, DS_DC_FUNCTION_2008 -from samba import DS_DC_FUNCTION_2008_R2 - -parser = optparse.OptionParser("domainlevel (show | raise )") -sambaopts = options.SambaOptions(parser) -parser.add_option_group(sambaopts) -parser.add_option_group(options.VersionOptions(parser)) -credopts = options.CredentialsOptions(parser) -parser.add_option_group(credopts) -parser.add_option("-H", help="LDB URL for database or target server", type=str) -parser.add_option("--quiet", help="Be quiet", action="store_true") -parser.add_option("--forest", type="choice", - choices=["2003", "2008", "2008_R2"], - help="The forest function level (2003 | 2008 | 2008_R2)") -parser.add_option("--domain", type="choice", - choices=["2003", "2008", "2008_R2"], - help="The domain function level (2003 | 2008 | 2008_R2)") -opts, args = parser.parse_args() - -# -# print a message if quiet is not set -# -def message(text): - if not opts.quiet: - print text - -if len(args) == 0: - parser.print_usage() - sys.exit(1) - -lp = sambaopts.get_loadparm() -creds = credopts.get_credentials(lp) - -if opts.H is not None: - url = opts.H -else: - url = lp.get("sam database") - -samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) - -domain_dn = SamDB.domain_dn(samdb) - -res_forest = samdb.search("CN=Partitions,CN=Configuration," + domain_dn, - 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,CN=Configuration," + domain_dn, - scope=ldb.SCOPE_SUBTREE, expression="(objectClass=nTDSDSA)", - attrs=["msDS-Behavior-Version"]) -assert(len(res_dc_s) >= 1) - -try: - level_forest = int(res_forest[0]["msDS-Behavior-Version"][0]) - level_domain = int(res_domain[0]["msDS-Behavior-Version"][0]) - level_domain_mixed = int(res_domain[0]["nTMixedDomain"][0]) - - min_level_dc = int(res_dc_s[0]["msDS-Behavior-Version"][0]) # Init value - for msg in res_dc_s: - if int(msg["msDS-Behavior-Version"][0]) < min_level_dc: - min_level_dc = int(msg["msDS-Behavior-Version"][0]) - - if level_forest < 0 or level_domain < 0: - print >>sys.stderr, "ERROR: Domain and/or forest function level(s) is/are invalid. Correct them or reprovision!" - sys.exit(1) - if min_level_dc < 0: - print >>sys.stderr, "ERROR: Lowest function level of a DC is invalid. Correct this or reprovision!" - sys.exit(1) - if level_forest > level_domain: - print >>sys.stderr, "ERROR: Forest function level is higher than the domain level(s). Correct this or reprovision!" - sys.exit(1) - if level_domain > min_level_dc: - print >>sys.stderr, "ERROR: Domain function level is higher than the lowest function level of a DC. Correct this or reprovision!" - sys.exit(1) - -except KeyError: - print >>sys.stderr, "ERROR: Could not retrieve the actual domain, forest level and/or lowest DC function level!" - if args[0] == "show": - print >>sys.stderr, "So the levels can't be displayed!" - sys.exit(1) - -if args[0] == "show": - message("Domain and forest function level for domain '" + domain_dn + "'") - if level_forest < DS_DOMAIN_FUNCTION_2003: - message("\nATTENTION: You run SAMBA 4 on a forest function level lower than Windows 2003 (Native). This isn't supported! Please raise!") - if level_domain < DS_DOMAIN_FUNCTION_2003: - message("\nATTENTION: You run SAMBA 4 on a domain function level lower than Windows 2003 (Native). This isn't supported! Please raise!") - if min_level_dc < DS_DC_FUNCTION_2003: - message("\nATTENTION: You run SAMBA 4 on a lowest function level of a DC lower than Windows 2003. This isn't supported! Please step-up or upgrade the concerning DC(s)!") - - message("") - - if level_forest == DS_DOMAIN_FUNCTION_2000: - outstr = "2000" - elif level_forest == DS_DOMAIN_FUNCTION_2003_MIXED: - outstr = "2003 with mixed domains/interim (NT4 DC support)" - elif level_forest == DS_DOMAIN_FUNCTION_2003: - outstr = "2003" - elif level_forest == DS_DOMAIN_FUNCTION_2008: - outstr = "2008" - elif level_forest == DS_DOMAIN_FUNCTION_2008_R2: - outstr = "2008 R2" - else: - outstr = "higher than 2008 R2" - message("Forest function level: (Windows) " + outstr) - - if level_domain == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed != 0: - outstr = "2000 mixed (NT4 DC support)" - elif level_domain == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed == 0: - outstr = "2000" - elif level_domain == DS_DOMAIN_FUNCTION_2003_MIXED: - outstr = "2003 with mixed domains/interim (NT4 DC support)" - elif level_domain == DS_DOMAIN_FUNCTION_2003: - outstr = "2003" - elif level_domain == DS_DOMAIN_FUNCTION_2008: - outstr = "2008" - elif level_domain == DS_DOMAIN_FUNCTION_2008_R2: - outstr = "2008 R2" - else: - outstr = "higher than 2008 R2" - message("Domain function level: (Windows) " + outstr) - - if min_level_dc == DS_DC_FUNCTION_2000: - outstr = "2000" - elif min_level_dc == DS_DC_FUNCTION_2003: - outstr = "2003" - elif min_level_dc == DS_DC_FUNCTION_2008: - outstr = "2008" - elif min_level_dc == DS_DC_FUNCTION_2008_R2: - outstr = "2008 R2" - else: - outstr = "higher than 2008 R2" - message("Lowest function level of a DC: (Windows) " + outstr) - -elif args[0] == "raise": - msgs = [] - - if opts.domain is not None: - arg = opts.domain - - if arg == "2003": - new_level_domain = DS_DOMAIN_FUNCTION_2003 - elif arg == "2008": - new_level_domain = DS_DOMAIN_FUNCTION_2008 - elif arg == "2008_R2": - new_level_domain = DS_DOMAIN_FUNCTION_2008_R2 - - if new_level_domain <= level_domain and level_domain_mixed == 0: - print >>sys.stderr, "ERROR: Domain function level can't be smaller equal to the actual one!" - sys.exit(1) - - if new_level_domain > min_level_dc: - print >>sys.stderr, "ERROR: Domain function level can't be higher than the lowest function level of a DC!" - sys.exit(1) - - # Deactivate mixed/interim domain support - if level_domain_mixed != 0: - m = ldb.Message() - m.dn = ldb.Dn(samdb, domain_dn) - m["nTMixedDomain"] = ldb.MessageElement("0", - ldb.FLAG_MOD_REPLACE, "nTMixedDomain") - samdb.modify(m) - - m = ldb.Message() - m.dn = ldb.Dn(samdb, domain_dn) - m["msDS-Behavior-Version"]= ldb.MessageElement( - str(new_level_domain), ldb.FLAG_MOD_REPLACE, - "msDS-Behavior-Version") - samdb.modify(m) - - level_domain = new_level_domain - - msgs.append("Domain function level changed!") - - if opts.forest is not None: - arg = opts.forest - - if arg == "2003": - new_level_forest = DS_DOMAIN_FUNCTION_2003 - elif arg == "2008": - new_level_forest = DS_DOMAIN_FUNCTION_2008 - elif arg == "2008_R2": - new_level_forest = DS_DOMAIN_FUNCTION_2008_R2 - - if new_level_forest <= level_forest: - print >>sys.stderr, "ERROR: Forest function level can't be smaller equal to the actual one!" - sys.exit(1) - - if new_level_forest > level_domain: - print >>sys.stderr, "ERROR: Forest function level can't be higher than the domain function level(s). Please raise it/them first!" - sys.exit(1) - - m = ldb.Message() - m.dn = ldb.Dn(samdb, "CN=Partitions,CN=Configuration," - + domain_dn) - m["msDS-Behavior-Version"]= ldb.MessageElement( - str(new_level_forest), ldb.FLAG_MOD_REPLACE, - "msDS-Behavior-Version") - samdb.modify(m) - - msgs.append("Forest function level changed!") - - msgs.append("All changes applied successfully!") - - message("\n".join(msgs)) -else: - print >>sys.stderr, "ERROR: Wrong argument '" + args[0] + "'!" - sys.exit(1)