summaryrefslogtreecommitdiff
path: root/source4/scripting
diff options
context:
space:
mode:
Diffstat (limited to 'source4/scripting')
-rw-r--r--source4/scripting/python/pyglue.c74
-rw-r--r--source4/scripting/python/samba/__init__.py8
-rw-r--r--source4/scripting/python/samba/getopt.py2
-rw-r--r--source4/scripting/python/samba/idmap.py2
-rw-r--r--source4/scripting/python/samba/ms_schema.py1
-rw-r--r--source4/scripting/python/samba/provision.py27
-rw-r--r--source4/scripting/python/samba/samba3.py4
-rw-r--r--source4/scripting/python/samba/samdb.py8
-rw-r--r--source4/scripting/python/samba/tests/shares.py74
-rw-r--r--source4/scripting/python/samba/upgrade.py9
10 files changed, 191 insertions, 18 deletions
diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c
index 5816d9637d..0869d2feac 100644
--- a/source4/scripting/python/pyglue.c
+++ b/source4/scripting/python/pyglue.c
@@ -46,6 +46,15 @@
} */\
ldb = PyLdb_AsLdbContext(py_ldb);
+static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+{
+ if (ret == LDB_ERR_PYTHON_EXCEPTION)
+ return; /* Python exception should already be set, just keep that */
+
+ PyErr_SetObject(error,
+ Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
+ ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+}
static PyObject *py_ldb_get_exception(void)
{
@@ -204,6 +213,63 @@ static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+static PyObject *py_dsdb_set_opaque_integer(PyObject *self, PyObject *args)
+{
+ PyObject *py_ldb;
+ int value;
+ int *old_val, *new_val;
+ char *py_opaque_name, *opaque_name_talloc;
+ struct ldb_context *ldb;
+ TALLOC_CTX *tmp_ctx;
+
+ if (!PyArg_ParseTuple(args, "Osi", &py_ldb, &py_opaque_name, &value))
+ return NULL;
+
+ PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+ /* see if we have a cached copy */
+ old_val = (int *)ldb_get_opaque(ldb,
+ py_opaque_name);
+
+ if (old_val) {
+ *old_val = value;
+ Py_RETURN_NONE;
+ }
+
+ tmp_ctx = talloc_new(ldb);
+ if (tmp_ctx == NULL) {
+ goto failed;
+ }
+
+ new_val = talloc(tmp_ctx, int);
+ if (!new_val) {
+ goto failed;
+ }
+
+ opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name);
+ if (!opaque_name_talloc) {
+ goto failed;
+ }
+
+ *new_val = value;
+
+ /* cache the domain_sid in the ldb */
+ if (ldb_set_opaque(ldb, opaque_name_talloc, new_val) != LDB_SUCCESS) {
+ goto failed;
+ }
+
+ talloc_steal(ldb, new_val);
+ talloc_steal(ldb, opaque_name_talloc);
+ talloc_free(tmp_ctx);
+
+ Py_RETURN_NONE;
+
+failed:
+ talloc_free(tmp_ctx);
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set opaque integer into the ldb!\n");
+ return NULL;
+}
+
static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
{
PyObject *py_ldb;
@@ -284,6 +350,8 @@ static PyMethodDef py_misc_methods[] = {
"Register Samba-specific LDB modules and schemas." },
{ "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
NULL },
+ { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
+ NULL },
{ "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
NULL },
{ "dsdb_attach_schema_from_ldif", (PyCFunction)py_dsdb_attach_schema_from_ldif, METH_VARARGS,
@@ -303,5 +371,11 @@ void initglue(void)
return;
PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
+
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2000", PyInt_FromLong(DS_BEHAVIOR_WIN2000));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003_INTERIM", PyInt_FromLong(DS_BEHAVIOR_WIN2003_INTERIM));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003", PyInt_FromLong(DS_BEHAVIOR_WIN2003));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2008", PyInt_FromLong(DS_BEHAVIOR_WIN2008));
+
}
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index 60a7919136..164803bb65 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py
@@ -42,7 +42,6 @@ else:
import ldb
-import credentials
import glue
class Ldb(ldb.Ldb):
@@ -73,6 +72,8 @@ class Ldb(ldb.Ldb):
self.set_modules_dir(modules_dir)
elif default_ldb_modules_dir is not None:
self.set_modules_dir(default_ldb_modules_dir)
+ elif lp is not None:
+ self.set_modules_dir(os.path.join(lp.get("modules dir"), "ldb"))
if credentials is not None:
self.set_credentials(credentials)
@@ -242,3 +243,8 @@ def valid_netbios_name(name):
return True
version = glue.version
+
+DS_BEHAVIOR_WIN2000 = glue.DS_BEHAVIOR_WIN2000
+DS_BEHAVIOR_WIN2003_INTERIM = glue.DS_BEHAVIOR_WIN2003_INTERIM
+DS_BEHAVIOR_WIN2003 = glue.DS_BEHAVIOR_WIN2003
+DS_BEHAVIOR_WIN2008 = glue.DS_BEHAVIOR_WIN2008
diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py
index c12245f6c5..8b756b2d6f 100644
--- a/source4/scripting/python/samba/getopt.py
+++ b/source4/scripting/python/samba/getopt.py
@@ -20,7 +20,7 @@
"""Support for parsing Samba-related command-line options."""
import optparse
-from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS
+from credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS
from hostconfig import Hostconfig
__docformat__ = "restructuredText"
diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py
index f8eeb18925..ee79be1af9 100644
--- a/source4/scripting/python/samba/idmap.py
+++ b/source4/scripting/python/samba/idmap.py
@@ -23,8 +23,6 @@
__docformat__ = "restructuredText"
import samba
-import glue
-import ldb
class IDmapDB(samba.Ldb):
"""The IDmap database."""
diff --git a/source4/scripting/python/samba/ms_schema.py b/source4/scripting/python/samba/ms_schema.py
index 2e8050e503..a0abc337ce 100644
--- a/source4/scripting/python/samba/ms_schema.py
+++ b/source4/scripting/python/samba/ms_schema.py
@@ -226,6 +226,7 @@ def __transform_entry(entry, objectClass):
assert(cn)
entry.insert(0, ["dn", "CN=%s,${SCHEMADN}" % cn])
entry.insert(1, ["objectClass", ["top", objectClass]])
+ entry.insert(2, ["cn", cn])
for l in entry:
key = l[0].lower()
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 189c93a1fc..8a7ed6a86e 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -37,13 +37,13 @@ import param
import registry
import samba
from auth import system_session
-from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
+from samba import version, Ldb, substitute_var, valid_netbios_name, check_all_substituted, \
+ DS_BEHAVIOR_WIN2008
from samba.samdb import SamDB
from samba.idmap import IDmapDB
from samba.dcerpc import security
import urllib
-from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
- timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE
+from ldb import SCOPE_SUBTREE, LdbError, timestring
from ms_schema import read_ms_schema
__docformat__ = "restructuredText"
@@ -729,7 +729,7 @@ def setup_samdb_rootdse(samdb, setup_path, names):
def setup_self_join(samdb, names,
machinepass, dnspass,
domainsid, invocationid, setup_path,
- policyguid):
+ policyguid, domainControllerFunctionality):
"""Join a host to its own domain."""
assert isinstance(invocationid, str)
setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {
@@ -745,7 +745,9 @@ def setup_self_join(samdb, names,
"DNSPASS_B64": b64encode(dnspass),
"REALM": names.realm,
"DOMAIN": names.domain,
- "DNSDOMAIN": names.dnsdomain})
+ "DNSDOMAIN": names.dnsdomain,
+ "SAMBA_VERSION_STRING": version,
+ "DOMAIN_CONTROLLER_FUNCTIONALITY": str(domainControllerFunctionality)})
setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), {
"POLICYGUID": policyguid,
"DNSDOMAIN": names.dnsdomain,
@@ -765,6 +767,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
:note: This will wipe the main SAM database file!
"""
+ domainFunctionality = DS_BEHAVIOR_WIN2008
+ forestFunctionality = DS_BEHAVIOR_WIN2008
+ domainControllerFunctionality = DS_BEHAVIOR_WIN2008
+
erase = (fill != FILL_DRS)
# Also wipes the database
@@ -780,6 +786,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
return samdb
message("Pre-loading the Samba 4 and AD schema")
+
+ samdb.set_opaque_integer("domainFunctionality", domainFunctionality)
+ samdb.set_opaque_integer("forestFunctionality", forestFunctionality)
+ samdb.set_opaque_integer("domainControllerFunctionality", domainControllerFunctionality)
+
samdb.set_domain_sid(str(domainsid))
if serverrole == "domain controller":
samdb.set_invocation_id(invocationid)
@@ -818,6 +829,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"POLICYGUID": policyguid,
"DOMAINDN": names.domaindn,
"DOMAINGUID_MOD": domainguid_mod,
+ "DOMAIN_FUNCTIONALITY": str(domainFunctionality)
})
message("Adding configuration container (permitted to fail)")
@@ -864,7 +876,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"DOMAIN": names.domain,
"SCHEMADN": names.schemadn,
"DOMAINDN": names.domaindn,
- "SERVERDN": names.serverdn
+ "SERVERDN": names.serverdn,
+ "FOREST_FUNCTIONALALITY": str(forestFunctionality)
})
message("Setting up display specifiers")
@@ -908,7 +921,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
dnspass=dnspass,
machinepass=machinepass,
domainsid=domainsid, policyguid=policyguid,
- setup_path=setup_path)
+ setup_path=setup_path, domainControllerFunctionality=domainControllerFunctionality)
except:
samdb.transaction_cancel()
diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py
index c8ddbc8864..179efa2700 100644
--- a/source4/scripting/python/samba/samba3.py
+++ b/source4/scripting/python/samba/samba3.py
@@ -502,7 +502,7 @@ TDBSAM_USER_PREFIX = "USER_"
class LdapSam(object):
"""Samba 3 LDAP passdb backend reader."""
def __init__(self, url):
- self.ldap_url = ldap_url
+ self.ldap_url = url
class TdbSam(TdbDatabase):
@@ -692,7 +692,7 @@ class ParamFile(object):
(k, v) = l.split("=", 1)
self._sections[section][self._sanitize_name(k)] = v
else:
- raise Error("Unable to parser line %d: %r" % (i+1,l))
+ raise Exception("Unable to parser line %d: %r" % (i+1,l))
def get(self, param, section=None):
"""Return the value of a parameter.
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index bc76cd3c5f..6cb2469846 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -231,6 +231,14 @@ userPassword:: %s
"""
glue.dsdb_set_ntds_invocation_id(self, invocation_id)
+ def set_opaque_integer(self, name, value):
+ """Set an integer as an opaque (a flag or other value) value on the database
+
+ :param name: The name for the opaque value
+ :param value: The integer value
+ """
+ glue.dsdb_set_opaque_integer(self, name, value)
+
def setexpiry(self, user, expiry_seconds, noexpiry):
"""Set the account expiry for a user
diff --git a/source4/scripting/python/samba/tests/shares.py b/source4/scripting/python/samba/tests/shares.py
new file mode 100644
index 0000000000..9130c36780
--- /dev/null
+++ b/source4/scripting/python/samba/tests/shares.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation. Tests for shares
+# Copyright (C) Jelmer Vernooij <jelmer@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/>.
+#
+from samba.shares import SharesContainer
+from unittest import TestCase
+
+
+class MockService(object):
+
+ def __init__(self, data):
+ self.data = data
+
+ def __getitem__(self, name):
+ return self.data[name]
+
+
+class MockLoadParm(object):
+
+ def __init__(self, data):
+ self.data = data
+
+ def __getitem__(self, name):
+ return MockService(self.data[name])
+
+ def __contains__(self, name):
+ return name in self.data
+
+ def __len__(self):
+ return len(self.data)
+
+ def services(self):
+ return self.data.keys()
+
+
+class ShareTests(TestCase):
+
+ def _get_shares(self, conf):
+ return SharesContainer(MockLoadParm(conf))
+
+ def test_len_no_global(self):
+ shares = self._get_shares({})
+ self.assertEquals(0, len(shares))
+
+ def test_iter(self):
+ self.assertEquals([], list(self._get_shares({})))
+ self.assertEquals([], list(self._get_shares({"global":{}})))
+ self.assertEquals(["bla"], list(self._get_shares({"global":{}, "bla":{}})))
+
+ def test_len(self):
+ shares = self._get_shares({"global": {}})
+ self.assertEquals(0, len(shares))
+
+ def test_getitem_nonexistant(self):
+ shares = self._get_shares({"global": {}})
+ self.assertRaises(KeyError, shares.__getitem__, "bla")
+
+ def test_getitem_global(self):
+ shares = self._get_shares({"global": {}})
+ self.assertRaises(KeyError, shares.__getitem__, "global")
diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py
index 0c83604e82..81945525e6 100644
--- a/source4/scripting/python/samba/upgrade.py
+++ b/source4/scripting/python/samba/upgrade.py
@@ -9,17 +9,16 @@
__docformat__ = "restructuredText"
-from provision import findnss, provision, FILL_DRS
+from provision import provision, FILL_DRS
import grp
import ldb
import time
import pwd
-import uuid
import registry
from samba import Ldb
-from samba.samdb import SamDB
+from samba.param import LoadParm
-def import_sam_policy(samldb, samba3_policy, domaindn):
+def import_sam_policy(samldb, policy, dn):
"""Import a Samba 3 policy database."""
samldb.modify_ldif("""
dn: %s
@@ -394,7 +393,7 @@ def upgrade_smbconf(oldconf,mark):
kept in the new configuration as "samba3:<name>"
"""
data = oldconf.data()
- newconf = param_init()
+ newconf = LoadParm()
for s in data:
for p in data[s]: