[SCM] Samba Shared Repository - branch master updated

Jelmer Vernooij jelmer at samba.org
Tue Dec 29 08:27:14 MST 2009


The branch, master has been updated
       via  fbb59b2... dsdb: Fix dependencies when building against system ldb.
       via  94454ad... net: Make arguments available to python commands as sys.argv.
       via  588b3e6... python: When updating sys.path to include the Samba python path, avoid throwing away the changes made by site.py.
       via  e2c4d82... s4/net: Allow options before arguments for Python commands.
       via  433f58f... s4/net: Pass all arguments through to the Python commands.
       via  e60a40e... s4/net: Add domainlevel subcommand.
       via  027f6ad... s4/net: Use d_printf consistently when reporting errors.
       via  732a763... Use CommandError exception to deal with problems during net commands.
       via  eaf4a9a... s4/net: Make pwsettings a net subcommand.
       via  8c19cd2... netcmd: Add some basic tests.
       via  9e603dfb.. s4/net: Support parsing arguments in Python commands.
       via  9b1a210... net: Support usage/help of subcommands implemented in Python.
       via  c064549... net: Support implementing subcommands in python.
      from  8b68349... s4:auth: add auth_get_server_info_principal() prototype to auth.h

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit fbb59b2dcac1ce4d952c17d010ebf3bcfca863cd
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Dec 29 16:08:44 2009 +0100

    dsdb: Fix dependencies when building against system ldb.

commit 94454ad07393e1fea0b04ede96fe95893ed2d00e
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Dec 29 16:08:17 2009 +0100

    net: Make arguments available to python commands as sys.argv.

commit 588b3e61812978f73d2708ec37da30726ac8026e
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Dec 29 16:07:54 2009 +0100

    python: When updating sys.path to include the Samba python path, avoid throwing away the changes made by site.py.

commit e2c4d8281d726716a00cfe2e3e0352777fc8b66f
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 21:07:25 2009 +0100

    s4/net: Allow options before arguments for Python commands.

commit 433f58f5a7490ba470dddc55e37325bb73cdba5c
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 20:37:48 2009 +0100

    s4/net: Pass all arguments through to the Python commands.

commit e60a40e287a1febdab98cc6cf81a80a8cb6bcfb2
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 16:48:07 2009 +0100

    s4/net: Add domainlevel subcommand.

commit 027f6ada63b34b5277fa73e5ffa6e436041d9ffb
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 16:06:04 2009 +0100

    s4/net: Use d_printf consistently when reporting errors.

commit 732a7630e9db2578c3a46d0836aaf602e1d5c604
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 16:05:04 2009 +0100

    Use CommandError exception to deal with problems during net commands.

commit eaf4a9afb24f2cc3cd1a268dda4ad37637821f9d
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 16:04:19 2009 +0100

    s4/net: Make pwsettings a net subcommand.

commit 8c19cd2dea470b5f4a981bfbd4b9e33c11bfde39
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 14:17:25 2009 +0100

    netcmd: Add some basic tests.

commit 9e603dfb95f61a7daf2acc80c9c3120ae9ecf98e
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 13:53:18 2009 +0100

    s4/net: Support parsing arguments in Python commands.

commit 9b1a21031187e83de61d999b70a6d1cda7b68444
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Mon Dec 28 01:21:27 2009 +0100

    net: Support usage/help of subcommands implemented in Python.

commit c064549e2e29b1a7e100300fa7d851451a90a6a7
Author: Jelmer Vernooij <jelmer at ganieda.vernstok.nl>
Date:   Mon Dec 28 01:04:33 2009 +0100

    net: Support implementing subcommands in python.

-----------------------------------------------------------------------

Summary of changes:
 source4/auth/credentials/config.mk                 |    2 +-
 source4/dsdb/config.mk                             |    4 +-
 source4/dsdb/samdb/ldb_modules/config.mk           |   17 +-
 source4/script/installmisc.sh                      |    2 +-
 source4/scripting/python/modules.c                 |   43 +++-
 source4/scripting/python/modules.h                 |    2 +-
 source4/scripting/python/samba/getopt.py           |   14 +-
 source4/scripting/python/samba/netcmd/__init__.py  |  128 ++++++++++
 .../scripting/python/samba/netcmd/domainlevel.py   |  229 ++++++++++++++++++
 .../scripting/python/samba/netcmd/pwsettings.py    |  190 +++++++++++++++
 source4/scripting/python/samba/tests/netcmd.py     |   34 +++
 source4/selftest/tests.sh                          |    1 +
 source4/setup/domainlevel                          |  250 --------------------
 source4/setup/pwsettings                           |  198 ----------------
 source4/utils/net/net.c                            |  154 ++++++++++++-
 15 files changed, 794 insertions(+), 474 deletions(-)
 create mode 100644 source4/scripting/python/samba/netcmd/__init__.py
 create mode 100644 source4/scripting/python/samba/netcmd/domainlevel.py
 create mode 100644 source4/scripting/python/samba/netcmd/pwsettings.py
 create mode 100644 source4/scripting/python/samba/tests/netcmd.py
 delete mode 100755 source4/setup/domainlevel
 delete mode 100755 source4/setup/pwsettings


Changeset truncated at 500 lines:

diff --git a/source4/auth/credentials/config.mk b/source4/auth/credentials/config.mk
index 6b051ef..32f415a 100644
--- a/source4/auth/credentials/config.mk
+++ b/source4/auth/credentials/config.mk
@@ -4,7 +4,7 @@
 PUBLIC_DEPENDENCIES = \
 		LIBCLI_AUTH SECRETS LIBCRYPTO KERBEROS UTIL_LDB HEIMDAL_GSSAPI 
 PRIVATE_DEPENDENCIES = \
-		SECRETS
+		SECRETS SAMDB
 
 
 CREDENTIALS_OBJ_FILES = $(addprefix $(authsrcdir)/credentials/, credentials.o credentials_files.o credentials_ntlm.o credentials_krb5.o ../kerberos/kerberos_util.o)
diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk
index dfc5def..c5d1c24 100644
--- a/source4/dsdb/config.mk
+++ b/source4/dsdb/config.mk
@@ -22,7 +22,7 @@ $(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/samdb_proto.h,$(SAMDB_OB
 # PUBLIC_HEADERS += dsdb/samdb/samdb.h
 
 [SUBSYSTEM::SAMDB_COMMON]
-PRIVATE_DEPENDENCIES = LIBLDB
+PRIVATE_DEPENDENCIES = LIBLDB NDR_DRSBLOBS LIBCLI_LDAP_NDR UTIL_LDB LIBCLI_AUTH
 
 SAMDB_COMMON_OBJ_FILES = $(addprefix $(dsdbsrcdir)/common/, \
 		util.o \
@@ -31,7 +31,7 @@ SAMDB_COMMON_OBJ_FILES = $(addprefix $(dsdbsrcdir)/common/, \
 $(eval $(call proto_header_template,$(dsdbsrcdir)/common/proto.h,$(SAMDB_COMMON_OBJ_FILES:.o=.c)))
 
 [SUBSYSTEM::SAMDB_SCHEMA]
-PRIVATE_DEPENDENCIES = SAMDB_COMMON NDR_DRSUAPI NDR_DRSBLOBS
+PRIVATE_DEPENDENCIES = SAMDB_COMMON NDR_DRSUAPI NDR_DRSBLOBS LDBSAMBA
 
 SAMDB_SCHEMA_OBJ_FILES = $(addprefix $(dsdbsrcdir)/schema/, \
 		schema_init.o \
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 3bd3860..6128dc9 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -1,7 +1,7 @@
 ################################################
 # Start SUBSYSTEM DSDB_MODULE_HELPERS
 [SUBSYSTEM::DSDB_MODULE_HELPERS]
-PRIVATE_DEPENDENCIES = LIBLDB
+PRIVATE_DEPENDENCIES = LIBLDB LIBNDR SAMDB_SCHEMA
 
 DSDB_MODULE_HELPERS_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/util.o
 
@@ -12,7 +12,7 @@ $(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/ldb_modules/util_proto.h
 # Start MODULE ldb_samba_dsdb
 [MODULE::ldb_samba_dsdb]
 SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS LIBNDR
+PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS LIBNDR DSDB_MODULE_HELPERS
 INIT_FUNCTION = LDB_MODULE(samba_dsdb)
 # End MODULE ldb_samba_dsdb
 ################################################
@@ -119,7 +119,7 @@ ldb_pdc_fsmo_OBJ_FILES = \
 # Start MODULE ldb_samldb
 [MODULE::ldb_samldb]
 SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE SAMDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE SAMDB DSDB_MODULE_HELPERS
 INIT_FUNCTION = LDB_MODULE(samldb)
 #
 # End MODULE ldb_samldb
@@ -242,7 +242,7 @@ ldb_extended_dn_out_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/extended_dn_out.
 # Start MODULE ldb_extended_dn_store
 [MODULE::ldb_extended_dn_store]
 SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSAMBA-UTIL SAMDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSAMBA-UTIL SAMDB DSDB_MODULE_HELPERS
 INIT_FUNCTION = LDB_MODULE(extended_dn_store)
 # End MODULE ldb_extended_dn_store
 ################################################
@@ -301,7 +301,7 @@ ldb_update_keytab_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/update_keytab.o
 [MODULE::ldb_objectclass]
 INIT_FUNCTION = LDB_MODULE(objectclass)
 CFLAGS = -Ilib/ldb/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSECURITY NDR_SECURITY SAMDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSECURITY NDR_SECURITY SAMDB DSDB_MODULE_HELPERS LIBSAMBA-UTIL
 SUBSYSTEM = LIBLDB
 # End MODULE ldb_objectclass
 ################################################
@@ -325,7 +325,7 @@ ldb_subtree_rename_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/subtree_rename.o
 [MODULE::ldb_subtree_delete]
 INIT_FUNCTION = LDB_MODULE(subtree_delete)
 CFLAGS = -Ilib/ldb/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSAMBA-UTIL
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSAMBA-UTIL DSDB_MODULE_HELPERS
 SUBSYSTEM = LIBLDB
 # End MODULE ldb_subtree_rename
 ################################################
@@ -385,7 +385,7 @@ ldb_instancetype_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/instancetype.o
 [MODULE::ldb_operational]
 SUBSYSTEM = LIBLDB
 CFLAGS = -Ilib/ldb/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT LIBSAMBA-UTIL SAMDB_COMMON DSDB_MODULE_HELPERS
 INIT_FUNCTION = LDB_MODULE(operational)
 # End MODULE ldb_operational
 ################################################
@@ -397,7 +397,8 @@ ldb_operational_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/operational.o
 [MODULE::ldb_descriptor]
 INIT_FUNCTION = LDB_MODULE(descriptor)
 CFLAGS = -Ilib/ldb/include
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSECURITY NDR_SECURITY SAMDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBSECURITY NDR_SECURITY SAMDB \
+	DSDB_MODULE_HELPERS
 SUBSYSTEM = LIBLDB
 # End MODULE ldb_descriptor
 ################################################
diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh
index c25b052..1617ff7 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 enableaccount newuser provision setexpiry setpassword 
 do
 	cp setup/$p $SBINDIR || exit 1
 	chmod a+x $SBINDIR/$p
diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c
index 5365c50..198b3cc 100644
--- a/source4/scripting/python/modules.c
+++ b/source4/scripting/python/modules.c
@@ -61,10 +61,47 @@ void py_load_samba_modules(void)
 	}
 }
 
-void py_update_path(const char *bindir)
+static bool PySys_PathPrepend(PyObject *list, const char *path)
+{
+	PyObject *py_path = PyString_FromString(path);
+	if (py_path == NULL)
+		return false;
+
+	return (PyList_Insert(list, 0, py_path) == 0);
+}
+
+bool py_update_path(const char *bindir)
 {
 	char *newpath;
-	asprintf(&newpath, "%s/python:%s/../scripting/python:%s", bindir, bindir, Py_GetPath());
-	PySys_SetPath(newpath);
+	PyObject *mod_sys, *py_path;
+
+	mod_sys = PyImport_ImportModule("sys");
+	if (mod_sys == NULL) {
+		return false;
+	}
+
+	py_path = PyObject_GetAttrString(mod_sys, "path");
+	if (py_path == NULL) {
+		return false;
+	}	
+
+	if (!PyList_Check(py_path)) {
+		return false;
+	}
+
+	asprintf(&newpath, "%s/../scripting/python", bindir);
+	if (!PySys_PathPrepend(py_path, newpath)) {
+		free(newpath);
+		return false;
+	}
 	free(newpath);
+
+	asprintf(&newpath, "%s/python", bindir);
+	if (!PySys_PathPrepend(py_path, newpath)) {
+		free(newpath);
+		return false;
+	}
+	free(newpath);
+
+	return true;
 }
diff --git a/source4/scripting/python/modules.h b/source4/scripting/python/modules.h
index 6b242ee..4d1067c 100644
--- a/source4/scripting/python/modules.h
+++ b/source4/scripting/python/modules.h
@@ -21,7 +21,7 @@
 #define __SAMBA_PYTHON_MODULES_H__
 
 void py_load_samba_modules(void);
-void py_update_path(const char *bindir);
+bool py_update_path(const char *bindir);
 
 #define py_iconv_convenience(mem_ctx) smb_iconv_convenience_init(mem_ctx, "ASCII", PyUnicode_GetDefaultEncoding(), true)
 
diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py
index 8b756b2..48d48dc 100644
--- a/source4/scripting/python/samba/getopt.py
+++ b/source4/scripting/python/samba/getopt.py
@@ -2,17 +2,17 @@
 
 # Samba-specific bits for optparse
 # Copyright (C) Jelmer Vernooij <jelmer at samba.org> 2007
-#   
+#
 # 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/>.
 #
@@ -30,7 +30,7 @@ class SambaOptions(optparse.OptionGroup):
     def __init__(self, parser):
         optparse.OptionGroup.__init__(self, parser, "Samba Common Options")
         self.add_option("-s", "--configfile", action="callback",
-                        type=str, metavar="FILE", help="Configuration file", 
+                        type=str, metavar="FILE", help="Configuration file",
                         callback=self._load_configfile)
         self._configfile = None
 
@@ -73,15 +73,15 @@ class CredentialsOptions(optparse.OptionGroup):
                         help="DN to use for a simple bind")
         self.add_option("--password", metavar="PASSWORD", action="callback",
                         help="Password", type=str, callback=self._set_password)
-        self.add_option("-U", "--username", metavar="USERNAME", 
+        self.add_option("-U", "--username", metavar="USERNAME",
                         action="callback", type=str,
                         help="Username", callback=self._parse_username)
-        self.add_option("-W", "--workgroup", metavar="WORKGROUP", 
+        self.add_option("-W", "--workgroup", metavar="WORKGROUP",
                         action="callback", type=str,
                         help="Workgroup", callback=self._parse_workgroup)
         self.add_option("-N", "--no-pass", action="store_true",
                         help="Don't ask for a password")
-        self.add_option("-k", "--kerberos", metavar="KERBEROS", 
+        self.add_option("-k", "--kerberos", metavar="KERBEROS",
                         action="callback", type=str,
                         help="Use Kerberos", callback=self._set_kerberos)
         self.creds = Credentials()
diff --git a/source4/scripting/python/samba/netcmd/__init__.py b/source4/scripting/python/samba/netcmd/__init__.py
new file mode 100644
index 0000000..1a04210
--- /dev/null
+++ b/source4/scripting/python/samba/netcmd/__init__.py
@@ -0,0 +1,128 @@
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation.
+# Copyright (C) Jelmer Vernooij <jelmer at samba.org> 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 <http://www.gnu.org/licenses/>.
+#
+
+import optparse
+from samba import getopt as options, Ldb
+import sys
+
+
+class Option(optparse.Option):
+    pass
+
+
+class Command(object):
+    """A net command."""
+
+    def _get_description(self):
+        return self.__doc__.splitlines()[0].rstrip("\n")
+
+    def _get_name(self):
+        name = self.__class__.__name__
+        if name.startswith("cmd_"):
+            return name[4:]
+        return name
+
+    name = property(_get_name)
+
+    def usage(self, args):
+        parser, _ = self._create_parser()
+        parser.print_usage()
+
+    description = property(_get_description)
+
+    def _get_synopsis(self):
+        ret = self.name
+        if self.takes_args:
+            ret += " " + " ".join(self.takes_args)
+        return ret
+
+    synopsis = property(_get_synopsis)
+
+    takes_args = []
+    takes_options = []
+    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):
+        parser, optiongroups = self._create_parser()
+        opts, args = parser.parse_args(list(argv))
+        # Filter out options from option groups
+        args = args[1:]
+        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
+        try:
+            return self.run(*args, **kwargs)
+        except CommandError, e:
+            print >>sys.stderr, "ERROR: %s" % e
+            return -1
+
+    def run(self):
+        """Run the command. This should be overriden by all subclasses."""
+        raise NotImplementedError(self.run)
+
+
+class SuperCommand(Command):
+    """A command with subcommands."""
+
+    subcommands = {}
+
+    def run(self, subcommand, *args, **kwargs):
+        if not subcommand in subcommands:
+            print >>sys.stderr, "ERROR: No such subcommand '%s'" % subcommand
+            return subcommands[subcommand].run(*args, **kwargs)
+
+    def usage(self, subcommand=None, *args, **kwargs):
+        if subcommand is None:
+            print "Available subcommands"
+            for subcommand in subcommands:
+                print "\t%s" % subcommand
+            return 0
+        else:
+            if not subcommand in subcommands:
+                print >>sys.stderr, "ERROR: No such subcommand '%s'" % subcommand
+            return subcommands[subcommand].usage(*args, **kwargs)
+
+
+class CommandError(Exception):
+    pass
+
+
+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 0000000..1c12bde
--- /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 <http://www.gnu.org/licenses/>.
+#
+
+# 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 <options>)"
+
+    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!")


-- 
Samba Shared Repository


More information about the samba-cvs mailing list