From 39adc2418a0586261c6c4aea36f72596c6cf8897 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 13:07:16 +0100 Subject: r26088: Import some native-python python modules and move original python swig torture code to common python directory as well. (This used to be commit cbf656ff054ab2b0b5ca81e1d4f16ac54c8098f1) --- source4/scripting/python/config.mk | 35 + source4/scripting/python/misc.i | 32 + source4/scripting/python/parammodule.c | 182 +++++ source4/scripting/python/samba/__init__.py | 57 ++ source4/scripting/python/samba/getopt.py | 46 ++ source4/scripting/python/samba/samr.py | 753 +++++++++++++++++++++ source4/scripting/python/samba/torture/pytorture | 51 ++ source4/scripting/python/samba/torture/spoolss.py | 437 ++++++++++++ .../scripting/python/samba/torture/torture_samr.py | 221 ++++++ .../scripting/python/samba/torture/torture_tdb.py | 90 +++ source4/scripting/python/samba/torture/winreg.py | 165 +++++ source4/scripting/python/sidmodule.c | 57 ++ source4/scripting/python/uuidmodule.c | 57 ++ 13 files changed, 2183 insertions(+) create mode 100644 source4/scripting/python/config.mk create mode 100644 source4/scripting/python/misc.i create mode 100644 source4/scripting/python/parammodule.c create mode 100644 source4/scripting/python/samba/__init__.py create mode 100644 source4/scripting/python/samba/getopt.py create mode 100644 source4/scripting/python/samba/samr.py create mode 100755 source4/scripting/python/samba/torture/pytorture create mode 100644 source4/scripting/python/samba/torture/spoolss.py create mode 100755 source4/scripting/python/samba/torture/torture_samr.py create mode 100755 source4/scripting/python/samba/torture/torture_tdb.py create mode 100755 source4/scripting/python/samba/torture/winreg.py create mode 100644 source4/scripting/python/sidmodule.c create mode 100644 source4/scripting/python/uuidmodule.c (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk new file mode 100644 index 0000000000..1c9ffb20ac --- /dev/null +++ b/source4/scripting/python/config.mk @@ -0,0 +1,35 @@ +[PYTHON::python_param] +PRIVATE_DEPENDENCIES = LIBSAMBA-CONFIG +OBJ_FILES = parammodule.o + +[PYTHON::python_uuid] +PRIVATE_DEPENDENCIES = LIBNDR +OBJ_FILES = uuidmodule.o + +[PYTHON::python_sid] +PRIVATE_DEPENDENCIES = LIBNDR +OBJ_FILES = sidmodule.o + +[PYTHON::python_misc] +PRIVATE_DEPENDENCIES = LIBNDR LIBLDB +SWIG_FILE = misc.i + +# Swig extensions +swig: pythonmods + +.SUFFIXES: _wrap.c .i + +.i_wrap.c: + swig -Wall -I$(srcdir)/scripting/swig -python $< + +clean:: + @echo "Removing SWIG output files" + @-rm -f bin/python/* + # FIXME: Remove _wrap.c files + # +pythonmods: $(PYTHON_DSOS) + +PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py + +pydoctor:: pythonmods + LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i new file mode 100644 index 0000000000..088522320e --- /dev/null +++ b/source4/scripting/python/misc.i @@ -0,0 +1,32 @@ +/* + Unix SMB/CIFS implementation. + Copyright (C) Jelmer Vernooij 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 . +*/ + +%module(package="samba.misc") misc + +%{ +#include "includes.h" +#include "ldb.h" +#include "auth/credentials/credentials.h" +%} + +%import "stdint.i" +%import "../../lib/talloc/talloc.i" + +%rename(random_password) generate_random_str; +char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); + diff --git a/source4/scripting/python/parammodule.c b/source4/scripting/python/parammodule.c new file mode 100644 index 0000000000..38d312cf1d --- /dev/null +++ b/source4/scripting/python/parammodule.c @@ -0,0 +1,182 @@ +/* + Unix SMB/CIFS implementation. + + Python wrapper for reading smb.conf files + + Copyright (C) Jelmer Vernooij 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "scripting/python/talloc.h" +#include "Python.h" +#include "param/param.h" + +staticforward PyTypeObject param_ParamFileType; + +typedef struct { + PyObject_HEAD + struct param_context *param_ctx; +} param_ParamFileObject; + +static param_ParamFileObject *py_param_init(void) +{ + param_ParamFileObject *param; + + param = PyObject_New(param_ParamFileObject, ¶m_ParamFileType); + + param->param_ctx = param_init(NULL); + + return param; +} + +static PyObject *py_param_load(PyObject *self, PyObject *args) +{ + char *filename = NULL; + param_ParamFileObject *param; + + if (!PyArg_ParseTuple(args, "|s:new", &filename)) + return NULL; + + param = py_param_init(); + + if (filename != NULL) { + int ret = param_read(param->param_ctx, filename); + + if (ret == -1) { + PyErr_SetString(PyExc_TypeError, "reading file failed"); + return NULL; + } + } + + return (PyObject *)param; +} + +static void +param_dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +static PyObject *py_param_get(PyObject *_self, PyObject *args) +{ + struct param_opt *param; + const char *section_name = NULL, *param_name = NULL; + param_ParamFileObject *self = (param_ParamFileObject *)_self; + + if (!PyArg_ParseTuple(args, (char *)"s|s", ¶m_name, §ion_name)) + return NULL; + + param = param_get(self->param_ctx, section_name, param_name); + if (param == NULL) + return Py_None; + + return PyString_FromString(param->value); +} + +static PyObject *py_param_set(PyObject *_self, PyObject *args) +{ + param_ParamFileObject *self = (param_ParamFileObject *)_self; + const char *section_name = NULL, *param_name = NULL, *param_value = NULL; + + if (!PyArg_ParseTuple(args, "ss|s", ¶m_name, ¶m_value, §ion_name)) + return NULL; + + if (section_name == NULL) + section_name = GLOBAL_NAME; + + if (param_set_string(self->param_ctx, section_name, param_name, param_value) != 0) { + PyErr_SetString(PyExc_TypeError, "setting variable failed"); + return NULL; + } + + return Py_None; +} + +static PyObject *py_param_save(PyObject *_self, PyObject *args) +{ + param_ParamFileObject *self = (param_ParamFileObject *)_self; + const char *filename = NULL; + + if (!PyArg_ParseTuple(args, "s", &filename)) + return NULL; + + if (param_write(self->param_ctx, filename) != 0) { + PyErr_SetString(PyExc_TypeError, "unable to save"); + return NULL; + } + + return Py_None; +} + +static PyObject *py_param_use(PyObject *_self, PyObject *args) +{ + param_ParamFileObject *self = (param_ParamFileObject *)_self; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + if (param_use(global_loadparm, self->param_ctx) != 0) { + PyErr_SetString(PyExc_TypeError, "unable to use"); + return NULL; + } + + return Py_None; +} + +static PyMethodDef param_methods[] = { + {"get", (PyCFunction)py_param_get, METH_VARARGS, + "Get a parameter."}, + {"set", (PyCFunction)py_param_set, METH_VARARGS, + "Set a parameter."}, + {"save", (PyCFunction)py_param_save, METH_VARARGS, + "Save file" }, + {"use", (PyCFunction)py_param_use, METH_VARARGS, + "Use param file" }, + {NULL, NULL, 0, NULL} +}; + +static PyObject * +param_getattr(PyTypeObject *obj, char *name) +{ + return Py_FindMethod(param_methods, (PyObject *)obj, name); +} + +static PyTypeObject param_ParamFileType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "ParamFile", + .tp_basicsize = sizeof(param_ParamFileObject), + .tp_dealloc = param_dealloc, + .tp_getattr = param_getattr, +}; + + +static PyMethodDef methods[] = { + { "ParamFile", (PyCFunction)py_param_load, METH_VARARGS, NULL}, + { NULL, NULL } +}; + +PyDoc_STRVAR(param_doc, "Simple wrappers around the smb.conf parsers"); + +PyMODINIT_FUNC initparam(void) +{ + PyObject *mod = Py_InitModule3("param", methods, param_doc); + if (mod == NULL) + return; + + PyModule_AddObject(mod, "configfile", + PyString_FromString(lp_configfile(global_loadparm))); +} diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py new file mode 100644 index 0000000000..46d8ff7d37 --- /dev/null +++ b/source4/scripting/python/samba/__init__.py @@ -0,0 +1,57 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Andrew Tridgell 2005 +# Copyright (C) Jelmer Vernooij 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 . +# + +import os +from misc import ldb_set_credentials + +def Ldb(url, session_info=None, credentials=None, modules_dir=None): + """Open a Samba Ldb file. + + This is different from a regular Ldb file in that the Samba-specific + modules-dir is used by default and that credentials and session_info + can be passed through (required by some modules). + """ + import ldb + ret = ldb.Ldb() + if modules_dir is None: + modules_dir = os.path.join(os.getcwd(), "bin", "modules", "ldb") + ret.set_modules_dir(modules_dir) + def samba_debug(level,text): + print "%d %s" % (level, text) + ldb_set_opaque("credentials", credentials) + ret.set_opaque("sessionInfo", session_info) + #ret.set_debug(samba_debug) + ret.connect(url) + return ret + + +def substitute_var(text, values): + """substitute strings of the form ${NAME} in str, replacing + with substitutions from subobj. + + :param text: Text in which to subsitute. + :param values: Dictionary with keys and values. + """ + + for (name, value) in values.items(): + text = text.replace("${%s}" % name, value) + + return text + diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py new file mode 100644 index 0000000000..8143dcafdb --- /dev/null +++ b/source4/scripting/python/samba/getopt.py @@ -0,0 +1,46 @@ +#!/usr/bin/python + +# Samba-specific bits for optparse +# Copyright (C) Jelmer Vernooij 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 . +# + +import optparse +from credentials import Credentials + +class SambaOptions(optparse.OptionGroup): + def __init__(self, parser): + optparse.OptionGroup.__init__(self, parser, "Samba Common Options") + self.add_option("--configfile", type="string", metavar="FILE", + help="Configuration file") + + +class VersionOptions(optparse.OptionGroup): + def __init__(self, parser): + optparse.OptionGroup.__init__(self, parser, "Version Options") + + +class CredentialsOptions(optparse.OptionGroup): + def __init__(self, parser): + optparse.OptionGroup.__init__(self, parser, "Credentials Options") + self.add_option("--simple-bind-dn", type="string", metavar="DN", + help="DN to use for a simple bind") + self.add_option("--password", type="string", metavar="PASSWORD", + help="Password") + + def get_credentials(self): + creds = Credentials() + # FIXME: Update + return creds diff --git a/source4/scripting/python/samba/samr.py b/source4/scripting/python/samba/samr.py new file mode 100644 index 0000000000..314f78b8ad --- /dev/null +++ b/source4/scripting/python/samba/samr.py @@ -0,0 +1,753 @@ +import dcerpc + +def sid_to_string(sid): + """Convert a Python dictionary SID to a string SID.""" + + result = 'S-%d' % sid.sid_rev_num + + result = result + '-%u' % \ + (dcerpc.uint8_array_getitem(sid.id_auth, 5) + + (dcerpc.uint8_array_getitem(sid.id_auth, 4) << 8) + + (dcerpc.uint8_array_getitem(sid.id_auth, 3) << 16) + + (dcerpc.uint8_array_getitem(sid.id_auth, 2) << 24)) + + for i in range(0, sid.num_auths): + result = result + '-%u' % \ + dcerpc.uint32_array_getitem(sid.sub_auths, i) + + return result + +def string_to_sid(string): + """Convert a string SID to a Python dictionary SID. Throws a + ValueError if the SID string was badly formed.""" + + if string[0] != 'S': + raise ValueError('Bad SID format') + + string = string[1:] + + import re + + match = re.match('-\d+', string) + + if not match: + raise ValueError('Bad SID format') + + try: + sid_rev_num = int(string[match.start()+1:match.end()]) + except ValueError: + raise ValueError('Bad SID format') + + string = string[match.end():] + + match = re.match('-\d+', string) + + if not match: + raise ValueError('Bad SID format') + + try: + ia = int(string[match.start()+1:match.end()]) + except ValueError: + raise ValueError('Bad SID format') + + string = string[match.end():] + + id_auth = [0, 0, (ia >> 24) & 0xff, (ia >> 16) & 0xff, + (ia >> 8) & 0xff, ia & 0xff] + + num_auths = 0 + sub_auths = [] + + while len(string): + + match = re.match('-\d+', string) + + if not match: + raise ValueError('Bad SID format') + + try: + sa = int(string[match.start() + 1 : match.end()]) + except ValueError: + raise ValueError('Bad SID format') + + num_auths = num_auths + 1 + sub_auths.append(int(sa)) + + string = string[match.end():] + + sid = dcerpc.dom_sid() + sid.sid_rev_num = sid_rev_num + sid.id_auth = dcerpc.new_uint8_array(6) + for i in range(6): + dcerpc.uint8_array_setitem(sid.id_auth, i, id_auth[i]) + sid.num_auths = num_auths + sid.sub_auths = dcerpc.new_uint32_array(num_auths) + for i in range(num_auths): + dcerpc.uint32_array_setitem(sid.sub_auths, i, sub_auths[i]) + + return sid + +def call_fn(fn, pipe, args): + """Wrap up a RPC call and throw an exception is an error was returned.""" + + result = fn(pipe, args); + + if result & 0xc0000000L: + raise dcerpc.NTSTATUS(result, dcerpc.nt_errstr(result)); + + return result; + +class SamrHandle: + + def __init__(self, pipe, handle): + + self.pipe = pipe + self.handle = handle + + def __del__(self): + + if self.handle is not None: + self.Close() + + def Close(self): + + r = dcerpc.samr_Close() + r.data_in.handle = self.handle + + call_fn(dcerpc.dcerpc_samr_Close, self.pipe, r) + + self.handle = None + + def QuerySecurity(self, sec_info = 7): + + r = dcerpc.samr_QuerySecurity() + r.data_in.handle = self.handle + r.data_in.sec_info = sec_info + + call_fn(dcerpc.dcerpc_samr_QuerySecurity, self.pipe, r) + + return r.data_out.sdbuf + + def SetSecurity(self, sdbuf, sec_info = 7): + + r = dcerpc.samr_SetSecurity() + r.data_in.handle = self.handle + r.data_in.sec_info = sec_info + r.data_in.sdbuf = sdbuf + + call_fn(dcerpc.dcerpc_samr_SetSecurity, self.pipe, r) + +class ConnectHandle(SamrHandle): + + def EnumDomains(self): + + r = dcerpc.samr_EnumDomains() + r.data_in.connect_handle = self.handle + r.data_in.resume_handle = 0 + r.data_in.buf_size = -1 + + domains = [] + + while 1: + + call_fn(dcerpc.dcerpc_samr_EnumDomains, self.pipe, r) + + for i in range(r.data_out.sam.count): + domains.append(dcerpc.samr_SamEntry_array_getitem( + r.data_out.sam.entries, i).name.string) + + # TODO: Handle more entries here + + break + + return domains + + def LookupDomain(self, domain_name): + + r = dcerpc.samr_LookupDomain() + r.data_in.connect_handle = self.handle + r.data_in.domain_name = dcerpc.samr_String() + r.data_in.domain_name.string = domain_name + + call_fn(dcerpc.dcerpc_samr_LookupDomain, self.pipe, r) + + return sid_to_string(r.data_out.sid); + + def OpenDomain(self, domain_sid, access_mask = 0x02000000): + + r = dcerpc.samr_OpenDomain() + r.data_in.connect_handle = self.handle + r.data_in.access_mask = access_mask + r.data_in.sid = string_to_sid(domain_sid) + + call_fn(dcerpc.dcerpc_samr_OpenDomain, self.pipe, r) + + return DomainHandle(self.pipe, r.data_out.domain_handle) + + def Shutdown(self): + + r = dcerpc.samr_Shutdown() + r.data_in.connect_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_Shutdown, self.pipe, r) + + def GetDomPwInfo(self, domain_name): + + r = dcerpc.samr_GetDomPwInfo() + r.data_in.domain_name = dcerpc.samr_String() + r.data_in.domain_name.string = domain_name + + call_fn(dcerpc.dcerpc_samr_GetDomPwInfo, self.pipe, r) + + return r.data_out.info + + + def SetBootKeyInformation(self, unknown1, unknown2, unknown3): + + r = dcerpc.samr_GetBootKeyInformation() + r.data_in.connect_handle = self.handle + r.data_in.unknown1 = unknown1 + r.data_in.unknown2 = unknown2 + r.data_in.unknown3 = unknown3 + + call_fn(dcerpc.dcerpc_samr_SetBootKeyInformation, self.pipe, r) + +class DomainHandle(SamrHandle): + + def QueryDomainInfo(self, level = 2): + + r = dcerpc.samr_QueryDomainInfo() + r.data_in.domain_handle = self.handle + r.data_in.level = level + + call_fn(dcerpc.dcerpc_samr_QueryDomainInfo, self.pipe, r) + + return getattr(r.data_out.info, 'info%d' % level) + + def QueryDomainInfo2(self, level = 2): + + r = dcerpc.samr_QueryDomainInfo2() + r.data_in.domain_handle = self.handle + r.data_in.level = level + + call_fn(dcerpc.dcerpc_samr_QueryDomainInfo2, self.pipe, r) + + return getattr(r.data_out.info, 'info%d' % level) + + def SetDomainInfo(self, level, info): + + r = dcerpc.samr_SetDomainInfo() + r.data_in.domain_handle = self.handle + r.data_in.level = level + r.data_in.info = dcerpc.samr_DomainInfo() + setattr(r.data_in.info, 'info%d' % level, info) + + call_fn(dcerpc.dcerpc_samr_SetDomainInfo, self.pipe, r) + + def EnumDomainGroups(self): + + r = dcerpc.samr_EnumDomainGroups() + r.data_in.domain_handle = self.handle + r.data_in.resume_handle = 0 + r.data_in.max_size = 1000 + + call_fn(dcerpc.dcerpc_samr_EnumDomainGroups, self.pipe, r) + + groups = [] + + if r.data_out.sam.entries: + for i in range(r.data_out.sam.count): + groups.append(dcerpc.samr_SamEntry_array_getitem( + r.data_out.sam.entries, i).name.string) + + return groups + + def EnumDomainAliases(self): + + r = dcerpc.samr_EnumDomainAliases() + r.data_in.domain_handle = self.handle + r.data_in.resume_handle = 0 + # acct_flags in SamrEnumerateAliasesInDomain has probably + # no meaning so use 0xffffffff like W2K + r.data_in.acct_flags = 0xffffffffL + + call_fn(dcerpc.dcerpc_samr_EnumDomainAliases, self.pipe, r) + + aliases = [] + + if r.data_out.sam.entries: + for i in range(r.data_out.sam.count): + aliases.append(dcerpc.samr_SamEntry_array_getitem( + r.data_out.sam.entries, i).name.string) + + return aliases + + def EnumDomainUsers(self, user_account_flags = 16): + + r = dcerpc.samr_EnumDomainUsers() + r.data_in.domain_handle = self.handle + r.data_in.resume_handle = 0 + r.data_in.acct_flags = user_account_flags + r.data_in.max_size = 1000 + + call_fn(dcerpc.dcerpc_samr_EnumDomainUsers, self.pipe, r) + + users = [] + + if r.data_out.sam.entries: + for i in range(r.data_out.sam.count): + users.append(dcerpc.samr_SamEntry_array_getitem( + r.data_out.sam.entries, i).name.string) + + return users + + def CreateUser(self, account_name, access_mask = 0x02000000): + + r = dcerpc.samr_CreateUser() + r.data_in.domain_handle = self.handle + r.data_in.account_name = dcerpc.samr_String() + r.data_in.account_name.string = account_name + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_CreateUser, self.pipe, r) + + return (r.data_out.user_handle, + dcerpc.uint32_array_getitem(r.data_out.rid, 0)) + + def CreateUser2(self, account_name, acct_flags = 0x00000010, + access_mask = 0x02000000): + + r = dcerpc.samr_CreateUser2() + r.data_in.domain_handle = self.handle + r.data_in.account_name = dcerpc.samr_String() + r.data_in.account_name.string = account_name + r.data_in.acct_flags = acct_flags + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_CreateUser2, self.pipe, r) + + return (r.data_out.user_handle, + dcerpc.uint32_array_getitem(r.data_out.access_granted, 0), + dcerpc.uint32_array_getitem(r.data_out.rid, 0)) + + def OpenUser(self, rid, access_mask = 0x02000000): + + r = dcerpc.samr_OpenUser() + r.data_in.domain_handle = self.handle + r.data_in.access_mask = access_mask + r.data_in.rid = rid + + call_fn(dcerpc.dcerpc_samr_OpenUser, self.pipe, r) + + return UserHandle(self.pipe, r.data_out.user_handle) + + def OpenGroup(self, rid, access_mask = 0x02000000): + + r = dcerpc.samr_OpenGroup() + r.data_in.domain_handle = self.handle + r.data_in.access_mask = access_mask + r.data_in.rid = rid + + call_fn(dcerpc.dcerpc_samr_OpenGroup, self.pipe, r) + + return GroupHandle(self.pipe, r.data_out.group_handle) + + def OpenAlias(self, rid, access_mask = 0x02000000): + + r = dcerpc.samr_OpenAlias() + r.data_in.domain_handle = self.handle + r.data_in.access_mask = access_mask + r.data_in.rid = rid + + call_fn(dcerpc.dcerpc_samr_OpenAlias, self.pipe, r) + + return AliasHandle(self.pipe, r.data_out.alias_handle) + + def CreateDomAlias(self, alias_name, access_mask = 0x02000000): + + r = dcerpc.samr_CreateDomAlias() + r.data_in.domain_handle = self.handle + r.data_in.alias_name = dcerpc.samr_String() + r.data_in.alias_name.string = alias_name + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_CreateDomAlias, self.pipe, r) + + return (AliasHandle(self.pipe, r.data_out.alias_handle), + r.data_out.rid) + + def RidToSid(self, rid): + + r = dcerpc.samr_RidToSid() + r.data_in.domain_handle = self.handle + r.data_in.rid = rid + + call_fn(dcerpc.dcerpc_samr_RidToSid, self.pipe, r) + + return sid_to_string(r.data_out.sid) + + def RemoveMemberFromForeignDomain(self, sid): + + r = dcerpc.samr_RemoveMemberFromForeignDomain() + r.data_in.domain_handle = self.handle + r.data_in.sid = sid + + call_fn(dcerpc.dcerpc_samr_RemoveMemberFromForeignDomain, self.pipe, r) + + def LookupNames(self, names): + + r = dcerpc.samr_LookupNames() + r.data_in.domain_handle = self.handle + r.data_in.num_names = len(names) + r.data_in.names = dcerpc.new_samr_String_array(len(names)) + + for i in range(len(names)): + s = dcerpc.samr_String() + s.string = names[i] + dcerpc.samr_String_array_setitem(r.data_in.names, i, s) + + call_fn(dcerpc.dcerpc_samr_LookupNames, self.pipe, r) + + return ([dcerpc.uint32_array_getitem(r.data_out.rids.ids, i) + for i in range(r.data_out.rids.count)], + [dcerpc.uint32_array_getitem(r.data_out.types.ids, i) + for i in range(r.data_out.types.count)]) + + def CreateDomainGroup(self, domain_name, access_mask = 0x02000000): + + r = dcerpc.samr_CreateDomainGroup() + r.data_in.domain_handle = self.handle + r.data_in.name = dcerpc.samr_String() + r.data_in.name.string = domain_name + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_CreateDomainGroup, self.pipe, r) + + def GetAliasMembership(self, sids): + + r = dcerpc.samr_GetAliasMembership() + r.data_in.domain_handle = self.handle + r.data_in.sids = dcerpc.lsa_SidArray() + r.data_in.sids.num_sids = len(sids) + r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids)) + + for i in range(len(sids)): + s = dcerpc.lsa_SidPtr() + s.sid = string_to_sid(sids[i]) + dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s) + + call_fn(dcerpc.dcerpc_samr_GetAliasMembership, self.pipe, r) + + return [r.ids[x] for x in range(r.count)] + + def QueryDisplayInfo(self, level): + + # TODO: Handle more data returns + + r = dcerpc.samr_QueryDisplayInfo() + r.data_in.domain_handle = self.handle + r.data_in.level = level + r.data_in.start_idx = 0 + r.data_in.max_entries = 1000 + r.data_in.buf_size = -1 + + call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo, self.pipe, r) + + # TODO: Return a mapping of the various samr_DispInfo + # structures here. + + return getattr(r.data_out.info, 'info%d' % level) + + def QueryDisplayInfo2(self, level): + + # TODO: Handle more data returns + + r = dcerpc.samr_QueryDisplayInfo2() + r.data_in.domain_handle = self.handle + r.data_in.level = level + r.data_in.start_idx = 0 + r.data_in.max_entries = 1000 + r.data_in.buf_size = -1 + + call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo2, self.pipe, r) + + # TODO: Return a mapping of the various samr_DispInfo + # structures here. + + return getattr(r.data_out.info, 'info%d' % level) + + def QueryDisplayInfo3(self, level): + + # TODO: Handle more data returns + + r = dcerpc.samr_QueryDisplayInfo3() + r.data_in.domain_handle = self.handle + r.data_in.level = level + r.data_in.start_idx = 0 + r.data_in.max_entries = 1000 + r.data_in.buf_size = -1 + + call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo3, self.pipe, r) + + # TODO: Return a mapping of the various samr_DispInfo + # structures here. + + return getattr(r.data_out.info, 'info%d' % level) + + def GetBootKeyInformation(self): + + r = dcerpc.samr_GetBootKeyInformation() + r.data_in.domain_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_GetBootKeyInformation, self.pipe, r) + + return r.data_out.unknown + + def SetBootKeyInformation(self): + + r = dcerpc.samr_GetBootKeyInformation() + r.data_in.domain_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_GetBootKeyInformation, self.pipe, r) + + def TestPrivateFunctionsDomain(self): + + r = dcerpc.samr_TestPrivateFunctionsDomain() + r.data_in.domain_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsDomain, self.pipe, r) + +class UserHandle(SamrHandle): + + def DeleteUser(self): + + r = dcerpc.samr_DeleteUser() + r.data_in.user_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_DeleteUser, self.pipe, r) + + self.handle = None + + def GetUserPwInfo(self): + + r = dcerpc.samr_GetUserPwInfo() + r.data_in.user_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_GetUserPwInfo, self.pipe, r) + + return r.data_out.info + + def QueryUserInfo(self, level): + + r = dcerpc.samr_QueryUserInfo() + r.data_in.user_handle = self.handle + r.data_in.level = level + + call_fn(dcerpc.dcerpc_samr_QueryUserInfo, self.pipe, r) + + return r.data_out.info + + def QueryUserInfo2(self, level): + + r = dcerpc.samr_QueryUserInfo2() + r.data_in.user_handle = self.handle + r.data_in.level = level + + call_fn(dcerpc.dcerpc_samr_QueryUserInfo2, self.pipe, r) + + return r.data_out.info + + def GetGroupsForUser(self): + + r = dcerpc.samr_GetGroupsForUser() + r.data_in.user_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_GetGroupsForUser, self.pipe, r) + + rid_types = [dcerpc.samr_RidType_array_getitem(r.data_out.rids.rid, x) + for x in range(r.data_out.rids.count)] + + return [(x.rid, x.type) for x in rid_types] + + def TestPrivateFunctionsUser(self): + + r = dcerpc.samr_TestPrivateFunctionsUser() + r.data_in.user_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsUser, self.pipe, r) + +class GroupHandle(SamrHandle): + + def QueryGroupInfo(self, level): + + r = dcerpc.samr_QueryGroupInfo() + r.data_in.group_handle = self.handle + r.data_in.level = level + + call_fn(dcerpc.dcerpc_samr_QueryGroupInfo, self.pipe, r) + + return r.data_out.info + + def SetGroupInfo(self, level, info): + + r = dcerpc.samr_SetGroupInfo() + r.data_in.group_handle = self.handle + r.data_in.level = level + r.data_in.info = info + + call_fn(dcerpc.dcerpc_samr_SetGroupInfo, self.pipe, r) + + def QueryGroupMember(self): + + r = dcerpc.samr_QueryGroupMember() + r.data_in.group_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_QueryGroupMember, self.pipe, r) + + return [(dcerpc.uint32_array_getitem(r.data_out.rids.rids, x), + dcerpc.uint32_array_getitem(r.data_out.rids.unknown, x)) + for x in range(r.data_out.rids.count)] + +class AliasHandle(SamrHandle): + + def DeleteDomAlias(self): + + r = dcerpc.samr_DeleteDomAlias() + r.data_in.alias_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_DeleteDomAlias, self.pipe, r) + + self.handle = None + + def QueryAliasInfo(self, level = 1): + + r = dcerpc.samr_QueryAliasInfo() + r.data_in.alias_handle = self.handle + r.data_in.level = level + + call_fn(dcerpc.dcerpc_samr_QueryAliasInfo, self.pipe, r) + + return r.data_out.info + + def SetAliasInfo(self, level, info): + + r = dcerpc.samr_SetAliasInfo() + r.data_in.alias_handle = self.handle + r.data_in.level = level + r.data_in.info = info + + call_fn(dcerpc.dcerpc_samr_SetAliasInfo, self.pipe, r) + + def AddAliasMember(self, sid): + + r = dcerpc.samr_AddAliasMember() + r.data_in.alias_handle = self.handle + r.data_in.sid = string_to_sid(sid) + + call_fn(dcerpc.dcerpc_samr_AddAliasMember, self.pipe, r) + + def AddMultipleMembersToAlias(self, sids): + + r = dcerpc.samr_AddMultipleMembersToAlias() + r.data_in.alias_handle = self.handle + r.data_in.sids = dcerpc.lsa_SidArray() + r.data_in.sids.num_sids = len(sids) + r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids)) + + for i in range(len(sids)): + s = dcerpc.lsa_SidPtr() + s.sid = string_to_sid(sids[i]) + dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s) + + call_fn(dcerpc.dcerpc_samr_AddMultipleMembersToAlias, self.pipe, r) + + def GetMembersInAlias(self): + + r = dcerpc.samr_GetMembersInAlias() + r.data_in.alias_handle = self.handle + + call_fn(dcerpc.dcerpc_samr_GetMembersInAlias, self.pipe, r) + + return [ + sid_to_string( + dcerpc.lsa_SidPtr_array_getitem(r.data_out.sids.sids, x).sid) + for x in range(r.data_out.sids.num_sids)] + +def Connect(pipe, access_mask = 0x02000000): + + r = dcerpc.samr_Connect() + r.data_in.system_name = dcerpc.new_uint16_array(1) + dcerpc.uint16_array_setitem(r.data_in.system_name, 0, ord('\\')) + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_Connect, pipe, r) + + return ConnectHandle(pipe, r.data_out.connect_handle) + +def Connect2(pipe, system_name = '', access_mask = 0x02000000): + """Connect to the SAMR pipe.""" + + r = dcerpc.samr_Connect2() + r.data_in.system_name = system_name + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_Connect2, pipe, r) + + return ConnectHandle(pipe, r.data_out.connect_handle) + +def Connect3(pipe, system_name = '', access_mask = 0x02000000): + + r = dcerpc.samr_Connect3() + r.data_in.system_name = system_name + r.data_in.unknown = 0 + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_Connect3, pipe, r) + + return ConnectHandle(pipe, r.data_out.connect_handle) + + +def Connect4(pipe, system_name = '', access_mask = 0x02000000): + + r = dcerpc.samr_Connect4() + r.data_in.system_name = system_name + r.data_in.unknown = 0 + r.data_in.access_mask = access_mask + + call_fn(dcerpc.dcerpc_samr_Connect4, pipe, r) + + return ConnectHandle(pipe, r.data_out.connect_handle) + +def Connect5(pipe, system_name = '', access_mask = 0x02000000): + + r = dcerpc.samr_Connect5() + r.data_in.system_name = system_name + r.data_in.access_mask = access_mask + r.data_in.level = 1 + r.data_in.info = dcerpc.new_samr_ConnectInfo_array(1) + r.data_in.info.unknown1 = 0 + r.data_in.info.unknown2 = 0 + + call_fn(dcerpc.dcerpc_samr_Connect5, pipe, r) + + return ConnectHandle(pipe, r.data_out.connect_handle) + +# AddGroupMember +# DeleteDomainGroup +# DeleteGroupMember +# SetMemberAttributesofGroup +# AddAliasMember +# DeleteAliasMember +# GetMembersinAlias +# SetUserInfo +# ChangePasswordUser +# GetDisplayEnumerationIndex +# RemoveMemberFromForeignDomain +# GetDisplayEnumerationIndex2 +# RemoveMultipleMembersFromAlias +# OemChangePasswordUser2 +# ChangePasswordUser2 +# SetUserInfo2 +# ChangePasswordUser3 +# SetDsrmPassword +# ValidatePassword diff --git a/source4/scripting/python/samba/torture/pytorture b/source4/scripting/python/samba/torture/pytorture new file mode 100755 index 0000000000..e0123447e8 --- /dev/null +++ b/source4/scripting/python/samba/torture/pytorture @@ -0,0 +1,51 @@ +#!/usr/bin/python + +import sys +from optparse import OptionParser + +# Parse command line + +parser = OptionParser() + +parser.add_option("-b", "--binding", action="store", type="string", + dest="binding") + +parser.add_option("-d", "--domain", action="store", type="string", + dest="domain") + +parser.add_option("-u", "--username", action="store", type="string", + dest="username") + +parser.add_option("-p", "--password", action="store", type="string", + dest="password") + +(options, args) = parser.parse_args() + +if not options.binding: + parser.error('You must supply a binding string') + +if not options.username or not options.password or not options.domain: + parser.error('You must supply a domain, username and password') + +binding = options.binding +domain = options.domain +username = options.username +password = options.password + +if len(args) == 0: + parser.error('You must supply the name of a module to test') + +# Import and test + +for test in args: + + try: + module = __import__('torture_%s' % test) + except ImportError: + print 'No such module "%s"' % test + sys.exit(1) + + if not hasattr(module, 'runtests'): + print 'Module "%s" does not have a runtests function' % test + + module.runtests(binding, (domain, username, password)) diff --git a/source4/scripting/python/samba/torture/spoolss.py b/source4/scripting/python/samba/torture/spoolss.py new file mode 100644 index 0000000000..a75385e079 --- /dev/null +++ b/source4/scripting/python/samba/torture/spoolss.py @@ -0,0 +1,437 @@ +import sys, string +import dcerpc + + +def ResizeBufferCall(fn, pipe, r): + + r['buffer'] = None + r['buf_size'] = 0 + + result = fn(pipe, r) + + if result['result'] == dcerpc.WERR_INSUFFICIENT_BUFFER or \ + result['result'] == dcerpc.WERR_MORE_DATA: + r['buffer'] = result['buf_size'] * '\x00' + r['buf_size'] = result['buf_size'] + + result = fn(pipe, r) + + return result + + +def test_OpenPrinterEx(pipe, printer): + + print 'spoolss_OpenPrinterEx(%s)' % printer + + printername = '\\\\%s' % dcerpc.dcerpc_server_name(pipe) + + if printer is not None: + printername = printername + '\\%s' % printer + + r = {} + r['printername'] = printername + r['datatype'] = None + r['devmode_ctr'] = {} + r['devmode_ctr']['size'] = 0 + r['devmode_ctr']['devmode'] = None + r['access_mask'] = 0x02000000 + r['level'] = 1 + r['userlevel'] = {} + r['userlevel']['level1'] = {} + r['userlevel']['level1']['size'] = 0 + r['userlevel']['level1']['client'] = None + r['userlevel']['level1']['user'] = None + r['userlevel']['level1']['build'] = 1381 + r['userlevel']['level1']['major'] = 2 + r['userlevel']['level1']['minor'] = 0 + r['userlevel']['level1']['processor'] = 0 + + result = dcerpc.spoolss_OpenPrinterEx(pipe, r) + + return result['handle'] + + +def test_ClosePrinter(pipe, handle): + + r = {} + r['handle'] = handle + + dcerpc.spoolss_ClosePrinter(pipe, r) + + +def test_GetPrinter(pipe, handle): + + r = {} + r['handle'] = handle + + for level in [0, 1, 2, 3, 4, 5, 6, 7]: + + print 'spoolss_GetPrinter(level = %d)' % level + + r['level'] = level + r['buffer'] = None + r['buf_size'] = 0 + + result = ResizeBufferCall(dcerpc.spoolss_GetPrinter, pipe, r) + + +def test_EnumForms(pipe, handle): + + print 'spoolss_EnumForms()' + + r = {} + r['handle'] = handle + r['level'] = 1 + r['buffer'] = None + r['buf_size'] = 0 + + result = ResizeBufferCall(dcerpc.spoolss_EnumForms, pipe, r) + + forms = dcerpc.unmarshall_spoolss_FormInfo_array( + result['buffer'], r['level'], result['count']) + + for form in forms: + + r = {} + r['handle'] = handle + r['formname'] = form['info1']['formname'] + r['level'] = 1 + + result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r) + + +def test_EnumPorts(pipe, handle): + + print 'spoolss_EnumPorts()' + + for level in [1, 2]: + + r = {} + r['handle'] = handle + r['servername'] = None + r['level'] = level + + result = ResizeBufferCall(dcerpc.spoolss_EnumPorts, pipe, r) + + ports = dcerpc.unmarshall_spoolss_PortInfo_array( + result['buffer'], r['level'], result['count']) + + if level == 1: + port_names = map(lambda x: x['info1']['port_name'], ports) + + +def test_DeleteForm(pipe, handle, formname): + + r = {} + r['handle'] = handle + r['formname'] = formname + + dcerpc.spoolss_DeleteForm(pipe, r) + + +def test_GetForm(pipe, handle, formname): + + r = {} + r['handle'] = handle + r['formname'] = formname + r['level'] = 1 + + result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r) + + return result['info']['info1'] + + +def test_SetForm(pipe, handle, form): + + print 'spoolss_SetForm()' + + r = {} + r['handle'] = handle + r['level'] = 1 + r['formname'] = form['info1']['formname'] + r['info'] = form + + dcerpc.spoolss_SetForm(pipe, r) + + newform = test_GetForm(pipe, handle, r['formname']) + + if form['info1'] != newform: + print 'SetForm: mismatch: %s != %s' % \ + (r['info']['info1'], f) + sys.exit(1) + + +def test_AddForm(pipe, handle): + + print 'spoolss_AddForm()' + + formname = '__testform__' + + r = {} + r['handle'] = handle + r['level'] = 1 + r['info'] = {} + r['info']['info1'] = {} + r['info']['info1']['formname'] = formname + r['info']['info1']['flags'] = 0x0002 + r['info']['info1']['width'] = 100 + r['info']['info1']['length'] = 100 + r['info']['info1']['left'] = 0 + r['info']['info1']['top'] = 1000 + r['info']['info1']['right'] = 2000 + r['info']['info1']['bottom'] = 3000 + + try: + result = dcerpc.spoolss_AddForm(pipe, r) + except dcerpc.WERROR, arg: + if arg[0] == dcerpc.WERR_ALREADY_EXISTS: + test_DeleteForm(pipe, handle, formname) + result = dcerpc.spoolss_AddForm(pipe, r) + + f = test_GetForm(pipe, handle, formname) + + if r['info']['info1'] != f: + print 'AddForm: mismatch: %s != %s' % \ + (r['info']['info1'], f) + sys.exit(1) + + r['formname'] = formname + + test_SetForm(pipe, handle, r['info']) + + test_DeleteForm(pipe, handle, formname) + + +def test_EnumJobs(pipe, handle): + + print 'spoolss_EnumJobs()' + + r = {} + r['handle'] = handle + r['firstjob'] = 0 + r['numjobs'] = 0xffffffff + r['level'] = 1 + + result = ResizeBufferCall(dcerpc.spoolss_EnumJobs, pipe, r) + + if result['buffer'] is None: + return + + jobs = dcerpc.unmarshall_spoolss_JobInfo_array( + result['buffer'], r['level'], result['count']) + + for job in jobs: + + s = {} + s['handle'] = handle + s['job_id'] = job['info1']['job_id'] + s['level'] = 1 + + result = ResizeBufferCall(dcerpc.spoolss_GetJob, pipe, s) + + if result['info'] != job: + print 'EnumJobs: mismatch: %s != %s' % (result['info'], job) + sys.exit(1) + + + # TODO: AddJob, DeleteJob, ScheduleJob + + +def test_EnumPrinterData(pipe, handle): + + print 'test_EnumPrinterData()' + + enum_index = 0 + + while 1: + + r = {} + r['handle'] = handle + r['enum_index'] = enum_index + + r['value_offered'] = 0 + r['data_size'] = 0 + + result = dcerpc.spoolss_EnumPrinterData(pipe, r) + + r['value_offered'] = result['value_needed'] + r['data_size'] = result['data_size'] + + result = dcerpc.spoolss_EnumPrinterData(pipe, r) + + if result['result'] == dcerpc.WERR_NO_MORE_ITEMS: + break + + s = {} + s['handle'] = handle + s['value_name'] = result['value_name'] + + result2 = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, s) + + if result['buffer'][:result2['buf_size']] != result2['buffer']: + print 'EnumPrinterData/GetPrinterData mismatch' + sys.exit(1) + + enum_index += 1 + + +def test_SetPrinterDataEx(pipe, handle): + + valuename = '__printerdataextest__' + data = '12345' + + r = {} + r['handle'] = handle + r['key_name'] = 'DsSpooler' + r['value_name'] = valuename + r['type'] = 3 + r['buffer'] = data + r['buf_size'] = len(data) + + result = dcerpc.spoolss_SetPrinterDataEx(pipe, r) + + +def test_EnumPrinterDataEx(pipe, handle): + + r = {} + r['handle'] = handle + r['key_name'] = 'DsSpooler' + r['buf_size'] = 0 + + result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r) + + if result['result'] == dcerpc.WERR_MORE_DATA: + r['buf_size'] = result['buf_size'] + + result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r) + + # TODO: test spoolss_GetPrinterDataEx() + + +def test_SetPrinterData(pipe, handle): + + print 'testing spoolss_SetPrinterData()' + + valuename = '__printerdatatest__' + data = '12345' + + r = {} + r['handle'] = handle + r['value_name'] = valuename + r['type'] = 3 # REG_BINARY + r['buffer'] = data + r['real_len'] = 5 + + dcerpc.spoolss_SetPrinterData(pipe, r) + + s = {} + s['handle'] = handle + s['value_name'] = valuename + + result = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, r) + + if result['buffer'] != data: + print 'SetPrinterData: mismatch' + sys.exit(1) + + dcerpc.spoolss_DeletePrinterData(pipe, r) + + +def test_EnumPrinters(pipe): + + print 'testing spoolss_EnumPrinters()' + + printer_names = None + + r = {} + r['flags'] = 0x02 + r['server'] = None + + for level in [0, 1, 2, 4, 5]: + + print 'test_EnumPrinters(level = %d)' % level + + r['level'] = level + + result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r) + + printers = dcerpc.unmarshall_spoolss_PrinterInfo_array( + result['buffer'], r['level'], result['count']) + + if level == 2: + for p in printers: + + # A nice check is for the specversion in the + # devicemode. This has always been observed to be + # 1025. + + if p['info2']['devmode']['specversion'] != 1025: + print 'test_EnumPrinters: specversion != 1025' + sys.exit(1) + + r['level'] = 1 + result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r) + + for printer in dcerpc.unmarshall_spoolss_PrinterInfo_array( + result['buffer'], r['level'], result['count']): + + if string.find(printer['info1']['name'], '\\\\') == 0: + print 'Skipping remote printer %s' % printer['info1']['name'] + continue + + printername = string.split(printer['info1']['name'], ',')[0] + + handle = test_OpenPrinterEx(pipe, printername) + + test_GetPrinter(pipe, handle) + test_EnumPorts(pipe, handle) + test_EnumForms(pipe, handle) + test_AddForm(pipe, handle) + test_EnumJobs(pipe, handle) + test_EnumPrinterData(pipe, handle) + test_EnumPrinterDataEx(pipe, handle) + test_SetPrinterData(pipe, handle) +# test_SetPrinterDataEx(pipe, handle) + test_ClosePrinter(pipe, handle) + + +def test_EnumPrinterDrivers(pipe): + + print 'test spoolss_EnumPrinterDrivers()' + + for level in [1, 2, 3]: + + r = {} + r['server'] = None + r['environment'] = None + r['level'] = level + + result = ResizeBufferCall(dcerpc.spoolss_EnumPrinterDrivers, pipe, r) + + drivers = dcerpc.unmarshall_spoolss_DriverInfo_array( + result['buffer'], r['level'], result['count']) + + if level == 1: + driver_names = map(lambda x: x['info1']['driver_name'], drivers) + + +def test_PrintServer(pipe): + + handle = test_OpenPrinterEx(pipe, None) + + # EnumForms and AddForm tests return WERR_BADFID here (??) + + test_ClosePrinter(pipe, handle) + + +def runtests(binding, domain, username, password): + + print 'Testing SPOOLSS pipe' + + pipe = dcerpc.pipe_connect(binding, + dcerpc.DCERPC_SPOOLSS_UUID, dcerpc.DCERPC_SPOOLSS_VERSION, + domain, username, password) + + test_EnumPrinters(pipe) + test_EnumPrinterDrivers(pipe) + test_PrintServer(pipe) diff --git a/source4/scripting/python/samba/torture/torture_samr.py b/source4/scripting/python/samba/torture/torture_samr.py new file mode 100755 index 0000000000..15c6dc1a76 --- /dev/null +++ b/source4/scripting/python/samba/torture/torture_samr.py @@ -0,0 +1,221 @@ +#!/usr/bin/python + +import sys +import dcerpc, samr + +def test_Connect(pipe): + + handle = samr.Connect(pipe) + handle = samr.Connect2(pipe) + handle = samr.Connect3(pipe) + handle = samr.Connect4(pipe) + + # WIN2K3 only? + + try: + handle = samr.Connect5(pipe) + except dcerpc.NTSTATUS, arg: + if arg[0] != 0xc00000d2L: # NT_STATUS_NET_WRITE_FAULT + raise + + return handle + +def test_UserHandle(user_handle): + + # QuerySecurity()/SetSecurity() + + user_handle.SetSecurity(user_handle.QuerySecurity()) + + # GetUserPwInfo() + + user_handle.GetUserPwInfo() + + # GetUserInfo() + + for level in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20, + 21, 23, 24, 25, 26]: + + try: + user_handle.QueryUserInfo(level) + user_handle.QueryUserInfo2(level) + except dcerpc.NTSTATUS, arg: + if arg[0] != 0xc0000003L: # NT_STATUS_INVALID_INFO_CLASS + raise + + # GetGroupsForUser() + + user_handle.GetGroupsForUser() + + # TestPrivateFunctionsUser() + + try: + user_handle.TestPrivateFunctionsUser() + except dcerpc.NTSTATUS, arg: + if arg[0] != 0xC0000002L: + raise + +def test_GroupHandle(group_handle): + + # QuerySecurity()/SetSecurity() + + group_handle.SetSecurity(group_handle.QuerySecurity()) + + # QueryGroupInfo() + + for level in [1, 2, 3, 4, 5]: + info = group_handle.QueryGroupInfo(level) + + # TODO: SetGroupinfo() + + # QueryGroupMember() + + group_handle.QueryGroupMember() + +def test_AliasHandle(alias_handle): + + # QuerySecurity()/SetSecurity() + + alias_handle.SetSecurity(alias_handle.QuerySecurity()) + + print alias_handle.GetMembersInAlias() + +def test_DomainHandle(name, sid, domain_handle): + + print 'testing %s (%s)' % (name, sid) + + # QuerySecurity()/SetSecurity() + + domain_handle.SetSecurity(domain_handle.QuerySecurity()) + + # LookupNames(), none mapped + + try: + domain_handle.LookupNames(['xxNONAMExx']) + except dcerpc.NTSTATUS, arg: + if arg[0] != 0xc0000073L: + raise dcerpc.NTSTATUS(arg) + + # LookupNames(), some mapped + + if name != 'Builtin': + domain_handle.LookupNames(['Administrator', 'xxNONAMExx']) + + # QueryDomainInfo()/SetDomainInfo() + + levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13] + set_ok = [1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0] + + for i in range(len(levels)): + + info = domain_handle.QueryDomainInfo(level = levels[i]) + + try: + domain_handle.SetDomainInfo(levels[i], info) + except dcerpc.NTSTATUS, arg: + if not (arg[0] == 0xc0000003L and not set_ok[i]): + raise + + # QueryDomainInfo2() + + levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13] + + for i in range(len(levels)): + domain_handle.QueryDomainInfo2(level = levels[i]) + + # EnumDomainUsers + + print 'testing users' + + users = domain_handle.EnumDomainUsers() + rids = domain_handle.LookupNames(users) + + for i in range(len(users)): + test_UserHandle(domain_handle.OpenUser(rids[0][i])) + + # QueryDisplayInfo + + for i in [1, 2, 3, 4, 5]: + domain_handle.QueryDisplayInfo(level = i) + domain_handle.QueryDisplayInfo2(level = i) + domain_handle.QueryDisplayInfo3(level = i) + + # EnumDomainGroups + + print 'testing groups' + + groups = domain_handle.EnumDomainGroups() + rids = domain_handle.LookupNames(groups) + + for i in range(len(groups)): + test_GroupHandle(domain_handle.OpenGroup(rids[0][i])) + + # EnumDomainAliases + + print 'testing aliases' + + aliases = domain_handle.EnumDomainAliases() + rids = domain_handle.LookupNames(aliases) + + for i in range(len(aliases)): + test_AliasHandle(domain_handle.OpenAlias(rids[0][i])) + + # CreateUser + # CreateUser2 + # CreateDomAlias + # RidToSid + # RemoveMemberFromForeignDomain + # CreateDomainGroup + # GetAliasMembership + + # GetBootKeyInformation() + + try: + domain_handle.GetBootKeyInformation() + except dcerpc.NTSTATUS, arg: + pass + + # TestPrivateFunctionsDomain() + + try: + domain_handle.TestPrivateFunctionsDomain() + except dcerpc.NTSTATUS, arg: + if arg[0] != 0xC0000002L: + raise + +def test_ConnectHandle(connect_handle): + + print 'testing connect handle' + + # QuerySecurity/SetSecurity + + connect_handle.SetSecurity(connect_handle.QuerySecurity()) + + # Lookup bogus domain + + try: + connect_handle.LookupDomain('xxNODOMAINxx') + except dcerpc.NTSTATUS, arg: + if arg[0] != 0xC00000DFL: # NT_STATUS_NO_SUCH_DOMAIN + raise + + # Test all domains + + for domain_name in connect_handle.EnumDomains(): + + connect_handle.GetDomPwInfo(domain_name) + sid = connect_handle.LookupDomain(domain_name) + domain_handle = connect_handle.OpenDomain(sid) + + test_DomainHandle(domain_name, sid, domain_handle) + + # TODO: Test Shutdown() function + +def runtests(binding, creds): + + print 'Testing SAMR pipe' + + pipe = dcerpc.pipe_connect(binding, + dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION), creds) + + handle = test_Connect(pipe) + test_ConnectHandle(handle) diff --git a/source4/scripting/python/samba/torture/torture_tdb.py b/source4/scripting/python/samba/torture/torture_tdb.py new file mode 100755 index 0000000000..7f97caf6cb --- /dev/null +++ b/source4/scripting/python/samba/torture/torture_tdb.py @@ -0,0 +1,90 @@ +#!/usr/bin/python + +import sys, os +import Tdb + +def fail(msg): + print 'FAILED:', msg + sys.exit(1) + +tdb_file = '/tmp/torture_tdb.tdb' + +# Create temporary tdb file + +t = Tdb.Tdb(tdb_file, flags = Tdb.CLEAR_IF_FIRST) + +# Check non-existent key throws KeyError exception + +try: + t['__none__'] +except KeyError: + pass +else: + fail('non-existent key did not throw KeyError') + +# Check storing key + +t['bar'] = '1234' +if t['bar'] != '1234': + fail('store key failed') + +# Check key exists + +if not t.has_key('bar'): + fail('has_key() failed for existing key') + +if t.has_key('__none__'): + fail('has_key() succeeded for non-existent key') + +# Delete key + +try: + del(t['__none__']) +except KeyError: + pass +else: + fail('delete of non-existent key did not throw KeyError') + +del t['bar'] +if t.has_key('bar'): + fail('delete of existing key did not delete key') + +# Clear all keys + +t.clear() +if len(t) != 0: + fail('clear failed to remove all keys') + +# Other dict functions + +t['a'] = '1' +t['ab'] = '12' +t['abc'] = '123' + +if len(t) != 3: + fail('len method produced wrong value') + +keys = t.keys() +values = t.values() +items = t.items() + +if set(keys) != set(['a', 'ab', 'abc']): + fail('keys method produced wrong values') + +if set(values) != set(['1', '12', '123']): + fail('values method produced wrong values') + +if set(items) != set([('a', '1'), ('ab', '12'), ('abc', '123')]): + fail('values method produced wrong values') + +t.close() + +# Re-open read-only + +t = Tdb.Tdb(tdb_file, open_flags = os.O_RDONLY) +t.keys() +t.close() + +# Clean up + +os.unlink(tdb_file) diff --git a/source4/scripting/python/samba/torture/winreg.py b/source4/scripting/python/samba/torture/winreg.py new file mode 100755 index 0000000000..eb60b9847e --- /dev/null +++ b/source4/scripting/python/samba/torture/winreg.py @@ -0,0 +1,165 @@ +#!/usr/bin/python + +import sys, dcerpc + +def test_OpenHKLM(pipe): + + r = {} + r['unknown'] = {} + r['unknown']['unknown0'] = 0x9038 + r['unknown']['unknown1'] = 0x0000 + r['access_required'] = 0x02000000 + + result = dcerpc.winreg_OpenHKLM(pipe, r) + + return result['handle'] + +def test_QueryInfoKey(pipe, handle): + + r = {} + r['handle'] = handle + r['class'] = {} + r['class']['name'] = None + + return dcerpc.winreg_QueryInfoKey(pipe, r) + +def test_CloseKey(pipe, handle): + + r = {} + r['handle'] = handle + + dcerpc.winreg_CloseKey(pipe, r) + +def test_FlushKey(pipe, handle): + + r = {} + r['handle'] = handle + + dcerpc.winreg_FlushKey(pipe, r) + +def test_GetVersion(pipe, handle): + + r = {} + r['handle'] = handle + + dcerpc.winreg_GetVersion(pipe, r) + +def test_GetKeySecurity(pipe, handle): + + r = {} + r['handle'] = handle + r['unknown'] = 4 + r['size'] = None + r['data'] = {} + r['data']['max_len'] = 0 + r['data']['data'] = '' + + result = dcerpc.winreg_GetKeySecurity(pipe, r) + + print result + + if result['result'] == dcerpc.WERR_INSUFFICIENT_BUFFER: + r['size'] = {} + r['size']['max_len'] = result['data']['max_len'] + r['size']['offset'] = 0 + r['size']['len'] = result['data']['max_len'] + + result = dcerpc.winreg_GetKeySecurity(pipe, r) + + print result + + sys.exit(1) + +def test_Key(pipe, handle, name, depth = 0): + + # Don't descend too far. Registries can be very deep. + + if depth > 2: + return + + try: + keyinfo = test_QueryInfoKey(pipe, handle) + except dcerpc.WERROR, arg: + if arg[0] == dcerpc.WERR_ACCESS_DENIED: + return + + test_GetVersion(pipe, handle) + + test_FlushKey(pipe, handle) + + test_GetKeySecurity(pipe, handle) + + # Enumerate values in this key + + r = {} + r['handle'] = handle + r['name_in'] = {} + r['name_in']['len'] = 0 + r['name_in']['max_len'] = (keyinfo['max_valnamelen'] + 1) * 2 + r['name_in']['buffer'] = {} + r['name_in']['buffer']['max_len'] = keyinfo['max_valnamelen'] + 1 + r['name_in']['buffer']['offset'] = 0 + r['name_in']['buffer']['len'] = 0 + r['type'] = 0 + r['value_in'] = {} + r['value_in']['max_len'] = keyinfo['max_valbufsize'] + r['value_in']['offset'] = 0 + r['value_in']['len'] = 0 + r['value_len1'] = keyinfo['max_valbufsize'] + r['value_len2'] = 0 + + for i in range(0, keyinfo['num_values']): + + r['enum_index'] = i + + dcerpc.winreg_EnumValue(pipe, r) + + # Recursively test subkeys of this key + + r = {} + r['handle'] = handle + r['key_name_len'] = 0 + r['unknown'] = 0x0414 + r['in_name'] = {} + r['in_name']['unknown'] = 0x20a + r['in_name']['key_name'] = {} + r['in_name']['key_name']['name'] = None + r['class'] = {} + r['class']['name'] = None + r['last_changed_time'] = {} + r['last_changed_time']['low'] = 0 + r['last_changed_time']['high'] = 0 + + for i in range(0, keyinfo['num_subkeys']): + + r['enum_index'] = i + + subkey = dcerpc.winreg_EnumKey(pipe, r) + + s = {} + s['handle'] = handle + s['keyname'] = {} + s['keyname']['name'] = subkey['out_name']['name'] + s['unknown'] = 0 + s['access_mask'] = 0x02000000 + + result = dcerpc.winreg_OpenKey(pipe, s) + + test_Key(pipe, result['handle'], name + '/' + s['keyname']['name'], + depth + 1) + + test_CloseKey(pipe, result['handle']) + + # Enumerate values + +def runtests(binding, domain, username, password): + + print 'Testing WINREG pipe' + + pipe = dcerpc.pipe_connect(binding, + dcerpc.DCERPC_WINREG_UUID, dcerpc.DCERPC_WINREG_VERSION, + domain, username, password) + + handle = test_OpenHKLM(pipe) + + test_Key(pipe, handle, 'HKLM') diff --git a/source4/scripting/python/sidmodule.c b/source4/scripting/python/sidmodule.c new file mode 100644 index 0000000000..2b3f152e9b --- /dev/null +++ b/source4/scripting/python/sidmodule.c @@ -0,0 +1,57 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 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 . +*/ + +#include "includes.h" +#include "scripting/python/talloc.h" +#include "Python.h" +#include "libcli/security/security.h" + +static PyObject *sid_random(PyObject *self, PyObject *args) +{ + char *str; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + str = talloc_asprintf(NULL, "S-1-5-21-%u-%u-%u", + (unsigned)generate_random(), + (unsigned)generate_random(), + (unsigned)generate_random()); + + if (str == NULL) { + PyErr_SetString(PyExc_TypeError, "can't generate random sid"); + return NULL; + } + + return PyString_FromString(str); +} + +static PyMethodDef methods[] = { + { "random", (PyCFunction)sid_random, METH_VARARGS, NULL}, + { NULL, NULL } +}; + +PyDoc_STRVAR(param_doc, "SID helper routines"); + +PyMODINIT_FUNC initsid(void) +{ + PyObject *mod = Py_InitModule3("sid", methods, param_doc); + if (mod == NULL) + return; +} diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c new file mode 100644 index 0000000000..9ae432dfa5 --- /dev/null +++ b/source4/scripting/python/uuidmodule.c @@ -0,0 +1,57 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 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 . +*/ + +#include "includes.h" +#include "Python.h" +#include "librpc/ndr/libndr.h" + +static PyObject *uuid_random(PyObject *self, PyObject *args) +{ + struct GUID guid; + char *str; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + guid = GUID_random(); + + str = GUID_string(NULL, &guid); + if (str == NULL) { + PyErr_SetString(PyExc_TypeError, "can't convert uuid to string"); + return NULL; + } + + talloc_free(str); + + return PyString_FromString(str); +} + +static PyMethodDef methods[] = { + { "random", (PyCFunction)uuid_random, METH_VARARGS, NULL}, + { NULL, NULL } +}; + +PyDoc_STRVAR(param_doc, "UUID helper routines"); + +PyMODINIT_FUNC inituuid(void) +{ + PyObject *mod = Py_InitModule3("uuid", methods, param_doc); + if (mod == NULL) + return; +} -- cgit From 29cf3a93cc8a67edcf307ba944bb3d5f90a3d55a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 13:22:54 +0100 Subject: r26089: Move python detection to a separate file, and don't make it an error if it isn't available. (This used to be commit 4e7709379de2fb9bf1eafd9ee9cbe10a0e6df51e) --- source4/scripting/python/config.m4 | 117 +++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 source4/scripting/python/config.m4 (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 new file mode 100644 index 0000000000..36bf8a6049 --- /dev/null +++ b/source4/scripting/python/config.m4 @@ -0,0 +1,117 @@ +AC_ARG_VAR([PYTHON_VERSION],[The installed Python + version to use, for example '2.3'. This string + will be appended to the Python interpreter + canonical name.]) + +AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) +if test -z "$PYTHON"; then + AC_MSG_WARN([No python found]) + SMB_ENABLE(LIBPYTHON,NO) +else + SMB_ENABLE(LIBPYTHON,YES) +fi + +# +# Check for a version of Python >= 2.1.0 +# +AC_MSG_CHECKING([for a version of Python >= '2.1.0']) +ac_supports_python_ver=`$PYTHON -c "import sys, string; \ + ver = string.split(sys.version)[[0]]; \ + print ver >= '2.1.0'"` +if test "$ac_supports_python_ver" != "True"; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([No recent version of python found]) +else + AC_MSG_RESULT([yes]) +fi + +# +# Check if you have distutils, else fail +# +AC_MSG_CHECKING([for the distutils Python package]) +ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` +if test -z "$ac_distutils_result"; then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([distutils not available]) +fi + +# +# Check for Python include path +# +AC_MSG_CHECKING([for Python include path]) +if test -z "$PYTHON_CPPFLAGS"; then + python_path=`$PYTHON -c "import distutils.sysconfig; \ + print distutils.sysconfig.get_python_inc();"` + if test -n "${python_path}"; then + python_path="-I$python_path" + fi + PYTHON_CPPFLAGS=$python_path +fi +AC_MSG_RESULT([$PYTHON_CPPFLAGS]) +AC_SUBST([PYTHON_CPPFLAGS]) + +# +# Check for Python library path +# +AC_MSG_CHECKING([for Python library path]) +if test -z "$PYTHON_LDFLAGS"; then + # (makes two attempts to ensure we've got a version number + # from the interpreter) + py_version=`$PYTHON -c "from distutils.sysconfig import *; \ + from string import join; \ + print join(get_config_vars('VERSION'))"` + if test "$py_version" == "[None]"; then + if test -n "$PYTHON_VERSION"; then + py_version=$PYTHON_VERSION + else + py_version=`$PYTHON -c "import sys; \ + print sys.version[[:3]]"` + fi + fi + + PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \ + from string import join; \ + print '-L' + get_python_lib(0,1), \ + '-lpython';"`$py_version +fi +AC_MSG_RESULT([$PYTHON_LDFLAGS]) +AC_SUBST([PYTHON_LDFLAGS]) + +# +# Check for site packages +# +AC_MSG_CHECKING([for Python site-packages path]) +if test -z "$PYTHON_SITE_PKG"; then + PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \ + print distutils.sysconfig.get_python_lib(0,0);"` +fi +AC_MSG_RESULT([$PYTHON_SITE_PKG]) +AC_SUBST([PYTHON_SITE_PKG]) + +# +# libraries which must be linked in when embedding +# +AC_MSG_CHECKING(python extra libraries) +if test -z "$PYTHON_EXTRA_LIBS"; then + PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print conf('LOCALMODLIBS'), conf('LIBS')"` +fi +AC_MSG_RESULT([$PYTHON_EXTRA_LIBS]) +AC_SUBST(PYTHON_EXTRA_LIBS) + +# +# linking flags needed when embedding +# +AC_MSG_CHECKING(python extra linking flags) +if test -z "$PYTHON_EXTRA_LDFLAGS"; then + PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \ + conf = distutils.sysconfig.get_config_var; \ + print conf('LINKFORSHARED')"` +fi +AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) +AC_SUBST(PYTHON_EXTRA_LDFLAGS) + +SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CPPFLAGS]) -- cgit From dd2a4719df68519c11f115aaa8b77e7afca0a2a3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 14:49:32 +0100 Subject: r26096: No longer include removed header (This used to be commit 42738301b1c88ccf46405d6c9171b3ae082423bd) --- source4/scripting/python/config.mk | 2 +- source4/scripting/python/parammodule.c | 1 - source4/scripting/python/sidmodule.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 1c9ffb20ac..b70d98d908 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -26,7 +26,7 @@ clean:: @echo "Removing SWIG output files" @-rm -f bin/python/* # FIXME: Remove _wrap.c files - # + pythonmods: $(PYTHON_DSOS) PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py diff --git a/source4/scripting/python/parammodule.c b/source4/scripting/python/parammodule.c index 38d312cf1d..bb7adab240 100644 --- a/source4/scripting/python/parammodule.c +++ b/source4/scripting/python/parammodule.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "scripting/python/talloc.h" #include "Python.h" #include "param/param.h" diff --git a/source4/scripting/python/sidmodule.c b/source4/scripting/python/sidmodule.c index 2b3f152e9b..4b199b1158 100644 --- a/source4/scripting/python/sidmodule.c +++ b/source4/scripting/python/sidmodule.c @@ -18,7 +18,6 @@ */ #include "includes.h" -#include "scripting/python/talloc.h" #include "Python.h" #include "libcli/security/security.h" -- cgit From 4e25ea3001805c9d3b573627d8d388d5d0a9b53b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 15:19:51 +0100 Subject: r26098: Make missing python no longer fatal. (This used to be commit 9af2aeb22500baf65c11bc46c0051385911a8d67) --- source4/scripting/python/config.m4 | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 36bf8a6049..0b5e174590 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -5,10 +5,8 @@ AC_ARG_VAR([PYTHON_VERSION],[The installed Python AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then + working_python=no AC_MSG_WARN([No python found]) - SMB_ENABLE(LIBPYTHON,NO) -else - SMB_ENABLE(LIBPYTHON,YES) fi # @@ -19,8 +17,8 @@ ac_supports_python_ver=`$PYTHON -c "import sys, string; \ ver = string.split(sys.version)[[0]]; \ print ver >= '2.1.0'"` if test "$ac_supports_python_ver" != "True"; then + working_python=no AC_MSG_RESULT([no]) - AC_MSG_ERROR([No recent version of python found]) else AC_MSG_RESULT([yes]) fi @@ -32,9 +30,10 @@ AC_MSG_CHECKING([for the distutils Python package]) ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` if test -z "$ac_distutils_result"; then AC_MSG_RESULT([yes]) + working_python=yes else AC_MSG_RESULT([no]) - AC_MSG_ERROR([distutils not available]) + working_python=no fi # @@ -115,3 +114,11 @@ AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) AC_SUBST(PYTHON_EXTRA_LDFLAGS) SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CPPFLAGS]) + +if test x$working_python = xyes +then + SMB_ENABLE(LIBPYTHON,YES) +else + SMB_ENABLE(LIBPYTHON,NO) +fi + -- cgit From c14de3fd893c4a44cf35c2b354e51bf7f4a81992 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Nov 2007 16:04:13 +0100 Subject: r26100: Also check for SWIG. (This used to be commit 1755adffecb8ed68047d6ad69087a680cc63ba8f) --- source4/scripting/python/config.m4 | 4 ++-- source4/scripting/python/config.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 0b5e174590..48103a0782 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -3,6 +3,7 @@ AC_ARG_VAR([PYTHON_VERSION],[The installed Python will be appended to the Python interpreter canonical name.]) +AC_PATH_PROG(SWIG,swig,no) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then working_python=no @@ -115,10 +116,9 @@ AC_SUBST(PYTHON_EXTRA_LDFLAGS) SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CPPFLAGS]) -if test x$working_python = xyes +if test x$working_python = xyes && test x$SWIG != xno then SMB_ENABLE(LIBPYTHON,YES) else SMB_ENABLE(LIBPYTHON,NO) fi - diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index b70d98d908..c176077267 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -20,7 +20,7 @@ swig: pythonmods .SUFFIXES: _wrap.c .i .i_wrap.c: - swig -Wall -I$(srcdir)/scripting/swig -python $< + $(SWIG) -Wall -I$(srcdir)/scripting/swig -python $< clean:: @echo "Removing SWIG output files" -- cgit From eaecbfa0e2703d429b295e51e230545ed8f3462c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 25 Nov 2007 15:34:12 +0100 Subject: r26114: Allow keyword-arguments. (This used to be commit 99c342641b865e37c9ee8dd280348b659076d1e5) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index c176077267..eb35919450 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -20,7 +20,7 @@ swig: pythonmods .SUFFIXES: _wrap.c .i .i_wrap.c: - $(SWIG) -Wall -I$(srcdir)/scripting/swig -python $< + $(SWIG) -Wall -I$(srcdir)/scripting/swig -python -keyword $< clean:: @echo "Removing SWIG output files" -- cgit From 16325f13395a48daa9c0a8cb58b354e552776fce Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Nov 2007 22:41:29 +0100 Subject: r26186: Generate SWIG files as part of autogen.sh (This used to be commit 4429f8b87e057787df0748f93c842c9a634dada5) --- source4/scripting/python/config.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index eb35919450..c396cf62bc 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -22,14 +22,14 @@ swig: pythonmods .i_wrap.c: $(SWIG) -Wall -I$(srcdir)/scripting/swig -python -keyword $< -clean:: +realdistclean:: @echo "Removing SWIG output files" @-rm -f bin/python/* # FIXME: Remove _wrap.c files pythonmods: $(PYTHON_DSOS) -PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py +PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) -- cgit From 660077476f43bb262b57f538147140e07e65f6df Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Nov 2007 22:41:37 +0100 Subject: r26188: Now that swig output is pregenerated, allow building python code without swig installed. (This used to be commit f97f82adbd2663cadcfc5522c809ce2e659fb42c) --- source4/scripting/python/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 48103a0782..bdc977b0ba 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -116,7 +116,7 @@ AC_SUBST(PYTHON_EXTRA_LDFLAGS) SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CPPFLAGS]) -if test x$working_python = xyes && test x$SWIG != xno +if test x$working_python = xyes then SMB_ENABLE(LIBPYTHON,YES) else -- cgit From 26ae331f75317bfc0a4787d3960a861b25225615 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 01:36:41 +0100 Subject: r26191: Import custom test runner for subunit, rather than using trial, which is part of twisted. (This used to be commit b0f808345f948c49ad46f34ba306ca8354393850) --- source4/scripting/python/subunit/__init__.py | 386 +++++++++++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 source4/scripting/python/subunit/__init__.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py new file mode 100644 index 0000000000..e44dd766cc --- /dev/null +++ b/source4/scripting/python/subunit/__init__.py @@ -0,0 +1,386 @@ +# +# subunit: extensions to python unittest to get test results from subprocesses. +# Copyright (C) 2005 Robert Collins +# Copyright (C) 2007 Jelmer Vernooij +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +import os +from StringIO import StringIO +import subprocess +import sys +import unittest + +def test_suite(): + import subunit.tests + return subunit.tests.test_suite() + + +def join_dir(base_path, path): + """ + Returns an absolute path to C{path}, calculated relative to the parent + of C{base_path}. + + @param base_path: A path to a file or directory. + @param path: An absolute path, or a path relative to the containing + directory of C{base_path}. + + @return: An absolute path to C{path}. + """ + return os.path.join(os.path.dirname(os.path.abspath(base_path)), path) + + +class TestProtocolServer(object): + """A class for receiving results from a TestProtocol client.""" + + OUTSIDE_TEST = 0 + TEST_STARTED = 1 + READING_FAILURE = 2 + READING_ERROR = 3 + + def __init__(self, client, stream=sys.stdout): + """Create a TestProtocol server instance. + + client should be an object that provides + - startTest + - addSuccess + - addFailure + - addError + - stopTest + methods, i.e. a TestResult. + """ + self.state = TestProtocolServer.OUTSIDE_TEST + self.client = client + self._stream = stream + + def _addError(self, offset, line): + if (self.state == TestProtocolServer.TEST_STARTED and + self.current_test_description == line[offset:-1]): + self.state = TestProtocolServer.OUTSIDE_TEST + self.current_test_description = None + self.client.addError(self._current_test, RemoteError("")) + self.client.stopTest(self._current_test) + self._current_test = None + elif (self.state == TestProtocolServer.TEST_STARTED and + self.current_test_description + " [" == line[offset:-1]): + self.state = TestProtocolServer.READING_ERROR + self._message = "" + else: + self.stdOutLineReceived(line) + + def _addFailure(self, offset, line): + if (self.state == TestProtocolServer.TEST_STARTED and + self.current_test_description == line[offset:-1]): + self.state = TestProtocolServer.OUTSIDE_TEST + self.current_test_description = None + self.client.addFailure(self._current_test, RemoteError()) + self.client.stopTest(self._current_test) + elif (self.state == TestProtocolServer.TEST_STARTED and + self.current_test_description + " [" == line[offset:-1]): + self.state = TestProtocolServer.READING_FAILURE + self._message = "" + else: + self.stdOutLineReceived(line) + + def _addSuccess(self, offset, line): + if (self.state == TestProtocolServer.TEST_STARTED and + self.current_test_description == line[offset:-1]): + self.client.addSuccess(self._current_test) + self.client.stopTest(self._current_test) + self.current_test_description = None + self._current_test = None + self.state = TestProtocolServer.OUTSIDE_TEST + else: + self.stdOutLineReceived(line) + + def _appendMessage(self, line): + if line[0:2] == " ]": + # quoted ] start + self._message += line[1:] + else: + self._message += line + + def endQuote(self, line): + if self.state == TestProtocolServer.READING_FAILURE: + self.state = TestProtocolServer.OUTSIDE_TEST + self.current_test_description = None + self.client.addFailure(self._current_test, + RemoteError(self._message)) + self.client.stopTest(self._current_test) + elif self.state == TestProtocolServer.READING_ERROR: + self.state = TestProtocolServer.OUTSIDE_TEST + self.current_test_description = None + self.client.addError(self._current_test, + RemoteError(self._message)) + self.client.stopTest(self._current_test) + else: + self.stdOutLineReceived(line) + + def lineReceived(self, line): + """Call the appropriate local method for the received line.""" + if line == "]\n": + self.endQuote(line) + elif (self.state == TestProtocolServer.READING_FAILURE or + self.state == TestProtocolServer.READING_ERROR): + self._appendMessage(line) + else: + parts = line.split(None, 1) + if len(parts) == 2: + cmd, rest = parts + offset = len(cmd) + 1 + cmd = cmd.strip(':') + if cmd in ('test', 'testing'): + self._startTest(offset, line) + elif cmd == 'error': + self._addError(offset, line) + elif cmd == 'failure': + self._addFailure(offset, line) + elif cmd in ('success', 'successful'): + self._addSuccess(offset, line) + else: + self.stdOutLineReceived(line) + else: + self.stdOutLineReceived(line) + + def lostConnection(self): + """The input connection has finished.""" + if self.state == TestProtocolServer.TEST_STARTED: + self.client.addError(self._current_test, + RemoteError("lost connection during test '%s'" + % self.current_test_description)) + self.client.stopTest(self._current_test) + elif self.state == TestProtocolServer.READING_ERROR: + self.client.addError(self._current_test, + RemoteError("lost connection during " + "error report of test " + "'%s'" % + self.current_test_description)) + self.client.stopTest(self._current_test) + elif self.state == TestProtocolServer.READING_FAILURE: + self.client.addError(self._current_test, + RemoteError("lost connection during " + "failure report of test " + "'%s'" % + self.current_test_description)) + self.client.stopTest(self._current_test) + + def readFrom(self, pipe): + for line in pipe.readlines(): + self.lineReceived(line) + self.lostConnection() + + def _startTest(self, offset, line): + """Internal call to change state machine. Override startTest().""" + if self.state == TestProtocolServer.OUTSIDE_TEST: + self.state = TestProtocolServer.TEST_STARTED + self._current_test = RemotedTestCase(line[offset:-1]) + self.current_test_description = line[offset:-1] + self.client.startTest(self._current_test) + else: + self.stdOutLineReceived(line) + + def stdOutLineReceived(self, line): + self._stream.write(line) + + +class RemoteException(Exception): + """An exception that occured remotely to python.""" + + def __eq__(self, other): + try: + return self.args == other.args + except AttributeError: + return False + + +class TestProtocolClient(unittest.TestResult): + """A class that looks like a TestResult and informs a TestProtocolServer.""" + + def __init__(self, stream): + unittest.TestResult.__init__(self) + self._stream = stream + + def addError(self, test, error): + """Report an error in test test.""" + self._stream.write("error: %s [\n" % (test.shortDescription() or str(test))) + for line in self._exc_info_to_string(error, test).split(): + self._stream.write("%s\n" % line) + self._stream.write("]\n") + + def addFailure(self, test, error): + """Report a failure in test test.""" + self._stream.write("failure: %s [\n" % (test.shortDescription() or str(test))) + for line in self._exc_info_to_string(error, test).split(): + self._stream.write("%s\n" % line) + self._stream.write("]\n") + + def addSuccess(self, test): + """Report a success in a test.""" + self._stream.write("successful: %s\n" % (test.shortDescription() or str(test))) + + def startTest(self, test): + """Mark a test as starting its test run.""" + self._stream.write("test: %s\n" % (test.shortDescription() or str(test))) + + +def RemoteError(description=""): + if description == "": + description = "\n" + return (RemoteException, RemoteException(description), None) + + +class RemotedTestCase(unittest.TestCase): + """A class to represent test cases run in child processes.""" + + def __eq__ (self, other): + try: + return self.__description == other.__description + except AttributeError: + return False + + def __init__(self, description): + """Create a psuedo test case with description description.""" + self.__description = description + + def error(self, label): + raise NotImplementedError("%s on RemotedTestCases is not permitted." % + label) + + def setUp(self): + self.error("setUp") + + def tearDown(self): + self.error("tearDown") + + def shortDescription(self): + return self.__description + + def id(self): + return "%s.%s" % (self._strclass(), self.__description) + + def __str__(self): + return "%s (%s)" % (self.__description, self._strclass()) + + def __repr__(self): + return "<%s description='%s'>" % \ + (self._strclass(), self.__description) + + def run(self, result=None): + if result is None: result = self.defaultTestResult() + result.startTest(self) + result.addError(self, RemoteError("Cannot run RemotedTestCases.\n")) + result.stopTest(self) + + def _strclass(self): + cls = self.__class__ + return "%s.%s" % (cls.__module__, cls.__name__) + + +class ExecTestCase(unittest.TestCase): + """A test case which runs external scripts for test fixtures.""" + + def __init__(self, methodName='runTest'): + """Create an instance of the class that will use the named test + method when executed. Raises a ValueError if the instance does + not have a method with the specified name. + """ + unittest.TestCase.__init__(self, methodName) + testMethod = getattr(self, methodName) + self.script = join_dir(sys.modules[self.__class__.__module__].__file__, + testMethod.__doc__) + + def countTestCases(self): + return 1 + + def run(self, result=None): + if result is None: result = self.defaultTestResult() + self._run(result) + + def debug(self): + """Run the test without collecting errors in a TestResult""" + self._run(unittest.TestResult()) + + def _run(self, result): + protocol = TestProtocolServer(result) + output = subprocess.Popen([self.script], + stdout=subprocess.PIPE).communicate()[0] + protocol.readFrom(StringIO(output)) + + +class IsolatedTestCase(unittest.TestCase): + """A TestCase which runs its tests in a forked process.""" + + def run(self, result=None): + if result is None: result = self.defaultTestResult() + run_isolated(unittest.TestCase, self, result) + + +class IsolatedTestSuite(unittest.TestSuite): + """A TestCase which runs its tests in a forked process.""" + + def run(self, result=None): + if result is None: result = unittest.TestResult() + run_isolated(unittest.TestSuite, self, result) + + +def run_isolated(klass, self, result): + """Run a test suite or case in a subprocess, using the run method on klass. + """ + c2pread, c2pwrite = os.pipe() + # fixme - error -> result + # now fork + pid = os.fork() + if pid == 0: + # Child + # Close parent's pipe ends + os.close(c2pread) + # Dup fds for child + os.dup2(c2pwrite, 1) + # Close pipe fds. + os.close(c2pwrite) + + # at this point, sys.stdin is redirected, now we want + # to filter it to escape ]'s. + ### XXX: test and write that bit. + + result = TestProtocolClient(sys.stdout) + klass.run(self, result) + sys.stdout.flush() + sys.stderr.flush() + # exit HARD, exit NOW. + os._exit(0) + else: + # Parent + # Close child pipe ends + os.close(c2pwrite) + # hookup a protocol engine + protocol = TestProtocolServer(result) + protocol.readFrom(os.fdopen(c2pread, 'rU')) + os.waitpid(pid, 0) + # TODO return code evaluation. + return result + + +class SubunitTestRunner: + def __init__(self, stream=sys.stdout): + self.stream = stream + + def run(self, test): + "Run the given test case or test suite." + result = TestProtocolClient(self.stream) + test(result) + return result + -- cgit From f2f16b45b58c2bbf3053ff55e7a290fc069e0efd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 14:49:47 +0100 Subject: r26197: Add bindings for libsecurity. (This used to be commit 8625cd403ba3a7d2b1b1fccfeb5efd7e21de0135) --- source4/scripting/python/config.mk | 4 --- source4/scripting/python/sidmodule.c | 56 ------------------------------------ 2 files changed, 60 deletions(-) delete mode 100644 source4/scripting/python/sidmodule.c (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index c396cf62bc..c17511203e 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -6,10 +6,6 @@ OBJ_FILES = parammodule.o PRIVATE_DEPENDENCIES = LIBNDR OBJ_FILES = uuidmodule.o -[PYTHON::python_sid] -PRIVATE_DEPENDENCIES = LIBNDR -OBJ_FILES = sidmodule.o - [PYTHON::python_misc] PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SWIG_FILE = misc.i diff --git a/source4/scripting/python/sidmodule.c b/source4/scripting/python/sidmodule.c deleted file mode 100644 index 4b199b1158..0000000000 --- a/source4/scripting/python/sidmodule.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 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 . -*/ - -#include "includes.h" -#include "Python.h" -#include "libcli/security/security.h" - -static PyObject *sid_random(PyObject *self, PyObject *args) -{ - char *str; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - - str = talloc_asprintf(NULL, "S-1-5-21-%u-%u-%u", - (unsigned)generate_random(), - (unsigned)generate_random(), - (unsigned)generate_random()); - - if (str == NULL) { - PyErr_SetString(PyExc_TypeError, "can't generate random sid"); - return NULL; - } - - return PyString_FromString(str); -} - -static PyMethodDef methods[] = { - { "random", (PyCFunction)sid_random, METH_VARARGS, NULL}, - { NULL, NULL } -}; - -PyDoc_STRVAR(param_doc, "SID helper routines"); - -PyMODINIT_FUNC initsid(void) -{ - PyObject *mod = Py_InitModule3("sid", methods, param_doc); - if (mod == NULL) - return; -} -- cgit From ef26c9a604657c00ce67768d34e237fd3a903a2c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 16:00:59 +0100 Subject: r26201: Build docs for the security module. (This used to be commit 31073a9e4ecaee08b3e27631db620957df8adde6) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index c17511203e..5d4bc48d8a 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -25,7 +25,7 @@ realdistclean:: pythonmods: $(PYTHON_DSOS) -PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py +PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) -- cgit From 4151cf9866640a5eb53730ff069625373b6d8c27 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 Nov 2007 17:49:13 +0100 Subject: r26207: Only compile swig files if swig is available. (This used to be commit cc5260971c4953ce742363b324ac3804c531e2dd) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 5d4bc48d8a..c4722e2b9a 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -16,7 +16,7 @@ swig: pythonmods .SUFFIXES: _wrap.c .i .i_wrap.c: - $(SWIG) -Wall -I$(srcdir)/scripting/swig -python -keyword $< + [ "$(SWIG)" != "no" ] && $(SWIG) -Wall -I$(srcdir)/scripting/swig -python -keyword $< realdistclean:: @echo "Removing SWIG output files" -- cgit From da0640518f67545df6a1da30c916fbc452d38a39 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 20:24:24 +0100 Subject: r26232: Provide replacement for stdint.i for users of older versions of swig. (This used to be commit fb2150a07aa6460165efb4587c86ecc820cdeac0) --- source4/scripting/python/replace/stdint.i | 109 ++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 source4/scripting/python/replace/stdint.i (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/replace/stdint.i b/source4/scripting/python/replace/stdint.i new file mode 100644 index 0000000000..7b48ca3884 --- /dev/null +++ b/source4/scripting/python/replace/stdint.i @@ -0,0 +1,109 @@ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * stdint.i + * + * SWIG library file for ISO C99 types: 7.18 Integer types + * ----------------------------------------------------------------------------- */ + +%{ +#include // Use the C99 official header +%} + +%include + +/* Exact integral types. */ + +/* Signed. */ + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +#if defined(SWIGWORDSIZE64) +typedef long int int64_t; +#else +typedef long long int int64_t; +#endif + +/* Unsigned. */ +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +#if defined(SWIGWORDSIZE64) +typedef unsigned long int uint64_t; +#else +typedef unsigned long long int uint64_t; +#endif + + +/* Small types. */ + +/* Signed. */ +typedef signed char int_least8_t; +typedef short int int_least16_t; +typedef int int_least32_t; +#if defined(SWIGWORDSIZE64) +typedef long int int_least64_t; +#else +typedef long long int int_least64_t; +#endif + +/* Unsigned. */ +typedef unsigned char uint_least8_t; +typedef unsigned short int uint_least16_t; +typedef unsigned int uint_least32_t; +#if defined(SWIGWORDSIZE64) +typedef unsigned long int uint_least64_t; +#else +typedef unsigned long long int uint_least64_t; +#endif + + +/* Fast types. */ + +/* Signed. */ +typedef signed char int_fast8_t; +#if defined(SWIGWORDSIZE64) +typedef long int int_fast16_t; +typedef long int int_fast32_t; +typedef long int int_fast64_t; +#else +typedef int int_fast16_t; +typedef int int_fast32_t; +typedef long long int int_fast64_t; +#endif + +/* Unsigned. */ +typedef unsigned char uint_fast8_t; +#if defined(SWIGWORDSIZE64) +typedef unsigned long int uint_fast16_t; +typedef unsigned long int uint_fast32_t; +typedef unsigned long int uint_fast64_t; +#else +typedef unsigned int uint_fast16_t; +typedef unsigned int uint_fast32_t; +typedef unsigned long long int uint_fast64_t; +#endif + + +/* Types for `void *' pointers. */ +#if defined(SWIGWORDSIZE64) +typedef long int intptr_t; +typedef unsigned long int uintptr_t; +#else +typedef int intptr_t; +typedef unsigned int uintptr_t; +#endif + + +/* Largest integral types. */ +#if defined(SWIGWORDSIZE64) +typedef long int intmax_t; +typedef unsigned long int uintmax_t; +#else +typedef long long int intmax_t; +typedef unsigned long long int uintmax_t; +#endif + + -- cgit From 7bf6b95b1ffdfe72144b39132c73fe1c234270b0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 03:14:27 +0100 Subject: r26242: Don't fail if swig is not available. (This used to be commit 12debcceac6cca1d8c8e1f78a0c7772b944e9f8d) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index c4722e2b9a..91437e1e0b 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -16,7 +16,7 @@ swig: pythonmods .SUFFIXES: _wrap.c .i .i_wrap.c: - [ "$(SWIG)" != "no" ] && $(SWIG) -Wall -I$(srcdir)/scripting/swig -python -keyword $< + [ "$(SWIG)" == "no" ] || $(SWIG) -Wall -I$(srcdir)/scripting/swig -python -keyword $< realdistclean:: @echo "Removing SWIG output files" -- cgit From 4f5adbdddf6e3e1a4789c2df81973084913742f9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 04:14:24 +0100 Subject: r26243: stdint.i requires swigarch.i (This used to be commit d9391316a982cfff6b283e7d4a86103ec6fe370d) --- source4/scripting/python/replace/swigarch.i | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 source4/scripting/python/replace/swigarch.i (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/replace/swigarch.i b/source4/scripting/python/replace/swigarch.i new file mode 100644 index 0000000000..260b608801 --- /dev/null +++ b/source4/scripting/python/replace/swigarch.i @@ -0,0 +1,65 @@ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * swigarch.i + * + * SWIG library file for 32bit/64bit code specialization and checking. + * + * Use only in extreme cases, when no arch. independent code can be + * generated + * + * To activate architecture specific code, use + * + * swig -DSWIGWORDSIZE32 + * + * or + * + * swig -DSWIGWORDSIZE64 + * + * Note that extra checking code will be added to the wrapped code, + * which will prevent the compilation in a different architecture. + * + * If you don't specify the SWIGWORDSIZE (the default case), swig will + * generate architecture independent and/or 32bits code, with no extra + * checking code added. + * ----------------------------------------------------------------------------- */ + +#if !defined(SWIGWORDSIZE32) && !defined(SWIGWORDSIZE64) +# if (__WORDSIZE == 32) +# define SWIGWORDSIZE32 +# endif +#endif + +#if !defined(SWIGWORDSIZE64) && !defined(SWIGWORDSIZE32) +# if defined(__x86_64) || defined(__x86_64__) || (__WORDSIZE == 64) +# define SWIGWORDSIZE64 +# endif +#endif + + +#ifdef SWIGWORDSIZE32 +%{ +#define SWIGWORDSIZE32 +#ifndef LONG_MAX +#include +#endif +#if (__WORDSIZE == 64) || (LONG_MAX != INT_MAX) +# error "SWIG wrapped code invalid in 64 bit architecture, regenarete code using -DSWIGWORDSIZE64" +#endif +%} +#endif + +#ifdef SWIGWORDSIZE64 +%{ +#define SWIGWORDSIZE64 +#ifndef LONG_MAX +#include +#endif +#if (__WORDSIZE == 32) || (LONG_MAX == INT_MAX) +# error "SWIG wrapped code invalid in 32 bit architecture, regenarete code using -DSWIGWORDSIZE32" +#endif +%} +#endif + + -- cgit From 5193e04368732874f980f681c86e2051505c0171 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 13:33:58 +0100 Subject: r26247: Don't allow use of older SWIG versions. (This used to be commit def0ae919b9b65e70124ee5bfcd70d3a22973a9b) --- source4/scripting/python/ac_pkg_swig.m4 | 125 ++++++++++++++++++++++++++++++++ source4/scripting/python/config.m4 | 5 +- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 source4/scripting/python/ac_pkg_swig.m4 (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/ac_pkg_swig.m4 b/source4/scripting/python/ac_pkg_swig.m4 new file mode 100644 index 0000000000..013743c1a0 --- /dev/null +++ b/source4/scripting/python/ac_pkg_swig.m4 @@ -0,0 +1,125 @@ +##### http://autoconf-archive.cryp.to/ac_pkg_swig.html +# +# SYNOPSIS +# +# AC_PROG_SWIG([major.minor.micro]) +# +# DESCRIPTION +# +# This macro searches for a SWIG installation on your system. If +# found you should call SWIG via $(SWIG). You can use the optional +# first argument to check if the version of the available SWIG is +# greater than or equal to the value of the argument. It should have +# the format: N[.N[.N]] (N is a number between 0 and 999. Only the +# first N is mandatory.) +# +# If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks +# that the swig package is this version number or higher. +# +# In configure.in, use as: +# +# AC_PROG_SWIG(1.3.17) +# SWIG_ENABLE_CXX +# SWIG_MULTI_MODULE_SUPPORT +# SWIG_PYTHON +# +# LAST MODIFICATION +# +# 2006-10-22 +# +# COPYLEFT +# +# Copyright (c) 2006 Sebastian Huber +# Copyright (c) 2006 Alan W. Irwin +# Copyright (c) 2006 Rafael Laboissiere +# Copyright (c) 2006 Andrew Collier +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# +# As a special exception, the respective Autoconf Macro's copyright +# owner gives unlimited permission to copy, distribute and modify the +# configure scripts that are the output of Autoconf when processing +# the Macro. You need not follow the terms of the GNU General Public +# License when using or distributing such scripts, even though +# portions of the text of the Macro appear in them. The GNU General +# Public License (GPL) does govern all other use of the material that +# constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the +# Autoconf Macro released by the Autoconf Macro Archive. When you +# make and distribute a modified version of the Autoconf Macro, you +# may extend this special exception to the GPL to apply to your +# modified version as well. + +AC_DEFUN([AC_PROG_SWIG],[ + AC_PATH_PROG([SWIG],[swig]) + if test -z "$SWIG" ; then + AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org]) + SWIG='no' + elif test -n "$1" ; then + AC_MSG_CHECKING([for SWIG version]) + [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`] + AC_MSG_RESULT([$swig_version]) + if test -n "$swig_version" ; then + # Calculate the required version number components + [required=$1] + [required_major=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_major" ; then + [required_major=0] + fi + [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] + [required_minor=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_minor" ; then + [required_minor=0] + fi + [required=`echo $required | sed 's/[0-9]*[^0-9]//'`] + [required_patch=`echo $required | sed 's/[^0-9].*//'`] + if test -z "$required_patch" ; then + [required_patch=0] + fi + # Calculate the available version number components + [available=$swig_version] + [available_major=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_major" ; then + [available_major=0] + fi + [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] + [available_minor=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_minor" ; then + [available_minor=0] + fi + [available=`echo $available | sed 's/[0-9]*[^0-9]//'`] + [available_patch=`echo $available | sed 's/[^0-9].*//'`] + if test -z "$available_patch" ; then + [available_patch=0] + fi + if test $available_major -ne $required_major \ + -o $available_minor -ne $required_minor \ + -o $available_patch -lt $required_patch ; then + AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org]) + SWIG='no' + else + AC_MSG_NOTICE([SWIG executable is '$SWIG']) + SWIG_LIB=`$SWIG -swiglib` + AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB']) + fi + else + AC_MSG_WARN([cannot determine SWIG version]) + SWIG='no' + fi + fi + AC_SUBST([SWIG_LIB]) +]) diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index bdc977b0ba..8a4aba4a66 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -1,9 +1,12 @@ +m4_include(scripting/python/ac_pkg_swig.m4) + AC_ARG_VAR([PYTHON_VERSION],[The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name.]) -AC_PATH_PROG(SWIG,swig,no) +AC_PROG_SWIG(1.3.25) + AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then working_python=no -- cgit From 53ae9bc9f6f66578948c3995073bdc1f1acae0f1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Dec 2007 13:48:09 +0100 Subject: r26248: Check in SWIG output so SWIG is not required when running out of svn. (This used to be commit 08501fbef38f81ce5ff4885a1696f9cb392fd631) --- source4/scripting/python/config.m4 | 2 +- source4/scripting/python/misc.py | 53 + source4/scripting/python/misc_wrap.c | 3279 +++++++++++++++++++++++++++ source4/scripting/python/replace/stdint.i | 109 - source4/scripting/python/replace/swigarch.i | 65 - 5 files changed, 3333 insertions(+), 175 deletions(-) create mode 100644 source4/scripting/python/misc.py create mode 100644 source4/scripting/python/misc_wrap.c delete mode 100644 source4/scripting/python/replace/stdint.i delete mode 100644 source4/scripting/python/replace/swigarch.i (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 8a4aba4a66..5e982556fc 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -5,7 +5,7 @@ AC_ARG_VAR([PYTHON_VERSION],[The installed Python will be appended to the Python interpreter canonical name.]) -AC_PROG_SWIG(1.3.25) +AC_PROG_SWIG(1.3.31) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py new file mode 100644 index 0000000000..94625be2c9 --- /dev/null +++ b/source4/scripting/python/misc.py @@ -0,0 +1,53 @@ +# This file was automatically generated by SWIG (http://www.swig.org). +# Version 1.3.33 +# +# Don't modify this file, modify the SWIG interface instead. +# This file is compatible with both classic and new-style classes. + +import _misc +import new +new_instancemethod = new.instancemethod +try: + _swig_property = property +except NameError: + pass # Python < 2.2 doesn't have 'property'. +def _swig_setattr_nondynamic(self,class_type,name,value,static=1): + if (name == "thisown"): return self.this.own(value) + if (name == "this"): + if type(value).__name__ == 'PySwigObject': + self.__dict__[name] = value + return + method = class_type.__swig_setmethods__.get(name,None) + if method: return method(self,value) + if (not static) or hasattr(self,name): + self.__dict__[name] = value + else: + raise AttributeError("You cannot add attributes to %s" % self) + +def _swig_setattr(self,class_type,name,value): + return _swig_setattr_nondynamic(self,class_type,name,value,0) + +def _swig_getattr(self,class_type,name): + if (name == "thisown"): return self.this.own() + method = class_type.__swig_getmethods__.get(name,None) + if method: return method(self) + raise AttributeError,name + +def _swig_repr(self): + try: strthis = "proxy of " + self.this.__repr__() + except: strthis = "" + return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) + +import types +try: + _object = types.ObjectType + _newclass = 1 +except AttributeError: + class _object : pass + _newclass = 0 +del types + + +random_password = _misc.random_password + + diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c new file mode 100644 index 0000000000..2237f9cb03 --- /dev/null +++ b/source4/scripting/python/misc_wrap.c @@ -0,0 +1,3279 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.33 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +#define SWIGPYTHON +#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +/* Python.h has to appear first */ +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic CAPI SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "3" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the swig runtime code. + In 99.9% of the cases, swig just needs to declare them as 'static'. + + But only do this if is strictly necessary, ie, if you have problems + with your compiler or so. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The swig conversion methods, as ConvertPtr, return and integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old swig versions, you usually write code as: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit as: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + that seems to be the same, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + requires also to SWIG_ConvertPtr to return new result values, as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + swig errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() + + + */ +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store inforomation on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* think of this as a c++ template<> or a scheme macro */ +#define SWIG_TypeCheck_Template(comparison, ty) \ + if (ty) { \ + swig_cast_info *iter = ty->cast; \ + while (iter) { \ + if (comparison) { \ + if (iter == ty->cast) return iter; \ + /* Move iter to the top of the linked list */ \ + iter->prev->next = iter->next; \ + if (iter->next) \ + iter->next->prev = iter->prev; \ + iter->next = ty->cast; \ + iter->prev = 0; \ + if (ty->cast) ty->cast->prev = iter; \ + ty->cast = iter; \ + return iter; \ + } \ + iter = iter->next; \ + } \ + } \ + return 0 + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); +} + +/* Same as previous function, except strcmp is replaced with a pointer comparison */ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { + SWIG_TypeCheck_Template(iter->type == from, into); +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +/* Add PyOS_snprintf for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) +# define PyOS_snprintf _snprintf +# else +# define PyOS_snprintf snprintf +# endif +#endif + +/* A crude PyString_FromFormat implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 + +#ifndef SWIG_PYBUFFER_SIZE +# define SWIG_PYBUFFER_SIZE 1024 +#endif + +static PyObject * +PyString_FromFormat(const char *fmt, ...) { + va_list ap; + char buf[SWIG_PYBUFFER_SIZE * 2]; + int res; + va_start(ap, fmt); + res = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); +} +#endif + +/* Add PyObject_Del for old Pythons */ +#if PY_VERSION_HEX < 0x01060000 +# define PyObject_Del(op) PyMem_DEL((op)) +#endif +#ifndef PyObject_DEL +# define PyObject_DEL PyObject_Del +#endif + +/* A crude PyExc_StopIteration exception for old Pythons */ +#if PY_VERSION_HEX < 0x02020000 +# ifndef PyExc_StopIteration +# define PyExc_StopIteration PyExc_RuntimeError +# endif +# ifndef PyObject_GenericGetAttr +# define PyObject_GenericGetAttr 0 +# endif +#endif +/* Py_NotImplemented is defined in 2.1 and up. */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef Py_NotImplemented +# define Py_NotImplemented PyExc_RuntimeError +# endif +#endif + + +/* A crude PyString_AsStringAndSize implementation for old Pythons */ +#if PY_VERSION_HEX < 0x02010000 +# ifndef PyString_AsStringAndSize +# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} +# endif +#endif + +/* PySequence_Size for old Pythons */ +#if PY_VERSION_HEX < 0x02000000 +# ifndef PySequence_Size +# define PySequence_Size PySequence_Length +# endif +#endif + + +/* PyBool_FromLong for old Pythons */ +#if PY_VERSION_HEX < 0x02030000 +static +PyObject *PyBool_FromLong(long ok) +{ + PyObject *result = ok ? Py_True : Py_False; + Py_INCREF(result); + return result; +} +#endif + +/* Py_ssize_t for old Pythons */ +/* This code is as recommended by: */ +/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +# define PY_SSIZE_T_MAX INT_MAX +# define PY_SSIZE_T_MIN INT_MIN +#endif + +/* ----------------------------------------------------------------------------- + * error manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIME PyObject* +SWIG_Python_ErrorType(int code) { + PyObject* type = 0; + switch(code) { + case SWIG_MemoryError: + type = PyExc_MemoryError; + break; + case SWIG_IOError: + type = PyExc_IOError; + break; + case SWIG_RuntimeError: + type = PyExc_RuntimeError; + break; + case SWIG_IndexError: + type = PyExc_IndexError; + break; + case SWIG_TypeError: + type = PyExc_TypeError; + break; + case SWIG_DivisionByZero: + type = PyExc_ZeroDivisionError; + break; + case SWIG_OverflowError: + type = PyExc_OverflowError; + break; + case SWIG_SyntaxError: + type = PyExc_SyntaxError; + break; + case SWIG_ValueError: + type = PyExc_ValueError; + break; + case SWIG_SystemError: + type = PyExc_SystemError; + break; + case SWIG_AttributeError: + type = PyExc_AttributeError; + break; + default: + type = PyExc_RuntimeError; + } + return type; +} + + +SWIGRUNTIME void +SWIG_Python_AddErrorMsg(const char* mesg) +{ + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + + if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + PyErr_Clear(); + Py_XINCREF(type); + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + Py_DECREF(old_str); + Py_DECREF(value); + } else { + PyErr_Format(PyExc_RuntimeError, mesg); + } +} + + + +#if defined(SWIG_PYTHON_NO_THREADS) +# if defined(SWIG_PYTHON_THREADS) +# undef SWIG_PYTHON_THREADS +# endif +#endif +#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ +# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) +# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ +# define SWIG_PYTHON_USE_GIL +# endif +# endif +# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ +# ifndef SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() +# endif +# ifdef __cplusplus /* C++ code */ + class SWIG_Python_Thread_Block { + bool status; + PyGILState_STATE state; + public: + void end() { if (status) { PyGILState_Release(state); status = false;} } + SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} + ~SWIG_Python_Thread_Block() { end(); } + }; + class SWIG_Python_Thread_Allow { + bool status; + PyThreadState *save; + public: + void end() { if (status) { PyEval_RestoreThread(save); status = false; }} + SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} + ~SWIG_Python_Thread_Allow() { end(); } + }; +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block +# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow +# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() +# else /* C code */ +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() +# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() +# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) +# endif +# else /* Old thread way, not implemented, user must provide it */ +# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) +# define SWIG_PYTHON_INITIALIZE_THREADS +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) +# define SWIG_PYTHON_THREAD_END_BLOCK +# endif +# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# endif +# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) +# define SWIG_PYTHON_THREAD_END_ALLOW +# endif +# endif +#else /* No thread support */ +# define SWIG_PYTHON_INITIALIZE_THREADS +# define SWIG_PYTHON_THREAD_BEGIN_BLOCK +# define SWIG_PYTHON_THREAD_END_BLOCK +# define SWIG_PYTHON_THREAD_BEGIN_ALLOW +# define SWIG_PYTHON_THREAD_END_ALLOW +#endif + +/* ----------------------------------------------------------------------------- + * Python API portion that goes into the runtime + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* ----------------------------------------------------------------------------- + * Constant declarations + * ----------------------------------------------------------------------------- */ + +/* Constant Types */ +#define SWIG_PY_POINTER 4 +#define SWIG_PY_BINARY 5 + +/* Constant information structure */ +typedef struct swig_const_info { + int type; + char *name; + long lvalue; + double dvalue; + void *pvalue; + swig_type_info **ptype; +} swig_const_info; + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * pyrun.swg + * + * This file contains the runtime support for Python modules + * and includes code for managing global variables and pointer + * type checking. + * + * ----------------------------------------------------------------------------- */ + +/* Common SWIG API */ + +/* for raw pointers */ +#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) +#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) +#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) +#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) +#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) +#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) +#define swig_owntype int + +/* for raw packed data */ +#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + +/* for class or struct pointers */ +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) + +/* for C or C++ function pointers */ +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) + +/* for C++ member pointers, ie, member methods */ +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) + + +/* Runtime API */ + +#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) +#define SWIG_NewClientData(obj) PySwigClientData_New(obj) + +#define SWIG_SetErrorObj SWIG_Python_SetErrorObj +#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg +#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) +#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) +#define SWIG_fail goto fail + + +/* Runtime API implementation */ + +/* Error manipulation */ + +SWIGINTERN void +SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetObject(errtype, obj); + Py_DECREF(obj); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +SWIGINTERN void +SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + PyErr_SetString(errtype, (char *) msg); + SWIG_PYTHON_THREAD_END_BLOCK; +} + +#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) + +/* Set a constant value */ + +SWIGINTERN void +SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { + PyDict_SetItemString(d, (char*) name, obj); + Py_DECREF(obj); +} + +/* Append a value to the result obj */ + +SWIGINTERN PyObject* +SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { +#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyList_Check(result)) { + PyObject *o2 = result; + result = PyList_New(1); + PyList_SetItem(result, 0, o2); + } + PyList_Append(result,obj); + Py_DECREF(obj); + } + return result; +#else + PyObject* o2; + PyObject* o3; + if (!result) { + result = obj; + } else if (result == Py_None) { + Py_DECREF(result); + result = obj; + } else { + if (!PyTuple_Check(result)) { + o2 = result; + result = PyTuple_New(1); + PyTuple_SET_ITEM(result, 0, o2); + } + o3 = PyTuple_New(1); + PyTuple_SET_ITEM(o3, 0, obj); + o2 = result; + result = PySequence_Concat(o2, o3); + Py_DECREF(o2); + Py_DECREF(o3); + } + return result; +#endif +} + +/* Unpack the argument tuple */ + +SWIGINTERN int +SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) +{ + if (!args) { + if (!min && !max) { + return 1; + } else { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", + name, (min == max ? "" : "at least "), (int)min); + return 0; + } + } + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); + return 0; + } else { + register Py_ssize_t l = PyTuple_GET_SIZE(args); + if (l < min) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at least "), (int)min, (int)l); + return 0; + } else if (l > max) { + PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", + name, (min == max ? "" : "at most "), (int)max, (int)l); + return 0; + } else { + register int i; + for (i = 0; i < l; ++i) { + objs[i] = PyTuple_GET_ITEM(args, i); + } + for (; l < max; ++l) { + objs[l] = 0; + } + return i + 1; + } + } +} + +/* A functor is a function object with one single object argument */ +#if PY_VERSION_HEX >= 0x02020000 +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); +#else +#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); +#endif + +/* + Helper for static pointer initialization for both C and C++ code, for example + static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); +*/ +#ifdef __cplusplus +#define SWIG_STATIC_POINTER(var) var +#else +#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var +#endif + +/* ----------------------------------------------------------------------------- + * Pointer declarations + * ----------------------------------------------------------------------------- */ + +/* Flags for new pointer objects */ +#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) +#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) + +#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* cc-mode */ +#endif +#endif + +/* How to access Py_None */ +#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# ifndef SWIG_PYTHON_NO_BUILD_NONE +# ifndef SWIG_PYTHON_BUILD_NONE +# define SWIG_PYTHON_BUILD_NONE +# endif +# endif +#endif + +#ifdef SWIG_PYTHON_BUILD_NONE +# ifdef Py_None +# undef Py_None +# define Py_None SWIG_Py_None() +# endif +SWIGRUNTIMEINLINE PyObject * +_SWIG_Py_None(void) +{ + PyObject *none = Py_BuildValue((char*)""); + Py_DECREF(none); + return none; +} +SWIGRUNTIME PyObject * +SWIG_Py_None(void) +{ + static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); + return none; +} +#endif + +/* The python void return value */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Py_Void(void) +{ + PyObject *none = Py_None; + Py_INCREF(none); + return none; +} + +/* PySwigClientData */ + +typedef struct { + PyObject *klass; + PyObject *newraw; + PyObject *newargs; + PyObject *destroy; + int delargs; + int implicitconv; +} PySwigClientData; + +SWIGRUNTIMEINLINE int +SWIG_Python_CheckImplicit(swig_type_info *ty) +{ + PySwigClientData *data = (PySwigClientData *)ty->clientdata; + return data ? data->implicitconv : 0; +} + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_ExceptionType(swig_type_info *desc) { + PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; + PyObject *klass = data ? data->klass : 0; + return (klass ? klass : PyExc_RuntimeError); +} + + +SWIGRUNTIME PySwigClientData * +PySwigClientData_New(PyObject* obj) +{ + if (!obj) { + return 0; + } else { + PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); + /* the klass element */ + data->klass = obj; + Py_INCREF(data->klass); + /* the newraw method and newargs arguments used to create a new raw instance */ + if (PyClass_Check(obj)) { + data->newraw = 0; + data->newargs = obj; + Py_INCREF(obj); + } else { +#if (PY_VERSION_HEX < 0x02020000) + data->newraw = 0; +#else + data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); +#endif + if (data->newraw) { + Py_INCREF(data->newraw); + data->newargs = PyTuple_New(1); + PyTuple_SetItem(data->newargs, 0, obj); + } else { + data->newargs = obj; + } + Py_INCREF(data->newargs); + } + /* the destroy method, aka as the C++ delete method */ + data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); + if (PyErr_Occurred()) { + PyErr_Clear(); + data->destroy = 0; + } + if (data->destroy) { + int flags; + Py_INCREF(data->destroy); + flags = PyCFunction_GET_FLAGS(data->destroy); +#ifdef METH_O + data->delargs = !(flags & (METH_O)); +#else + data->delargs = 0; +#endif + } else { + data->delargs = 0; + } + data->implicitconv = 0; + return data; + } +} + +SWIGRUNTIME void +PySwigClientData_Del(PySwigClientData* data) +{ + Py_XDECREF(data->newraw); + Py_XDECREF(data->newargs); + Py_XDECREF(data->destroy); +} + +/* =============== PySwigObject =====================*/ + +typedef struct { + PyObject_HEAD + void *ptr; + swig_type_info *ty; + int own; + PyObject *next; +} PySwigObject; + +SWIGRUNTIME PyObject * +PySwigObject_long(PySwigObject *v) +{ + return PyLong_FromVoidPtr(v->ptr); +} + +SWIGRUNTIME PyObject * +PySwigObject_format(const char* fmt, PySwigObject *v) +{ + PyObject *res = NULL; + PyObject *args = PyTuple_New(1); + if (args) { + if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { + PyObject *ofmt = PyString_FromString(fmt); + if (ofmt) { + res = PyString_Format(ofmt,args); + Py_DECREF(ofmt); + } + Py_DECREF(args); + } + } + return res; +} + +SWIGRUNTIME PyObject * +PySwigObject_oct(PySwigObject *v) +{ + return PySwigObject_format("%o",v); +} + +SWIGRUNTIME PyObject * +PySwigObject_hex(PySwigObject *v) +{ + return PySwigObject_format("%x",v); +} + +SWIGRUNTIME PyObject * +#ifdef METH_NOARGS +PySwigObject_repr(PySwigObject *v) +#else +PySwigObject_repr(PySwigObject *v, PyObject *args) +#endif +{ + const char *name = SWIG_TypePrettyName(v->ty); + PyObject *hex = PySwigObject_hex(v); + PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); + Py_DECREF(hex); + if (v->next) { +#ifdef METH_NOARGS + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); +#else + PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); +#endif + PyString_ConcatAndDel(&repr,nrep); + } + return repr; +} + +SWIGRUNTIME int +PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ +#ifdef METH_NOARGS + PyObject *repr = PySwigObject_repr(v); +#else + PyObject *repr = PySwigObject_repr(v, NULL); +#endif + if (repr) { + fputs(PyString_AsString(repr), fp); + Py_DECREF(repr); + return 0; + } else { + return 1; + } +} + +SWIGRUNTIME PyObject * +PySwigObject_str(PySwigObject *v) +{ + char result[SWIG_BUFFER_SIZE]; + return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? + PyString_FromString(result) : 0; +} + +SWIGRUNTIME int +PySwigObject_compare(PySwigObject *v, PySwigObject *w) +{ + void *i = v->ptr; + void *j = w->ptr; + return (i < j) ? -1 : ((i > j) ? 1 : 0); +} + +SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigObject_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigObject_Check(PyObject *op) { + return ((op)->ob_type == PySwigObject_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own); + +SWIGRUNTIME void +PySwigObject_dealloc(PyObject *v) +{ + PySwigObject *sobj = (PySwigObject *) v; + PyObject *next = sobj->next; + if (sobj->own) { + swig_type_info *ty = sobj->ty; + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + PyObject *destroy = data ? data->destroy : 0; + if (destroy) { + /* destroy is always a VARARGS method */ + PyObject *res; + if (data->delargs) { + /* we need to create a temporal object to carry the destroy operation */ + PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); + res = SWIG_Python_CallFunctor(destroy, tmp); + Py_DECREF(tmp); + } else { + PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); + PyObject *mself = PyCFunction_GET_SELF(destroy); + res = ((*meth)(mself, v)); + } + Py_XDECREF(res); + } else { + const char *name = SWIG_TypePrettyName(ty); +#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); +#endif + } + } + Py_XDECREF(next); + PyObject_DEL(v); +} + +SWIGRUNTIME PyObject* +PySwigObject_append(PyObject* v, PyObject* next) +{ + PySwigObject *sobj = (PySwigObject *) v; +#ifndef METH_O + PyObject *tmp = 0; + if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; + next = tmp; +#endif + if (!PySwigObject_Check(next)) { + return NULL; + } + sobj->next = next; + Py_INCREF(next); + return SWIG_Py_Void(); +} + +SWIGRUNTIME PyObject* +#ifdef METH_NOARGS +PySwigObject_next(PyObject* v) +#else +PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *) v; + if (sobj->next) { + Py_INCREF(sobj->next); + return sobj->next; + } else { + return SWIG_Py_Void(); + } +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_disown(PyObject *v) +#else +PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = 0; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +#ifdef METH_NOARGS +PySwigObject_acquire(PyObject *v) +#else +PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) +#endif +{ + PySwigObject *sobj = (PySwigObject *)v; + sobj->own = SWIG_POINTER_OWN; + return SWIG_Py_Void(); +} + +SWIGINTERN PyObject* +PySwigObject_own(PyObject *v, PyObject *args) +{ + PyObject *val = 0; +#if (PY_VERSION_HEX < 0x02020000) + if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) +#else + if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) +#endif + { + return NULL; + } + else + { + PySwigObject *sobj = (PySwigObject *)v; + PyObject *obj = PyBool_FromLong(sobj->own); + if (val) { +#ifdef METH_NOARGS + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v); + } else { + PySwigObject_disown(v); + } +#else + if (PyObject_IsTrue(val)) { + PySwigObject_acquire(v,args); + } else { + PySwigObject_disown(v,args); + } +#endif + } + return obj; + } +} + +#ifdef METH_O +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#else +static PyMethodDef +swigobject_methods[] = { + {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, + {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, + {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, + {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, + {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, + {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, + {0, 0, 0, 0} +}; +#endif + +#if PY_VERSION_HEX < 0x02020000 +SWIGINTERN PyObject * +PySwigObject_getattr(PySwigObject *sobj,char *name) +{ + return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); +} +#endif + +SWIGRUNTIME PyTypeObject* +_PySwigObject_type(void) { + static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; + + static PyNumberMethods PySwigObject_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)0, /*nb_multiply*/ + (binaryfunc)0, /*nb_divide*/ + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0,/*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + 0, /*nb_invert*/ + 0, /*nb_lshift*/ + 0, /*nb_rshift*/ + 0, /*nb_and*/ + 0, /*nb_xor*/ + 0, /*nb_or*/ + (coercion)0, /*nb_coerce*/ + (unaryfunc)PySwigObject_long, /*nb_int*/ + (unaryfunc)PySwigObject_long, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ + (unaryfunc)PySwigObject_oct, /*nb_oct*/ + (unaryfunc)PySwigObject_hex, /*nb_hex*/ +#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ +#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ +#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */ + 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ +#endif + }; + + static PyTypeObject pyswigobject_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigObject", /* tp_name */ + sizeof(PySwigObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigObject_dealloc, /* tp_dealloc */ + (printfunc)PySwigObject_print, /* tp_print */ +#if PY_VERSION_HEX < 0x02020000 + (getattrfunc)PySwigObject_getattr, /* tp_getattr */ +#else + (getattrfunc)0, /* tp_getattr */ +#endif + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigObject_compare, /* tp_compare */ + (reprfunc)PySwigObject_repr, /* tp_repr */ + &PySwigObject_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigObject_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigobject_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + swigobject_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigobject_type = tmp; + pyswigobject_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigobject_type; +} + +SWIGRUNTIME PyObject * +PySwigObject_New(void *ptr, swig_type_info *ty, int own) +{ + PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); + if (sobj) { + sobj->ptr = ptr; + sobj->ty = ty; + sobj->own = own; + sobj->next = 0; + } + return (PyObject *)sobj; +} + +/* ----------------------------------------------------------------------------- + * Implements a simple Swig Packed type, and use it instead of string + * ----------------------------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + void *pack; + swig_type_info *ty; + size_t size; +} PySwigPacked; + +SWIGRUNTIME int +PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) +{ + char result[SWIG_BUFFER_SIZE]; + fputs("pack, v->size, 0, sizeof(result))) { + fputs("at ", fp); + fputs(result, fp); + } + fputs(v->ty->name,fp); + fputs(">", fp); + return 0; +} + +SWIGRUNTIME PyObject * +PySwigPacked_repr(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { + return PyString_FromFormat("", result, v->ty->name); + } else { + return PyString_FromFormat("", v->ty->name); + } +} + +SWIGRUNTIME PyObject * +PySwigPacked_str(PySwigPacked *v) +{ + char result[SWIG_BUFFER_SIZE]; + if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ + return PyString_FromFormat("%s%s", result, v->ty->name); + } else { + return PyString_FromString(v->ty->name); + } +} + +SWIGRUNTIME int +PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) +{ + size_t i = v->size; + size_t j = w->size; + int s = (i < j) ? -1 : ((i > j) ? 1 : 0); + return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); +} + +SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); + +SWIGRUNTIME PyTypeObject* +PySwigPacked_type(void) { + static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); + return type; +} + +SWIGRUNTIMEINLINE int +PySwigPacked_Check(PyObject *op) { + return ((op)->ob_type == _PySwigPacked_type()) + || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); +} + +SWIGRUNTIME void +PySwigPacked_dealloc(PyObject *v) +{ + if (PySwigPacked_Check(v)) { + PySwigPacked *sobj = (PySwigPacked *) v; + free(sobj->pack); + } + PyObject_DEL(v); +} + +SWIGRUNTIME PyTypeObject* +_PySwigPacked_type(void) { + static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; + static PyTypeObject pyswigpacked_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + (char *)"PySwigPacked", /* tp_name */ + sizeof(PySwigPacked), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)PySwigPacked_dealloc, /* tp_dealloc */ + (printfunc)PySwigPacked_print, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)PySwigPacked_compare, /* tp_compare */ + (reprfunc)PySwigPacked_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)0, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)PySwigPacked_str, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + swigpacked_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ + 0, /* tp_mro */ + 0, /* tp_cache */ + 0, /* tp_subclasses */ + 0, /* tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + pyswigpacked_type = tmp; + pyswigpacked_type.ob_type = &PyType_Type; + type_init = 1; + } + return &pyswigpacked_type; +} + +SWIGRUNTIME PyObject * +PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) +{ + PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); + if (sobj) { + void *pack = malloc(size); + if (pack) { + memcpy(pack, ptr, size); + sobj->pack = pack; + sobj->ty = ty; + sobj->size = size; + } else { + PyObject_DEL((PyObject *) sobj); + sobj = 0; + } + } + return (PyObject *) sobj; +} + +SWIGRUNTIME swig_type_info * +PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) +{ + if (PySwigPacked_Check(obj)) { + PySwigPacked *sobj = (PySwigPacked *)obj; + if (sobj->size != size) return 0; + memcpy(ptr, sobj->pack, size); + return sobj->ty; + } else { + return 0; + } +} + +/* ----------------------------------------------------------------------------- + * pointers/data manipulation + * ----------------------------------------------------------------------------- */ + +SWIGRUNTIMEINLINE PyObject * +_SWIG_This(void) +{ + return PyString_FromString("this"); +} + +SWIGRUNTIME PyObject * +SWIG_This(void) +{ + static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); + return swig_this; +} + +/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ + +SWIGRUNTIME PySwigObject * +SWIG_Python_GetSwigThis(PyObject *pyobj) +{ + if (PySwigObject_Check(pyobj)) { + return (PySwigObject *) pyobj; + } else { + PyObject *obj = 0; +#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) + if (PyInstance_Check(pyobj)) { + obj = _PyInstance_Lookup(pyobj, SWIG_This()); + } else { + PyObject **dictptr = _PyObject_GetDictPtr(pyobj); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; + } else { +#ifdef PyWeakref_CheckProxy + if (PyWeakref_CheckProxy(pyobj)) { + PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); + return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; + } +#endif + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } + } + } +#else + obj = PyObject_GetAttr(pyobj,SWIG_This()); + if (obj) { + Py_DECREF(obj); + } else { + if (PyErr_Occurred()) PyErr_Clear(); + return 0; + } +#endif + if (obj && !PySwigObject_Check(obj)) { + /* a PyObject is called 'this', try to get the 'real this' + PySwigObject from it */ + return SWIG_Python_GetSwigThis(obj); + } + return (PySwigObject *)obj; + } +} + +/* Acquire a pointer value */ + +SWIGRUNTIME int +SWIG_Python_AcquirePtr(PyObject *obj, int own) { + if (own) { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (sobj) { + int oldown = sobj->own; + sobj->own = own; + return oldown; + } + } + return 0; +} + +/* Convert a pointer value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { + if (!obj) return SWIG_ERROR; + if (obj == Py_None) { + if (ptr) *ptr = 0; + return SWIG_OK; + } else { + PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + while (sobj) { + void *vptr = sobj->ptr; + if (ty) { + swig_type_info *to = sobj->ty; + if (to == ty) { + /* no type cast needed */ + if (ptr) *ptr = vptr; + break; + } else { + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) { + sobj = (PySwigObject *)sobj->next; + } else { + if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + break; + } + } + } else { + if (ptr) *ptr = vptr; + break; + } + } + if (sobj) { + if (own) *own = sobj->own; + if (flags & SWIG_POINTER_DISOWN) { + sobj->own = 0; + } + return SWIG_OK; + } else { + int res = SWIG_ERROR; + if (flags & SWIG_POINTER_IMPLICIT_CONV) { + PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; + if (data && !data->implicitconv) { + PyObject *klass = data->klass; + if (klass) { + PyObject *impconv; + data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ + impconv = SWIG_Python_CallFunctor(klass, obj); + data->implicitconv = 0; + if (PyErr_Occurred()) { + PyErr_Clear(); + impconv = 0; + } + if (impconv) { + PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); + if (iobj) { + void *vptr; + res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); + if (SWIG_IsOK(res)) { + if (ptr) { + *ptr = vptr; + /* transfer the ownership to 'ptr' */ + iobj->own = 0; + res = SWIG_AddCast(res); + res = SWIG_AddNewMask(res); + } else { + res = SWIG_AddCast(res); + } + } + } + Py_DECREF(impconv); + } + } + } + } + return res; + } + } +} + +/* Convert a function ptr value */ + +SWIGRUNTIME int +SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { + if (!PyCFunction_Check(obj)) { + return SWIG_ConvertPtr(obj, ptr, ty, 0); + } else { + void *vptr = 0; + + /* here we get the method pointer for callbacks */ + const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); + const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; + if (desc) { + desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; + if (!desc) return SWIG_ERROR; + } + if (ty) { + swig_cast_info *tc = SWIG_TypeCheck(desc,ty); + if (!tc) return SWIG_ERROR; + *ptr = SWIG_TypeCast(tc,vptr); + } else { + *ptr = vptr; + } + return SWIG_OK; + } +} + +/* Convert a packed value value */ + +SWIGRUNTIME int +SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * Create a new pointer object + * ----------------------------------------------------------------------------- */ + +/* + Create a new instance object, whitout calling __init__, and set the + 'this' attribute. +*/ + +SWIGRUNTIME PyObject* +SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) +{ +#if (PY_VERSION_HEX >= 0x02020000) + PyObject *inst = 0; + PyObject *newraw = data->newraw; + if (newraw) { + inst = PyObject_Call(newraw, data->newargs, NULL); + if (inst) { +#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + PyObject *dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + PyDict_SetItem(dict, SWIG_This(), swig_this); + } + } +#else + PyObject *key = SWIG_This(); + PyObject_SetAttr(inst, key, swig_this); +#endif + } + } else { + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + } + return inst; +#else +#if (PY_VERSION_HEX >= 0x02010000) + PyObject *inst; + PyObject *dict = PyDict_New(); + PyDict_SetItem(dict, SWIG_This(), swig_this); + inst = PyInstance_NewRaw(data->newargs, dict); + Py_DECREF(dict); + return (PyObject *) inst; +#else + PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); + if (inst == NULL) { + return NULL; + } + inst->in_class = (PyClassObject *)data->newargs; + Py_INCREF(inst->in_class); + inst->in_dict = PyDict_New(); + if (inst->in_dict == NULL) { + Py_DECREF(inst); + return NULL; + } +#ifdef Py_TPFLAGS_HAVE_WEAKREFS + inst->in_weakreflist = NULL; +#endif +#ifdef Py_TPFLAGS_GC + PyObject_GC_Init(inst); +#endif + PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); + return (PyObject *) inst; +#endif +#endif +} + +SWIGRUNTIME void +SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) +{ + PyObject *dict; +#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) + PyObject **dictptr = _PyObject_GetDictPtr(inst); + if (dictptr != NULL) { + dict = *dictptr; + if (dict == NULL) { + dict = PyDict_New(); + *dictptr = dict; + } + PyDict_SetItem(dict, SWIG_This(), swig_this); + return; + } +#endif + dict = PyObject_GetAttrString(inst, (char*)"__dict__"); + PyDict_SetItem(dict, SWIG_This(), swig_this); + Py_DECREF(dict); +} + + +SWIGINTERN PyObject * +SWIG_Python_InitShadowInstance(PyObject *args) { + PyObject *obj[2]; + if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { + return NULL; + } else { + PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); + if (sthis) { + PySwigObject_append((PyObject*) sthis, obj[1]); + } else { + SWIG_Python_SetSwigThis(obj[0], obj[1]); + } + return SWIG_Py_Void(); + } +} + +/* Create a new pointer object */ + +SWIGRUNTIME PyObject * +SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { + if (!ptr) { + return SWIG_Py_Void(); + } else { + int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; + PyObject *robj = PySwigObject_New(ptr, type, own); + PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; + if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { + PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); + if (inst) { + Py_DECREF(robj); + robj = inst; + } + } + return robj; + } +} + +/* Create a new packed object */ + +SWIGRUNTIMEINLINE PyObject * +SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { + return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); +} + +/* -----------------------------------------------------------------------------* + * Get type list + * -----------------------------------------------------------------------------*/ + +#ifdef SWIG_LINK_RUNTIME +void *SWIG_ReturnGlobalTypeList(void *); +#endif + +SWIGRUNTIME swig_module_info * +SWIG_Python_GetModule(void) { + static void *type_pointer = (void *)0; + /* first check if module already created */ + if (!type_pointer) { +#ifdef SWIG_LINK_RUNTIME + type_pointer = SWIG_ReturnGlobalTypeList((void *)0); +#else + type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); + if (PyErr_Occurred()) { + PyErr_Clear(); + type_pointer = (void *)0; + } +#endif + } + return (swig_module_info *) type_pointer; +} + +#if PY_MAJOR_VERSION < 2 +/* PyModule_AddObject function was introduced in Python 2.0. The following function + is copied out of Python/modsupport.c in python version 2.3.4 */ +SWIGINTERN int +PyModule_AddObject(PyObject *m, char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return SWIG_ERROR; + } + if (!o) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return SWIG_ERROR; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return SWIG_ERROR; + } + if (PyDict_SetItemString(dict, name, o)) + return SWIG_ERROR; + Py_DECREF(o); + return SWIG_OK; +} +#endif + +SWIGRUNTIME void +SWIG_Python_DestroyModule(void *vptr) +{ + swig_module_info *swig_module = (swig_module_info *) vptr; + swig_type_info **types = swig_module->types; + size_t i; + for (i =0; i < swig_module->size; ++i) { + swig_type_info *ty = types[i]; + if (ty->owndata) { + PySwigClientData *data = (PySwigClientData *) ty->clientdata; + if (data) PySwigClientData_Del(data); + } + } + Py_DECREF(SWIG_This()); +} + +SWIGRUNTIME void +SWIG_Python_SetModule(swig_module_info *swig_module) { + static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ + + PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, + swig_empty_runtime_method_table); + PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); + if (pointer && module) { + PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); + } else { + Py_XDECREF(pointer); + } +} + +/* The python cached type query */ +SWIGRUNTIME PyObject * +SWIG_Python_TypeCache(void) { + static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); + return cache; +} + +SWIGRUNTIME swig_type_info * +SWIG_Python_TypeQuery(const char *type) +{ + PyObject *cache = SWIG_Python_TypeCache(); + PyObject *key = PyString_FromString(type); + PyObject *obj = PyDict_GetItem(cache, key); + swig_type_info *descriptor; + if (obj) { + descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); + } else { + swig_module_info *swig_module = SWIG_Python_GetModule(); + descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); + if (descriptor) { + obj = PyCObject_FromVoidPtr(descriptor, NULL); + PyDict_SetItem(cache, key, obj); + Py_DECREF(obj); + } + } + Py_DECREF(key); + return descriptor; +} + +/* + For backward compatibility only +*/ +#define SWIG_POINTER_EXCEPTION 0 +#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) +#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) + +SWIGRUNTIME int +SWIG_Python_AddErrMesg(const char* mesg, int infront) +{ + if (PyErr_Occurred()) { + PyObject *type = 0; + PyObject *value = 0; + PyObject *traceback = 0; + PyErr_Fetch(&type, &value, &traceback); + if (value) { + PyObject *old_str = PyObject_Str(value); + Py_XINCREF(type); + PyErr_Clear(); + if (infront) { + PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); + } else { + PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); + } + Py_DECREF(old_str); + } + return 1; + } else { + return 0; + } +} + +SWIGRUNTIME int +SWIG_Python_ArgFail(int argnum) +{ + if (PyErr_Occurred()) { + /* add information about failing argument */ + char mesg[256]; + PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); + return SWIG_Python_AddErrMesg(mesg, 1); + } else { + return 0; + } +} + +SWIGRUNTIMEINLINE const char * +PySwigObject_GetDesc(PyObject *self) +{ + PySwigObject *v = (PySwigObject *)self; + swig_type_info *ty = v ? v->ty : 0; + return ty ? ty->str : (char*)""; +} + +SWIGRUNTIME void +SWIG_Python_TypeError(const char *type, PyObject *obj) +{ + if (type) { +#if defined(SWIG_COBJECT_TYPES) + if (obj && PySwigObject_Check(obj)) { + const char *otype = (const char *) PySwigObject_GetDesc(obj); + if (otype) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", + type, otype); + return; + } + } else +#endif + { + const char *otype = (obj ? obj->ob_type->tp_name : 0); + if (otype) { + PyObject *str = PyObject_Str(obj); + const char *cstr = str ? PyString_AsString(str) : 0; + if (cstr) { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", + type, otype, cstr); + } else { + PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", + type, otype); + } + Py_XDECREF(str); + return; + } + } + PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); + } else { + PyErr_Format(PyExc_TypeError, "unexpected type is received"); + } +} + + +/* Convert a pointer value, signal an exception on a type mismatch */ +SWIGRUNTIME void * +SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { + void *result; + if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { + PyErr_Clear(); + if (flags & SWIG_POINTER_EXCEPTION) { + SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); + SWIG_Python_ArgFail(argnum); + } + } + return result; +} + + +#ifdef __cplusplus +#if 0 +{ /* cc-mode */ +#endif +} +#endif + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_TALLOC_CTX swig_types[0] +#define SWIGTYPE_p_char swig_types[1] +#define SWIGTYPE_p_int swig_types[2] +#define SWIGTYPE_p_long_long swig_types[3] +#define SWIGTYPE_p_short swig_types[4] +#define SWIGTYPE_p_signed_char swig_types[5] +#define SWIGTYPE_p_unsigned_char swig_types[6] +#define SWIGTYPE_p_unsigned_int swig_types[7] +#define SWIGTYPE_p_unsigned_long_long swig_types[8] +#define SWIGTYPE_p_unsigned_short swig_types[9] +static swig_type_info *swig_types[11]; +static swig_module_info swig_module = {swig_types, 10, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + +#if (PY_VERSION_HEX <= 0x02000000) +# if !defined(SWIG_PYTHON_CLASSIC) +# error "This python version requires swig to be run with the '-classic' option" +# endif +#endif + +/*----------------------------------------------- + @(target):= _misc.so + ------------------------------------------------*/ +#define SWIG_init init_misc + +#define SWIG_name "_misc" + +#define SWIGVERSION 0x010333 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "includes.h" +#include "ldb.h" +#include "auth/credentials/credentials.h" + + +SWIGINTERN int +SWIG_AsVal_double (PyObject *obj, double *val) +{ + int res = SWIG_TypeError; + if (PyFloat_Check(obj)) { + if (val) *val = PyFloat_AsDouble(obj); + return SWIG_OK; + } else if (PyInt_Check(obj)) { + if (val) *val = PyInt_AsLong(obj); + return SWIG_OK; + } else if (PyLong_Check(obj)) { + double v = PyLong_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + double d = PyFloat_AsDouble(obj); + if (!PyErr_Occurred()) { + if (val) *val = d; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + long v = PyLong_AsLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); + } else { + PyErr_Clear(); + } + } + } +#endif + return res; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val) +{ + if (PyInt_Check(obj)) { + long v = PyInt_AsLong(obj); + if (v >= 0) { + if (val) *val = v; + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else if (PyLong_Check(obj)) { + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_OK; + } else { + PyErr_Clear(); + } + } +#ifdef SWIG_PYTHON_CAST_MODE + { + int dispatch = 0; + unsigned long v = PyLong_AsUnsignedLong(obj); + if (!PyErr_Occurred()) { + if (val) *val = v; + return SWIG_AddCast(SWIG_OK); + } else { + PyErr_Clear(); + } + if (!dispatch) { + double d; + int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); + if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { + if (val) *val = (unsigned long)(d); + return res; + } + } + } +#endif + return SWIG_TypeError; +} + + +SWIGINTERNINLINE int +SWIG_AsVal_size_t (PyObject * obj, size_t *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0); + if (SWIG_IsOK(res) && val) *val = (size_t)(v); + return res; +} + + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + return pchar_descriptor ? + SWIG_NewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); + } else { + return PyString_FromStringAndSize(carray, (int)(size)); + } + } else { + return SWIG_Py_Void(); + } +} + + +SWIGINTERNINLINE PyObject * +SWIG_FromCharPtr(const char *cptr) +{ + return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); +} + +#ifdef __cplusplus +extern "C" { +#endif +SWIGINTERN PyObject *_wrap_random_password(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + size_t arg2 ; + char *result = 0 ; + size_t val2 ; + int ecode2 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "len", NULL + }; + + { + arg1 = NULL; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:random_password",kwnames,&obj0)) SWIG_fail; + ecode2 = SWIG_AsVal_size_t(obj0, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "random_password" "', argument " "2"" of type '" "size_t""'"); + } + arg2 = (size_t)(val2); + result = (char *)generate_random_str(arg1,arg2); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + +static PyMethodDef SwigMethods[] = { + { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, + { NULL, NULL, 0, NULL } +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_TALLOC_CTX, + &_swigt__p_char, + &_swigt__p_int, + &_swigt__p_long_long, + &_swigt__p_short, + &_swigt__p_signed_char, + &_swigt__p_unsigned_char, + &_swigt__p_unsigned_int, + &_swigt__p_unsigned_long_long, + &_swigt__p_unsigned_short, +}; + +static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_TALLOC_CTX, + _swigc__p_char, + _swigc__p_int, + _swigc__p_long_long, + _swigc__p_short, + _swigc__p_signed_char, + _swigc__p_unsigned_char, + _swigc__p_unsigned_int, + _swigc__p_unsigned_long_long, + _swigc__p_unsigned_short, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + +static swig_const_info swig_const_table[] = { +{0, 0, 0, 0.0, 0, 0}}; + +#ifdef __cplusplus +} +#endif +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ + /* c-mode */ +#endif +} +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + /* Python-specific SWIG API */ +#define SWIG_newvarlink() SWIG_Python_newvarlink() +#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) +#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) + + /* ----------------------------------------------------------------------------- + * global variable support code. + * ----------------------------------------------------------------------------- */ + + typedef struct swig_globalvar { + char *name; /* Name of global variable */ + PyObject *(*get_attr)(void); /* Return the current value */ + int (*set_attr)(PyObject *); /* Set the value */ + struct swig_globalvar *next; + } swig_globalvar; + + typedef struct swig_varlinkobject { + PyObject_HEAD + swig_globalvar *vars; + } swig_varlinkobject; + + SWIGINTERN PyObject * + swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { + return PyString_FromString(""); + } + + SWIGINTERN PyObject * + swig_varlink_str(swig_varlinkobject *v) { + PyObject *str = PyString_FromString("("); + swig_globalvar *var; + for (var = v->vars; var; var=var->next) { + PyString_ConcatAndDel(&str,PyString_FromString(var->name)); + if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); + } + PyString_ConcatAndDel(&str,PyString_FromString(")")); + return str; + } + + SWIGINTERN int + swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { + PyObject *str = swig_varlink_str(v); + fprintf(fp,"Swig global variables "); + fprintf(fp,"%s\n", PyString_AsString(str)); + Py_DECREF(str); + return 0; + } + + SWIGINTERN void + swig_varlink_dealloc(swig_varlinkobject *v) { + swig_globalvar *var = v->vars; + while (var) { + swig_globalvar *n = var->next; + free(var->name); + free(var); + var = n; + } + } + + SWIGINTERN PyObject * + swig_varlink_getattr(swig_varlinkobject *v, char *n) { + PyObject *res = NULL; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->get_attr)(); + break; + } + var = var->next; + } + if (res == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN int + swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { + int res = 1; + swig_globalvar *var = v->vars; + while (var) { + if (strcmp(var->name,n) == 0) { + res = (*var->set_attr)(p); + break; + } + var = var->next; + } + if (res == 1 && !PyErr_Occurred()) { + PyErr_SetString(PyExc_NameError,"Unknown C global variable"); + } + return res; + } + + SWIGINTERN PyTypeObject* + swig_varlink_type(void) { + static char varlink__doc__[] = "Swig var link object"; + static PyTypeObject varlink_type; + static int type_init = 0; + if (!type_init) { + const PyTypeObject tmp + = { + PyObject_HEAD_INIT(NULL) + 0, /* Number of items in variable part (ob_size) */ + (char *)"swigvarlink", /* Type name (tp_name) */ + sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ + 0, /* Itemsize (tp_itemsize) */ + (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ + (printfunc) swig_varlink_print, /* Print (tp_print) */ + (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ + (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ + 0, /* tp_compare */ + (reprfunc) swig_varlink_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)swig_varlink_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + varlink__doc__, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ +#if PY_VERSION_HEX >= 0x02020000 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ +#endif +#if PY_VERSION_HEX >= 0x02030000 + 0, /* tp_del */ +#endif +#ifdef COUNT_ALLOCS + 0,0,0,0 /* tp_alloc -> tp_next */ +#endif + }; + varlink_type = tmp; + varlink_type.ob_type = &PyType_Type; + type_init = 1; + } + return &varlink_type; + } + + /* Create a variable linking object for use later */ + SWIGINTERN PyObject * + SWIG_Python_newvarlink(void) { + swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); + if (result) { + result->vars = 0; + } + return ((PyObject*) result); + } + + SWIGINTERN void + SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { + swig_varlinkobject *v = (swig_varlinkobject *) p; + swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); + if (gv) { + size_t size = strlen(name)+1; + gv->name = (char *)malloc(size); + if (gv->name) { + strncpy(gv->name,name,size); + gv->get_attr = get_attr; + gv->set_attr = set_attr; + gv->next = v->vars; + } + } + v->vars = gv; + } + + SWIGINTERN PyObject * + SWIG_globals(void) { + static PyObject *_SWIG_globals = 0; + if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); + return _SWIG_globals; + } + + /* ----------------------------------------------------------------------------- + * constants/methods manipulation + * ----------------------------------------------------------------------------- */ + + /* Install Constants */ + SWIGINTERN void + SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { + PyObject *obj = 0; + size_t i; + for (i = 0; constants[i].type; ++i) { + switch(constants[i].type) { + case SWIG_PY_POINTER: + obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); + break; + case SWIG_PY_BINARY: + obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); + break; + default: + obj = 0; + break; + } + if (obj) { + PyDict_SetItemString(d, constants[i].name, obj); + Py_DECREF(obj); + } + } + } + + /* -----------------------------------------------------------------------------*/ + /* Fix SwigMethods to carry the callback ptrs when needed */ + /* -----------------------------------------------------------------------------*/ + + SWIGINTERN void + SWIG_Python_FixMethods(PyMethodDef *methods, + swig_const_info *const_table, + swig_type_info **types, + swig_type_info **types_initial) { + size_t i; + for (i = 0; methods[i].ml_name; ++i) { + const char *c = methods[i].ml_doc; + if (c && (c = strstr(c, "swig_ptr: "))) { + int j; + swig_const_info *ci = 0; + const char *name = c + 10; + for (j = 0; const_table[j].type; ++j) { + if (strncmp(const_table[j].name, name, + strlen(const_table[j].name)) == 0) { + ci = &(const_table[j]); + break; + } + } + if (ci) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + strncpy(buff, methods[i].ml_doc, ldoc); + buff += ldoc; + strncpy(buff, "swig_ptr: ", 10); + buff += 10; + SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); + methods[i].ml_doc = ndoc; + } + } + } + } + } + } + +#ifdef __cplusplus +} +#endif + +/* -----------------------------------------------------------------------------* + * Partial Init method + * -----------------------------------------------------------------------------*/ + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIG_init(void) { + PyObject *m, *d; + + /* Fix SwigMethods to carry the callback ptrs when needed */ + SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); + + m = Py_InitModule((char *) SWIG_name, SwigMethods); + d = PyModule_GetDict(m); + + SWIG_InitializeModule(0); + SWIG_InstallConstants(d,swig_const_table); + + +} + diff --git a/source4/scripting/python/replace/stdint.i b/source4/scripting/python/replace/stdint.i deleted file mode 100644 index 7b48ca3884..0000000000 --- a/source4/scripting/python/replace/stdint.i +++ /dev/null @@ -1,109 +0,0 @@ -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * stdint.i - * - * SWIG library file for ISO C99 types: 7.18 Integer types - * ----------------------------------------------------------------------------- */ - -%{ -#include // Use the C99 official header -%} - -%include - -/* Exact integral types. */ - -/* Signed. */ - -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -#if defined(SWIGWORDSIZE64) -typedef long int int64_t; -#else -typedef long long int int64_t; -#endif - -/* Unsigned. */ -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -#if defined(SWIGWORDSIZE64) -typedef unsigned long int uint64_t; -#else -typedef unsigned long long int uint64_t; -#endif - - -/* Small types. */ - -/* Signed. */ -typedef signed char int_least8_t; -typedef short int int_least16_t; -typedef int int_least32_t; -#if defined(SWIGWORDSIZE64) -typedef long int int_least64_t; -#else -typedef long long int int_least64_t; -#endif - -/* Unsigned. */ -typedef unsigned char uint_least8_t; -typedef unsigned short int uint_least16_t; -typedef unsigned int uint_least32_t; -#if defined(SWIGWORDSIZE64) -typedef unsigned long int uint_least64_t; -#else -typedef unsigned long long int uint_least64_t; -#endif - - -/* Fast types. */ - -/* Signed. */ -typedef signed char int_fast8_t; -#if defined(SWIGWORDSIZE64) -typedef long int int_fast16_t; -typedef long int int_fast32_t; -typedef long int int_fast64_t; -#else -typedef int int_fast16_t; -typedef int int_fast32_t; -typedef long long int int_fast64_t; -#endif - -/* Unsigned. */ -typedef unsigned char uint_fast8_t; -#if defined(SWIGWORDSIZE64) -typedef unsigned long int uint_fast16_t; -typedef unsigned long int uint_fast32_t; -typedef unsigned long int uint_fast64_t; -#else -typedef unsigned int uint_fast16_t; -typedef unsigned int uint_fast32_t; -typedef unsigned long long int uint_fast64_t; -#endif - - -/* Types for `void *' pointers. */ -#if defined(SWIGWORDSIZE64) -typedef long int intptr_t; -typedef unsigned long int uintptr_t; -#else -typedef int intptr_t; -typedef unsigned int uintptr_t; -#endif - - -/* Largest integral types. */ -#if defined(SWIGWORDSIZE64) -typedef long int intmax_t; -typedef unsigned long int uintmax_t; -#else -typedef long long int intmax_t; -typedef unsigned long long int uintmax_t; -#endif - - diff --git a/source4/scripting/python/replace/swigarch.i b/source4/scripting/python/replace/swigarch.i deleted file mode 100644 index 260b608801..0000000000 --- a/source4/scripting/python/replace/swigarch.i +++ /dev/null @@ -1,65 +0,0 @@ -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * swigarch.i - * - * SWIG library file for 32bit/64bit code specialization and checking. - * - * Use only in extreme cases, when no arch. independent code can be - * generated - * - * To activate architecture specific code, use - * - * swig -DSWIGWORDSIZE32 - * - * or - * - * swig -DSWIGWORDSIZE64 - * - * Note that extra checking code will be added to the wrapped code, - * which will prevent the compilation in a different architecture. - * - * If you don't specify the SWIGWORDSIZE (the default case), swig will - * generate architecture independent and/or 32bits code, with no extra - * checking code added. - * ----------------------------------------------------------------------------- */ - -#if !defined(SWIGWORDSIZE32) && !defined(SWIGWORDSIZE64) -# if (__WORDSIZE == 32) -# define SWIGWORDSIZE32 -# endif -#endif - -#if !defined(SWIGWORDSIZE64) && !defined(SWIGWORDSIZE32) -# if defined(__x86_64) || defined(__x86_64__) || (__WORDSIZE == 64) -# define SWIGWORDSIZE64 -# endif -#endif - - -#ifdef SWIGWORDSIZE32 -%{ -#define SWIGWORDSIZE32 -#ifndef LONG_MAX -#include -#endif -#if (__WORDSIZE == 64) || (LONG_MAX != INT_MAX) -# error "SWIG wrapped code invalid in 64 bit architecture, regenarete code using -DSWIGWORDSIZE64" -#endif -%} -#endif - -#ifdef SWIGWORDSIZE64 -%{ -#define SWIGWORDSIZE64 -#ifndef LONG_MAX -#include -#endif -#if (__WORDSIZE == 32) || (LONG_MAX == INT_MAX) -# error "SWIG wrapped code invalid in 32 bit architecture, regenarete code using -DSWIGWORDSIZE32" -#endif -%} -#endif - - -- cgit From c926cddfad97713ca017c03e61c6e90414c1ad62 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 09:29:00 +0100 Subject: r26366: Import provision scripts in Python. (This used to be commit 090c799f98adf2c4186daca445c81b4e26e91f2f) --- source4/scripting/python/samba/provision.py | 842 ++++++++++++++++++++++++++++ source4/scripting/python/samba/upgrade.py | 561 ++++++++++++++++++ 2 files changed, 1403 insertions(+) create mode 100644 source4/scripting/python/samba/provision.py create mode 100644 source4/scripting/python/samba/upgrade.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py new file mode 100644 index 0000000000..3d391863da --- /dev/null +++ b/source4/scripting/python/samba/provision.py @@ -0,0 +1,842 @@ +# +# backend code for provisioning a Samba4 server +# Copyright Andrew Tridgell 2005 +# Copyright Jelmer Vernooij 2007 +# Released under the GNU GPL v2 or later +# + +from base64 import b64encode +import os +import pwd +import grp +import time +import uuid, sid, misc +from socket import gethostname, gethostbyname +import param +import registry +from samba import Ldb, substitute_var +from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ + LDB_ERR_NO_SUCH_OBJECT, timestring + + +class InvalidNetbiosName(Exception): + def __init__(self, name): + super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) + + +class ProvisionSettings(object): + def __init__(self, realm=None, domain=None, hostname=None, hostip=None): + self.realm = realm + self.domain = domain + self.hostname = hostname + self.hostip = hostip + self.domainsid = None + self.invocationid = None + self.krbtgtpass = None + self.machinepass = None + self.adminpass = None + self.defaultsite = "Default-First-Site-Name" + self.datestring = None + self.root = None + self.nobody = None + self.nogroup = None + self.wheel = None + self.backup = None + self.users = None + self.dnsdomain = None + self.dnsname = None + self.domaindn = None + self.domaindn_ldb = None + self.rootdn = None + self.configdn = None + self.configdn_ldb = None + self.schemedn = None + self.schemedn_ldb = None + self.s4_ldapi_path = None + self.policyguid = None + + def subst_vars(self): + return {"SCHEMADN": self.schemadn, + "SCHEMADN_LDB": self.schemadn_ldb, + "SCHEMADN_MOD": "schema_fsmo", + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": self.configdn, + "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list) + "MODULES_LIST2": ",".join(self.modules_list2) + "CONFIGDN_LDB": self.configdn_ldb, + "DOMAINDN": self.domaindn, + "DOMAINDN_LDB": self.domaindn_ldb, + "DOMAINDN_MOD": "pdc_fsmo,password_hash", + "DOMAINDN_MOD2": ",objectguid", + "DOMAINSID": self.domainsid, + "MODULES_LIST": ",".join(self.modules_list), + "CONFIGDN_MOD": "naming_fsmo", + "CONFIGDN_MOD2": ",objectguid", + "NETBIOSNAME": self.netbiosname, + "DNSNAME": self.dnsname, + "ROOTDN": self.rootdn, + "DNSDOMAIN": self.dnsdomain, + "REALM": self.realm, + "DEFAULTSITE": self.defaultsite, + "MACHINEPASS_B64": b64encode(self.machinepass), + "ADMINPASS_B64": b64encode(self.adminpass), + "DNSPASS_B64": b64encode(self.dnspass), + "KRBTGTPASS_B64": b64encode(self.krbtgtpass), + "S4_LDAPI_URI": "ldapi://%s" % self.s4_ldapi_path.replace("/", "%2F"), + "LDAPTIME": timestring(int(time.time())), + "POLICYGUID": self.policyguid, + "RDN_DC": self.rdn_dc, + "DOMAINGUID_MOD": self.domainguid_mod, + } + + def fix(self, paths): + self.realm = self.realm.upper() + self.hostname = self.hostname.lower() + self.domain = self.domain.upper() + if not valid_netbios_name(self.domain): + raise InvalidNetbiosName(self.domain) + self.netbiosname = self.hostname.upper() + if not valid_netbios_name(self.netbiosname): + raise InvalidNetbiosName(self.netbiosname) + rdns = self.domaindn.split(",") + self.rdn_dc = rdns[0][len("DC="):] + + self.sam_ldb = paths.samdb + self.secrets_ldb = paths.secrets + self.secrets_keytab = paths.keytab + + self.s4_ldapi_path = paths.s4_ldapi_path + + def validate(self, lp): + if not valid_netbios_name(self.domain): + raise InvalidNetbiosName(self.domain) + + if not valid_netbios_name(self.netbiosname): + raise InvalidNetbiosName(self.netbiosname) + + if lp.get("workgroup").upper() != self.domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", + lp.get("workgroup"), self.domain) + + if lp.get("realm").upper() != self.realm.upper(): + raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + (lp.get("realm"), self.realm)) + + +class ProvisionPaths: + def __init__(self): + self.smbconf = None + self.shareconf = None + self.hklm = None + self.hkcu = None + self.hkcr = None + self.hku = None + self.hkpd = None + self.hkpt = None + self.samdb = None + self.secrets = None + self.keytab = None + self.dns = None + self.winsdb = None + self.ldap_basedn_ldif = None + self.ldap_config_basedn_ldif = None + self.ldap_schema_basedn_ldif = None + self.s4_ldapi_path = None + + +def install_ok(lp, session_info, credentials): + """Check whether the current install seems ok.""" + if lp.get("realm") == "": + return False + ldb = Ldb(lp.get("sam database"), session_info=session_info, + credentials=credentials) + if len(ldb.search("(cn=Administrator)")) != 1: + return False + return True + + +def findnss(nssfn, *names): + """Find a user or group from a list of possibilities.""" + for name in names: + try: + return nssfn(name) + except KeyError: + pass + raise Exception("Unable to find user/group for %s" % arguments[1]) + +def add_foreign(ldb, subobj, sid, desc): + """Add a foreign security principle.""" + add = """ +dn: CN=%s,CN=ForeignSecurityPrincipals,%s +objectClass: top +objectClass: foreignSecurityPrincipal +description: %s +""" % (sid, subobj.domaindn, desc) + # deliberately ignore errors from this, as the records may + # already exist + for msg in ldb.parse_ldif(add): + ldb.add(msg[1]) + +def setup_name_mapping(subobj, ldb, sid, unixname): + """Setup a mapping between a sam name and a unix name.""" + res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_SUBTREE, + "objectSid=%s" % sid, ["dn"]) + assert len(res) == 1, "Failed to find record for objectSid %s" % sid + + mod = """ +dn: %s +changetype: modify +replace: unixName +unixName: %s +""" % (res[0].dn, unixname) + ldb.modify(ldb.parse_ldif(mod).next()[1]) + +def hostip(): + """return first host IP.""" + return gethostbyname(hostname()) + +def hostname(): + """return first part of hostname.""" + return gethostname().split(".")[0] + +def ldb_delete(ldb): + """Delete a LDB file. + + This may be necessary if the ldb is in bad shape, possibly due to being + built from an incompatible previous version of the code, so delete it + completely. + """ + print "Deleting %s\n" % ldb.filename + os.unlink(ldb.filename) + ldb.connect(ldb.filename) + + +def ldb_erase(ldb): + """Erase an ldb, removing all records.""" + # delete the specials + for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", + "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: + try: + ldb.delete(Dn(ldb, attr)) + except LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): + # Ignore missing dn errors + pass + + basedn = Dn(ldb, "") + # and the rest + for msg in ldb.search(basedn, SCOPE_SUBTREE, + "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", + ["dn"]): + ldb.delete(msg.dn) + + res = ldb.search(basedn, SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) + assert len(res) == 0 + + +def ldb_erase_partitions(subobj, message, ldb, ldapbackend): + """Erase an ldb, removing all records.""" + assert ldb is not None + res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", + ["namingContexts"]) + assert len(res) == 1 + if not "namingContexts" in res[0]: + return + for basedn in res[0]["namingContexts"]: + anything = "(|(objectclass=*)(dn=*))" + previous_remaining = 1 + current_remaining = 0 + + if ldapbackend and (basedn == subobj.domaindn): + # Only delete objects that were created by provision + anything = "(objectcategory=*)" + + k = 0 + while ++k < 10 and (previous_remaining != current_remaining): + # and the rest + res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) + previous_remaining = current_remaining + current_remaining = len(res2) + for msg in res2: + try: + ldb.delete(msg.dn) + except LdbError, (_, text): + message("Unable to delete %s: %s" % (msg.dn, text)) + + +def open_ldb(session_info, credentials, dbname): + assert session_info is not None + try: + return Ldb(dbname, session_info=session_info, credentials=credentials) + except LdbError, e: + print e + os.unlink(dbname) + return Ldb(dbname, session_info=session_info, credentials=credentials) + + +def setup_add_ldif(setup_dir, ldif, subobj, ldb): + """Setup a ldb in the private dir.""" + assert isinstance(ldif, str) + assert isinstance(setup_dir, str) + src = os.path.join(setup_dir, ldif) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + + for msg in ldb.parse_ldif(data): + ldb.add(msg[1]) + + +def setup_modify_ldif(setup_dir, ldif, subobj, ldb): + src = os.path.join(setup_dir, ldif) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + + for (changetype, msg) in ldb.parse_ldif(data): + ldb.modify(msg) + + +def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, dbname, + erase=True): + assert dbname is not None + ldb = open_ldb(session_info, credentials, dbname) + assert ldb is not None + ldb.transaction_start() + try: + if erase: + ldb_erase(ldb); + setup_add_ldif(setup_dir, ldif, subobj, ldb) + except: + ldb.transaction_cancel() + raise + ldb.transaction_commit() + + +def setup_ldb_modify(setup_dir, ldif, subobj, ldb): + """Modify a ldb in the private dir.""" + src = os.path.join(setup_dir, ldif) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + assert not "${" in data + + for (changetype, msg) in ldb.parse_ldif(data): + ldb.modify(msg) + + +def setup_file(setup_dir, template, message, fname, subobj): + """Setup a file in the private dir.""" + f = fname + src = os.path.join(setup_dir, template) + + os.unlink(f) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + assert not "${" in data + + open(f, 'w').write(data) + + +def provision_default_paths(lp, subobj): + """Set the default paths for provisioning. + + :param lp: Loadparm context. + :param subobj: Object + """ + paths = ProvisionPaths() + private_dir = lp.get("private dir") + paths.shareconf = os.path.join(private_dir, "share.ldb") + paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") + paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.templates = os.path.join(private_dir, "templates.ldb") + paths.keytab = os.path.join(private_dir, "secrets.keytab") + paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") + paths.winsdb = os.path.join(private_dir, "wins.ldb") + paths.ldap_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + ".ldif") + paths.ldap_config_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-config.ldif") + paths.ldap_schema_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-schema.ldif") + paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") + paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") + paths.hklm = os.path.join(private_dir, "hklm.ldb") + return paths + + +def setup_name_mappings(subobj, ldb): + """setup reasonable name mappings for sam names to unix names.""" + res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectSid=*", + ["objectSid"]) + assert len(res) == 1 + assert "objectSid" in res[0] + sid = list(res[0]["objectSid"])[0] + + # add some foreign sids if they are not present already + add_foreign(ldb, subobj, "S-1-5-7", "Anonymous") + add_foreign(ldb, subobj, "S-1-1-0", "World") + add_foreign(ldb, subobj, "S-1-5-2", "Network") + add_foreign(ldb, subobj, "S-1-5-18", "System") + add_foreign(ldb, subobj, "S-1-5-11", "Authenticated Users") + + # some well known sids + setup_name_mapping(subobj, ldb, "S-1-5-7", subobj.nobody) + setup_name_mapping(subobj, ldb, "S-1-1-0", subobj.nogroup) + setup_name_mapping(subobj, ldb, "S-1-5-2", subobj.nogroup) + setup_name_mapping(subobj, ldb, "S-1-5-18", subobj.root) + setup_name_mapping(subobj, ldb, "S-1-5-11", subobj.users) + setup_name_mapping(subobj, ldb, "S-1-5-32-544", subobj.wheel) + setup_name_mapping(subobj, ldb, "S-1-5-32-545", subobj.users) + setup_name_mapping(subobj, ldb, "S-1-5-32-546", subobj.nogroup) + setup_name_mapping(subobj, ldb, "S-1-5-32-551", subobj.backup) + + # and some well known domain rids + setup_name_mapping(subobj, ldb, sid + "-500", subobj.root) + setup_name_mapping(subobj, ldb, sid + "-518", subobj.wheel) + setup_name_mapping(subobj, ldb, sid + "-519", subobj.wheel) + setup_name_mapping(subobj, ldb, sid + "-512", subobj.wheel) + setup_name_mapping(subobj, ldb, sid + "-513", subobj.users) + setup_name_mapping(subobj, ldb, sid + "-520", subobj.wheel) + + +def provision_become_dc(setup_dir, subobj, message, paths, session_info, + credentials): + assert session_info is not None + subobj.fix(paths) + + message("Setting up templates into %s" % paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, + credentials, subobj, paths.templates) + + # Also wipes the database + message("Setting up %s partitions" % paths.samdb) + setup_ldb(setup_dir, "provision_partitions.ldif", session_info, + credentials, subobj, paths.samdb) + + samdb = open_ldb(session_info, credentials, paths.samdb) + ldb.transaction_start() + try: + message("Setting up %s attributes" % paths.samdb) + setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + + message("Setting up %s rootDSE" % paths.samdb) + setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + + message("Erasing data from partitions") + ldb_erase_partitions(subobj, message, samdb, undefined) + + message("Setting up %s indexes" % paths.samdb) + setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + + message("Setting up %s" % paths.secrets) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, + subobj, paths.secrets) + + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + paths.secrets, False) + + +def provision(lp, setup_dir, subobj, message, blank, paths, session_info, + credentials, ldapbackend): + """Provision samba4 + + :note: caution, this wipes all existing data! + """ + subobj.fix(paths) + + if subobj.domain_guid is not None: + subobj.domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid + else: + subobj.domainguid_mod = "" + + if subobj.host_guid is not None: + subobj.hostguid_add = "objectGUID: %s" % subobj.host_guid + else: + subobj.hostguid_add = "" + + assert paths.smbconf is not None + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(paths.smbconf): + message("Setting up smb.conf") + setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, subobj) + lp.reload() + + # only install a new shares config db if there is none + if not os.path.exists(paths.shareconf): + message("Setting up share.ldb") + setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, paths.shareconf) + + message("Setting up %s" % paths.secrets) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, paths.secrets) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, paths.secrets, False) + + message("Setting up registry") + reg = registry.Registry() + # FIXME: Still fails for some reason: + #reg.mount(paths.hklm, registry.HKEY_LOCAL_MACHINE, []) + #reg.apply_patchfile(os.path.join(setup_dir, "provision.reg")) + + message("Setting up templates into %s" % paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, paths.templates) + + message("Setting up sam.ldb partitions") + setup_ldb(setup_dir, "provision_partitions.ldif", session_info, + credentials, subobj, paths.samdb) + + samdb = open_ldb(session_info, credentials, paths.samdb) + samdb.transaction_start() + try: + message("Setting up sam.ldb attributes") + setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + + message("Setting up sam.ldb rootDSE") + setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + + message("Erasing data from partitions") + ldb_erase_partitions(subobj, message, samdb, ldapbackend) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + + message("Pre-loading the Samba 4 and AD schema") + + samdb = open_ldb(session_info, credentials, paths.samdb) + + samdb.set_domain_sid(subobj.domainsid) + + load_schema(setup_dir, subobj, samdb) + + samdb.transaction_start() + + try: + message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn) + setup_add_ldif(setup_dir, "provision_basedn.ldif", subobj, samdb) + message("Modifying DomainDN: " + subobj.domaindn + "") + setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", subobj, samdb) + + message("Adding configuration container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_configuration_basedn.ldif", subobj, samdb) + message("Modifying configuration container") + setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", subobj, samdb) + + message("Adding schema container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_schema_basedn.ldif", subobj, samdb) + message("Modifying schema container") + setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", subobj, samdb) + message("Setting up sam.ldb Samba4 schema") + setup_add_ldif(setup_dir, "schema_samba4.ldif", subobj, samdb) + message("Setting up sam.ldb AD schema") + setup_add_ldif(setup_dir, "schema.ldif", subobj, samdb) + + message("Setting up sam.ldb configuration data") + setup_add_ldif(setup_dir, "provision_configuration.ldif", subobj, samdb) + + message("Setting up display specifiers") + setup_add_ldif(setup_dir, "display_specifiers.ldif", subobj, samdb) + + message("Adding users container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_users_add.ldif", subobj, samdb) + message("Modifying users container") + setup_ldb_modify(setup_dir, "provision_users_modify.ldif", subobj, samdb) + message("Adding computers container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_computers_add.ldif", subobj, samdb) + message("Modifying computers container") + setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", subobj, samdb) + message("Setting up sam.ldb data") + setup_add_ldif(setup_dir, "provision.ldif", subobj, samdb) + + if blank: + message("Setting up sam.ldb index") + setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + + message("Setting up sam.ldb rootDSE marking as syncronized") + setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + + samdb.transaction_commit() + return + + # message("Activate schema module") + # setup_modify_ldif("schema_activation.ldif", info, samdb, False) + # + # // (hack) Reload, now we have the schema loaded. + # commit_ok = samdb.transaction_commit() + # if (!commit_ok) { + # message("samdb commit failed: " + samdb.errstring() + "\n") + # assert(commit_ok) + # } + # samdb.close() + # + # samdb = open_ldb(info, paths.samdb, False) + # + message("Setting up sam.ldb users and groups") + setup_add_ldif(setup_dir, "provision_users.ldif", subobj, samdb) + + setup_name_mappings(subobj, samdb) + + message("Setting up sam.ldb index") + setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + + message("Setting up sam.ldb rootDSE marking as syncronized") + setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + + message("Setting up phpLDAPadmin configuration") + setup_file(setup_dir, "phpldapadmin-config.php", message, + paths.phpldapadminconfig, subobj) + message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + + +def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): + """Write out a DNS zone file, from the info in the current database.""" + message("Setting up DNS zone: %s" % subobj.dnsdomain) + # connect to the sam + ldb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) + + # These values may have changed, due to an incoming SamSync, + # or may not have been specified, so fetch them from the database + + res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectGUID=*", + ["objectGUID"]) + assert(len(res) == 1) + assert(res[0]["objectGUID"] is not None) + subobj.domainguid = res[0]["objectGUID"] + + subobj.host_guid = searchone(ldb, subobj.domaindn, + "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID") + assert subobj.host_guid is not None + + setup_file(setup_dir, "provision.zone", message, paths.dns, subobj) + + message("Please install the zone located in %s into your DNS server" % paths.dns) + + +def provision_ldapbase(setup_dir, subobj, message, paths): + """Write out a DNS zone file, from the info in the current database.""" + message("Setting up LDAP base entry: %s" % subobj.domaindn) + rdns = subobj.domaindn.split(",") + subobj.extensibleobject = "objectClass: extensibleObject" + + subobj.rdn_dc = rdns[0][len("DC="):] + + setup_file(setup_dir, "provision_basedn.ldif", + message, paths.ldap_basedn_ldif, + subobj) + + setup_file(setup_dir, "provision_configuration_basedn.ldif", + message, paths.ldap_config_basedn_ldif, + subobj) + + setup_file(setup_dir, "provision_schema_basedn.ldif", + message, paths.ldap_schema_basedn_ldif, + subobj) + + message("Please install the LDIF located in " + paths.ldap_basedn_ldif + ", " + paths.ldap_config_basedn_ldif + " and " + paths.ldap_schema_basedn_ldif + " into your LDAP server, and re-run with --ldap-backend=ldap://my.ldap.server") + + +def provision_guess(lp): + """guess reasonably default options for provisioning.""" + subobj = ProvisionSettings(realm=lp.get("realm").upper(), + domain=lp.get("workgroup"), + hostname=hostname(), + hostip=hostip()) + + assert subobj.realm is not None + assert subobj.domain is not None + assert subobj.hostname is not None + + subobj.domainsid = sid.random() + subobj.invocationid = uuid.random() + subobj.policyguid = uuid.random() + subobj.krbtgtpass = misc.random_password(12) + subobj.machinepass = misc.random_password(12) + subobj.adminpass = misc.random_password(12) + subobj.dnspass = misc.random_password(12) + subobj.datestring = time.strftime("%Y%m%d%H") + subobj.root = findnss(pwd.getpwnam, "root")[4] + subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] + subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + subobj.wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + subobj.backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + subobj.users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + + subobj.dnsdomain = subobj.realm.lower() + subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) + subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=") + subobj.domaindn_ldb = "users.ldb" + subobj.rootdn = subobj.domaindn + subobj.configdn = "CN=Configuration," + subobj.rootdn + subobj.configdn_ldb = "configuration.ldb" + subobj.schemadn = "CN=Schema," + subobj.configdn + subobj.schemadn_ldb = "schema.ldb" + + #Add modules to the list to activate them by default + #beware often order is important + # + # Some Known ordering constraints: + # - rootdse must be first, as it makes redirects from "" -> cn=rootdse + # - objectclass must be before password_hash, because password_hash checks + # that the objectclass is of type person (filled in by objectclass + # module when expanding the objectclass list) + # - partition must be last + # - each partition has its own module list then + subobj.modules_list = ["rootdse", + "paged_results", + "ranged_results", + "server_sort", + "extended_dn", + "asq", + "samldb", + "rdn_name", + "objectclass", + "kludge_acl", + "operational"] + subobj.tdb_modules_list = [ + "subtree_rename", + "subtree_delete", + "linked_attributes"] + subobj.modules_list2 = ["show_deleted", + "partition"] + + subobj.extensibleobject = "# no objectClass: extensibleObject for local ldb" + subobj.aci = "# no aci for local ldb" + return subobj + + +def searchone(ldb, basedn, expression, attribute): + """search for one attribute as a string.""" + res = ldb.search(basedn, SCOPE_SUBTREE, expression, [attribute]) + if len(res) != 1 or res[0][attribute] is None: + return None + return res[0][attribute] + + +def load_schema(setup_dir, subobj, samdb): + """Load schema.""" + src = os.path.join(setup_dir, "schema.ldif") + + schema_data = open(src, 'r').read() + + src = os.path.join(setup_dir, "schema_samba4.ldif") + + schema_data += open(src, 'r').read() + + schema_data = substitute_var(schema_data, subobj.subst_vars()) + + src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") + + head_data = open(src, 'r').read() + + head_data = substitute_var(head_data, subobj.subst_vars()) + + samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) + + +def enable_account(ldb, user_dn): + """enable the account.""" + res = ldb.search(user_dn, SCOPE_ONELEVEL, None, ["userAccountControl"]) + assert len(res) == 1 + userAccountControl = res[0].userAccountControl + userAccountControl = userAccountControl - 2 # remove disabled bit + mod = """ +dn: %s +changetype: modify +replace: userAccountControl +userAccountControl: %u +""" % (user_dn, userAccountControl) + ldb.modify(mod) + + +def newuser(sam, username, unixname, password, message, session_info, + credentials): + """add a new user record""" + # connect to the sam + ldb.transaction_start() + + # find the DNs for the domain and the domain users group + res = ldb.search("", SCOPE_BASE, "defaultNamingContext=*", + ["defaultNamingContext"]) + assert(len(res) == 1 and res[0].defaultNamingContext is not None) + domain_dn = res[0].defaultNamingContext + assert(domain_dn is not None) + dom_users = searchone(ldb, domain_dn, "name=Domain Users", "dn") + assert(dom_users is not None) + + user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) + + # + # the new user record. note the reliance on the samdb module to fill + # in a sid, guid etc + # + ldif = """ +dn: %s +sAMAccountName: %s +unixName: %s +sambaPassword: %s +objectClass: user +""" % (user_dn, username, unixname, password) + # add the user to the users group as well + modgroup = """ +dn: %s +changetype: modify +add: member +member: %s +""" % (dom_users, user_dn) + + + # now the real work + message("Adding user %s" % user_dn) + ldb.add(ldif) + + message("Modifying group %s" % dom_users) + ldb.modify(modgroup) + + # modify the userAccountControl to remove the disabled bit + enable_account(ldb, user_dn) + ldb.transaction_commit() + + +def valid_netbios_name(name): + """Check whether a name is valid as a NetBIOS name. """ + # FIXME: There are probably more constraints here. + # crh has a paragraph on this in his book (1.4.1.1) + if len(name) > 13: + return False + return True + + +def join_domain(domain, netbios_name, join_type, creds, message): + ctx = NetContext(creds) + joindom = object() + joindom.domain = domain + joindom.join_type = join_type + joindom.netbios_name = netbios_name + if not ctx.JoinDomain(joindom): + raise Exception("Domain Join failed: " + joindom.error_string) + + +def vampire(domain, session_info, credentials, message): + """Vampire a remote domain. + + Session info and credentials are required for for + access to our local database (might be remote ldap) + """ + ctx = NetContext(credentials) + vampire_ctx = object() + machine_creds = credentials_init() + machine_creds.set_domain(form.domain) + if not machine_creds.set_machine_account(): + raise Exception("Failed to access domain join information!") + vampire_ctx.machine_creds = machine_creds + vampire_ctx.session_info = session_info + if not ctx.SamSyncLdb(vampire_ctx): + raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py new file mode 100644 index 0000000000..49aee3f94d --- /dev/null +++ b/source4/scripting/python/samba/upgrade.py @@ -0,0 +1,561 @@ +#!/usr/bin/python +# +# backend code for upgrading from Samba3 +# Copyright Jelmer Vernooij 2005-2007 +# Released under the GNU GPL v3 or later +# + +"""Support code for upgrading from Samba 3 to Samba 4.""" + +from provision import findnss +import provision +import grp +import pwd +from uuid import uuid4 +from param import default_configuration + +def regkey_to_dn(name): + dn = "hive=NONE" + + for el in name.split("/")[1:]: + dn = "key=%s," % el + dn + + return dn + +# Where prefix is any of: +# - HKLM +# HKU +# HKCR +# HKPD +# HKPT +# + +def upgrade_registry(regdb,prefix,ldb): + """Migrate registry contents.""" + assert regdb is not None: + prefix_up = prefix.upper() + ldif = [] + + for rk in regdb.keys: + pts = rk.name.split("/") + + # Only handle selected hive + if pts[0].upper() != prefix_up: + continue + + keydn = regkey_to_dn(rk.name) + + pts = rk.name.split("/") + + # Convert key name to dn + ldif[rk.name] = """ +dn: %s +name: %s + +""" % (keydn, pts[0]) + + for rv in rk.values: + ldif[rk.name + " (" + rv.name + ")"] = """ +dn: %s,value=%s +value: %s +type: %d +data:: %s""" % (keydn, rv.name, rv.name, rv.type, ldb.encode(rv.data)) + + return ldif + +def upgrade_sam_policy(samba3,dn): + ldif = """ +dn: %s +changetype: modify +replace: minPwdLength +minPwdLength: %d +pwdHistoryLength: %d +minPwdAge: %d +maxPwdAge: %d +lockoutDuration: %d +samba3ResetCountMinutes: %d +samba3UserMustLogonToChangePassword: %d +samba3BadLockoutMinutes: %d +samba3DisconnectTime: %d + +""" % (dn, samba3.policy.min_password_length, + samba3.policy.password_history, samba3.policy.minimum_password_age, + samba3.policy.maximum_password_age, samba3.policy.lockout_duration, + samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password, + samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time) + + return ldif + +def upgrade_sam_account(ldb,acc,domaindn,domainsid): + """Upgrade a SAM account.""" + if acc.nt_username is None or acc.nt_username == "": + acc.nt_username = acc.username + + if acc.fullname is None: + acc.fullname = pwd.getpwnam(acc.fullname)[4] + + acc.fullname = acc.fullname.split(",")[0] + + if acc.fullname is None: + acc.fullname = acc.username + + assert acc.fullname is not None + assert acc.nt_username is not None + + ldif = """dn: cn=%s,%s +objectClass: top +objectClass: user +lastLogon: %d +lastLogoff: %d +unixName: %s +sAMAccountName: %s +cn: %s +description: %s +primaryGroupID: %d +badPwdcount: %d +logonCount: %d +samba3Domain: %s +samba3DirDrive: %s +samba3MungedDial: %s +samba3Homedir: %s +samba3LogonScript: %s +samba3ProfilePath: %s +samba3Workstations: %s +samba3KickOffTime: %d +samba3BadPwdTime: %d +samba3PassLastSetTime: %d +samba3PassCanChangeTime: %d +samba3PassMustChangeTime: %d +objectSid: %s-%d +lmPwdHash:: %s +ntPwdHash:: %s + +""" % (ldb.dn_escape(acc.fullname), domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, acc.nt_username, +acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count, +acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script, +acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time, +acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid, + ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw)) + + return ldif + +def upgrade_sam_group(group,domaindn): + """Upgrade a SAM group.""" + if group.sid_name_use == 5: # Well-known group + return None + + if group.nt_name in ("Domain Guests", "Domain Users", "Domain Admins"): + return None + + if group.gid == -1: + gr = grp.getgrnam(grp.nt_name) + else: + gr = grp.getgrgid(grp.gid) + + if gr is None: + group.unixname = "UNKNOWN" + else: + group.unixname = gr.gr_name + + assert group.unixname is not None + + ldif = """dn: cn=%s,%s +objectClass: top +objectClass: group +description: %s +cn: %s +objectSid: %s +unixName: %s +samba3SidNameUse: %d +""" % (group.nt_name, domaindn, +group.comment, group.nt_name, group.sid, group.unixname, group.sid_name_use) + + return ldif + +def upgrade_winbind(samba3,domaindn): + ldif = """ + +dn: dc=none +userHwm: %d +groupHwm: %d + +""" % (samba3.idmap.user_hwm, samba3.idmap.group_hwm) + + for m in samba3.idmap.mappings: + ldif += """ +dn: SID=%s,%s +SID: %s +type: %d +unixID: %d""" % (m.sid, domaindn, m.sid, m.type, m.unix_id) + + return ldif + +def upgrade_wins(samba3): + ldif = "" + version_id = 0 + + for e in samba3.winsentries: + now = sys.nttime() + ttl = sys.unix2nttime(e.ttl) + + version_id+=1 + + numIPs = len(e.ips) + + if e.type == 0x1C: + rType = 0x2 + elif e.type & 0x80: + if numIPs > 1: + rType = 0x2 + else: + rType = 0x1 + else: + if numIPs > 1: + rType = 0x3 + else: + rType = 0x0 + + if ttl > now: + rState = 0x0 # active + else: + rState = 0x1 # released + + nType = ((e.nb_flags & 0x60)>>5) + + ldif += """ +dn: name=%s,type=0x%02X +type: 0x%02X +name: %s +objectClass: winsRecord +recordType: %u +recordState: %u +nodeType: %u +isStatic: 0 +expireTime: %s +versionID: %llu +""" % (e.name, e.type, e.type, e.name, + rType, rState, nType, + ldaptime(ttl), version_id) + + for ip in e.ips: + ldif += "address: %s\n" % ip + + ldif += """ +dn: CN=VERSION +objectClass: winsMaxVersion +maxVersion: %llu +""" % version_id + + return ldif + +def upgrade_provision(lp, samba3): + subobj = Object() + + domainname = samba3.configuration.get("workgroup") + + if domainname is None: + domainname = samba3.secrets.domains[0].name + print "No domain specified in smb.conf file, assuming '%s'\n" % domainname + + domsec = samba3.find_domainsecrets(domainname) + hostsec = samba3.find_domainsecrets(hostname()) + realm = samba3.configuration.get("realm") + + if realm is None: + realm = domainname + print "No realm specified in smb.conf file, assuming '%s'\n" % realm + random_init(local) + + subobj.realm = realm + subobj.domain = domainname + subobj.hostname = hostname() + + assert subobj.realm is not None + assert subobj.domain is not None + assert subobj.hostname is not None + + subobj.HOSTIP = hostip() + if domsec is not None: + subobj.DOMAINGUID = domsec.guid + subobj.DOMAINSID = domsec.sid + else: + print "Can't find domain secrets for '%s'; using random SID and GUID\n" % domainname + subobj.DOMAINGUID = uuid4() + subobj.DOMAINSID = randsid() + + if hostsec: + subobj.HOSTGUID = hostsec.guid + else: + subobj.HOSTGUID = uuid4() + subobj.invocationid = uuid4() + subobj.krbtgtpass = randpass(12) + subobj.machinepass = randpass(12) + subobj.adminpass = randpass(12) + subobj.datestring = datestring() + subobj.root = findnss(pwd.getpwnam, "root")[4] + subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] + subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + subobj.wheel = findnss(grp.getgrnam, "wheel", "root")[2] + subobj.users = findnss(grp.getgrnam, "users", "guest", "other")[2] + subobj.dnsdomain = subobj.realm.lower() + subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) + subobj.basedn = "DC=" + ",DC=".join(subobj.realm.split(".")) + rdn_list = subobj.dnsdomain.split(".") + subobj.domaindn = "DC=" + ",DC=".join(rdn_list) + subobj.domaindn_ldb = "users.ldb" + subobj.rootdn = subobj.domaindn + + modules_list = ["rootdse", + "kludge_acl", + "paged_results", + "server_sort", + "extended_dn", + "asq", + "samldb", + "password_hash", + "operational", + "objectclass", + "rdn_name", + "show_deleted", + "partition"] + subobj.modules_list = ",".join(modules_list) + + return subobj + +smbconf_keep = [ + "dos charset", + "unix charset", + "display charset", + "comment", + "path", + "directory", + "workgroup", + "realm", + "netbios name", + "netbios aliases", + "netbios scope", + "server string", + "interfaces", + "bind interfaces only", + "security", + "auth methods", + "encrypt passwords", + "null passwords", + "obey pam restrictions", + "password server", + "smb passwd file", + "private dir", + "passwd chat", + "password level", + "lanman auth", + "ntlm auth", + "client NTLMv2 auth", + "client lanman auth", + "client plaintext auth", + "read only", + "hosts allow", + "hosts deny", + "log level", + "debuglevel", + "log file", + "smb ports", + "large readwrite", + "max protocol", + "min protocol", + "unicode", + "read raw", + "write raw", + "disable netbios", + "nt status support", + "announce version", + "announce as", + "max mux", + "max xmit", + "name resolve order", + "max wins ttl", + "min wins ttl", + "time server", + "unix extensions", + "use spnego", + "server signing", + "client signing", + "max connections", + "paranoid server security", + "socket options", + "strict sync", + "max print jobs", + "printable", + "print ok", + "printer name", + "printer", + "map system", + "map hidden", + "map archive", + "preferred master", + "prefered master", + "local master", + "browseable", + "browsable", + "wins server", + "wins support", + "csc policy", + "strict locking", + "preload", + "auto services", + "lock dir", + "lock directory", + "pid directory", + "socket address", + "copy", + "include", + "available", + "volume", + "fstype", + "panic action", + "msdfs root", + "host msdfs", + "winbind separator"] + +# +# Remove configuration variables not present in Samba4 +# oldconf: Old configuration structure +# mark: Whether removed configuration variables should be +# kept in the new configuration as "samba3:" +def upgrade_smbconf(oldconf,mark): + data = oldconf.data() + newconf = param_init() + + for (s in data) { + for (p in data[s]) { + keep = False + for (k in smbconf_keep) { + if smbconf_keep[k] == p: + keep = True + break + } + + if keep: + newconf.set(s, p, oldconf.get(s, p)) + elif mark: + newconf.set(s, "samba3:"+p, oldconf.get(s,p)) + } + } + + if oldconf.get("domain logons") == "True": + newconf.set("server role", "domain controller") + else: + if oldconf.get("security") == "user": + newconf.set("server role", "standalone") + else: + newconf.set("server role", "member server") + + return newconf + +def upgrade(subobj, samba3, message, paths, session_info, credentials): + ret = 0 + lp = loadparm_init() + samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) + + message("Writing configuration") + newconf = upgrade_smbconf(samba3.configuration,True) + newconf.save(paths.smbconf) + + message("Importing account policies") + ldif = upgrade_sam_policy(samba3,subobj.BASEDN) + samdb.modify(ldif) + regdb = Ldb(paths.hklm) + + regdb.modify(" +dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE +replace: type +type: 4 +replace: data +data: %d +" % samba3.policy.refuse_machine_password_change) + + message("Importing users") + for account in samba3.samaccounts: + msg = "... " + account.username + ldif = upgrade_sam_account(samdb, accounts,subobj.BASEDN,subobj.DOMAINSID) + try: + samdb.add(ldif) + except LdbError, e: + # FIXME: Ignore 'Record exists' errors + msg += "... error: " + str(e) + ret += 1; + message(msg) + + message("Importing groups") + for mapping in samba3.groupmappings: + msg = "... " + mapping.nt_name + ldif = upgrade_sam_group(mapping, subobj.BASEDN) + if ldif is not None: + try: + samdb.add(ldif) + except LdbError, e: + # FIXME: Ignore 'Record exists' errors + msg += "... error: " + str(e) + ret += 1 + message(msg) + + message("Importing registry data") + for hive in ["hkcr","hkcu","hklm","hkpd","hku","hkpt"]: + message("... " + hive) + regdb = Ldb(paths[hive]) + ldif = upgrade_registry(samba3.registry, hive, regdb) + for (var j in ldif) { + var msg = "... ... " + j + try: + regdb.add(ldif[j]) + except LdbError, e: + # FIXME: Ignore 'Record exists' errors + msg += "... error: " + str(e) + ret += 1 + message(msg) + + message("Importing WINS data") + winsdb = Ldb(paths.winsdb) + ldb_erase(winsdb) + + ldif = upgrade_wins(samba3) + winsdb.add(ldif) + + # figure out ldapurl, if applicable + ldapurl = None + pdb = samba3.configuration.get_list("passdb backend") + if pdb is not None: + for backend in pdb: + if len(backend) >= 7 and backend[0:7] == "ldapsam": + ldapurl = backend[7:] + + # URL was not specified in passdb backend but ldap /is/ used + if ldapurl == "": + ldapurl = "ldap://%s" % samba3.configuration.get("ldap server") + + # Enable samba3sam module if original passdb backend was ldap + if ldapurl is not None: + message("Enabling Samba3 LDAP mappings for SAM database") + + samdb.modify(""" +dn: @MODULES +changetype: modify +replace: @LIST +@LIST: samldb,operational,objectguid,rdn_name,samba3sam +""") + + samdb.add(""" +dn: @MAP=samba3sam +@MAP_URL: %s""", ldapurl)) + + return ret + +def upgrade_verify(subobj, samba3, paths, message): + message("Verifying account policies") + + samldb = Ldb(paths.samdb) + + for account in samba3.samaccounts: + msg = samldb.search("(&(sAMAccountName=" + account.nt_username + ")(objectclass=user))") + assert(len(msg) >= 1) + + # FIXME -- cgit From b414ac505282f5a2a59c7580a19dfbd86489676e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 10:29:20 +0100 Subject: r26369: Start on tests for the upgrade python code. (This used to be commit c4458d11c710d4f0f892b26c7cb0701a43273587) --- source4/scripting/python/samba/tests/upgrade.py | 28 +++++++++++++++++++++++++ source4/scripting/python/samba/upgrade.py | 2 ++ 2 files changed, 30 insertions(+) create mode 100644 source4/scripting/python/samba/tests/upgrade.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/upgrade.py b/source4/scripting/python/samba/tests/upgrade.py new file mode 100644 index 0000000000..f46d869656 --- /dev/null +++ b/source4/scripting/python/samba/tests/upgrade.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 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 . +# + +from samba.upgrade import regkey_to_dn +from unittest import TestCase + +class RegkeyDnTests(TestCase): + def test_empty(self): + self.assertEquals("hive=NONE", regkey_to_dn("")) + + def test_nested(self): + self.assertEquals("key=foo,key=bar,hive=NONE", regkey_to_dn("foo/bar")) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 49aee3f94d..1908e3ea55 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -15,6 +15,7 @@ from uuid import uuid4 from param import default_configuration def regkey_to_dn(name): + """Convert a registry key to a DN.""" dn = "hive=NONE" for el in name.split("/")[1:]: @@ -191,6 +192,7 @@ unixID: %d""" % (m.sid, domaindn, m.sid, m.type, m.unix_id) return ldif def upgrade_wins(samba3): + """Upgrade the WINS database.""" ldif = "" version_id = 0 -- cgit From eba25f5d1897fbe61e8d7c623fcacb647629bf07 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 10:29:45 +0100 Subject: r26375: Move provision-independent utility function to main samba python module. (This used to be commit 9d0ff47be069422de7ef2794357c6f3e9c540e67) --- source4/scripting/python/samba/__init__.py | 9 +++++++++ source4/scripting/python/samba/provision.py | 14 ++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 46d8ff7d37..00b82e1800 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -55,3 +55,12 @@ def substitute_var(text, values): return text + +def valid_netbios_name(name): + """Check whether a name is valid as a NetBIOS name. """ + # FIXME: There are probably more constraints here. + # crh has a paragraph on this in his book (1.4.1.1) + if len(name) > 13: + return False + return True + diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3d391863da..692e49b095 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -14,7 +14,7 @@ import uuid, sid, misc from socket import gethostname, gethostbyname import param import registry -from samba import Ldb, substitute_var +from samba import Ldb, substitute_var, valid_netbios_name from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring @@ -191,14 +191,17 @@ unixName: %s """ % (res[0].dn, unixname) ldb.modify(ldb.parse_ldif(mod).next()[1]) + def hostip(): """return first host IP.""" return gethostbyname(hostname()) + def hostname(): """return first part of hostname.""" return gethostname().split(".")[0] + def ldb_delete(ldb): """Delete a LDB file. @@ -805,15 +808,6 @@ member: %s ldb.transaction_commit() -def valid_netbios_name(name): - """Check whether a name is valid as a NetBIOS name. """ - # FIXME: There are probably more constraints here. - # crh has a paragraph on this in his book (1.4.1.1) - if len(name) > 13: - return False - return True - - def join_domain(domain, netbios_name, join_type, creds, message): ctx = NetContext(creds) joindom = object() -- cgit From 68dc2dc526e146dd0ac68d5d68eb55b601282caf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 14:31:01 +0100 Subject: r26399: Use -O option for SWIG (less evil generated code). (This used to be commit 3378b6a559272cb702b52966692bf423f67a2b41) --- source4/scripting/python/config.mk | 2 +- source4/scripting/python/misc.py | 11 ++++++++++- source4/scripting/python/misc_wrap.c | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 91437e1e0b..c958761c70 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -16,7 +16,7 @@ swig: pythonmods .SUFFIXES: _wrap.c .i .i_wrap.c: - [ "$(SWIG)" == "no" ] || $(SWIG) -Wall -I$(srcdir)/scripting/swig -python -keyword $< + [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $< realdistclean:: @echo "Removing SWIG output files" diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 94625be2c9..afe7b723e0 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -2,7 +2,6 @@ # Version 1.3.33 # # Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. import _misc import new @@ -48,6 +47,16 @@ except AttributeError: del types +def _swig_setattr_nondynamic_method(set): + def set_attr(self,name,value): + if (name == "thisown"): return self.this.own(value) + if hasattr(self,name) or (name == "this"): + set(self,name,value) + else: + raise AttributeError("You cannot add attributes to %s" % self) + return set_attr + + random_password = _misc.random_password diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 2237f9cb03..fbdd33afda 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -9,7 +9,7 @@ * ----------------------------------------------------------------------------- */ #define SWIGPYTHON -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE +#define SWIG_PYTHON_NO_BUILD_NONE /* ----------------------------------------------------------------------------- * This section contains generic SWIG labels for method/variable * declarations/attributes, and other compiler dependent labels. @@ -2478,6 +2478,19 @@ static swig_module_info swig_module = {swig_types, 10, 0, 0, 0, 0}; # error "This python version requires swig to be run with the '-classic' option" # endif #endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodern' option" +#endif +#if (PY_VERSION_HEX <= 0x02020000) +# error "This python version requires swig to be run with the '-nomodernargs' option" +#endif +#ifndef METH_O +# error "This python version requires swig to be run with the '-nofastunpack' option" +#endif +#ifdef SWIG_TypeQuery +# undef SWIG_TypeQuery +#endif +#define SWIG_TypeQuery SWIG_Python_TypeQuery /*----------------------------------------------- @(target):= _misc.so -- cgit From 6d2edec0a27c674798c118076c2816b3ffdd78e5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 12 Dec 2007 03:02:18 +0100 Subject: r26411: Double check Python installation - make sure we can compile and link using it. (This used to be commit 3d8fc5808ced6f54274701d80fe2d42423bf9fee) --- source4/scripting/python/config.m4 | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 5e982556fc..64a8c70b41 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -119,9 +119,23 @@ AC_SUBST(PYTHON_EXTRA_LDFLAGS) SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CPPFLAGS]) + if test x$working_python = xyes then - SMB_ENABLE(LIBPYTHON,YES) + ac_save_LIBS="$LIBS" + ac_save_CFLAGS="$CFLAGS" + LIBS="$LIBS $PYTHON_LDFLAGS" + CFLAGS="$CFLAGS $PYTHON_CPPFLAGS" + + AC_TRY_LINK([ +#include +#include ], +[Py_InitModule(NULL, NULL);], + [SMB_ENABLE(LIBPYTHON,YES)], + [SMB_ENABLE(LIBPYTHON,NO)]) + + LIBS="$ac_save_LIBS" + CFLAGS="$ac_save_CFLAGS" else SMB_ENABLE(LIBPYTHON,NO) fi -- cgit From 8530e8429ac7b12f4bde285af2b7933610461253 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Dec 2007 08:36:03 +0100 Subject: r26422: build: let configure print out if we have working python module support metze (This used to be commit dfb9d704d053455d636d4f9d9d49cbfb70ada53e) --- source4/scripting/python/config.m4 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 64a8c70b41..8c4225175e 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -120,6 +120,7 @@ AC_SUBST(PYTHON_EXTRA_LDFLAGS) SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CPPFLAGS]) +AC_MSG_CHECKING(working python module support) if test x$working_python = xyes then ac_save_LIBS="$LIBS" @@ -128,14 +129,21 @@ then CFLAGS="$CFLAGS $PYTHON_CPPFLAGS" AC_TRY_LINK([ -#include -#include ], -[Py_InitModule(NULL, NULL);], - [SMB_ENABLE(LIBPYTHON,YES)], - [SMB_ENABLE(LIBPYTHON,NO)]) + #include + #include + ],[ + Py_InitModule(NULL, NULL); + ],[ + SMB_ENABLE(LIBPYTHON,YES) + AC_MSG_RESULT([yes]) + ],[ + SMB_ENABLE(LIBPYTHON,NO) + AC_MSG_RESULT([no]) + ]) LIBS="$ac_save_LIBS" CFLAGS="$ac_save_CFLAGS" else SMB_ENABLE(LIBPYTHON,NO) + AC_MSG_RESULT([no]) fi -- cgit From 55f90f1166d1050d010fffcca696dfb897e42e82 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 01:26:12 +0100 Subject: r26446: Convert param module to SWIG. (This used to be commit 94e5f9c92f65070ec8f1c1170c4a0769a4857c6d) --- source4/scripting/python/config.mk | 4 - source4/scripting/python/parammodule.c | 181 --------------------------------- 2 files changed, 185 deletions(-) delete mode 100644 source4/scripting/python/parammodule.c (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index c958761c70..9d972f7ee0 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,7 +1,3 @@ -[PYTHON::python_param] -PRIVATE_DEPENDENCIES = LIBSAMBA-CONFIG -OBJ_FILES = parammodule.o - [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR OBJ_FILES = uuidmodule.o diff --git a/source4/scripting/python/parammodule.c b/source4/scripting/python/parammodule.c deleted file mode 100644 index bb7adab240..0000000000 --- a/source4/scripting/python/parammodule.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python wrapper for reading smb.conf files - - Copyright (C) Jelmer Vernooij 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 2 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, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "Python.h" -#include "param/param.h" - -staticforward PyTypeObject param_ParamFileType; - -typedef struct { - PyObject_HEAD - struct param_context *param_ctx; -} param_ParamFileObject; - -static param_ParamFileObject *py_param_init(void) -{ - param_ParamFileObject *param; - - param = PyObject_New(param_ParamFileObject, ¶m_ParamFileType); - - param->param_ctx = param_init(NULL); - - return param; -} - -static PyObject *py_param_load(PyObject *self, PyObject *args) -{ - char *filename = NULL; - param_ParamFileObject *param; - - if (!PyArg_ParseTuple(args, "|s:new", &filename)) - return NULL; - - param = py_param_init(); - - if (filename != NULL) { - int ret = param_read(param->param_ctx, filename); - - if (ret == -1) { - PyErr_SetString(PyExc_TypeError, "reading file failed"); - return NULL; - } - } - - return (PyObject *)param; -} - -static void -param_dealloc(PyObject* self) -{ - PyObject_Del(self); -} - -static PyObject *py_param_get(PyObject *_self, PyObject *args) -{ - struct param_opt *param; - const char *section_name = NULL, *param_name = NULL; - param_ParamFileObject *self = (param_ParamFileObject *)_self; - - if (!PyArg_ParseTuple(args, (char *)"s|s", ¶m_name, §ion_name)) - return NULL; - - param = param_get(self->param_ctx, section_name, param_name); - if (param == NULL) - return Py_None; - - return PyString_FromString(param->value); -} - -static PyObject *py_param_set(PyObject *_self, PyObject *args) -{ - param_ParamFileObject *self = (param_ParamFileObject *)_self; - const char *section_name = NULL, *param_name = NULL, *param_value = NULL; - - if (!PyArg_ParseTuple(args, "ss|s", ¶m_name, ¶m_value, §ion_name)) - return NULL; - - if (section_name == NULL) - section_name = GLOBAL_NAME; - - if (param_set_string(self->param_ctx, section_name, param_name, param_value) != 0) { - PyErr_SetString(PyExc_TypeError, "setting variable failed"); - return NULL; - } - - return Py_None; -} - -static PyObject *py_param_save(PyObject *_self, PyObject *args) -{ - param_ParamFileObject *self = (param_ParamFileObject *)_self; - const char *filename = NULL; - - if (!PyArg_ParseTuple(args, "s", &filename)) - return NULL; - - if (param_write(self->param_ctx, filename) != 0) { - PyErr_SetString(PyExc_TypeError, "unable to save"); - return NULL; - } - - return Py_None; -} - -static PyObject *py_param_use(PyObject *_self, PyObject *args) -{ - param_ParamFileObject *self = (param_ParamFileObject *)_self; - - if (!PyArg_ParseTuple(args, "")) - return NULL; - - if (param_use(global_loadparm, self->param_ctx) != 0) { - PyErr_SetString(PyExc_TypeError, "unable to use"); - return NULL; - } - - return Py_None; -} - -static PyMethodDef param_methods[] = { - {"get", (PyCFunction)py_param_get, METH_VARARGS, - "Get a parameter."}, - {"set", (PyCFunction)py_param_set, METH_VARARGS, - "Set a parameter."}, - {"save", (PyCFunction)py_param_save, METH_VARARGS, - "Save file" }, - {"use", (PyCFunction)py_param_use, METH_VARARGS, - "Use param file" }, - {NULL, NULL, 0, NULL} -}; - -static PyObject * -param_getattr(PyTypeObject *obj, char *name) -{ - return Py_FindMethod(param_methods, (PyObject *)obj, name); -} - -static PyTypeObject param_ParamFileType = { - PyObject_HEAD_INIT(NULL) 0, - .tp_name = "ParamFile", - .tp_basicsize = sizeof(param_ParamFileObject), - .tp_dealloc = param_dealloc, - .tp_getattr = param_getattr, -}; - - -static PyMethodDef methods[] = { - { "ParamFile", (PyCFunction)py_param_load, METH_VARARGS, NULL}, - { NULL, NULL } -}; - -PyDoc_STRVAR(param_doc, "Simple wrappers around the smb.conf parsers"); - -PyMODINIT_FUNC initparam(void) -{ - PyObject *mod = Py_InitModule3("param", methods, param_doc); - if (mod == NULL) - return; - - PyModule_AddObject(mod, "configfile", - PyString_FromString(lp_configfile(global_loadparm))); -} -- cgit From 4a33ca21943f72ddde4b22ddd6591c2ccdbb657b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 01:53:54 +0100 Subject: r26450: The subprocess is only available in python >= 2.4 so avoid it for now. (This used to be commit 5300bc175ea425e2d28332c5e18bd8e3846b458d) --- source4/scripting/python/subunit/__init__.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py index e44dd766cc..4f24803e63 100644 --- a/source4/scripting/python/subunit/__init__.py +++ b/source4/scripting/python/subunit/__init__.py @@ -20,7 +20,6 @@ import os from StringIO import StringIO -import subprocess import sys import unittest @@ -315,9 +314,8 @@ class ExecTestCase(unittest.TestCase): def _run(self, result): protocol = TestProtocolServer(result) - output = subprocess.Popen([self.script], - stdout=subprocess.PIPE).communicate()[0] - protocol.readFrom(StringIO(output)) + output = os.popen(self.script, mode='r') + protocol.readFrom(output) class IsolatedTestCase(unittest.TestCase): -- cgit From eb2c71912baceb1a6884ce143ae91f1e3d2a69fb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 16 Dec 2007 14:50:18 +0100 Subject: r26471: Sync with js version. (This used to be commit c0eea26e8e8eb326112e1833d137751fb7e900d2) --- source4/scripting/python/samba/provision.py | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 692e49b095..df40c2fb7a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -695,6 +695,7 @@ def provision_guess(lp): subobj.modules_list = ["rootdse", "paged_results", "ranged_results", + "anr", "server_sort", "extended_dn", "asq", -- cgit From 1afe0549163bbc639ae1a030239c9ebcd1b922bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 16 Dec 2007 15:33:58 +0100 Subject: r26474: Move credentials-specific kerberos file to credentials subsystem. Fixes missing symbols in some of the python bindings. (This used to be commit e26d0fff6d40899113196ac35a86a9baa10cc9c2) --- source4/scripting/python/config.mk | 4 ++++ source4/scripting/python/samba/__init__.py | 9 +++++++++ 2 files changed, 13 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 9d972f7ee0..cf17a28a70 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -25,3 +25,7 @@ PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) + +clean:: + @echo "Removing python modules" + @rm -f bin/python/* diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 00b82e1800..2c51440b0c 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -21,6 +21,15 @@ import os from misc import ldb_set_credentials +def _in_source_tree(): + print os.path.exists("%s/../../../samba4-skip" % os.path.dirname(__file__)) + +# When running, in-tree, make sure bin/python is in the PYTHONPATH +if _in_source_tree(): + import sys + dir = os.path.dirname(__file__) + sys.path.append("%s/../../../bin/python" % os.path.dirname(__file__)) + def Ldb(url, session_info=None, credentials=None, modules_dir=None): """Open a Samba Ldb file. -- cgit From 0a01f50f9802ecfae430d2218af3b96a3682218d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 16 Dec 2007 15:50:02 +0100 Subject: r26475: Add ldb.set_credentials function. (This used to be commit dbebb4ef477d2c8de7b8d1e5cde9b9dada47044f) --- source4/scripting/python/misc.i | 10 ++- source4/scripting/python/misc.py | 4 + source4/scripting/python/misc_wrap.c | 134 ++++++++++++++++++++++++++--- source4/scripting/python/samba/__init__.py | 7 +- 4 files changed, 141 insertions(+), 14 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 088522320e..3d886a25bc 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -21,12 +21,20 @@ %{ #include "includes.h" #include "ldb.h" -#include "auth/credentials/credentials.h" %} %import "stdint.i" +%include "exception.i" %import "../../lib/talloc/talloc.i" +%import "../../lib/ldb/ldb.i" +%import "../../auth/credentials/credentials.i" %rename(random_password) generate_random_str; char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); +%inline %{ +void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) +{ + ldb_set_opaque(ldb, "credentials", creds); +} +%} diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index afe7b723e0..94b341ba72 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -57,6 +57,10 @@ def _swig_setattr_nondynamic_method(set): return set_attr +import ldb +import credentials +import param random_password = _misc.random_password +ldb_set_credentials = _misc.ldb_set_credentials diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index fbdd33afda..1f34d7f3ac 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2454,20 +2454,35 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) + #define SWIG_exception(code, msg) do { SWIG_Error(code, msg); SWIG_fail;; } while(0) + + /* -------- TYPES TABLE (BEGIN) -------- */ #define SWIGTYPE_p_TALLOC_CTX swig_types[0] #define SWIGTYPE_p_char swig_types[1] -#define SWIGTYPE_p_int swig_types[2] -#define SWIGTYPE_p_long_long swig_types[3] -#define SWIGTYPE_p_short swig_types[4] -#define SWIGTYPE_p_signed_char swig_types[5] -#define SWIGTYPE_p_unsigned_char swig_types[6] -#define SWIGTYPE_p_unsigned_int swig_types[7] -#define SWIGTYPE_p_unsigned_long_long swig_types[8] -#define SWIGTYPE_p_unsigned_short swig_types[9] -static swig_type_info *swig_types[11]; -static swig_module_info swig_module = {swig_types, 10, 0, 0, 0, 0}; +#define SWIGTYPE_p_cli_credentials swig_types[2] +#define SWIGTYPE_p_int swig_types[3] +#define SWIGTYPE_p_ldb_context swig_types[4] +#define SWIGTYPE_p_ldb_dn swig_types[5] +#define SWIGTYPE_p_ldb_ldif swig_types[6] +#define SWIGTYPE_p_ldb_message swig_types[7] +#define SWIGTYPE_p_ldb_message_element swig_types[8] +#define SWIGTYPE_p_ldb_result swig_types[9] +#define SWIGTYPE_p_loadparm_context swig_types[10] +#define SWIGTYPE_p_loadparm_service swig_types[11] +#define SWIGTYPE_p_long_long swig_types[12] +#define SWIGTYPE_p_param_context swig_types[13] +#define SWIGTYPE_p_param_section swig_types[14] +#define SWIGTYPE_p_short swig_types[15] +#define SWIGTYPE_p_signed_char swig_types[16] +#define SWIGTYPE_p_unsigned_char swig_types[17] +#define SWIGTYPE_p_unsigned_int swig_types[18] +#define SWIGTYPE_p_unsigned_long swig_types[19] +#define SWIGTYPE_p_unsigned_long_long swig_types[20] +#define SWIGTYPE_p_unsigned_short swig_types[21] +static swig_type_info *swig_types[23]; +static swig_module_info swig_module = {swig_types, 22, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2509,7 +2524,6 @@ static swig_module_info swig_module = {swig_types, 10, 0, 0, 0, 0}; #include "includes.h" #include "ldb.h" -#include "auth/credentials/credentials.h" SWIGINTERN int @@ -2682,6 +2696,12 @@ SWIG_FromCharPtr(const char *cptr) return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0)); } + +void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) +{ + ldb_set_opaque(ldb, "credentials", creds); +} + #ifdef __cplusplus extern "C" { #endif @@ -2714,8 +2734,52 @@ fail: } +SWIGINTERN PyObject *_wrap_ldb_set_credentials(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + struct cli_credentials *arg2 = (struct cli_credentials *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "Ldb",(char *) "creds", NULL + }; + + { + arg2 = NULL; + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|O:ldb_set_credentials",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_set_credentials" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + if (obj1) { + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_cli_credentials, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_set_credentials" "', argument " "2"" of type '" "struct cli_credentials *""'"); + } + arg2 = (struct cli_credentials *)(argp2); + } + { + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + } + ldb_set_credentials(arg1,arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; @@ -2724,48 +2788,96 @@ static PyMethodDef SwigMethods[] = { static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_context = {"_p_ldb_context", "struct ldb_context *|ldb *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_dn = {"_p_ldb_dn", "struct ldb_dn *|ldb_dn *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_ldif = {"_p_ldb_ldif", "struct ldb_ldif *|ldb_ldif *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_message = {"_p_ldb_message", "ldb_msg *|struct ldb_message *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element", "struct ldb_message_element *|ldb_msg_element *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_param_context = {"_p_param_context", "struct param_context *|param *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_param_section = {"_p_param_section", "struct param_section *|param_section *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_int = {"_p_unsigned_int", "uintptr_t *|uint_least32_t *|uint_fast32_t *|uint32_t *|unsigned int *|uint_fast16_t *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_unsigned_long = {"_p_unsigned_long", "unsigned long *|time_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", "uint_least64_t *|uint_fast64_t *|uint64_t *|unsigned long long *|uintmax_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { &_swigt__p_TALLOC_CTX, &_swigt__p_char, + &_swigt__p_cli_credentials, &_swigt__p_int, + &_swigt__p_ldb_context, + &_swigt__p_ldb_dn, + &_swigt__p_ldb_ldif, + &_swigt__p_ldb_message, + &_swigt__p_ldb_message_element, + &_swigt__p_ldb_result, + &_swigt__p_loadparm_context, + &_swigt__p_loadparm_service, &_swigt__p_long_long, + &_swigt__p_param_context, + &_swigt__p_param_section, &_swigt__p_short, &_swigt__p_signed_char, &_swigt__p_unsigned_char, &_swigt__p_unsigned_int, + &_swigt__p_unsigned_long, &_swigt__p_unsigned_long_long, &_swigt__p_unsigned_short, }; static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_cli_credentials[] = { {&_swigt__p_cli_credentials, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ldb_context[] = { {&_swigt__p_ldb_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ldb_dn[] = { {&_swigt__p_ldb_dn, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ldb_ldif[] = { {&_swigt__p_ldb_ldif, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ldb_message[] = { {&_swigt__p_ldb_message, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ldb_message_element[] = { {&_swigt__p_ldb_message_element, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_ldb_result[] = { {&_swigt__p_ldb_result, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_loadparm_context[] = { {&_swigt__p_loadparm_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_loadparm_service[] = { {&_swigt__p_loadparm_service, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_param_context[] = { {&_swigt__p_param_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_param_section[] = { {&_swigt__p_param_section, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_int[] = { {&_swigt__p_unsigned_int, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_unsigned_long[] = { {&_swigt__p_unsigned_long, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_long_long, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { _swigc__p_TALLOC_CTX, _swigc__p_char, + _swigc__p_cli_credentials, _swigc__p_int, + _swigc__p_ldb_context, + _swigc__p_ldb_dn, + _swigc__p_ldb_ldif, + _swigc__p_ldb_message, + _swigc__p_ldb_message_element, + _swigc__p_ldb_result, + _swigc__p_loadparm_context, + _swigc__p_loadparm_service, _swigc__p_long_long, + _swigc__p_param_context, + _swigc__p_param_section, _swigc__p_short, _swigc__p_signed_char, _swigc__p_unsigned_char, _swigc__p_unsigned_int, + _swigc__p_unsigned_long, _swigc__p_unsigned_long_long, _swigc__p_unsigned_short, }; diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 2c51440b0c..29d322e2fc 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -19,10 +19,9 @@ # import os -from misc import ldb_set_credentials def _in_source_tree(): - print os.path.exists("%s/../../../samba4-skip" % os.path.dirname(__file__)) + return os.path.exists("%s/../../../samba4-skip" % os.path.dirname(__file__)) # When running, in-tree, make sure bin/python is in the PYTHONPATH if _in_source_tree(): @@ -30,6 +29,10 @@ if _in_source_tree(): dir = os.path.dirname(__file__) sys.path.append("%s/../../../bin/python" % os.path.dirname(__file__)) +import misc +import ldb +ldb.ldb.set_credentials = misc.ldb_set_credentials + def Ldb(url, session_info=None, credentials=None, modules_dir=None): """Open a Samba Ldb file. -- cgit From 440fd879613b94cc75eb0737af91602d96c89bf9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 16 Dec 2007 17:17:37 +0100 Subject: r26477: Allow setting loadparm context for a ldb context in python, plus some other minor improvements. (This used to be commit d88527a9d6435203faa8273347d5aa41937e5395) --- source4/scripting/python/misc.i | 14 ++++++++ source4/scripting/python/misc.py | 1 + source4/scripting/python/misc_wrap.c | 57 ++++++++++++++++++++++++++++++ source4/scripting/python/samba/__init__.py | 31 ++++++++++++---- 4 files changed, 96 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 3d886a25bc..b2a7ad8ee8 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -21,6 +21,7 @@ %{ #include "includes.h" #include "ldb.h" +#include "param/param.h" %} %import "stdint.i" @@ -28,6 +29,7 @@ %import "../../lib/talloc/talloc.i" %import "../../lib/ldb/ldb.i" %import "../../auth/credentials/credentials.i" +%import "../../param/param.i" %rename(random_password) generate_random_str; char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); @@ -37,4 +39,16 @@ void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) { ldb_set_opaque(ldb, "credentials", creds); } + +#if 0 /* Fails to link.. */ +void ldb_set_session_info(struct ldb_context *ldb, struct auth_session_info *session_info) +{ + ldb_set_opaque(ldb, "sessionInfo", session_info); +} +#endif + +void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) +{ + ldb_set_opaque(ldb, "loadparm", lp_ctx); +} %} diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 94b341ba72..8a8ff80107 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -62,5 +62,6 @@ import credentials import param random_password = _misc.random_password ldb_set_credentials = _misc.ldb_set_credentials +ldb_set_loadparm = _misc.ldb_set_loadparm diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 1f34d7f3ac..af0f32fcb2 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2524,6 +2524,7 @@ static swig_module_info swig_module = {swig_types, 22, 0, 0, 0, 0}; #include "includes.h" #include "ldb.h" +#include "param/param.h" SWIGINTERN int @@ -2702,6 +2703,18 @@ void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) ldb_set_opaque(ldb, "credentials", creds); } +#if 0 /* Fails to link.. */ +void ldb_set_session_info(struct ldb_context *ldb, struct auth_session_info *session_info) +{ + ldb_set_opaque(ldb, "sessionInfo", session_info); +} +#endif + +void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) +{ + ldb_set_opaque(ldb, "loadparm", lp_ctx); +} + #ifdef __cplusplus extern "C" { #endif @@ -2777,9 +2790,53 @@ fail: } +SWIGINTERN PyObject *_wrap_ldb_set_loadparm(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + struct loadparm_context *arg2 = (struct loadparm_context *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "Ldb",(char *) "lp_ctx", NULL + }; + + { + arg2 = loadparm_init(NULL); + } + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|O:ldb_set_loadparm",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_set_loadparm" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + if (obj1) { + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_set_loadparm" "', argument " "2"" of type '" "struct loadparm_context *""'"); + } + arg2 = (struct loadparm_context *)(argp2); + } + { + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + } + ldb_set_loadparm(arg1,arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 29d322e2fc..08a262eec8 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -21,21 +21,33 @@ import os def _in_source_tree(): + """Check whether the script is being run from the source dir. """ return os.path.exists("%s/../../../samba4-skip" % os.path.dirname(__file__)) + # When running, in-tree, make sure bin/python is in the PYTHONPATH if _in_source_tree(): import sys - dir = os.path.dirname(__file__) - sys.path.append("%s/../../../bin/python" % os.path.dirname(__file__)) + srcdir = "%s/../../.." % os.path.dirname(__file__) + sys.path.append("%s/bin/python" % srcdir) + default_ldb_modules_dir = "%s/bin/modules/ldb" % srcdir + import misc import ldb ldb.ldb.set_credentials = misc.ldb_set_credentials +#FIXME: ldb.ldb.set_session_info = misc.ldb_set_session_info +ldb.ldb.set_loadparm = misc.ldb_set_loadparm -def Ldb(url, session_info=None, credentials=None, modules_dir=None): +def Ldb(url, session_info=None, credentials=None, modules_dir=None, lp=None): """Open a Samba Ldb file. + :param url: LDB Url to open + :param session_info: Optional session information + :param credentials: Optional credentials, defaults to anonymous. + :param modules_dir: Modules directory, automatically set if not specified. + :param lp: Loadparm object, optional. + This is different from a regular Ldb file in that the Samba-specific modules-dir is used by default and that credentials and session_info can be passed through (required by some modules). @@ -43,12 +55,17 @@ def Ldb(url, session_info=None, credentials=None, modules_dir=None): import ldb ret = ldb.Ldb() if modules_dir is None: - modules_dir = os.path.join(os.getcwd(), "bin", "modules", "ldb") - ret.set_modules_dir(modules_dir) + modules_dir = default_ldb_modules_dir + if modules_dir is not None: + ret.set_modules_dir(modules_dir) def samba_debug(level,text): print "%d %s" % (level, text) - ldb_set_opaque("credentials", credentials) - ret.set_opaque("sessionInfo", session_info) + if credentials is not None: + ldb.set_credentials(credentials) + if session_info is not None: + ldb.set_session_info(session_info) + if lp is not None: + ldb.set_loadparm(lp) #ret.set_debug(samba_debug) ret.connect(url) return ret -- cgit From 07beaf09c95a06636cb029fcc2dbbeb7293879ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 03:25:28 +0100 Subject: r26480: Add utility class for testing LDB code. (This used to be commit d7f0b12c9e43b93705f6b9fa6b5ab74fe68e80a0) --- source4/scripting/python/samba/tests/__init__.py | 37 ++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 source4/scripting/python/samba/tests/__init__.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py new file mode 100644 index 0000000000..d374f8bafa --- /dev/null +++ b/source4/scripting/python/samba/tests/__init__.py @@ -0,0 +1,37 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 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 . +# + +import os +import ldb +import samba +import unittest + +class LdbTestCase(unittest.TestCase): + def setUp(self): + self.filename = os.tempnam() + self.ldb = samba.Ldb(self.filename) + + def load_modules(self, modules=[]): + m = ldb.Message() + m.dn = ldb.Dn(self.ldb, "@MODULES") + m["@LIST"] = ",".join(modules) + self.ldb.add(m) + self.ldb = samba.Ldb(self.filename) + + -- cgit From be999912671de052af909bb88f13c956f12b30e1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 04:56:54 +0100 Subject: r26484: Don't rely on removed header. (This used to be commit 6ca2b350858c0747449671234d54584635512705) --- source4/scripting/python/samba/provision.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index df40c2fb7a..ce496a8bc1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -10,7 +10,7 @@ import os import pwd import grp import time -import uuid, sid, misc +import uuid, misc from socket import gethostname, gethostbyname import param import registry @@ -61,8 +61,8 @@ class ProvisionSettings(object): "SCHEMADN_MOD": "schema_fsmo", "SCHEMADN_MOD2": ",objectguid", "CONFIGDN": self.configdn, - "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list) - "MODULES_LIST2": ",".join(self.modules_list2) + "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list), + "MODULES_LIST2": ",".join(self.modules_list2), "CONFIGDN_LDB": self.configdn_ldb, "DOMAINDN": self.domaindn, "DOMAINDN_LDB": self.domaindn_ldb, -- cgit From b0360e3a8617c59661d0b0fd805666e6cefcd811 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 08:20:20 +0100 Subject: r26496: Move some provision functions to a new SamDB class, support setting session_info on a ldb context from python. (This used to be commit 75cfb0d609687538048a7d72a499a5205af46a34) --- source4/scripting/python/misc.i | 2 - source4/scripting/python/misc.py | 1 + source4/scripting/python/misc_wrap.c | 96 ++++++++---- source4/scripting/python/samba/__init__.py | 104 +++++++++---- source4/scripting/python/samba/provision.py | 230 +++++++--------------------- source4/scripting/python/samba/samdb.py | 117 ++++++++++++++ 6 files changed, 316 insertions(+), 234 deletions(-) create mode 100644 source4/scripting/python/samba/samdb.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index b2a7ad8ee8..0a94fcdc29 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -40,12 +40,10 @@ void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) ldb_set_opaque(ldb, "credentials", creds); } -#if 0 /* Fails to link.. */ void ldb_set_session_info(struct ldb_context *ldb, struct auth_session_info *session_info) { ldb_set_opaque(ldb, "sessionInfo", session_info); } -#endif void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) { diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 8a8ff80107..7628dbcb15 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -62,6 +62,7 @@ import credentials import param random_password = _misc.random_password ldb_set_credentials = _misc.ldb_set_credentials +ldb_set_session_info = _misc.ldb_set_session_info ldb_set_loadparm = _misc.ldb_set_loadparm diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index af0f32fcb2..f5e23d0407 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2460,29 +2460,30 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) /* -------- TYPES TABLE (BEGIN) -------- */ #define SWIGTYPE_p_TALLOC_CTX swig_types[0] -#define SWIGTYPE_p_char swig_types[1] -#define SWIGTYPE_p_cli_credentials swig_types[2] -#define SWIGTYPE_p_int swig_types[3] -#define SWIGTYPE_p_ldb_context swig_types[4] -#define SWIGTYPE_p_ldb_dn swig_types[5] -#define SWIGTYPE_p_ldb_ldif swig_types[6] -#define SWIGTYPE_p_ldb_message swig_types[7] -#define SWIGTYPE_p_ldb_message_element swig_types[8] -#define SWIGTYPE_p_ldb_result swig_types[9] -#define SWIGTYPE_p_loadparm_context swig_types[10] -#define SWIGTYPE_p_loadparm_service swig_types[11] -#define SWIGTYPE_p_long_long swig_types[12] -#define SWIGTYPE_p_param_context swig_types[13] -#define SWIGTYPE_p_param_section swig_types[14] -#define SWIGTYPE_p_short swig_types[15] -#define SWIGTYPE_p_signed_char swig_types[16] -#define SWIGTYPE_p_unsigned_char swig_types[17] -#define SWIGTYPE_p_unsigned_int swig_types[18] -#define SWIGTYPE_p_unsigned_long swig_types[19] -#define SWIGTYPE_p_unsigned_long_long swig_types[20] -#define SWIGTYPE_p_unsigned_short swig_types[21] -static swig_type_info *swig_types[23]; -static swig_module_info swig_module = {swig_types, 22, 0, 0, 0, 0}; +#define SWIGTYPE_p_auth_session_info swig_types[1] +#define SWIGTYPE_p_char swig_types[2] +#define SWIGTYPE_p_cli_credentials swig_types[3] +#define SWIGTYPE_p_int swig_types[4] +#define SWIGTYPE_p_ldb_context swig_types[5] +#define SWIGTYPE_p_ldb_dn swig_types[6] +#define SWIGTYPE_p_ldb_ldif swig_types[7] +#define SWIGTYPE_p_ldb_message swig_types[8] +#define SWIGTYPE_p_ldb_message_element swig_types[9] +#define SWIGTYPE_p_ldb_result swig_types[10] +#define SWIGTYPE_p_loadparm_context swig_types[11] +#define SWIGTYPE_p_loadparm_service swig_types[12] +#define SWIGTYPE_p_long_long swig_types[13] +#define SWIGTYPE_p_param_context swig_types[14] +#define SWIGTYPE_p_param_section swig_types[15] +#define SWIGTYPE_p_short swig_types[16] +#define SWIGTYPE_p_signed_char swig_types[17] +#define SWIGTYPE_p_unsigned_char swig_types[18] +#define SWIGTYPE_p_unsigned_int swig_types[19] +#define SWIGTYPE_p_unsigned_long swig_types[20] +#define SWIGTYPE_p_unsigned_long_long swig_types[21] +#define SWIGTYPE_p_unsigned_short swig_types[22] +static swig_type_info *swig_types[24]; +static swig_module_info swig_module = {swig_types, 23, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2703,12 +2704,10 @@ void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) ldb_set_opaque(ldb, "credentials", creds); } -#if 0 /* Fails to link.. */ void ldb_set_session_info(struct ldb_context *ldb, struct auth_session_info *session_info) { ldb_set_opaque(ldb, "sessionInfo", session_info); } -#endif void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) { @@ -2758,7 +2757,7 @@ SWIGINTERN PyObject *_wrap_ldb_set_credentials(PyObject *SWIGUNUSEDPARM(self), P PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; char * kwnames[] = { - (char *) "Ldb",(char *) "creds", NULL + (char *) "ldb",(char *) "creds", NULL }; { @@ -2790,6 +2789,44 @@ fail: } +SWIGINTERN PyObject *_wrap_ldb_set_session_info(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + struct auth_session_info *arg2 = (struct auth_session_info *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "ldb",(char *) "session_info", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:ldb_set_session_info",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_set_session_info" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_auth_session_info, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_set_session_info" "', argument " "2"" of type '" "struct auth_session_info *""'"); + } + arg2 = (struct auth_session_info *)(argp2); + { + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + } + ldb_set_session_info(arg1,arg2); + resultobj = SWIG_Py_Void(); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_ldb_set_loadparm(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; @@ -2801,7 +2838,7 @@ SWIGINTERN PyObject *_wrap_ldb_set_loadparm(PyObject *SWIGUNUSEDPARM(self), PyOb PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; char * kwnames[] = { - (char *) "Ldb",(char *) "lp_ctx", NULL + (char *) "ldb",(char *) "lp_ctx", NULL }; { @@ -2836,6 +2873,7 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_set_session_info", (PyCFunction) _wrap_ldb_set_session_info, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; @@ -2844,6 +2882,7 @@ static PyMethodDef SwigMethods[] = { /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; @@ -2868,6 +2907,7 @@ static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned static swig_type_info *swig_type_initial[] = { &_swigt__p_TALLOC_CTX, + &_swigt__p_auth_session_info, &_swigt__p_char, &_swigt__p_cli_credentials, &_swigt__p_int, @@ -2892,6 +2932,7 @@ static swig_type_info *swig_type_initial[] = { }; static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_auth_session_info[] = { {&_swigt__p_auth_session_info, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_cli_credentials[] = { {&_swigt__p_cli_credentials, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; @@ -2916,6 +2957,7 @@ static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short static swig_cast_info *swig_cast_initial[] = { _swigc__p_TALLOC_CTX, + _swigc__p_auth_session_info, _swigc__p_char, _swigc__p_cli_credentials, _swigc__p_int, diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 08a262eec8..56adce4473 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -35,40 +35,78 @@ if _in_source_tree(): import misc import ldb -ldb.ldb.set_credentials = misc.ldb_set_credentials -#FIXME: ldb.ldb.set_session_info = misc.ldb_set_session_info -ldb.ldb.set_loadparm = misc.ldb_set_loadparm - -def Ldb(url, session_info=None, credentials=None, modules_dir=None, lp=None): - """Open a Samba Ldb file. - - :param url: LDB Url to open - :param session_info: Optional session information - :param credentials: Optional credentials, defaults to anonymous. - :param modules_dir: Modules directory, automatically set if not specified. - :param lp: Loadparm object, optional. - - This is different from a regular Ldb file in that the Samba-specific - modules-dir is used by default and that credentials and session_info - can be passed through (required by some modules). +ldb.Ldb.set_credentials = misc.ldb_set_credentials +ldb.Ldb.set_session_info = misc.ldb_set_session_info +ldb.Ldb.set_loadparm = misc.ldb_set_loadparm + +class Ldb(ldb.Ldb): + """Simple Samba-specific LDB subclass that takes care + of setting up the modules dir, credentials pointers, etc. + + Please note that this is intended to be for all Samba LDB files, + not necessarily the Sam database. For Sam-specific helper + functions see samdb.py. """ - import ldb - ret = ldb.Ldb() - if modules_dir is None: - modules_dir = default_ldb_modules_dir - if modules_dir is not None: - ret.set_modules_dir(modules_dir) - def samba_debug(level,text): - print "%d %s" % (level, text) - if credentials is not None: - ldb.set_credentials(credentials) - if session_info is not None: - ldb.set_session_info(session_info) - if lp is not None: - ldb.set_loadparm(lp) - #ret.set_debug(samba_debug) - ret.connect(url) - return ret + def __init__(url, session_info=None, credentials=None, modules_dir=None, + lp=None): + """Open a Samba Ldb file. + + :param url: LDB Url to open + :param session_info: Optional session information + :param credentials: Optional credentials, defaults to anonymous. + :param modules_dir: Modules directory, automatically set if not specified. + :param lp: Loadparm object, optional. + + This is different from a regular Ldb file in that the Samba-specific + modules-dir is used by default and that credentials and session_info + can be passed through (required by some modules). + """ + super(self, Ldb).__init__() + import ldb + ret = ldb.Ldb() + if modules_dir is None: + modules_dir = default_ldb_modules_dir + if modules_dir is not None: + ret.set_modules_dir(modules_dir) + def samba_debug(level,text): + print "%d %s" % (level, text) + if credentials is not None: + ldb.set_credentials(credentials) + if session_info is not None: + ldb.set_session_info(session_info) + if lp is not None: + ldb.set_loadparm(lp) + #ret.set_debug(samba_debug) + ret.connect(url) + return ret + + def searchone(self, basedn, expression, attribute): + """Search for one attribute as a string.""" + res = self.search(basedn, SCOPE_SUBTREE, expression, [attribute]) + if len(res) != 1 or res[0][attribute] is None: + return None + return res[0][attribute] + + def erase(self): + """Erase an ldb, removing all records.""" + # delete the specials + for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", + "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: + try: + self.delete(Dn(self, attr)) + except LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): + # Ignore missing dn errors + pass + + basedn = Dn(self, "") + # and the rest + for msg in self.search(basedn, SCOPE_SUBTREE, + "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", + ["dn"]): + self.delete(msg.dn) + + res = self.search(basedn, SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) + assert len(res) == 0 def substitute_var(text, values): diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ce496a8bc1..63e50897fe 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -15,6 +15,7 @@ from socket import gethostname, gethostbyname import param import registry from samba import Ldb, substitute_var, valid_netbios_name +from samba.samdb import SamDB from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring @@ -164,32 +165,6 @@ def findnss(nssfn, *names): pass raise Exception("Unable to find user/group for %s" % arguments[1]) -def add_foreign(ldb, subobj, sid, desc): - """Add a foreign security principle.""" - add = """ -dn: CN=%s,CN=ForeignSecurityPrincipals,%s -objectClass: top -objectClass: foreignSecurityPrincipal -description: %s -""" % (sid, subobj.domaindn, desc) - # deliberately ignore errors from this, as the records may - # already exist - for msg in ldb.parse_ldif(add): - ldb.add(msg[1]) - -def setup_name_mapping(subobj, ldb, sid, unixname): - """Setup a mapping between a sam name and a unix name.""" - res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_SUBTREE, - "objectSid=%s" % sid, ["dn"]) - assert len(res) == 1, "Failed to find record for objectSid %s" % sid - - mod = """ -dn: %s -changetype: modify -replace: unixName -unixName: %s -""" % (res[0].dn, unixname) - ldb.modify(ldb.parse_ldif(mod).next()[1]) def hostip(): @@ -214,57 +189,6 @@ def ldb_delete(ldb): ldb.connect(ldb.filename) -def ldb_erase(ldb): - """Erase an ldb, removing all records.""" - # delete the specials - for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", - "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: - try: - ldb.delete(Dn(ldb, attr)) - except LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): - # Ignore missing dn errors - pass - - basedn = Dn(ldb, "") - # and the rest - for msg in ldb.search(basedn, SCOPE_SUBTREE, - "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", - ["dn"]): - ldb.delete(msg.dn) - - res = ldb.search(basedn, SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) - assert len(res) == 0 - - -def ldb_erase_partitions(subobj, message, ldb, ldapbackend): - """Erase an ldb, removing all records.""" - assert ldb is not None - res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", - ["namingContexts"]) - assert len(res) == 1 - if not "namingContexts" in res[0]: - return - for basedn in res[0]["namingContexts"]: - anything = "(|(objectclass=*)(dn=*))" - previous_remaining = 1 - current_remaining = 0 - - if ldapbackend and (basedn == subobj.domaindn): - # Only delete objects that were created by provision - anything = "(objectcategory=*)" - - k = 0 - while ++k < 10 and (previous_remaining != current_remaining): - # and the rest - res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) - previous_remaining = current_remaining - current_remaining = len(res2) - for msg in res2: - try: - ldb.delete(msg.dn) - except LdbError, (_, text): - message("Unable to delete %s: %s" % (msg.dn, text)) - def open_ldb(session_info, credentials, dbname): assert session_info is not None @@ -374,30 +298,30 @@ def setup_name_mappings(subobj, ldb): sid = list(res[0]["objectSid"])[0] # add some foreign sids if they are not present already - add_foreign(ldb, subobj, "S-1-5-7", "Anonymous") - add_foreign(ldb, subobj, "S-1-1-0", "World") - add_foreign(ldb, subobj, "S-1-5-2", "Network") - add_foreign(ldb, subobj, "S-1-5-18", "System") - add_foreign(ldb, subobj, "S-1-5-11", "Authenticated Users") + ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") + ldb.add_foreign(subobj.domaindn, "S-1-1-0", "World") + ldb.add_foreign(subobj.domaindn, "S-1-5-2", "Network") + ldb.add_foreign(subobj.domaindn, "S-1-5-18", "System") + ldb.add_foreign(subobj.domaindn, "S-1-5-11", "Authenticated Users") # some well known sids - setup_name_mapping(subobj, ldb, "S-1-5-7", subobj.nobody) - setup_name_mapping(subobj, ldb, "S-1-1-0", subobj.nogroup) - setup_name_mapping(subobj, ldb, "S-1-5-2", subobj.nogroup) - setup_name_mapping(subobj, ldb, "S-1-5-18", subobj.root) - setup_name_mapping(subobj, ldb, "S-1-5-11", subobj.users) - setup_name_mapping(subobj, ldb, "S-1-5-32-544", subobj.wheel) - setup_name_mapping(subobj, ldb, "S-1-5-32-545", subobj.users) - setup_name_mapping(subobj, ldb, "S-1-5-32-546", subobj.nogroup) - setup_name_mapping(subobj, ldb, "S-1-5-32-551", subobj.backup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-7", subobj.nobody) + ldb.setup_name_mapping(subobj.domaindn, "S-1-1-0", subobj.nogroup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-2", subobj.nogroup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-18", subobj.root) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-11", subobj.users) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-544", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-545", subobj.users) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-546", subobj.nogroup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-551", subobj.backup) # and some well known domain rids - setup_name_mapping(subobj, ldb, sid + "-500", subobj.root) - setup_name_mapping(subobj, ldb, sid + "-518", subobj.wheel) - setup_name_mapping(subobj, ldb, sid + "-519", subobj.wheel) - setup_name_mapping(subobj, ldb, sid + "-512", subobj.wheel) - setup_name_mapping(subobj, ldb, sid + "-513", subobj.users) - setup_name_mapping(subobj, ldb, sid + "-520", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-500", subobj.root) + ldb.setup_name_mapping(subobj.domaindn, sid + "-518", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-519", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-512", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-513", subobj.users) + ldb.setup_name_mapping(subobj.domaindn, sid + "-520", subobj.wheel) def provision_become_dc(setup_dir, subobj, message, paths, session_info, @@ -414,7 +338,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, session_info, setup_ldb(setup_dir, "provision_partitions.ldif", session_info, credentials, subobj, paths.samdb) - samdb = open_ldb(session_info, credentials, paths.samdb) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials) ldb.transaction_start() try: message("Setting up %s attributes" % paths.samdb) @@ -424,7 +349,7 @@ def provision_become_dc(setup_dir, subobj, message, paths, session_info, setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) message("Erasing data from partitions") - ldb_erase_partitions(subobj, message, samdb, undefined) + ldb_erase_partitions(subobj, message, samdb, None) message("Setting up %s indexes" % paths.samdb) setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) @@ -603,7 +528,7 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): """Write out a DNS zone file, from the info in the current database.""" message("Setting up DNS zone: %s" % subobj.dnsdomain) # connect to the sam - ldb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) + ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials) # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database @@ -614,7 +539,7 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): assert(res[0]["objectGUID"] is not None) subobj.domainguid = res[0]["objectGUID"] - subobj.host_guid = searchone(ldb, subobj.domaindn, + subobj.host_guid = ldb.searchone(subobj.domaindn, "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID") assert subobj.host_guid is not None @@ -716,13 +641,6 @@ def provision_guess(lp): return subobj -def searchone(ldb, basedn, expression, attribute): - """search for one attribute as a string.""" - res = ldb.search(basedn, SCOPE_SUBTREE, expression, [attribute]) - if len(res) != 1 or res[0][attribute] is None: - return None - return res[0][attribute] - def load_schema(setup_dir, subobj, samdb): """Load schema.""" @@ -745,70 +663,6 @@ def load_schema(setup_dir, subobj, samdb): samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) -def enable_account(ldb, user_dn): - """enable the account.""" - res = ldb.search(user_dn, SCOPE_ONELEVEL, None, ["userAccountControl"]) - assert len(res) == 1 - userAccountControl = res[0].userAccountControl - userAccountControl = userAccountControl - 2 # remove disabled bit - mod = """ -dn: %s -changetype: modify -replace: userAccountControl -userAccountControl: %u -""" % (user_dn, userAccountControl) - ldb.modify(mod) - - -def newuser(sam, username, unixname, password, message, session_info, - credentials): - """add a new user record""" - # connect to the sam - ldb.transaction_start() - - # find the DNs for the domain and the domain users group - res = ldb.search("", SCOPE_BASE, "defaultNamingContext=*", - ["defaultNamingContext"]) - assert(len(res) == 1 and res[0].defaultNamingContext is not None) - domain_dn = res[0].defaultNamingContext - assert(domain_dn is not None) - dom_users = searchone(ldb, domain_dn, "name=Domain Users", "dn") - assert(dom_users is not None) - - user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) - - # - # the new user record. note the reliance on the samdb module to fill - # in a sid, guid etc - # - ldif = """ -dn: %s -sAMAccountName: %s -unixName: %s -sambaPassword: %s -objectClass: user -""" % (user_dn, username, unixname, password) - # add the user to the users group as well - modgroup = """ -dn: %s -changetype: modify -add: member -member: %s -""" % (dom_users, user_dn) - - - # now the real work - message("Adding user %s" % user_dn) - ldb.add(ldif) - - message("Modifying group %s" % dom_users) - ldb.modify(modgroup) - - # modify the userAccountControl to remove the disabled bit - enable_account(ldb, user_dn) - ldb.transaction_commit() - - def join_domain(domain, netbios_name, join_type, creds, message): ctx = NetContext(creds) joindom = object() @@ -835,3 +689,35 @@ def vampire(domain, session_info, credentials, message): vampire_ctx.session_info = session_info if not ctx.SamSyncLdb(vampire_ctx): raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) + + +def ldb_erase_partitions(subobj, message, ldb, ldapbackend): + """Erase an ldb, removing all records.""" + assert ldb is not None + res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", + ["namingContexts"]) + assert len(res) == 1 + if not "namingContexts" in res[0]: + return + for basedn in res[0]["namingContexts"]: + anything = "(|(objectclass=*)(dn=*))" + previous_remaining = 1 + current_remaining = 0 + + if ldapbackend and (basedn == subobj.domaindn): + # Only delete objects that were created by provision + anything = "(objectcategory=*)" + + k = 0 + while ++k < 10 and (previous_remaining != current_remaining): + # and the rest + res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) + previous_remaining = current_remaining + current_remaining = len(res2) + for msg in res2: + try: + ldb.delete(msg.dn) + except LdbError, (_, text): + message("Unable to delete %s: %s" % (msg.dn, text)) + + diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py new file mode 100644 index 0000000000..50164bf590 --- /dev/null +++ b/source4/scripting/python/samba/samdb.py @@ -0,0 +1,117 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2007 +# +# Based on the original in EJS: +# Copyright (C) Andrew Tridgell 2005 +# +# 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 . +# + +import samba + +class SamDB(samba.Ldb): + def add_foreign(self, domaindn, sid, desc): + """Add a foreign security principle.""" + add = """ +dn: CN=%s,CN=ForeignSecurityPrincipals,%s +objectClass: top +objectClass: foreignSecurityPrincipal +description: %s + """ % (sid, domaindn, desc) + # deliberately ignore errors from this, as the records may + # already exist + for msg in self.parse_ldif(add): + self.add(msg[1]) + + def setup_name_mapping(self, domaindn, sid, unixname): + """Setup a mapping between a sam name and a unix name.""" + res = self.search(Dn(ldb, domaindn), SCOPE_SUBTREE, + "objectSid=%s" % sid, ["dn"]) + assert len(res) == 1, "Failed to find record for objectSid %s" % sid + + mod = """ +dn: %s +changetype: modify +replace: unixName +unixName: %s +""" % (res[0].dn, unixname) + self.modify(self.parse_ldif(mod).next()[1]) + + def enable_account(self, user_dn): + """enable the account. + + :param user_dn: Dn of the account to enable. + """ + res = self.search(user_dn, SCOPE_ONELEVEL, None, ["userAccountControl"]) + assert len(res) == 1 + userAccountControl = res[0].userAccountControl + userAccountControl = userAccountControl - 2 # remove disabled bit + mod = """ +dn: %s +changetype: modify +replace: userAccountControl +userAccountControl: %u +""" % (user_dn, userAccountControl) + self.modify(mod) + + def newuser(self, username, unixname, password, message): + """add a new user record""" + # connect to the sam + self.transaction_start() + + # find the DNs for the domain and the domain users group + res = self.search("", SCOPE_BASE, "defaultNamingContext=*", + ["defaultNamingContext"]) + assert(len(res) == 1 and res[0].defaultNamingContext is not None) + domain_dn = res[0].defaultNamingContext + assert(domain_dn is not None) + dom_users = searchone(self, domain_dn, "name=Domain Users", "dn") + assert(dom_users is not None) + + user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) + + # + # the new user record. note the reliance on the samdb module to fill + # in a sid, guid etc + # + ldif = """ +dn: %s +sAMAccountName: %s +unixName: %s +sambaPassword: %s +objectClass: user + """ % (user_dn, username, unixname, password) + # add the user to the users group as well + modgroup = """ +dn: %s +changetype: modify +add: member +member: %s +""" % (dom_users, user_dn) + + + # now the real work + message("Adding user %s" % user_dn) + self.add(ldif) + + message("Modifying group %s" % dom_users) + self.modify(modgroup) + + # modify the userAccountControl to remove the disabled bit + enable_account(self, user_dn) + self.transaction_commit() + + -- cgit From 09915ce8b7edcf23335d570d70f79797afe83a71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 08:36:39 +0100 Subject: r26499: Allow testing python provision by setting the PROVISION_PYTHON environment variable. (This used to be commit 379d0bbb2f9e0cd9b1855fd77bbb89827e0315ad) --- source4/scripting/python/samba/provision.py | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 63e50897fe..60dcf06c83 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -189,7 +189,6 @@ def ldb_delete(ldb): ldb.connect(ldb.filename) - def open_ldb(session_info, credentials, dbname): assert session_info is not None try: @@ -641,25 +640,16 @@ def provision_guess(lp): return subobj - def load_schema(setup_dir, subobj, samdb): """Load schema.""" src = os.path.join(setup_dir, "schema.ldif") - schema_data = open(src, 'r').read() - src = os.path.join(setup_dir, "schema_samba4.ldif") - schema_data += open(src, 'r').read() - schema_data = substitute_var(schema_data, subobj.subst_vars()) - src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") - head_data = open(src, 'r').read() - head_data = substitute_var(head_data, subobj.subst_vars()) - samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) -- cgit From 32f439bfa458f7936b507cb5a1e3c74bcb8c68bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 11:12:36 +0100 Subject: r26503: Change order of arguments in param interface so it's easier to make the section name optional. Fix several smaller bits and pieces in the Python code. (This used to be commit 1b89311e5fa4fcde060df50e580dc221205cc8ca) --- source4/scripting/python/misc_wrap.c | 25 ++++++----- source4/scripting/python/samba/__init__.py | 56 ++++++++++++------------ source4/scripting/python/samba/provision.py | 30 ++++++------- source4/scripting/python/samba/tests/__init__.py | 2 +- 4 files changed, 60 insertions(+), 53 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index f5e23d0407..25b6389f6a 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2474,16 +2474,17 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_loadparm_service swig_types[12] #define SWIGTYPE_p_long_long swig_types[13] #define SWIGTYPE_p_param_context swig_types[14] -#define SWIGTYPE_p_param_section swig_types[15] -#define SWIGTYPE_p_short swig_types[16] -#define SWIGTYPE_p_signed_char swig_types[17] -#define SWIGTYPE_p_unsigned_char swig_types[18] -#define SWIGTYPE_p_unsigned_int swig_types[19] -#define SWIGTYPE_p_unsigned_long swig_types[20] -#define SWIGTYPE_p_unsigned_long_long swig_types[21] -#define SWIGTYPE_p_unsigned_short swig_types[22] -static swig_type_info *swig_types[24]; -static swig_module_info swig_module = {swig_types, 23, 0, 0, 0, 0}; +#define SWIGTYPE_p_param_opt swig_types[15] +#define SWIGTYPE_p_param_section swig_types[16] +#define SWIGTYPE_p_short swig_types[17] +#define SWIGTYPE_p_signed_char swig_types[18] +#define SWIGTYPE_p_unsigned_char swig_types[19] +#define SWIGTYPE_p_unsigned_int swig_types[20] +#define SWIGTYPE_p_unsigned_long swig_types[21] +#define SWIGTYPE_p_unsigned_long_long swig_types[22] +#define SWIGTYPE_p_unsigned_short swig_types[23] +static swig_type_info *swig_types[25]; +static swig_module_info swig_module = {swig_types, 24, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2896,6 +2897,7 @@ static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "stru static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_context = {"_p_param_context", "struct param_context *|param *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_param_opt = {"_p_param_opt", "struct param_opt *|param_opt *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_section = {"_p_param_section", "struct param_section *|param_section *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; @@ -2921,6 +2923,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_loadparm_service, &_swigt__p_long_long, &_swigt__p_param_context, + &_swigt__p_param_opt, &_swigt__p_param_section, &_swigt__p_short, &_swigt__p_signed_char, @@ -2946,6 +2949,7 @@ static swig_cast_info _swigc__p_loadparm_context[] = { {&_swigt__p_loadparm_con static swig_cast_info _swigc__p_loadparm_service[] = { {&_swigt__p_loadparm_service, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_context[] = { {&_swigt__p_param_context, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_param_opt[] = { {&_swigt__p_param_opt, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_section[] = { {&_swigt__p_param_section, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; @@ -2971,6 +2975,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_loadparm_service, _swigc__p_long_long, _swigc__p_param_context, + _swigc__p_param_opt, _swigc__p_param_section, _swigc__p_short, _swigc__p_signed_char, diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 56adce4473..511dcd905a 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -33,11 +33,9 @@ if _in_source_tree(): default_ldb_modules_dir = "%s/bin/modules/ldb" % srcdir -import misc import ldb -ldb.Ldb.set_credentials = misc.ldb_set_credentials -ldb.Ldb.set_session_info = misc.ldb_set_session_info -ldb.Ldb.set_loadparm = misc.ldb_set_loadparm +import credentials +import misc class Ldb(ldb.Ldb): """Simple Samba-specific LDB subclass that takes care @@ -47,38 +45,42 @@ class Ldb(ldb.Ldb): not necessarily the Sam database. For Sam-specific helper functions see samdb.py. """ - def __init__(url, session_info=None, credentials=None, modules_dir=None, - lp=None): + def __init__(self, url=None, session_info=None, credentials=None, + modules_dir=None, lp=None): """Open a Samba Ldb file. - :param url: LDB Url to open + :param url: Optional LDB URL to open :param session_info: Optional session information :param credentials: Optional credentials, defaults to anonymous. - :param modules_dir: Modules directory, automatically set if not specified. + :param modules_dir: Modules directory, if not the default. :param lp: Loadparm object, optional. This is different from a regular Ldb file in that the Samba-specific modules-dir is used by default and that credentials and session_info can be passed through (required by some modules). """ - super(self, Ldb).__init__() - import ldb - ret = ldb.Ldb() - if modules_dir is None: - modules_dir = default_ldb_modules_dir + super(Ldb, self).__init__() + if modules_dir is not None: - ret.set_modules_dir(modules_dir) - def samba_debug(level,text): - print "%d %s" % (level, text) + self.set_modules_dir(modules_dir) + elif default_ldb_modules_dir is not None: + self.set_modules_dir(default_ldb_modules_dir) + if credentials is not None: - ldb.set_credentials(credentials) + self.set_credentials(self, credentials) + if session_info is not None: - ldb.set_session_info(session_info) + self.set_session_info(self, session_info) + if lp is not None: - ldb.set_loadparm(lp) - #ret.set_debug(samba_debug) - ret.connect(url) - return ret + self.set_loadparm(self, lp) + + if url: + self.connect(url) + + set_credentials = misc.ldb_set_credentials + set_session_info = misc.ldb_set_session_info + set_loadparm = misc.ldb_set_loadparm def searchone(self, basedn, expression, attribute): """Search for one attribute as a string.""" @@ -93,19 +95,19 @@ class Ldb(ldb.Ldb): for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: try: - self.delete(Dn(self, attr)) - except LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): + self.delete(ldb.Dn(self, attr)) + except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): # Ignore missing dn errors pass - basedn = Dn(self, "") + basedn = ldb.Dn(self, "") # and the rest - for msg in self.search(basedn, SCOPE_SUBTREE, + for msg in self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]): self.delete(msg.dn) - res = self.search(basedn, SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) + res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) assert len(res) == 0 diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 60dcf06c83..5332a9f9ff 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -16,6 +16,7 @@ import param import registry from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB +import security from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring @@ -69,7 +70,7 @@ class ProvisionSettings(object): "DOMAINDN_LDB": self.domaindn_ldb, "DOMAINDN_MOD": "pdc_fsmo,password_hash", "DOMAINDN_MOD2": ",objectguid", - "DOMAINSID": self.domainsid, + "DOMAINSID": str(self.domainsid), "MODULES_LIST": ",".join(self.modules_list), "CONFIGDN_MOD": "naming_fsmo", "CONFIGDN_MOD2": ",objectguid", @@ -115,13 +116,13 @@ class ProvisionSettings(object): if not valid_netbios_name(self.netbiosname): raise InvalidNetbiosName(self.netbiosname) - if lp.get("workgroup").upper() != self.domain.upper(): + if lp.get_string("workgroup").upper() != self.domain.upper(): raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), self.domain) + lp.get_string("workgroup"), self.domain) - if lp.get("realm").upper() != self.realm.upper(): + if lp.get_string("realm").upper() != self.realm.upper(): raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get("realm"), self.realm)) + (lp.get_string("realm"), self.realm)) class ProvisionPaths: @@ -147,9 +148,9 @@ class ProvisionPaths: def install_ok(lp, session_info, credentials): """Check whether the current install seems ok.""" - if lp.get("realm") == "": + if lp.get_string("realm") == "": return False - ldb = Ldb(lp.get("sam database"), session_info=session_info, + ldb = Ldb(lp.get_string("sam database"), session_info=session_info, credentials=credentials) if len(ldb.search("(cn=Administrator)")) != 1: return False @@ -166,7 +167,6 @@ def findnss(nssfn, *names): raise Exception("Unable to find user/group for %s" % arguments[1]) - def hostip(): """return first host IP.""" return gethostbyname(hostname()) @@ -230,7 +230,7 @@ def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, dbname, ldb.transaction_start() try: if erase: - ldb_erase(ldb); + ldb.erase(); setup_add_ldif(setup_dir, ldif, subobj, ldb) except: ldb.transaction_cancel() @@ -271,10 +271,10 @@ def provision_default_paths(lp, subobj): :param subobj: Object """ paths = ProvisionPaths() - private_dir = lp.get("private dir") + private_dir = lp.get_string("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") - paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.samdb = lp.get_string("sam database") or os.path.join(private_dir, "samdb.ldb") + paths.secrets = lp.get_string("secrets database") or os.path.join(private_dir, "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") @@ -572,8 +572,8 @@ def provision_ldapbase(setup_dir, subobj, message, paths): def provision_guess(lp): """guess reasonably default options for provisioning.""" - subobj = ProvisionSettings(realm=lp.get("realm").upper(), - domain=lp.get("workgroup"), + subobj = ProvisionSettings(realm=lp.get_string("realm").upper(), + domain=lp.get_string("workgroup"), hostname=hostname(), hostip=hostip()) @@ -581,7 +581,7 @@ def provision_guess(lp): assert subobj.domain is not None assert subobj.hostname is not None - subobj.domainsid = sid.random() + subobj.domainsid = security.random_sid() subobj.invocationid = uuid.random() subobj.policyguid = uuid.random() subobj.krbtgtpass = misc.random_password(12) diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index d374f8bafa..d3930e217a 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -27,7 +27,7 @@ class LdbTestCase(unittest.TestCase): self.filename = os.tempnam() self.ldb = samba.Ldb(self.filename) - def load_modules(self, modules=[]): + def set_modules(self, modules=[]): m = ldb.Message() m.dn = ldb.Dn(self.ldb, "@MODULES") m["@LIST"] = ",".join(modules) -- cgit From f89c7a6e5eb082794d64b487e69fc442d138ca28 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 12:07:51 +0100 Subject: r26505: Add python bindings for some samdb-related functions, improve provisioning in python. (This used to be commit d2402251666738c0372bbbaeaa1d26c06e254033) --- source4/scripting/python/config.mk | 2 +- source4/scripting/python/misc.i | 9 ++ source4/scripting/python/misc.py | 3 + source4/scripting/python/misc_wrap.c | 225 +++++++++++++++++++++++++--- source4/scripting/python/samba/provision.py | 6 +- source4/scripting/python/samba/samdb.py | 5 + 6 files changed, 223 insertions(+), 27 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index cf17a28a70..d0d3829eef 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -3,7 +3,7 @@ PRIVATE_DEPENDENCIES = LIBNDR OBJ_FILES = uuidmodule.o [PYTHON::python_misc] -PRIVATE_DEPENDENCIES = LIBNDR LIBLDB +PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB SWIG_FILE = misc.i # Swig extensions diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 0a94fcdc29..518011ea43 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -22,6 +22,7 @@ #include "includes.h" #include "ldb.h" #include "param/param.h" +#include "dsdb/samdb/samdb.h" %} %import "stdint.i" @@ -30,6 +31,8 @@ %import "../../lib/ldb/ldb.i" %import "../../auth/credentials/credentials.i" %import "../../param/param.i" +%import "../../libcli/security/security.i" +%import "../../libcli/util/errors.i"; %rename(random_password) generate_random_str; char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); @@ -49,4 +52,10 @@ void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) { ldb_set_opaque(ldb, "loadparm", lp_ctx); } + %} + +bool samdb_set_domain_sid(struct ldb_context *ldb, + const struct dom_sid *dom_sid_in); + +WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df); diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 7628dbcb15..525869ff58 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -60,9 +60,12 @@ def _swig_setattr_nondynamic_method(set): import ldb import credentials import param +import security random_password = _misc.random_password ldb_set_credentials = _misc.ldb_set_credentials ldb_set_session_info = _misc.ldb_set_session_info ldb_set_loadparm = _misc.ldb_set_loadparm +samdb_set_domain_sid = _misc.samdb_set_domain_sid +dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 25b6389f6a..7db909d392 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2463,28 +2463,31 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_auth_session_info swig_types[1] #define SWIGTYPE_p_char swig_types[2] #define SWIGTYPE_p_cli_credentials swig_types[3] -#define SWIGTYPE_p_int swig_types[4] -#define SWIGTYPE_p_ldb_context swig_types[5] -#define SWIGTYPE_p_ldb_dn swig_types[6] -#define SWIGTYPE_p_ldb_ldif swig_types[7] -#define SWIGTYPE_p_ldb_message swig_types[8] -#define SWIGTYPE_p_ldb_message_element swig_types[9] -#define SWIGTYPE_p_ldb_result swig_types[10] -#define SWIGTYPE_p_loadparm_context swig_types[11] -#define SWIGTYPE_p_loadparm_service swig_types[12] -#define SWIGTYPE_p_long_long swig_types[13] -#define SWIGTYPE_p_param_context swig_types[14] -#define SWIGTYPE_p_param_opt swig_types[15] -#define SWIGTYPE_p_param_section swig_types[16] -#define SWIGTYPE_p_short swig_types[17] -#define SWIGTYPE_p_signed_char swig_types[18] -#define SWIGTYPE_p_unsigned_char swig_types[19] -#define SWIGTYPE_p_unsigned_int swig_types[20] -#define SWIGTYPE_p_unsigned_long swig_types[21] -#define SWIGTYPE_p_unsigned_long_long swig_types[22] -#define SWIGTYPE_p_unsigned_short swig_types[23] -static swig_type_info *swig_types[25]; -static swig_module_info swig_module = {swig_types, 24, 0, 0, 0, 0}; +#define SWIGTYPE_p_dom_sid swig_types[4] +#define SWIGTYPE_p_int swig_types[5] +#define SWIGTYPE_p_ldb_context swig_types[6] +#define SWIGTYPE_p_ldb_dn swig_types[7] +#define SWIGTYPE_p_ldb_ldif swig_types[8] +#define SWIGTYPE_p_ldb_message swig_types[9] +#define SWIGTYPE_p_ldb_message_element swig_types[10] +#define SWIGTYPE_p_ldb_result swig_types[11] +#define SWIGTYPE_p_loadparm_context swig_types[12] +#define SWIGTYPE_p_loadparm_service swig_types[13] +#define SWIGTYPE_p_long_long swig_types[14] +#define SWIGTYPE_p_param_context swig_types[15] +#define SWIGTYPE_p_param_opt swig_types[16] +#define SWIGTYPE_p_param_section swig_types[17] +#define SWIGTYPE_p_security_descriptor swig_types[18] +#define SWIGTYPE_p_security_token swig_types[19] +#define SWIGTYPE_p_short swig_types[20] +#define SWIGTYPE_p_signed_char swig_types[21] +#define SWIGTYPE_p_unsigned_char swig_types[22] +#define SWIGTYPE_p_unsigned_int swig_types[23] +#define SWIGTYPE_p_unsigned_long swig_types[24] +#define SWIGTYPE_p_unsigned_long_long swig_types[25] +#define SWIGTYPE_p_unsigned_short swig_types[26] +static swig_type_info *swig_types[28]; +static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2527,6 +2530,7 @@ static swig_module_info swig_module = {swig_types, 24, 0, 0, 0, 0}; #include "includes.h" #include "ldb.h" #include "param/param.h" +#include "dsdb/samdb/samdb.h" SWIGINTERN int @@ -2715,6 +2719,69 @@ void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) ldb_set_opaque(ldb, "loadparm", lp_ctx); } + + +SWIGINTERNINLINE PyObject* + SWIG_From_bool (bool value) +{ + return PyBool_FromLong(value ? 1 : 0); +} + + +SWIGINTERN int +SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +{ + if (PyString_Check(obj)) { + char *cstr; Py_ssize_t len; + PyString_AsStringAndSize(obj, &cstr, &len); + if (cptr) { + if (alloc) { + /* + In python the user should not be able to modify the inner + string representation. To warranty that, if you define + SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string + buffer is always returned. + + The default behavior is just to return the pointer value, + so, be careful. + */ +#if defined(SWIG_PYTHON_SAFE_CSTRINGS) + if (*alloc != SWIG_OLDOBJ) +#else + if (*alloc == SWIG_NEWOBJ) +#endif + { + *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); + *alloc = SWIG_NEWOBJ; + } + else { + *cptr = cstr; + *alloc = SWIG_OLDOBJ; + } + } else { + *cptr = PyString_AsString(obj); + } + } + if (psize) *psize = len + 1; + return SWIG_OK; + } else { + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + } + return SWIG_TypeError; +} + + + + #ifdef __cplusplus extern "C" { #endif @@ -2871,11 +2938,113 @@ fail: } +SWIGINTERN PyObject *_wrap_samdb_set_domain_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + struct dom_sid *arg2 = (struct dom_sid *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "ldb",(char *) "dom_sid_in", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:samdb_set_domain_sid",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "samdb_set_domain_sid" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_dom_sid, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "samdb_set_domain_sid" "', argument " "2"" of type '" "struct dom_sid const *""'"); + } + arg2 = (struct dom_sid *)(argp2); + { + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + } + result = (bool)samdb_set_domain_sid(arg1,(struct dom_sid const *)arg2); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + WERROR result; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + int res3 ; + char *buf3 = 0 ; + int alloc3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "ldb",(char *) "pf",(char *) "df", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:dsdb_attach_schema_from_ldif_file",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsdb_attach_schema_from_ldif_file" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dsdb_attach_schema_from_ldif_file" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + res3 = SWIG_AsCharPtrAndSize(obj2, &buf3, NULL, &alloc3); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "dsdb_attach_schema_from_ldif_file" "', argument " "3"" of type '" "char const *""'"); + } + arg3 = (char *)(buf3); + { + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + } + result = dsdb_attach_schema_from_ldif_file(arg1,(char const *)arg2,(char const *)arg3); + { + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + } else if (resultobj == NULL) { + resultobj = Py_None; + } + } + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_session_info", (PyCFunction) _wrap_ldb_set_session_info, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"samdb_set_domain_sid", (PyCFunction) _wrap_samdb_set_domain_sid, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"dsdb_attach_schema_from_ldif_file", (PyCFunction) _wrap_dsdb_attach_schema_from_ldif_file, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; @@ -2886,6 +3055,7 @@ static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0 static swig_type_info _swigt__p_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_cli_credentials = {"_p_cli_credentials", "struct cli_credentials *|cli_credentials *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_dom_sid = {"_p_dom_sid", "struct dom_sid *|dom_sid *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_int = {"_p_int", "intptr_t *|int *|int_least32_t *|int_fast32_t *|int32_t *|int_fast16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_context = {"_p_ldb_context", "struct ldb_context *|ldb *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_dn = {"_p_ldb_dn", "struct ldb_dn *|ldb_dn *", 0, 0, (void*)0, 0}; @@ -2899,6 +3069,8 @@ static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|in static swig_type_info _swigt__p_param_context = {"_p_param_context", "struct param_context *|param *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_opt = {"_p_param_opt", "struct param_opt *|param_opt *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_param_section = {"_p_param_section", "struct param_section *|param_section *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_security_descriptor = {"_p_security_descriptor", "struct security_descriptor *|security_descriptor *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_security_token = {"_p_security_token", "struct security_token *|security_token *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_short = {"_p_short", "short *|int_least16_t *|int16_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_signed_char = {"_p_signed_char", "signed char *|int_least8_t *|int_fast8_t *|int8_t *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_unsigned_char = {"_p_unsigned_char", "unsigned char *|uint_least8_t *|uint_fast8_t *|uint8_t *", 0, 0, (void*)0, 0}; @@ -2912,6 +3084,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_auth_session_info, &_swigt__p_char, &_swigt__p_cli_credentials, + &_swigt__p_dom_sid, &_swigt__p_int, &_swigt__p_ldb_context, &_swigt__p_ldb_dn, @@ -2925,6 +3098,8 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_param_context, &_swigt__p_param_opt, &_swigt__p_param_section, + &_swigt__p_security_descriptor, + &_swigt__p_security_token, &_swigt__p_short, &_swigt__p_signed_char, &_swigt__p_unsigned_char, @@ -2938,6 +3113,7 @@ static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, static swig_cast_info _swigc__p_auth_session_info[] = { {&_swigt__p_auth_session_info, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_cli_credentials[] = { {&_swigt__p_cli_credentials, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_dom_sid[] = { {&_swigt__p_dom_sid, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_ldb_context[] = { {&_swigt__p_ldb_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_ldb_dn[] = { {&_swigt__p_ldb_dn, 0, 0, 0},{0, 0, 0, 0}}; @@ -2951,6 +3127,8 @@ static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0} static swig_cast_info _swigc__p_param_context[] = { {&_swigt__p_param_context, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_opt[] = { {&_swigt__p_param_opt, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_param_section[] = { {&_swigt__p_param_section, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_security_descriptor[] = { {&_swigt__p_security_descriptor, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_security_token[] = { {&_swigt__p_security_token, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_short[] = { {&_swigt__p_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_signed_char[] = { {&_swigt__p_signed_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_unsigned_char[] = { {&_swigt__p_unsigned_char, 0, 0, 0},{0, 0, 0, 0}}; @@ -2964,6 +3142,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_auth_session_info, _swigc__p_char, _swigc__p_cli_credentials, + _swigc__p_dom_sid, _swigc__p_int, _swigc__p_ldb_context, _swigc__p_ldb_dn, @@ -2977,6 +3156,8 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_param_context, _swigc__p_param_opt, _swigc__p_param_section, + _swigc__p_security_descriptor, + _swigc__p_security_token, _swigc__p_short, _swigc__p_signed_char, _swigc__p_unsigned_char, diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 5332a9f9ff..34191b7269 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -433,10 +433,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Pre-loading the Samba 4 and AD schema") - samdb = open_ldb(session_info, credentials, paths.samdb) - + samdb = SamDB(paths.samdb, session_info, credentials) samdb.set_domain_sid(subobj.domainsid) - load_schema(setup_dir, subobj, samdb) samdb.transaction_start() @@ -650,7 +648,7 @@ def load_schema(setup_dir, subobj, samdb): src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") head_data = open(src, 'r').read() head_data = substitute_var(head_data, subobj.subst_vars()) - samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) + samdb.attach_schema_from_ldif(head_data, schema_data) def join_domain(domain, netbios_name, join_type, creds, message): diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 50164bf590..73426121a6 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -21,6 +21,7 @@ # import samba +import misc class SamDB(samba.Ldb): def add_foreign(self, domaindn, sid, desc): @@ -114,4 +115,8 @@ member: %s enable_account(self, user_dn) self.transaction_commit() + def set_domain_sid(self, sid): + misc.samdb_set_domain_sid(self, sid) + def attach_schema_from_ldif(self, pf, df): + misc.dsdb_attach_schema_from_ldif_file(self, pf, df) -- cgit From 323c174be37214d561a5d525a7c3eef47ac700e8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 12:19:45 +0100 Subject: r26506: Start running (really trivial) tests for upgrade script. (This used to be commit 73bd4a9566d15f85a971e3a87cefbec2e2eece1c) --- source4/scripting/python/samba/tests/upgrade.py | 2 +- source4/scripting/python/samba/upgrade.py | 602 ++++++++++++------------ 2 files changed, 302 insertions(+), 302 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/upgrade.py b/source4/scripting/python/samba/tests/upgrade.py index f46d869656..a25743425b 100644 --- a/source4/scripting/python/samba/tests/upgrade.py +++ b/source4/scripting/python/samba/tests/upgrade.py @@ -25,4 +25,4 @@ class RegkeyDnTests(TestCase): self.assertEquals("hive=NONE", regkey_to_dn("")) def test_nested(self): - self.assertEquals("key=foo,key=bar,hive=NONE", regkey_to_dn("foo/bar")) + self.assertEquals("key=bar,key=foo,hive=NONE", regkey_to_dn("foo/bar")) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 1908e3ea55..783cc008d5 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -11,17 +11,19 @@ from provision import findnss import provision import grp import pwd -from uuid import uuid4 -from param import default_configuration +import uuid def regkey_to_dn(name): """Convert a registry key to a DN.""" - dn = "hive=NONE" + dn = "hive=NONE" - for el in name.split("/")[1:]: + if name == "": + return dn + + for el in name.split("/"): dn = "key=%s," % el + dn - return dn + return dn # Where prefix is any of: # - HKLM @@ -33,39 +35,39 @@ def regkey_to_dn(name): def upgrade_registry(regdb,prefix,ldb): """Migrate registry contents.""" - assert regdb is not None: - prefix_up = prefix.upper() - ldif = [] + assert regdb is not None + prefix_up = prefix.upper() + ldif = [] for rk in regdb.keys: - pts = rk.name.split("/") + pts = rk.name.split("/") - # Only handle selected hive + # Only handle selected hive if pts[0].upper() != prefix_up: - continue + continue - keydn = regkey_to_dn(rk.name) + keydn = regkey_to_dn(rk.name) - pts = rk.name.split("/") + pts = rk.name.split("/") - # Convert key name to dn - ldif[rk.name] = """ + # Convert key name to dn + ldif[rk.name] = """ dn: %s name: %s """ % (keydn, pts[0]) - + for rv in rk.values: - ldif[rk.name + " (" + rv.name + ")"] = """ + ldif[rk.name + " (" + rv.name + ")"] = """ dn: %s,value=%s value: %s type: %d data:: %s""" % (keydn, rv.name, rv.name, rv.type, ldb.encode(rv.data)) - return ldif + return ldif def upgrade_sam_policy(samba3,dn): - ldif = """ + ldif = """ dn: %s changetype: modify replace: minPwdLength @@ -80,30 +82,30 @@ samba3BadLockoutMinutes: %d samba3DisconnectTime: %d """ % (dn, samba3.policy.min_password_length, - samba3.policy.password_history, samba3.policy.minimum_password_age, - samba3.policy.maximum_password_age, samba3.policy.lockout_duration, - samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password, - samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time) - - return ldif + samba3.policy.password_history, samba3.policy.minimum_password_age, + samba3.policy.maximum_password_age, samba3.policy.lockout_duration, + samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password, + samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time) + + return ldif def upgrade_sam_account(ldb,acc,domaindn,domainsid): """Upgrade a SAM account.""" if acc.nt_username is None or acc.nt_username == "": - acc.nt_username = acc.username + acc.nt_username = acc.username if acc.fullname is None: - acc.fullname = pwd.getpwnam(acc.fullname)[4] + acc.fullname = pwd.getpwnam(acc.fullname)[4] - acc.fullname = acc.fullname.split(",")[0] + acc.fullname = acc.fullname.split(",")[0] if acc.fullname is None: - acc.fullname = acc.username - - assert acc.fullname is not None - assert acc.nt_username is not None + acc.fullname = acc.username + + assert acc.fullname is not None + assert acc.nt_username is not None - ldif = """dn: cn=%s,%s + ldif = """dn: cn=%s,%s objectClass: top objectClass: user lastLogon: %d @@ -136,31 +138,31 @@ acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count, acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script, acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time, acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid, - ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw)) + ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw)) - return ldif + return ldif def upgrade_sam_group(group,domaindn): """Upgrade a SAM group.""" - if group.sid_name_use == 5: # Well-known group - return None + if group.sid_name_use == 5: # Well-known group + return None if group.nt_name in ("Domain Guests", "Domain Users", "Domain Admins"): - return None - + return None + if group.gid == -1: - gr = grp.getgrnam(grp.nt_name) + gr = grp.getgrnam(grp.nt_name) else: - gr = grp.getgrgid(grp.gid) + gr = grp.getgrgid(grp.gid) if gr is None: - group.unixname = "UNKNOWN" + group.unixname = "UNKNOWN" else: - group.unixname = gr.gr_name + group.unixname = gr.gr_name - assert group.unixname is not None - - ldif = """dn: cn=%s,%s + assert group.unixname is not None + + ldif = """dn: cn=%s,%s objectClass: top objectClass: group description: %s @@ -171,11 +173,11 @@ samba3SidNameUse: %d """ % (group.nt_name, domaindn, group.comment, group.nt_name, group.sid, group.unixname, group.sid_name_use) - return ldif + return ldif def upgrade_winbind(samba3,domaindn): - ldif = """ - + ldif = """ + dn: dc=none userHwm: %d groupHwm: %d @@ -183,48 +185,48 @@ groupHwm: %d """ % (samba3.idmap.user_hwm, samba3.idmap.group_hwm) for m in samba3.idmap.mappings: - ldif += """ + ldif += """ dn: SID=%s,%s SID: %s type: %d unixID: %d""" % (m.sid, domaindn, m.sid, m.type, m.unix_id) - - return ldif + + return ldif def upgrade_wins(samba3): """Upgrade the WINS database.""" - ldif = "" - version_id = 0 + ldif = "" + version_id = 0 for e in samba3.winsentries: - now = sys.nttime() - ttl = sys.unix2nttime(e.ttl) + now = sys.nttime() + ttl = sys.unix2nttime(e.ttl) - version_id+=1 + version_id+=1 numIPs = len(e.ips) if e.type == 0x1C: - rType = 0x2 + rType = 0x2 elif e.type & 0x80: if numIPs > 1: - rType = 0x2 + rType = 0x2 else: - rType = 0x1 + rType = 0x1 else: if numIPs > 1: - rType = 0x3 + rType = 0x3 else: - rType = 0x0 + rType = 0x0 if ttl > now: - rState = 0x0 # active + rState = 0x0 # active else: - rState = 0x1 # released + rState = 0x1 # released - nType = ((e.nb_flags & 0x60)>>5) + nType = ((e.nb_flags & 0x60)>>5) - ldif += """ + ldif += """ dn: name=%s,type=0x%02X type: 0x%02X name: %s @@ -240,324 +242,322 @@ versionID: %llu ldaptime(ttl), version_id) for ip in e.ips: - ldif += "address: %s\n" % ip + ldif += "address: %s\n" % ip - ldif += """ + ldif += """ dn: CN=VERSION objectClass: winsMaxVersion maxVersion: %llu """ % version_id - return ldif + return ldif def upgrade_provision(lp, samba3): - subobj = Object() + subobj = Object() - domainname = samba3.configuration.get("workgroup") - + domainname = samba3.configuration.get("workgroup") + if domainname is None: - domainname = samba3.secrets.domains[0].name - print "No domain specified in smb.conf file, assuming '%s'\n" % domainname - - domsec = samba3.find_domainsecrets(domainname) - hostsec = samba3.find_domainsecrets(hostname()) - realm = samba3.configuration.get("realm") + domainname = samba3.secrets.domains[0].name + print "No domain specified in smb.conf file, assuming '%s'\n" % domainname + + domsec = samba3.find_domainsecrets(domainname) + hostsec = samba3.find_domainsecrets(hostname()) + realm = samba3.configuration.get("realm") if realm is None: - realm = domainname - print "No realm specified in smb.conf file, assuming '%s'\n" % realm - random_init(local) + realm = domainname + print "No realm specified in smb.conf file, assuming '%s'\n" % realm + random_init(local) - subobj.realm = realm - subobj.domain = domainname - subobj.hostname = hostname() + subobj.realm = realm + subobj.domain = domainname + subobj.hostname = hostname() - assert subobj.realm is not None - assert subobj.domain is not None - assert subobj.hostname is not None + assert subobj.realm is not None + assert subobj.domain is not None + assert subobj.hostname is not None - subobj.HOSTIP = hostip() + subobj.HOSTIP = hostip() if domsec is not None: - subobj.DOMAINGUID = domsec.guid - subobj.DOMAINSID = domsec.sid + subobj.DOMAINGUID = domsec.guid + subobj.DOMAINSID = domsec.sid else: - print "Can't find domain secrets for '%s'; using random SID and GUID\n" % domainname - subobj.DOMAINGUID = uuid4() - subobj.DOMAINSID = randsid() - + print "Can't find domain secrets for '%s'; using random SID and GUID\n" % domainname + subobj.DOMAINGUID = uuid.random() + subobj.DOMAINSID = randsid() + if hostsec: - subobj.HOSTGUID = hostsec.guid + subobj.HOSTGUID = hostsec.guid else: - subobj.HOSTGUID = uuid4() - subobj.invocationid = uuid4() - subobj.krbtgtpass = randpass(12) - subobj.machinepass = randpass(12) - subobj.adminpass = randpass(12) - subobj.datestring = datestring() - subobj.root = findnss(pwd.getpwnam, "root")[4] - subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] - subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] - subobj.wheel = findnss(grp.getgrnam, "wheel", "root")[2] - subobj.users = findnss(grp.getgrnam, "users", "guest", "other")[2] - subobj.dnsdomain = subobj.realm.lower() - subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) - subobj.basedn = "DC=" + ",DC=".join(subobj.realm.split(".")) - rdn_list = subobj.dnsdomain.split(".") - subobj.domaindn = "DC=" + ",DC=".join(rdn_list) - subobj.domaindn_ldb = "users.ldb" - subobj.rootdn = subobj.domaindn - - modules_list = ["rootdse", - "kludge_acl", - "paged_results", - "server_sort", - "extended_dn", - "asq", - "samldb", - "password_hash", - "operational", - "objectclass", - "rdn_name", - "show_deleted", - "partition"] - subobj.modules_list = ",".join(modules_list) - - return subobj + subobj.HOSTGUID = uuid.random() + subobj.invocationid = uuid.random() + subobj.krbtgtpass = randpass(12) + subobj.machinepass = randpass(12) + subobj.adminpass = randpass(12) + subobj.datestring = datestring() + subobj.root = findnss(pwd.getpwnam, "root")[4] + subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] + subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + subobj.wheel = findnss(grp.getgrnam, "wheel", "root")[2] + subobj.users = findnss(grp.getgrnam, "users", "guest", "other")[2] + subobj.dnsdomain = subobj.realm.lower() + subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) + subobj.basedn = "DC=" + ",DC=".join(subobj.realm.split(".")) + rdn_list = subobj.dnsdomain.split(".") + subobj.domaindn = "DC=" + ",DC=".join(rdn_list) + subobj.domaindn_ldb = "users.ldb" + subobj.rootdn = subobj.domaindn + + modules_list = ["rootdse", + "kludge_acl", + "paged_results", + "server_sort", + "extended_dn", + "asq", + "samldb", + "password_hash", + "operational", + "objectclass", + "rdn_name", + "show_deleted", + "partition"] + subobj.modules_list = ",".join(modules_list) + + return subobj smbconf_keep = [ - "dos charset", - "unix charset", - "display charset", - "comment", - "path", - "directory", - "workgroup", - "realm", - "netbios name", - "netbios aliases", - "netbios scope", - "server string", - "interfaces", - "bind interfaces only", - "security", - "auth methods", - "encrypt passwords", - "null passwords", - "obey pam restrictions", - "password server", - "smb passwd file", - "private dir", - "passwd chat", - "password level", - "lanman auth", - "ntlm auth", - "client NTLMv2 auth", - "client lanman auth", - "client plaintext auth", - "read only", - "hosts allow", - "hosts deny", - "log level", - "debuglevel", - "log file", - "smb ports", - "large readwrite", - "max protocol", - "min protocol", - "unicode", - "read raw", - "write raw", - "disable netbios", - "nt status support", - "announce version", - "announce as", - "max mux", - "max xmit", - "name resolve order", - "max wins ttl", - "min wins ttl", - "time server", - "unix extensions", - "use spnego", - "server signing", - "client signing", - "max connections", - "paranoid server security", - "socket options", - "strict sync", - "max print jobs", - "printable", - "print ok", - "printer name", - "printer", - "map system", - "map hidden", - "map archive", - "preferred master", - "prefered master", - "local master", - "browseable", - "browsable", - "wins server", - "wins support", - "csc policy", - "strict locking", - "preload", - "auto services", - "lock dir", - "lock directory", - "pid directory", - "socket address", - "copy", - "include", - "available", - "volume", - "fstype", - "panic action", - "msdfs root", - "host msdfs", - "winbind separator"] + "dos charset", + "unix charset", + "display charset", + "comment", + "path", + "directory", + "workgroup", + "realm", + "netbios name", + "netbios aliases", + "netbios scope", + "server string", + "interfaces", + "bind interfaces only", + "security", + "auth methods", + "encrypt passwords", + "null passwords", + "obey pam restrictions", + "password server", + "smb passwd file", + "private dir", + "passwd chat", + "password level", + "lanman auth", + "ntlm auth", + "client NTLMv2 auth", + "client lanman auth", + "client plaintext auth", + "read only", + "hosts allow", + "hosts deny", + "log level", + "debuglevel", + "log file", + "smb ports", + "large readwrite", + "max protocol", + "min protocol", + "unicode", + "read raw", + "write raw", + "disable netbios", + "nt status support", + "announce version", + "announce as", + "max mux", + "max xmit", + "name resolve order", + "max wins ttl", + "min wins ttl", + "time server", + "unix extensions", + "use spnego", + "server signing", + "client signing", + "max connections", + "paranoid server security", + "socket options", + "strict sync", + "max print jobs", + "printable", + "print ok", + "printer name", + "printer", + "map system", + "map hidden", + "map archive", + "preferred master", + "prefered master", + "local master", + "browseable", + "browsable", + "wins server", + "wins support", + "csc policy", + "strict locking", + "preload", + "auto services", + "lock dir", + "lock directory", + "pid directory", + "socket address", + "copy", + "include", + "available", + "volume", + "fstype", + "panic action", + "msdfs root", + "host msdfs", + "winbind separator"] -# -# Remove configuration variables not present in Samba4 -# oldconf: Old configuration structure -# mark: Whether removed configuration variables should be -# kept in the new configuration as "samba3:" def upgrade_smbconf(oldconf,mark): - data = oldconf.data() - newconf = param_init() - - for (s in data) { - for (p in data[s]) { - keep = False - for (k in smbconf_keep) { + """Remove configuration variables not present in Samba4 + + :param oldconf: Old configuration structure + :param mark: Whether removed configuration variables should be + kept in the new configuration as "samba3:" + """ + data = oldconf.data() + newconf = param_init() + + for s in data: + for p in data[s]: + keep = False + for k in smbconf_keep: if smbconf_keep[k] == p: - keep = True - break - } + keep = True + break if keep: - newconf.set(s, p, oldconf.get(s, p)) + newconf.set(s, p, oldconf.get(s, p)) elif mark: - newconf.set(s, "samba3:"+p, oldconf.get(s,p)) - } - } + newconf.set(s, "samba3:"+p, oldconf.get(s,p)) if oldconf.get("domain logons") == "True": - newconf.set("server role", "domain controller") + newconf.set("server role", "domain controller") else: if oldconf.get("security") == "user": - newconf.set("server role", "standalone") + newconf.set("server role", "standalone") else: - newconf.set("server role", "member server") + newconf.set("server role", "member server") - return newconf + return newconf def upgrade(subobj, samba3, message, paths, session_info, credentials): - ret = 0 - lp = loadparm_init() - samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) + ret = 0 + lp = loadparm_init() + samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) - message("Writing configuration") - newconf = upgrade_smbconf(samba3.configuration,True) - newconf.save(paths.smbconf) + message("Writing configuration") + newconf = upgrade_smbconf(samba3.configuration,True) + newconf.save(paths.smbconf) - message("Importing account policies") - ldif = upgrade_sam_policy(samba3,subobj.BASEDN) - samdb.modify(ldif) - regdb = Ldb(paths.hklm) + message("Importing account policies") + ldif = upgrade_sam_policy(samba3,subobj.BASEDN) + samdb.modify(ldif) + regdb = Ldb(paths.hklm) - regdb.modify(" + regdb.modify(""" dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE replace: type type: 4 replace: data data: %d -" % samba3.policy.refuse_machine_password_change) +""" % samba3.policy.refuse_machine_password_change) - message("Importing users") + message("Importing users") for account in samba3.samaccounts: - msg = "... " + account.username - ldif = upgrade_sam_account(samdb, accounts,subobj.BASEDN,subobj.DOMAINSID) + msg = "... " + account.username + ldif = upgrade_sam_account(samdb, accounts,subobj.BASEDN,subobj.DOMAINSID) try: samdb.add(ldif) except LdbError, e: # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1; - message(msg) + msg += "... error: " + str(e) + ret += 1; + message(msg) - message("Importing groups") + message("Importing groups") for mapping in samba3.groupmappings: - msg = "... " + mapping.nt_name - ldif = upgrade_sam_group(mapping, subobj.BASEDN) + msg = "... " + mapping.nt_name + ldif = upgrade_sam_group(mapping, subobj.BASEDN) if ldif is not None: try: - samdb.add(ldif) + samdb.add(ldif) except LdbError, e: # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1 - message(msg) + msg += "... error: " + str(e) + ret += 1 + message(msg) - message("Importing registry data") + message("Importing registry data") for hive in ["hkcr","hkcu","hklm","hkpd","hku","hkpt"]: - message("... " + hive) - regdb = Ldb(paths[hive]) - ldif = upgrade_registry(samba3.registry, hive, regdb) - for (var j in ldif) { - var msg = "... ... " + j + message("... " + hive) + regdb = Ldb(paths[hive]) + ldif = upgrade_registry(samba3.registry, hive, regdb) + for j in ldif: + msg = "... ... " + j try: regdb.add(ldif[j]) except LdbError, e: # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1 - message(msg) + msg += "... error: " + str(e) + ret += 1 + message(msg) - message("Importing WINS data") - winsdb = Ldb(paths.winsdb) - ldb_erase(winsdb) + message("Importing WINS data") + winsdb = Ldb(paths.winsdb) + ldb_erase(winsdb) - ldif = upgrade_wins(samba3) - winsdb.add(ldif) + ldif = upgrade_wins(samba3) + winsdb.add(ldif) - # figure out ldapurl, if applicable - ldapurl = None - pdb = samba3.configuration.get_list("passdb backend") + # figure out ldapurl, if applicable + ldapurl = None + pdb = samba3.configuration.get_list("passdb backend") if pdb is not None: for backend in pdb: if len(backend) >= 7 and backend[0:7] == "ldapsam": ldapurl = backend[7:] - # URL was not specified in passdb backend but ldap /is/ used + # URL was not specified in passdb backend but ldap /is/ used if ldapurl == "": - ldapurl = "ldap://%s" % samba3.configuration.get("ldap server") + ldapurl = "ldap://%s" % samba3.configuration.get("ldap server") - # Enable samba3sam module if original passdb backend was ldap + # Enable samba3sam module if original passdb backend was ldap if ldapurl is not None: - message("Enabling Samba3 LDAP mappings for SAM database") + message("Enabling Samba3 LDAP mappings for SAM database") - samdb.modify(""" + samdb.modify(""" dn: @MODULES changetype: modify replace: @LIST @LIST: samldb,operational,objectguid,rdn_name,samba3sam """) - samdb.add(""" + samdb.add(""" dn: @MAP=samba3sam -@MAP_URL: %s""", ldapurl)) +@MAP_URL: %s""" % ldapurl) - return ret + return ret def upgrade_verify(subobj, samba3, paths, message): - message("Verifying account policies") + message("Verifying account policies") - samldb = Ldb(paths.samdb) + samldb = Ldb(paths.samdb) for account in samba3.samaccounts: - msg = samldb.search("(&(sAMAccountName=" + account.nt_username + ")(objectclass=user))") - assert(len(msg) >= 1) - - # FIXME + msg = samldb.search("(&(sAMAccountName=" + account.nt_username + ")(objectclass=user))") + assert(len(msg) >= 1) + + # FIXME -- cgit From ca74c6e6c426e6b69ba31676e2b06dda29b5409e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 20:03:06 +0100 Subject: r26513: Update substitution dictionary for ldifs. (This used to be commit 60fb2de2119cb2f42f858868e39c3b0d303ac20f) --- source4/scripting/python/misc.i | 3 +++ source4/scripting/python/misc.py | 1 + source4/scripting/python/misc_wrap.c | 14 ++++++++++++++ source4/scripting/python/samba/__init__.py | 3 +++ source4/scripting/python/samba/provision.py | 6 ++++++ 5 files changed, 27 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 518011ea43..eda0db2c3d 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -59,3 +59,6 @@ bool samdb_set_domain_sid(struct ldb_context *ldb, const struct dom_sid *dom_sid_in); WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df); + +%rename(version) samba_version_string; +const char *samba_version_string(void); diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 525869ff58..228ab24dbf 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -67,5 +67,6 @@ ldb_set_session_info = _misc.ldb_set_session_info ldb_set_loadparm = _misc.ldb_set_loadparm samdb_set_domain_sid = _misc.samdb_set_domain_sid dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file +version = _misc.version diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 7db909d392..effabdecef 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -3038,6 +3038,19 @@ fail: } +SWIGINTERN PyObject *_wrap_version(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + char *result = 0 ; + + if (!SWIG_Python_UnpackTuple(args,"version",0,0,0)) SWIG_fail; + result = (char *)samba_version_string(); + resultobj = SWIG_FromCharPtr((const char *)result); + return resultobj; +fail: + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -3045,6 +3058,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"samdb_set_domain_sid", (PyCFunction) _wrap_samdb_set_domain_sid, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"dsdb_attach_schema_from_ldif_file", (PyCFunction) _wrap_dsdb_attach_schema_from_ldif_file, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, NULL}, { NULL, NULL, 0, NULL } }; diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 511dcd905a..f89ac39ac7 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -122,6 +122,8 @@ def substitute_var(text, values): for (name, value) in values.items(): text = text.replace("${%s}" % name, value) + assert "${" not in text, text + return text @@ -133,3 +135,4 @@ def valid_netbios_name(name): return False return True +version = misc.version diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 34191b7269..7d7b85c13e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -14,6 +14,7 @@ import uuid, misc from socket import gethostname, gethostbyname import param import registry +import samba from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB import security @@ -56,6 +57,7 @@ class ProvisionSettings(object): self.schemedn_ldb = None self.s4_ldapi_path = None self.policyguid = None + self.extensibleobject = None def subst_vars(self): return {"SCHEMADN": self.schemadn, @@ -77,6 +79,7 @@ class ProvisionSettings(object): "NETBIOSNAME": self.netbiosname, "DNSNAME": self.dnsname, "ROOTDN": self.rootdn, + "DOMAIN": self.domain, "DNSDOMAIN": self.dnsdomain, "REALM": self.realm, "DEFAULTSITE": self.defaultsite, @@ -89,6 +92,9 @@ class ProvisionSettings(object): "POLICYGUID": self.policyguid, "RDN_DC": self.rdn_dc, "DOMAINGUID_MOD": self.domainguid_mod, + "VERSION": samba.version(), + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": self.extensibleobject, } def fix(self, paths): -- cgit From c619f86efc4f502f7127a1fd2ac165dd970658f9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 23:16:05 +0100 Subject: r26516: Fix line splitting in subunitrun. (This used to be commit 623b7b31144f9da5e256e5541d04db8698dd39d3) --- source4/scripting/python/subunit/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py index 4f24803e63..4d3434a3ea 100644 --- a/source4/scripting/python/subunit/__init__.py +++ b/source4/scripting/python/subunit/__init__.py @@ -215,14 +215,14 @@ class TestProtocolClient(unittest.TestResult): def addError(self, test, error): """Report an error in test test.""" self._stream.write("error: %s [\n" % (test.shortDescription() or str(test))) - for line in self._exc_info_to_string(error, test).split(): + for line in self._exc_info_to_string(error, test).splitlines(): self._stream.write("%s\n" % line) self._stream.write("]\n") def addFailure(self, test, error): """Report a failure in test test.""" self._stream.write("failure: %s [\n" % (test.shortDescription() or str(test))) - for line in self._exc_info_to_string(error, test).split(): + for line in self._exc_info_to_string(error, test).splitlines(): self._stream.write("%s\n" % line) self._stream.write("]\n") -- cgit From 57b8a8fd42f5d89f439fd9d0781bd8f561a84131 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 23:16:12 +0100 Subject: r26517: Add functions for setting and getting parameters on a LoadParm. Pass loadparm context along to Ldb contexts. Other minor Python improvements. (This used to be commit 7a15b486bae8fb774058b2d94cc12b7b01ee6ac0) --- source4/scripting/python/misc.i | 2 +- source4/scripting/python/samba/provision.py | 66 +++++++++++++++-------------- 2 files changed, 36 insertions(+), 32 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index eda0db2c3d..a0519644b8 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -32,7 +32,7 @@ %import "../../auth/credentials/credentials.i" %import "../../param/param.i" %import "../../libcli/security/security.i" -%import "../../libcli/util/errors.i"; +%import "../../libcli/util/errors.i" %rename(random_password) generate_random_str; char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 7d7b85c13e..d88b8501ba 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -122,13 +122,13 @@ class ProvisionSettings(object): if not valid_netbios_name(self.netbiosname): raise InvalidNetbiosName(self.netbiosname) - if lp.get_string("workgroup").upper() != self.domain.upper(): + if lp.get("workgroup").upper() != self.domain.upper(): raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get_string("workgroup"), self.domain) + lp.get("workgroup"), self.domain) - if lp.get_string("realm").upper() != self.realm.upper(): + if lp.get("realm").upper() != self.realm.upper(): raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get_string("realm"), self.realm)) + (lp.get("realm"), self.realm)) class ProvisionPaths: @@ -154,10 +154,10 @@ class ProvisionPaths: def install_ok(lp, session_info, credentials): """Check whether the current install seems ok.""" - if lp.get_string("realm") == "": + if lp.get("realm") == "": return False - ldb = Ldb(lp.get_string("sam database"), session_info=session_info, - credentials=credentials) + ldb = Ldb(lp.get("sam database"), session_info=session_info, + credentials=credentials, lp=lp) if len(ldb.search("(cn=Administrator)")) != 1: return False return True @@ -195,14 +195,16 @@ def ldb_delete(ldb): ldb.connect(ldb.filename) -def open_ldb(session_info, credentials, dbname): +def open_ldb(session_info, credentials, lp, dbname): assert session_info is not None try: - return Ldb(dbname, session_info=session_info, credentials=credentials) + return Ldb(dbname, session_info=session_info, credentials=credentials, + lp=lp) except LdbError, e: print e os.unlink(dbname) - return Ldb(dbname, session_info=session_info, credentials=credentials) + return Ldb(dbname, session_info=session_info, credentials=credentials, + lp=lp) def setup_add_ldif(setup_dir, ldif, subobj, ldb): @@ -228,10 +230,10 @@ def setup_modify_ldif(setup_dir, ldif, subobj, ldb): ldb.modify(msg) -def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, dbname, +def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, lp, dbname, erase=True): assert dbname is not None - ldb = open_ldb(session_info, credentials, dbname) + ldb = open_ldb(session_info, credentials, lp, dbname) assert ldb is not None ldb.transaction_start() try: @@ -277,10 +279,10 @@ def provision_default_paths(lp, subobj): :param subobj: Object """ paths = ProvisionPaths() - private_dir = lp.get_string("private dir") + private_dir = lp.get("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = lp.get_string("sam database") or os.path.join(private_dir, "samdb.ldb") - paths.secrets = lp.get_string("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") + paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") @@ -329,22 +331,22 @@ def setup_name_mappings(subobj, ldb): ldb.setup_name_mapping(subobj.domaindn, sid + "-520", subobj.wheel) -def provision_become_dc(setup_dir, subobj, message, paths, session_info, +def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, credentials): assert session_info is not None subobj.fix(paths) message("Setting up templates into %s" % paths.templates) setup_ldb(setup_dir, "provision_templates.ldif", session_info, - credentials, subobj, paths.templates) + credentials, subobj, lp, paths.templates) # Also wipes the database message("Setting up %s partitions" % paths.samdb) setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, paths.samdb) + credentials, subobj, lp, paths.samdb) samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials) + credentials=credentials, lp=lp) ldb.transaction_start() try: message("Setting up %s attributes" % paths.samdb) @@ -366,9 +368,9 @@ def provision_become_dc(setup_dir, subobj, message, paths, session_info, message("Setting up %s" % paths.secrets) setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, - subobj, paths.secrets) + subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, paths.secrets, False) @@ -401,11 +403,11 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") - setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, paths.shareconf) + setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, lp, paths.shareconf) message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, paths.secrets, False) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, lp, paths.secrets) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, paths.secrets, False) message("Setting up registry") reg = registry.Registry() @@ -414,13 +416,13 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, #reg.apply_patchfile(os.path.join(setup_dir, "provision.reg")) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, lp, paths.templates) message("Setting up sam.ldb partitions") setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, paths.samdb) + credentials, subobj, lp, paths.samdb) - samdb = open_ldb(session_info, credentials, paths.samdb) + samdb = open_ldb(session_info, credentials, lp, paths.samdb) samdb.transaction_start() try: message("Setting up sam.ldb attributes") @@ -439,7 +441,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(paths.samdb, session_info, credentials) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) samdb.set_domain_sid(subobj.domainsid) load_schema(setup_dir, subobj, samdb) @@ -531,7 +534,8 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): """Write out a DNS zone file, from the info in the current database.""" message("Setting up DNS zone: %s" % subobj.dnsdomain) # connect to the sam - ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials) + ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, + lp=lp) # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database @@ -576,8 +580,8 @@ def provision_ldapbase(setup_dir, subobj, message, paths): def provision_guess(lp): """guess reasonably default options for provisioning.""" - subobj = ProvisionSettings(realm=lp.get_string("realm").upper(), - domain=lp.get_string("workgroup"), + subobj = ProvisionSettings(realm=lp.get("realm").upper(), + domain=lp.get("workgroup"), hostname=hostname(), hostip=hostip()) -- cgit From 12a513b47b1a1f2adeb2cb2a10ac36d02dd44065 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 23:16:16 +0100 Subject: r26518: Fix provision of registry using Python. (This used to be commit 12eb38e553993b2726a803af4ae9c05229d6ebe4) --- source4/scripting/python/samba/provision.py | 40 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d88b8501ba..d9863420b6 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -287,11 +287,15 @@ def provision_default_paths(lp, subobj): paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") - paths.ldap_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + ".ldif") - paths.ldap_config_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-config.ldif") - paths.ldap_schema_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-schema.ldif") + paths.ldap_basedn_ldif = os.path.join(private_dir, + subobj.dnsdomain + ".ldif") + paths.ldap_config_basedn_ldif = os.path.join(private_dir, + subobj.dnsdomain + "-config.ldif") + paths.ldap_schema_basedn_ldif = os.path.join(private_dir, + subobj.dnsdomain + "-schema.ldif") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") - paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") + paths.phpldapadminconfig = os.path.join(private_dir, + "phpldapadmin-config.php") paths.hklm = os.path.join(private_dir, "hklm.ldb") return paths @@ -370,8 +374,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, - paths.secrets, False) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + lp, paths.secrets, False) def provision(lp, setup_dir, subobj, message, blank, paths, session_info, @@ -397,26 +401,34 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new smb.conf if there isn't one there already if not os.path.exists(paths.smbconf): message("Setting up smb.conf") - setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, subobj) + setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, + subobj) lp.reload() # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") - setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, lp, paths.shareconf) + setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, + lp, paths.shareconf) message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, paths.secrets, False) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, + subobj, lp, paths.secrets) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + lp, paths.secrets, False) message("Setting up registry") reg = registry.Registry() - # FIXME: Still fails for some reason: - #reg.mount(paths.hklm, registry.HKEY_LOCAL_MACHINE, []) - #reg.apply_patchfile(os.path.join(setup_dir, "provision.reg")) + hive = registry.Hive(paths.hklm, session_info=session_info, + credentials=credentials, lp_ctx=lp) + reg.mount_hive(hive, registry.HKEY_LOCAL_MACHINE, []) + provision_reg = os.path.join(setup_dir, "provision.reg") + assert os.path.exists(provision_reg) + reg.apply_patchfile(provision_reg) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, lp, paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, + credentials, subobj, lp, paths.templates) message("Setting up sam.ldb partitions") setup_ldb(setup_dir, "provision_partitions.ldif", session_info, -- cgit From 63f53094efa29b76eb4136cddf19d9c5d325fc5f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 02:21:14 +0100 Subject: r26520: More Python updates. (This used to be commit a8b1fe15ac853082961132ede061fe1556ae29f7) --- source4/scripting/python/misc.i | 3 ++ source4/scripting/python/misc.py | 2 + source4/scripting/python/misc_wrap.c | 73 +++++++++++++++++++++++++++++ source4/scripting/python/samba/__init__.py | 4 ++ source4/scripting/python/samba/provision.py | 13 ++--- source4/scripting/python/samba/samdb.py | 8 +++- 6 files changed, 96 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index a0519644b8..3af10dfce9 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -23,6 +23,7 @@ #include "ldb.h" #include "param/param.h" #include "dsdb/samdb/samdb.h" +#include "lib/ldb-samba/ldif_handlers.h" %} %import "stdint.i" @@ -62,3 +63,5 @@ WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf %rename(version) samba_version_string; const char *samba_version_string(void); +int dsdb_set_global_schema(struct ldb_context *ldb); +int ldb_register_samba_handlers(struct ldb_context *ldb); diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 228ab24dbf..ae900a1f62 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -68,5 +68,7 @@ ldb_set_loadparm = _misc.ldb_set_loadparm samdb_set_domain_sid = _misc.samdb_set_domain_sid dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file version = _misc.version +dsdb_set_global_schema = _misc.dsdb_set_global_schema +ldb_register_samba_handlers = _misc.ldb_register_samba_handlers diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index effabdecef..dc1203e2f0 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2531,6 +2531,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #include "ldb.h" #include "param/param.h" #include "dsdb/samdb/samdb.h" +#include "lib/ldb-samba/ldif_handlers.h" SWIGINTERN int @@ -2782,6 +2783,16 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) + + #define SWIG_From_long PyInt_FromLong + + +SWIGINTERNINLINE PyObject * +SWIG_From_int (int value) +{ + return SWIG_From_long (value); +} + #ifdef __cplusplus extern "C" { #endif @@ -3051,6 +3062,66 @@ fail: } +SWIGINTERN PyObject *_wrap_dsdb_set_global_schema(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "ldb", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:dsdb_set_global_schema",kwnames,&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsdb_set_global_schema" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + { + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + } + result = (int)dsdb_set_global_schema(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_ldb_register_samba_handlers(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + int result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "ldb", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:ldb_register_samba_handlers",kwnames,&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_register_samba_handlers" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + { + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + } + result = (int)ldb_register_samba_handlers(arg1); + resultobj = SWIG_From_int((int)(result)); + return resultobj; +fail: + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -3059,6 +3130,8 @@ static PyMethodDef SwigMethods[] = { { (char *)"samdb_set_domain_sid", (PyCFunction) _wrap_samdb_set_domain_sid, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"dsdb_attach_schema_from_ldif_file", (PyCFunction) _wrap_dsdb_attach_schema_from_ldif_file, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, NULL}, + { (char *)"dsdb_set_global_schema", (PyCFunction) _wrap_dsdb_set_global_schema, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index f89ac39ac7..8e0eff3011 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -78,6 +78,10 @@ class Ldb(ldb.Ldb): if url: self.connect(url) + def msg(l,text): + print text + #self.set_debug(msg) + set_credentials = misc.ldb_set_credentials set_session_info = misc.ldb_set_session_info set_loadparm = misc.ldb_set_loadparm diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d9863420b6..0a3c183fcc 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -306,7 +306,7 @@ def setup_name_mappings(subobj, ldb): ["objectSid"]) assert len(res) == 1 assert "objectSid" in res[0] - sid = list(res[0]["objectSid"])[0] + sid = str(list(res[0]["objectSid"])[0]) # add some foreign sids if they are not present already ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") @@ -419,12 +419,12 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Setting up registry") reg = registry.Registry() - hive = registry.Hive(paths.hklm, session_info=session_info, - credentials=credentials, lp_ctx=lp) - reg.mount_hive(hive, registry.HKEY_LOCAL_MACHINE, []) + #hive = registry.Hive(paths.hklm, session_info=session_info, + # credentials=credentials, lp_ctx=lp) + #reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") provision_reg = os.path.join(setup_dir, "provision.reg") assert os.path.exists(provision_reg) - reg.apply_patchfile(provision_reg) + #reg.apply_patchfile(provision_reg) message("Setting up templates into %s" % paths.templates) setup_ldb(setup_dir, "provision_templates.ldif", session_info, @@ -434,7 +434,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_ldb(setup_dir, "provision_partitions.ldif", session_info, credentials, subobj, lp, paths.samdb) - samdb = open_ldb(session_info, credentials, lp, paths.samdb) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) samdb.transaction_start() try: message("Setting up sam.ldb attributes") diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 73426121a6..ce06efa3de 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -22,8 +22,14 @@ import samba import misc +import ldb class SamDB(samba.Ldb): + def __init__(self, *args, **kwargs): + super(SamDB, self).__init__(*args, **kwargs) + misc.dsdb_set_global_schema(self) + misc.ldb_register_samba_handlers(self) + def add_foreign(self, domaindn, sid, desc): """Add a foreign security principle.""" add = """ @@ -39,7 +45,7 @@ description: %s def setup_name_mapping(self, domaindn, sid, unixname): """Setup a mapping between a sam name and a unix name.""" - res = self.search(Dn(ldb, domaindn), SCOPE_SUBTREE, + res = self.search(ldb.Dn(self, domaindn), ldb.SCOPE_SUBTREE, "objectSid=%s" % sid, ["dn"]) assert len(res) == 1, "Failed to find record for objectSid %s" % sid -- cgit From 2fef113e82c1f324dc5b5474100eb537f0c98f80 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 02:21:24 +0100 Subject: r26521: Fix newlines. (This used to be commit 174aa1583791a4c305bc49cf78f8f10d42701bc9) --- source4/scripting/python/samba/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 8e0eff3011..a46b148bbb 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -80,7 +80,7 @@ class Ldb(ldb.Ldb): def msg(l,text): print text - #self.set_debug(msg) + self.set_debug(msg) set_credentials = misc.ldb_set_credentials set_session_info = misc.ldb_set_session_info -- cgit From 54a48d40a10c813954e4b777377607bb8366a57e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 02:21:28 +0100 Subject: r26522: Fix warnings on SamDB connect from Python, simplify the setup code for the various LDBs. (This used to be commit 20c686f501b652ec0578a075a124b72ecb5f41b6) --- source4/scripting/python/samba/__init__.py | 7 ++-- source4/scripting/python/samba/provision.py | 61 ++++++++++++++++------------- source4/scripting/python/samba/samdb.py | 8 +++- 3 files changed, 43 insertions(+), 33 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index a46b148bbb..fd294952b8 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -75,13 +75,14 @@ class Ldb(ldb.Ldb): if lp is not None: self.set_loadparm(self, lp) - if url: - self.connect(url) - def msg(l,text): print text self.set_debug(msg) + if url is not None: + self.connect(url) + + set_credentials = misc.ldb_set_credentials set_session_info = misc.ldb_set_session_info set_loadparm = misc.ldb_set_loadparm diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0a3c183fcc..2c6e50219a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -230,15 +230,10 @@ def setup_modify_ldif(setup_dir, ldif, subobj, ldb): ldb.modify(msg) -def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, lp, dbname, - erase=True): - assert dbname is not None - ldb = open_ldb(session_info, credentials, lp, dbname) +def setup_ldb(ldb, setup_dir, ldif, subobj): assert ldb is not None ldb.transaction_start() try: - if erase: - ldb.erase(); setup_add_ldif(setup_dir, ldif, subobj, ldb) except: ldb.transaction_cancel() @@ -281,8 +276,8 @@ def provision_default_paths(lp, subobj): paths = ProvisionPaths() private_dir = lp.get("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") - paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") + paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") @@ -341,13 +336,17 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, subobj.fix(paths) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, - credentials, subobj, lp, paths.templates) + templates_ldb = Ldb(paths.templates, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.erase() + setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) # Also wipes the database message("Setting up %s partitions" % paths.samdb) - setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, lp, paths.samdb) + samdb = SamDB(paths.samdb, credentials=credentials, + session_info=session_info, lp=lp) + samdb.erase() + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -371,11 +370,12 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, - subobj, lp, paths.secrets) - - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, - lp, paths.secrets, False) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secrets_ldb.clear() + setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) + setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) + setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", subobj) def provision(lp, setup_dir, subobj, message, blank, paths, session_info, @@ -408,14 +408,16 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") - setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, - lp, paths.shareconf) + share_ldb = Ldb(paths.shareconf, session_info=session_info, + credentials=credentials, lp=lp) + setup_ldb(share_ldb, setup_dir, "share.ldif", subobj) message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, - subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, - lp, paths.secrets, False) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secrets_ldb.erase() + setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) + setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) message("Setting up registry") reg = registry.Registry() @@ -427,12 +429,16 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, #reg.apply_patchfile(provision_reg) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, - credentials, subobj, lp, paths.templates) + templates_ldb = Ldb(paths.templates, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.erase() + setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) message("Setting up sam.ldb partitions") - setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, lp, paths.samdb) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) + samdb.erase() + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -453,7 +459,6 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.transaction_commit() message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(subobj.domainsid) diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index ce06efa3de..e3f001deb1 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -25,10 +25,14 @@ import misc import ldb class SamDB(samba.Ldb): - def __init__(self, *args, **kwargs): - super(SamDB, self).__init__(*args, **kwargs) + def __init__(self, url=None, session_info=None, credentials=None, + modules_dir=None, lp=None): + super(SamDB, self).__init__(session_info=session_info, credentials=credentials, + modules_dir=modules_dir, lp=lp) misc.dsdb_set_global_schema(self) misc.ldb_register_samba_handlers(self) + if url: + self.connect(url) def add_foreign(self, domaindn, sid, desc): """Add a foreign security principle.""" -- cgit From 1c29a63d443fde3fc0253f634822c12749f1afad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 17:21:13 +0100 Subject: r26523: Refactor provisioning code. (This used to be commit ac1083178f9e521dcd5d3d8b5199abcb00159adf) --- source4/scripting/python/samba/__init__.py | 8 +- source4/scripting/python/samba/provision.py | 396 +++++++++++++++++----------- source4/scripting/python/samba/samdb.py | 2 +- 3 files changed, 250 insertions(+), 156 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index fd294952b8..3981464681 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -77,7 +77,7 @@ class Ldb(ldb.Ldb): def msg(l,text): print text - self.set_debug(msg) + #self.set_debug(msg) if url is not None: self.connect(url) @@ -87,9 +87,9 @@ class Ldb(ldb.Ldb): set_session_info = misc.ldb_set_session_info set_loadparm = misc.ldb_set_loadparm - def searchone(self, basedn, expression, attribute): + def searchone(self, basedn, attribute, expression=None, scope=ldb.SCOPE_BASE): """Search for one attribute as a string.""" - res = self.search(basedn, SCOPE_SUBTREE, expression, [attribute]) + res = self.search(basedn, scope, expression, [attribute]) if len(res) != 1 or res[0][attribute] is None: return None return res[0][attribute] @@ -125,6 +125,8 @@ def substitute_var(text, values): """ for (name, value) in values.items(): + assert isinstance(name, str), "%r is not a string" % name + assert isinstance(value, str), "Value %r for %s is not a string" % (value, name) text = text.replace("${%s}" % name, value) assert "${" not in text, text diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 2c6e50219a..a8aeb8c831 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -39,7 +39,6 @@ class ProvisionSettings(object): self.machinepass = None self.adminpass = None self.defaultsite = "Default-First-Site-Name" - self.datestring = None self.root = None self.nobody = None self.nogroup = None @@ -49,52 +48,19 @@ class ProvisionSettings(object): self.dnsdomain = None self.dnsname = None self.domaindn = None - self.domaindn_ldb = None self.rootdn = None self.configdn = None - self.configdn_ldb = None self.schemedn = None self.schemedn_ldb = None self.s4_ldapi_path = None self.policyguid = None - self.extensibleobject = None + self.serverrole = None def subst_vars(self): - return {"SCHEMADN": self.schemadn, - "SCHEMADN_LDB": self.schemadn_ldb, - "SCHEMADN_MOD": "schema_fsmo", - "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": self.configdn, - "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list), - "MODULES_LIST2": ",".join(self.modules_list2), - "CONFIGDN_LDB": self.configdn_ldb, - "DOMAINDN": self.domaindn, - "DOMAINDN_LDB": self.domaindn_ldb, - "DOMAINDN_MOD": "pdc_fsmo,password_hash", - "DOMAINDN_MOD2": ",objectguid", - "DOMAINSID": str(self.domainsid), - "MODULES_LIST": ",".join(self.modules_list), - "CONFIGDN_MOD": "naming_fsmo", - "CONFIGDN_MOD2": ",objectguid", - "NETBIOSNAME": self.netbiosname, - "DNSNAME": self.dnsname, - "ROOTDN": self.rootdn, - "DOMAIN": self.domain, - "DNSDOMAIN": self.dnsdomain, - "REALM": self.realm, - "DEFAULTSITE": self.defaultsite, - "MACHINEPASS_B64": b64encode(self.machinepass), - "ADMINPASS_B64": b64encode(self.adminpass), - "DNSPASS_B64": b64encode(self.dnspass), - "KRBTGTPASS_B64": b64encode(self.krbtgtpass), - "S4_LDAPI_URI": "ldapi://%s" % self.s4_ldapi_path.replace("/", "%2F"), - "LDAPTIME": timestring(int(time.time())), - "POLICYGUID": self.policyguid, - "RDN_DC": self.rdn_dc, - "DOMAINGUID_MOD": self.domainguid_mod, - "VERSION": samba.version(), - "ACI": "# no aci for local ldb", - "EXTENSIBLEOBJECT": self.extensibleobject, + return { + "SERVERROLE": self.serverrole, + "DOMAIN_CONF": self.domain, + "REALM_CONF": self.realm, } def fix(self, paths): @@ -114,6 +80,7 @@ class ProvisionSettings(object): self.secrets_keytab = paths.keytab self.s4_ldapi_path = paths.s4_ldapi_path + self.serverrole = "domain controller" def validate(self, lp): if not valid_netbios_name(self.domain): @@ -207,61 +174,64 @@ def open_ldb(session_info, credentials, lp, dbname): lp=lp) -def setup_add_ldif(setup_dir, ldif, subobj, ldb): +def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): """Setup a ldb in the private dir.""" assert isinstance(ldif, str) assert isinstance(setup_dir, str) src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + if subst_vars is not None: + data = substitute_var(data, subst_vars) for msg in ldb.parse_ldif(data): ldb.add(msg[1]) -def setup_modify_ldif(setup_dir, ldif, subobj, ldb): +def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + if substvars is not None: + data = substitute_var(data, substvars) for (changetype, msg) in ldb.parse_ldif(data): ldb.modify(msg) -def setup_ldb(ldb, setup_dir, ldif, subobj): +def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): assert ldb is not None ldb.transaction_start() try: - setup_add_ldif(setup_dir, ldif, subobj, ldb) + setup_add_ldif(ldb, setup_dir, ldif, subst_vars) except: ldb.transaction_cancel() raise ldb.transaction_commit() -def setup_ldb_modify(setup_dir, ldif, subobj, ldb): +def setup_ldb_modify(setup_dir, ldif, substvars, ldb): """Modify a ldb in the private dir.""" src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + data = substitute_var(data, substvars) assert not "${" in data for (changetype, msg) in ldb.parse_ldif(data): ldb.modify(msg) -def setup_file(setup_dir, template, message, fname, subobj): +def setup_file(setup_dir, template, fname, substvars): """Setup a file in the private dir.""" f = fname src = os.path.join(setup_dir, template) - os.unlink(f) + if os.path.exists(f): + os.unlink(f) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + data = substitute_var(data, substvars) assert not "${" in data open(f, 'w').write(data) @@ -297,11 +267,7 @@ def provision_default_paths(lp, subobj): def setup_name_mappings(subobj, ldb): """setup reasonable name mappings for sam names to unix names.""" - res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectSid=*", - ["objectSid"]) - assert len(res) == 1 - assert "objectSid" in res[0] - sid = str(list(res[0]["objectSid"])[0]) + sid = str(subobj.domainsid) # add some foreign sids if they are not present already ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") @@ -336,33 +302,35 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, subobj.fix(paths) message("Setting up templates into %s" % paths.templates) - templates_ldb = Ldb(paths.templates, session_info=session_info, - credentials=credentials, lp=lp) - templates_ldb.erase() - setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) + setup_templatesdb(paths.templates, setup_dir, session_info, + credentials, lp) # Also wipes the database - message("Setting up %s partitions" % paths.samdb) + message("Setting up samdb") + os.path.unlink(paths.samdb) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) samdb.erase() - setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) - samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials, lp=lp) + message("Setting up %s partitions" % paths.samdb) + setup_samdb_partitions(samdb, setup_dir, subobj) + + samdb = SamDB(paths.samdb, credentials=credentials, + session_info=session_info, lp=lp) + ldb.transaction_start() try: message("Setting up %s attributes" % paths.samdb) - setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up %s rootDSE" % paths.samdb) - setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") ldb_erase_partitions(subobj, message, samdb, None) message("Setting up %s indexes" % paths.samdb) - setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_index.ldif") except: samdb.transaction_cancel() raise @@ -370,12 +338,70 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, - credentials=credentials, lp=lp) - secrets_ldb.clear() - setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) - setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) - setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", subobj) + secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info, credentials, lp) + setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", + { "MACHINEPASS_B64": b64encode(self.machinepass) }) + + +def setup_secretsdb(path, setup_dir, session_info, credentials, lp): + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) + secrets_ldb.erase() + setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif") + setup_ldb(secrets_ldb, setup_dir, "secrets.ldif") + return secrets_ldb + + +def setup_templatesdb(path, setup_dir, session_info, credentials, lp): + templates_ldb = Ldb(path, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.erase() + setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", None) + + +def setup_registry(path, setup_dir, session_info, credentials, lp): + reg = registry.Registry() + hive = registry.Hive(path, session_info=session_info, + credentials=credentials, lp_ctx=lp) + reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") + provision_reg = os.path.join(setup_dir, "provision.reg") + assert os.path.exists(provision_reg) + reg.apply_patchfile(provision_reg) + + +def setup_samdb_rootdse(samdb, setup_dir, subobj): + setup_add_ldif(samdb, setup_dir, "provision_rootdse_add.ldif", { + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "DNSDOMAIN": subobj.dnsdomain, + "DEFAULTSITE": subobj.defaultsite, + "REALM": subobj.realm, + "DNSNAME": subobj.dnsname, + "DOMAINDN": subobj.domaindn, + "ROOTDN": subobj.rootdn, + "CONFIGDN": subobj.configdn, + "VERSION": samba.version(), + }) + + +def setup_samdb_partitions(samdb, setup_dir, subobj): + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", { + "SCHEMADN": subobj.schemadn, + "SCHEMADN_LDB": "schema.ldb", + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": subobj.configdn, + "CONFIGDN_LDB": "configuration.ldb", + "DOMAINDN": subobj.domaindn, + "DOMAINDN_LDB": "users.ldb", + "SCHEMADN_MOD": "schema_fsmo", + "CONFIGDN_MOD": "naming_fsmo", + "CONFIGDN_MOD2": ",objectguid", + "DOMAINDN_MOD": "pdc_fsmo,password_hash", + "DOMAINDN_MOD2": ",objectguid", + "MODULES_LIST": ",".join(subobj.modules_list), + "TDB_MODULES_LIST": ","+",".join(subobj.tdb_modules_list), + "MODULES_LIST2": ",".join(subobj.modules_list2), + }) + def provision(lp, setup_dir, subobj, message, blank, paths, session_info, @@ -386,11 +412,6 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, """ subobj.fix(paths) - if subobj.domain_guid is not None: - subobj.domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid - else: - subobj.domainguid_mod = "" - if subobj.host_guid is not None: subobj.hostguid_add = "objectGUID: %s" % subobj.host_guid else: @@ -401,8 +422,14 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new smb.conf if there isn't one there already if not os.path.exists(paths.smbconf): message("Setting up smb.conf") - setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, - subobj) + if lp.get("server role") == "domain controller": + smbconfsuffix = "dc" + elif lp.get("server role") == "member": + smbconfsuffix = "member" + else: + assert "Invalid server role setting: %s" % lp.get("server role") + setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf, + None) lp.reload() # only install a new shares config db if there is none @@ -410,45 +437,37 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Setting up share.ldb") share_ldb = Ldb(paths.shareconf, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(share_ldb, setup_dir, "share.ldif", subobj) + setup_ldb(share_ldb, setup_dir, "share.ldif", None) message("Setting up %s" % paths.secrets) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, - credentials=credentials, lp=lp) - secrets_ldb.erase() - setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) - setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) + setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, + credentials=credentials, lp=lp) message("Setting up registry") - reg = registry.Registry() - #hive = registry.Hive(paths.hklm, session_info=session_info, - # credentials=credentials, lp_ctx=lp) - #reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") - provision_reg = os.path.join(setup_dir, "provision.reg") - assert os.path.exists(provision_reg) - #reg.apply_patchfile(provision_reg) + #setup_registry(paths.hklm, setup_dir, session_info, + # credentials=credentials, lp=lp) message("Setting up templates into %s" % paths.templates) - templates_ldb = Ldb(paths.templates, session_info=session_info, - credentials=credentials, lp=lp) - templates_ldb.erase() - setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) + setup_templatesdb(paths.templates, setup_dir, session_info=session_info, + credentials=credentials, lp=lp) - message("Setting up sam.ldb partitions") samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.erase() - setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) + + message("Setting up sam.ldb partitions") + setup_samdb_partitions(samdb, setup_dir, subobj) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) + samdb.transaction_start() try: message("Setting up sam.ldb attributes") - setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up sam.ldb rootDSE") - setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") ldb_erase_partitions(subobj, message, samdb, ldapbackend) @@ -462,53 +481,113 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(subobj.domainsid) - load_schema(setup_dir, subobj, samdb) + load_schema(setup_dir, samdb, subobj) samdb.transaction_start() try: message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn) - setup_add_ldif(setup_dir, "provision_basedn.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_basedn.ldif", { + "DOMAINDN": subobj.domaindn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", + "RDN_DC": subobj.rdn_dc, + }) + message("Modifying DomainDN: " + subobj.domaindn + "") - setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", subobj, samdb) + if subobj.domain_guid is not None: + domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid + else: + domainguid_mod = "" + + setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", { + "RDN_DC": subobj.rdn_dc, + "LDAPTIME": timestring(int(time.time())), + "DOMAINSID": str(subobj.domainsid), + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "CONFIGDN": subobj.configdn, + "POLICYGUID": subobj.policyguid, + "DOMAINDN": subobj.domaindn, + "DOMAINGUID_MOD": domainguid_mod, + }, samdb) message("Adding configuration container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_configuration_basedn.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { + "CONFIGDN": subobj.configdn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", + }) message("Modifying configuration container") - setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", { + "CONFIGDN": subobj.configdn, + "SCHEMADN": subobj.schemadn, + }, samdb) message("Adding schema container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_schema_basedn.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { + "SCHEMADN": subobj.schemadn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" + }) message("Modifying schema container") - setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", { + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "CONFIGDN": subobj.configdn, + }, samdb) + message("Setting up sam.ldb Samba4 schema") - setup_add_ldif(setup_dir, "schema_samba4.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", { + "SCHEMADN": subobj.schemadn, + }) message("Setting up sam.ldb AD schema") - setup_add_ldif(setup_dir, "schema.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "schema.ldif", { + "SCHEMADN": subobj.schemadn, + }) message("Setting up sam.ldb configuration data") - setup_add_ldif(setup_dir, "provision_configuration.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_configuration.ldif", { + "CONFIGDN": subobj.configdn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "DNSDOMAIN": subobj.dnsdomain, + "DOMAIN": subobj.domain, + "SCHEMADN": subobj.schemadn, + "DOMAINDN": subobj.domaindn, + }) message("Setting up display specifiers") - setup_add_ldif(setup_dir, "display_specifiers.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": subobj.configdn}) message("Adding users container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_users_add.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { + "DOMAINDN": subobj.domaindn}) message("Modifying users container") - setup_ldb_modify(setup_dir, "provision_users_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_users_modify.ldif", { + "DOMAINDN": subobj.domaindn}, samdb) message("Adding computers container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_computers_add.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { + "DOMAINDN": subobj.domaindn}) message("Modifying computers container") - setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", { + "DOMAINDN": subobj.domaindn}, samdb) message("Setting up sam.ldb data") - setup_add_ldif(setup_dir, "provision.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision.ldif", { + "DOMAINDN": subobj.domaindn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "CONFIGDN": subobj.configdn, + }) if blank: message("Setting up sam.ldb index") - setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_index.ldif") message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") samdb.transaction_commit() return @@ -527,15 +606,21 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # samdb = open_ldb(info, paths.samdb, False) # message("Setting up sam.ldb users and groups") - setup_add_ldif(setup_dir, "provision_users.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { + "DOMAINDN": subobj.domaindn, + "DOMAINSID": str(subobj.domainsid), + "CONFIGDN": subobj.configdn, + "ADMINPASS_B64": b64encode(subobj.adminpass), + "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), + }) setup_name_mappings(subobj, samdb) message("Setting up sam.ldb index") - setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_index.ldif") message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") except: samdb.transaction_cancel() raise @@ -543,12 +628,17 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.transaction_commit() message("Setting up phpLDAPadmin configuration") - setup_file(setup_dir, "phpldapadmin-config.php", message, - paths.phpldapadminconfig, subobj) + create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, subobj.s4_ldapi_path) + message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) -def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): +def create_phplpapdadmin_config(path, setup_dir, s4_ldapi_path): + setup_file(setup_dir, "phpldapadmin-config.php", + path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) + + +def provision_dns(setup_dir, subobj, message, paths, session_info, credentials, lp): """Write out a DNS zone file, from the info in the current database.""" message("Setting up DNS zone: %s" % subobj.dnsdomain) # connect to the sam @@ -557,18 +647,22 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database - - res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectGUID=*", - ["objectGUID"]) - assert(len(res) == 1) - assert(res[0]["objectGUID"] is not None) - subobj.domainguid = res[0]["objectGUID"] - - subobj.host_guid = ldb.searchone(subobj.domaindn, - "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID") - assert subobj.host_guid is not None - - setup_file(setup_dir, "provision.zone", message, paths.dns, subobj) + domainguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID")) + + hostguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID" , + expression="(&(objectClass=computer)(cn=%s))" % subobj.netbiosname)) + + setup_file(setup_dir, "provision.zone", paths.dns, { + "DNSPASS_B64": b64encode(subobj.dnspass), + "HOSTNAME": hostname(), + "DNSDOMAIN": subobj.dnsdomain, + "REALM": subobj.realm, + "HOSTIP": hostip(), + "DOMAINGUID": domainguid, + "DATESTRING": time.strftime("%Y%m%d%H"), + "DEFAULTSITE": subobj.defaultsite, + "HOSTGUID": hostguid, + }) message("Please install the zone located in %s into your DNS server" % paths.dns) @@ -577,21 +671,21 @@ def provision_ldapbase(setup_dir, subobj, message, paths): """Write out a DNS zone file, from the info in the current database.""" message("Setting up LDAP base entry: %s" % subobj.domaindn) rdns = subobj.domaindn.split(",") - subobj.extensibleobject = "objectClass: extensibleObject" subobj.rdn_dc = rdns[0][len("DC="):] setup_file(setup_dir, "provision_basedn.ldif", - message, paths.ldap_basedn_ldif, - subobj) + paths.ldap_basedn_ldif, + None) setup_file(setup_dir, "provision_configuration_basedn.ldif", - message, paths.ldap_config_basedn_ldif, - subobj) + paths.ldap_config_basedn_ldif, None) setup_file(setup_dir, "provision_schema_basedn.ldif", - message, paths.ldap_schema_basedn_ldif, - subobj) + paths.ldap_schema_basedn_ldif, { + "SCHEMADN": subobj.schemadn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "objectClass: extensibleObject"}) message("Please install the LDIF located in " + paths.ldap_basedn_ldif + ", " + paths.ldap_config_basedn_ldif + " and " + paths.ldap_schema_basedn_ldif + " into your LDAP server, and re-run with --ldap-backend=ldap://my.ldap.server") @@ -614,7 +708,6 @@ def provision_guess(lp): subobj.machinepass = misc.random_password(12) subobj.adminpass = misc.random_password(12) subobj.dnspass = misc.random_password(12) - subobj.datestring = time.strftime("%Y%m%d%H") subobj.root = findnss(pwd.getpwnam, "root")[4] subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] @@ -625,12 +718,9 @@ def provision_guess(lp): subobj.dnsdomain = subobj.realm.lower() subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=") - subobj.domaindn_ldb = "users.ldb" subobj.rootdn = subobj.domaindn subobj.configdn = "CN=Configuration," + subobj.rootdn - subobj.configdn_ldb = "configuration.ldb" subobj.schemadn = "CN=Schema," + subobj.configdn - subobj.schemadn_ldb = "schema.ldb" #Add modules to the list to activate them by default #beware often order is important @@ -661,21 +751,23 @@ def provision_guess(lp): subobj.modules_list2 = ["show_deleted", "partition"] - subobj.extensibleobject = "# no objectClass: extensibleObject for local ldb" - subobj.aci = "# no aci for local ldb" return subobj -def load_schema(setup_dir, subobj, samdb): +def load_schema(setup_dir, samdb, subobj): """Load schema.""" src = os.path.join(setup_dir, "schema.ldif") schema_data = open(src, 'r').read() src = os.path.join(setup_dir, "schema_samba4.ldif") schema_data += open(src, 'r').read() - schema_data = substitute_var(schema_data, subobj.subst_vars()) + schema_data = substitute_var(schema_data, {"SCHEMADN": subobj.schemadn}) src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") head_data = open(src, 'r').read() - head_data = substitute_var(head_data, subobj.subst_vars()) + head_data = substitute_var(head_data, { + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "CONFIGDN": subobj.configdn, + "DEFAULTSITE": subobj.defaultsite}) samdb.attach_schema_from_ldif(head_data, schema_data) diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index e3f001deb1..7061e22ce4 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -89,7 +89,7 @@ userAccountControl: %u assert(len(res) == 1 and res[0].defaultNamingContext is not None) domain_dn = res[0].defaultNamingContext assert(domain_dn is not None) - dom_users = searchone(self, domain_dn, "name=Domain Users", "dn") + dom_users = self.searchone(domain_dn, "dn", "name=Domain Users") assert(dom_users is not None) user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) -- cgit From 4bfbd78086a342e4075596a6a9e5de0cec0b47ac Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 17:21:20 +0100 Subject: r26524: Import self join. (This used to be commit daae983c260da6af6a4f1cba1290bc7240d7a970) --- source4/scripting/python/samba/provision.py | 117 ++++++++++++++++++---------- 1 file changed, 75 insertions(+), 42 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a8aeb8c831..c17b74345a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -54,14 +54,6 @@ class ProvisionSettings(object): self.schemedn_ldb = None self.s4_ldapi_path = None self.policyguid = None - self.serverrole = None - - def subst_vars(self): - return { - "SERVERROLE": self.serverrole, - "DOMAIN_CONF": self.domain, - "REALM_CONF": self.realm, - } def fix(self, paths): self.realm = self.realm.upper() @@ -75,13 +67,6 @@ class ProvisionSettings(object): rdns = self.domaindn.split(",") self.rdn_dc = rdns[0][len("DC="):] - self.sam_ldb = paths.samdb - self.secrets_ldb = paths.secrets - self.secrets_keytab = paths.keytab - - self.s4_ldapi_path = paths.s4_ldapi_path - self.serverrole = "domain controller" - def validate(self, lp): if not valid_netbios_name(self.domain): raise InvalidNetbiosName(self.domain) @@ -111,12 +96,12 @@ class ProvisionPaths: self.samdb = None self.secrets = None self.keytab = None + self.dns_keytab = None self.dns = None self.winsdb = None self.ldap_basedn_ldif = None self.ldap_config_basedn_ldif = None self.ldap_schema_basedn_ldif = None - self.s4_ldapi_path = None def install_ok(lp, session_info, credentials): @@ -184,6 +169,8 @@ def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): if subst_vars is not None: data = substitute_var(data, subst_vars) + assert "${" not in data + for msg in ldb.parse_ldif(data): ldb.add(msg[1]) @@ -195,6 +182,8 @@ def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): if substvars is not None: data = substitute_var(data, substvars) + assert "${" not in data + for (changetype, msg) in ldb.parse_ldif(data): ldb.modify(msg) @@ -231,7 +220,8 @@ def setup_file(setup_dir, template, fname, substvars): os.unlink(f) data = open(src, 'r').read() - data = substitute_var(data, substvars) + if substvars: + data = substitute_var(data, substvars) assert not "${" in data open(f, 'w').write(data) @@ -250,6 +240,7 @@ def provision_default_paths(lp, subobj): paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") + paths.dns_keytab = os.path.join(private_dir, "dns.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.ldap_basedn_ldif = os.path.join(private_dir, @@ -262,6 +253,14 @@ def provision_default_paths(lp, subobj): paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") paths.hklm = os.path.join(private_dir, "hklm.ldb") + paths.sysvol = lp.get("sysvol", "path") + if paths.sysvol is None: + paths.sysvol = os.path.join(lp.get("lock dir"), "sysvol") + + paths.netlogon = lp.get("netlogon", "path") + if paths.netlogon is None: + paths.netlogon = os.path.join(os.path.join(paths.sysvol, "scripts")) + return paths @@ -412,11 +411,6 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, """ subobj.fix(paths) - if subobj.host_guid is not None: - subobj.hostguid_add = "objectGUID: %s" % subobj.host_guid - else: - subobj.hostguid_add = "" - assert paths.smbconf is not None # only install a new smb.conf if there isn't one there already @@ -440,10 +434,11 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_ldb(share_ldb, setup_dir, "share.ldif", None) message("Setting up %s" % paths.secrets) - setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, + secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, credentials=credentials, lp=lp) message("Setting up registry") + # FIXME: Still fails for some reason #setup_registry(paths.hklm, setup_dir, session_info, # credentials=credentials, lp=lp) @@ -582,15 +577,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "CONFIGDN": subobj.configdn, }) - if blank: - message("Setting up sam.ldb index") - setup_add_ldif(samdb, setup_dir, "provision_index.ldif") - - message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") - - samdb.transaction_commit() - return + if not blank: # message("Activate schema module") # setup_modify_ldif("schema_activation.ldif", info, samdb, False) @@ -605,16 +592,62 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # # samdb = open_ldb(info, paths.samdb, False) # - message("Setting up sam.ldb users and groups") - setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { - "DOMAINDN": subobj.domaindn, - "DOMAINSID": str(subobj.domainsid), - "CONFIGDN": subobj.configdn, - "ADMINPASS_B64": b64encode(subobj.adminpass), - "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), - }) + message("Setting up sam.ldb users and groups") + setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { + "DOMAINDN": subobj.domaindn, + "DOMAINSID": str(subobj.domainsid), + "CONFIGDN": subobj.configdn, + "ADMINPASS_B64": b64encode(subobj.adminpass), + "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), + }) + + if lp.get("server role") == "domain controller": + message("Setting up self join") + if subobj.host_guid is not None: + hostguid_add = "objectGUID: %s" % subobj.host_guid + else: + hostguid_add = "" + + setup_add_ldif(samdb, setup_dir, "provision_self_join.ldif", { + "CONFIGDN": subobj.configdn, + "SCHEMADN": subobj.schemadn, + "DOMAINDN": subobj.domaindn, + "INVOCATIONID": subobj.invocationid, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "DNSNAME": subobj.dnsname, + "MACHINEPASS_B64": b64encode(subobj.machinepass), + "DNSPASS_B64": b64encode(subobj.dnspass), + "REALM": subobj.realm, + "DOMAIN": subobj.domain, + "HOSTGUID_ADD": hostguid_add, + "DNSDOMAIN": subobj.dnsdomain}) + setup_add_ldif(samdb, setup_dir, "provision_group_policy.ldif", { + "POLICYGUID": subobj.policyguid, + "DNSDOMAIN": subobj.dnsdomain, + "DOMAINSID": str(subobj.domainsid), + "DOMAINDN": subobj.domaindn}) + + os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}"), 0755) + os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "Machine"), 0755) + os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "User"), 0755) + if not os.path.isdir(paths.netlogon): + os.makedirs(paths.netlogon, 0755) + setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", { + "MACHINEPASS_B64": b64encode(subobj.machinepass), + "DOMAIN": subobj.domain, + "REALM": subobj.realm, + "LDAPTIME": timestring(int(time.time())), + "DNSDOMAIN": subobj.dnsdomain, + "DOMAINSID": str(subobj.domainsid), + "SECRETS_KEYTAB": paths.keytab, + "NETBIOSNAME": subobj.netbiosname, + "SAM_LDB": paths.samdb, + "DNS_KEYTAB": paths.dns_keytab, + "DNSPASS_B64": b64encode(subobj.dnspass), + }) - setup_name_mappings(subobj, samdb) + setup_name_mappings(subobj, samdb) message("Setting up sam.ldb index") setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -628,7 +661,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.transaction_commit() message("Setting up phpLDAPadmin configuration") - create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, subobj.s4_ldapi_path) + create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, paths.s4_ldapi_path) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) -- cgit From 44946cefb3c016a45f1d167db765b705e96ed70c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 17:21:24 +0100 Subject: r26525: Consistency in the API. (This used to be commit 37577fee582e7c9896b5cf8b62016d480b8f147e) --- source4/scripting/python/samba/provision.py | 103 ++++++++++++++-------------- 1 file changed, 53 insertions(+), 50 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c17b74345a..ebc8288351 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -199,12 +199,13 @@ def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): ldb.transaction_commit() -def setup_ldb_modify(setup_dir, ldif, substvars, ldb): +def setup_ldb_modify(ldb, setup_dir, ldif, substvars=None): """Modify a ldb in the private dir.""" src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, substvars) + if substvars is not None: + data = substitute_var(data, substvars) assert not "${" in data for (changetype, msg) in ldb.parse_ldif(data): @@ -312,7 +313,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.erase() message("Setting up %s partitions" % paths.samdb) - setup_samdb_partitions(samdb, setup_dir, subobj) + setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, + subobj.configdn, subobj.domaindn) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) @@ -382,23 +384,52 @@ def setup_samdb_rootdse(samdb, setup_dir, subobj): }) -def setup_samdb_partitions(samdb, setup_dir, subobj): +def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): + #Add modules to the list to activate them by default + #beware often order is important + # + # Some Known ordering constraints: + # - rootdse must be first, as it makes redirects from "" -> cn=rootdse + # - objectclass must be before password_hash, because password_hash checks + # that the objectclass is of type person (filled in by objectclass + # module when expanding the objectclass list) + # - partition must be last + # - each partition has its own module list then + modules_list = ["rootdse", + "paged_results", + "ranged_results", + "anr", + "server_sort", + "extended_dn", + "asq", + "samldb", + "rdn_name", + "objectclass", + "kludge_acl", + "operational"] + tdb_modules_list = [ + "subtree_rename", + "subtree_delete", + "linked_attributes"] + modules_list2 = ["show_deleted", + "partition"] + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", { - "SCHEMADN": subobj.schemadn, + "SCHEMADN": schemadn, "SCHEMADN_LDB": "schema.ldb", "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": subobj.configdn, + "CONFIGDN": configdn, "CONFIGDN_LDB": "configuration.ldb", - "DOMAINDN": subobj.domaindn, + "DOMAINDN": domaindn, "DOMAINDN_LDB": "users.ldb", "SCHEMADN_MOD": "schema_fsmo", "CONFIGDN_MOD": "naming_fsmo", "CONFIGDN_MOD2": ",objectguid", "DOMAINDN_MOD": "pdc_fsmo,password_hash", "DOMAINDN_MOD2": ",objectguid", - "MODULES_LIST": ",".join(subobj.modules_list), - "TDB_MODULES_LIST": ","+",".join(subobj.tdb_modules_list), - "MODULES_LIST2": ",".join(subobj.modules_list2), + "MODULES_LIST": ",".join(modules_list), + "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "MODULES_LIST2": ",".join(modules_list2), }) @@ -451,7 +482,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.erase() message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_dir, subobj) + setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, + subobj.configdn, subobj.domaindn) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -495,7 +527,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, else: domainguid_mod = "" - setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", { + setup_ldb_modify(samdb, setup_dir, "provision_basedn_modify.ldif", { "RDN_DC": subobj.rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(subobj.domainsid), @@ -506,7 +538,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "POLICYGUID": subobj.policyguid, "DOMAINDN": subobj.domaindn, "DOMAINGUID_MOD": domainguid_mod, - }, samdb) + }) message("Adding configuration container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { @@ -515,10 +547,10 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") - setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", { + setup_ldb_modify(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { "CONFIGDN": subobj.configdn, "SCHEMADN": subobj.schemadn, - }, samdb) + }) message("Adding schema container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { @@ -527,12 +559,12 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", { + setup_ldb_modify(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { "SCHEMADN": subobj.schemadn, "NETBIOSNAME": subobj.netbiosname, "DEFAULTSITE": subobj.defaultsite, "CONFIGDN": subobj.configdn, - }, samdb) + }) message("Setting up sam.ldb Samba4 schema") setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", { @@ -561,14 +593,14 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying users container") - setup_ldb_modify(setup_dir, "provision_users_modify.ldif", { - "DOMAINDN": subobj.domaindn}, samdb) + setup_ldb_modify(samdb, setup_dir, "provision_users_modify.ldif", { + "DOMAINDN": subobj.domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying computers container") - setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", { - "DOMAINDN": subobj.domaindn}, samdb) + setup_ldb_modify(samdb, setup_dir, "provision_computers_modify.ldif", { + "DOMAINDN": subobj.domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_dir, "provision.ldif", { "DOMAINDN": subobj.domaindn, @@ -755,35 +787,6 @@ def provision_guess(lp): subobj.configdn = "CN=Configuration," + subobj.rootdn subobj.schemadn = "CN=Schema," + subobj.configdn - #Add modules to the list to activate them by default - #beware often order is important - # - # Some Known ordering constraints: - # - rootdse must be first, as it makes redirects from "" -> cn=rootdse - # - objectclass must be before password_hash, because password_hash checks - # that the objectclass is of type person (filled in by objectclass - # module when expanding the objectclass list) - # - partition must be last - # - each partition has its own module list then - subobj.modules_list = ["rootdse", - "paged_results", - "ranged_results", - "anr", - "server_sort", - "extended_dn", - "asq", - "samldb", - "rdn_name", - "objectclass", - "kludge_acl", - "operational"] - subobj.tdb_modules_list = [ - "subtree_rename", - "subtree_delete", - "linked_attributes"] - subobj.modules_list2 = ["show_deleted", - "partition"] - return subobj -- cgit From 4e6ab64762477c0117aa823fd8e6b1275d63e0d7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 18:54:19 +0100 Subject: r26527: Start on tests for provision. (This used to be commit 84ac6c6bbfc4baaf28906ee5826a9cf888043656) --- source4/scripting/python/samba/__init__.py | 2 - source4/scripting/python/samba/provision.py | 60 ++++++++--------------- source4/scripting/python/samba/tests/__init__.py | 17 +++++++ source4/scripting/python/samba/tests/provision.py | 59 ++++++++++++++++++++++ 4 files changed, 96 insertions(+), 42 deletions(-) create mode 100644 source4/scripting/python/samba/tests/provision.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 3981464681..9ac283e660 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -129,8 +129,6 @@ def substitute_var(text, values): assert isinstance(value, str), "Value %r for %s is not a string" % (value, name) text = text.replace("${%s}" % name, value) - assert "${" not in text, text - return text diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ebc8288351..04f50e8359 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -135,18 +135,6 @@ def hostname(): return gethostname().split(".")[0] -def ldb_delete(ldb): - """Delete a LDB file. - - This may be necessary if the ldb is in bad shape, possibly due to being - built from an incompatible previous version of the code, so delete it - completely. - """ - print "Deleting %s\n" % ldb.filename - os.unlink(ldb.filename) - ldb.connect(ldb.filename) - - def open_ldb(session_info, credentials, lp, dbname): assert session_info is not None try: @@ -176,6 +164,13 @@ def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): + """Modify a ldb in the private dir. + + :param ldb: LDB object. + :param setup_dir: Setup directory. + :param ldif: LDIF file path. + :param substvars: Optional dictionary with substitution variables. + """ src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() @@ -199,19 +194,6 @@ def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): ldb.transaction_commit() -def setup_ldb_modify(ldb, setup_dir, ldif, substvars=None): - """Modify a ldb in the private dir.""" - src = os.path.join(setup_dir, ldif) - - data = open(src, 'r').read() - if substvars is not None: - data = substitute_var(data, substvars) - assert not "${" in data - - for (changetype, msg) in ldb.parse_ldif(data): - ldb.modify(msg) - - def setup_file(setup_dir, template, fname, substvars): """Setup a file in the private dir.""" f = fname @@ -328,7 +310,7 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") - ldb_erase_partitions(subobj, message, samdb, None) + ldb_erase_partitions(subobj.domaindn, message, samdb, None) message("Setting up %s indexes" % paths.samdb) setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -453,8 +435,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, smbconfsuffix = "member" else: assert "Invalid server role setting: %s" % lp.get("server role") - setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf, - None) + setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf) lp.reload() # only install a new shares config db if there is none @@ -462,7 +443,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Setting up share.ldb") share_ldb = Ldb(paths.shareconf, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(share_ldb, setup_dir, "share.ldif", None) + setup_ldb(share_ldb, setup_dir, "share.ldif") message("Setting up %s" % paths.secrets) secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, @@ -497,7 +478,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") - ldb_erase_partitions(subobj, message, samdb, ldapbackend) + ldb_erase_partitions(subobj.domaindn, message, samdb, ldapbackend) except: samdb.transaction_cancel() raise @@ -527,7 +508,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, else: domainguid_mod = "" - setup_ldb_modify(samdb, setup_dir, "provision_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_basedn_modify.ldif", { "RDN_DC": subobj.rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(subobj.domainsid), @@ -547,7 +528,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") - setup_ldb_modify(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { "CONFIGDN": subobj.configdn, "SCHEMADN": subobj.schemadn, }) @@ -559,7 +540,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_ldb_modify(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { "SCHEMADN": subobj.schemadn, "NETBIOSNAME": subobj.netbiosname, "DEFAULTSITE": subobj.defaultsite, @@ -593,13 +574,13 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying users container") - setup_ldb_modify(samdb, setup_dir, "provision_users_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_users_modify.ldif", { "DOMAINDN": subobj.domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying computers container") - setup_ldb_modify(samdb, setup_dir, "provision_computers_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_computers_modify.ldif", { "DOMAINDN": subobj.domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_dir, "provision.ldif", { @@ -807,7 +788,7 @@ def load_schema(setup_dir, samdb, subobj): samdb.attach_schema_from_ldif(head_data, schema_data) -def join_domain(domain, netbios_name, join_type, creds, message): +def join_domain(domain, netbios_name, join_type, creds): ctx = NetContext(creds) joindom = object() joindom.domain = domain @@ -824,8 +805,7 @@ def vampire(domain, session_info, credentials, message): access to our local database (might be remote ldap) """ ctx = NetContext(credentials) - vampire_ctx = object() - machine_creds = credentials_init() + machine_creds = Credentials() machine_creds.set_domain(form.domain) if not machine_creds.set_machine_account(): raise Exception("Failed to access domain join information!") @@ -835,7 +815,7 @@ def vampire(domain, session_info, credentials, message): raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) -def ldb_erase_partitions(subobj, message, ldb, ldapbackend): +def ldb_erase_partitions(domaindn, message, ldb, ldapbackend): """Erase an ldb, removing all records.""" assert ldb is not None res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", @@ -848,7 +828,7 @@ def ldb_erase_partitions(subobj, message, ldb, ldapbackend): previous_remaining = 1 current_remaining = 0 - if ldapbackend and (basedn == subobj.domaindn): + if ldapbackend and (basedn == domaindn): # Only delete objects that were created by provision anything = "(objectcategory=*)" diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index d3930e217a..0808469907 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -35,3 +35,20 @@ class LdbTestCase(unittest.TestCase): self.ldb = samba.Ldb(self.filename) +class SubstituteVarTestCase(unittest.TestCase): + def test_empty(self): + self.assertEquals("", samba.substitute_var("", {})) + + def test_nothing(self): + self.assertEquals("foo bar", samba.substitute_var("foo bar", {"bar": "bla"})) + + def test_replace(self): + self.assertEquals("foo bla", samba.substitute_var("foo ${bar}", {"bar": "bla"})) + + def test_broken(self): + self.assertEquals("foo ${bdkjfhsdkfh sdkfh ", + samba.substitute_var("foo ${bdkjfhsdkfh sdkfh ", {"bar": "bla"})) + + def test_unknown_var(self): + self.assertEquals("foo ${bla} gsff", + samba.substitute_var("foo ${bla} gsff", {"bar": "bla"})) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py new file mode 100644 index 0000000000..5edfe79084 --- /dev/null +++ b/source4/scripting/python/samba/tests/provision.py @@ -0,0 +1,59 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 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 . +# + +import unittest +import samba.provision + +class ProvisionTestCase(unittest.TestCase): + def test_setup_secretsdb(self): + raise NotImplementedError(self.test_setup_secretsdb) + + def test_setup_templatesdb(self): + raise NotImplementedError(self.test_setup_templatesdb) + + def test_setup_registry(self): + raise NotImplementedError(self.test_setup_registry) + + def test_setup_samdb_rootdse(self): + raise NotImplementedError(self.test_setup_samdb_rootdse) + + def test_setup_samdb_partitions(self): + raise NotImplementedError(self.test_setup_samdb_partitions) + + def test_create_phpldapadmin_config(self): + raise NotImplementedError(self.test_create_phpldapadmin_config) + + def test_provision_dns(self): + raise NotImplementedError(self.test_provision_dns) + + def test_provision_ldapbase(self): + raise NotImplementedError(self.test_provision_ldapbase) + + def test_provision_guess(self): + raise NotImplementedError(self.test_provision_guess) + + def test_join_domain(self): + raise NotImplementedError(self.test_join_domain) + + def test_vampire(self): + raise NotImplementedError(self.test_vampire) + + def test_erase_partitions(self): + raise NotImplementedError(self.test_erase_partitions) + -- cgit From 5ed08ebac3545e60ac8c553ffe8b019d7ba3f853 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Dec 2007 11:34:36 +0100 Subject: r26534: configure: using == in shell scripts isn't portable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to Björn Jacke for reporting this. metze (This used to be commit 1d5d97083029956fd1ce5eb2c0333052a46a334a) --- source4/scripting/python/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 8c4225175e..96e4da9add 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -65,7 +65,7 @@ if test -z "$PYTHON_LDFLAGS"; then py_version=`$PYTHON -c "from distutils.sysconfig import *; \ from string import join; \ print join(get_config_vars('VERSION'))"` - if test "$py_version" == "[None]"; then + if test "$py_version" = "[None]"; then if test -n "$PYTHON_VERSION"; then py_version=$PYTHON_VERSION else -- cgit From 595ec370da471116b35464dc65d2962f28380d74 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:24 +0100 Subject: r26535: Get rid of all-knowing ProvisionSettings object. (This used to be commit 40bf88c8a70e8379a6081cb6050034bcd7ae56eb) --- source4/scripting/python/samba/provision.py | 522 ++++++++++++++-------------- 1 file changed, 258 insertions(+), 264 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 04f50e8359..c9cb457b4a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1,8 +1,10 @@ # # backend code for provisioning a Samba4 server -# Copyright Andrew Tridgell 2005 -# Copyright Jelmer Vernooij 2007 # Released under the GNU GPL v2 or later +# Copyright Jelmer Vernooij 2007 +# +# Based on the original in EJS: +# Copyright Andrew Tridgell 2005 # from base64 import b64encode @@ -22,67 +24,13 @@ from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring +DEFAULTSITE = "Default-First-Site-Name" + class InvalidNetbiosName(Exception): def __init__(self, name): super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) -class ProvisionSettings(object): - def __init__(self, realm=None, domain=None, hostname=None, hostip=None): - self.realm = realm - self.domain = domain - self.hostname = hostname - self.hostip = hostip - self.domainsid = None - self.invocationid = None - self.krbtgtpass = None - self.machinepass = None - self.adminpass = None - self.defaultsite = "Default-First-Site-Name" - self.root = None - self.nobody = None - self.nogroup = None - self.wheel = None - self.backup = None - self.users = None - self.dnsdomain = None - self.dnsname = None - self.domaindn = None - self.rootdn = None - self.configdn = None - self.schemedn = None - self.schemedn_ldb = None - self.s4_ldapi_path = None - self.policyguid = None - - def fix(self, paths): - self.realm = self.realm.upper() - self.hostname = self.hostname.lower() - self.domain = self.domain.upper() - if not valid_netbios_name(self.domain): - raise InvalidNetbiosName(self.domain) - self.netbiosname = self.hostname.upper() - if not valid_netbios_name(self.netbiosname): - raise InvalidNetbiosName(self.netbiosname) - rdns = self.domaindn.split(",") - self.rdn_dc = rdns[0][len("DC="):] - - def validate(self, lp): - if not valid_netbios_name(self.domain): - raise InvalidNetbiosName(self.domain) - - if not valid_netbios_name(self.netbiosname): - raise InvalidNetbiosName(self.netbiosname) - - if lp.get("workgroup").upper() != self.domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), self.domain) - - if lp.get("realm").upper() != self.realm.upper(): - raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get("realm"), self.realm)) - - class ProvisionPaths: def __init__(self): self.smbconf = None @@ -125,11 +73,6 @@ def findnss(nssfn, *names): raise Exception("Unable to find user/group for %s" % arguments[1]) -def hostip(): - """return first host IP.""" - return gethostbyname(hostname()) - - def hostname(): """return first part of hostname.""" return gethostname().split(".")[0] @@ -210,11 +153,11 @@ def setup_file(setup_dir, template, fname, substvars): open(f, 'w').write(data) -def provision_default_paths(lp, subobj): +def provision_default_paths(lp, dnsdomain): """Set the default paths for provisioning. :param lp: Loadparm context. - :param subobj: Object + :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() private_dir = lp.get("private dir") @@ -224,14 +167,14 @@ def provision_default_paths(lp, subobj): paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns_keytab = os.path.join(private_dir, "dns.keytab") - paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") + paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.ldap_basedn_ldif = os.path.join(private_dir, - subobj.dnsdomain + ".ldif") + dnsdomain + ".ldif") paths.ldap_config_basedn_ldif = os.path.join(private_dir, - subobj.dnsdomain + "-config.ldif") + dnsdomain + "-config.ldif") paths.ldap_schema_basedn_ldif = os.path.join(private_dir, - subobj.dnsdomain + "-schema.ldif") + dnsdomain + "-schema.ldif") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") @@ -247,41 +190,39 @@ def provision_default_paths(lp, subobj): return paths -def setup_name_mappings(subobj, ldb): +def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, + wheel, backup): """setup reasonable name mappings for sam names to unix names.""" - sid = str(subobj.domainsid) - # add some foreign sids if they are not present already - ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") - ldb.add_foreign(subobj.domaindn, "S-1-1-0", "World") - ldb.add_foreign(subobj.domaindn, "S-1-5-2", "Network") - ldb.add_foreign(subobj.domaindn, "S-1-5-18", "System") - ldb.add_foreign(subobj.domaindn, "S-1-5-11", "Authenticated Users") + ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous") + ldb.add_foreign(domaindn, "S-1-1-0", "World") + ldb.add_foreign(domaindn, "S-1-5-2", "Network") + ldb.add_foreign(domaindn, "S-1-5-18", "System") + ldb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") # some well known sids - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-7", subobj.nobody) - ldb.setup_name_mapping(subobj.domaindn, "S-1-1-0", subobj.nogroup) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-2", subobj.nogroup) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-18", subobj.root) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-11", subobj.users) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-544", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-545", subobj.users) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-546", subobj.nogroup) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-551", subobj.backup) + ldb.setup_name_mapping(domaindn, "S-1-5-7", nobody) + ldb.setup_name_mapping(domaindn, "S-1-1-0", nogroup) + ldb.setup_name_mapping(domaindn, "S-1-5-2", nogroup) + ldb.setup_name_mapping(domaindn, "S-1-5-18", root) + ldb.setup_name_mapping(domaindn, "S-1-5-11", users) + ldb.setup_name_mapping(domaindn, "S-1-5-32-544", wheel) + ldb.setup_name_mapping(domaindn, "S-1-5-32-545", users) + ldb.setup_name_mapping(domaindn, "S-1-5-32-546", nogroup) + ldb.setup_name_mapping(domaindn, "S-1-5-32-551", backup) # and some well known domain rids - ldb.setup_name_mapping(subobj.domaindn, sid + "-500", subobj.root) - ldb.setup_name_mapping(subobj.domaindn, sid + "-518", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, sid + "-519", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, sid + "-512", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, sid + "-513", subobj.users) - ldb.setup_name_mapping(subobj.domaindn, sid + "-520", subobj.wheel) + ldb.setup_name_mapping(domaindn, sid + "-500", root) + ldb.setup_name_mapping(domaindn, sid + "-518", wheel) + ldb.setup_name_mapping(domaindn, sid + "-519", wheel) + ldb.setup_name_mapping(domaindn, sid + "-512", wheel) + ldb.setup_name_mapping(domaindn, sid + "-513", users) + ldb.setup_name_mapping(domaindn, sid + "-520", wheel) -def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, +def provision_become_dc(setup_dir, message, paths, lp, session_info, credentials): assert session_info is not None - subobj.fix(paths) message("Setting up templates into %s" % paths.templates) setup_templatesdb(paths.templates, setup_dir, session_info, @@ -295,8 +236,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.erase() message("Setting up %s partitions" % paths.samdb) - setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, - subobj.configdn, subobj.domaindn) + setup_samdb_partitions(samdb, setup_dir, schemadn, + configdn, domaindn) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) @@ -307,10 +248,12 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up %s rootDSE" % paths.samdb) - setup_samdb_rootdse(samdb, setup_dir, subobj) + setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + hostname, dnsdomain, realm, rootdn, configdn, + netbiosname) message("Erasing data from partitions") - ldb_erase_partitions(subobj.domaindn, message, samdb, None) + ldb_erase_partitions(domaindn, message, samdb, None) message("Setting up %s indexes" % paths.samdb) setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -323,7 +266,7 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, message("Setting up %s" % paths.secrets) secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info, credentials, lp) setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", - { "MACHINEPASS_B64": b64encode(self.machinepass) }) + { "MACHINEPASS_B64": b64encode(machinepass) }) def setup_secretsdb(path, setup_dir, session_info, credentials, lp): @@ -351,17 +294,18 @@ def setup_registry(path, setup_dir, session_info, credentials, lp): reg.apply_patchfile(provision_reg) -def setup_samdb_rootdse(samdb, setup_dir, subobj): +def setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, hostname, + dnsdomain, realm, rootdn, configdn, netbiosname): setup_add_ldif(samdb, setup_dir, "provision_rootdse_add.ldif", { - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "DNSDOMAIN": subobj.dnsdomain, - "DEFAULTSITE": subobj.defaultsite, - "REALM": subobj.realm, - "DNSNAME": subobj.dnsname, - "DOMAINDN": subobj.domaindn, - "ROOTDN": subobj.rootdn, - "CONFIGDN": subobj.configdn, + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "DNSDOMAIN": dnsdomain, + "DEFAULTSITE": DEFAULTSITE, + "REALM": realm, + "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "DOMAINDN": domaindn, + "ROOTDN": rootdn, + "CONFIGDN": configdn, "VERSION": samba.version(), }) @@ -416,25 +360,103 @@ def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): -def provision(lp, setup_dir, subobj, message, blank, paths, session_info, - credentials, ldapbackend): +def provision(lp, setup_dir, message, blank, paths, session_info, + credentials, ldapbackend, realm=None, domain=None, hostname=None, + hostip=None, domainsid=None, hostguid=None, adminpass=None, + krbtgtpass=None, domainguid=None, policyguid=None, + invocationid=None, machinepass=None, dnspass=None, root=None, + nobody=None, nogroup=None, users=None, wheel=None, backup=None, + aci=None, serverrole=None): """Provision samba4 :note: caution, this wipes all existing data! """ - subobj.fix(paths) + + if domainsid is None: + domainsid = security.random_sid() + if policyguid is None: + policyguid = uuid.random() + if invocationid is None: + invocationid = uuid.random() + if adminpass is None: + adminpass = misc.random_password(12) + if krbtgtpass is None: + krbtgtpass = misc.random_password(12) + if machinepass is None: + machinepass = misc.random_password(12) + if dnspass is None: + dnspass = misc.random_password(12) + if root is None: + root = findnss(pwd.getpwnam, "root")[4] + if nobody is None: + nobody = findnss(pwd.getpwnam, "nobody")[4] + if nogroup is None: + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + if users is None: + users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + if wheel is None: + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + if backup is None: + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + if aci is None: + aci = "# no aci for local ldb" + if serverrole is None: + serverrole = lp.get("server role") + + if realm is None: + realm = lp.get("realm") + else: + if lp.get("realm").upper() != realm.upper(): + raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + (lp.get("realm"), realm)) + + assert realm is not None + realm = realm.upper() + + if domain is None: + domain = lp.get("workgroup") + else: + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", + lp.get("workgroup"), domain) + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if hostip is None: + hostip = gethostbyname(hostname) + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + dnsdomain = realm.lower() + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + rootdn = domaindn + configdn = "CN=Configuration," + rootdn + schemadn = "CN=Schema," + configdn + + rdn_dc = domaindn.split(",")[0][len("DC="):] + + message("Provisioning for %s in realm %s" % (domain, realm)) + message("Using administrator password: %s" % adminpass) assert paths.smbconf is not None # only install a new smb.conf if there isn't one there already if not os.path.exists(paths.smbconf): message("Setting up smb.conf") - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": smbconfsuffix = "dc" - elif lp.get("server role") == "member": + elif serverrole == "member": smbconfsuffix = "member" else: - assert "Invalid server role setting: %s" % lp.get("server role") + assert "Invalid server role setting: %s" % serverrole setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf) lp.reload() @@ -463,8 +485,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.erase() message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, - subobj.configdn, subobj.domaindn) + setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -475,10 +496,12 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_dir, subobj) + setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + hostname, dnsdomain, realm, rootdn, configdn, + netbiosname) message("Erasing data from partitions") - ldb_erase_partitions(subobj.domaindn, message, samdb, ldapbackend) + ldb_erase_partitions(domaindn, message, samdb, ldapbackend) except: samdb.transaction_cancel() raise @@ -488,106 +511,104 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Pre-loading the Samba 4 and AD schema") samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - samdb.set_domain_sid(subobj.domainsid) - load_schema(setup_dir, samdb, subobj) + samdb.set_domain_sid(domainsid) + load_schema(setup_dir, samdb, schemadn, netbiosname, configdn) samdb.transaction_start() try: - message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn) + message("Adding DomainDN: %s (permitted to fail)" % domaindn) setup_add_ldif(samdb, setup_dir, "provision_basedn.ldif", { - "DOMAINDN": subobj.domaindn, - "ACI": "# no aci for local ldb", + "DOMAINDN": domaindn, + "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", - "RDN_DC": subobj.rdn_dc, + "RDN_DC": rdn_dc, }) - message("Modifying DomainDN: " + subobj.domaindn + "") - if subobj.domain_guid is not None: - domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid + message("Modifying DomainDN: " + domaindn + "") + if domainguid is not None: + domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % domainguid else: domainguid_mod = "" setup_modify_ldif(samdb, setup_dir, "provision_basedn_modify.ldif", { - "RDN_DC": subobj.rdn_dc, + "RDN_DC": rdn_dc, "LDAPTIME": timestring(int(time.time())), - "DOMAINSID": str(subobj.domainsid), - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "CONFIGDN": subobj.configdn, - "POLICYGUID": subobj.policyguid, - "DOMAINDN": subobj.domaindn, + "DOMAINSID": str(domainsid), + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": configdn, + "POLICYGUID": policyguid, + "DOMAINDN": domaindn, "DOMAINGUID_MOD": domainguid_mod, }) message("Adding configuration container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { - "CONFIGDN": subobj.configdn, - "ACI": "# no aci for local ldb", + "CONFIGDN": configdn, + "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") setup_modify_ldif(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { - "CONFIGDN": subobj.configdn, - "SCHEMADN": subobj.schemadn, + "CONFIGDN": configdn, + "SCHEMADN": schemadn, }) message("Adding schema container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { - "SCHEMADN": subobj.schemadn, - "ACI": "# no aci for local ldb", + "SCHEMADN": schemadn, + "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") setup_modify_ldif(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "CONFIGDN": subobj.configdn, + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": configdn, }) message("Setting up sam.ldb Samba4 schema") - setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", { - "SCHEMADN": subobj.schemadn, - }) + setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", + {"SCHEMADN": schemadn }) message("Setting up sam.ldb AD schema") - setup_add_ldif(samdb, setup_dir, "schema.ldif", { - "SCHEMADN": subobj.schemadn, - }) + setup_add_ldif(samdb, setup_dir, "schema.ldif", + {"SCHEMADN": schemadn}) message("Setting up sam.ldb configuration data") setup_add_ldif(samdb, setup_dir, "provision_configuration.ldif", { - "CONFIGDN": subobj.configdn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "DNSDOMAIN": subobj.dnsdomain, - "DOMAIN": subobj.domain, - "SCHEMADN": subobj.schemadn, - "DOMAINDN": subobj.domaindn, + "CONFIGDN": configdn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "DNSDOMAIN": dnsdomain, + "DOMAIN": domain, + "SCHEMADN": schemadn, + "DOMAINDN": domaindn, }) message("Setting up display specifiers") - setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": subobj.configdn}) + setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": configdn}) message("Adding users container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Modifying users container") setup_modify_ldif(samdb, setup_dir, "provision_users_modify.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Modifying computers container") setup_modify_ldif(samdb, setup_dir, "provision_computers_modify.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_dir, "provision.ldif", { - "DOMAINDN": subobj.domaindn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "CONFIGDN": subobj.configdn, + "DOMAINDN": domaindn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": configdn, }) if not blank: @@ -607,60 +628,63 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { - "DOMAINDN": subobj.domaindn, - "DOMAINSID": str(subobj.domainsid), - "CONFIGDN": subobj.configdn, - "ADMINPASS_B64": b64encode(subobj.adminpass), - "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), + "DOMAINDN": domaindn, + "DOMAINSID": str(domainsid), + "CONFIGDN": configdn, + "ADMINPASS_B64": b64encode(adminpass), + "KRBTGTPASS_B64": b64encode(krbtgtpass), }) if lp.get("server role") == "domain controller": message("Setting up self join") - if subobj.host_guid is not None: - hostguid_add = "objectGUID: %s" % subobj.host_guid + if hostguid is not None: + hostguid_add = "objectGUID: %s" % hostguid else: hostguid_add = "" setup_add_ldif(samdb, setup_dir, "provision_self_join.ldif", { - "CONFIGDN": subobj.configdn, - "SCHEMADN": subobj.schemadn, - "DOMAINDN": subobj.domaindn, - "INVOCATIONID": subobj.invocationid, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "DNSNAME": subobj.dnsname, - "MACHINEPASS_B64": b64encode(subobj.machinepass), - "DNSPASS_B64": b64encode(subobj.dnspass), - "REALM": subobj.realm, - "DOMAIN": subobj.domain, + "CONFIGDN": configdn, + "SCHEMADN": schemadn, + "DOMAINDN": domaindn, + "INVOCATIONID": invocationid, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "MACHINEPASS_B64": b64encode(machinepass), + "DNSPASS_B64": b64encode(dnspass), + "REALM": realm, + "DOMAIN": domain, "HOSTGUID_ADD": hostguid_add, - "DNSDOMAIN": subobj.dnsdomain}) + "DNSDOMAIN": dnsdomain}) setup_add_ldif(samdb, setup_dir, "provision_group_policy.ldif", { - "POLICYGUID": subobj.policyguid, - "DNSDOMAIN": subobj.dnsdomain, - "DOMAINSID": str(subobj.domainsid), - "DOMAINDN": subobj.domaindn}) - - os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}"), 0755) - os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "Machine"), 0755) - os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "User"), 0755) + "POLICYGUID": policyguid, + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "DOMAINDN": domaindn}) + + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", { - "MACHINEPASS_B64": b64encode(subobj.machinepass), - "DOMAIN": subobj.domain, - "REALM": subobj.realm, + "MACHINEPASS_B64": b64encode(machinepass), + "DOMAIN": domain, + "REALM": realm, "LDAPTIME": timestring(int(time.time())), - "DNSDOMAIN": subobj.dnsdomain, - "DOMAINSID": str(subobj.domainsid), + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), "SECRETS_KEYTAB": paths.keytab, - "NETBIOSNAME": subobj.netbiosname, + "NETBIOSNAME": netbiosname, "SAM_LDB": paths.samdb, "DNS_KEYTAB": paths.dns_keytab, - "DNSPASS_B64": b64encode(subobj.dnspass), + "DNSPASS_B64": b64encode(dnspass), }) - setup_name_mappings(subobj, samdb) + setup_name_mappings(samdb, str(domainsid), + domaindn, root=root, nobody=nobody, + nogroup=nogroup, wheel=wheel, users=users, + backup=backup) message("Setting up sam.ldb index") setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -678,113 +702,83 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + message("Setting up DNS zone: %s" % dnsdomain) + provision_dns(setup_dir, paths, session_info, credentials, lp, + hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, + domaindn=domaindn, dnspass=dnspass, realm=realm) + message("Please install the zone located in %s into your DNS server" % paths.dns) def create_phplpapdadmin_config(path, setup_dir, s4_ldapi_path): setup_file(setup_dir, "phpldapadmin-config.php", path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) -def provision_dns(setup_dir, subobj, message, paths, session_info, credentials, lp): +def provision_dns(setup_dir, paths, session_info, + credentials, lp, dnsdomain, domaindn, + hostip, hostname, dnspass, realm): """Write out a DNS zone file, from the info in the current database.""" - message("Setting up DNS zone: %s" % subobj.dnsdomain) + # connect to the sam ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database - domainguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID")) + domainguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID")) - hostguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID" , - expression="(&(objectClass=computer)(cn=%s))" % subobj.netbiosname)) + hostguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID" , + expression="(&(objectClass=computer)(cn=%s))" % hostname)) setup_file(setup_dir, "provision.zone", paths.dns, { - "DNSPASS_B64": b64encode(subobj.dnspass), - "HOSTNAME": hostname(), - "DNSDOMAIN": subobj.dnsdomain, - "REALM": subobj.realm, - "HOSTIP": hostip(), + "DNSPASS_B64": b64encode(dnspass), + "HOSTNAME": hostname, + "DNSDOMAIN": dnsdomain, + "REALM": realm, + "HOSTIP": hostip, "DOMAINGUID": domainguid, "DATESTRING": time.strftime("%Y%m%d%H"), - "DEFAULTSITE": subobj.defaultsite, + "DEFAULTSITE": DEFAULTSITE, "HOSTGUID": hostguid, }) - message("Please install the zone located in %s into your DNS server" % paths.dns) -def provision_ldapbase(setup_dir, subobj, message, paths): +def provision_ldapbase(setup_dir, message, paths): """Write out a DNS zone file, from the info in the current database.""" - message("Setting up LDAP base entry: %s" % subobj.domaindn) - rdns = subobj.domaindn.split(",") + message("Setting up LDAP base entry: %s" % domaindn) + rdns = domaindn.split(",") - subobj.rdn_dc = rdns[0][len("DC="):] + rdn_dc = rdns[0][len("DC="):] setup_file(setup_dir, "provision_basedn.ldif", - paths.ldap_basedn_ldif, - None) + paths.ldap_basedn_ldif) setup_file(setup_dir, "provision_configuration_basedn.ldif", - paths.ldap_config_basedn_ldif, None) + paths.ldap_config_basedn_ldif) setup_file(setup_dir, "provision_schema_basedn.ldif", paths.ldap_schema_basedn_ldif, { - "SCHEMADN": subobj.schemadn, + "SCHEMADN": schemadn, "ACI": "# no aci for local ldb", "EXTENSIBLEOBJECT": "objectClass: extensibleObject"}) message("Please install the LDIF located in " + paths.ldap_basedn_ldif + ", " + paths.ldap_config_basedn_ldif + " and " + paths.ldap_schema_basedn_ldif + " into your LDAP server, and re-run with --ldap-backend=ldap://my.ldap.server") -def provision_guess(lp): - """guess reasonably default options for provisioning.""" - subobj = ProvisionSettings(realm=lp.get("realm").upper(), - domain=lp.get("workgroup"), - hostname=hostname(), - hostip=hostip()) - - assert subobj.realm is not None - assert subobj.domain is not None - assert subobj.hostname is not None - - subobj.domainsid = security.random_sid() - subobj.invocationid = uuid.random() - subobj.policyguid = uuid.random() - subobj.krbtgtpass = misc.random_password(12) - subobj.machinepass = misc.random_password(12) - subobj.adminpass = misc.random_password(12) - subobj.dnspass = misc.random_password(12) - subobj.root = findnss(pwd.getpwnam, "root")[4] - subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] - subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] - subobj.wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] - subobj.backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] - subobj.users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] - - subobj.dnsdomain = subobj.realm.lower() - subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) - subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=") - subobj.rootdn = subobj.domaindn - subobj.configdn = "CN=Configuration," + subobj.rootdn - subobj.schemadn = "CN=Schema," + subobj.configdn - - return subobj - - -def load_schema(setup_dir, samdb, subobj): +def load_schema(setup_dir, samdb, schemadn, netbiosname, configdn): """Load schema.""" src = os.path.join(setup_dir, "schema.ldif") schema_data = open(src, 'r').read() src = os.path.join(setup_dir, "schema_samba4.ldif") schema_data += open(src, 'r').read() - schema_data = substitute_var(schema_data, {"SCHEMADN": subobj.schemadn}) + schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") head_data = open(src, 'r').read() head_data = substitute_var(head_data, { - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "CONFIGDN": subobj.configdn, - "DEFAULTSITE": subobj.defaultsite}) + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "CONFIGDN": configdn, + "DEFAULTSITE": DEFAULTSITE}) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 86f91db7d5c84526b3fbd4369d7a56dc0f057b4c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:31 +0100 Subject: r26536: More tests for provisioning code. (This used to be commit 43c8bfeedf06ce806c524a28fa72c643f6db60f4) --- source4/scripting/python/samba/__init__.py | 4 +++- source4/scripting/python/samba/provision.py | 6 ------ source4/scripting/python/samba/tests/__init__.py | 18 ++++++++++++++++++ source4/scripting/python/samba/tests/provision.py | 17 +++++++++++++---- source4/scripting/python/samba/upgrade.py | 18 +++++------------- 5 files changed, 39 insertions(+), 24 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 9ac283e660..d185464a58 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -92,7 +92,9 @@ class Ldb(ldb.Ldb): res = self.search(basedn, scope, expression, [attribute]) if len(res) != 1 or res[0][attribute] is None: return None - return res[0][attribute] + values = set(res[0][attribute]) + assert len(values) == 1 + return values.pop() def erase(self): """Erase an ldb, removing all records.""" diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c9cb457b4a..f3fc138e6b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -73,11 +73,6 @@ def findnss(nssfn, *names): raise Exception("Unable to find user/group for %s" % arguments[1]) -def hostname(): - """return first part of hostname.""" - return gethostname().split(".")[0] - - def open_ldb(session_info, credentials, lp, dbname): assert session_info is not None try: @@ -742,7 +737,6 @@ def provision_dns(setup_dir, paths, session_info, }) - def provision_ldapbase(setup_dir, message, paths): """Write out a DNS zone file, from the info in the current database.""" message("Setting up LDAP base entry: %s" % domaindn) diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index 0808469907..45588ecb5a 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -20,6 +20,7 @@ import os import ldb import samba +import tempfile import unittest class LdbTestCase(unittest.TestCase): @@ -35,6 +36,15 @@ class LdbTestCase(unittest.TestCase): self.ldb = samba.Ldb(self.filename) +class TestCaseInTempDir(unittest.TestCase): + def setUp(self): + super(TestCaseInTempDir, self).setUp() + self.tempdir = tempfile.mkdtemp() + + def tearDown(self): + super(TestCaseInTempDir, self).tearDown() + + class SubstituteVarTestCase(unittest.TestCase): def test_empty(self): self.assertEquals("", samba.substitute_var("", {})) @@ -52,3 +62,11 @@ class SubstituteVarTestCase(unittest.TestCase): def test_unknown_var(self): self.assertEquals("foo ${bla} gsff", samba.substitute_var("foo ${bla} gsff", {"bar": "bla"})) + + +class LdbExtensionTests(TestCaseInTempDir): + def test_searchone(self): + l = samba.Ldb(self.tempdir + "/searchone.ldb") + l.add({"dn": ldb.Dn(l, "foo=dc"), "bar": "bla"}) + self.assertEquals("bla", l.searchone(ldb.Dn(l, "foo=dc"), "bar")) + diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 5edfe79084..c8bd99283b 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -17,13 +17,22 @@ # along with this program. If not, see . # -import unittest -import samba.provision +import os +from samba.provision import setup_secretsdb +import samba.tests +from ldb import Dn -class ProvisionTestCase(unittest.TestCase): +setup_dir = "setup" + +class ProvisionTestCase(samba.tests.TestCaseInTempDir): def test_setup_secretsdb(self): - raise NotImplementedError(self.test_setup_secretsdb) + ldb = setup_secretsdb(os.path.join(self.tempdir, "secrets.ldb"), + setup_dir, None, None, None) + self.assertEquals("LSA Secrets", + ldb.searchone(Dn(ldb, "CN=LSA Secrets"), "CN")) + +class Disabled: def test_setup_templatesdb(self): raise NotImplementedError(self.test_setup_templatesdb) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 783cc008d5..4521d4604d 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -14,7 +14,10 @@ import pwd import uuid def regkey_to_dn(name): - """Convert a registry key to a DN.""" + """Convert a registry key to a DN. + + :name: The registry key name. + :return: A matching DN.""" dn = "hive=NONE" if name == "": @@ -253,8 +256,6 @@ maxVersion: %llu return ldif def upgrade_provision(lp, samba3): - subobj = Object() - domainname = samba3.configuration.get("workgroup") if domainname is None: @@ -272,13 +273,7 @@ def upgrade_provision(lp, samba3): subobj.realm = realm subobj.domain = domainname - subobj.hostname = hostname() - assert subobj.realm is not None - assert subobj.domain is not None - assert subobj.hostname is not None - - subobj.HOSTIP = hostip() if domsec is not None: subobj.DOMAINGUID = domsec.guid subobj.DOMAINSID = domsec.sid @@ -288,10 +283,7 @@ def upgrade_provision(lp, samba3): subobj.DOMAINSID = randsid() if hostsec: - subobj.HOSTGUID = hostsec.guid - else: - subobj.HOSTGUID = uuid.random() - subobj.invocationid = uuid.random() + hostguid = hostsec.guid subobj.krbtgtpass = randpass(12) subobj.machinepass = randpass(12) subobj.adminpass = randpass(12) -- cgit From c2fffa8335ac68ff70de52f9fc80fb49e5d6d686 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:38 +0100 Subject: r26538: Pass path generation function around rather than base directory. (This used to be commit 5f921af41e4dcd6844f6a662d56bd27c4e76ff88) --- source4/scripting/python/samba/__init__.py | 41 +++- source4/scripting/python/samba/provision.py | 256 ++++++++++------------ source4/scripting/python/samba/samdb.py | 4 +- source4/scripting/python/samba/tests/__init__.py | 2 +- source4/scripting/python/samba/tests/provision.py | 5 +- source4/scripting/python/samba/upgrade.py | 4 +- 6 files changed, 164 insertions(+), 148 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index d185464a58..2c46f72883 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -87,7 +87,8 @@ class Ldb(ldb.Ldb): set_session_info = misc.ldb_set_session_info set_loadparm = misc.ldb_set_loadparm - def searchone(self, basedn, attribute, expression=None, scope=ldb.SCOPE_BASE): + def searchone(self, basedn, attribute, expression=None, + scope=ldb.SCOPE_BASE): """Search for one attribute as a string.""" res = self.search(basedn, scope, expression, [attribute]) if len(res) != 1 or res[0][attribute] is None: @@ -112,11 +113,47 @@ class Ldb(ldb.Ldb): for msg in self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]): - self.delete(msg.dn) + try: + self.delete(msg.dn) + except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): + # Ignor eno such object errors + pass res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) assert len(res) == 0 + def erase_partitions(self): + """Erase an ldb, removing all records.""" + res = self.search(ldb.Dn(self, ""), ldb.SCOPE_BASE, "(objectClass=*)", + ["namingContexts"]) + assert len(res) == 1 + if not "namingContexts" in res[0]: + return + for basedn in res[0]["namingContexts"]: + previous_remaining = 1 + current_remaining = 0 + + k = 0 + while ++k < 10 and (previous_remaining != current_remaining): + # and the rest + res2 = self.search(ldb.Dn(self, basedn), ldb.SCOPE_SUBTREE, "(|(objectclass=*)(dn=*))", ["dn"]) + previous_remaining = current_remaining + current_remaining = len(res2) + for msg in res2: + self.delete(msg.dn) + + def load_ldif_file_add(self, ldif_path): + """Load a LDIF file. + + :param ldif_path: Path to LDIF file. + """ + self.load_ldif_add(open(ldif_path, 'r').read()) + + def load_ldif_add(self, ldif): + for changetype, msg in self.parse_ldif(ldif): + assert changetype == ldb.CHANGETYPE_NONE + self.add(msg) + def substitute_var(text, values): """substitute strings of the form ${NAME} in str, replacing diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f3fc138e6b..90f7cd0697 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -21,7 +21,7 @@ from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB import security from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ - LDB_ERR_NO_SUCH_OBJECT, timestring + LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE DEFAULTSITE = "Default-First-Site-Name" @@ -58,7 +58,7 @@ def install_ok(lp, session_info, credentials): return False ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) - if len(ldb.search("(cn=Administrator)")) != 1: + if len(ldb.search(ldb.Dn("(cn=Administrator)"))) != 1: return False return True @@ -85,62 +85,56 @@ def open_ldb(session_info, credentials, lp, dbname): lp=lp) -def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): +def setup_add_ldif(ldb, ldif_path, subst_vars=None): """Setup a ldb in the private dir.""" - assert isinstance(ldif, str) - assert isinstance(setup_dir, str) - src = os.path.join(setup_dir, ldif) + assert isinstance(ldif_path, str) - data = open(src, 'r').read() + data = open(ldif_path, 'r').read() if subst_vars is not None: data = substitute_var(data, subst_vars) assert "${" not in data - for msg in ldb.parse_ldif(data): - ldb.add(msg[1]) + ldb.load_ldif_add(data) -def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): +def setup_modify_ldif(ldb, ldif_path, substvars=None): """Modify a ldb in the private dir. :param ldb: LDB object. - :param setup_dir: Setup directory. - :param ldif: LDIF file path. + :param ldif_path: LDIF file path. :param substvars: Optional dictionary with substitution variables. """ - src = os.path.join(setup_dir, ldif) - - data = open(src, 'r').read() + data = open(ldif_path, 'r').read() if substvars is not None: data = substitute_var(data, substvars) assert "${" not in data for (changetype, msg) in ldb.parse_ldif(data): + assert changetype == CHANGETYPE_MODIFY ldb.modify(msg) -def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): +def setup_ldb(ldb, ldif_path, subst_vars): assert ldb is not None ldb.transaction_start() try: - setup_add_ldif(ldb, setup_dir, ldif, subst_vars) + setup_add_ldif(ldb, ldif_path, subst_vars) except: ldb.transaction_cancel() raise ldb.transaction_commit() -def setup_file(setup_dir, template, fname, substvars): +def setup_file(template, fname, substvars): """Setup a file in the private dir.""" f = fname - src = os.path.join(setup_dir, template) if os.path.exists(f): os.unlink(f) - data = open(src, 'r').read() + data = open(template, 'r').read() if substvars: data = substitute_var(data, substvars) assert not "${" in data @@ -218,40 +212,44 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, def provision_become_dc(setup_dir, message, paths, lp, session_info, credentials): assert session_info is not None + erase = False + + def setup_path(file): + return os.path.join(setup_dir, file) + os.path.unlink(paths.samdb) - message("Setting up templates into %s" % paths.templates) - setup_templatesdb(paths.templates, setup_dir, session_info, + message("Setting up templates db") + setup_templatesdb(paths.templates, setup_path, session_info, credentials, lp) # Also wipes the database - message("Setting up samdb") - os.path.unlink(paths.samdb) + message("Setting up sam.ldb") samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) - samdb.erase() - message("Setting up %s partitions" % paths.samdb) - setup_samdb_partitions(samdb, setup_dir, schemadn, - configdn, domaindn) + message("Setting up sam.ldb partitions") + setup_samdb_partitions(samdb, setup_path, schemadn, + configdn, domaindn) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) ldb.transaction_start() try: - message("Setting up %s attributes" % paths.samdb) - setup_add_ldif(samdb, setup_dir, "provision_init.ldif") + message("Setting up sam.ldb attributes") + samdb.load_ldif_file_add(setup_path("provision_init.ldif")) - message("Setting up %s rootDSE" % paths.samdb) - setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + message("Setting up sam.ldb rootDSE") + setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname) - message("Erasing data from partitions") - ldb_erase_partitions(domaindn, message, samdb, None) + if erase: + message("Erasing data from partitions") + samdb.erase_partitions() - message("Setting up %s indexes" % paths.samdb) - setup_add_ldif(samdb, setup_dir, "provision_index.ldif") + message("Setting up sam.ldb indexes") + samdb.load_ldif_file_add(setup_path("provision_index.ldif")) except: samdb.transaction_cancel() raise @@ -259,39 +257,39 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info, credentials, lp) - setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, credentials, lp) + setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass) }) -def setup_secretsdb(path, setup_dir, session_info, credentials, lp): +def setup_secretsdb(path, setup_path, session_info, credentials, lp): secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) secrets_ldb.erase() - setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif") - setup_ldb(secrets_ldb, setup_dir, "secrets.ldif") + secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) + secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) return secrets_ldb -def setup_templatesdb(path, setup_dir, session_info, credentials, lp): - templates_ldb = Ldb(path, session_info=session_info, +def setup_templatesdb(path, setup_path, session_info, credentials, lp): + templates_ldb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) templates_ldb.erase() - setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", None) + templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif")) -def setup_registry(path, setup_dir, session_info, credentials, lp): +def setup_registry(path, setup_path, session_info, credentials, lp): reg = registry.Registry() hive = registry.Hive(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") - provision_reg = os.path.join(setup_dir, "provision.reg") + provision_reg = setup_path("provision.reg") assert os.path.exists(provision_reg) reg.apply_patchfile(provision_reg) -def setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, hostname, +def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname): - setup_add_ldif(samdb, setup_dir, "provision_rootdse_add.ldif", { + setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DNSDOMAIN": dnsdomain, @@ -305,7 +303,7 @@ def setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, hostname, }) -def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): +def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): #Add modules to the list to activate them by default #beware often order is important # @@ -335,7 +333,7 @@ def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): modules_list2 = ["show_deleted", "partition"] - setup_ldb(samdb, setup_dir, "provision_partitions.ldif", { + setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { "SCHEMADN": schemadn, "SCHEMADN_LDB": "schema.ldb", "SCHEMADN_MOD2": ",objectguid", @@ -367,6 +365,11 @@ def provision(lp, setup_dir, message, blank, paths, session_info, :note: caution, this wipes all existing data! """ + def setup_path(file): + return os.path.join(setup_dir, file) + + erase = False + if domainsid is None: domainsid = security.random_sid() if policyguid is None: @@ -438,6 +441,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, rdn_dc = domaindn.split(",")[0][len("DC="):] + message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) @@ -452,7 +456,14 @@ def provision(lp, setup_dir, message, blank, paths, session_info, smbconfsuffix = "member" else: assert "Invalid server role setting: %s" % serverrole - setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf) + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { + "HOSTNAME": hostname, + "DOMAIN_CONF": domain, + "REALM_CONF": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": paths.netlogon, + "SYSVOLPATH": paths.sysvol, + }) lp.reload() # only install a new shares config db if there is none @@ -460,27 +471,26 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Setting up share.ldb") share_ldb = Ldb(paths.shareconf, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(share_ldb, setup_dir, "share.ldif") + share_ldb.load_ldif_file_add(setup_path("share.ldif")) - message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, + message("Setting up secrets.ldb") + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info=session_info, credentials=credentials, lp=lp) - message("Setting up registry") + message("Setting up the registry") # FIXME: Still fails for some reason - #setup_registry(paths.hklm, setup_dir, session_info, + #setup_registry(paths.hklm, setup_path, session_info, # credentials=credentials, lp=lp) - message("Setting up templates into %s" % paths.templates) - setup_templatesdb(paths.templates, setup_dir, session_info=session_info, + message("Setting up templates db") + setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - samdb.erase() message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn) + setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -488,15 +498,16 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb.transaction_start() try: message("Setting up sam.ldb attributes") - setup_add_ldif(samdb, setup_dir, "provision_init.ldif") + samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname) - message("Erasing data from partitions") - ldb_erase_partitions(domaindn, message, samdb, ldapbackend) + if erase: + message("Erasing data from partitions") + samdb.erase_partitions() except: samdb.transaction_cancel() raise @@ -507,13 +518,13 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) - load_schema(setup_dir, samdb, schemadn, netbiosname, configdn) + load_schema(setup_path, samdb, schemadn, netbiosname, configdn) samdb.transaction_start() try: message("Adding DomainDN: %s (permitted to fail)" % domaindn) - setup_add_ldif(samdb, setup_dir, "provision_basedn.ldif", { + setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": domaindn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", @@ -526,7 +537,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, else: domainguid_mod = "" - setup_modify_ldif(samdb, setup_dir, "provision_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), { "RDN_DC": rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(domainsid), @@ -540,25 +551,25 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) message("Adding configuration container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { + setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), { "CONFIGDN": configdn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") - setup_modify_ldif(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), { "CONFIGDN": configdn, "SCHEMADN": schemadn, }) message("Adding schema container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { + setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), { "SCHEMADN": schemadn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_modify_ldif(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -566,14 +577,14 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) message("Setting up sam.ldb Samba4 schema") - setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", + setup_add_ldif(samdb, setup_path("schema_samba4.ldif"), {"SCHEMADN": schemadn }) message("Setting up sam.ldb AD schema") - setup_add_ldif(samdb, setup_dir, "schema.ldif", + setup_add_ldif(samdb, setup_path("schema.ldif"), {"SCHEMADN": schemadn}) message("Setting up sam.ldb configuration data") - setup_add_ldif(samdb, setup_dir, "provision_configuration.ldif", { + setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { "CONFIGDN": configdn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -584,22 +595,23 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) message("Setting up display specifiers") - setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": configdn}) + setup_add_ldif(samdb, setup_path("display_specifiers.ldif"), + {"CONFIGDN": configdn}) message("Adding users container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { + setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), { "DOMAINDN": domaindn}) message("Modifying users container") - setup_modify_ldif(samdb, setup_dir, "provision_users_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), { "DOMAINDN": domaindn}) message("Adding computers container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { + setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), { "DOMAINDN": domaindn}) message("Modifying computers container") - setup_modify_ldif(samdb, setup_dir, "provision_computers_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_computers_modify.ldif"), { "DOMAINDN": domaindn}) message("Setting up sam.ldb data") - setup_add_ldif(samdb, setup_dir, "provision.ldif", { + setup_add_ldif(samdb, setup_path("provision.ldif"), { "DOMAINDN": domaindn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -622,7 +634,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, # samdb = open_ldb(info, paths.samdb, False) # message("Setting up sam.ldb users and groups") - setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { + setup_add_ldif(samdb, setup_path("provision_users.ldif"), { "DOMAINDN": domaindn, "DOMAINSID": str(domainsid), "CONFIGDN": configdn, @@ -637,7 +649,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, else: hostguid_add = "" - setup_add_ldif(samdb, setup_dir, "provision_self_join.ldif", { + setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": configdn, "SCHEMADN": schemadn, "DOMAINDN": domaindn, @@ -651,7 +663,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "DOMAIN": domain, "HOSTGUID_ADD": hostguid_add, "DNSDOMAIN": dnsdomain}) - setup_add_ldif(samdb, setup_dir, "provision_group_policy.ldif", { + setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { "POLICYGUID": policyguid, "DNSDOMAIN": dnsdomain, "DOMAINSID": str(domainsid), @@ -662,7 +674,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) - setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", { + setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass), "DOMAIN": domain, "REALM": realm, @@ -682,10 +694,10 @@ def provision(lp, setup_dir, message, blank, paths, session_info, backup=backup) message("Setting up sam.ldb index") - setup_add_ldif(samdb, setup_dir, "provision_index.ldif") + samdb.load_ldif_file_add(setup_path("provision_index.ldif")) message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") + setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) except: samdb.transaction_cancel() raise @@ -693,38 +705,33 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb.transaction_commit() message("Setting up phpLDAPadmin configuration") - create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, paths.s4_ldapi_path) + create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) message("Setting up DNS zone: %s" % dnsdomain) - provision_dns(setup_dir, paths, session_info, credentials, lp, + create_zone_file(paths.dns, setup_path, samdb, hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, domaindn=domaindn, dnspass=dnspass, realm=realm) message("Please install the zone located in %s into your DNS server" % paths.dns) -def create_phplpapdadmin_config(path, setup_dir, s4_ldapi_path): - setup_file(setup_dir, "phpldapadmin-config.php", +def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): + setup_file(setup_path("phpldapadmin-config.php"), path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) -def provision_dns(setup_dir, paths, session_info, - credentials, lp, dnsdomain, domaindn, +def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip, hostname, dnspass, realm): """Write out a DNS zone file, from the info in the current database.""" # connect to the sam - ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, - lp=lp) - # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database - domainguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID")) + domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID" , + expression="(&(objectClass=computer)(cn=%s))" % hostname) - hostguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID" , - expression="(&(objectClass=computer)(cn=%s))" % hostname)) - - setup_file(setup_dir, "provision.zone", paths.dns, { + setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, "DNSDOMAIN": dnsdomain, @@ -744,13 +751,16 @@ def provision_ldapbase(setup_dir, message, paths): rdn_dc = rdns[0][len("DC="):] - setup_file(setup_dir, "provision_basedn.ldif", + def setup_path(file): + return os.path.join(setup_dir, file) + + setup_file(setup_path("provision_basedn.ldif"), paths.ldap_basedn_ldif) - setup_file(setup_dir, "provision_configuration_basedn.ldif", + setup_file(setup_path("provision_configuration_basedn.ldif"), paths.ldap_config_basedn_ldif) - setup_file(setup_dir, "provision_schema_basedn.ldif", + setup_file(setup_path("provision_schema_basedn.ldif"), paths.ldap_schema_basedn_ldif, { "SCHEMADN": schemadn, "ACI": "# no aci for local ldb", @@ -759,15 +769,12 @@ def provision_ldapbase(setup_dir, message, paths): message("Please install the LDIF located in " + paths.ldap_basedn_ldif + ", " + paths.ldap_config_basedn_ldif + " and " + paths.ldap_schema_basedn_ldif + " into your LDAP server, and re-run with --ldap-backend=ldap://my.ldap.server") -def load_schema(setup_dir, samdb, schemadn, netbiosname, configdn): +def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): """Load schema.""" - src = os.path.join(setup_dir, "schema.ldif") - schema_data = open(src, 'r').read() - src = os.path.join(setup_dir, "schema_samba4.ldif") - schema_data += open(src, 'r').read() + schema_data = open(setup_path("schema.ldif"), 'r').read() + schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) - src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") - head_data = open(src, 'r').read() + head_data = open(setup_path("provision_schema_basedn_modify.ldif"), 'r').read() head_data = substitute_var(head_data, { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, @@ -803,33 +810,4 @@ def vampire(domain, session_info, credentials, message): raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) -def ldb_erase_partitions(domaindn, message, ldb, ldapbackend): - """Erase an ldb, removing all records.""" - assert ldb is not None - res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", - ["namingContexts"]) - assert len(res) == 1 - if not "namingContexts" in res[0]: - return - for basedn in res[0]["namingContexts"]: - anything = "(|(objectclass=*)(dn=*))" - previous_remaining = 1 - current_remaining = 0 - - if ldapbackend and (basedn == domaindn): - # Only delete objects that were created by provision - anything = "(objectcategory=*)" - - k = 0 - while ++k < 10 and (previous_remaining != current_remaining): - # and the rest - res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) - previous_remaining = current_remaining - current_remaining = len(res2) - for msg in res2: - try: - ldb.delete(msg.dn) - except LdbError, (_, text): - message("Unable to delete %s: %s" % (msg.dn, text)) - diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 7061e22ce4..84b604dbc4 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -29,8 +29,8 @@ class SamDB(samba.Ldb): modules_dir=None, lp=None): super(SamDB, self).__init__(session_info=session_info, credentials=credentials, modules_dir=modules_dir, lp=lp) - misc.dsdb_set_global_schema(self) - misc.ldb_register_samba_handlers(self) + assert misc.dsdb_set_global_schema(self) == 0 + assert misc.ldb_register_samba_handlers(self) == 0 if url: self.connect(url) diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index 45588ecb5a..e213c1cc1f 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -67,6 +67,6 @@ class SubstituteVarTestCase(unittest.TestCase): class LdbExtensionTests(TestCaseInTempDir): def test_searchone(self): l = samba.Ldb(self.tempdir + "/searchone.ldb") - l.add({"dn": ldb.Dn(l, "foo=dc"), "bar": "bla"}) + l.add({"dn": "foo=dc", "bar": "bla"}) self.assertEquals("bla", l.searchone(ldb.Dn(l, "foo=dc"), "bar")) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index c8bd99283b..bf7182dbd3 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -23,11 +23,14 @@ import samba.tests from ldb import Dn setup_dir = "setup" +def setup_path(file): + return os.path.join(setup_dir, file) + class ProvisionTestCase(samba.tests.TestCaseInTempDir): def test_setup_secretsdb(self): ldb = setup_secretsdb(os.path.join(self.tempdir, "secrets.ldb"), - setup_dir, None, None, None) + setup_path, None, None, None) self.assertEquals("LSA Secrets", ldb.searchone(Dn(ldb, "CN=LSA Secrets"), "CN")) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 4521d4604d..1c27f8ec25 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -537,9 +537,7 @@ replace: @LIST @LIST: samldb,operational,objectguid,rdn_name,samba3sam """) - samdb.add(""" -dn: @MAP=samba3sam -@MAP_URL: %s""" % ldapurl) + samdb.add({"dn": "@MAP=samba3sam", "@MAP_URL": ldapurl}) return ret -- cgit From 109a903750e6bec865e402f02c5c457250594e55 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Dec 2007 15:53:56 +0100 Subject: r26545: Sync output with ejs. (This used to be commit 48ceaa964327ed7094275780cc3c0767636bcb18) --- source4/scripting/python/samba/__init__.py | 2 + source4/scripting/python/samba/provision.py | 65 +++++++++++++---------------- source4/scripting/python/samba/samdb.py | 1 - 3 files changed, 32 insertions(+), 36 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 2c46f72883..c735361353 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -72,6 +72,8 @@ class Ldb(ldb.Ldb): if session_info is not None: self.set_session_info(self, session_info) + assert misc.ldb_register_samba_handlers(self) == 0 + if lp is not None: self.set_loadparm(self, lp) diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 90f7cd0697..a4a9e7ac46 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -219,20 +219,19 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, os.path.unlink(paths.samdb) message("Setting up templates db") - setup_templatesdb(paths.templates, setup_path, session_info, - credentials, lp) + setup_templatesdb(paths.templates, setup_path, session_info=session_info, + credentials=credentials, lp=lp) # Also wipes the database message("Setting up sam.ldb") - samdb = SamDB(paths.samdb, credentials=credentials, - session_info=session_info, lp=lp) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_path, schemadn, - configdn, domaindn) + setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) - samdb = SamDB(paths.samdb, credentials=credentials, - session_info=session_info, lp=lp) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) ldb.transaction_start() try: @@ -257,12 +256,15 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, credentials, lp) + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, + credentials, lp) setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass) }) def setup_secretsdb(path, setup_path, session_info, credentials, lp): + if os.path.exists(path): + os.unlink(path) secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) @@ -474,8 +476,9 @@ def provision(lp, setup_dir, message, blank, paths, session_info, share_ldb.load_ldif_file_add(setup_path("share.ldif")) message("Setting up secrets.ldb") - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info=session_info, - credentials=credentials, lp=lp) + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, + session_info=session_info, + credentials=credentials, lp=lp) message("Setting up the registry") # FIXME: Still fails for some reason @@ -486,6 +489,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) + # Also wipes the database + message("Setting up sam.ldb") samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -619,20 +624,6 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) if not blank: - - # message("Activate schema module") - # setup_modify_ldif("schema_activation.ldif", info, samdb, False) - # - # // (hack) Reload, now we have the schema loaded. - # commit_ok = samdb.transaction_commit() - # if (!commit_ok) { - # message("samdb commit failed: " + samdb.errstring() + "\n") - # assert(commit_ok) - # } - # samdb.close() - # - # samdb = open_ldb(info, paths.samdb, False) - # message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_path("provision_users.ldif"), { "DOMAINDN": domaindn, @@ -696,7 +687,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) - message("Setting up sam.ldb rootDSE marking as syncronized") + message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) except: samdb.transaction_cancel() @@ -709,10 +700,21 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) + + domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + assert isinstance(domainguid, str) + hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", + expression="(&(objectClass=computer)(cn=%s))" % hostname, + scope=SCOPE_SUBTREE) + assert isinstance(hostguid, str) + message("Setting up DNS zone: %s" % dnsdomain) create_zone_file(paths.dns, setup_path, samdb, hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm) + domaindn=domaindn, dnspass=dnspass, realm=realm, + domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): @@ -721,16 +723,9 @@ def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, - hostip, hostname, dnspass, realm): + hostip, hostname, dnspass, realm, domainguid, hostguid): """Write out a DNS zone file, from the info in the current database.""" - # connect to the sam - # These values may have changed, due to an incoming SamSync, - # or may not have been specified, so fetch them from the database - domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") - hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID" , - expression="(&(objectClass=computer)(cn=%s))" % hostname) - setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 84b604dbc4..46707f060f 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -30,7 +30,6 @@ class SamDB(samba.Ldb): super(SamDB, self).__init__(session_info=session_info, credentials=credentials, modules_dir=modules_dir, lp=lp) assert misc.dsdb_set_global_schema(self) == 0 - assert misc.ldb_register_samba_handlers(self) == 0 if url: self.connect(url) -- cgit From 758be0eedc8c0a780405a767970417f2c88dde27 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Dec 2007 00:36:17 -0600 Subject: r26555: Use python-config utility to find python compile/link flags. (This used to be commit 6cc5e838e6c411ce74e7abde685720aa1f3cbdfb) --- source4/scripting/python/config.m4 | 110 +++---------------------------------- 1 file changed, 8 insertions(+), 102 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 96e4da9add..8951b4da08 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -13,112 +13,18 @@ if test -z "$PYTHON"; then AC_MSG_WARN([No python found]) fi -# -# Check for a version of Python >= 2.1.0 -# -AC_MSG_CHECKING([for a version of Python >= '2.1.0']) -ac_supports_python_ver=`$PYTHON -c "import sys, string; \ - ver = string.split(sys.version)[[0]]; \ - print ver >= '2.1.0'"` -if test "$ac_supports_python_ver" != "True"; then +AC_PATH_PROG([PYTHON_CONFIG],[python[$PYTHON_VERSION]-config]) +if test -z "$PYTHON_CONFIG"; then working_python=no - AC_MSG_RESULT([no]) -else - AC_MSG_RESULT([yes]) -fi - -# -# Check if you have distutils, else fail -# -AC_MSG_CHECKING([for the distutils Python package]) -ac_distutils_result=`$PYTHON -c "import distutils" 2>&1` -if test -z "$ac_distutils_result"; then - AC_MSG_RESULT([yes]) - working_python=yes + AC_MSG_WARN([No python-config found]) else - AC_MSG_RESULT([no]) - working_python=no -fi - -# -# Check for Python include path -# -AC_MSG_CHECKING([for Python include path]) -if test -z "$PYTHON_CPPFLAGS"; then - python_path=`$PYTHON -c "import distutils.sysconfig; \ - print distutils.sysconfig.get_python_inc();"` - if test -n "${python_path}"; then - python_path="-I$python_path" - fi - PYTHON_CPPFLAGS=$python_path -fi -AC_MSG_RESULT([$PYTHON_CPPFLAGS]) -AC_SUBST([PYTHON_CPPFLAGS]) - -# -# Check for Python library path -# -AC_MSG_CHECKING([for Python library path]) -if test -z "$PYTHON_LDFLAGS"; then - # (makes two attempts to ensure we've got a version number - # from the interpreter) - py_version=`$PYTHON -c "from distutils.sysconfig import *; \ - from string import join; \ - print join(get_config_vars('VERSION'))"` - if test "$py_version" = "[None]"; then - if test -n "$PYTHON_VERSION"; then - py_version=$PYTHON_VERSION - else - py_version=`$PYTHON -c "import sys; \ - print sys.version[[:3]]"` - fi - fi - - PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \ - from string import join; \ - print '-L' + get_python_lib(0,1), \ - '-lpython';"`$py_version -fi -AC_MSG_RESULT([$PYTHON_LDFLAGS]) -AC_SUBST([PYTHON_LDFLAGS]) - -# -# Check for site packages -# -AC_MSG_CHECKING([for Python site-packages path]) -if test -z "$PYTHON_SITE_PKG"; then - PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \ - print distutils.sysconfig.get_python_lib(0,0);"` -fi -AC_MSG_RESULT([$PYTHON_SITE_PKG]) -AC_SUBST([PYTHON_SITE_PKG]) - -# -# libraries which must be linked in when embedding -# -AC_MSG_CHECKING(python extra libraries) -if test -z "$PYTHON_EXTRA_LIBS"; then - PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \ - conf = distutils.sysconfig.get_config_var; \ - print conf('LOCALMODLIBS'), conf('LIBS')"` -fi -AC_MSG_RESULT([$PYTHON_EXTRA_LIBS]) -AC_SUBST(PYTHON_EXTRA_LIBS) - -# -# linking flags needed when embedding -# -AC_MSG_CHECKING(python extra linking flags) -if test -z "$PYTHON_EXTRA_LDFLAGS"; then - PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \ - conf = distutils.sysconfig.get_config_var; \ - print conf('LINKFORSHARED')"` + working_python=yes fi -AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS]) -AC_SUBST(PYTHON_EXTRA_LDFLAGS) -SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CPPFLAGS]) +PYTHON_LDFLAGS=`$PYTHON_CONFIG --ldflags` +PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags` +SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) AC_MSG_CHECKING(working python module support) if test x$working_python = xyes @@ -126,7 +32,7 @@ then ac_save_LIBS="$LIBS" ac_save_CFLAGS="$CFLAGS" LIBS="$LIBS $PYTHON_LDFLAGS" - CFLAGS="$CFLAGS $PYTHON_CPPFLAGS" + CFLAGS="$CFLAGS $PYTHON_CFLAGS" AC_TRY_LINK([ #include -- cgit From 30ce895e0c75c50bbe510b6a3685c7e1f217b919 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 00:47:36 -0600 Subject: r26559: Make the provision function a bit smaller. (This used to be commit a1175231a58c60f32574816643dafc78ff867161) --- source4/scripting/python/samba/provision.py | 346 +++++++++++++++------------- 1 file changed, 182 insertions(+), 164 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a4a9e7ac46..f516e73893 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -354,150 +354,21 @@ def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): }) - -def provision(lp, setup_dir, message, blank, paths, session_info, - credentials, ldapbackend, realm=None, domain=None, hostname=None, - hostip=None, domainsid=None, hostguid=None, adminpass=None, - krbtgtpass=None, domainguid=None, policyguid=None, - invocationid=None, machinepass=None, dnspass=None, root=None, - nobody=None, nogroup=None, users=None, wheel=None, backup=None, - aci=None, serverrole=None): - """Provision samba4 - - :note: caution, this wipes all existing data! - """ - - def setup_path(file): - return os.path.join(setup_dir, file) - - erase = False - - if domainsid is None: - domainsid = security.random_sid() - if policyguid is None: - policyguid = uuid.random() - if invocationid is None: - invocationid = uuid.random() - if adminpass is None: - adminpass = misc.random_password(12) - if krbtgtpass is None: - krbtgtpass = misc.random_password(12) - if machinepass is None: - machinepass = misc.random_password(12) - if dnspass is None: - dnspass = misc.random_password(12) - if root is None: - root = findnss(pwd.getpwnam, "root")[4] - if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[4] - if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] - if users is None: - users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] - if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] - if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] - if aci is None: - aci = "# no aci for local ldb" - if serverrole is None: - serverrole = lp.get("server role") - - if realm is None: - realm = lp.get("realm") - else: - if lp.get("realm").upper() != realm.upper(): - raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get("realm"), realm)) - - assert realm is not None - realm = realm.upper() - - if domain is None: - domain = lp.get("workgroup") - else: - if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), domain) - - assert domain is not None - domain = domain.upper() - if not valid_netbios_name(domain): - raise InvalidNetbiosName(domain) - - if hostname is None: - hostname = gethostname().split(".")[0].lower() - - if hostip is None: - hostip = gethostbyname(hostname) - - netbiosname = hostname.upper() - if not valid_netbios_name(netbiosname): - raise InvalidNetbiosName(netbiosname) - - dnsdomain = realm.lower() - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") - rootdn = domaindn - configdn = "CN=Configuration," + rootdn - schemadn = "CN=Schema," + configdn - - rdn_dc = domaindn.split(",")[0][len("DC="):] - - message("set DOMAIN SID: %s" % str(domainsid)) - message("Provisioning for %s in realm %s" % (domain, realm)) - message("Using administrator password: %s" % adminpass) - - assert paths.smbconf is not None - - # only install a new smb.conf if there isn't one there already - if not os.path.exists(paths.smbconf): - message("Setting up smb.conf") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member": - smbconfsuffix = "member" - else: - assert "Invalid server role setting: %s" % serverrole - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { - "HOSTNAME": hostname, - "DOMAIN_CONF": domain, - "REALM_CONF": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": paths.netlogon, - "SYSVOLPATH": paths.sysvol, - }) - lp.reload() - - # only install a new shares config db if there is none - if not os.path.exists(paths.shareconf): - message("Setting up share.ldb") - share_ldb = Ldb(paths.shareconf, session_info=session_info, - credentials=credentials, lp=lp) - share_ldb.load_ldif_file_add(setup_path("share.ldif")) - - message("Setting up secrets.ldb") - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, - session_info=session_info, - credentials=credentials, lp=lp) - - message("Setting up the registry") - # FIXME: Still fails for some reason - #setup_registry(paths.hklm, setup_path, session_info, - # credentials=credentials, lp=lp) - - message("Setting up templates db") - setup_templatesdb(paths.templates, setup_path, session_info=session_info, - credentials=credentials, lp=lp) - +def setup_samdb(path, setup_path, session_info, credentials, lp, + schemadn, configdn, domaindn, dnsdomain, realm, + netbiosname, message, hostname, rootdn, erase, + domainsid, aci, rdn_dc, domainguid, policyguid, + domainname, blank, adminpass, krbtgtpass, + machinepass, hostguid, invocationid, dnspass): # Also wipes the database message("Setting up sam.ldb") - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) message("Setting up sam.ldb partitions") setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.transaction_start() @@ -520,7 +391,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb.transaction_commit() message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) load_schema(setup_path, samdb, schemadn, netbiosname, configdn) @@ -594,7 +465,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, "DNSDOMAIN": dnsdomain, - "DOMAIN": domain, + "DOMAIN": domainname, "SCHEMADN": schemadn, "DOMAINDN": domaindn, }) @@ -651,7 +522,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "MACHINEPASS_B64": b64encode(machinepass), "DNSPASS_B64": b64encode(dnspass), "REALM": realm, - "DOMAIN": domain, + "DOMAIN": domainname, "HOSTGUID_ADD": hostguid_add, "DNSDOMAIN": dnsdomain}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { @@ -660,30 +531,6 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "DOMAINSID": str(domainsid), "DOMAINDN": domaindn}) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) - if not os.path.isdir(paths.netlogon): - os.makedirs(paths.netlogon, 0755) - setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { - "MACHINEPASS_B64": b64encode(machinepass), - "DOMAIN": domain, - "REALM": realm, - "LDAPTIME": timestring(int(time.time())), - "DNSDOMAIN": dnsdomain, - "DOMAINSID": str(domainsid), - "SECRETS_KEYTAB": paths.keytab, - "NETBIOSNAME": netbiosname, - "SAM_LDB": paths.samdb, - "DNS_KEYTAB": paths.dns_keytab, - "DNSPASS_B64": b64encode(dnspass), - }) - - setup_name_mappings(samdb, str(domainsid), - domaindn, root=root, nobody=nobody, - nogroup=nogroup, wheel=wheel, users=users, - backup=backup) - message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) @@ -694,6 +541,177 @@ def provision(lp, setup_dir, message, blank, paths, session_info, raise samdb.transaction_commit() + return samdb + + +def provision(lp, setup_dir, message, blank, paths, session_info, + credentials, ldapbackend, realm=None, domain=None, hostname=None, + hostip=None, domainsid=None, hostguid=None, adminpass=None, + krbtgtpass=None, domainguid=None, policyguid=None, + invocationid=None, machinepass=None, dnspass=None, root=None, + nobody=None, nogroup=None, users=None, wheel=None, backup=None, + aci=None, serverrole=None): + """Provision samba4 + + :note: caution, this wipes all existing data! + """ + + def setup_path(file): + return os.path.join(setup_dir, file) + + erase = False + + if domainsid is None: + domainsid = security.random_sid() + if policyguid is None: + policyguid = uuid.random() + if invocationid is None: + invocationid = uuid.random() + if adminpass is None: + adminpass = misc.random_password(12) + if krbtgtpass is None: + krbtgtpass = misc.random_password(12) + if machinepass is None: + machinepass = misc.random_password(12) + if dnspass is None: + dnspass = misc.random_password(12) + if root is None: + root = findnss(pwd.getpwnam, "root")[4] + if nobody is None: + nobody = findnss(pwd.getpwnam, "nobody")[4] + if nogroup is None: + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + if users is None: + users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + if wheel is None: + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + if backup is None: + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + if aci is None: + aci = "# no aci for local ldb" + if serverrole is None: + serverrole = lp.get("server role") + + if realm is None: + realm = lp.get("realm") + else: + if lp.get("realm").upper() != realm.upper(): + raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + (lp.get("realm"), realm)) + + assert realm is not None + realm = realm.upper() + + if domain is None: + domain = lp.get("workgroup") + else: + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", + lp.get("workgroup"), domain) + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if hostip is None: + hostip = gethostbyname(hostname) + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + dnsdomain = realm.lower() + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + rootdn = domaindn + configdn = "CN=Configuration," + rootdn + schemadn = "CN=Schema," + configdn + + rdn_dc = domaindn.split(",")[0][len("DC="):] + + message("set DOMAIN SID: %s" % str(domainsid)) + message("Provisioning for %s in realm %s" % (domain, realm)) + message("Using administrator password: %s" % adminpass) + + assert paths.smbconf is not None + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(paths.smbconf): + message("Setting up smb.conf") + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member": + smbconfsuffix = "member" + else: + assert "Invalid server role setting: %s" % serverrole + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { + "HOSTNAME": hostname, + "DOMAIN_CONF": domain, + "REALM_CONF": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": paths.netlogon, + "SYSVOLPATH": paths.sysvol, + }) + lp.reload() + + # only install a new shares config db if there is none + if not os.path.exists(paths.shareconf): + message("Setting up share.ldb") + share_ldb = Ldb(paths.shareconf, session_info=session_info, + credentials=credentials, lp=lp) + share_ldb.load_ldif_file_add(setup_path("share.ldif")) + + message("Setting up secrets.ldb") + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, + session_info=session_info, + credentials=credentials, lp=lp) + + message("Setting up the registry") + # FIXME: Still fails for some reason + #setup_registry(paths.hklm, setup_path, session_info, + # credentials=credentials, lp=lp) + + message("Setting up templates db") + setup_templatesdb(paths.templates, setup_path, session_info=session_info, + credentials=credentials, lp=lp) + + samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, + lp=lp, schemadn=schemadn, configdn=configdn, domaindn=domaindn, + dnsdomain=dnsdomain, netbiosname=netbiosname, realm=realm, message=message, + hostname=hostname, rootdn=rootdn, erase=erase, domainsid=domainsid, aci=aci, + rdn_dc=rdn_dc, domainguid=domainguid, policyguid=policyguid, + domainname=domain, blank=blank, adminpass=adminpass, krbtgtpass=krbtgtpass, + hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, + dnspass=dnspass) + + if lp.get("server role") == "domain controller": + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) + if not os.path.isdir(paths.netlogon): + os.makedirs(paths.netlogon, 0755) + setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { + "MACHINEPASS_B64": b64encode(machinepass), + "DOMAIN": domain, + "REALM": realm, + "LDAPTIME": timestring(int(time.time())), + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "SECRETS_KEYTAB": paths.keytab, + "NETBIOSNAME": netbiosname, + "SAM_LDB": paths.samdb, + "DNS_KEYTAB": paths.dns_keytab, + "DNSPASS_B64": b64encode(dnspass), + }) + + if not blank: + setup_name_mappings(samdb, str(domainsid), + domaindn, root=root, nobody=nobody, + nogroup=nogroup, wheel=wheel, users=users, + backup=backup) message("Setting up phpLDAPadmin configuration") create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path) -- cgit From b7ffc3b404fbe3cf759e743c23e7bdbf75e71286 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 02:26:38 -0600 Subject: r26562: Fix provisioning using Python. (This used to be commit b07ca944ba62a3f3de58c06b66533c0953a32de9) --- source4/scripting/python/samba/provision.py | 73 +++++++++++++++++------------ 1 file changed, 43 insertions(+), 30 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f516e73893..65094ecfac 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -354,6 +354,36 @@ def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): }) +def setup_self_join(samdb, configdn, schemadn, domaindn, + netbiosname, hostname, dnsdomain, machinepass, dnspass, + realm, domainname, domainsid, invocationid, setup_path, + policyguid, hostguid=None): + if hostguid is not None: + hostguid_add = "objectGUID: %s" % hostguid + else: + hostguid_add = "" + + setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { + "CONFIGDN": configdn, + "SCHEMADN": schemadn, + "DOMAINDN": domaindn, + "INVOCATIONID": invocationid, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "MACHINEPASS_B64": b64encode(machinepass), + "DNSPASS_B64": b64encode(dnspass), + "REALM": realm, + "DOMAIN": domainname, + "HOSTGUID_ADD": hostguid_add, + "DNSDOMAIN": dnsdomain}) + setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { + "POLICYGUID": policyguid, + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "DOMAINDN": domaindn}) + + def setup_samdb(path, setup_path, session_info, credentials, lp, schemadn, configdn, domaindn, dnsdomain, realm, netbiosname, message, hostname, rootdn, erase, @@ -506,30 +536,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if lp.get("server role") == "domain controller": message("Setting up self join") - if hostguid is not None: - hostguid_add = "objectGUID: %s" % hostguid - else: - hostguid_add = "" - - setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { - "CONFIGDN": configdn, - "SCHEMADN": schemadn, - "DOMAINDN": domaindn, - "INVOCATIONID": invocationid, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, - "DNSNAME": "%s.%s" % (hostname, dnsdomain), - "MACHINEPASS_B64": b64encode(machinepass), - "DNSPASS_B64": b64encode(dnspass), - "REALM": realm, - "DOMAIN": domainname, - "HOSTGUID_ADD": hostguid_add, - "DNSDOMAIN": dnsdomain}) - setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { - "POLICYGUID": policyguid, - "DNSDOMAIN": dnsdomain, - "DOMAINSID": str(domainsid), - "DOMAINDN": domaindn}) + setup_self_join(samdb, configdn=configdn, schemadn=schemadn, domaindn=domaindn, + invocationid=invocationid, dnspass=dnspass, netbiosname=netbiosname, + dnsdomain=dnsdomain, realm=realm, machinepass=machinepass, + domainname=domainname, domainsid=domainsid, policyguid=policyguid, + hostname=hostname, hostguid=hostguid, setup_path=setup_path) message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) @@ -693,6 +704,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp) setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass), "DOMAIN": domain, @@ -728,12 +740,13 @@ def provision(lp, setup_dir, message, blank, paths, session_info, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - message("Setting up DNS zone: %s" % dnsdomain) - create_zone_file(paths.dns, setup_path, samdb, - hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm, - domainguid=domainguid, hostguid=hostguid) - message("Please install the zone located in %s into your DNS server" % paths.dns) + if lp.get("server role") == "domain controller": + message("Setting up DNS zone: %s" % dnsdomain) + create_zone_file(paths.dns, setup_path, samdb, + hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, + domaindn=domaindn, dnspass=dnspass, realm=realm, + domainguid=domainguid, hostguid=hostguid) + message("Please install the zone located in %s into your DNS server" % paths.dns) def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): setup_file(setup_path("phpldapadmin-config.php"), -- cgit From 09f820f0bd1a9fc7ffd171418ceb0e19df8e2e43 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:02:57 -0600 Subject: r26564: More python bindings for registry code. (This used to be commit f40fad9827d0e9567224bc1e64ea91e610a07a3f) --- source4/scripting/python/samba/provision.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 65094ecfac..1d606d80e5 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -681,9 +681,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, credentials=credentials, lp=lp) message("Setting up the registry") - # FIXME: Still fails for some reason - #setup_registry(paths.hklm, setup_path, session_info, - # credentials=credentials, lp=lp) + setup_registry(paths.hklm, setup_path, session_info, + credentials=credentials, lp=lp) message("Setting up templates db") setup_templatesdb(paths.templates, setup_path, session_info=session_info, -- cgit From 249cc734cebfef31320ec10b05dbfaaaa39682ca Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:03:02 -0600 Subject: r26565: Fix python registry bindings. 'PROVISION_PYTHON=yes make test' works now. (This used to be commit 485d1fa3d17fe6cc7a0ecd80e8bac42d173bbb19) --- source4/scripting/python/samba/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 1d606d80e5..b5fe3eba9e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -281,12 +281,12 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): def setup_registry(path, setup_path, session_info, credentials, lp): reg = registry.Registry() - hive = registry.Hive(path, session_info=session_info, + hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") provision_reg = setup_path("provision.reg") assert os.path.exists(provision_reg) - reg.apply_patchfile(provision_reg) + reg.diff_apply(provision_reg) def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, -- cgit From f053e385ff796914392d0eafa1e8756ff5ffdb18 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:11:21 -0600 Subject: r26566: Fix member provision when using python. (This used to be commit e5573283df9e98bccc8eae227cf0f11367ecf084) --- source4/scripting/python/samba/provision.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b5fe3eba9e..dcf567954a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -729,17 +729,17 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials, lp=lp) + if lp.get("server role") == "domain controller": + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) - domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") - assert isinstance(domainguid, str) - hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", - expression="(&(objectClass=computer)(cn=%s))" % hostname, - scope=SCOPE_SUBTREE) - assert isinstance(hostguid, str) + domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + assert isinstance(domainguid, str) + hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", + expression="(&(objectClass=computer)(cn=%s))" % hostname, + scope=SCOPE_SUBTREE) + assert isinstance(hostguid, str) - if lp.get("server role") == "domain controller": message("Setting up DNS zone: %s" % dnsdomain) create_zone_file(paths.dns, setup_path, samdb, hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, -- cgit From aa0a06f13c44e0eca0b3f2f0c34f0f7995b87159 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 19:19:41 -0600 Subject: r26570: - Trim size of the swig-generated Python bindings by removing a bunch of {}'s. - Start working on Python equivalents for various EJS tests. - Fix regression in argument order for reg_diff_apply() in EJS bindings. (This used to be commit c550c03372cb260b78f6a6c132e70571bc4cb852) --- source4/scripting/python/misc_wrap.c | 73 +++----- source4/scripting/python/samba/__init__.py | 20 +- source4/scripting/python/samba/provision.py | 4 +- source4/scripting/python/samba/samba3.py | 224 +++++++++++++++++++++++ source4/scripting/python/samba/tests/__init__.py | 1 + source4/scripting/python/samba/tests/samba3.py | 57 ++++++ source4/scripting/python/samba/upgrade.py | 16 +- 7 files changed, 335 insertions(+), 60 deletions(-) create mode 100644 source4/scripting/python/samba/samba3.py create mode 100644 source4/scripting/python/samba/tests/samba3.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index dc1203e2f0..0f36647487 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2808,9 +2808,7 @@ SWIGINTERN PyObject *_wrap_random_password(PyObject *SWIGUNUSEDPARM(self), PyObj (char *) "len", NULL }; - { - arg1 = NULL; - } + arg1 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:random_password",kwnames,&obj0)) SWIG_fail; ecode2 = SWIG_AsVal_size_t(obj0, &val2); if (!SWIG_IsOK(ecode2)) { @@ -2855,11 +2853,9 @@ SWIGINTERN PyObject *_wrap_ldb_set_credentials(PyObject *SWIGUNUSEDPARM(self), P } arg2 = (struct cli_credentials *)(argp2); } - { - if (arg1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); - } + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); ldb_set_credentials(arg1,arg2); resultobj = SWIG_Py_Void(); return resultobj; @@ -2893,11 +2889,9 @@ SWIGINTERN PyObject *_wrap_ldb_set_session_info(PyObject *SWIGUNUSEDPARM(self), SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_set_session_info" "', argument " "2"" of type '" "struct auth_session_info *""'"); } arg2 = (struct auth_session_info *)(argp2); - { - if (arg1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); - } + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); ldb_set_session_info(arg1,arg2); resultobj = SWIG_Py_Void(); return resultobj; @@ -2936,11 +2930,9 @@ SWIGINTERN PyObject *_wrap_ldb_set_loadparm(PyObject *SWIGUNUSEDPARM(self), PyOb } arg2 = (struct loadparm_context *)(argp2); } - { - if (arg1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); - } + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); ldb_set_loadparm(arg1,arg2); resultobj = SWIG_Py_Void(); return resultobj; @@ -2975,11 +2967,9 @@ SWIGINTERN PyObject *_wrap_samdb_set_domain_sid(PyObject *SWIGUNUSEDPARM(self), SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "samdb_set_domain_sid" "', argument " "2"" of type '" "struct dom_sid const *""'"); } arg2 = (struct dom_sid *)(argp2); - { - if (arg1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); - } + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); result = (bool)samdb_set_domain_sid(arg1,(struct dom_sid const *)arg2); resultobj = SWIG_From_bool((bool)(result)); return resultobj; @@ -3025,19 +3015,16 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "dsdb_attach_schema_from_ldif_file" "', argument " "3"" of type '" "char const *""'"); } arg3 = (char *)(buf3); - { - if (arg1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); - } + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); result = dsdb_attach_schema_from_ldif_file(arg1,(char const *)arg2,(char const *)arg3); - { - if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); - } else if (resultobj == NULL) { - resultobj = Py_None; - } + if (!W_ERROR_IS_OK(result)) { + PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyErr_SetObject(PyExc_RuntimeError, obj); + SWIG_fail; + } else if (resultobj == NULL) { + resultobj = Py_None; } if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); @@ -3079,11 +3066,9 @@ SWIGINTERN PyObject *_wrap_dsdb_set_global_schema(PyObject *SWIGUNUSEDPARM(self) SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsdb_set_global_schema" "', argument " "1"" of type '" "struct ldb_context *""'"); } arg1 = (struct ldb_context *)(argp1); - { - if (arg1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); - } + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); result = (int)dsdb_set_global_schema(arg1); resultobj = SWIG_From_int((int)(result)); return resultobj; @@ -3109,11 +3094,9 @@ SWIGINTERN PyObject *_wrap_ldb_register_samba_handlers(PyObject *SWIGUNUSEDPARM( SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_register_samba_handlers" "', argument " "1"" of type '" "struct ldb_context *""'"); } arg1 = (struct ldb_context *)(argp1); - { - if (arg1 == NULL) - SWIG_exception(SWIG_ValueError, - "ldb context must be non-NULL"); - } + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); result = (int)ldb_register_samba_handlers(arg1); resultobj = SWIG_From_int((int)(result)); return resultobj; diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index c735361353..5b34534133 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -91,7 +91,14 @@ class Ldb(ldb.Ldb): def searchone(self, basedn, attribute, expression=None, scope=ldb.SCOPE_BASE): - """Search for one attribute as a string.""" + """Search for one attribute as a string. + + :param basedn: BaseDN for the search. + :param attribute: Name of the attribute + :param expression: Optional search expression. + :param scope: Search scope (defaults to base). + :return: Value of attribute as a string or None if it wasn't found. + """ res = self.search(basedn, scope, expression, [attribute]) if len(res) != 1 or res[0][attribute] is None: return None @@ -100,7 +107,7 @@ class Ldb(ldb.Ldb): return values.pop() def erase(self): - """Erase an ldb, removing all records.""" + """Erase this ldb, removing all records.""" # delete the specials for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: @@ -149,13 +156,18 @@ class Ldb(ldb.Ldb): :param ldif_path: Path to LDIF file. """ - self.load_ldif_add(open(ldif_path, 'r').read()) + self.add_ldif(open(ldif_path, 'r').read()) - def load_ldif_add(self, ldif): + def add_ldif(self, ldif): for changetype, msg in self.parse_ldif(ldif): assert changetype == ldb.CHANGETYPE_NONE self.add(msg) + def modify_ldif(self, ldif): + for (changetype, msg) in ldb.parse_ldif(data): + assert changetype == CHANGETYPE_MODIFY + ldb.modify(msg) + def substitute_var(text, values): """substitute strings of the form ${NAME} in str, replacing diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index dcf567954a..a4e6c6a214 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -111,9 +111,7 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None): assert "${" not in data - for (changetype, msg) in ldb.parse_ldif(data): - assert changetype == CHANGETYPE_MODIFY - ldb.modify(msg) + ldb.modify_ldif(data) def setup_ldb(ldb, ldif_path, subst_vars): diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py new file mode 100644 index 0000000000..d8289ae756 --- /dev/null +++ b/source4/scripting/python/samba/samba3.py @@ -0,0 +1,224 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 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 . +# + +"""Support for reading Samba 3 data files.""" + +REGISTRY_VALUE_PREFIX = "SAMBA_REGVAL" +REGISTRY_DB_VERSION = 1 + +import tdb + +class Registry: + """Simple read-only support for reading the Samba3 registry.""" + def __init__(self, file): + self.tdb = tdb.Tdb(file) + + def __len__(self): + """Return the number of keys.""" + return len(self.keys()) + + def keys(self): + """Return list with all the keys.""" + return [k.rstrip("\x00") for k in self.tdb.keys() if not k.startswith(REGISTRY_VALUE_PREFIX)] + + def subkeys(self, key): + data = self.tdb.get(key) + if data is None: + return [] + # FIXME: Parse data + return [] + + def values(self, key): + """Return a dictionary with the values set for a specific key.""" + data = self.tdb.get("%s/%s" % (REGISTRY_VALUE_PREFIX, key)) + if data is None: + return {} + # FIXME: Parse data + return {} + + +class PolicyDatabase: + def __init__(self, file): + self.tdb = tdb.Tdb(file) + self.min_password_length = tdb.fetch_uint32("min password length") + self.user_must_logon_to_change_password = tdb.fetch_uint32("password history") + self.user_must_logon_to_change_password = tdb.fetch_uint32("user must logon to change pasword") + self.maximum_password_age = tdb.fetch_uint32("maximum password age") + self.minimum_password_age = tdb.fetch_uint32("minimum password age") + self.lockout_duration = tdb.fetch_uint32("lockout duration") + self.reset_count_minutes = tdb.fetch_uint32("reset count minutes") + self.bad_lockout_minutes = tdb.fetch_uint32("bad lockout minutes") + self.disconnect_time = tdb.fetch_uint32("disconnect time") + self.refuse_machine_password_change = tdb.fetch_uint32("refuse machine password change") + + # FIXME: Read privileges as well + + +GROUPDB_DATABASE_VERSION_V1 = 1 # native byte format. +GROUPDB_DATABASE_VERSION_V2 = 2 # le format. + +GROUP_PREFIX = "UNIXGROUP/" + +# Alias memberships are stored reverse, as memberships. The performance +# critical operation is to determine the aliases a SID is member of, not +# listing alias members. So we store a list of alias SIDs a SID is member of +# hanging of the member as key. +MEMBEROF_PREFIX = "MEMBEROF/" + +class GroupMappingDatabase: + def __init__(self, file): + self.tdb = tdb.Tdb(file) + + +# High water mark keys +HWM_GROUP = "GROUP HWM" +HWM_USER = "USER HWM" + +# idmap version determines auto-conversion +IDMAP_VERSION = 2 + +class IdmapDatabase: + def __init__(self, file): + self.tdb = tdb.Tdb(file) + assert self.tdb.fetch_int32("IDMAP_VERSION") == IDMAP_VERSION + + +class SecretsDatabase: + def __init__(self, file): + self.tdb = tdb.Tdb(file) + self.domains = {} + for k, v in self.tdb.items(): + if k == "SECRETS/AUTH_PASSWORD": + self.auth_password = v + elif k == "SECRETS/AUTH_DOMAIN": + self.auth_domain = v + elif k == "SECRETS/AUTH_USER": + self.auth_user = v + elif k.startswith("SECRETS/SID/"): + pass # FIXME + elif k.startswith("SECRETS/DOMGUID/"): + pass # FIXME + elif k.startswith("SECRETS/LDAP_BIND_PW/"): + pass # FIXME + elif k.startswith("SECRETS/AFS_KEYFILE/"): + pass # FIXME + elif k.startswith("SECRETS/MACHINE_SEC_CHANNEL_TYPE/"): + pass # FIXME + elif k.startswith("SECRETS/MACHINE_LAST_CHANGE_TIME/"): + pass # FIXME + elif k.startswith("SECRETS/MACHINE_PASSWORD/"): + pass # FIXME + elif k.startswith("SECRETS/$MACHINE.ACC/"): + pass # FIXME + elif k.startswith("SECRETS/$DOMTRUST.ACC/"): + pass # FIXME + elif k == "INFO/random_seed": + self.random_seed = v + else: + raise "Unknown key %s in secrets database" % k + +SHARE_DATABASE_VERSION_V1 = 1 +SHARE_DATABASE_VERSION_V2 = 2 + +class ShareInfoDatabase: + def __init__(self, file): + self.tdb = tdb.Tdb(file) + assert self.tdb.fetch_int32("INFO/version") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) + + def get_secdesc(self, name): + secdesc = self.tdb.get("SECDESC/%s" % name) + # FIXME: Run ndr_pull_security_descriptor + + +ACB_DISABLED = 0x00000001 +ACB_HOMDIRREQ = 0x00000002 +ACB_PWNOTREQ = 0x00000004 +ACB_TEMPDUP = 0x00000008 +ACB_NORMAL = 0x00000010 +ACB_MNS = 0x00000020 +ACB_DOMTRUST = 0x00000040 +ACB_WSTRUST = 0x00000080 +ACB_SVRTRUST = 0x00000100 +ACB_PWNOEXP = 0x00000200 +ACB_AUTOLOCK = 0x00000400 +ACB_ENC_TXT_PWD_ALLOWED = 0x00000800 +ACB_SMARTCARD_REQUIRED = 0x00001000 +ACB_TRUSTED_FOR_DELEGATION = 0x00002000 +ACB_NOT_DELEGATED = 0x00004000 +ACB_USE_DES_KEY_ONLY = 0x00008000 +ACB_DONT_REQUIRE_PREAUTH = 0x00010000 +ACB_PW_EXPIRED = 0x00020000 +ACB_NO_AUTH_DATA_REQD = 0x00080000 + +acb_info_mapping = { + 'N': ACB_PWNOTREQ, # 'N'o password. + 'D': ACB_DISABLED, # 'D'isabled. + 'H': ACB_HOMDIRREQ, # 'H'omedir required. + 'T': ACB_TEMPDUP, # 'T'emp account. + 'U': ACB_NORMAL, # 'U'ser account (normal). + 'M': ACB_MNS, # 'M'NS logon user account. What is this ? + 'W': ACB_WSTRUST, # 'W'orkstation account. + 'S': ACB_SVRTRUST, # 'S'erver account. + 'L': ACB_AUTOLOCK, # 'L'ocked account. + 'X': ACB_PWNOEXP, # No 'X'piry on password + 'I': ACB_DOMTRUST, # 'I'nterdomain trust account. + ' ': 0 + } + + +class Smbpasswd: + def __init__(self, file): + pass + + +class TdbSam: + def __init__(self, file): + self.tdb = tdb.Tdb(file) + + +class WinsDatabase: + def __init__(self, file): + pass + + +class Samba3: + def __init__(self, smbconfpath, libdir): + self.smbconfpath = smbconfpath + self.libdir = libdir + + def get_policy_db(self): + return PolicyDatabase(os.path.join(libdir, "account_policy.tdb")) + + def get_registry(self): + return Registry(os.path.join(libdir, "registry.tdb")) + + def get_secrets_db(self): + return SecretsDatabase(os.path.join(libdir, "secrets.tdb")) + + def get_shares_db(self): + return ShareInfoDatabase(os.path.join(libdir, "share_info.tdb")) + + def get_idmap_db(self): + return IdmapDatabase(os.path.join(libdir, "winbindd_idmap.tdb")) + + def get_wins_db(self): + return WinsDatabase(os.path.join(libdir, "wins.dat")) + + def get_groupmapping_db(self): + return GroupMappingDatabase(os.path.join(libdir, "group_mapping.tdb")) diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index e213c1cc1f..b01807c02f 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -43,6 +43,7 @@ class TestCaseInTempDir(unittest.TestCase): def tearDown(self): super(TestCaseInTempDir, self).tearDown() + # FIXME: Remove all files in self.tempdir class SubstituteVarTestCase(unittest.TestCase): diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py new file mode 100644 index 0000000000..c6b6281c60 --- /dev/null +++ b/source4/scripting/python/samba/tests/samba3.py @@ -0,0 +1,57 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 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 . +# + +import unittest +from samba.samba3 import GroupMappingDatabase, Registry, PolicyDatabase +import os + +DATADIR=os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") + +class RegistryTestCase(unittest.TestCase): + def setUp(self): + self.registry = Registry(os.path.join(DATADIR, "registry.tdb")) + + def test_length(self): + self.assertEquals(28, len(self.registry)) + + def test_keys(self): + self.assertEquals([], self.registry.keys()) + + +class PolicyTestCase(unittest.TestCase): + def setUp(self): + self.policy = PolicyDatabase(os.path.join(DATADIR, "account_policy.tdb")) + + def test_policy(self): + self.assertEquals(self.policy.min_password_length, 5) + self.assertEquals(self.policy.minimum_password_age, 0) + self.assertEquals(self.policy.maximum_password_age, 999999999) + self.assertEquals(self.policy.refuse_machine_password_change, 0) + self.assertEquals(self.policy.reset_count_minutes, 0) + self.assertEquals(self.policy.disconnect_time, -1) + self.assertEquals(self.policy.user_must_logon_to_change_password, 0) + self.assertEquals(self.policy.password_history, 0) + self.assertEquals(self.policy.lockout_duration, 0) + self.assertEquals(self.policy.bad_lockout_minutes, 0) + + +class GroupsTestCase(unittest.TestCase): + def setUp(self): + self.groupdb = GroupMappingDatabase(os.path.join(DATADIR, "group_mapping.tdb")) + diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 1c27f8ec25..3168fedf2d 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -7,7 +7,7 @@ """Support code for upgrading from Samba 3 to Samba 4.""" -from provision import findnss +from provision import findnss, provision import provision import grp import pwd @@ -69,7 +69,7 @@ data:: %s""" % (keydn, rv.name, rv.name, rv.type, ldb.encode(rv.data)) return ldif -def upgrade_sam_policy(samba3,dn): +def upgrade_sam_policy(policy,dn): ldif = """ dn: %s changetype: modify @@ -84,11 +84,11 @@ samba3UserMustLogonToChangePassword: %d samba3BadLockoutMinutes: %d samba3DisconnectTime: %d -""" % (dn, samba3.policy.min_password_length, - samba3.policy.password_history, samba3.policy.minimum_password_age, - samba3.policy.maximum_password_age, samba3.policy.lockout_duration, - samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password, - samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time) +""" % (dn, policy.min_password_length, + policy.password_history, policy.minimum_password_age, + policy.maximum_password_age, policy.lockout_duration, + policy.reset_count_minutes, policy.user_must_logon_to_change_password, + policy.bad_lockout_minutes, policy.disconnect_time) return ldif @@ -465,7 +465,7 @@ replace: type type: 4 replace: data data: %d -""" % samba3.policy.refuse_machine_password_change) +""" % policy.refuse_machine_password_change) message("Importing users") for account in samba3.samaccounts: -- cgit From 3ee442c54f658e0dc9541a492e46fd8f6bf3a7f4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 20:22:46 -0600 Subject: r26571: Hide warnings about unused macros and casting qualifiers in autogenerated files. (This used to be commit cb76c60007ae1254181c09ba1ab09c419f500bc5) --- source4/scripting/python/misc_wrap.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 0f36647487..03128c2e9e 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2837,9 +2837,7 @@ SWIGINTERN PyObject *_wrap_ldb_set_credentials(PyObject *SWIGUNUSEDPARM(self), P (char *) "ldb",(char *) "creds", NULL }; - { - arg2 = NULL; - } + arg2 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|O:ldb_set_credentials",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); if (!SWIG_IsOK(res1)) { @@ -2914,9 +2912,7 @@ SWIGINTERN PyObject *_wrap_ldb_set_loadparm(PyObject *SWIGUNUSEDPARM(self), PyOb (char *) "ldb",(char *) "lp_ctx", NULL }; - { - arg2 = loadparm_init(NULL); - } + arg2 = loadparm_init(NULL); if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|O:ldb_set_loadparm",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); if (!SWIG_IsOK(res1)) { -- cgit From d0ba9f001474bfee9b1e8fb516effab736cd4050 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 20:56:41 -0600 Subject: r26572: Fix warnings in the Python code. (This used to be commit 15038d9586d0b58f301ca8c39c21ef10c4283f28) --- source4/scripting/python/misc.i | 1 + source4/scripting/python/misc_wrap.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 3af10dfce9..2f41840670 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -22,6 +22,7 @@ #include "includes.h" #include "ldb.h" #include "param/param.h" +#include "auth/credentials/credentials.h" #include "dsdb/samdb/samdb.h" #include "lib/ldb-samba/ldif_handlers.h" %} diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 03128c2e9e..a7493550cc 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2530,6 +2530,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #include "includes.h" #include "ldb.h" #include "param/param.h" +#include "auth/credentials/credentials.h" #include "dsdb/samdb/samdb.h" #include "lib/ldb-samba/ldif_handlers.h" @@ -3016,7 +3017,7 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE "ldb context must be non-NULL"); result = dsdb_attach_schema_from_ldif_file(arg1,(char const *)arg2,(char const *)arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue("(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { -- cgit From 1ab5bcfb93c9fc7b18d55e6c5995efddf97fea09 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 22:06:29 -0600 Subject: r26575: Build a private copy of the Python executable for Samba 4, so we know we're always using the same library we build the modules for. (This used to be commit 03270c5ffdb1476bef5eba846c2ea008111375fc) --- source4/scripting/python/config.m4 | 3 +++ source4/scripting/python/config.mk | 5 +++++ source4/scripting/python/smbpython.c | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 source4/scripting/python/smbpython.c (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 8951b4da08..49ad7273a4 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -41,9 +41,11 @@ then Py_InitModule(NULL, NULL); ],[ SMB_ENABLE(LIBPYTHON,YES) + SMB_ENABLE(smbpython,YES) AC_MSG_RESULT([yes]) ],[ SMB_ENABLE(LIBPYTHON,NO) + SMB_ENABLE(smbpython,NO) AC_MSG_RESULT([no]) ]) @@ -51,5 +53,6 @@ then CFLAGS="$ac_save_CFLAGS" else SMB_ENABLE(LIBPYTHON,NO) + SMB_ENABLE(smbpython,NO) AC_MSG_RESULT([no]) fi diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index d0d3829eef..ac923cb8d1 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,3 +1,8 @@ +[BINARY::smbpython] +PRIVATE_DEPENDENCIES = LIBPYTHON +OBJ_FILES = \ + smbpython.o + [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR OBJ_FILES = uuidmodule.o diff --git a/source4/scripting/python/smbpython.c b/source4/scripting/python/smbpython.c new file mode 100644 index 0000000000..43785765c1 --- /dev/null +++ b/source4/scripting/python/smbpython.c @@ -0,0 +1,25 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 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 . +*/ + +#include "includes.h" +#include + +int main(int argc, char **argv) { + return Py_Main(argc,argv); +} -- cgit From be33f4c611d37ebba59ff618033dc73601339ad1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 23:54:30 -0600 Subject: r26576: Allow the static module loading code to be used for the Python modules. Simplify the way module initialization functions are handled. (This used to be commit ba8be2dfc0de4434c798663336b81f7f95cde520) --- source4/scripting/python/config.m4 | 9 ++++--- source4/scripting/python/config.mk | 7 ++++-- source4/scripting/python/modules.c | 45 +++++++++++++++++++++++++++++++++++ source4/scripting/python/smbpython.c | 6 ++++- source4/scripting/python/uuidmodule.c | 4 ++-- 5 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 source4/scripting/python/modules.c (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 49ad7273a4..b6ca7966df 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -24,7 +24,7 @@ fi PYTHON_LDFLAGS=`$PYTHON_CONFIG --ldflags` PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags` -SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) +SMB_EXT_LIB(EXT_LIB_PYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) AC_MSG_CHECKING(working python module support) if test x$working_python = xyes @@ -40,10 +40,12 @@ then ],[ Py_InitModule(NULL, NULL); ],[ - SMB_ENABLE(LIBPYTHON,YES) + SMB_ENABLE(EXT_LIB_PYTHON,YES) SMB_ENABLE(smbpython,YES) + SMB_ENABLE(LIBPYTHON,YES) AC_MSG_RESULT([yes]) ],[ + SMB_ENABLE(EXT_LIB_PYTHON,NO) SMB_ENABLE(LIBPYTHON,NO) SMB_ENABLE(smbpython,NO) AC_MSG_RESULT([no]) @@ -52,7 +54,8 @@ then LIBS="$ac_save_LIBS" CFLAGS="$ac_save_CFLAGS" else - SMB_ENABLE(LIBPYTHON,NO) + SMB_ENABLE(EXT_LIB_PYTHON,NO) + SMB_ENABLE(LIBPYTHONyy,NO) SMB_ENABLE(smbpython,NO) AC_MSG_RESULT([no]) fi diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index ac923cb8d1..601e432906 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,7 +1,10 @@ [BINARY::smbpython] PRIVATE_DEPENDENCIES = LIBPYTHON -OBJ_FILES = \ - smbpython.o +OBJ_FILES = smbpython.o + +[SUBSYSTEM::LIBPYTHON] +PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON +OBJ_FILES = modules.o [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c new file mode 100644 index 0000000000..6a766f3412 --- /dev/null +++ b/source4/scripting/python/modules.c @@ -0,0 +1,45 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 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 . +*/ + +#include "includes.h" +#include +#include "build.h" + +extern void init_ldb(void); +extern void init_security(void); +extern void init_registry(void); +extern void init_param(void); +extern void init_misc(void); +extern void init_ldb(void); +extern void init_auth(void); +extern void init_credentials(void); +extern void init_tdb(void); +extern void init_dcerpc(void); +extern void init_events(void); +extern void inituuid(void); + +static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; + +void py_load_samba_modules(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(py_modules); i++) { + PyImport_ExtendInittab(&py_modules[i]); + } +} diff --git a/source4/scripting/python/smbpython.c b/source4/scripting/python/smbpython.c index 43785765c1..19c458e7ac 100644 --- a/source4/scripting/python/smbpython.c +++ b/source4/scripting/python/smbpython.c @@ -20,6 +20,10 @@ #include "includes.h" #include -int main(int argc, char **argv) { +void py_load_samba_modules(void); + +int main(int argc, char **argv) +{ + py_load_samba_modules(); return Py_Main(argc,argv); } diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c index 9ae432dfa5..02c929d4a5 100644 --- a/source4/scripting/python/uuidmodule.c +++ b/source4/scripting/python/uuidmodule.c @@ -26,7 +26,7 @@ static PyObject *uuid_random(PyObject *self, PyObject *args) struct GUID guid; char *str; - if (!PyArg_ParseTuple(args, "")) + if (!PyArg_ParseTuple(args, (char *)"")) return NULL; guid = GUID_random(); @@ -51,7 +51,7 @@ PyDoc_STRVAR(param_doc, "UUID helper routines"); PyMODINIT_FUNC inituuid(void) { - PyObject *mod = Py_InitModule3("uuid", methods, param_doc); + PyObject *mod = Py_InitModule3((char *)"uuid", methods, param_doc); if (mod == NULL) return; } -- cgit From c13ae707313c5bf9819a75c1699d099565d2494d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Dec 2007 01:28:22 -0600 Subject: r26580: Include sentinel in build.h, in case the list is empty. (This used to be commit f1997dabed584bdc864c4b7235c29603c312ef46) --- source4/scripting/python/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 601e432906..226f9637db 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -4,6 +4,7 @@ OBJ_FILES = smbpython.o [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON +INIT_FUNCTION_SENTINEL = { NULL, NULL } OBJ_FILES = modules.o [PYTHON::python_uuid] -- cgit From 59efa6e5d074f9f0fbc0b5fd2b5bcdc9d78b95e3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Dec 2007 11:02:52 -0600 Subject: r26585: Fix samba3.python tests. (This used to be commit 231ec0777b7d1fb1297e3a974871b8735a386cfa) --- source4/scripting/python/samba/samba3.py | 42 ++++++++++++++------------ source4/scripting/python/samba/tests/samba3.py | 10 ++++-- 2 files changed, 30 insertions(+), 22 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index d8289ae756..8225eacd58 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -22,12 +22,16 @@ REGISTRY_VALUE_PREFIX = "SAMBA_REGVAL" REGISTRY_DB_VERSION = 1 +import os import tdb class Registry: """Simple read-only support for reading the Samba3 registry.""" def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + + def close(self): + self.tdb.close() def __len__(self): """Return the number of keys.""" @@ -38,7 +42,7 @@ class Registry: return [k.rstrip("\x00") for k in self.tdb.keys() if not k.startswith(REGISTRY_VALUE_PREFIX)] def subkeys(self, key): - data = self.tdb.get(key) + data = self.tdb.get("%s\x00" % key) if data is None: return [] # FIXME: Parse data @@ -46,7 +50,7 @@ class Registry: def values(self, key): """Return a dictionary with the values set for a specific key.""" - data = self.tdb.get("%s/%s" % (REGISTRY_VALUE_PREFIX, key)) + data = self.tdb.get("%s/%s\x00" % (REGISTRY_VALUE_PREFIX, key)) if data is None: return {} # FIXME: Parse data @@ -55,17 +59,17 @@ class Registry: class PolicyDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) - self.min_password_length = tdb.fetch_uint32("min password length") - self.user_must_logon_to_change_password = tdb.fetch_uint32("password history") - self.user_must_logon_to_change_password = tdb.fetch_uint32("user must logon to change pasword") - self.maximum_password_age = tdb.fetch_uint32("maximum password age") - self.minimum_password_age = tdb.fetch_uint32("minimum password age") - self.lockout_duration = tdb.fetch_uint32("lockout duration") - self.reset_count_minutes = tdb.fetch_uint32("reset count minutes") - self.bad_lockout_minutes = tdb.fetch_uint32("bad lockout minutes") - self.disconnect_time = tdb.fetch_uint32("disconnect time") - self.refuse_machine_password_change = tdb.fetch_uint32("refuse machine password change") + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + self.min_password_length = self.tdb.fetch_uint32("min password length\x00") + self.password_history = self.tdb.fetch_uint32("password history\x00") + self.user_must_logon_to_change_password = self.tdb.fetch_uint32("user must logon to change pasword\x00") + self.maximum_password_age = self.tdb.fetch_uint32("maximum password age\x00") + self.minimum_password_age = self.tdb.fetch_uint32("minimum password age\x00") + self.lockout_duration = self.tdb.fetch_uint32("lockout duration\x00") + self.reset_count_minutes = self.tdb.fetch_uint32("reset count minutes\x00") + self.bad_lockout_minutes = self.tdb.fetch_uint32("bad lockout minutes\x00") + self.disconnect_time = self.tdb.fetch_int32("disconnect time\x00") + self.refuse_machine_password_change = self.tdb.fetch_uint32("refuse machine password change\x00") # FIXME: Read privileges as well @@ -83,7 +87,7 @@ MEMBEROF_PREFIX = "MEMBEROF/" class GroupMappingDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) # High water mark keys @@ -95,13 +99,13 @@ IDMAP_VERSION = 2 class IdmapDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) assert self.tdb.fetch_int32("IDMAP_VERSION") == IDMAP_VERSION class SecretsDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) self.domains = {} for k, v in self.tdb.items(): if k == "SECRETS/AUTH_PASSWORD": @@ -138,7 +142,7 @@ SHARE_DATABASE_VERSION_V2 = 2 class ShareInfoDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) assert self.tdb.fetch_int32("INFO/version") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) def get_secdesc(self, name): @@ -189,7 +193,7 @@ class Smbpasswd: class TdbSam: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) class WinsDatabase: diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index c6b6281c60..0d56ca9117 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -22,16 +22,20 @@ from samba.samba3 import GroupMappingDatabase, Registry, PolicyDatabase import os DATADIR=os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") +print "Samba 3 data dir: %s" % DATADIR class RegistryTestCase(unittest.TestCase): def setUp(self): self.registry = Registry(os.path.join(DATADIR, "registry.tdb")) + def tearDown(self): + self.registry.close() + def test_length(self): self.assertEquals(28, len(self.registry)) def test_keys(self): - self.assertEquals([], self.registry.keys()) + self.assertTrue("HKLM" in self.registry.keys()) class PolicyTestCase(unittest.TestCase): @@ -45,10 +49,10 @@ class PolicyTestCase(unittest.TestCase): self.assertEquals(self.policy.refuse_machine_password_change, 0) self.assertEquals(self.policy.reset_count_minutes, 0) self.assertEquals(self.policy.disconnect_time, -1) - self.assertEquals(self.policy.user_must_logon_to_change_password, 0) + self.assertEquals(self.policy.user_must_logon_to_change_password, None) self.assertEquals(self.policy.password_history, 0) self.assertEquals(self.policy.lockout_duration, 0) - self.assertEquals(self.policy.bad_lockout_minutes, 0) + self.assertEquals(self.policy.bad_lockout_minutes, None) class GroupsTestCase(unittest.TestCase): -- cgit From 95b1f554b2c57a9f975a0cc27ca51bec6c7594d6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Dec 2007 13:04:33 -0600 Subject: r26587: Fix reading Samba 3 WINS database and initial work on group db, aliases and secrets. (This used to be commit c7c4cf258ac7975b409d26c9386838d4780c756f) --- source4/scripting/python/samba/samba3.py | 160 ++++++++++++++++++++----- source4/scripting/python/samba/tests/samba3.py | 55 ++++++++- source4/scripting/python/samba/upgrade.py | 21 ++-- 3 files changed, 196 insertions(+), 40 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 8225eacd58..509ee29c1d 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -73,6 +73,9 @@ class PolicyDatabase: # FIXME: Read privileges as well + def close(self): + self.tdb.close() + GROUPDB_DATABASE_VERSION_V1 = 1 # native byte format. GROUPDB_DATABASE_VERSION_V2 = 2 # le format. @@ -88,6 +91,20 @@ MEMBEROF_PREFIX = "MEMBEROF/" class GroupMappingDatabase: def __init__(self, file): self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + assert self.tdb.fetch_int32("INFO/version\x00") in (GROUPDB_DATABASE_VERSION_V1, GROUPDB_DATABASE_VERSION_V2) + + def groupsids(self): + for k in self.tdb.keys(): + if k.startswith(GROUP_PREFIX): + yield k[len(GROUP_PREFIX):].rstrip("\0") + + def aliases(self): + for k in self.tdb.keys(): + if k.startswith(MEMBEROF_PREFIX): + yield k[len(MEMBEROF_PREFIX):].rstrip("\0") + + def close(self): + self.tdb.close() # High water mark keys @@ -102,40 +119,56 @@ class IdmapDatabase: self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) assert self.tdb.fetch_int32("IDMAP_VERSION") == IDMAP_VERSION + def close(self): + self.tdb.close() + class SecretsDatabase: def __init__(self, file): self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) - self.domains = {} - for k, v in self.tdb.items(): - if k == "SECRETS/AUTH_PASSWORD": - self.auth_password = v - elif k == "SECRETS/AUTH_DOMAIN": - self.auth_domain = v - elif k == "SECRETS/AUTH_USER": - self.auth_user = v - elif k.startswith("SECRETS/SID/"): - pass # FIXME - elif k.startswith("SECRETS/DOMGUID/"): - pass # FIXME - elif k.startswith("SECRETS/LDAP_BIND_PW/"): - pass # FIXME - elif k.startswith("SECRETS/AFS_KEYFILE/"): - pass # FIXME - elif k.startswith("SECRETS/MACHINE_SEC_CHANNEL_TYPE/"): - pass # FIXME - elif k.startswith("SECRETS/MACHINE_LAST_CHANGE_TIME/"): - pass # FIXME - elif k.startswith("SECRETS/MACHINE_PASSWORD/"): - pass # FIXME - elif k.startswith("SECRETS/$MACHINE.ACC/"): - pass # FIXME - elif k.startswith("SECRETS/$DOMTRUST.ACC/"): - pass # FIXME - elif k == "INFO/random_seed": - self.random_seed = v - else: - raise "Unknown key %s in secrets database" % k + + def get_auth_password(self): + return self.tdb.get("SECRETS/AUTH_PASSWORD") + + def get_auth_domain(self): + return self.tdb.get("SECRETS/AUTH_DOMAIN") + + def get_auth_user(self): + return self.tdb.get("SECRETS/AUTH_USER") + + def get_dom_guid(self, host): + return self.tdb.get("SECRETS/DOMGUID/%s" % host) + + def get_ldap_bind_pw(self, host): + return self.tdb.get("SECRETS/LDAP_BIND_PW/%s" % host) + + def get_afs_keyfile(self, host): + return self.tdb.get("SECRETS/AFS_KEYFILE/%s" % host) + + def get_machine_sec_channel_type(self, host): + return self.tdb.get("SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s" % host) + + def get_machine_last_change_time(self, host): + return self.tdb.get("SECRETS/MACHINE_LAST_CHANGE_TIME/%s" % host) + + def get_machine_password(self, host): + return self.tdb.get("SECRETS/MACHINE_PASSWORD/%s" % host) + + def get_machine_acc(self, host): + return self.tdb.get("SECRETS/$MACHINE.ACC/%s" % host) + + def get_domtrust_acc(self, host): + return self.tdb.get("SECRETS/$DOMTRUST.ACC/%s" % host) + + def get_random_seed(self): + return self.tdb.get("INFO/random_seed") + + def get_sid(self, host): + return self.tdb.get("SECRETS/SID/%s" % host.upper()) + + def close(self): + self.tdb.close() + SHARE_DATABASE_VERSION_V1 = 1 SHARE_DATABASE_VERSION_V2 = 2 @@ -149,6 +182,8 @@ class ShareInfoDatabase: secdesc = self.tdb.get("SECDESC/%s" % name) # FIXME: Run ndr_pull_security_descriptor + def close(self): + self.tdb.close() ACB_DISABLED = 0x00000001 ACB_HOMDIRREQ = 0x00000002 @@ -190,16 +225,79 @@ class Smbpasswd: def __init__(self, file): pass +TDBSAM_FORMAT_STRING_V0 = "ddddddBBBBBBBBBBBBddBBwdwdBwwd" +TDBSAM_FORMAT_STRING_V1 = "dddddddBBBBBBBBBBBBddBBwdwdBwwd" +TDBSAM_FORMAT_STRING_V2 = "dddddddBBBBBBBBBBBBddBBBwwdBwwd" +TDBSAM_USER_PREFIX = "USER_" + class TdbSam: def __init__(self, file): self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + self.version = self.tdb.fetch_uint32("INFO/version") or 0 + assert self.version in (0, 1, 2) + + def usernames(self): + for k in self.tdb.keys(): + if k.startswith(TDBSAM_USER_PREFIX): + yield k[len(TDBSAM_USER_PREFIX):].rstrip("\0") + + def close(self): + self.tdb.close() + + +def shellsplit(text): + """Very simple shell-like line splitting. + + :param text: Text to split. + :return: List with parts of the line as strings. + """ + ret = list() + inquotes = False + current = "" + for c in text: + if c == "\"": + inquotes = not inquotes + elif c in ("\t", "\n", " ") and not inquotes: + ret.append(current) + current = "" + else: + current += c + if current != "": + ret.append(current) + return ret class WinsDatabase: def __init__(self, file): - pass + self.entries = {} + f = open(file, 'r') + assert f.readline().rstrip("\n") == "VERSION 1 0" + for l in f.readlines(): + if l[0] == "#": # skip comments + continue + entries = shellsplit(l.rstrip("\n")) + print entries + name = entries[0] + ttl = int(entries[1]) + i = 2 + ips = [] + while "." in entries[i]: + ips.append(entries[i]) + i+=1 + nb_flags = entries[i] + assert not name in self.entries, "Name %s exists twice" % name + self.entries[name] = (ttl, ips, nb_flags) + f.close() + + def __getitem__(self, name): + return self.entries[name] + def __len__(self): + return len(self.entries) + + def close(self): # for consistency + pass class Samba3: def __init__(self, smbconfpath, libdir): diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index 0d56ca9117..92d11d11d4 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -18,7 +18,8 @@ # import unittest -from samba.samba3 import GroupMappingDatabase, Registry, PolicyDatabase +from samba.samba3 import (GroupMappingDatabase, Registry, PolicyDatabase, SecretsDatabase, TdbSam, + WinsDatabase) import os DATADIR=os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") @@ -59,3 +60,55 @@ class GroupsTestCase(unittest.TestCase): def setUp(self): self.groupdb = GroupMappingDatabase(os.path.join(DATADIR, "group_mapping.tdb")) + def tearDown(self): + self.groupdb.close() + + def test_group_length(self): + self.assertEquals(13, len(list(self.groupdb.groupsids()))) + + def test_groupsids(self): + sids = list(self.groupdb.groupsids()) + self.assertTrue("S-1-5-32-544" in sids) + + def test_alias_length(self): + self.assertEquals(0, len(list(self.groupdb.aliases()))) + + +class SecretsDbTestCase(unittest.TestCase): + def setUp(self): + self.secretsdb = SecretsDatabase(os.path.join(DATADIR, "secrets.tdb")) + + def tearDown(self): + self.secretsdb.close() + + def test_get_sid(self): + self.assertTrue(self.secretsdb.get_sid("BEDWYR") is not None) + + +class TdbSamTestCase(unittest.TestCase): + def setUp(self): + self.samdb = TdbSam(os.path.join(DATADIR, "passdb.tdb")) + + def tearDown(self): + self.samdb.close() + + def test_usernames(self): + self.assertEquals(3, len(list(self.samdb.usernames()))) + + +class WinsDatabaseTestCase(unittest.TestCase): + def setUp(self): + self.winsdb = WinsDatabase(os.path.join(DATADIR, "wins.dat")) + + def test_length(self): + self.assertEquals(22, len(self.winsdb)) + + def test_first_entry(self): + self.assertEqual((1124185120, ["192.168.1.5"], "64R"), self.winsdb["ADMINISTRATOR#03"]) + + def tearDown(self): + self.winsdb.close() + +# FIXME: smbpasswd +# FIXME: idmapdb +# FIXME: Shares diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 3168fedf2d..4f2ab46ef0 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -530,14 +530,7 @@ data: %d if ldapurl is not None: message("Enabling Samba3 LDAP mappings for SAM database") - samdb.modify(""" -dn: @MODULES -changetype: modify -replace: @LIST -@LIST: samldb,operational,objectguid,rdn_name,samba3sam -""") - - samdb.add({"dn": "@MAP=samba3sam", "@MAP_URL": ldapurl}) + enable_samba3sam(samdb) return ret @@ -551,3 +544,15 @@ def upgrade_verify(subobj, samba3, paths, message): assert(len(msg) >= 1) # FIXME + + + +def enable_samba3sam(samdb): + samdb.modify(""" +dn: @MODULES +changetype: modify +replace: @LIST +@LIST: samldb,operational,objectguid,rdn_name,samba3sam +""") + + samdb.add({"dn": "@MAP=samba3sam", "@MAP_URL": ldapurl}) -- cgit From 8ada900ee67fc8e1a1ff94c9e5f7a50752d11017 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Dec 2007 14:16:40 -0600 Subject: r26590: Parsing routines for the smbpasswd file and idmap database. (This used to be commit 0c14e16a2bc965d3319ca990089566bff98a47fe) --- source4/scripting/python/samba/samba3.py | 96 ++++++++++++++++++++++++-- source4/scripting/python/samba/tests/samba3.py | 53 ++++++++++++-- 2 files changed, 140 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 509ee29c1d..b75b24ba34 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -108,16 +108,47 @@ class GroupMappingDatabase: # High water mark keys -HWM_GROUP = "GROUP HWM" -HWM_USER = "USER HWM" +IDMAP_HWM_GROUP = "GROUP HWM\0" +IDMAP_HWM_USER = "USER HWM\0" + +IDMAP_GROUP_PREFIX = "GID " +IDMAP_USER_PREFIX = "UID " # idmap version determines auto-conversion -IDMAP_VERSION = 2 +IDMAP_VERSION_V2 = 2 class IdmapDatabase: def __init__(self, file): self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) - assert self.tdb.fetch_int32("IDMAP_VERSION") == IDMAP_VERSION + assert self.tdb.fetch_int32("IDMAP_VERSION\0") == IDMAP_VERSION_V2 + + def uids(self): + for k in self.tdb.keys(): + if k.startswith(IDMAP_USER_PREFIX): + yield int(k[len(IDMAP_USER_PREFIX):].rstrip("\0")) + + def gids(self): + for k in self.tdb.keys(): + if k.startswith(IDMAP_GROUP_PREFIX): + yield int(k[len(IDMAP_GROUP_PREFIX):].rstrip("\0")) + + def get_user_sid(self, uid): + data = self.tdb.get("%s%d\0" % (IDMAP_USER_PREFIX, uid)) + if data is None: + return data + return data.rstrip("\0") + + def get_group_sid(self, gid): + data = self.tdb.get("%s%d\0" % (IDMAP_GROUP_PREFIX, gid)) + if data is None: + return data + return data.rstrip("\0") + + def get_user_hwm(self): + return self.tdb.fetch_uint32(IDMAP_HWM_USER) + + def get_group_hwm(self): + return self.tdb.fetch_uint32(IDMAP_HWM_GROUP) def close(self): self.tdb.close() @@ -181,6 +212,7 @@ class ShareInfoDatabase: def get_secdesc(self, name): secdesc = self.tdb.get("SECDESC/%s" % name) # FIXME: Run ndr_pull_security_descriptor + return secdesc def close(self): self.tdb.close() @@ -220,11 +252,65 @@ acb_info_mapping = { ' ': 0 } +def decode_acb(text): + assert not "[" in text and not "]" in text + ret = 0 + for x in text: + ret |= acb_info_mapping[x] + return ret -class Smbpasswd: + +class SmbpasswdFile: def __init__(self, file): + self.users = {} + f = open(file, 'r') + for l in f.readlines(): + if len(l) == 0 or l[0] == "#": + continue # Skip comments and blank lines + parts = l.split(":") + username = parts[0] + uid = int(parts[1]) + acct_ctrl = 0 + last_change_time = None + if parts[2] == "NO PASSWORD": + acct_ctrl |= ACB_PWNOTREQ + lm_password = None + elif parts[2][0] in ("*", "X"): + # No password set + lm_password = None + else: + lm_password = parts[2] + + if parts[3][0] in ("*", "X"): + # No password set + nt_password = None + else: + nt_password = parts[3] + + if parts[4][0] == '[': + assert "]" in parts[4] + acct_ctrl |= decode_acb(parts[4][1:-1]) + if parts[5].startswith("LCT-"): + last_change_time = int(parts[5][len("LCT-"):], 16) + else: # old style file + if username[-1] == "$": + acct_ctrl &= ~ACB_NORMAL + acct_ctrl |= ACB_WSTRUST + + self.users[username] = (uid, lm_password, nt_password, acct_ctrl, last_change_time) + + f.close() + + def __len__(self): + return len(self.users) + + def __getitem__(self, name): + return self.users[name] + + def close(self): # For consistency pass + TDBSAM_FORMAT_STRING_V0 = "ddddddBBBBBBBBBBBBddBBwdwdBwwd" TDBSAM_FORMAT_STRING_V1 = "dddddddBBBBBBBBBBBBddBBwdwdBwwd" TDBSAM_FORMAT_STRING_V2 = "dddddddBBBBBBBBBBBBddBBBwwdBwwd" diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index 92d11d11d4..580bcfa3c2 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -19,7 +19,7 @@ import unittest from samba.samba3 import (GroupMappingDatabase, Registry, PolicyDatabase, SecretsDatabase, TdbSam, - WinsDatabase) + WinsDatabase, SmbpasswdFile, ACB_NORMAL, IdmapDatabase) import os DATADIR=os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") @@ -109,6 +109,51 @@ class WinsDatabaseTestCase(unittest.TestCase): def tearDown(self): self.winsdb.close() -# FIXME: smbpasswd -# FIXME: idmapdb -# FIXME: Shares +class SmbpasswdTestCase(unittest.TestCase): + def setUp(self): + self.samdb = SmbpasswdFile(os.path.join(DATADIR, "smbpasswd")) + + def test_length(self): + self.assertEquals(3, len(self.samdb)) + + def test_get_user(self): + self.assertEquals((0, "552902031BEDE9EFAAD3B435B51404EE", "878D8014606CDA29677A44EFA1353FC7", ACB_NORMAL, int(1125418267)), self.samdb["rootpw"]) + + def tearDown(self): + self.samdb.close() + + +class IdmapDbTestCase(unittest.TestCase): + def setUp(self): + self.idmapdb = IdmapDatabase(os.path.join(DATADIR, "winbindd_idmap.tdb")) + + def test_user_hwm(self): + self.assertEquals(10000, self.idmapdb.get_user_hwm()) + + def test_group_hwm(self): + self.assertEquals(10002, self.idmapdb.get_group_hwm()) + + def test_uids(self): + self.assertEquals(1, len(list(self.idmapdb.uids()))) + + def test_gids(self): + self.assertEquals(3, len(list(self.idmapdb.gids()))) + + def test_get_user_sid(self): + self.assertEquals("S-1-5-21-58189338-3053988021-627566699-501", self.idmapdb.get_user_sid(65534)) + + def test_get_group_sid(self): + self.assertEquals("S-1-5-21-2447931902-1787058256-3961074038-3007", self.idmapdb.get_group_sid(10001)) + + def tearDown(self): + self.idmapdb.close() + + +class ShareInfoTestCase(unittest.TestCase): + def setUp(self): + self.shareinfodb = ShareInfoDatabase(os.path.join(DATADIR, "share_info.tdb")) + + # FIXME: needs proper data so it can be tested + + def tearDown(self): + self.shareinfodb.close() -- cgit From 3c22677a8ce1635d7e055f954153dec4c1796b17 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Dec 2007 14:16:59 -0600 Subject: r26591: Get the first bits of samba3dump to work again. (This used to be commit 3511027515f8ea860fbe46639d9169999646a297) --- source4/scripting/python/samba/samba3.py | 42 +++++++++++++++++++++++-------- source4/scripting/python/samba/upgrade.py | 4 +-- 2 files changed, 32 insertions(+), 14 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index b75b24ba34..40443bd8ba 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -170,6 +170,16 @@ class SecretsDatabase: def get_dom_guid(self, host): return self.tdb.get("SECRETS/DOMGUID/%s" % host) + def ldap_dns(self): + for k in self.tdb.keys(): + if k.startswith("SECRETS/LDAP_BIND_PW/"): + yield k[len("SECRETS/LDAP_BIND_PW/"):].rstrip("\0") + + def domains(self): + for k in self.tdb.keys(): + if k.startswith("SECRETS/SID/"): + yield k[len("SECRETS/SID/"):].rstrip("\0") + def get_ldap_bind_pw(self, host): return self.tdb.get("SECRETS/LDAP_BIND_PW/%s" % host) @@ -177,10 +187,10 @@ class SecretsDatabase: return self.tdb.get("SECRETS/AFS_KEYFILE/%s" % host) def get_machine_sec_channel_type(self, host): - return self.tdb.get("SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s" % host) + return self.tdb.fetch_uint32("SECRETS/MACHINE_SEC_CHANNEL_TYPE/%s" % host) def get_machine_last_change_time(self, host): - return self.tdb.get("SECRETS/MACHINE_LAST_CHANGE_TIME/%s" % host) + return self.tdb.fetch_uint32("SECRETS/MACHINE_LAST_CHANGE_TIME/%s" % host) def get_machine_password(self, host): return self.tdb.get("SECRETS/MACHINE_PASSWORD/%s" % host) @@ -191,6 +201,11 @@ class SecretsDatabase: def get_domtrust_acc(self, host): return self.tdb.get("SECRETS/$DOMTRUST.ACC/%s" % host) + def trusted_domains(self): + for k in self.tdb.keys(): + if k.startswith("SECRETS/$DOMTRUST.ACC/"): + yield k[len("SECRETS/$DOMTRUST.ACC/"):].rstrip("\0") + def get_random_seed(self): return self.tdb.get("INFO/random_seed") @@ -307,6 +322,9 @@ class SmbpasswdFile: def __getitem__(self, name): return self.users[name] + def __iter__(self): + return iter(self.entries) + def close(self): # For consistency pass @@ -363,7 +381,6 @@ class WinsDatabase: if l[0] == "#": # skip comments continue entries = shellsplit(l.rstrip("\n")) - print entries name = entries[0] ttl = int(entries[1]) i = 2 @@ -382,31 +399,34 @@ class WinsDatabase: def __len__(self): return len(self.entries) + def __iter__(self): + return iter(self.entries) + def close(self): # for consistency pass class Samba3: - def __init__(self, smbconfpath, libdir): + def __init__(self, libdir, smbconfpath): self.smbconfpath = smbconfpath self.libdir = libdir def get_policy_db(self): - return PolicyDatabase(os.path.join(libdir, "account_policy.tdb")) + return PolicyDatabase(os.path.join(self.libdir, "account_policy.tdb")) def get_registry(self): - return Registry(os.path.join(libdir, "registry.tdb")) + return Registry(os.path.join(self.libdir, "registry.tdb")) def get_secrets_db(self): - return SecretsDatabase(os.path.join(libdir, "secrets.tdb")) + return SecretsDatabase(os.path.join(self.libdir, "secrets.tdb")) def get_shares_db(self): - return ShareInfoDatabase(os.path.join(libdir, "share_info.tdb")) + return ShareInfoDatabase(os.path.join(self.libdir, "share_info.tdb")) def get_idmap_db(self): - return IdmapDatabase(os.path.join(libdir, "winbindd_idmap.tdb")) + return IdmapDatabase(os.path.join(self.libdir, "winbindd_idmap.tdb")) def get_wins_db(self): - return WinsDatabase(os.path.join(libdir, "wins.dat")) + return WinsDatabase(os.path.join(self.libdir, "wins.dat")) def get_groupmapping_db(self): - return GroupMappingDatabase(os.path.join(libdir, "group_mapping.tdb")) + return GroupMappingDatabase(os.path.join(self.libdir, "group_mapping.tdb")) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 4f2ab46ef0..375c39eb5a 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -447,7 +447,6 @@ def upgrade_smbconf(oldconf,mark): def upgrade(subobj, samba3, message, paths, session_info, credentials): ret = 0 - lp = loadparm_init() samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) message("Writing configuration") @@ -455,8 +454,7 @@ def upgrade(subobj, samba3, message, paths, session_info, credentials): newconf.save(paths.smbconf) message("Importing account policies") - ldif = upgrade_sam_policy(samba3,subobj.BASEDN) - samdb.modify(ldif) + samdb.modify_ldif(upgrade_sam_policy(samba3,subobj.BASEDN)) regdb = Ldb(paths.hklm) regdb.modify(""" -- cgit From cc30cb5e24160d107b67936d71f54645d9b3d23f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:23 -0600 Subject: r26592: Finish fixing the samba3dump script. (This used to be commit 85679f3fc98238f90280f9f10d42550d71eeb918) --- source4/scripting/python/samba/samba3.py | 63 +++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 40443bd8ba..d125e3164b 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -222,7 +222,7 @@ SHARE_DATABASE_VERSION_V2 = 2 class ShareInfoDatabase: def __init__(self, file): self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) - assert self.tdb.fetch_int32("INFO/version") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) + assert self.tdb.fetch_int32("INFO/version\0") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) def get_secdesc(self, name): secdesc = self.tdb.get("SECDESC/%s" % name) @@ -232,6 +232,19 @@ class ShareInfoDatabase: def close(self): self.tdb.close() + +class Shares: + def __init__(self, lp, shareinfo): + self.lp = lp + self.shareinfo = shareinfo + + def __len__(self): + return len(self.lp) - 1 + + def __iter__(self): + return self.lp.__iter__() + + ACB_DISABLED = 0x00000001 ACB_HOMDIRREQ = 0x00000002 ACB_PWNOTREQ = 0x00000004 @@ -323,7 +336,7 @@ class SmbpasswdFile: return self.users[name] def __iter__(self): - return iter(self.entries) + return iter(self.users) def close(self): # For consistency pass @@ -346,6 +359,8 @@ class TdbSam: if k.startswith(TDBSAM_USER_PREFIX): yield k[len(TDBSAM_USER_PREFIX):].rstrip("\0") + __iter__ = usernames + def close(self): self.tdb.close() @@ -409,24 +424,52 @@ class Samba3: def __init__(self, libdir, smbconfpath): self.smbconfpath = smbconfpath self.libdir = libdir + import param + self.lp = param.ParamFile() + self.lp.read(self.smbconfpath) + + def libdir_path(self, path): + if path[0] == "/" or path[0] == ".": + return path + return os.path.join(self.libdir, path) + + def get_conf(self): + return self.lp + + def get_sam_db(self): + lp = self.get_conf() + backends = str(lp.get("passdb backend")).split(" ") + if backends[0].startswith("smbpasswd"): + if ":" in backends[0]: + return SmbpasswdFile(self.libdir_path(backends[0][len("smbpasswd:"):])) + return SmbpasswdFile(self.libdir_path("smbpasswd")) + elif backends[0].startswith("tdbsam"): + if ":" in backends[0]: + return TdbSam(self.libdir_path(backends[0][len("tdbsam:"):])) + return TdbSam(self.libdir_path("passdb.tdb")) + else: + raise NotImplementedError("unsupported passdb backend %s" % backends[0]) def get_policy_db(self): - return PolicyDatabase(os.path.join(self.libdir, "account_policy.tdb")) + return PolicyDatabase(self.libdir_path("account_policy.tdb")) def get_registry(self): - return Registry(os.path.join(self.libdir, "registry.tdb")) + return Registry(self.libdir_path("registry.tdb")) def get_secrets_db(self): - return SecretsDatabase(os.path.join(self.libdir, "secrets.tdb")) + return SecretsDatabase(self.libdir_path("secrets.tdb")) - def get_shares_db(self): - return ShareInfoDatabase(os.path.join(self.libdir, "share_info.tdb")) + def get_shareinfo_db(self): + return ShareInfoDatabase(self.libdir_path("share_info.tdb")) def get_idmap_db(self): - return IdmapDatabase(os.path.join(self.libdir, "winbindd_idmap.tdb")) + return IdmapDatabase(self.libdir_path("winbindd_idmap.tdb")) def get_wins_db(self): - return WinsDatabase(os.path.join(self.libdir, "wins.dat")) + return WinsDatabase(self.libdir_path("wins.dat")) + + def get_shares(self): + return Shares(self.get_conf(), self.get_shareinfo_db()) def get_groupmapping_db(self): - return GroupMappingDatabase(os.path.join(self.libdir, "group_mapping.tdb")) + return GroupMappingDatabase(self.libdir_path("group_mapping.tdb")) -- cgit From 7c146c42d2cf51e891b9f29d3b61a40f173a3b23 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:31 -0600 Subject: r26593: - More work on the python versions of samba3dump and the samba3sam tests. - Initial work converting the upgrade code to Python. - Removed the old EJS upgrade code because it has been broken for a long time. (This used to be commit 150cf39fbd4fe088546870fb0d8f20c0d9eb4aca) --- source4/scripting/python/samba/samba3.py | 2 +- source4/scripting/python/samba/tests/__init__.py | 2 +- source4/scripting/python/samba/upgrade.py | 94 ++++++++---------------- 3 files changed, 33 insertions(+), 65 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index d125e3164b..b4261f7c74 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -167,7 +167,7 @@ class SecretsDatabase: def get_auth_user(self): return self.tdb.get("SECRETS/AUTH_USER") - def get_dom_guid(self, host): + def get_domain_guid(self, host): return self.tdb.get("SECRETS/DOMGUID/%s" % host) def ldap_dns(self): diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index b01807c02f..5885a3b507 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -43,7 +43,7 @@ class TestCaseInTempDir(unittest.TestCase): def tearDown(self): super(TestCaseInTempDir, self).tearDown() - # FIXME: Remove all files in self.tempdir + os.rmdir(self.tempdir) class SubstituteVarTestCase(unittest.TestCase): diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 375c39eb5a..c13351bc63 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -255,68 +255,44 @@ maxVersion: %llu return ldif -def upgrade_provision(lp, samba3): - domainname = samba3.configuration.get("workgroup") +def upgrade_provision(samba3, setup_dir, message, credentials, session_info, paths): + oldconf = samba3.get_conf() + + if oldconf.get("domain logons") == "True": + serverrole = "domain controller" + else: + if oldconf.get("security") == "user": + serverrole = "standalone" + else: + serverrole = "member server" + + domainname = oldconf.get("workgroup") + realm = oldconf.get("realm") + netbiosname = oldconf.get("netbios name") + + secrets_db = samba3.get_secrets_db() if domainname is None: - domainname = samba3.secrets.domains[0].name - print "No domain specified in smb.conf file, assuming '%s'\n" % domainname + domainname = secrets_db.domains()[0] + message("No domain specified in smb.conf file, assuming '%s'" % domainname) - domsec = samba3.find_domainsecrets(domainname) - hostsec = samba3.find_domainsecrets(hostname()) - realm = samba3.configuration.get("realm") - if realm is None: - realm = domainname - print "No realm specified in smb.conf file, assuming '%s'\n" % realm - random_init(local) + realm = domainname.lower() + message("No realm specified in smb.conf file, assuming '%s'\n" % realm) - subobj.realm = realm - subobj.domain = domainname - - if domsec is not None: - subobj.DOMAINGUID = domsec.guid - subobj.DOMAINSID = domsec.sid + domainguid = secrets_db.get_domain_guid(domainname) + domainsid = secrets_db.get_sid(domainsid) + if domainsid is None: + message("Can't find domain secrets for '%s'; using random SID\n" % domainname) + + if netbiosname is not None: + machinepass = secrets_db.get_machine_password(netbiosname) else: - print "Can't find domain secrets for '%s'; using random SID and GUID\n" % domainname - subobj.DOMAINGUID = uuid.random() - subobj.DOMAINSID = randsid() + netbiosname = None - if hostsec: - hostguid = hostsec.guid - subobj.krbtgtpass = randpass(12) - subobj.machinepass = randpass(12) - subobj.adminpass = randpass(12) - subobj.datestring = datestring() - subobj.root = findnss(pwd.getpwnam, "root")[4] - subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] - subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] - subobj.wheel = findnss(grp.getgrnam, "wheel", "root")[2] - subobj.users = findnss(grp.getgrnam, "users", "guest", "other")[2] - subobj.dnsdomain = subobj.realm.lower() - subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) - subobj.basedn = "DC=" + ",DC=".join(subobj.realm.split(".")) - rdn_list = subobj.dnsdomain.split(".") - subobj.domaindn = "DC=" + ",DC=".join(rdn_list) - subobj.domaindn_ldb = "users.ldb" - subobj.rootdn = subobj.domaindn - - modules_list = ["rootdse", - "kludge_acl", - "paged_results", - "server_sort", - "extended_dn", - "asq", - "samldb", - "password_hash", - "operational", - "objectclass", - "rdn_name", - "show_deleted", - "partition"] - subobj.modules_list = ",".join(modules_list) - - return subobj + provision(lp, setup_dir, message, blank=True, paths=path, session_info=session_info, + credentials=credentials, realm=realm, domain=domainname, + domainsid=domainsid, domainguid=domainguid, machinepass=machinepass, serverrole=serverrole) smbconf_keep = [ "dos charset", @@ -435,14 +411,6 @@ def upgrade_smbconf(oldconf,mark): elif mark: newconf.set(s, "samba3:"+p, oldconf.get(s,p)) - if oldconf.get("domain logons") == "True": - newconf.set("server role", "domain controller") - else: - if oldconf.get("security") == "user": - newconf.set("server role", "standalone") - else: - newconf.set("server role", "member server") - return newconf def upgrade(subobj, samba3, message, paths, session_info, credentials): -- cgit From e8bca8dd71c9bb64b84f6a74632a46a661be0d97 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:36 -0600 Subject: r26594: Add right paths to the Python sys.path setting so we don't have to set magic environment variables when running from the build directory. (This used to be commit 2d2674ad79330f59210408fd03e859afc01f40f2) --- source4/scripting/python/modules.c | 8 ++++++++ source4/scripting/python/smbpython.c | 7 +++++++ 2 files changed, 15 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 6a766f3412..2a88870660 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -43,3 +43,11 @@ void py_load_samba_modules(void) PyImport_ExtendInittab(&py_modules[i]); } } + +void py_update_path(const char *bindir) +{ + char *newpath; + asprintf(&newpath, "%s:%s/python:%s/../scripting/python", Py_GetPath(), bindir, bindir); + PySys_SetPath(newpath); + free(newpath); +} diff --git a/source4/scripting/python/smbpython.c b/source4/scripting/python/smbpython.c index 19c458e7ac..27286236ef 100644 --- a/source4/scripting/python/smbpython.c +++ b/source4/scripting/python/smbpython.c @@ -21,9 +21,16 @@ #include void py_load_samba_modules(void); +void py_update_path(const char *bindir); int main(int argc, char **argv) { py_load_samba_modules(); + Py_Initialize(); + if (strchr(argv[0], '/') != NULL) { + char *bindir = strndup(argv[0], strrchr(argv[0], '/')-argv[0]); + py_update_path(bindir); + free(bindir); + } return Py_Main(argc,argv); } -- cgit From cea31e32163fe639be72b3f4dfca1362c93b5576 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:39 -0600 Subject: r26595: Fix includes for hosts without gssapi as system header. (This used to be commit 64203a6b7b98be59af192290b0106979c2b2f71a) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 226f9637db..4a531f5062 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -12,7 +12,7 @@ PRIVATE_DEPENDENCIES = LIBNDR OBJ_FILES = uuidmodule.o [PYTHON::python_misc] -PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB +PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i # Swig extensions -- cgit From 533cc583ed20efdfd6bee60f86d16fef3942898b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:44 -0600 Subject: r26596: Fixed upgrade.py. Added blackbox tests for provision and upgrade Python scripts. Clean up temporary files created by the Python tests. (This used to be commit 2227fb6df62240cae64d27a1920d878316f819fc) --- source4/scripting/python/samba/__init__.py | 6 +++--- source4/scripting/python/samba/provision.py | 6 +++--- source4/scripting/python/samba/tests/__init__.py | 11 +++++++--- source4/scripting/python/samba/tests/provision.py | 10 ++++++--- source4/scripting/python/samba/upgrade.py | 26 ++++++++--------------- 5 files changed, 30 insertions(+), 29 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 5b34534133..359457d815 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -164,9 +164,9 @@ class Ldb(ldb.Ldb): self.add(msg) def modify_ldif(self, ldif): - for (changetype, msg) in ldb.parse_ldif(data): - assert changetype == CHANGETYPE_MODIFY - ldb.modify(msg) + for (changetype, msg) in self.parse_ldif(ldif): + assert changetype == ldb.CHANGETYPE_MODIFY + self.modify(msg) def substitute_var(text, values): diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a4e6c6a214..c4a3bb7fd6 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -95,7 +95,7 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None): assert "${" not in data - ldb.load_ldif_add(data) + ldb.add_ldif(data) def setup_modify_ldif(ldb, ldif_path, substvars=None): @@ -140,7 +140,7 @@ def setup_file(template, fname, substvars): open(f, 'w').write(data) -def provision_default_paths(lp, dnsdomain): +def provision_paths_from_lp(lp, dnsdomain): """Set the default paths for provisioning. :param lp: Loadparm context. @@ -605,7 +605,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, realm = lp.get("realm") else: if lp.get("realm").upper() != realm.upper(): - raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + raise Exception("realm '%s' in smb.conf must match chosen realm '%s'\n" % (lp.get("realm"), realm)) assert realm is not None diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index 5885a3b507..5e1ff87c2b 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -67,7 +67,12 @@ class SubstituteVarTestCase(unittest.TestCase): class LdbExtensionTests(TestCaseInTempDir): def test_searchone(self): - l = samba.Ldb(self.tempdir + "/searchone.ldb") - l.add({"dn": "foo=dc", "bar": "bla"}) - self.assertEquals("bla", l.searchone(ldb.Dn(l, "foo=dc"), "bar")) + path = self.tempdir + "/searchone.ldb" + l = samba.Ldb(path) + try: + l.add({"dn": "foo=dc", "bar": "bla"}) + self.assertEquals("bla", l.searchone(ldb.Dn(l, "foo=dc"), "bar")) + finally: + del l + os.unlink(path) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index bf7182dbd3..f5a0339c1f 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -29,10 +29,14 @@ def setup_path(file): class ProvisionTestCase(samba.tests.TestCaseInTempDir): def test_setup_secretsdb(self): - ldb = setup_secretsdb(os.path.join(self.tempdir, "secrets.ldb"), - setup_path, None, None, None) - self.assertEquals("LSA Secrets", + path = os.path.join(self.tempdir, "secrets.ldb") + ldb = setup_secretsdb(path, setup_path, None, None, None) + try: + self.assertEquals("LSA Secrets", ldb.searchone(Dn(ldb, "CN=LSA Secrets"), "CN")) + finally: + del ldb + os.unlink(path) class Disabled: diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index c13351bc63..05a63d9326 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -8,7 +8,6 @@ """Support code for upgrading from Samba 3 to Samba 4.""" from provision import findnss, provision -import provision import grp import pwd import uuid @@ -255,7 +254,7 @@ maxVersion: %llu return ldif -def upgrade_provision(samba3, setup_dir, message, credentials, session_info, paths): +def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, paths): oldconf = samba3.get_conf() if oldconf.get("domain logons") == "True": @@ -266,7 +265,11 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, pat else: serverrole = "member server" + lp.set("server role", serverrole) domainname = oldconf.get("workgroup") + if domainname: + domainname = str(domainname) + lp.set("workgroup", domainname) realm = oldconf.get("realm") netbiosname = oldconf.get("netbios name") @@ -279,18 +282,19 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, pat if realm is None: realm = domainname.lower() message("No realm specified in smb.conf file, assuming '%s'\n" % realm) + lp.set("realm", realm) domainguid = secrets_db.get_domain_guid(domainname) - domainsid = secrets_db.get_sid(domainsid) + domainsid = secrets_db.get_sid(domainname) if domainsid is None: message("Can't find domain secrets for '%s'; using random SID\n" % domainname) if netbiosname is not None: machinepass = secrets_db.get_machine_password(netbiosname) else: - netbiosname = None + machinepass = None - provision(lp, setup_dir, message, blank=True, paths=path, session_info=session_info, + provision(lp=lp, setup_dir=setup_dir, message=message, blank=True, ldapbackend=None, paths=paths, session_info=session_info, credentials=credentials, realm=realm, domain=domainname, domainsid=domainsid, domainguid=domainguid, machinepass=machinepass, serverrole=serverrole) @@ -500,18 +504,6 @@ data: %d return ret -def upgrade_verify(subobj, samba3, paths, message): - message("Verifying account policies") - - samldb = Ldb(paths.samdb) - - for account in samba3.samaccounts: - msg = samldb.search("(&(sAMAccountName=" + account.nt_username + ")(objectclass=user))") - assert(len(msg) >= 1) - - # FIXME - - def enable_samba3sam(samdb): samdb.modify(""" -- cgit From 327847b98765e29a10f70e2b7512bd9acd6a0570 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:50 -0600 Subject: r26597: Attempt to provide alternative for hosts that don't have python-config. (This used to be commit fa5d1923efe5c1dc7ef12757b41f8d8eafcb1288) --- source4/scripting/python/config.m4 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index b6ca7966df..a629aa8f92 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -19,10 +19,16 @@ if test -z "$PYTHON_CONFIG"; then AC_MSG_WARN([No python-config found]) else working_python=yes + PYTHON_LDFLAGS=`$PYTHON_CONFIG --ldflags` + PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags` fi -PYTHON_LDFLAGS=`$PYTHON_CONFIG --ldflags` -PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags` +if test $working_python = no && test x$PYTHON != x +then + PYTHON_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True), sysconfig.get_config_var('CFLAGS'))"` + PYTHON_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"` + working_python=yes +fi SMB_EXT_LIB(EXT_LIB_PYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) -- cgit From 7ff974a226b3dda63a91ef0702b12406e130f809 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:58 -0600 Subject: r26599: Attempt to also support provisioning using Python in the BECOME-DC test. Not tested yet as the test it is part of has been disabled because it's broken. (This used to be commit 6b1e25b702847cd6662b4aece35692b099707b74) --- source4/scripting/python/modules.h | 26 ++++++++++++++++++++++++++ source4/scripting/python/smbpython.c | 4 +--- 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 source4/scripting/python/modules.h (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.h b/source4/scripting/python/modules.h new file mode 100644 index 0000000000..238c73455f --- /dev/null +++ b/source4/scripting/python/modules.h @@ -0,0 +1,26 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 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 . +*/ + +#ifndef __SAMBA_PYTHON_MODULES_H__ +#define __SAMBA_PYTHON_MODULES_H__ + +void py_load_samba_modules(void); +void py_update_path(const char *bindir); + +#endif /* __SAMBA_PYTHON_MODULES_H__ */ diff --git a/source4/scripting/python/smbpython.c b/source4/scripting/python/smbpython.c index 27286236ef..c5de53fd60 100644 --- a/source4/scripting/python/smbpython.c +++ b/source4/scripting/python/smbpython.c @@ -19,9 +19,7 @@ #include "includes.h" #include - -void py_load_samba_modules(void); -void py_update_path(const char *bindir); +#include "scripting/python/modules.h" int main(int argc, char **argv) { -- cgit From 251a4e07803d0fa95b1324d60133475ef8c41e79 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:37:02 -0600 Subject: r26600: Provide dir variable with current basedir in Makefile. (This used to be commit b06d3e1a52d6b71a1e3e7a9e0ecf69f3b899ae18) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 4a531f5062..ecf8f9a102 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -33,7 +33,7 @@ pythonmods: $(PYTHON_DSOS) PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py pydoctor:: pythonmods - LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) + LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package $(dir)/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) clean:: @echo "Removing python modules" -- cgit From aa79008d4b8741cab917a75d4a7e1f8d6a25e897 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 17:34:07 -0600 Subject: r26602: Revert my previous commit as it only works with GNU make. (This used to be commit ecd2d96c3173e4d2f77a1ca50f26a16ac7a313b1) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index ecf8f9a102..4a531f5062 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -33,7 +33,7 @@ pythonmods: $(PYTHON_DSOS) PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py pydoctor:: pythonmods - LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package $(dir)/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) + LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) clean:: @echo "Removing python modules" -- cgit From c4d3666ac2821518be57ca89d963f77bbddaedf4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Dec 2007 20:55:05 -0600 Subject: r26607: Fix reading of values and subkeys in Samba 3 registry files. (This used to be commit e3d7454ef70d6fe9a1ce34eaf57268bd5b713ccf) --- source4/scripting/python/samba/samba3.py | 28 +++- source4/scripting/python/samba/tests/samba3.py | 8 ++ source4/scripting/python/samba/upgrade.py | 188 +++++++++---------------- 3 files changed, 102 insertions(+), 122 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index b4261f7c74..df94f3503c 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -45,16 +45,36 @@ class Registry: data = self.tdb.get("%s\x00" % key) if data is None: return [] - # FIXME: Parse data - return [] + import struct + (num, ) = struct.unpack(" 1: + elif type & 0x80: + if len(ips) > 1: rType = 0x2 else: rType = 0x1 else: - if numIPs > 1: + if len(ips) > 1: rType = 0x3 else: rType = 0x0 - if ttl > now: + if ttl > time.time(): rState = 0x0 # active else: rState = 0x1 # released - nType = ((e.nb_flags & 0x60)>>5) - - ldif += """ -dn: name=%s,type=0x%02X -type: 0x%02X -name: %s -objectClass: winsRecord -recordType: %u -recordState: %u -nodeType: %u -isStatic: 0 -expireTime: %s -versionID: %llu -""" % (e.name, e.type, e.type, e.name, - rType, rState, nType, - ldaptime(ttl), version_id) - - for ip in e.ips: - ldif += "address: %s\n" % ip - - ldif += """ -dn: CN=VERSION -objectClass: winsMaxVersion -maxVersion: %llu -""" % version_id + nType = ((nb_flags & 0x60)>>5) - return ldif + samba4_winsdb.add({"dn": "name=%s,type=0x%s" % name.split("#"), + "type": name.split("#")[1], + "name": name.split("#")[0], + "objectClass": "winsRecord", + "recordType": str(rType), + "recordState": str(rState), + "nodeType": str(nType), + "expireTime": ldb.ldaptime(ttl), + "isStatic": "0", + "versionID": str(version_id), + "address": ips}) + + samba4_winsdb.add({"dn": "CN=VERSION", + "objectClass": "winsMaxVersion", + "maxVersion": str(version_id)}) def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, paths): oldconf = samba3.get_conf() @@ -417,6 +360,30 @@ def upgrade_smbconf(oldconf,mark): return newconf +SAMBA3_PREDEF_NAMES = { + 'HKLM': registry.HKEY_LOCAL_MACHINE, +} + +def import_registry(samba4_registry, samba3_regdb): + """Import a Samba 3 registry database into the Samba 4 registry. + + :param samba4_registry: Samba 4 registry handle. + :param samba3_regdb: Samba 3 registry database handle. + """ + def ensure_key_exists(keypath): + (predef_name, keypath) = keypath.split("/", 1) + predef_id = SAMBA3_PREDEF_NAMES[predef_name] + keypath = keypath.replace("/", "\\") + return samba4_registry.create_key(predef_id, keypath) + + for key in samba3_regdb.keys(): + key_handle = ensure_key_exists(key) + for subkey in samba3_regdb.subkeys(key): + ensure_key_exists(subkey) + for (value_name, (value_type, value_data)) in samba3_regdb.values(key).items(): + key_handle.set_value(value_name, value_type, value_data) + + def upgrade(subobj, samba3, message, paths, session_info, credentials): ret = 0 samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) @@ -462,21 +429,6 @@ data: %d ret += 1 message(msg) - message("Importing registry data") - for hive in ["hkcr","hkcu","hklm","hkpd","hku","hkpt"]: - message("... " + hive) - regdb = Ldb(paths[hive]) - ldif = upgrade_registry(samba3.registry, hive, regdb) - for j in ldif: - msg = "... ... " + j - try: - regdb.add(ldif[j]) - except LdbError, e: - # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1 - message(msg) - message("Importing WINS data") winsdb = Ldb(paths.winsdb) ldb_erase(winsdb) -- cgit From 222262b54e74a01a66b3cbbea5502d4ce488905d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Dec 2007 03:09:49 -0600 Subject: r26608: More improvements to the upgrade code. (This used to be commit 7ea06d91f602f770f55a1171174f11b922fed8e7) --- source4/scripting/python/samba/provision.py | 2 + source4/scripting/python/samba/samba3.py | 165 +++++++++++++-- source4/scripting/python/samba/tests/samba3.py | 20 +- source4/scripting/python/samba/tests/upgrade.py | 8 +- source4/scripting/python/samba/upgrade.py | 260 +++++++++++++----------- 5 files changed, 307 insertions(+), 148 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c4a3bb7fd6..53eb1d618f 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -745,6 +745,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) + return domaindn + def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): setup_file(setup_path("phpldapadmin-config.php"), path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index df94f3503c..c9153d85cf 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -118,6 +118,15 @@ class GroupMappingDatabase: if k.startswith(GROUP_PREFIX): yield k[len(GROUP_PREFIX):].rstrip("\0") + def get_group(self, sid): + data = self.tdb.get("%s%s\0" % (GROUP_PREFIX, sid)) + if data is None: + return data + import struct + (gid, sid_name_use) = struct.unpack("username, /* B */ +# &domain_len, &sampass->domain, /* B */ +# &nt_username_len, &sampass->nt_username, /* B */ +# &fullname_len, &sampass->fullname, /* B */ +# &homedir_len, &sampass->homedir, /* B */ +# &dir_drive_len, &sampass->dir_drive, /* B */ +# &logon_script_len, &sampass->logon_script, /* B */ +# &profile_path_len, &sampass->profile_path, /* B */ +# &acct_desc_len, &sampass->acct_desc, /* B */ +# &workstations_len, &sampass->workstations, /* B */ +# &unknown_str_len, &sampass->unknown_str, /* B */ +# &munged_dial_len, &sampass->munged_dial, /* B */ +# &sampass->user_rid, /* d */ +# &sampass->group_rid, /* d */ +# &lm_pw_len, sampass->lm_pw.hash, /* B */ +# &nt_pw_len, sampass->nt_pw.hash, /* B */ +# &sampass->acct_ctrl, /* w */ +# &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */ +# &sampass->logon_divs, /* w */ +# &sampass->hours_len, /* d */ +# &hourslen, &sampass->hours, /* B */ +# &sampass->bad_password_count, /* w */ +# &sampass->logon_count, /* w */ +# &sampass->unknown_6); /* d */ +# + return user def close(self): self.tdb.close() @@ -423,7 +542,7 @@ class WinsDatabase: while "." in entries[i]: ips.append(entries[i]) i+=1 - nb_flags = entries[i] + nb_flags = int(entries[i][:-1], 16) assert not name in self.entries, "Name %s exists twice" % name self.entries[name] = (ttl, ips, nb_flags) f.close() @@ -437,6 +556,9 @@ class WinsDatabase: def __iter__(self): return iter(self.entries) + def items(self): + return self.entries.items() + def close(self): # for consistency pass @@ -459,14 +581,19 @@ class Samba3: def get_sam_db(self): lp = self.get_conf() backends = str(lp.get("passdb backend")).split(" ") - if backends[0].startswith("smbpasswd"): - if ":" in backends[0]: - return SmbpasswdFile(self.libdir_path(backends[0][len("smbpasswd:"):])) - return SmbpasswdFile(self.libdir_path("smbpasswd")) - elif backends[0].startswith("tdbsam"): - if ":" in backends[0]: - return TdbSam(self.libdir_path(backends[0][len("tdbsam:"):])) - return TdbSam(self.libdir_path("passdb.tdb")) + if ":" in backends[0]: + (name, location) = backends[0].split(":", 2) + else: + name = backends[0] + location = None + if name == "smbpasswd": + return SmbpasswdFile(self.libdir_path(location or "smbpasswd")) + elif name == "tdbsam": + return TdbSam(self.libdir_path(location or "passdb.tdb")) + elif name == "ldapsam": + if location is not None: + return LdapSam("ldap:%s" % location) + return LdapSam(lp.get("ldap server")) else: raise NotImplementedError("unsupported passdb backend %s" % backends[0]) diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index e25562929a..22b21ba1b4 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -19,7 +19,7 @@ import unittest from samba.samba3 import (GroupMappingDatabase, Registry, PolicyDatabase, SecretsDatabase, TdbSam, - WinsDatabase, SmbpasswdFile, ACB_NORMAL, IdmapDatabase) + WinsDatabase, SmbpasswdFile, ACB_NORMAL, IdmapDatabase, SAMUser) import os DATADIR=os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") @@ -74,6 +74,9 @@ class GroupsTestCase(unittest.TestCase): def test_group_length(self): self.assertEquals(13, len(list(self.groupdb.groupsids()))) + def test_get_group(self): + self.assertEquals((-1, 5L, 'Administrators', ''), self.groupdb.get_group("S-1-5-32-544")) + def test_groupsids(self): sids = list(self.groupdb.groupsids()) self.assertTrue("S-1-5-32-544" in sids) @@ -103,6 +106,11 @@ class TdbSamTestCase(unittest.TestCase): def test_usernames(self): self.assertEquals(3, len(list(self.samdb.usernames()))) + def test_getuser(self): + return + user = SAMUser("root") + self.assertEquals(user, self.samdb["root"]) + class WinsDatabaseTestCase(unittest.TestCase): def setUp(self): @@ -112,7 +120,7 @@ class WinsDatabaseTestCase(unittest.TestCase): self.assertEquals(22, len(self.winsdb)) def test_first_entry(self): - self.assertEqual((1124185120, ["192.168.1.5"], "64R"), self.winsdb["ADMINISTRATOR#03"]) + self.assertEqual((1124185120, ["192.168.1.5"], 0x64), self.winsdb["ADMINISTRATOR#03"]) def tearDown(self): self.winsdb.close() @@ -125,7 +133,13 @@ class SmbpasswdTestCase(unittest.TestCase): self.assertEquals(3, len(self.samdb)) def test_get_user(self): - self.assertEquals((0, "552902031BEDE9EFAAD3B435B51404EE", "878D8014606CDA29677A44EFA1353FC7", ACB_NORMAL, int(1125418267)), self.samdb["rootpw"]) + user = SAMUser("rootpw") + user.lm_password = "552902031BEDE9EFAAD3B435B51404EE" + user.nt_password = "878D8014606CDA29677A44EFA1353FC7" + user.acct_ctrl = ACB_NORMAL + user.pass_last_set_time = int(1125418267) + user.uid = 0 + self.assertEquals(user, self.samdb["rootpw"]) def tearDown(self): self.samdb.close() diff --git a/source4/scripting/python/samba/tests/upgrade.py b/source4/scripting/python/samba/tests/upgrade.py index a25743425b..ddafa00691 100644 --- a/source4/scripting/python/samba/tests/upgrade.py +++ b/source4/scripting/python/samba/tests/upgrade.py @@ -17,12 +17,6 @@ # along with this program. If not, see . # -from samba.upgrade import regkey_to_dn +import samba.upgrade from unittest import TestCase -class RegkeyDnTests(TestCase): - def test_empty(self): - self.assertEquals("hive=NONE", regkey_to_dn("")) - - def test_nested(self): - self.assertEquals("key=bar,key=foo,hive=NONE", regkey_to_dn("foo/bar")) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index a6bd07df58..3ecfe872f9 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -9,20 +9,15 @@ from provision import findnss, provision import grp +import ldb import pwd import uuid import registry +from samba import Ldb +from samba.samdb import SamDB -# Where prefix is any of: -# - HKLM -# HKU -# HKCR -# HKPD -# HKPT -# - -def upgrade_sam_policy(policy,dn): - ldif = """ +def import_sam_policy(samldb, samba3_policy, domaindn): + samldb.modify_ldif(""" dn: %s changetype: modify replace: minPwdLength @@ -40,19 +35,24 @@ samba3DisconnectTime: %d policy.password_history, policy.minimum_password_age, policy.maximum_password_age, policy.lockout_duration, policy.reset_count_minutes, policy.user_must_logon_to_change_password, - policy.bad_lockout_minutes, policy.disconnect_time) - - return ldif + policy.bad_lockout_minutes, policy.disconnect_time)) + -def upgrade_sam_account(ldb,acc,domaindn,domainsid): - """Upgrade a SAM account.""" +def import_sam_account(samldb,acc,domaindn,domainsid): + """Import a Samba 3 SAM account. + + :param samldb: Samba 4 SAM Database handle + :param acc: Samba 3 account + :param domaindn: Domain DN + :param domainsid: Domain SID.""" if acc.nt_username is None or acc.nt_username == "": acc.nt_username = acc.username if acc.fullname is None: - acc.fullname = pwd.getpwnam(acc.fullname)[4] - - acc.fullname = acc.fullname.split(",")[0] + try: + acc.fullname = pwd.getpwnam(acc.username)[4].split(",")[0] + except KeyError: + pass if acc.fullname is None: acc.fullname = acc.username @@ -60,105 +60,113 @@ def upgrade_sam_account(ldb,acc,domaindn,domainsid): assert acc.fullname is not None assert acc.nt_username is not None - ldif = """dn: cn=%s,%s -objectClass: top -objectClass: user -lastLogon: %d -lastLogoff: %d -unixName: %s -sAMAccountName: %s -cn: %s -description: %s -primaryGroupID: %d -badPwdcount: %d -logonCount: %d -samba3Domain: %s -samba3DirDrive: %s -samba3MungedDial: %s -samba3Homedir: %s -samba3LogonScript: %s -samba3ProfilePath: %s -samba3Workstations: %s -samba3KickOffTime: %d -samba3BadPwdTime: %d -samba3PassLastSetTime: %d -samba3PassCanChangeTime: %d -samba3PassMustChangeTime: %d -objectSid: %s-%d -lmPwdHash:: %s -ntPwdHash:: %s - -""" % (ldb.dn_escape(acc.fullname), domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, acc.nt_username, -acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count, -acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script, -acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time, -acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid, - ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw)) - - return ldif - -def upgrade_sam_group(group,domaindn): - """Upgrade a SAM group.""" - if group.sid_name_use == 5: # Well-known group + samldb.add({ + "dn": "cn=%s,%s" % (acc.fullname, domaindn), + "objectClass": ["top", "user"], + "lastLogon": str(acc.logon_time), + "lastLogoff": str(acc.logoff_time), + "unixName": acc.username, + "sAMAccountName": acc.nt_username, + "cn": acc.nt_username, + "description": acc.acct_desc, + "primaryGroupID": str(acc.group_rid), + "badPwdcount": str(acc.bad_password_count), + "logonCount": str(acc.logon_count), + "samba3Domain": acc.domain, + "samba3DirDrive": acc.dir_drive, + "samba3MungedDial": acc.munged_dial, + "samba3Homedir": acc.homedir, + "samba3LogonScript": acc.logon_script, + "samba3ProfilePath": acc.profile_path, + "samba3Workstations": acc.workstations, + "samba3KickOffTime": str(acc.kickoff_time), + "samba3BadPwdTime": str(acc.bad_password_time), + "samba3PassLastSetTime": str(acc.pass_last_set_time), + "samba3PassCanChangeTime": str(acc.pass_can_change_time), + "samba3PassMustChangeTime": str(acc.pass_must_change_time), + "objectSid": "%s-%d" % (domainsid, acc.user_rid), + "lmPwdHash:": acc.lm_password, + "ntPwdHash:": acc.nt_password, + }) + + +def import_sam_group(samldb, sid, gid, sid_name_use, nt_name, comment, domaindn): + """Upgrade a SAM group. + + :param samldb: SAM database. + :param gid: Group GID + :param sid_name_use: SID name use + :param nt_name: NT Group Name + :param comment: NT Group Comment + :param domaindn: Domain DN + """ + + if sid_name_use == 5: # Well-known group return None - if group.nt_name in ("Domain Guests", "Domain Users", "Domain Admins"): + if nt_name in ("Domain Guests", "Domain Users", "Domain Admins"): return None - if group.gid == -1: - gr = grp.getgrnam(grp.nt_name) + if gid == -1: + gr = grp.getgrnam(nt_name) else: - gr = grp.getgrgid(grp.gid) + gr = grp.getgrgid(gid) if gr is None: - group.unixname = "UNKNOWN" + unixname = "UNKNOWN" else: - group.unixname = gr.gr_name + unixname = gr.gr_name - assert group.unixname is not None + assert unixname is not None - ldif = """dn: cn=%s,%s -objectClass: top -objectClass: group -description: %s -cn: %s -objectSid: %s -unixName: %s -samba3SidNameUse: %d -""" % (group.nt_name, domaindn, -group.comment, group.nt_name, group.sid, group.unixname, group.sid_name_use) - - return ldif - -def import_idmap(samba4_idmap,samba3_idmap,domaindn): - samba4_idmap.add({ + samldb.add({ + "dn": "cn=%s,%s" % (nt_name, domaindn), + "objectClass": ["top", "group"], + "description": comment, + "cn": nt_name, + "objectSid": sid, + "unixName": unixname, + "samba3SidNameUse": str(sid_name_use) + }) + + +def import_idmap(samdb,samba3_idmap,domaindn): + """Import idmap data. + + :param samdb: SamDB handle. + :param samba3_idmap: Samba 3 IDMAP database to import from + :param domaindn: Domain DN. + """ + samdb.add({ "dn": domaindn, "userHwm": str(samba3_idmap.get_user_hwm()), "groupHwm": str(samba3_idmap.get_group_hwm())}) for uid in samba3_idmap.uids(): - samba4_idmap.add({"dn": "SID=%s,%s" % (samba3_idmap.get_user_sid(uid), domaindn), + samdb.add({"dn": "SID=%s,%s" % (samba3_idmap.get_user_sid(uid), domaindn), "SID": samba3_idmap.get_user_sid(uid), "type": "user", "unixID": str(uid)}) for gid in samba3_idmap.uids(): - samba4_idmap.add({"dn": "SID=%s,%s" % (samba3_idmap.get_group_sid(gid), domaindn), + samdb.add({"dn": "SID=%s,%s" % (samba3_idmap.get_group_sid(gid), domaindn), "SID": samba3_idmap.get_group_sid(gid), "type": "group", "unixID": str(gid)}) def import_wins(samba4_winsdb, samba3_winsdb): - """Import settings from a Samba3 WINS database.""" + """Import settings from a Samba3 WINS database. + + :param samba4_winsdb: WINS database to import to + :param samba3_winsdb: WINS database to import from + """ version_id = 0 import time for (name, (ttl, ips, nb_flags)) in samba3_winsdb.items(): version_id+=1 - numIPs = len(e.ips) - type = int(name.split("#", 1)[1], 16) if type == 0x1C: @@ -181,14 +189,14 @@ def import_wins(samba4_winsdb, samba3_winsdb): nType = ((nb_flags & 0x60)>>5) - samba4_winsdb.add({"dn": "name=%s,type=0x%s" % name.split("#"), + samba4_winsdb.add({"dn": "name=%s,type=0x%s" % tuple(name.split("#")), "type": name.split("#")[1], "name": name.split("#")[0], "objectClass": "winsRecord", "recordType": str(rType), "recordState": str(rState), "nodeType": str(nType), - "expireTime": ldb.ldaptime(ttl), + "expireTime": ldb.timestring(ttl), "isStatic": "0", "versionID": str(version_id), "address": ips}) @@ -237,9 +245,52 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, else: machinepass = None - provision(lp=lp, setup_dir=setup_dir, message=message, blank=True, ldapbackend=None, paths=paths, session_info=session_info, - credentials=credentials, realm=realm, domain=domainname, - domainsid=domainsid, domainguid=domainguid, machinepass=machinepass, serverrole=serverrole) + domaindn = provision(lp=lp, setup_dir=setup_dir, message=message, blank=True, ldapbackend=None, + paths=paths, session_info=session_info, credentials=credentials, realm=realm, + domain=domainname, domainsid=domainsid, domainguid=domainguid, + machinepass=machinepass, serverrole=serverrole) + + samdb = SamDB(paths.samdb, credentials=credentials, lp=lp, session_info=session_info) + + import_wins(Ldb(paths.winsdb), samba3.get_wins_db()) + + # FIXME: import_registry(registry.Registry(), samba3.get_registry()) + + # FIXME: import_idmap(samdb,samba3.get_idmap_db(),domaindn) + + groupdb = samba3.get_groupmapping_db() + for sid in groupdb.groupsids(): + (gid, sid_name_use, nt_name, comment) = groupdb.get_group(sid) + # FIXME: import_sam_group(samdb, sid, gid, sid_name_use, nt_name, comment, domaindn) + + # FIXME: Aliases + + passdb = samba3.get_sam_db() + for name in passdb: + user = passdb[name] + #FIXME: import_sam_account(samdb, user, domaindn, domainsid) + + if hasattr(passdb, 'ldap_url'): + message("Enabling Samba3 LDAP mappings for SAM database") + + enable_samba3sam(samdb, passdb.ldap_url) + + +def enable_samba3sam(samdb, ldapurl): + """Enable Samba 3 LDAP URL database. + + :param samdb: SAM Database. + :param ldapurl: Samba 3 LDAP URL + """ + samdb.modify_ldif(""" +dn: @MODULES +changetype: modify +replace: @LIST +@LIST: samldb,operational,objectguid,rdn_name,samba3sam +""") + + samdb.add({"dn": "@MAP=samba3sam", "@MAP_URL": ldapurl}) + smbconf_keep = [ "dos charset", @@ -436,33 +487,4 @@ data: %d ldif = upgrade_wins(samba3) winsdb.add(ldif) - # figure out ldapurl, if applicable - ldapurl = None - pdb = samba3.configuration.get_list("passdb backend") - if pdb is not None: - for backend in pdb: - if len(backend) >= 7 and backend[0:7] == "ldapsam": - ldapurl = backend[7:] - - # URL was not specified in passdb backend but ldap /is/ used - if ldapurl == "": - ldapurl = "ldap://%s" % samba3.configuration.get("ldap server") - # Enable samba3sam module if original passdb backend was ldap - if ldapurl is not None: - message("Enabling Samba3 LDAP mappings for SAM database") - - enable_samba3sam(samdb) - - return ret - - -def enable_samba3sam(samdb): - samdb.modify(""" -dn: @MODULES -changetype: modify -replace: @LIST -@LIST: samldb,operational,objectguid,rdn_name,samba3sam -""") - - samdb.add({"dn": "@MAP=samba3sam", "@MAP_URL": ldapurl}) -- cgit From 094f364fe172a117fd1cf8ae1855fd72fca8e5b4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Dec 2007 23:31:42 -0600 Subject: r26614: Fix options parsing for credentials in Python. (This used to be commit 9ef3b7de6baadeb2240ef9d24c55be9dc4cccf1e) --- source4/scripting/python/samba/getopt.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 8143dcafdb..3335c55bc6 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -35,12 +35,24 @@ class VersionOptions(optparse.OptionGroup): class CredentialsOptions(optparse.OptionGroup): def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Credentials Options") - self.add_option("--simple-bind-dn", type="string", metavar="DN", + self.add_option("--simple-bind-dn", metavar="DN", action="callback", + callback=self.set_simple_bind_dn, type=str, help="DN to use for a simple bind") - self.add_option("--password", type="string", metavar="PASSWORD", - help="Password") + self.add_option("--password", metavar="PASSWORD", action="callback", + help="Password", type=str, callback=self.set_password) + self.add_option("-U", "--username", metavar="USERNAME", + action="callback", type=str, + help="username", callback=self.parse_username) + self.creds = Credentials() + + def parse_username(self, option, opt_str, arg, parser): + self.creds.parse_string(arg) + + def set_password(self, option, opt_str, arg, parser): + self.creds.set_password(arg) + + def set_simple_bind_dn(self, option, opt_str, arg, parser): + self.creds.set_simple_bind_dn(arg) def get_credentials(self): - creds = Credentials() - # FIXME: Update - return creds + return self.creds -- cgit From 8ad2a035e35284f50ed2650bb202f050416de248 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Dec 2007 23:31:59 -0600 Subject: r26616: Support parsing of user data in SAmba 3 tdbsam. (This used to be commit 2f33e0451d6699fed8bc9abfa2f331317502b358) --- source4/scripting/python/samba/getopt.py | 2 +- source4/scripting/python/samba/samba3.py | 139 ++++++++++++++----------- source4/scripting/python/samba/tests/samba3.py | 32 +++++- source4/scripting/python/samba/upgrade.py | 53 ---------- 4 files changed, 111 insertions(+), 115 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 3335c55bc6..014dd336d8 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -23,7 +23,7 @@ from credentials import Credentials class SambaOptions(optparse.OptionGroup): def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Samba Common Options") - self.add_option("--configfile", type="string", metavar="FILE", + self.add_option("-s", "--configfile", type="string", metavar="FILE", help="Configuration file") diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index c9153d85cf..27656900ad 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -324,7 +324,8 @@ class SAMUser: domain=None, dir_drive=None, munged_dial=None, homedir=None, logon_script=None, profile_path=None, workstations=None, kickoff_time=None, bad_password_time=None, pass_last_set_time=None, pass_can_change_time=None, pass_must_change_time=None, - user_rid=None): + user_rid=None, unknown_6=None, nt_password_history=None, + unknown_str=None, hours=None, logon_divs=None): self.username = name self.uid = uid self.lm_password = lm_password @@ -351,37 +352,16 @@ class SAMUser: self.pass_can_change_time = pass_can_change_time self.pass_must_change_time = pass_must_change_time self.user_rid = user_rid + self.unknown_6 = unknown_6 + self.nt_password_history = nt_password_history + self.unknown_str = unknown_str + self.hours = hours + self.logon_divs = logon_divs def __eq__(self, other): if not isinstance(other, SAMUser): return False - return (self.username == other.username and - self.uid == other.uid and - self.lm_password == other.lm_password and - self.nt_password == other.nt_password and - self.acct_ctrl == other.acct_ctrl and - self.pass_last_set_time == other.pass_last_set_time and - self.nt_username == other.nt_username and - self.fullname == other.fullname and - self.logon_time == other.logon_time and - self.logoff_time == other.logoff_time and - self.acct_desc == other.acct_desc and - self.group_rid == other.group_rid and - self.bad_password_count == other.bad_password_count and - self.logon_count == other.logon_count and - self.domain == other.domain and - self.dir_drive == other.dir_drive and - self.munged_dial == other.munged_dial and - self.homedir == other.homedir and - self.logon_script == other.logon_script and - self.profile_path == other.profile_path and - self.workstations == other.workstations and - self.kickoff_time == other.kickoff_time and - self.bad_password_time == other.bad_password_time and - self.pass_can_change_time == other.pass_can_change_time and - self.pass_must_change_time == other.pass_must_change_time and - self.user_rid == other.user_rid) - + return self.__dict__ == other.__dict__ class SmbpasswdFile: def __init__(self, file): @@ -451,7 +431,7 @@ class LdapSam: class TdbSam: def __init__(self, file): self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) - self.version = self.tdb.fetch_uint32("INFO/version") or 0 + self.version = self.tdb.fetch_uint32("INFO/version\0") or 0 assert self.version in (0, 1, 2) def usernames(self): @@ -463,41 +443,82 @@ class TdbSam: def __getitem__(self, name): data = self.tdb["%s%s\0" % (TDBSAM_USER_PREFIX, name)] - import struct - (logon_time, logoff_time, kickoff_time, pass_last_set_time, pass_can_change_time, \ - pass_must_change_time) = struct.unpack(" 0: + (bad_password_time, data) = unpack_int32(data) + if bad_password_time != 0: + user.bad_password_time = bad_password_time + (pass_last_set_time, data) = unpack_int32(data) + (pass_can_change_time, data) = unpack_int32(data) + (pass_must_change_time, data) = unpack_int32(data) + + if logon_time != 0: + user.logon_time = logon_time user.logoff_time = logoff_time user.kickoff_time = kickoff_time - user.pass_last_set_time = pass_last_set_time + if pass_last_set_time != 0: + user.pass_last_set_time = pass_last_set_time user.pass_can_change_time = pass_can_change_time -# &username_len, &sampass->username, /* B */ -# &domain_len, &sampass->domain, /* B */ -# &nt_username_len, &sampass->nt_username, /* B */ -# &fullname_len, &sampass->fullname, /* B */ -# &homedir_len, &sampass->homedir, /* B */ -# &dir_drive_len, &sampass->dir_drive, /* B */ -# &logon_script_len, &sampass->logon_script, /* B */ -# &profile_path_len, &sampass->profile_path, /* B */ -# &acct_desc_len, &sampass->acct_desc, /* B */ -# &workstations_len, &sampass->workstations, /* B */ -# &unknown_str_len, &sampass->unknown_str, /* B */ -# &munged_dial_len, &sampass->munged_dial, /* B */ -# &sampass->user_rid, /* d */ -# &sampass->group_rid, /* d */ -# &lm_pw_len, sampass->lm_pw.hash, /* B */ -# &nt_pw_len, sampass->nt_pw.hash, /* B */ -# &sampass->acct_ctrl, /* w */ -# &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */ -# &sampass->logon_divs, /* w */ -# &sampass->hours_len, /* d */ -# &hourslen, &sampass->hours, /* B */ -# &sampass->bad_password_count, /* w */ -# &sampass->logon_count, /* w */ -# &sampass->unknown_6); /* d */ -# + (user.username, data) = unpack_string(data) + (user.domain, data) = unpack_string(data) + (user.nt_username, data) = unpack_string(data) + (user.fullname, data) = unpack_string(data) + (user.homedir, data) = unpack_string(data) + (user.dir_drive, data) = unpack_string(data) + (user.logon_script, data) = unpack_string(data) + (user.profile_path, data) = unpack_string(data) + (user.acct_desc, data) = unpack_string(data) + (user.workstations, data) = unpack_string(data) + (user.unknown_str, data) = unpack_string(data) + (user.munged_dial, data) = unpack_string(data) + + (user.user_rid, data) = unpack_int32(data) + (user.group_rid, data) = unpack_int32(data) + + (user.lm_password, data) = unpack_string(data) + (user.nt_password, data) = unpack_string(data) + + if self.version > 1: + (user.nt_password_history, data) = unpack_string(data) + + (user.acct_ctrl, data) = unpack_uint16(data) + (_, data) = unpack_uint32(data) # remove_me field + (user.logon_divs, data) = unpack_uint16(data) + (hours, data) = unpack_string(data) + user.hours = [] + for entry in hours: + for i in range(8): + user.hours.append(ord(entry) & (2 ** i) == (2 ** i)) + (user.bad_password_count, data) = unpack_uint16(data) + (user.logon_count, data) = unpack_uint16(data) + (user.unknown_6, data) = unpack_uint32(data) + assert len(data) == 0 return user def close(self): diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index 22b21ba1b4..175aa90497 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -107,9 +107,37 @@ class TdbSamTestCase(unittest.TestCase): self.assertEquals(3, len(list(self.samdb.usernames()))) def test_getuser(self): - return user = SAMUser("root") - self.assertEquals(user, self.samdb["root"]) + user.logoff_time = 2147483647 + user.kickoff_time = 2147483647 + user.pass_can_change_time = 1125418267 + user.username = "root" + user.uid = None + user.lm_password = 'U)\x02\x03\x1b\xed\xe9\xef\xaa\xd3\xb45\xb5\x14\x04\xee' + user.nt_password = '\x87\x8d\x80\x14`l\xda)gzD\xef\xa15?\xc7' + user.acct_ctrl = 16 + user.pass_last_set_time = 1125418267 + user.fullname = "root" + user.nt_username = "" + user.logoff_time = 2147483647 + user.acct_desc = "" + user.group_rid = 1001 + user.logon_count = 0 + user.bad_password_count = 0 + user.domain = "BEDWYR" + user.munged_dial = "" + user.workstations = "" + user.user_rid = 1000 + user.kickoff_time = 2147483647 + user.logoff_time = 2147483647 + user.unknown_6 = 1260L + user.logon_divs = 0 + user.hours = [True for i in range(168)] + other = self.samdb["root"] + for name in other.__dict__: + if other.__dict__[name] != user.__dict__[name]: + print "%s: %r != %r" % (name, other.__dict__[name], user.__dict__[name]) + self.assertEquals(user, other) class WinsDatabaseTestCase(unittest.TestCase): diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 3ecfe872f9..abf1127c36 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -435,56 +435,3 @@ def import_registry(samba4_registry, samba3_regdb): key_handle.set_value(value_name, value_type, value_data) -def upgrade(subobj, samba3, message, paths, session_info, credentials): - ret = 0 - samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) - - message("Writing configuration") - newconf = upgrade_smbconf(samba3.configuration,True) - newconf.save(paths.smbconf) - - message("Importing account policies") - samdb.modify_ldif(upgrade_sam_policy(samba3,subobj.BASEDN)) - regdb = Ldb(paths.hklm) - - regdb.modify(""" -dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE -replace: type -type: 4 -replace: data -data: %d -""" % policy.refuse_machine_password_change) - - message("Importing users") - for account in samba3.samaccounts: - msg = "... " + account.username - ldif = upgrade_sam_account(samdb, accounts,subobj.BASEDN,subobj.DOMAINSID) - try: - samdb.add(ldif) - except LdbError, e: - # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1; - message(msg) - - message("Importing groups") - for mapping in samba3.groupmappings: - msg = "... " + mapping.nt_name - ldif = upgrade_sam_group(mapping, subobj.BASEDN) - if ldif is not None: - try: - samdb.add(ldif) - except LdbError, e: - # FIXME: Ignore 'Record exists' errors - msg += "... error: " + str(e) - ret += 1 - message(msg) - - message("Importing WINS data") - winsdb = Ldb(paths.winsdb) - ldb_erase(winsdb) - - ldif = upgrade_wins(samba3) - winsdb.add(ldif) - - -- cgit From 77c825f08b516e3e5acf40d0b744a01ce68635fe Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Dec 2007 15:36:55 -0600 Subject: r26618: Implement -W option support. (This used to be commit e48026b17d682c01eb3343ef35f6e847b18fa297) --- source4/scripting/python/samba/getopt.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 014dd336d8..87cf171ca2 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -42,12 +42,18 @@ class CredentialsOptions(optparse.OptionGroup): help="Password", type=str, callback=self.set_password) self.add_option("-U", "--username", metavar="USERNAME", action="callback", type=str, - help="username", callback=self.parse_username) + help="Username", callback=self.parse_username) + self.add_option("-W", "--workgroup", metavar="WORKGROUP", + action="callback", type=str, + help="Workgroup", callback=self.parse_workgroup) self.creds = Credentials() def parse_username(self, option, opt_str, arg, parser): self.creds.parse_string(arg) + def parse_workgroup(self, option, opt_str, arg, parser): + self.creds.set_domain(arg) + def set_password(self, option, opt_str, arg, parser): self.creds.set_password(arg) -- cgit From a61e25f17492bf78eb5d5ec962f0d174f94d8f84 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Dec 2007 16:25:17 -0600 Subject: r26622: python: Update license version, clarify copyright. (This used to be commit 3ee62094074d74b6c69948730f2892f0a430f40b) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 53eb1d618f..fa45f7a79d 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1,6 +1,6 @@ # # backend code for provisioning a Samba4 server -# Released under the GNU GPL v2 or later +# Released under the GNU GPL v3 or later # Copyright Jelmer Vernooij 2007 # # Based on the original in EJS: -- cgit From 68b698270481f2b033046dcd6e0a293c1cdaf838 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Dec 2007 16:25:27 -0600 Subject: r26624: libnet/python: Use standard function for constructing context, allow overriding credentials. (This used to be commit a5fb3caedefaf5387e3a384d060272f11a3b4b99) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 2a88870660..6094cb49f4 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -33,6 +33,7 @@ extern void init_tdb(void); extern void init_dcerpc(void); extern void init_events(void); extern void inituuid(void); +extern void init_net(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 6817c5d885a75a1af0e646827c3fa8220df8c7a5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Dec 2007 18:14:15 -0600 Subject: r26628: python: Add more documentation, simplify code in Samba3 module. (This used to be commit 3c329ee73d9979236313c37e51750ec06b8dd69e) --- source4/scripting/python/config.mk | 2 +- source4/scripting/python/samba/__init__.py | 8 ++ source4/scripting/python/samba/getopt.py | 2 +- source4/scripting/python/samba/provision.py | 96 ++++++++++++++-------- source4/scripting/python/samba/samba3.py | 100 +++++++++++++++-------- source4/scripting/python/samba/samdb.py | 50 ++++++++---- source4/scripting/python/samba/tests/__init__.py | 4 + 7 files changed, 175 insertions(+), 87 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 4a531f5062..cfd179aff5 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -30,7 +30,7 @@ realdistclean:: pythonmods: $(PYTHON_DSOS) -PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py +PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 359457d815..01fdea6665 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -159,11 +159,19 @@ class Ldb(ldb.Ldb): self.add_ldif(open(ldif_path, 'r').read()) def add_ldif(self, ldif): + """Add data based on a LDIF string. + + :param ldif: LDIF text. + """ for changetype, msg in self.parse_ldif(ldif): assert changetype == ldb.CHANGETYPE_NONE self.add(msg) def modify_ldif(self, ldif): + """Modify database based on a LDIF string. + + :param ldif: LDIF text. + """ for (changetype, msg) in self.parse_ldif(ldif): assert changetype == ldb.CHANGETYPE_MODIFY self.modify(msg) diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 87cf171ca2..c0e7053062 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -58,7 +58,7 @@ class CredentialsOptions(optparse.OptionGroup): self.creds.set_password(arg) def set_simple_bind_dn(self, option, opt_str, arg, parser): - self.creds.set_simple_bind_dn(arg) + self.creds.set_bind_dn(arg) def get_credentials(self): return self.creds diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index fa45f7a79d..bdfe035c41 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -74,6 +74,14 @@ def findnss(nssfn, *names): def open_ldb(session_info, credentials, lp, dbname): + """Open a LDB, thrashing it if it is corrupt. + + :param session_info: auth session information + :param credentials: credentials + :param lp: Loadparm context + :param dbname: Path of the database to open. + :return: a Ldb object + """ assert session_info is not None try: return Ldb(dbname, session_info=session_info, credentials=credentials, @@ -86,7 +94,12 @@ def open_ldb(session_info, credentials, lp, dbname): def setup_add_ldif(ldb, ldif_path, subst_vars=None): - """Setup a ldb in the private dir.""" + """Setup a ldb in the private dir. + + :param ldb: LDB file to import data into + :param ldif_path: Path of the LDIF file to load + :param subst_vars: Optional variables to subsitute in LDIF. + """ assert isinstance(ldif_path, str) data = open(ldif_path, 'r').read() @@ -126,7 +139,12 @@ def setup_ldb(ldb, ldif_path, subst_vars): def setup_file(template, fname, substvars): - """Setup a file in the private dir.""" + """Setup a file in the private dir. + + :param template: Path of the template file. + :param fname: Path of the file to create. + :param substvars: Substitution variables. + """ f = fname if os.path.exists(f): @@ -179,7 +197,17 @@ def provision_paths_from_lp(lp, dnsdomain): def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, wheel, backup): - """setup reasonable name mappings for sam names to unix names.""" + """setup reasonable name mappings for sam names to unix names. + + :param ldb: SamDB object. + :param sid: The domain sid. + :param domaindn: The domain DN. + :param root: Name of the UNIX root user. + :param nobody: Name of the UNIX nobody user. + :param nogroup: Name of the unix nobody group. + :param users: Name of the unix users group. + :param wheel: Name of the wheel group (users that can become root). + :param backup: Name of the backup group.""" # add some foreign sids if they are not present already ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous") ldb.add_foreign(domaindn, "S-1-1-0", "World") @@ -591,7 +619,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, if nogroup is None: nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] if users is None: - users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", + "usr")[2] if wheel is None: wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] if backup is None: @@ -748,13 +777,32 @@ def provision(lp, setup_dir, message, blank, paths, session_info, return domaindn def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): + """Create a PHP LDAP admin configuration file. + + :param path: Path to write the configuration to. + :param setup_path: Function to generate setup paths. + :param s4_ldapi_path: Path to Samba 4 LDAPI socket. + """ setup_file(setup_path("phpldapadmin-config.php"), path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip, hostname, dnspass, realm, domainguid, hostguid): - """Write out a DNS zone file, from the info in the current database.""" + """Write out a DNS zone file, from the info in the current database. + + :param path: Path of the new file. + :param setup_path": Setup path function. + :param samdb: SamDB object + :param dnsdomain: DNS Domain name + :param domaindn: DN of the Domain + :param hostip: Local IP + :param hostname: Local hostname + :param dnspass: Password for DNS + :param realm: Realm name + :param domainguid: GUID of the domain. + :param hostguid: GUID of the host. + """ setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), @@ -795,7 +843,14 @@ def provision_ldapbase(setup_dir, message, paths): def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): - """Load schema.""" + """Load schema. + + :param samdb: Load a schema into a SamDB. + :param setup_path: Setup path function. + :param schemadn: DN of the schema + :param netbiosname: NetBIOS name of the host. + :param configdn: DN of the configuration + """ schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) @@ -807,32 +862,3 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): "DEFAULTSITE": DEFAULTSITE}) samdb.attach_schema_from_ldif(head_data, schema_data) - -def join_domain(domain, netbios_name, join_type, creds): - ctx = NetContext(creds) - joindom = object() - joindom.domain = domain - joindom.join_type = join_type - joindom.netbios_name = netbios_name - if not ctx.JoinDomain(joindom): - raise Exception("Domain Join failed: " + joindom.error_string) - - -def vampire(domain, session_info, credentials, message): - """Vampire a remote domain. - - Session info and credentials are required for for - access to our local database (might be remote ldap) - """ - ctx = NetContext(credentials) - machine_creds = Credentials() - machine_creds.set_domain(form.domain) - if not machine_creds.set_machine_account(): - raise Exception("Failed to access domain join information!") - vampire_ctx.machine_creds = machine_creds - vampire_ctx.session_info = session_info - if not ctx.SamSyncLdb(vampire_ctx): - raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) - - - diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 27656900ad..113348e6f1 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -25,14 +25,33 @@ REGISTRY_DB_VERSION = 1 import os import tdb -class Registry: - """Simple read-only support for reading the Samba3 registry.""" + +class TdbDatabase: + """Simple Samba 3 TDB database reader.""" def __init__(self, file): + """Open a file. + + :param file: Path of the file to open. + """ self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + self._check_version() + + def _check_version(self): + pass def close(self): + """Close resources associated with this object.""" self.tdb.close() + +class Registry(TdbDatabase): + """Simple read-only support for reading the Samba3 registry. + + :note: This object uses the same syntax for registry key paths as + Samba 3. This particular format uses forward slashes for key path + separators and abbreviations for the predefined key names. + e.g.: HKLM/Software/Bar. + """ def __len__(self): """Return the number of keys.""" return len(self.keys()) @@ -42,6 +61,11 @@ class Registry: return [k.rstrip("\x00") for k in self.tdb.keys() if not k.startswith(REGISTRY_VALUE_PREFIX)] def subkeys(self, key): + """Retrieve the subkeys for the specified key. + + :param key: Key path. + :return: list with key names + """ data = self.tdb.get("%s\x00" % key) if data is None: return [] @@ -54,7 +78,11 @@ class Registry: return keys def values(self, key): - """Return a dictionary with the values set for a specific key.""" + """Return a dictionary with the values set for a specific key. + + :param key: Key to retrieve values for. + :return: Dictionary with value names as key, tuple with type and + data as value.""" data = self.tdb.get("%s/%s\x00" % (REGISTRY_VALUE_PREFIX, key)) if data is None: return {} @@ -77,9 +105,14 @@ class Registry: return ret -class PolicyDatabase: +class PolicyDatabase(TdbDatabase): + """Samba 3 Account Policy database reader.""" def __init__(self, file): - self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + """Open a policy database + + :param file: Path to the file to open. + """ + super(PolicyDatabase, self).__init__(file) self.min_password_length = self.tdb.fetch_uint32("min password length\x00") self.password_history = self.tdb.fetch_uint32("password history\x00") self.user_must_logon_to_change_password = self.tdb.fetch_uint32("user must logon to change pasword\x00") @@ -93,9 +126,6 @@ class PolicyDatabase: # FIXME: Read privileges as well - def close(self): - self.tdb.close() - GROUPDB_DATABASE_VERSION_V1 = 1 # native byte format. GROUPDB_DATABASE_VERSION_V2 = 2 # le format. @@ -108,17 +138,27 @@ GROUP_PREFIX = "UNIXGROUP/" # hanging of the member as key. MEMBEROF_PREFIX = "MEMBEROF/" -class GroupMappingDatabase: - def __init__(self, file): - self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) +class GroupMappingDatabase(TdbDatabase): + """Samba 3 group mapping database reader.""" + def _check_version(self): assert self.tdb.fetch_int32("INFO/version\x00") in (GROUPDB_DATABASE_VERSION_V1, GROUPDB_DATABASE_VERSION_V2) def groupsids(self): + """Retrieve the SIDs for the groups in this database. + + :return: List with sids as strings. + """ for k in self.tdb.keys(): if k.startswith(GROUP_PREFIX): yield k[len(GROUP_PREFIX):].rstrip("\0") def get_group(self, sid): + """Retrieve the group mapping information for a particular group. + + :param sid: SID of the group + :return: None if the group can not be found, otherwise + a tuple with gid, sid_name_use, the NT name and comment. + """ data = self.tdb.get("%s%s\0" % (GROUP_PREFIX, sid)) if data is None: return data @@ -128,13 +168,11 @@ class GroupMappingDatabase: return (gid, sid_name_use, nt_name, comment) def aliases(self): + """Retrieve the aliases in this database.""" for k in self.tdb.keys(): if k.startswith(MEMBEROF_PREFIX): yield k[len(MEMBEROF_PREFIX):].rstrip("\0") - def close(self): - self.tdb.close() - # High water mark keys IDMAP_HWM_GROUP = "GROUP HWM\0" @@ -146,22 +184,29 @@ IDMAP_USER_PREFIX = "UID " # idmap version determines auto-conversion IDMAP_VERSION_V2 = 2 -class IdmapDatabase: - def __init__(self, file): - self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) +class IdmapDatabase(TdbDatabase): + """Samba 3 ID map database reader.""" + def _check_version(self): assert self.tdb.fetch_int32("IDMAP_VERSION\0") == IDMAP_VERSION_V2 def uids(self): + """Retrieve a list of all uids in this database.""" for k in self.tdb.keys(): if k.startswith(IDMAP_USER_PREFIX): yield int(k[len(IDMAP_USER_PREFIX):].rstrip("\0")) def gids(self): + """Retrieve a list of all gids in this database.""" for k in self.tdb.keys(): if k.startswith(IDMAP_GROUP_PREFIX): yield int(k[len(IDMAP_GROUP_PREFIX):].rstrip("\0")) def get_user_sid(self, uid): + """Retrieve the SID associated with a particular uid. + + :param uid: UID to retrieve SID for. + :return: A SID or None if no mapping was found. + """ data = self.tdb.get("%s%d\0" % (IDMAP_USER_PREFIX, uid)) if data is None: return data @@ -174,19 +219,15 @@ class IdmapDatabase: return data.rstrip("\0") def get_user_hwm(self): + """Obtain the user high-water mark.""" return self.tdb.fetch_uint32(IDMAP_HWM_USER) def get_group_hwm(self): + """Obtain the group high-water mark.""" return self.tdb.fetch_uint32(IDMAP_HWM_GROUP) - def close(self): - self.tdb.close() - - -class SecretsDatabase: - def __init__(self, file): - self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) +class SecretsDatabase(TdbDatabase): def get_auth_password(self): return self.tdb.get("SECRETS/AUTH_PASSWORD") @@ -241,16 +282,12 @@ class SecretsDatabase: def get_sid(self, host): return self.tdb.get("SECRETS/SID/%s" % host.upper()) - def close(self): - self.tdb.close() - SHARE_DATABASE_VERSION_V1 = 1 SHARE_DATABASE_VERSION_V2 = 2 -class ShareInfoDatabase: - def __init__(self, file): - self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) +class ShareInfoDatabase(TdbDatabase): + def _check_version(self): assert self.tdb.fetch_int32("INFO/version\0") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) def get_secdesc(self, name): @@ -258,9 +295,6 @@ class ShareInfoDatabase: # FIXME: Run ndr_pull_security_descriptor return secdesc - def close(self): - self.tdb.close() - class Shares: def __init__(self, lp, shareinfo): diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 46707f060f..2af56d8d8e 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -20,13 +20,20 @@ # along with this program. If not, see . # +"""Convenience functions for using the SAM.""" + import samba import misc import ldb class SamDB(samba.Ldb): + """The SAM database.""" def __init__(self, url=None, session_info=None, credentials=None, modules_dir=None, lp=None): + """Open the Sam Database. + + :param url: URL of the database. + """ super(SamDB, self).__init__(session_info=session_info, credentials=credentials, modules_dir=modules_dir, lp=lp) assert misc.dsdb_set_global_schema(self) == 0 @@ -47,7 +54,12 @@ description: %s self.add(msg[1]) def setup_name_mapping(self, domaindn, sid, unixname): - """Setup a mapping between a sam name and a unix name.""" + """Setup a mapping between a sam name and a unix name. + + :param domaindn: DN of the domain. + :param sid: SID of the NT-side of the mapping. + :param unixname: Unix name to map to. + """ res = self.search(ldb.Dn(self, domaindn), ldb.SCOPE_SUBTREE, "objectSid=%s" % sid, ["dn"]) assert len(res) == 1, "Failed to find record for objectSid %s" % sid @@ -61,7 +73,7 @@ unixName: %s self.modify(self.parse_ldif(mod).next()[1]) def enable_account(self, user_dn): - """enable the account. + """Enable an account. :param user_dn: Dn of the account to enable. """ @@ -75,10 +87,15 @@ changetype: modify replace: userAccountControl userAccountControl: %u """ % (user_dn, userAccountControl) - self.modify(mod) + self.modify_ldif(mod) - def newuser(self, username, unixname, password, message): - """add a new user record""" + def newuser(self, username, unixname, password): + """add a new user record. + + :param username: Name of the new user. + :param unixname: Name of the unix user to map to. + :param password: Password for the new user + """ # connect to the sam self.transaction_start() @@ -97,13 +114,13 @@ userAccountControl: %u # the new user record. note the reliance on the samdb module to fill # in a sid, guid etc # - ldif = """ -dn: %s -sAMAccountName: %s -unixName: %s -sambaPassword: %s -objectClass: user - """ % (user_dn, username, unixname, password) + # now the real work + self.add({"dn": user_dn, + "sAMAccountName": username, + "unixName": unixname, + "sambaPassword": password, + "objectClass": "user"}) + # add the user to the users group as well modgroup = """ dn: %s @@ -113,11 +130,6 @@ member: %s """ % (dom_users, user_dn) - # now the real work - message("Adding user %s" % user_dn) - self.add(ldif) - - message("Modifying group %s" % dom_users) self.modify(modgroup) # modify the userAccountControl to remove the disabled bit @@ -125,6 +137,10 @@ member: %s self.transaction_commit() def set_domain_sid(self, sid): + """Change the domain SID used by this SamDB. + + :param sid: The new domain sid to use. + """ misc.samdb_set_domain_sid(self, sid) def attach_schema_from_ldif(self, pf, df): diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index 5e1ff87c2b..ad8a2524b5 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -17,6 +17,8 @@ # along with this program. If not, see . # +"""Samba Python tests.""" + import os import ldb import samba @@ -24,11 +26,13 @@ import tempfile import unittest class LdbTestCase(unittest.TestCase): + """Trivial test case for running tests against a LDB.""" def setUp(self): self.filename = os.tempnam() self.ldb = samba.Ldb(self.filename) def set_modules(self, modules=[]): + """Change the modules for this Ldb.""" m = ldb.Message() m.dn = ldb.Dn(self.ldb, "@MODULES") m["@LIST"] = ",".join(modules) -- cgit From 2bd4bf6a1beb2b00ab86cca59ac875bf75c921ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Dec 2007 18:14:18 -0600 Subject: r26629: python: Improve documentation in various places. (This used to be commit ee71a27bca66426d34cb1d686a83ac6a342329d3) --- source4/scripting/python/samba/getopt.py | 16 +++++------ source4/scripting/python/samba/provision.py | 8 +++++- source4/scripting/python/samba/samba3.py | 43 +++++++++++++++++++++++------ 3 files changed, 50 insertions(+), 17 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index c0e7053062..a087974a69 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -36,28 +36,28 @@ class CredentialsOptions(optparse.OptionGroup): def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Credentials Options") self.add_option("--simple-bind-dn", metavar="DN", action="callback", - callback=self.set_simple_bind_dn, type=str, + callback=self._set_simple_bind_dn, type=str, help="DN to use for a simple bind") self.add_option("--password", metavar="PASSWORD", action="callback", - help="Password", type=str, callback=self.set_password) + help="Password", type=str, callback=self._set_password) self.add_option("-U", "--username", metavar="USERNAME", action="callback", type=str, - help="Username", callback=self.parse_username) + help="Username", callback=self._parse_username) self.add_option("-W", "--workgroup", metavar="WORKGROUP", action="callback", type=str, - help="Workgroup", callback=self.parse_workgroup) + help="Workgroup", callback=self._parse_workgroup) self.creds = Credentials() - def parse_username(self, option, opt_str, arg, parser): + def _parse_username(self, option, opt_str, arg, parser): self.creds.parse_string(arg) - def parse_workgroup(self, option, opt_str, arg, parser): + def _parse_workgroup(self, option, opt_str, arg, parser): self.creds.set_domain(arg) - def set_password(self, option, opt_str, arg, parser): + def _set_password(self, option, opt_str, arg, parser): self.creds.set_password(arg) - def set_simple_bind_dn(self, option, opt_str, arg, parser): + def _set_simple_bind_dn(self, option, opt_str, arg, parser): self.creds.set_bind_dn(arg) def get_credentials(self): diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index bdfe035c41..db3749f721 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -23,6 +23,7 @@ import security from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE +"""Functions for setting up a Samba configuration.""" DEFAULTSITE = "Default-First-Site-Name" @@ -53,7 +54,12 @@ class ProvisionPaths: def install_ok(lp, session_info, credentials): - """Check whether the current install seems ok.""" + """Check whether the current install seems ok. + + :param lp: Loadparm context + :param session_info: Session information + :param credentials: Credentials + """ if lp.get("realm") == "": return False ldb = Ldb(lp.get("sam database"), session_info=session_info, diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 113348e6f1..cffedb54af 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -26,7 +26,7 @@ import os import tdb -class TdbDatabase: +class TdbDatabase(object): """Simple Samba 3 TDB database reader.""" def __init__(self, file): """Open a file. @@ -228,6 +228,7 @@ class IdmapDatabase(TdbDatabase): class SecretsDatabase(TdbDatabase): + """Samba 3 Secrets database reader.""" def get_auth_password(self): return self.tdb.get("SECRETS/AUTH_PASSWORD") @@ -246,6 +247,10 @@ class SecretsDatabase(TdbDatabase): yield k[len("SECRETS/LDAP_BIND_PW/"):].rstrip("\0") def domains(self): + """Iterate over domains in this database. + + :return: Iterator over the names of domains in this database. + """ for k in self.tdb.keys(): if k.startswith("SECRETS/SID/"): yield k[len("SECRETS/SID/"):].rstrip("\0") @@ -287,10 +292,15 @@ SHARE_DATABASE_VERSION_V1 = 1 SHARE_DATABASE_VERSION_V2 = 2 class ShareInfoDatabase(TdbDatabase): + """Samba 3 Share Info database reader.""" def _check_version(self): assert self.tdb.fetch_int32("INFO/version\0") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) def get_secdesc(self, name): + """Obtain the security descriptor on a particular share. + + :param name: Name of the share + """ secdesc = self.tdb.get("SECDESC/%s" % name) # FIXME: Run ndr_pull_security_descriptor return secdesc @@ -302,9 +312,11 @@ class Shares: self.shareinfo = shareinfo def __len__(self): + """Number of shares.""" return len(self.lp) - 1 def __iter__(self): + """Iterate over the share names.""" return self.lp.__iter__() @@ -329,7 +341,7 @@ ACB_PW_EXPIRED = 0x00020000 ACB_NO_AUTH_DATA_REQD = 0x00080000 acb_info_mapping = { - 'N': ACB_PWNOTREQ, # 'N'o password. + 'N': ACB_PWNOTREQ, # 'N'o password. 'D': ACB_DISABLED, # 'D'isabled. 'H': ACB_HOMDIRREQ, # 'H'omedir required. 'T': ACB_TEMPDUP, # 'T'emp account. @@ -344,6 +356,11 @@ acb_info_mapping = { } def decode_acb(text): + """Decode a ACB field. + + :param text: ACB text + :return: integer with flags set. + """ assert not "[" in text and not "]" in text ret = 0 for x in text: @@ -352,6 +369,10 @@ def decode_acb(text): class SAMUser: + """Samba 3 SAM User. + + :note: Unknown or unset fields are set to None. + """ def __init__(self, name, uid=None, lm_password=None, nt_password=None, acct_ctrl=None, last_change_time=None, nt_username=None, fullname=None, logon_time=None, logoff_time=None, acct_desc=None, group_rid=None, bad_password_count=None, logon_count=None, @@ -398,6 +419,7 @@ class SAMUser: return self.__dict__ == other.__dict__ class SmbpasswdFile: + """Samba 3 smbpasswd file reader.""" def __init__(self, file): self.users = {} f = open(file, 'r') @@ -458,13 +480,14 @@ TDBSAM_USER_PREFIX = "USER_" class LdapSam: + """Samba 3 LDAP passdb backend reader.""" def __init__(self, url): self.ldap_url = ldap_url -class TdbSam: - def __init__(self, file): - self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) +class TdbSam(TdbDatabase): + """Samba 3 TDB passdb backend reader.""" + def _check_version(self): self.version = self.tdb.fetch_uint32("INFO/version\0") or 0 assert self.version in (0, 1, 2) @@ -555,9 +578,6 @@ class TdbSam: assert len(data) == 0 return user - def close(self): - self.tdb.close() - def shellsplit(text): """Very simple shell-like line splitting. @@ -582,6 +602,7 @@ def shellsplit(text): class WinsDatabase: + """Samba 3 WINS database reader.""" def __init__(self, file): self.entries = {} f = open(file, 'r') @@ -618,7 +639,13 @@ class WinsDatabase: pass class Samba3: + """Samba 3 configuration and state data reader.""" def __init__(self, libdir, smbconfpath): + """Open the configuration and data for a Samba 3 installation. + + :param libdir: Library directory + :param smbconfpath: Path to the smb.conf file. + """ self.smbconfpath = smbconfpath self.libdir = libdir import param -- cgit From 5e03b921825ffe177bf9d00ed1e12de02728da75 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Jan 2008 01:52:31 -0600 Subject: r26642: samba3sam.py: Remove more EJS-specific code. (This used to be commit 7d14b657b3d59924b15f4f84bbd5745cd7f759ef) --- source4/scripting/python/samba/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 01fdea6665..e0b9e1d410 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -172,8 +172,7 @@ class Ldb(ldb.Ldb): :param ldif: LDIF text. """ - for (changetype, msg) in self.parse_ldif(ldif): - assert changetype == ldb.CHANGETYPE_MODIFY + for changetype, msg in self.parse_ldif(ldif): self.modify(msg) -- cgit From 6ed5fc0919d2f43ad28f9fff08e2a3c8f09bbecd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Jan 2008 21:21:12 -0600 Subject: r26656: python: Add file documentating the status of the Python migration. (This used to be commit 5c86cc6648169bf52161a1ffdbf17a38b62c611f) --- source4/scripting/python/STATUS | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 source4/scripting/python/STATUS (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS new file mode 100644 index 0000000000..b39563da29 --- /dev/null +++ b/source4/scripting/python/STATUS @@ -0,0 +1,20 @@ +dsdb/samdb/ldb_modules/tests/samba3sam.py +lib/ldb/tests/python/ldap.py +SWAT +hierarchy +DCE/RPC bindings + - pidl: + Parse::Pidl::Samba::Python + - wrap struct/bitmap/enum/union types + - __ndr_pack__/__ndr_unpack__ members + Parse::Pidl::Samba::NDR::Python + - pidl generated client fns + - one class per interface + - AddOne() + + - scripting/bin/smbstatus.py + - scripting/bin/winreg.py + +not important before making Python the default: +- scripting/python/samba/upgrade.py +- install python modules into system -- cgit From 1548d8d2be2a1012549f626d504070272bb51c9e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Jan 2008 21:45:18 -0600 Subject: r26658: pidl: Register Python modules. (This used to be commit f47044aacc8eb6df856524744ab87bee997bae6d) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 6094cb49f4..55df51d881 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -34,6 +34,7 @@ extern void init_dcerpc(void); extern void init_events(void); extern void inituuid(void); extern void init_net(void); +extern void initecho(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From e652fc802a13ead5e3b0ef7c2b4a6976ab0e1ec6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 14:00:07 -0600 Subject: r26666: python: Prefer newer Python versions as they use const properly. (This used to be commit aa2adf33275dc637022d9feee1531aa79aa08e25) --- source4/scripting/python/config.m4 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index a629aa8f92..326cef8440 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -13,7 +13,12 @@ if test -z "$PYTHON"; then AC_MSG_WARN([No python found]) fi -AC_PATH_PROG([PYTHON_CONFIG],[python[$PYTHON_VERSION]-config]) +if test -z "$PYTHON_VERSION"; then + AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config]) +else + AC_PATH_PROG([PYTHON_CONFIG], [python[$PYTHON_VERSION]-config]) +fi + if test -z "$PYTHON_CONFIG"; then working_python=no AC_MSG_WARN([No python-config found]) -- cgit From ff1017b1426a7620618ca3b5e2b4cd5cdac3dcd2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 7 Jan 2008 14:11:19 -0600 Subject: r26687: python: Update status after feedback from abartlett. (This used to be commit f08192750eecdd8b0ffbed84a53abcae51afd2df) --- source4/scripting/python/STATUS | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index b39563da29..c82275fff8 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -1,6 +1,9 @@ dsdb/samdb/ldb_modules/tests/samba3sam.py lib/ldb/tests/python/ldap.py +provisioning in LDAP mode SWAT +command-line vampire +provisioning: combine some of the python dictionaries hierarchy DCE/RPC bindings - pidl: -- cgit From 48c75bade7fe68f3fcaf075a97bcdb80b448bbb7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 10 Jan 2008 17:47:58 +0100 Subject: configure: Complain when Python is not found. (This used to be commit 6aaccdb0b38366963d5bdff444d24d6dcacc817b) --- source4/scripting/python/config.m4 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 326cef8440..348f9197f7 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -65,8 +65,5 @@ then LIBS="$ac_save_LIBS" CFLAGS="$ac_save_CFLAGS" else - SMB_ENABLE(EXT_LIB_PYTHON,NO) - SMB_ENABLE(LIBPYTHONyy,NO) - SMB_ENABLE(smbpython,NO) - AC_MSG_RESULT([no]) + AC_MSG_ERROR([Python not found. Please install Python 2.x and its development headers/libraries.]) fi -- cgit From 5b8ffcca53d40c8067531f75c658f856886ee095 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 10 Jan 2008 17:53:56 +0100 Subject: python: Update STATUS. (This used to be commit bcd82a9ae3cb01b3d8ed0c36999f7a1c0bbab19a) --- source4/scripting/python/STATUS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index c82275fff8..f2f1641658 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -1,7 +1,6 @@ -dsdb/samdb/ldb_modules/tests/samba3sam.py -lib/ldb/tests/python/ldap.py -provisioning in LDAP mode -SWAT +dsdb/samdb/ldb_modules/tests/samba3sam.py: Fix remaining failing tests +lib/ldb/tests/python/ldap.py: Fix remaining failing tests +provisioning in LDAP mode(TEST_LDAP=yes PROVISION_PYTHON=yes make test) command-line vampire provisioning: combine some of the python dictionaries hierarchy @@ -21,3 +20,4 @@ DCE/RPC bindings not important before making Python the default: - scripting/python/samba/upgrade.py - install python modules into system +- SWAT -- cgit From 63bbb9239848beb376d8ffacd787e3fde7cd77e7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 04:07:14 +0100 Subject: Python: Update STATUS. (This used to be commit cbf3b74e5f5076d864b08c772f21b20751ea5163) --- source4/scripting/python/STATUS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index f2f1641658..5972027f59 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -1,5 +1,5 @@ dsdb/samdb/ldb_modules/tests/samba3sam.py: Fix remaining failing tests -lib/ldb/tests/python/ldap.py: Fix remaining failing tests +lib/ldb/tests/python/ldap.py: Fix remaining 3 FIXME's provisioning in LDAP mode(TEST_LDAP=yes PROVISION_PYTHON=yes make test) command-line vampire provisioning: combine some of the python dictionaries -- cgit From 7c3e8c838f0ada9ebae9dbb2bc5d84320c8431f2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 16:13:46 +0100 Subject: Python: Simplify code in a couple of places. Copy Andrew's changes from g53b5166. (This used to be commit f056f624958af79204c972eba3f85e36e93daed7) --- source4/scripting/python/samba/__init__.py | 12 ++++++------ source4/scripting/python/samba/provision.py | 8 ++++---- source4/scripting/python/samba/samdb.py | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index e0b9e1d410..e858180169 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -112,15 +112,15 @@ class Ldb(ldb.Ldb): for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: try: - self.delete(ldb.Dn(self, attr)) + self.delete(attr) except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): # Ignore missing dn errors pass - basedn = ldb.Dn(self, "") + basedn = "" # and the rest for msg in self.search(basedn, ldb.SCOPE_SUBTREE, - "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", + "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", ["dn"]): try: self.delete(msg.dn) @@ -128,12 +128,12 @@ class Ldb(ldb.Ldb): # Ignor eno such object errors pass - res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) + res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguisedName=@BASEINFO)))", ["dn"]) assert len(res) == 0 def erase_partitions(self): """Erase an ldb, removing all records.""" - res = self.search(ldb.Dn(self, ""), ldb.SCOPE_BASE, "(objectClass=*)", + res = self.search("", ldb.SCOPE_BASE, "(objectClass=*)", ["namingContexts"]) assert len(res) == 1 if not "namingContexts" in res[0]: @@ -145,7 +145,7 @@ class Ldb(ldb.Ldb): k = 0 while ++k < 10 and (previous_remaining != current_remaining): # and the rest - res2 = self.search(ldb.Dn(self, basedn), ldb.SCOPE_SUBTREE, "(|(objectclass=*)(dn=*))", ["dn"]) + res2 = self.search(basedn, ldb.SCOPE_SUBTREE, "(|(objectclass=*)(distinguishedName=*))", ["distinguishedName"]) previous_remaining = current_remaining current_remaining = len(res2) for msg in res2: diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index db3749f721..1607cb343b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -20,7 +20,7 @@ import samba from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB import security -from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ +from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE """Functions for setting up a Samba configuration.""" @@ -64,7 +64,7 @@ def install_ok(lp, session_info, credentials): return False ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) - if len(ldb.search(ldb.Dn("(cn=Administrator)"))) != 1: + if len(ldb.search("(cn=Administrator)")) != 1: return False return True @@ -766,9 +766,9 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + domainguid = samdb.searchone(domaindn, "objectGUID") assert isinstance(domainguid, str) - hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", + hostguid = samdb.searchone(domaindn, "objectGUID", expression="(&(objectClass=computer)(cn=%s))" % hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 2af56d8d8e..353eaee198 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -60,7 +60,7 @@ description: %s :param sid: SID of the NT-side of the mapping. :param unixname: Unix name to map to. """ - res = self.search(ldb.Dn(self, domaindn), ldb.SCOPE_SUBTREE, + res = self.search(domaindn, ldb.SCOPE_SUBTREE, "objectSid=%s" % sid, ["dn"]) assert len(res) == 1, "Failed to find record for objectSid %s" % sid @@ -103,7 +103,7 @@ userAccountControl: %u res = self.search("", SCOPE_BASE, "defaultNamingContext=*", ["defaultNamingContext"]) assert(len(res) == 1 and res[0].defaultNamingContext is not None) - domain_dn = res[0].defaultNamingContext + domain_dn = res[0]["defaultNamingContext"][0] assert(domain_dn is not None) dom_users = self.searchone(domain_dn, "dn", "name=Domain Users") assert(dom_users is not None) -- cgit From 378dff1365801b2dd23677a38f2fb20828cbbf39 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 16:28:17 +0100 Subject: python: Fix typo. (This used to be commit d6b06fc03e37781f5f59b15cff8fe3ee8df63444) --- source4/scripting/python/samba/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index e858180169..483929661d 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -121,14 +121,14 @@ class Ldb(ldb.Ldb): # and the rest for msg in self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", - ["dn"]): + ["distinguishedName"]): try: self.delete(msg.dn) except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): # Ignor eno such object errors pass - res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguisedName=@BASEINFO)))", ["dn"]) + res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", ["distinguishedName"]) assert len(res) == 0 def erase_partitions(self): -- cgit From 53c33aa2b42732304f247798a4dbe3bcae14e407 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 03:32:44 +0100 Subject: python: Avoid PyDoc_STRVAR() macro which doesn't exist in Python2.2. (This used to be commit dec3f421be5d7fd4ead3b71f8b69921c41bad39a) --- source4/scripting/python/uuidmodule.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c index 02c929d4a5..9b952d31b9 100644 --- a/source4/scripting/python/uuidmodule.c +++ b/source4/scripting/python/uuidmodule.c @@ -18,7 +18,7 @@ */ #include "includes.h" -#include "Python.h" +#include #include "librpc/ndr/libndr.h" static PyObject *uuid_random(PyObject *self, PyObject *args) @@ -47,11 +47,9 @@ static PyMethodDef methods[] = { { NULL, NULL } }; -PyDoc_STRVAR(param_doc, "UUID helper routines"); - PyMODINIT_FUNC inituuid(void) { - PyObject *mod = Py_InitModule3((char *)"uuid", methods, param_doc); + PyObject *mod = Py_InitModule3((char *)"uuid", methods, "UUID helper routines"); if (mod == NULL) return; } -- cgit From c264fb4bde955ede94b82b5e98308553ecab93f2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 04:17:04 +0100 Subject: python: Try more possible flags. The flags returned by python-config may be for gcc and may not work for other compilers. (This used to be commit 1fbc3a9f47a33f785d935e39345021d9ca455bb9) --- source4/scripting/python/config.m4 | 65 ++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 31 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 326cef8440..6cf667a338 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -13,6 +13,30 @@ if test -z "$PYTHON"; then AC_MSG_WARN([No python found]) fi +AC_DEFUN([TRY_LINK_PYTHON], +[ + if test $working_python = no; then + ac_save_LIBS="$LIBS" + ac_save_CFLAGS="$CFLAGS" + LIBS="$LIBS $1" + CFLAGS="$CFLAGS $2" + + AC_TRY_LINK([ + #include + #include + ],[ + Py_InitModule(NULL, NULL); + ],[ + PYTHON_LDFLAGS="$1" + PYTHON_CFLAGS="$2" + working_python=yes + ]) + LIBS="$ac_save_LIBS" + CFLAGS="$ac_save_CFLAGS" + fi +]) + + if test -z "$PYTHON_VERSION"; then AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config]) else @@ -23,50 +47,29 @@ if test -z "$PYTHON_CONFIG"; then working_python=no AC_MSG_WARN([No python-config found]) else - working_python=yes - PYTHON_LDFLAGS=`$PYTHON_CONFIG --ldflags` - PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags` + TRY_LINK_PYTHON([`$PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --includes`]) + TRY_LINK_PYTHON([`$PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --cflags`]) fi -if test $working_python = no && test x$PYTHON != x +if test x$PYTHON != x then PYTHON_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True), sysconfig.get_config_var('CFLAGS'))"` PYTHON_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"` - working_python=yes + TRY_LINK_PYTHON($PYTHON_LDFLAGS, $PYTHON_CFLAGS) fi SMB_EXT_LIB(EXT_LIB_PYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) AC_MSG_CHECKING(working python module support) -if test x$working_python = xyes -then - ac_save_LIBS="$LIBS" - ac_save_CFLAGS="$CFLAGS" - LIBS="$LIBS $PYTHON_LDFLAGS" - CFLAGS="$CFLAGS $PYTHON_CFLAGS" - - AC_TRY_LINK([ - #include - #include - ],[ - Py_InitModule(NULL, NULL); - ],[ - SMB_ENABLE(EXT_LIB_PYTHON,YES) - SMB_ENABLE(smbpython,YES) - SMB_ENABLE(LIBPYTHON,YES) - AC_MSG_RESULT([yes]) - ],[ - SMB_ENABLE(EXT_LIB_PYTHON,NO) - SMB_ENABLE(LIBPYTHON,NO) - SMB_ENABLE(smbpython,NO) - AC_MSG_RESULT([no]) - ]) - - LIBS="$ac_save_LIBS" - CFLAGS="$ac_save_CFLAGS" +if test $working_python = yes; then + SMB_ENABLE(EXT_LIB_PYTHON,YES) + SMB_ENABLE(smbpython,YES) + SMB_ENABLE(LIBPYTHON,YES) + AC_MSG_RESULT([yes]) else SMB_ENABLE(EXT_LIB_PYTHON,NO) SMB_ENABLE(LIBPYTHONyy,NO) SMB_ENABLE(smbpython,NO) AC_MSG_RESULT([no]) fi + -- cgit From 2c90e6fc7a2c0858babaa45f3bf969238739aabf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 04:23:09 +0100 Subject: python: Fix initialization of variable. (This used to be commit 620ec696657558dbad2a6c7d4231deabcaeaaef1) --- source4/scripting/python/config.m4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 6cf667a338..b0884478c1 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -36,6 +36,8 @@ AC_DEFUN([TRY_LINK_PYTHON], fi ]) +dnl assume no working python +working_python=no if test -z "$PYTHON_VERSION"; then AC_PATH_PROGS([PYTHON_CONFIG], [python2.6-config python2.5-config python2.4-config python-config]) @@ -44,7 +46,6 @@ else fi if test -z "$PYTHON_CONFIG"; then - working_python=no AC_MSG_WARN([No python-config found]) else TRY_LINK_PYTHON([`$PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --includes`]) -- cgit From 6ef36c1f82fa9d48a3418f25202cab55b2f54d2f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 06:07:20 +0100 Subject: python: Avoid PyMODINIT_FUNC because it doesn't exist in older pythons. (This used to be commit e179db6d0fcf093082f2ad441980a2bb77ac6b17) --- source4/scripting/python/uuidmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c index 9b952d31b9..e05b286dd0 100644 --- a/source4/scripting/python/uuidmodule.c +++ b/source4/scripting/python/uuidmodule.c @@ -47,7 +47,7 @@ static PyMethodDef methods[] = { { NULL, NULL } }; -PyMODINIT_FUNC inituuid(void) +void inituuid(void) { PyObject *mod = Py_InitModule3((char *)"uuid", methods, "UUID helper routines"); if (mod == NULL) -- cgit From ecf52b2bc7c55fdc574f8dc58e90a9f52bdf1925 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 14:59:16 +0100 Subject: python: Avoid overwriting flags for already found version of Python. (This used to be commit 9041e385fe666c16d9a5b9a030b54a856f17e5e5) --- source4/scripting/python/config.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index b0884478c1..4f46f92682 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -54,9 +54,9 @@ fi if test x$PYTHON != x then - PYTHON_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True), sysconfig.get_config_var('CFLAGS'))"` - PYTHON_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"` - TRY_LINK_PYTHON($PYTHON_LDFLAGS, $PYTHON_CFLAGS) + DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True), sysconfig.get_config_var('CFLAGS'))"` + DISTUTILS_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"` + TRY_LINK_PYTHON($DISTUTILS_LDFLAGS, $DISTUTILS_CFLAGS) fi SMB_EXT_LIB(EXT_LIB_PYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) -- cgit From 252675a5788059dbcc49b175b56fa6c6a35ef74a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 16:44:42 +0100 Subject: python: Add some utility functions for working with Python objects based on talloc pointers. (This used to be commit 9366ddba92e192cd88e12eafba4a90af8c266f1c) --- source4/scripting/python/pytalloc.c | 34 +++++++++++++++++++++++++++++ source4/scripting/python/pytalloc.h | 43 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 source4/scripting/python/pytalloc.c create mode 100644 source4/scripting/python/pytalloc.h (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c new file mode 100644 index 0000000000..55ed56a627 --- /dev/null +++ b/source4/scripting/python/pytalloc.c @@ -0,0 +1,34 @@ +/* + Unix SMB/CIFS implementation. + Python/Talloc glue + Copyright (C) Jelmer Vernooij 2008 + + 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 . +*/ + +#include "includes.h" + +void py_talloc_dealloc(PyObject* self) +{ + py_talloc_Object *obj = (py_talloc_Object *)self; + talloc_free(obj->object); + PyObject_Del(self); +} + +PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr) +{ + PyObject *ret = PyObject_New(py_talloc_Object, &py_type); + ret->talloc_ptr = talloc_reference(NULL, ptr); + return ret; +} diff --git a/source4/scripting/python/pytalloc.h b/source4/scripting/python/pytalloc.h new file mode 100644 index 0000000000..93f6b48d82 --- /dev/null +++ b/source4/scripting/python/pytalloc.h @@ -0,0 +1,43 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2008 + + 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 . +*/ + +#ifndef _PY_TALLOC_H_ +#define _PY_TALLOC_H_ + +#include + +typedef struct { + PyObject_HEAD + void *talloc_ptr; +} py_talloc_Object; + +/* Deallocate a py_talloc_Object */ +void py_talloc_dealloc(PyObject* self); + +/* Retrieve the pointer for a py_talloc_object. Like talloc_get_type() + * but for py_talloc_Objects. */ + +/* FIXME: Call PyErr_SetString(PyExc_TypeError, "expected " __STR(type) ") + * when talloc_get_type() returns NULL. */ +#define py_talloc_get_type(py_obj, type) \ + talloc_get_type(((py_talloc_Object *)py_obj)->talloc_ptr, type) + +PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr); + +#endif /* _PY_TALLOC_H_ */ -- cgit From f7a0ef04f00cd44845bcee0a171e4cc05a545350 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 18:38:12 +0100 Subject: pidl/python: Support repr() for python types. (This used to be commit cf3664594d3540db20d32bc844f18e20abfa0d96) --- source4/scripting/python/pytalloc.c | 10 +++++++++- source4/scripting/python/pytalloc.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index 55ed56a627..4032ff75a4 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -22,7 +22,7 @@ void py_talloc_dealloc(PyObject* self) { py_talloc_Object *obj = (py_talloc_Object *)self; - talloc_free(obj->object); + talloc_free(obj->talloc_ptr); PyObject_Del(self); } @@ -32,3 +32,11 @@ PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr) ret->talloc_ptr = talloc_reference(NULL, ptr); return ret; } + +PyObject *py_talloc_default_repr(PyObject *py_obj) +{ + py_talloc_Object *obj = (py_talloc_Object *)py_obj; + + return PyString_FromFormat("", + talloc_get_name(obj->talloc_ptr)); +} diff --git a/source4/scripting/python/pytalloc.h b/source4/scripting/python/pytalloc.h index 93f6b48d82..735829bfcb 100644 --- a/source4/scripting/python/pytalloc.h +++ b/source4/scripting/python/pytalloc.h @@ -40,4 +40,7 @@ void py_talloc_dealloc(PyObject* self); PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr); +/* Sane default implementation of reprfunc. */ +PyObject *py_talloc_default_repr(PyObject *py_obj); + #endif /* _PY_TALLOC_H_ */ -- cgit From bfab9862fcdd657a1bddafde49cdd182f89fcf8b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 20:41:34 +0100 Subject: python: Allow wrapping pointers within talloc'ed memory that are not talloc contexts. (This used to be commit 9c038a74113fb55ed5eb12a7d0ae4a46bad9050c) --- source4/scripting/python/pytalloc.c | 10 ++++++---- source4/scripting/python/pytalloc.h | 11 ++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index 4032ff75a4..d0b8cb83f2 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -22,14 +22,16 @@ void py_talloc_dealloc(PyObject* self) { py_talloc_Object *obj = (py_talloc_Object *)self; - talloc_free(obj->talloc_ptr); + talloc_free(obj->talloc_ctx); PyObject_Del(self); } -PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr) +PyObject *py_talloc_import(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, + void *ptr) { PyObject *ret = PyObject_New(py_talloc_Object, &py_type); - ret->talloc_ptr = talloc_reference(NULL, ptr); + ret->talloc_ctx = talloc_reference(mem_ctx, ptr); + ret->ptr = ptr; return ret; } @@ -38,5 +40,5 @@ PyObject *py_talloc_default_repr(PyObject *py_obj) py_talloc_Object *obj = (py_talloc_Object *)py_obj; return PyString_FromFormat("", - talloc_get_name(obj->talloc_ptr)); + talloc_get_name(obj->talloc_ctx)); } diff --git a/source4/scripting/python/pytalloc.h b/source4/scripting/python/pytalloc.h index 735829bfcb..aad5840a67 100644 --- a/source4/scripting/python/pytalloc.h +++ b/source4/scripting/python/pytalloc.h @@ -24,7 +24,8 @@ typedef struct { PyObject_HEAD - void *talloc_ptr; + TALLOC_CTX *talloc_ctx; + void *ptr; } py_talloc_Object; /* Deallocate a py_talloc_Object */ @@ -36,9 +37,13 @@ void py_talloc_dealloc(PyObject* self); /* FIXME: Call PyErr_SetString(PyExc_TypeError, "expected " __STR(type) ") * when talloc_get_type() returns NULL. */ #define py_talloc_get_type(py_obj, type) \ - talloc_get_type(((py_talloc_Object *)py_obj)->talloc_ptr, type) + talloc_get_type(py_talloc_get_ptr(py_obj), type) -PyObject *py_talloc_import(PyTypeObject *py_type, void *ptr); +#define py_talloc_get_ptr(py_obj) ((py_talloc_Object *)py_obj)->ptr +#define py_talloc_get_mem_ctx(py_obj) ((py_talloc_Object *)py_obj)->talloc_ctx + +PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); +#define py_talloc_import(py_type, talloc_ptr) py_talloc_import_ex(py_type, talloc_ptr, talloc_ptr) /* Sane default implementation of reprfunc. */ PyObject *py_talloc_default_repr(PyObject *py_obj); -- cgit From d5903fd75e9640831f0e78fc04d3ffa5ea3b1b4a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 02:48:50 +0100 Subject: pidl/python: Fix compilation of py_echo. (This used to be commit 5ee99ff31c80ece6861b2a0323d71170ef9346b9) --- source4/scripting/python/config.mk | 2 +- source4/scripting/python/pytalloc.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index cfd179aff5..f00b477919 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -5,7 +5,7 @@ OBJ_FILES = smbpython.o [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON INIT_FUNCTION_SENTINEL = { NULL, NULL } -OBJ_FILES = modules.o +OBJ_FILES = modules.o pytalloc.o [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index d0b8cb83f2..dc61a0a13d 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "scripting/python/pytalloc.h" void py_talloc_dealloc(PyObject* self) { @@ -26,13 +27,13 @@ void py_talloc_dealloc(PyObject* self) PyObject_Del(self); } -PyObject *py_talloc_import(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, +PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { - PyObject *ret = PyObject_New(py_talloc_Object, &py_type); + py_talloc_Object *ret = PyObject_New(py_talloc_Object, py_type); ret->talloc_ctx = talloc_reference(mem_ctx, ptr); ret->ptr = ptr; - return ret; + return (PyObject *)ret; } PyObject *py_talloc_default_repr(PyObject *py_obj) -- cgit From db4ee4cce5f1fd84f3f0a331e769a70394126ca5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 03:59:36 +0100 Subject: python: Fix rpcecho tests. (This used to be commit ebb78ea4232c1614755844849580e3697b0a53fa) --- source4/scripting/python/STATUS | 5 --- .../python/samba/tests/dcerpc/__init__.py | 0 .../scripting/python/samba/tests/dcerpc/rpcecho.py | 39 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 source4/scripting/python/samba/tests/dcerpc/__init__.py create mode 100644 source4/scripting/python/samba/tests/dcerpc/rpcecho.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 5972027f59..9a1c5b1b64 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -9,11 +9,6 @@ DCE/RPC bindings Parse::Pidl::Samba::Python - wrap struct/bitmap/enum/union types - __ndr_pack__/__ndr_unpack__ members - Parse::Pidl::Samba::NDR::Python - - pidl generated client fns - - one class per interface - - AddOne() - - scripting/bin/smbstatus.py - scripting/bin/winreg.py diff --git a/source4/scripting/python/samba/tests/dcerpc/__init__.py b/source4/scripting/python/samba/tests/dcerpc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py new file mode 100644 index 0000000000..cedd0cc2fe --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -0,0 +1,39 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# + +import echo +import unittest + +class RpcEchoTests(unittest.TestCase): + def setUp(self): + self.conn = echo.rpcecho("ncalrpc:") + + def test_addone(self): + self.assertEquals(2, conn.AddOne(1)) + + def test_echodata(self): + self.assertEquals("bla", conn.EchoData(3, "bla")) + + def test_call(self): + self.assertEquals("foobar", conn.TestCall("foobar")) + + def test_surrounding(self): + somearray = [1,2,3,4] + (y,) = conn.TestSurrounding(echo.Surrounding(4, somearray)) + self.assertEquals(8 * [0], y.surrounding) -- cgit From 3b16c532f21202696d54ef87f8fa74d066812898 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 05:16:51 +0100 Subject: pidl/python: Pass credentials and loadparm context when connecting using DCE/RPC. (This used to be commit 4c87af95310e4aaee3f2e2da02d0ea70ed1ec25b) --- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index cedd0cc2fe..52a4f49bb4 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -18,22 +18,25 @@ # import echo +from param import LoadParm import unittest class RpcEchoTests(unittest.TestCase): def setUp(self): - self.conn = echo.rpcecho("ncalrpc:") + lp_ctx = LoadParm() + lp_ctx.load("st/client/client.conf") + self.conn = echo.rpcecho("ncalrpc:", lp_ctx) def test_addone(self): - self.assertEquals(2, conn.AddOne(1)) + self.assertEquals(2, self.conn.AddOne(1)) def test_echodata(self): - self.assertEquals("bla", conn.EchoData(3, "bla")) + self.assertEquals("bla", self.conn.EchoData(3, "bla")) def test_call(self): - self.assertEquals("foobar", conn.TestCall("foobar")) + self.assertEquals("foobar", self.conn.TestCall("foobar")) def test_surrounding(self): somearray = [1,2,3,4] - (y,) = conn.TestSurrounding(echo.Surrounding(4, somearray)) + (y,) = self.conn.TestSurrounding(echo.Surrounding(4, somearray)) self.assertEquals(8 * [0], y.surrounding) -- cgit From aca6bd5a2a2c5fe266509499be624bbab7b5c3c0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 06:03:33 +0100 Subject: python: Fix deallocation bug in pytalloc. (This used to be commit b849b4a6c4c9b03a9704449a69f00a59fc0df9c5) --- source4/scripting/python/pytalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index dc61a0a13d..d8d3efe69c 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -31,7 +31,7 @@ PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { py_talloc_Object *ret = PyObject_New(py_talloc_Object, py_type); - ret->talloc_ctx = talloc_reference(mem_ctx, ptr); + ret->talloc_ctx = talloc_reference(NULL, mem_ctx); ret->ptr = ptr; return (PyObject *)ret; } -- cgit From 271f5f18f2c871cfba256f7088839e4eb195e289 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 06:05:28 +0100 Subject: python: Fix last bugs in rpcecho test. It passes now! (This used to be commit 25a0cd091bb24e579ceb34472d9c213aae157ba9) --- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 52a4f49bb4..52c2bb8c72 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -31,12 +31,14 @@ class RpcEchoTests(unittest.TestCase): self.assertEquals(2, self.conn.AddOne(1)) def test_echodata(self): - self.assertEquals("bla", self.conn.EchoData(3, "bla")) + self.assertEquals([1,2,3], self.conn.EchoData(3, [1, 2, 3])) def test_call(self): - self.assertEquals("foobar", self.conn.TestCall("foobar")) + self.assertEquals(u"foobar", self.conn.TestCall(u"foobar")) def test_surrounding(self): - somearray = [1,2,3,4] - (y,) = self.conn.TestSurrounding(echo.Surrounding(4, somearray)) + surrounding_struct = echo.Surrounding() + surrounding_struct.x = 4 + surrounding_struct.surrounding = [1,2,3,4] + y = self.conn.TestSurrounding(surrounding_struct) self.assertEquals(8 * [0], y.surrounding) -- cgit From e42322848b81a36528a0af88138acb3ec997bf01 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 13:26:21 +0100 Subject: python: Start building winreg module. (This used to be commit f1a9fad83cee7754304b3422aa273d5f64868e40) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 55df51d881..5e53aadb94 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -35,6 +35,7 @@ extern void init_events(void); extern void inituuid(void); extern void init_net(void); extern void initecho(void); +extern void initwinreg(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 7dd468ff2e5a4c4ce503e1b8e024bf91dcf7a412 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 14:48:59 +0100 Subject: python: Fix python code for winreg, add test. (This used to be commit bd3e6c41c42738fcfcc5cef4e65f0e219d358260) --- source4/scripting/python/STATUS | 1 - .../python/samba/tests/dcerpc/registry.py | 53 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 source4/scripting/python/samba/tests/dcerpc/registry.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 9a1c5b1b64..0e88b4041c 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -10,7 +10,6 @@ DCE/RPC bindings - wrap struct/bitmap/enum/union types - __ndr_pack__/__ndr_unpack__ members - scripting/bin/smbstatus.py - - scripting/bin/winreg.py not important before making Python the default: - scripting/python/samba/upgrade.py diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py new file mode 100644 index 0000000000..7979592a40 --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -0,0 +1,53 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# + + +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# + +import winreg +from param import LoadParm +import unittest + +class WinregTests(unittest.TestCase): + def setUp(self): + lp_ctx = LoadParm() + lp_ctx.load("st/client/client.conf") + self.conn = winreg.winreg("ncalrpc:", lp_ctx) + + def test_hklm(self): + (handle, _) = self.conn.OpenHKLM(None, + winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + self.conn.CloseKey(handle) -- cgit From 035599fa651409502a6894179d5cd8a026110ba1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 15:25:09 +0100 Subject: python: Be more pythonic - turn WERROR and NTSTATUS return codes into exceptions. (This used to be commit 16fc69b843e92ae62b15caf927335cc117156499) --- .../python/samba/tests/dcerpc/registry.py | 39 ++++++++++------------ 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 7979592a40..f3f0b0fb1a 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -17,26 +17,6 @@ # along with this program. If not, see . # - -#!/usr/bin/python - -# Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2008 -# -# 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 . -# - import winreg from param import LoadParm import unittest @@ -47,7 +27,24 @@ class WinregTests(unittest.TestCase): lp_ctx.load("st/client/client.conf") self.conn = winreg.winreg("ncalrpc:", lp_ctx) + def get_hklm(self): + return self.conn.OpenHKLM(None, + winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + def test_hklm(self): - (handle, _) = self.conn.OpenHKLM(None, + handle = self.conn.OpenHKLM(None, + winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + self.conn.CloseKey(handle) + + def test_getversion(self): + handle = self.get_hklm() + version = self.conn.GetVersion(handle) + self.assertEquals(int, version.__class__) + self.conn.CloseKey(handle) + + def test_getkeyinfo(self): + handle = self.conn.OpenHKLM(None, winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + x = self.conn.QueryInfoKey(handle, winreg.String()) + self.assertEquals(9, len(x)) # should return a 9-tuple self.conn.CloseKey(handle) -- cgit From fa5397fbeda759ac66fc5d0a6bdfb60a070a7962 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 16:11:58 +0100 Subject: python: Build epmapper module. (This used to be commit 6cb78c7634de0f9ab327583844d7860d384356eb) --- source4/scripting/python/modules.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 5e53aadb94..d8a5fdeeae 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -36,6 +36,9 @@ extern void inituuid(void); extern void init_net(void); extern void initecho(void); extern void initwinreg(void); +extern void initepmapper(void); +extern void initinitshutdown(void); +static void initdcerpc_misc(void) {} static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From a896c8940ca372808c0725bc4f2725f6cb8467b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 16:48:27 +0100 Subject: python: Enable python bindings for samr and lsa interfaces. (This used to be commit 3dfcefd8ac640ef1539185f19f7414fbcea9e741) --- source4/scripting/python/modules.c | 3 +++ source4/scripting/python/pyrpc.h | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 source4/scripting/python/pyrpc.h (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index d8a5fdeeae..8c5115efca 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -39,6 +39,9 @@ extern void initwinreg(void); extern void initepmapper(void); extern void initinitshutdown(void); static void initdcerpc_misc(void) {} +extern void initmgmt(void); +extern void initatsvc(void); +extern void initsamr(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h new file mode 100644 index 0000000000..d7b64dbe93 --- /dev/null +++ b/source4/scripting/python/pyrpc.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2008 + + 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 . +*/ + +#define PY_CHECK_TYPE(type, var, fail) \ + if (!type ## _Check(var)) {\ + PyErr_Format(PyExc_TypeError, "Expected type %s", type ## _Type.tp_name); \ + fail; \ + } + +#define dom_sid2_Type dom_sid_Type +#define dom_sid28_Type dom_sid_Type -- cgit From 860106b3f426a06eed6a681fa839dd89f339ba9a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 16:49:19 +0100 Subject: python: Move some convenience macros to a separate header rather than putting them in every generated py_* file. (This used to be commit 712274b9bdf524da125cbbe6e4bb475b21b1da66) --- source4/scripting/python/pyrpc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h index d7b64dbe93..5390c6923d 100644 --- a/source4/scripting/python/pyrpc.h +++ b/source4/scripting/python/pyrpc.h @@ -25,3 +25,5 @@ #define dom_sid2_Type dom_sid_Type #define dom_sid28_Type dom_sid_Type +#define dom_sid2_Check dom_sid_Check +#define dom_sid28_Check dom_sid28_Check -- cgit From d28eb21a984a733e8f1de51170e41ae7c879f7e9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 18:59:11 +0100 Subject: python: Compile security module, handle uint. (This used to be commit dee64344fb13aaed38a550ebb4048d0fa526d5b6) --- source4/scripting/python/modules.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 8c5115efca..1728f166bd 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -42,6 +42,8 @@ static void initdcerpc_misc(void) {} extern void initmgmt(void); extern void initatsvc(void); extern void initsamr(void); +extern void initsecurity(void); +extern void initlsa(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 001b2435f0a47f75f82a32f2ccead2759596a09d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 19:05:08 +0100 Subject: python: Add simple test for samr python code. (This used to be commit 0a039fabcba9510ab600b2e4becbf75a58d2134d) --- source4/scripting/python/samba/tests/dcerpc/sam.py | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 source4/scripting/python/samba/tests/dcerpc/sam.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py new file mode 100644 index 0000000000..50caaf2348 --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# + +import samr +import unittest + +class SamrTests(unittest.TestCase): + def setUp(self): + self.conn = samr.samr("ncalrpc:", "st/client/client.conf") + + def test_connect5(self): + (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) -- cgit From 2aa8cbca8baf1159544c2f3c0ce316da03035d71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 19:49:52 +0100 Subject: python: Work around the fact that there are two "security" modules now. This well demonstrates the fact we need hierarchy. (This used to be commit df7e3498824e27f8a6d61b8b6f52577eab248d2c) --- source4/scripting/python/modules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 1728f166bd..c953e9866c 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -42,7 +42,7 @@ static void initdcerpc_misc(void) {} extern void initmgmt(void); extern void initatsvc(void); extern void initsamr(void); -extern void initsecurity(void); +static void initdcerpc_security(void) {} extern void initlsa(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 506f6432882804ed62fd3b8c1ddc2a4ac80fa08d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 20:08:04 +0100 Subject: python: Compile in svcctl Python bindings. (This used to be commit 567099b66d0369715f8e0a083a5ce160faaf4da2) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index c953e9866c..dc6e79fe1a 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -44,6 +44,7 @@ extern void initatsvc(void); extern void initsamr(void); static void initdcerpc_security(void) {} extern void initlsa(void); +extern void initsvcctl(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From d869de531c9f6b81c7eca43c3bfaab294c14cab1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 20:14:53 +0100 Subject: python: Enable building of the wkssvc python bindings. (This used to be commit 7a00d48a478be84e9f38c5e6cb57739063d0d613) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index dc6e79fe1a..b2dd50b507 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -45,6 +45,7 @@ extern void initsamr(void); static void initdcerpc_security(void) {} extern void initlsa(void); extern void initsvcctl(void); +extern void initwkssvc(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From 0c7f4c23b7c98b41dce1919aca78bc7b760659fe Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Jan 2008 01:08:30 +0100 Subject: python: Update status. (This used to be commit b4b12f00a7eb952024795ddc5ab3481fd4ba03fc) --- source4/scripting/python/STATUS | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 0e88b4041c..6e6475bfde 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -3,15 +3,13 @@ lib/ldb/tests/python/ldap.py: Fix remaining 3 FIXME's provisioning in LDAP mode(TEST_LDAP=yes PROVISION_PYTHON=yes make test) command-line vampire provisioning: combine some of the python dictionaries -hierarchy -DCE/RPC bindings - - pidl: - Parse::Pidl::Samba::Python - - wrap struct/bitmap/enum/union types - - __ndr_pack__/__ndr_unpack__ members - - scripting/bin/smbstatus.py +finish scripting/bin/smbstatus.py not important before making Python the default: +- hierarchy (rename samr -> dcerpc.samr, misc -> samba.misc, etc) - scripting/python/samba/upgrade.py - install python modules into system - SWAT +- __ndr_pack__/__ndr_unpack__ members for the NDR struct bindings +- generate docstrings in DCE/RPC bindings +- eliminate some variables from the python interface because they can be induced -- cgit From ad5bb10f707dddc0cea159af09393520128157d7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 23:04:57 +0100 Subject: python: Build shared python modules for generic use. (This used to be commit 502424955237ace5a276d4c91c62e95233ecd978) --- source4/scripting/python/config.mk | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index f00b477919..450da0e90a 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -16,7 +16,7 @@ PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i # Swig extensions -swig: pythonmods +swig:: pythonmods .SUFFIXES: _wrap.c .i @@ -28,13 +28,19 @@ realdistclean:: @-rm -f bin/python/* # FIXME: Remove _wrap.c files -pythonmods: $(PYTHON_DSOS) +pythonmods:: $(PYTHON_DSOS) $(PYTHON_PYS) PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) +installpython:: pythonmods + @$(SHELL) $(srcdir)/script/installpython.sh \ + $(INSTALLPERMS) \ + $(DESTDIR)$(PYTHONDIR) \ + scripting/python bin/python + clean:: @echo "Removing python modules" @rm -f bin/python/* -- cgit From 064eb82870596e72373c290dfaf0e6b8289303de Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jan 2008 13:25:01 +1100 Subject: Remove --ldap-base from the python provision script (This is a merge from the ejs script) Andrew Bartlett (This used to be commit d822dfa017b84895222ace8c44935fb872930548) --- source4/scripting/python/samba/provision.py | 32 ----------------------------- 1 file changed, 32 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 1607cb343b..d59cea121e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -180,12 +180,6 @@ def provision_paths_from_lp(lp, dnsdomain): paths.dns_keytab = os.path.join(private_dir, "dns.keytab") paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") - paths.ldap_basedn_ldif = os.path.join(private_dir, - dnsdomain + ".ldif") - paths.ldap_config_basedn_ldif = os.path.join(private_dir, - dnsdomain + "-config.ldif") - paths.ldap_schema_basedn_ldif = os.path.join(private_dir, - dnsdomain + "-schema.ldif") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") @@ -465,7 +459,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": domaindn, "ACI": aci, - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", "RDN_DC": rdn_dc, }) @@ -823,31 +816,6 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, }) -def provision_ldapbase(setup_dir, message, paths): - """Write out a DNS zone file, from the info in the current database.""" - message("Setting up LDAP base entry: %s" % domaindn) - rdns = domaindn.split(",") - - rdn_dc = rdns[0][len("DC="):] - - def setup_path(file): - return os.path.join(setup_dir, file) - - setup_file(setup_path("provision_basedn.ldif"), - paths.ldap_basedn_ldif) - - setup_file(setup_path("provision_configuration_basedn.ldif"), - paths.ldap_config_basedn_ldif) - - setup_file(setup_path("provision_schema_basedn.ldif"), - paths.ldap_schema_basedn_ldif, { - "SCHEMADN": schemadn, - "ACI": "# no aci for local ldb", - "EXTENSIBLEOBJECT": "objectClass: extensibleObject"}) - - message("Please install the LDIF located in " + paths.ldap_basedn_ldif + ", " + paths.ldap_config_basedn_ldif + " and " + paths.ldap_schema_basedn_ldif + " into your LDAP server, and re-run with --ldap-backend=ldap://my.ldap.server") - - def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): """Load schema. -- cgit From 42a793107e79624644ddfcac960b23eae3362002 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 20 Jan 2008 18:04:19 +0100 Subject: python: Fix init functions. (This used to be commit 4b057b9bffcef9ecc61fe016746f5ce6f17f6d06) --- source4/scripting/python/modules.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index b2dd50b507..fff981e941 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -46,6 +46,8 @@ static void initdcerpc_security(void) {} extern void initlsa(void); extern void initsvcctl(void); extern void initwkssvc(void); +extern void init_libcli_nbt(void); +extern void init_libcli_smb(void); static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES }; -- cgit From decdf5954d5e1ae84318d6767317965f544a897f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 23 Jan 2008 23:33:36 +0100 Subject: python: Add convenience function for getting command line loadparm context and default to using system smb.conf. (This used to be commit b3afde0f00ab5093b577b139a062c233d4db2524) --- source4/scripting/python/samba/getopt.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index a087974a69..dfcf2c457e 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -23,9 +23,25 @@ from credentials import Credentials class SambaOptions(optparse.OptionGroup): def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Samba Common Options") - self.add_option("-s", "--configfile", type="string", metavar="FILE", - help="Configuration file") + self.add_option("-s", "--configfile", action="callback", + type=str, metavar="FILE", help="Configuration file", + callback=self._load_configfile) + self._configfile = None + def get_loadparm_path(self): + return self._configfile + + def _load_configfile(self, option, opt_str, arg, parser): + self._configfile = arg + + def get_loadparm(self): + import param + lp = param.LoadParm() + if self._configfile is None: + lp.load_default() + else: + lp.load(self._configfile) + return lp class VersionOptions(optparse.OptionGroup): def __init__(self, parser): -- cgit From 42771814530639940b3349a6b5091f9a7d19f8f7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 24 Jan 2008 01:05:57 +0100 Subject: python: Support --no-pass. (This used to be commit a90f3e8c420bec7fd7a39e0d5e2df6b32aedcdd5) --- source4/scripting/python/samba/getopt.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index dfcf2c457e..088a5acf6f 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -50,6 +50,7 @@ class VersionOptions(optparse.OptionGroup): class CredentialsOptions(optparse.OptionGroup): def __init__(self, parser): + self.no_pass = False optparse.OptionGroup.__init__(self, parser, "Credentials Options") self.add_option("--simple-bind-dn", metavar="DN", action="callback", callback=self._set_simple_bind_dn, type=str, @@ -62,6 +63,8 @@ class CredentialsOptions(optparse.OptionGroup): 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.creds = Credentials() def _parse_username(self, option, opt_str, arg, parser): @@ -77,4 +80,7 @@ class CredentialsOptions(optparse.OptionGroup): self.creds.set_bind_dn(arg) def get_credentials(self): + self.creds.guess() + if not self.no_pass: + self.creds.set_cmdline_callbacks() return self.creds -- cgit From a2dcf7bd22b5f206ef3c3816d0c93b140260da67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 24 Jan 2008 01:06:19 +0100 Subject: Python: add some docstrings. (This used to be commit 1de69a772e1cc007220add1f51bffe83784c3344) --- source4/scripting/python/samba/provision.py | 51 ++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d59cea121e..11dd819ad3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -289,6 +289,14 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, def setup_secretsdb(path, setup_path, session_info, credentials, lp): + """Setup the secrets database. + + :param path: Path to the secrets database. + :param setup_path: Get the path to a setup file. + :param session_info: Session info. + :param credentials: Credentials + :param lp: Loadparm context + """ if os.path.exists(path): os.unlink(path) secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) @@ -299,6 +307,14 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): def setup_templatesdb(path, setup_path, session_info, credentials, lp): + """Setup the templates database. + + :param path: Path to the database. + :param setup_path: Function for obtaining the path to setup files. + :param session_info: Session info + :param credentials: Credentials + :param lp: Loadparm context + """ templates_ldb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) templates_ldb.erase() @@ -306,6 +322,14 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): def setup_registry(path, setup_path, session_info, credentials, lp): + """Setup the registry. + + :param path: Path to the registry database + :param setup_path: Function that returns the path to a setup. + :param session_info: Session information + :param credentials: Credentials + :param lp: Loadparm context + """ reg = registry.Registry() hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) @@ -317,6 +341,12 @@ def setup_registry(path, setup_path, session_info, credentials, lp): def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname): + """Setup the SamDB rootdse. + + :param samdb: Sam Database handle + :param setup_path: Obtain setup path + ... + """ setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, @@ -332,6 +362,14 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): + """Setup SAM database partitions. + + :param samdb: Sam Database handle + :param setup_path: Setup path function + :param schemadn: Schema DN. + :param configdn: Configuration DN. + :param domaindn: Domain DN. + """ #Add modules to the list to activate them by default #beware often order is important # @@ -561,11 +599,14 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if lp.get("server role") == "domain controller": message("Setting up self join") - setup_self_join(samdb, configdn=configdn, schemadn=schemadn, domaindn=domaindn, - invocationid=invocationid, dnspass=dnspass, netbiosname=netbiosname, - dnsdomain=dnsdomain, realm=realm, machinepass=machinepass, - domainname=domainname, domainsid=domainsid, policyguid=policyguid, - hostname=hostname, hostguid=hostguid, setup_path=setup_path) + setup_self_join(samdb, configdn=configdn, schemadn=schemadn, + domaindn=domaindn, invocationid=invocationid, + dnspass=dnspass, netbiosname=netbiosname, + dnsdomain=dnsdomain, realm=realm, + machinepass=machinepass, domainname=domainname, + domainsid=domainsid, policyguid=policyguid, + hostname=hostname, hostguid=hostguid, + setup_path=setup_path) message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) -- cgit From 859b847a68cf10526b9f356ebcb328e7334a8cb1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 24 Jan 2008 22:08:39 +0100 Subject: python: Add bindings for SamDB.set_invocation_id(). (This used to be commit c09efa7b778f9cb29032a6abfd914fcaae8df163) --- source4/scripting/python/misc.i | 2 + source4/scripting/python/misc.py | 1 + source4/scripting/python/misc_wrap.c | 101 +++++++++++++++++++++++--------- source4/scripting/python/samba/samdb.py | 7 +++ 4 files changed, 82 insertions(+), 29 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 2f41840670..d5c9cde93e 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -66,3 +66,5 @@ WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf const char *samba_version_string(void); int dsdb_set_global_schema(struct ldb_context *ldb); int ldb_register_samba_handlers(struct ldb_context *ldb); + +bool samdb_set_ntds_invocation_id(struct ldb_context *ldb, const struct GUID *invocation_id_in); \ No newline at end of file diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index ae900a1f62..998de46504 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -70,5 +70,6 @@ dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file version = _misc.version dsdb_set_global_schema = _misc.dsdb_set_global_schema ldb_register_samba_handlers = _misc.ldb_register_samba_handlers +samdb_set_ntds_invocation_id = _misc.samdb_set_ntds_invocation_id diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index a7493550cc..564bcc0e46 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2459,35 +2459,36 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) /* -------- TYPES TABLE (BEGIN) -------- */ -#define SWIGTYPE_p_TALLOC_CTX swig_types[0] -#define SWIGTYPE_p_auth_session_info swig_types[1] -#define SWIGTYPE_p_char swig_types[2] -#define SWIGTYPE_p_cli_credentials swig_types[3] -#define SWIGTYPE_p_dom_sid swig_types[4] -#define SWIGTYPE_p_int swig_types[5] -#define SWIGTYPE_p_ldb_context swig_types[6] -#define SWIGTYPE_p_ldb_dn swig_types[7] -#define SWIGTYPE_p_ldb_ldif swig_types[8] -#define SWIGTYPE_p_ldb_message swig_types[9] -#define SWIGTYPE_p_ldb_message_element swig_types[10] -#define SWIGTYPE_p_ldb_result swig_types[11] -#define SWIGTYPE_p_loadparm_context swig_types[12] -#define SWIGTYPE_p_loadparm_service swig_types[13] -#define SWIGTYPE_p_long_long swig_types[14] -#define SWIGTYPE_p_param_context swig_types[15] -#define SWIGTYPE_p_param_opt swig_types[16] -#define SWIGTYPE_p_param_section swig_types[17] -#define SWIGTYPE_p_security_descriptor swig_types[18] -#define SWIGTYPE_p_security_token swig_types[19] -#define SWIGTYPE_p_short swig_types[20] -#define SWIGTYPE_p_signed_char swig_types[21] -#define SWIGTYPE_p_unsigned_char swig_types[22] -#define SWIGTYPE_p_unsigned_int swig_types[23] -#define SWIGTYPE_p_unsigned_long swig_types[24] -#define SWIGTYPE_p_unsigned_long_long swig_types[25] -#define SWIGTYPE_p_unsigned_short swig_types[26] -static swig_type_info *swig_types[28]; -static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; +#define SWIGTYPE_p_GUID swig_types[0] +#define SWIGTYPE_p_TALLOC_CTX swig_types[1] +#define SWIGTYPE_p_auth_session_info swig_types[2] +#define SWIGTYPE_p_char swig_types[3] +#define SWIGTYPE_p_cli_credentials swig_types[4] +#define SWIGTYPE_p_dom_sid swig_types[5] +#define SWIGTYPE_p_int swig_types[6] +#define SWIGTYPE_p_ldb_context swig_types[7] +#define SWIGTYPE_p_ldb_dn swig_types[8] +#define SWIGTYPE_p_ldb_ldif swig_types[9] +#define SWIGTYPE_p_ldb_message swig_types[10] +#define SWIGTYPE_p_ldb_message_element swig_types[11] +#define SWIGTYPE_p_ldb_result swig_types[12] +#define SWIGTYPE_p_loadparm_context swig_types[13] +#define SWIGTYPE_p_loadparm_service swig_types[14] +#define SWIGTYPE_p_long_long swig_types[15] +#define SWIGTYPE_p_param_context swig_types[16] +#define SWIGTYPE_p_param_opt swig_types[17] +#define SWIGTYPE_p_param_section swig_types[18] +#define SWIGTYPE_p_security_descriptor swig_types[19] +#define SWIGTYPE_p_security_token swig_types[20] +#define SWIGTYPE_p_short swig_types[21] +#define SWIGTYPE_p_signed_char swig_types[22] +#define SWIGTYPE_p_unsigned_char swig_types[23] +#define SWIGTYPE_p_unsigned_int swig_types[24] +#define SWIGTYPE_p_unsigned_long swig_types[25] +#define SWIGTYPE_p_unsigned_long_long swig_types[26] +#define SWIGTYPE_p_unsigned_short swig_types[27] +static swig_type_info *swig_types[29]; +static swig_module_info swig_module = {swig_types, 28, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -3102,6 +3103,43 @@ fail: } +SWIGINTERN PyObject *_wrap_samdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + struct GUID *arg2 = (struct GUID *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "ldb",(char *) "invocation_id_in", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:samdb_set_ntds_invocation_id",kwnames,&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "samdb_set_ntds_invocation_id" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_GUID, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "samdb_set_ntds_invocation_id" "', argument " "2"" of type '" "struct GUID const *""'"); + } + arg2 = (struct GUID *)(argp2); + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + result = (bool)samdb_set_ntds_invocation_id(arg1,(struct GUID const *)arg2); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -3112,12 +3150,14 @@ static PyMethodDef SwigMethods[] = { { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, NULL}, { (char *)"dsdb_set_global_schema", (PyCFunction) _wrap_dsdb_set_global_schema, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"samdb_set_ntds_invocation_id", (PyCFunction) _wrap_samdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ +static swig_type_info _swigt__p_GUID = {"_p_GUID", "struct GUID *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; @@ -3147,6 +3187,7 @@ static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", " static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { + &_swigt__p_GUID, &_swigt__p_TALLOC_CTX, &_swigt__p_auth_session_info, &_swigt__p_char, @@ -3176,6 +3217,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_unsigned_short, }; +static swig_cast_info _swigc__p_GUID[] = { {&_swigt__p_GUID, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_auth_session_info[] = { {&_swigt__p_auth_session_info, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; @@ -3205,6 +3247,7 @@ static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_l static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { + _swigc__p_GUID, _swigc__p_TALLOC_CTX, _swigc__p_auth_session_info, _swigc__p_char, diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 353eaee198..e92a4bbb90 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -145,3 +145,10 @@ member: %s def attach_schema_from_ldif(self, pf, df): misc.dsdb_attach_schema_from_ldif_file(self, pf, df) + + def set_invocation_id(self, invocation_id): + """Set the invocation id for this SamDB handle. + + :param invocation_id: GUID of the invocation id. + """ + misc.samdb_set_ntds_invocation_id(self, invocation_id) \ No newline at end of file -- cgit From d958f4b3912dc298037c112ad724b85a7a46ecdb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 24 Jan 2008 22:18:27 +0100 Subject: python: Add function to look for unsubsituted variables. (This used to be commit e726ce5bc515ae8d10b472396e228cfd35737476) --- source4/scripting/python/samba/__init__.py | 15 +++++++++++++++ source4/scripting/python/samba/tests/__init__.py | 4 ++++ 2 files changed, 19 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 483929661d..b5d7f2ebc7 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -192,6 +192,21 @@ def substitute_var(text, values): return text +def check_all_substituted(text): + """Make sure that all substitution variables in a string have been replaced. + If not, raise an exception. + + :param text: The text to search for substitution variables + """ + if not "${" in text: + return + + var_start = text.find("${") + var_end = text.find("}", var_start) + + raise Exception("Not all variables substituted: %s" % text[var_start:var_end]) + + def valid_netbios_name(name): """Check whether a name is valid as a NetBIOS name. """ # FIXME: There are probably more constraints here. diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index ad8a2524b5..6fbf420339 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -67,6 +67,10 @@ class SubstituteVarTestCase(unittest.TestCase): def test_unknown_var(self): self.assertEquals("foo ${bla} gsff", samba.substitute_var("foo ${bla} gsff", {"bar": "bla"})) + + def test_check_all_substituted(self): + check_all_substituted("nothing to see here") + self.assertRaises(Exception, check_all_substituted, "Not subsituted: ${FOOBAR}") class LdbExtensionTests(TestCaseInTempDir): -- cgit From 8afcbdcfe71fad0f6a22314de16ac047148d42b8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 00:51:09 +0100 Subject: python: Make SamDB.set_ntds_invocation_id take a string. (This used to be commit 59bb26772f089cf4d8727c12230cfef8126762b1) --- source4/scripting/python/misc.i | 11 +++- source4/scripting/python/misc.py | 2 +- source4/scripting/python/misc_wrap.c | 100 +++++++++++++++++++---------------- 3 files changed, 65 insertions(+), 48 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index d5c9cde93e..a11b2fb825 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -67,4 +67,13 @@ const char *samba_version_string(void); int dsdb_set_global_schema(struct ldb_context *ldb); int ldb_register_samba_handlers(struct ldb_context *ldb); -bool samdb_set_ntds_invocation_id(struct ldb_context *ldb, const struct GUID *invocation_id_in); \ No newline at end of file +%inline %{ +bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid) +{ + struct GUID invocation_id_in; + if (NT_STATUS_IS_ERR(GUID_from_string(guid, &invocation_id_in))) { + return false; + } + return samdb_set_ntds_invocation_id(ldb, &invocation_id_in); +} +%} diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 998de46504..2fc7fe37e7 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -70,6 +70,6 @@ dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file version = _misc.version dsdb_set_global_schema = _misc.dsdb_set_global_schema ldb_register_samba_handlers = _misc.ldb_register_samba_handlers -samdb_set_ntds_invocation_id = _misc.samdb_set_ntds_invocation_id +dsdb_set_ntds_invocation_id = _misc.dsdb_set_ntds_invocation_id diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 564bcc0e46..f467f851bd 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2459,36 +2459,35 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) /* -------- TYPES TABLE (BEGIN) -------- */ -#define SWIGTYPE_p_GUID swig_types[0] -#define SWIGTYPE_p_TALLOC_CTX swig_types[1] -#define SWIGTYPE_p_auth_session_info swig_types[2] -#define SWIGTYPE_p_char swig_types[3] -#define SWIGTYPE_p_cli_credentials swig_types[4] -#define SWIGTYPE_p_dom_sid swig_types[5] -#define SWIGTYPE_p_int swig_types[6] -#define SWIGTYPE_p_ldb_context swig_types[7] -#define SWIGTYPE_p_ldb_dn swig_types[8] -#define SWIGTYPE_p_ldb_ldif swig_types[9] -#define SWIGTYPE_p_ldb_message swig_types[10] -#define SWIGTYPE_p_ldb_message_element swig_types[11] -#define SWIGTYPE_p_ldb_result swig_types[12] -#define SWIGTYPE_p_loadparm_context swig_types[13] -#define SWIGTYPE_p_loadparm_service swig_types[14] -#define SWIGTYPE_p_long_long swig_types[15] -#define SWIGTYPE_p_param_context swig_types[16] -#define SWIGTYPE_p_param_opt swig_types[17] -#define SWIGTYPE_p_param_section swig_types[18] -#define SWIGTYPE_p_security_descriptor swig_types[19] -#define SWIGTYPE_p_security_token swig_types[20] -#define SWIGTYPE_p_short swig_types[21] -#define SWIGTYPE_p_signed_char swig_types[22] -#define SWIGTYPE_p_unsigned_char swig_types[23] -#define SWIGTYPE_p_unsigned_int swig_types[24] -#define SWIGTYPE_p_unsigned_long swig_types[25] -#define SWIGTYPE_p_unsigned_long_long swig_types[26] -#define SWIGTYPE_p_unsigned_short swig_types[27] -static swig_type_info *swig_types[29]; -static swig_module_info swig_module = {swig_types, 28, 0, 0, 0, 0}; +#define SWIGTYPE_p_TALLOC_CTX swig_types[0] +#define SWIGTYPE_p_auth_session_info swig_types[1] +#define SWIGTYPE_p_char swig_types[2] +#define SWIGTYPE_p_cli_credentials swig_types[3] +#define SWIGTYPE_p_dom_sid swig_types[4] +#define SWIGTYPE_p_int swig_types[5] +#define SWIGTYPE_p_ldb_context swig_types[6] +#define SWIGTYPE_p_ldb_dn swig_types[7] +#define SWIGTYPE_p_ldb_ldif swig_types[8] +#define SWIGTYPE_p_ldb_message swig_types[9] +#define SWIGTYPE_p_ldb_message_element swig_types[10] +#define SWIGTYPE_p_ldb_result swig_types[11] +#define SWIGTYPE_p_loadparm_context swig_types[12] +#define SWIGTYPE_p_loadparm_service swig_types[13] +#define SWIGTYPE_p_long_long swig_types[14] +#define SWIGTYPE_p_param_context swig_types[15] +#define SWIGTYPE_p_param_opt swig_types[16] +#define SWIGTYPE_p_param_section swig_types[17] +#define SWIGTYPE_p_security_descriptor swig_types[18] +#define SWIGTYPE_p_security_token swig_types[19] +#define SWIGTYPE_p_short swig_types[20] +#define SWIGTYPE_p_signed_char swig_types[21] +#define SWIGTYPE_p_unsigned_char swig_types[22] +#define SWIGTYPE_p_unsigned_int swig_types[23] +#define SWIGTYPE_p_unsigned_long swig_types[24] +#define SWIGTYPE_p_unsigned_long_long swig_types[25] +#define SWIGTYPE_p_unsigned_short swig_types[26] +static swig_type_info *swig_types[28]; +static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) @@ -2795,6 +2794,16 @@ SWIG_From_int (int value) return SWIG_From_long (value); } + +bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid) +{ + struct GUID invocation_id_in; + if (NT_STATUS_IS_ERR(GUID_from_string(guid, &invocation_id_in))) { + return false; + } + return samdb_set_ntds_invocation_id(ldb, &invocation_id_in); +} + #ifdef __cplusplus extern "C" { #endif @@ -3103,39 +3112,42 @@ fail: } -SWIGINTERN PyObject *_wrap_samdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { +SWIGINTERN PyObject *_wrap_dsdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; - struct GUID *arg2 = (struct GUID *) 0 ; + char *arg2 = (char *) 0 ; bool result; void *argp1 = 0 ; int res1 = 0 ; - void *argp2 = 0 ; - int res2 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; char * kwnames[] = { - (char *) "ldb",(char *) "invocation_id_in", NULL + (char *) "ldb",(char *) "guid", NULL }; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:samdb_set_ntds_invocation_id",kwnames,&obj0,&obj1)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:dsdb_set_ntds_invocation_id",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "samdb_set_ntds_invocation_id" "', argument " "1"" of type '" "struct ldb_context *""'"); + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsdb_set_ntds_invocation_id" "', argument " "1"" of type '" "struct ldb_context *""'"); } arg1 = (struct ldb_context *)(argp1); - res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_GUID, 0 | 0 ); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "samdb_set_ntds_invocation_id" "', argument " "2"" of type '" "struct GUID const *""'"); + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dsdb_set_ntds_invocation_id" "', argument " "2"" of type '" "char const *""'"); } - arg2 = (struct GUID *)(argp2); + arg2 = (char *)(buf2); if (arg1 == NULL) SWIG_exception(SWIG_ValueError, "ldb context must be non-NULL"); - result = (bool)samdb_set_ntds_invocation_id(arg1,(struct GUID const *)arg2); + result = (bool)dsdb_set_ntds_invocation_id(arg1,(char const *)arg2); resultobj = SWIG_From_bool((bool)(result)); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return resultobj; fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); return NULL; } @@ -3150,14 +3162,13 @@ static PyMethodDef SwigMethods[] = { { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, NULL}, { (char *)"dsdb_set_global_schema", (PyCFunction) _wrap_dsdb_set_global_schema, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"samdb_set_ntds_invocation_id", (PyCFunction) _wrap_samdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"dsdb_set_ntds_invocation_id", (PyCFunction) _wrap_dsdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ -static swig_type_info _swigt__p_GUID = {"_p_GUID", "struct GUID *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_TALLOC_CTX = {"_p_TALLOC_CTX", "TALLOC_CTX *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_auth_session_info = {"_p_auth_session_info", "struct auth_session_info *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; @@ -3187,7 +3198,6 @@ static swig_type_info _swigt__p_unsigned_long_long = {"_p_unsigned_long_long", " static swig_type_info _swigt__p_unsigned_short = {"_p_unsigned_short", "unsigned short *|uint_least16_t *|uint16_t *", 0, 0, (void*)0, 0}; static swig_type_info *swig_type_initial[] = { - &_swigt__p_GUID, &_swigt__p_TALLOC_CTX, &_swigt__p_auth_session_info, &_swigt__p_char, @@ -3217,7 +3227,6 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_unsigned_short, }; -static swig_cast_info _swigc__p_GUID[] = { {&_swigt__p_GUID, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_TALLOC_CTX[] = { {&_swigt__p_TALLOC_CTX, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_auth_session_info[] = { {&_swigt__p_auth_session_info, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; @@ -3247,7 +3256,6 @@ static swig_cast_info _swigc__p_unsigned_long_long[] = { {&_swigt__p_unsigned_l static swig_cast_info _swigc__p_unsigned_short[] = { {&_swigt__p_unsigned_short, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info *swig_cast_initial[] = { - _swigc__p_GUID, _swigc__p_TALLOC_CTX, _swigc__p_auth_session_info, _swigc__p_char, -- cgit From 37f35d2a03409e0d52232d4c4f956ec8637d4884 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 01:02:13 +0100 Subject: python/provision: Reconcile code partitions-only provisioning and generic provisioning, some other minor refactoring of the provisioning. Pair-programmed by Andrew and me using obby :-) (This used to be commit 688adcbb635af87fcfedb869b7f1857a947fd2f9) --- source4/scripting/python/samba/__init__.py | 6 +- source4/scripting/python/samba/provision.py | 469 +++++++++++++---------- source4/scripting/python/samba/samdb.py | 6 +- source4/scripting/python/samba/tests/__init__.py | 2 +- source4/scripting/python/samba/upgrade.py | 5 +- 5 files changed, 276 insertions(+), 212 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index b5d7f2ebc7..5c14edd357 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -1,8 +1,10 @@ #!/usr/bin/python # Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2007-2008 +# +# Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 -# Copyright (C) Jelmer Vernooij 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 @@ -204,7 +206,7 @@ def check_all_substituted(text): var_start = text.find("${") var_end = text.find("}", var_start) - raise Exception("Not all variables substituted: %s" % text[var_start:var_end]) + raise Exception("Not all variables substituted: %s" % text[var_start:var_end+1]) def valid_netbios_name(name): diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 11dd819ad3..918d983782 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1,10 +1,25 @@ # -# backend code for provisioning a Samba4 server -# Released under the GNU GPL v3 or later -# Copyright Jelmer Vernooij 2007 +# Unix SMB/CIFS implementation. +# backend code for provisioning a Samba4 server + +# Copyright (C) Jelmer Vernooij 2007-2008 +# Copyright (C) Andrew Bartlett 2008 # # Based on the original in EJS: -# Copyright Andrew Tridgell 2005 +# Copyright (C) Andrew Tridgell 2005 +# +# 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 . # from base64 import b64encode @@ -17,9 +32,10 @@ from socket import gethostname, gethostbyname import param import registry import samba -from samba import Ldb, substitute_var, valid_netbios_name +from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted from samba.samdb import SamDB import security +import urllib from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE @@ -53,7 +69,7 @@ class ProvisionPaths: self.ldap_schema_basedn_ldif = None -def install_ok(lp, session_info, credentials): +def check_install(lp, session_info, credentials): """Check whether the current install seems ok. :param lp: Loadparm context @@ -61,12 +77,11 @@ def install_ok(lp, session_info, credentials): :param credentials: Credentials """ if lp.get("realm") == "": - return False + raise Error("Realm empty") ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) if len(ldb.search("(cn=Administrator)")) != 1: - return False - return True + raise "No administrator account found" def findnss(nssfn, *names): @@ -112,7 +127,7 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None): if subst_vars is not None: data = substitute_var(data, subst_vars) - assert "${" not in data + check_all_substituted(data) ldb.add_ldif(data) @@ -128,7 +143,7 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None): if substvars is not None: data = substitute_var(data, substvars) - assert "${" not in data + check_all_substituted(data) ldb.modify_ldif(data) @@ -159,19 +174,20 @@ def setup_file(template, fname, substvars): data = open(template, 'r').read() if substvars: data = substitute_var(data, substvars) - assert not "${" in data + check_all_substituted(data) open(f, 'w').write(data) -def provision_paths_from_lp(lp, dnsdomain): +def provision_paths_from_lp(lp, dnsdomain, private_dir=None): """Set the default paths for provisioning. :param lp: Loadparm context. :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() - private_dir = lp.get("private dir") + if private_dir is None: + private_dir = lp.get("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") @@ -235,57 +251,144 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, ldb.setup_name_mapping(domaindn, sid + "-520", wheel) -def provision_become_dc(setup_dir, message, paths, lp, session_info, - credentials): +def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, + credentials, configdn, schemadn, domaindn, + hostname, netbiosname, dnsdomain, realm, + rootdn, serverrole, ldap_backend=None, + ldap_backend_type=None, erase=False): + """Setup the partitions for the SAM database. + + Alternatively, provision() may call this, and then populate the database. + + :param erase: Remove the existing data present in the database. + :param + + :note: This will wipe the Sam Database! + + :note: This function always removes the local SAM LDB file. The erase + parameter controls whether to erase the existing data, which + may not be stored locally but in LDAP. + """ assert session_info is not None - erase = False - def setup_path(file): - return os.path.join(setup_dir, file) - os.path.unlink(paths.samdb) - - message("Setting up templates db") - setup_templatesdb(paths.templates, setup_path, session_info=session_info, - credentials=credentials, lp=lp) + if os.path.exists(samdb_path): + os.unlink(samdb_path) # Also wipes the database - message("Setting up sam.ldb") - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) - message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) + #Add modules to the list to activate them by default + #beware often order is important + # + # Some Known ordering constraints: + # - rootdse must be first, as it makes redirects from "" -> cn=rootdse + # - objectclass must be before password_hash, because password_hash checks + # that the objectclass is of type person (filled in by objectclass + # module when expanding the objectclass list) + # - partition must be last + # - each partition has its own module list then + modules_list = ["rootdse", + "paged_results", + "ranged_results", + "anr", + "server_sort", + "extended_dn", + "asq", + "samldb", + "rdn_name", + "objectclass", + "kludge_acl", + "operational"] + tdb_modules_list = [ + "subtree_rename", + "subtree_delete", + "linked_attributes"] + modules_list2 = ["show_deleted", + "partition"] + + domaindn_ldb = "users.ldb" + if ldap_backend is not None: + domaindn_ldb = ldap_backend + configdn_ldb = "configuration.ldb" + if ldap_backend is not None: + configdn_ldb = ldap_backend + schema_ldb = "schema.ldb" + if ldap_backend is not None: + schema_ldb = ldap_backend + + if ldap_backend_type == "fedora-ds": + backend_modules = ["nsuniqueid","paged_searches"] + elif ldap_backend_type == "openldap": + backend_modules = ["normalise","entryuuid","paged_searches"] + elif serverrole == "domain controller": + backend_modules = ["repl_meta_data"] + else: + backend_modules = ["objectguid"] + + setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { + "SCHEMADN": schemadn, + "SCHEMADN_LDB": "schema.ldb", + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": configdn, + "CONFIGDN_LDB": "configuration.ldb", + "DOMAINDN": domaindn, + "DOMAINDN_LDB": "users.ldb", + "SCHEMADN_MOD": "schema_fsmo,instancetype", + "CONFIGDN_MOD": "naming_fsmo,instancetype", + "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", + "MODULES_LIST": ",".join(modules_list), + "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "MODULES_LIST2": ",".join(modules_list2), + "BACKEND_MOD": ",".join(backend_modules), + }) - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) - ldb.transaction_start() + samdb.transaction_start() try: message("Setting up sam.ldb attributes") samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, - hostname, dnsdomain, realm, rootdn, configdn, - netbiosname) + setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, + dnsdomain, realm, rootdn, configdn, netbiosname) if erase: message("Erasing data from partitions") samdb.erase_partitions() - message("Setting up sam.ldb indexes") - samdb.load_ldif_file_add(setup_path("provision_index.ldif")) except: samdb.transaction_cancel() raise samdb.transaction_commit() + + return samdb + - message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, - credentials, lp) - setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), - { "MACHINEPASS_B64": b64encode(machinepass) }) +def secretsdb_become_dc(secretsdb, setup_path, domain, realm, dnsdomain, + netbiosname, domainsid, keytab_path, samdb_url, + dns_keytab_path, dnspass, machinepass): + """Add DC-specific bits to a secrets database. + + :param secretsdb: Ldb Handle to the secrets database + :param setup_path: Setup path function + :param machinepass: Machine password + """ + setup_ldb(secretsdb, setup_path("secrets_dc.ldif"), { + "MACHINEPASS_B64": b64encode(machinepass), + "DOMAIN": domain, + "REALM": realm, + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "SECRETS_KEYTAB": keytab_path, + "NETBIOSNAME": netbiosname, + "SAM_LDB": samdb_url, + "DNS_KEYTAB": dns_keytab_path, + "DNSPASS_B64": b64encode(dnspass), + }) def setup_secretsdb(path, setup_path, session_info, credentials, lp): @@ -296,10 +399,12 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): :param session_info: Session info. :param credentials: Credentials :param lp: Loadparm context + :return: LDB handle for the created secrets database """ if os.path.exists(path): os.unlink(path) - secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) @@ -316,7 +421,7 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): :param lp: Loadparm context """ templates_ldb = SamDB(path, session_info=session_info, - credentials=credentials, lp=lp) + credentials=credentials, lp=lp) templates_ldb.erase() templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif")) @@ -359,69 +464,13 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, "CONFIGDN": configdn, "VERSION": samba.version(), }) - - -def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): - """Setup SAM database partitions. - - :param samdb: Sam Database handle - :param setup_path: Setup path function - :param schemadn: Schema DN. - :param configdn: Configuration DN. - :param domaindn: Domain DN. - """ - #Add modules to the list to activate them by default - #beware often order is important - # - # Some Known ordering constraints: - # - rootdse must be first, as it makes redirects from "" -> cn=rootdse - # - objectclass must be before password_hash, because password_hash checks - # that the objectclass is of type person (filled in by objectclass - # module when expanding the objectclass list) - # - partition must be last - # - each partition has its own module list then - modules_list = ["rootdse", - "paged_results", - "ranged_results", - "anr", - "server_sort", - "extended_dn", - "asq", - "samldb", - "rdn_name", - "objectclass", - "kludge_acl", - "operational"] - tdb_modules_list = [ - "subtree_rename", - "subtree_delete", - "linked_attributes"] - modules_list2 = ["show_deleted", - "partition"] - - setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { - "SCHEMADN": schemadn, - "SCHEMADN_LDB": "schema.ldb", - "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": configdn, - "CONFIGDN_LDB": "configuration.ldb", - "DOMAINDN": domaindn, - "DOMAINDN_LDB": "users.ldb", - "SCHEMADN_MOD": "schema_fsmo", - "CONFIGDN_MOD": "naming_fsmo", - "CONFIGDN_MOD2": ",objectguid", - "DOMAINDN_MOD": "pdc_fsmo,password_hash", - "DOMAINDN_MOD2": ",objectguid", - "MODULES_LIST": ",".join(modules_list), - "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), - "MODULES_LIST2": ",".join(modules_list2), - }) - + def setup_self_join(samdb, configdn, schemadn, domaindn, netbiosname, hostname, dnsdomain, machinepass, dnspass, realm, domainname, domainsid, invocationid, setup_path, policyguid, hostguid=None): + """Join a host to its own domain.""" if hostguid is not None: hostguid_add = "objectGUID: %s" % hostguid else: @@ -451,43 +500,39 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, def setup_samdb(path, setup_path, session_info, credentials, lp, schemadn, configdn, domaindn, dnsdomain, realm, netbiosname, message, hostname, rootdn, erase, - domainsid, aci, rdn_dc, domainguid, policyguid, - domainname, blank, adminpass, krbtgtpass, - machinepass, hostguid, invocationid, dnspass): - # Also wipes the database - message("Setting up sam.ldb") - samdb = SamDB(path, session_info=session_info, - credentials=credentials, lp=lp) + domainsid, aci, domainguid, policyguid, + domainname, fill, adminpass, krbtgtpass, + machinepass, hostguid, invocationid, dnspass, + serverrole, ldap_backend=None, ldap_backend_type=None): + """Setup a complete SAM Database. + + """ - message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) + # Also wipes the database + setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, + domaindn=domaindn, message=message, lp=lp, + credentials=credentials, session_info=session_info, + hostname=hostname, netbiosname=netbiosname, + dnsdomain=dnsdomain, realm=realm, rootdn=rootdn, + ldap_backend=ldap_backend, serverrole=serverrole, + ldap_backend_type=ldap_backend_type, erase=erase) samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) - samdb.transaction_start() - try: - message("Setting up sam.ldb attributes") - samdb.load_ldif_file_add(setup_path("provision_init.ldif")) - - message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, - hostname, dnsdomain, realm, rootdn, configdn, - netbiosname) - - if erase: - message("Erasing data from partitions") - samdb.erase_partitions() - except: - samdb.transaction_cancel() - raise - - samdb.transaction_commit() + if fill == FILL_DRS: + # We want to finish here, but setup the index before we do so + message("Setting up sam.ldb index") + samdb.load_ldif_file_add(setup_path("provision_index.ldif")) + return samdb message("Pre-loading the Samba 4 and AD schema") samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) + if lp.get("server role") == "domain controller": + samdb.set_invocation_id(invocationid) + load_schema(setup_path, samdb, schemadn, netbiosname, configdn) samdb.transaction_start() @@ -497,7 +542,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": domaindn, "ACI": aci, - "RDN_DC": rdn_dc, }) message("Modifying DomainDN: " + domaindn + "") @@ -507,7 +551,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domainguid_mod = "" setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), { - "RDN_DC": rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(domainsid), "SCHEMADN": schemadn, @@ -538,7 +581,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { + setup_modify_ldif(samdb, + setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -587,7 +631,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "CONFIGDN": configdn, }) - if not blank: + if fill == FILL_FULL: message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_path("provision_users.ldif"), { "DOMAINDN": domaindn, @@ -608,11 +652,9 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, hostname=hostname, hostguid=hostguid, setup_path=setup_path) + #We want to setup the index last, as adds are faster unindexed message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) - - message("Setting up sam.ldb rootDSE marking as synchronized") - setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) except: samdb.transaction_cancel() raise @@ -620,14 +662,18 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb.transaction_commit() return samdb - -def provision(lp, setup_dir, message, blank, paths, session_info, - credentials, ldapbackend, realm=None, domain=None, hostname=None, - hostip=None, domainsid=None, hostguid=None, adminpass=None, - krbtgtpass=None, domainguid=None, policyguid=None, - invocationid=None, machinepass=None, dnspass=None, root=None, - nobody=None, nogroup=None, users=None, wheel=None, backup=None, - aci=None, serverrole=None): +FILL_FULL = "FULL" +FILL_NT4SYNC = "NT4SYNC" +FILL_DRS = "DRS" + +def provision(lp, setup_dir, message, paths, session_info, + credentials, ldapbackend, samdb_fill=FILL_FULL, realm=None, rootdn=None, + domain=None, hostname=None, hostip=None, domainsid=None, + hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + policyguid=None, invocationid=None, machinepass=None, + dnspass=None, root=None, nobody=None, nogroup=None, users=None, + wheel=None, backup=None, aci=None, serverrole=None, erase=False, + ldap_backend=None, ldap_backend_type=None): """Provision samba4 :note: caution, this wipes all existing data! @@ -636,14 +682,10 @@ def provision(lp, setup_dir, message, blank, paths, session_info, def setup_path(file): return os.path.join(setup_dir, file) - erase = False - if domainsid is None: domainsid = security.random_sid() if policyguid is None: policyguid = uuid.random() - if invocationid is None: - invocationid = uuid.random() if adminpass is None: adminpass = misc.random_password(12) if krbtgtpass is None: @@ -669,29 +711,25 @@ def provision(lp, setup_dir, message, blank, paths, session_info, aci = "# no aci for local ldb" if serverrole is None: serverrole = lp.get("server role") + if invocationid is None and serverrole == "domain controller": + invocationid = uuid.random() if realm is None: realm = lp.get("realm") - else: - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in smb.conf must match chosen realm '%s'\n" % + + if lp.get("realm").upper() != realm.upper(): + raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % (lp.get("realm"), realm)) + ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path) + + if ldap_backend == "ldapi": + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi")) + assert realm is not None realm = realm.upper() - if domain is None: - domain = lp.get("workgroup") - else: - if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), domain) - - assert domain is not None - domain = domain.upper() - if not valid_netbios_name(domain): - raise InvalidNetbiosName(domain) - if hostname is None: hostname = gethostname().split(".")[0].lower() @@ -703,13 +741,30 @@ def provision(lp, setup_dir, message, blank, paths, session_info, raise InvalidNetbiosName(netbiosname) dnsdomain = realm.lower() - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") - rootdn = domaindn + if serverrole == "domain controller": + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + if domain is None: + domain = lp.get("workgroup") + + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", + lp.get("workgroup"), domain) + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + else: + domaindn = "CN=" + netbiosname + domain = netbiosname + + if rootdn is None: + rootdn = domaindn + configdn = "CN=Configuration," + rootdn schemadn = "CN=Schema," + configdn - rdn_dc = domaindn.split(",")[0][len("DC="):] - message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) @@ -725,7 +780,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, smbconfsuffix = "member" else: assert "Invalid server role setting: %s" % serverrole - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + paths.smbconf, { "HOSTNAME": hostname, "DOMAIN_CONF": domain, "REALM_CONF": realm, @@ -742,6 +798,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, credentials=credentials, lp=lp) share_ldb.load_ldif_file_add(setup_path("share.ldif")) + message("Setting up secrets.ldb") secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info=session_info, @@ -755,44 +812,47 @@ def provision(lp, setup_dir, message, blank, paths, session_info, setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) - samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, - lp=lp, schemadn=schemadn, configdn=configdn, domaindn=domaindn, - dnsdomain=dnsdomain, netbiosname=netbiosname, realm=realm, message=message, - hostname=hostname, rootdn=rootdn, erase=erase, domainsid=domainsid, aci=aci, - rdn_dc=rdn_dc, domainguid=domainguid, policyguid=policyguid, - domainname=domain, blank=blank, adminpass=adminpass, krbtgtpass=krbtgtpass, - hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, - dnspass=dnspass) + samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, + credentials=credentials, lp=lp, schemadn=schemadn, + configdn=configdn, domaindn=domaindn, + dnsdomain=dnsdomain, netbiosname=netbiosname, + realm=realm, message=message, hostname=hostname, + rootdn=rootdn, erase=erase, domainsid=domainsid, + aci=aci, domainguid=domainguid, policyguid=policyguid, + domainname=domain, fill=samdb_fill, + adminpass=adminpass, krbtgtpass=krbtgtpass, + hostguid=hostguid, invocationid=invocationid, + machinepass=machinepass, dnspass=dnspass, + serverrole=serverrole, ldap_backend=ldap_backend, + ldap_backend_type=ldap_backend_type) if lp.get("server role") == "domain controller": - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) - if not os.path.isdir(paths.netlogon): + policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", + "{" + policyguid + "}") + os.makedirs(policy_path, 0755) + os.makedirs(os.path.join(policy_path, "Machine"), 0755) + os.makedirs(os.path.join(policy_path, "User"), 0755) + if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { - "MACHINEPASS_B64": b64encode(machinepass), - "DOMAIN": domain, - "REALM": realm, - "LDAPTIME": timestring(int(time.time())), - "DNSDOMAIN": dnsdomain, - "DOMAINSID": str(domainsid), - "SECRETS_KEYTAB": paths.keytab, - "NETBIOSNAME": netbiosname, - "SAM_LDB": paths.samdb, - "DNS_KEYTAB": paths.dns_keytab, - "DNSPASS_B64": b64encode(dnspass), - }) - - if not blank: - setup_name_mappings(samdb, str(domainsid), - domaindn, root=root, nobody=nobody, - nogroup=nogroup, wheel=wheel, users=users, - backup=backup) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=realm, + netbiosname=netbiosname, domainsid=domainsid, + keytab_path=paths.keytab, samdb_url=paths.samdb, + dns_keytab_path=paths.dns_keytab, dnspass=dnspass, + machinepass=machinepass, dnsdomain=dnsdomain) + + if samdb_fill == FILL_FULL: + setup_name_mappings(samdb, str(domainsid), domaindn, root=root, + nobody=nobody, nogroup=nogroup, wheel=wheel, + users=users, backup=backup) + + message("Setting up sam.ldb rootDSE marking as synchronized") + setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) message("Setting up phpLDAPadmin configuration") - create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path) + create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, + ldapi_url) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) @@ -816,15 +876,15 @@ def provision(lp, setup_dir, message, blank, paths, session_info, return domaindn -def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): + +def create_phpldapadmin_config(path, setup_path, ldap_backend): """Create a PHP LDAP admin configuration file. :param path: Path to write the configuration to. :param setup_path: Function to generate setup paths. - :param s4_ldapi_path: Path to Samba 4 LDAPI socket. """ - setup_file(setup_path("phpldapadmin-config.php"), - path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) + setup_file(setup_path("phpldapadmin-config.php"), path, + {"S4_LDAPI_URI": ldap_backend}) def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, @@ -874,6 +934,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE": DEFAULTSITE}) + "DEFAULTSITE": DEFAULTSITE + }) samdb.attach_schema_from_ldif(head_data, schema_data) diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index e92a4bbb90..b757330ecb 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -1,10 +1,10 @@ #!/usr/bin/python # Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2007 +# Copyright (C) Jelmer Vernooij 2007-2008 # # Based on the original in EJS: -# Copyright (C) Andrew Tridgell 2005 +# Copyright (C) Andrew Tridgell 2005 # # 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 @@ -151,4 +151,4 @@ member: %s :param invocation_id: GUID of the invocation id. """ - misc.samdb_set_ntds_invocation_id(self, invocation_id) \ No newline at end of file + misc.dsdb_set_ntds_invocation_id(self, invocation_id) diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index 6fbf420339..9839811470 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -1,7 +1,7 @@ #!/usr/bin/python # Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2007 +# Copyright (C) Jelmer Vernooij 2007-2008 # # 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 diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index abf1127c36..a118af2526 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -7,7 +7,7 @@ """Support code for upgrading from Samba 3 to Samba 4.""" -from provision import findnss, provision +from provision import findnss, provision, FILL_DRS import grp import ldb import pwd @@ -245,7 +245,8 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, else: machinepass = None - domaindn = provision(lp=lp, setup_dir=setup_dir, message=message, blank=True, ldapbackend=None, + domaindn = provision(lp=lp, setup_dir=setup_dir, message=message, + samdb_fill=FILL_DRS, ldapbackend=None, paths=paths, session_info=session_info, credentials=credentials, realm=realm, domain=domainname, domainsid=domainsid, domainguid=domainguid, machinepass=machinepass, serverrole=serverrole) -- cgit From 76eb7ddd75719eb516a0dc10a88e23fd6463a718 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 01:30:43 +0100 Subject: python: fix tests for check_all_substituted. (This used to be commit 859cffed9d3a62f9f7610d74472aa3c0d1979a35) --- source4/scripting/python/samba/tests/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index 9839811470..e557dd95be 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -69,8 +69,8 @@ class SubstituteVarTestCase(unittest.TestCase): samba.substitute_var("foo ${bla} gsff", {"bar": "bla"})) def test_check_all_substituted(self): - check_all_substituted("nothing to see here") - self.assertRaises(Exception, check_all_substituted, "Not subsituted: ${FOOBAR}") + samba.check_all_substituted("nothing to see here") + self.assertRaises(Exception, samba.check_all_substituted, "Not subsituted: ${FOOBAR}") class LdbExtensionTests(TestCaseInTempDir): -- cgit From c91791bbc489d90eca5f6b8d6dc369d7e2129c29 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 01:37:47 +0100 Subject: python: Add test for secretsdb_become_dc (This used to be commit 9173c678efb6f74dbec64298bcb00952feff2ed7) --- source4/scripting/python/samba/tests/provision.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index f5a0339c1f..83952df9fe 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -1,7 +1,7 @@ #!/usr/bin/python # Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2007 +# Copyright (C) Jelmer Vernooij 2007-2008 # # 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 @@ -18,7 +18,7 @@ # import os -from samba.provision import setup_secretsdb +from samba.provision import setup_secretsdb, secretsdb_become_dc import samba.tests from ldb import Dn @@ -37,7 +37,22 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): finally: del ldb os.unlink(path) - + + def test_become_dc(self): + path = os.path.join(self.tempdir, "secrets.ldb") + secrets_ldb = setup_secretsdb(path, setup_path, None, None, None) + try: + secretsdb_become_dc(secrets_ldb, setup_path, domain="EXAMPLE", + realm="example", netbiosname="myhost", + domainsid="S-5-22", keytab_path="keytab.path", + samdb_url="ldap://url/", + dns_keytab_path="dns.keytab", dnspass="bla", + machinepass="machinepass", dnsdomain="example.com") + self.assertEquals(1, + len(secrets_ldb.search("samAccountName=krbtgt,flatname=EXAMPLE,CN=Principals"))) + finally: + del secrets_ldb + os.unlink(path) class Disabled: def test_setup_templatesdb(self): -- cgit From dcb04065cda7fc7f23c494ec138af6b882651f20 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 03:54:33 +0100 Subject: python: Fix representation of UUIDs as strings in zone files rather than binary blobs, fix escaping of LDAP URL's in PHP LDAP admin configuration. Pair-programmed with Andrew, but git doesn't appear to support multiple --author arguments. :-( (This used to be commit dff54ff043563f93b86361039c46e662045f62cc) --- source4/scripting/python/samba/__init__.py | 4 ++-- source4/scripting/python/samba/provision.py | 11 ++++++----- source4/scripting/python/samba/samdb.py | 2 +- source4/scripting/python/samba/tests/__init__.py | 2 +- source4/scripting/python/samba/tests/provision.py | 10 +++++++++- 5 files changed, 19 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 5c14edd357..b041165800 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -91,7 +91,7 @@ class Ldb(ldb.Ldb): set_session_info = misc.ldb_set_session_info set_loadparm = misc.ldb_set_loadparm - def searchone(self, basedn, attribute, expression=None, + def searchone(self, attribute, basedn=None, expression=None, scope=ldb.SCOPE_BASE): """Search for one attribute as a string. @@ -106,7 +106,7 @@ class Ldb(ldb.Ldb): return None values = set(res[0][attribute]) assert len(values) == 1 - return values.pop() + return self.schema_format_value(attribute, values.pop()) def erase(self): """Erase this ldb, removing all records.""" diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 918d983782..0e498f65e5 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -725,7 +725,7 @@ def provision(lp, setup_dir, message, paths, session_info, if ldap_backend == "ldapi": # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi")) + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), "") assert realm is not None realm = realm.upper() @@ -860,9 +860,9 @@ def provision(lp, setup_dir, message, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - domainguid = samdb.searchone(domaindn, "objectGUID") + domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") assert isinstance(domainguid, str) - hostguid = samdb.searchone(domaindn, "objectGUID", + hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", expression="(&(objectClass=computer)(cn=%s))" % hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) @@ -877,14 +877,14 @@ def provision(lp, setup_dir, message, paths, session_info, return domaindn -def create_phpldapadmin_config(path, setup_path, ldap_backend): +def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. :param path: Path to write the configuration to. :param setup_path: Function to generate setup paths. """ setup_file(setup_path("phpldapadmin-config.php"), path, - {"S4_LDAPI_URI": ldap_backend}) + {"S4_LDAPI_URI": ldapi_uri}) def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, @@ -903,6 +903,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, :param domainguid: GUID of the domain. :param hostguid: GUID of the host. """ + assert isinstance(domainguid, str) setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index b757330ecb..c11fabf553 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -105,7 +105,7 @@ userAccountControl: %u assert(len(res) == 1 and res[0].defaultNamingContext is not None) domain_dn = res[0]["defaultNamingContext"][0] assert(domain_dn is not None) - dom_users = self.searchone(domain_dn, "dn", "name=Domain Users") + dom_users = self.searchone(basedn=domain_dn, attribute="dn", expression="name=Domain Users") assert(dom_users is not None) user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index e557dd95be..9402002674 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -79,7 +79,7 @@ class LdbExtensionTests(TestCaseInTempDir): l = samba.Ldb(path) try: l.add({"dn": "foo=dc", "bar": "bla"}) - self.assertEquals("bla", l.searchone(ldb.Dn(l, "foo=dc"), "bar")) + self.assertEquals("bla", l.searchone(basedn=ldb.Dn(l, "foo=dc"), attribute="bar")) finally: del l os.unlink(path) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 83952df9fe..1456b6751c 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -33,7 +33,7 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): ldb = setup_secretsdb(path, setup_path, None, None, None) try: self.assertEquals("LSA Secrets", - ldb.searchone(Dn(ldb, "CN=LSA Secrets"), "CN")) + ldb.searchone(basedn="CN=LSA Secrets", attribute="CN")) finally: del ldb os.unlink(path) @@ -50,6 +50,14 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): machinepass="machinepass", dnsdomain="example.com") self.assertEquals(1, len(secrets_ldb.search("samAccountName=krbtgt,flatname=EXAMPLE,CN=Principals"))) + self.assertEquals("keytab.path", + secrets_ldb.searchone(basedn="flatname=EXAMPLE,CN=primary domains", + expression="(privateKeytab=*)", + attribute="privateKeytab")) + self.assertEquals("S-5-22", + secrets_ldb.searchone(basedn="flatname=EXAMPLE,CN=primary domains", + expression="objectSid=*", attribute="objectSid")) + finally: del secrets_ldb os.unlink(path) -- cgit From 1b18de131c556280004dea6393e22547c9681fd9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jan 2008 17:11:20 +1100 Subject: Tidy up the last regresesions on the python smbscript, from my work with Jelmer today. The only remaining issue is that for the build farm, we will need to manually specify the users and groups from the NSS_WRAPPPER, as python isn't compiled with this. Andrew Bartlett (This used to be commit 5370484d25b8c7a5bde730d9be36ecbbb0aaf315) --- source4/scripting/python/samba/provision.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0e498f65e5..26c4afe3c8 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -188,12 +188,17 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths = ProvisionPaths() if private_dir is None: private_dir = lp.get("private dir") + paths.keytab = "secrets.keytab" + paths.dns_keytab = "dns.keytab" + else: + paths.keytab = os.path.join(private_dir, "secrets.keytab") + paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") - paths.keytab = os.path.join(private_dir, "secrets.keytab") - paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") @@ -407,6 +412,8 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) return secrets_ldb @@ -695,18 +702,18 @@ def provision(lp, setup_dir, message, paths, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, "root")[4] + root = findnss(pwd.getpwnam, "root")[0] if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[4] + nobody = findnss(pwd.getpwnam, "nobody")[0] if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[0] if users is None: users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", - "usr")[2] + "usr")[0] if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[0] if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[0] if aci is None: aci = "# no aci for local ldb" if serverrole is None: @@ -721,11 +728,11 @@ def provision(lp, setup_dir, message, paths, session_info, raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % (lp.get("realm"), realm)) - ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path) + ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") if ldap_backend == "ldapi": # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), "") + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") assert realm is not None realm = realm.upper() -- cgit From 6c2d4f2806bae8072d61ba8795832d9a9e75573e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 11:47:44 +0100 Subject: python/provision: Reload secrets when necessary, fix unix names in mappings. Pair programmed with Andrew. (This used to be commit 04fe8c8aefae8da8966954d0654c37adf2d0361d) --- source4/scripting/python/samba/provision.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0e498f65e5..4d99cd9cd9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -193,7 +193,7 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") - paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + paths.dns_keytab = "dns.keytab" paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") @@ -407,6 +407,8 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) return secrets_ldb @@ -695,18 +697,18 @@ def provision(lp, setup_dir, message, paths, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, "root")[4] + root = findnss(pwd.getpwnam, "root")[0] if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[4] + nobody = findnss(pwd.getpwnam, "nobody")[0] if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[0] if users is None: users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", - "usr")[2] + "usr")[0] if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[0] if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[0] if aci is None: aci = "# no aci for local ldb" if serverrole is None: -- cgit From 21f5f4d4409e5a7076194639570f11ec32cf3257 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 12:16:13 +0100 Subject: python: Give precedence to Samba's syspath over the already set system one. (This used to be commit f3ebaf0a0c0b881da28063c69bb6306f6aa1c774) --- source4/scripting/python/modules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index fff981e941..2ecad20b8e 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -62,7 +62,7 @@ void py_load_samba_modules(void) void py_update_path(const char *bindir) { char *newpath; - asprintf(&newpath, "%s:%s/python:%s/../scripting/python", Py_GetPath(), bindir, bindir); + asprintf(&newpath, "%s/python:%s/../scripting/python:%s", bindir, bindir, Py_GetPath()); PySys_SetPath(newpath); free(newpath); } -- cgit From e41a6329029130f7209671c29fd219525d9012f8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jan 2008 15:40:55 +0100 Subject: configure: define HAVE_WORKING_PYTHON metze (This used to be commit 351c2e99ab8b6a91f7355077b2d2944fd820839c) --- source4/scripting/python/config.m4 | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 4f46f92682..3acd7321c7 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -66,6 +66,7 @@ if test $working_python = yes; then SMB_ENABLE(EXT_LIB_PYTHON,YES) SMB_ENABLE(smbpython,YES) SMB_ENABLE(LIBPYTHON,YES) + AC_DEFINE(HAVE_WORKING_PYTHON, 1, [Whether we have working python support]) AC_MSG_RESULT([yes]) else SMB_ENABLE(EXT_LIB_PYTHON,NO) -- cgit From 172e00d8a174646e4e1279e66805c24eeac00c40 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 26 Jan 2008 02:55:03 +0100 Subject: python: Load smb.conf file for the provision tests. (This used to be commit 41571bbb933c763a9608f4ba56f1a5a97af133ab) --- source4/scripting/python/samba/tests/provision.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 1456b6751c..4e9fa9c3ef 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -21,6 +21,10 @@ import os from samba.provision import setup_secretsdb, secretsdb_become_dc import samba.tests from ldb import Dn +import param + +lp = param.LoadParm() +lp.load("st/dc/etc/smb.conf") setup_dir = "setup" def setup_path(file): @@ -30,7 +34,7 @@ def setup_path(file): class ProvisionTestCase(samba.tests.TestCaseInTempDir): def test_setup_secretsdb(self): path = os.path.join(self.tempdir, "secrets.ldb") - ldb = setup_secretsdb(path, setup_path, None, None, None) + ldb = setup_secretsdb(path, setup_path, None, None, lp=lp) try: self.assertEquals("LSA Secrets", ldb.searchone(basedn="CN=LSA Secrets", attribute="CN")) @@ -40,7 +44,7 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): def test_become_dc(self): path = os.path.join(self.tempdir, "secrets.ldb") - secrets_ldb = setup_secretsdb(path, setup_path, None, None, None) + secrets_ldb = setup_secretsdb(path, setup_path, None, None, lp=lp) try: secretsdb_become_dc(secrets_ldb, setup_path, domain="EXAMPLE", realm="example", netbiosname="myhost", -- cgit From cab677a33f0376cd1bf96ec561dc0463bbf80edd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 26 Jan 2008 04:22:42 +0100 Subject: python: Use relative paths for registry. (This used to be commit 079200b824de6dd8c7de3e5b76ed1805fde02965) --- source4/scripting/python/samba/provision.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f244679eb5..d2a4f28b64 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -203,7 +203,13 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") - paths.hklm = os.path.join(private_dir, "hklm.ldb") + paths.hklm = "hklm.ldb" + paths.hkcr = "hkcr.ldb" + paths.hkcu = "hkcu.ldb" + paths.hku = "hku.ldb" + paths.hkpd = "hkpd.ldb" + paths.hkpt = "hkpt.ldb" + paths.sysvol = lp.get("sysvol", "path") if paths.sysvol is None: paths.sysvol = os.path.join(lp.get("lock dir"), "sysvol") @@ -442,6 +448,7 @@ def setup_registry(path, setup_path, session_info, credentials, lp): :param lp: Loadparm context """ reg = registry.Registry() + print path hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") -- cgit From bcad73a7f7f63b33c02df5a62c7986f2c7dc11ff Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 29 Jan 2008 13:10:43 +0100 Subject: Partially revert d64a2288a2cb3a8f74a18b740b265a460773635d and 351c2e99ab8b6a91f7355077b2d2944fd820839c to see if that fixes the build. (This used to be commit 2a79cebfd99f4048214be65a6c918cc988dc83ed) --- source4/scripting/python/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 3acd7321c7..e4a34ece1e 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -66,7 +66,7 @@ if test $working_python = yes; then SMB_ENABLE(EXT_LIB_PYTHON,YES) SMB_ENABLE(smbpython,YES) SMB_ENABLE(LIBPYTHON,YES) - AC_DEFINE(HAVE_WORKING_PYTHON, 1, [Whether we have working python support]) + dnl AC_DEFINE(HAVE_WORKING_PYTHON, 1, [Whether we have working python support]) AC_MSG_RESULT([yes]) else SMB_ENABLE(EXT_LIB_PYTHON,NO) -- cgit From 61379d97cd3f4f21cc55d3cf3539e0adfa274b7f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 29 Jan 2008 14:27:27 +0100 Subject: python: Provide PyAPI_DATA macro for older versions of Python (< 2.3). (This used to be commit 421bdd203eab09e560f4919715fa4cc4497e406f) --- source4/scripting/python/pyrpc.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h index 5390c6923d..3a5d235cfc 100644 --- a/source4/scripting/python/pyrpc.h +++ b/source4/scripting/python/pyrpc.h @@ -27,3 +27,8 @@ #define dom_sid28_Type dom_sid_Type #define dom_sid2_Check dom_sid_Check #define dom_sid28_Check dom_sid28_Check + +/* This macro is only provided by Python >= 2.3 */ +#ifndef PyAPI_DATA +# define PyAPI_DATA(RTYPE) extern RTYPE +#endif -- cgit From fffe4f3bdd27b11dce75c9b2c931f5291f04ab6b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 8 Feb 2008 03:03:44 +0100 Subject: Fix formatting. (This used to be commit 73d1b0fcb64fdc7be1e1e1002f3f182fcbe476ae) --- source4/scripting/python/samba/provision.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d2a4f28b64..bcadcca583 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -319,14 +319,14 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, domaindn_ldb = "users.ldb" if ldap_backend is not None: - domaindn_ldb = ldap_backend + domaindn_ldb = ldap_backend configdn_ldb = "configuration.ldb" if ldap_backend is not None: - configdn_ldb = ldap_backend + configdn_ldb = ldap_backend schema_ldb = "schema.ldb" if ldap_backend is not None: - schema_ldb = ldap_backend - + schema_ldb = ldap_backend + if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid","paged_searches"] elif ldap_backend_type == "openldap": @@ -737,8 +737,8 @@ def provision(lp, setup_dir, message, paths, session_info, ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") if ldap_backend == "ldapi": - # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") assert realm is not None realm = realm.upper() @@ -755,7 +755,7 @@ def provision(lp, setup_dir, message, paths, session_info, dnsdomain = realm.lower() if serverrole == "domain controller": - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if domain is None: domain = lp.get("workgroup") @@ -769,9 +769,9 @@ def provision(lp, setup_dir, message, paths, session_info, raise InvalidNetbiosName(domain) else: - domaindn = "CN=" + netbiosname - domain = netbiosname - + domaindn = "CN=" + netbiosname + domain = netbiosname + if rootdn is None: rootdn = domaindn -- cgit From 26897518ea88e6c70eda4031e62c02fcbcdb0fc0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 8 Feb 2008 17:11:26 +1100 Subject: Fix LDAP backend with python We were still setting the hard-coded users.ldb etc, rather than switching to the ldapi:// URI Andrew Bartlett (This used to be commit 603e981250b26b533ec35dd607cb635226cf99df) --- source4/scripting/python/samba/provision.py | 44 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d2a4f28b64..9a44983d8e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -323,9 +323,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, configdn_ldb = "configuration.ldb" if ldap_backend is not None: configdn_ldb = ldap_backend - schema_ldb = "schema.ldb" + schemadn_ldb = "schema.ldb" if ldap_backend is not None: - schema_ldb = ldap_backend + schemadn_ldb = ldap_backend if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid","paged_searches"] @@ -336,23 +336,31 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, else: backend_modules = ["objectguid"] - setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { - "SCHEMADN": schemadn, - "SCHEMADN_LDB": "schema.ldb", - "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": configdn, - "CONFIGDN_LDB": "configuration.ldb", - "DOMAINDN": domaindn, - "DOMAINDN_LDB": "users.ldb", - "SCHEMADN_MOD": "schema_fsmo,instancetype", - "CONFIGDN_MOD": "naming_fsmo,instancetype", - "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", - "MODULES_LIST": ",".join(modules_list), - "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), - "MODULES_LIST2": ",".join(modules_list2), - "BACKEND_MOD": ",".join(backend_modules), + samdb.transaction_start() + try: + setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { + "SCHEMADN": schemadn, + "SCHEMADN_LDB": schemadn_ldb, + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": configdn, + "CONFIGDN_LDB": configdn_ldb, + "DOMAINDN": domaindn, + "DOMAINDN_LDB": domaindn_ldb, + "SCHEMADN_MOD": "schema_fsmo,instancetype", + "CONFIGDN_MOD": "naming_fsmo,instancetype", + "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", + "MODULES_LIST": ",".join(modules_list), + "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "MODULES_LIST2": ",".join(modules_list2), + "BACKEND_MOD": ",".join(backend_modules), }) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) @@ -680,7 +688,7 @@ FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" def provision(lp, setup_dir, message, paths, session_info, - credentials, ldapbackend, samdb_fill=FILL_FULL, realm=None, rootdn=None, + credentials, samdb_fill=FILL_FULL, realm=None, rootdn=None, domain=None, hostname=None, hostip=None, domainsid=None, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, -- cgit From c1c09e584e134a9b9ccf0fcb6517a87619c3a5ed Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 8 Feb 2008 17:12:25 +1100 Subject: LDAP now works with the python provision! Andrew Bartlett (This used to be commit 8f0a89ca19d6a3986dacd981fab1ebbc8b1a4ad0) --- source4/scripting/python/STATUS | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/STATUS b/source4/scripting/python/STATUS index 6e6475bfde..ee67b8bc7a 100644 --- a/source4/scripting/python/STATUS +++ b/source4/scripting/python/STATUS @@ -1,6 +1,5 @@ dsdb/samdb/ldb_modules/tests/samba3sam.py: Fix remaining failing tests lib/ldb/tests/python/ldap.py: Fix remaining 3 FIXME's -provisioning in LDAP mode(TEST_LDAP=yes PROVISION_PYTHON=yes make test) command-line vampire provisioning: combine some of the python dictionaries finish scripting/bin/smbstatus.py -- cgit From c1d8ac0ab1226c27a46fcbb0101c2921d63de599 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 01:42:38 +0100 Subject: Remove unused class members. (This used to be commit 373ef4287f998b79bf9ba6364d6a67e5c522833d) --- source4/scripting/python/samba/provision.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0c16ab3bfe..e15f205813 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -64,9 +64,6 @@ class ProvisionPaths: self.dns_keytab = None self.dns = None self.winsdb = None - self.ldap_basedn_ldif = None - self.ldap_config_basedn_ldif = None - self.ldap_schema_basedn_ldif = None def check_install(lp, session_info, credentials): @@ -201,6 +198,7 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") + paths.smbconf = os.path.join(private_dir, "smb.conf") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") paths.hklm = "hklm.ldb" @@ -812,7 +810,7 @@ def provision(lp, setup_dir, message, paths, session_info, "NETLOGONPATH": paths.netlogon, "SYSVOLPATH": paths.sysvol, }) - lp.reload() + lp.load(paths.smbconf) # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): -- cgit From 2aac2a5df8a03a42ed92e84f093b8aa5ba16dd1d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 02:10:49 +0100 Subject: Add tests for findnss(), add some docstrings. (This used to be commit 4eec2bbc9a139e927ce21c615ebfbb3026b26384) --- source4/scripting/python/samba/provision.py | 39 +++++++++++++++-------- source4/scripting/python/samba/tests/provision.py | 23 ++++++++++++- 2 files changed, 48 insertions(+), 14 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e15f205813..b094581fb4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -81,14 +81,19 @@ def check_install(lp, session_info, credentials): raise "No administrator account found" -def findnss(nssfn, *names): - """Find a user or group from a list of possibilities.""" +def findnss(nssfn, names): + """Find a user or group from a list of possibilities. + + :param nssfn: NSS Function to try (should raise KeyError if not found) + :param names: Names to check. + :return: Value return by first names list. + """ for name in names: try: return nssfn(name) except KeyError: pass - raise Exception("Unable to find user/group for %s" % arguments[1]) + raise KeyError("Unable to find user/group %r" % names) def open_ldb(session_info, credentials, lp, dbname): @@ -146,6 +151,14 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None): def setup_ldb(ldb, ldif_path, subst_vars): + """Import a LDIF a file into a LDB handle, optionally substituting variables. + + :note: Either all LDIF data will be added or none (using transactions). + + :param ldb: LDB file to import into. + :param ldif_path: Path to the LDIF file. + :param subst_vars: Dictionary with substitution variables. + """ assert ldb is not None ldb.transaction_start() try: @@ -716,18 +729,18 @@ def provision(lp, setup_dir, message, paths, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, "root")[0] + root = findnss(pwd.getpwnam, ["root"])[0] if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[0] + nobody = findnss(pwd.getpwnam, ["nobody"])[0] if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[0] + nogroup = findnss(grp.getgrnam, ["nogroup", "nobody"])[0] if users is None: - users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", - "usr")[0] + users = findnss(grp.getgrnam, ["users", "guest", "other", "unknown", + "usr"])[0] if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[0] + wheel = findnss(grp.getgrnam, ["wheel", "root", "staff", "adm"])[0] if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[0] + backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] if aci is None: aci = "# no aci for local ldb" if serverrole is None: @@ -781,10 +794,10 @@ def provision(lp, setup_dir, message, paths, session_info, domain = netbiosname if rootdn is None: - rootdn = domaindn + rootdn = domaindn - configdn = "CN=Configuration," + rootdn - schemadn = "CN=Schema," + configdn + configdn = "CN=Configuration," + rootdn + schemadn = "CN=Schema," + configdn message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 4e9fa9c3ef..eb49f7af83 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -18,10 +18,11 @@ # import os -from samba.provision import setup_secretsdb, secretsdb_become_dc +from samba.provision import setup_secretsdb, secretsdb_become_dc, findnss import samba.tests from ldb import Dn import param +import unittest lp = param.LoadParm() lp.load("st/dc/etc/smb.conf") @@ -66,6 +67,25 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): del secrets_ldb os.unlink(path) + +class FindNssTests(unittest.TestCase): + """Test findnss() function.""" + def test_nothing(self): + def x(y): + raise KeyError + self.assertRaises(KeyError, findnss, x, []) + + def test_first(self): + self.assertEquals("bla", findnss(lambda x: "bla", ["bla"])) + + def test_skip_first(self): + def x(y): + if y != "bla": + raise KeyError + return "ha" + self.assertEquals("ha", findnss(x, ["bloe", "bla"])) + + class Disabled: def test_setup_templatesdb(self): raise NotImplementedError(self.test_setup_templatesdb) @@ -100,3 +120,4 @@ class Disabled: def test_erase_partitions(self): raise NotImplementedError(self.test_erase_partitions) + -- cgit From bd0bfe683386f983318b507c5a614f818cdfb38d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 03:09:56 +0100 Subject: Fix provision python test. (This used to be commit b173fa6bd2b24b5a3e7b4fbcb926f6c9771c10ba) --- source4/scripting/python/samba/provision.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b094581fb4..7dd564fae1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -189,20 +189,16 @@ def setup_file(template, fname, substvars): open(f, 'w').write(data) -def provision_paths_from_lp(lp, dnsdomain, private_dir=None): +def provision_paths_from_lp(lp, dnsdomain): """Set the default paths for provisioning. :param lp: Loadparm context. :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() - if private_dir is None: - private_dir = lp.get("private dir") - paths.keytab = "secrets.keytab" - paths.dns_keytab = "dns.keytab" - else: - paths.keytab = os.path.join(private_dir, "secrets.keytab") - paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + private_dir = lp.get("private dir") + paths.keytab = "secrets.keytab" + paths.dns_keytab = "dns.keytab" paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") @@ -469,7 +465,6 @@ def setup_registry(path, setup_path, session_info, credentials, lp): :param lp: Loadparm context """ reg = registry.Registry() - print path hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") @@ -540,6 +535,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, serverrole, ldap_backend=None, ldap_backend_type=None): """Setup a complete SAM Database. + :note: This will wipe the main SAM database file! """ # Also wipes the database @@ -745,6 +741,7 @@ def provision(lp, setup_dir, message, paths, session_info, aci = "# no aci for local ldb" if serverrole is None: serverrole = lp.get("server role") + assert serverrole in ("domain controller", "member server") if invocationid is None and serverrole == "domain controller": invocationid = uuid.random() @@ -774,9 +771,9 @@ def provision(lp, setup_dir, message, paths, session_info, if not valid_netbios_name(netbiosname): raise InvalidNetbiosName(netbiosname) - dnsdomain = realm.lower() + dnsdomain = realm.lower() if serverrole == "domain controller": - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if domain is None: domain = lp.get("workgroup") @@ -788,7 +785,6 @@ def provision(lp, setup_dir, message, paths, session_info, domain = domain.upper() if not valid_netbios_name(domain): raise InvalidNetbiosName(domain) - else: domaindn = "CN=" + netbiosname domain = netbiosname @@ -812,8 +808,6 @@ def provision(lp, setup_dir, message, paths, session_info, smbconfsuffix = "dc" elif serverrole == "member": smbconfsuffix = "member" - else: - assert "Invalid server role setting: %s" % serverrole setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { "HOSTNAME": hostname, @@ -953,7 +947,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): - """Load schema. + """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. :param setup_path: Setup path function. -- cgit From 4932e4bb7ad11c6ef8ad3187063dba4e7481afa7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 03:59:45 +0100 Subject: Fix upgrade after provision parameter rename. (This used to be commit 361b9f43fb2abb64f2cbae7740b89a616a3c2646) --- source4/scripting/python/samba/upgrade.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index a118af2526..b332bb89ae 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -246,8 +246,8 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, machinepass = None domaindn = provision(lp=lp, setup_dir=setup_dir, message=message, - samdb_fill=FILL_DRS, ldapbackend=None, - paths=paths, session_info=session_info, credentials=credentials, realm=realm, + samdb_fill=FILL_DRS, paths=paths, session_info=session_info, + credentials=credentials, realm=realm, domain=domainname, domainsid=domainsid, domainguid=domainguid, machinepass=machinepass, serverrole=serverrole) -- cgit From c61dc3849434347ca8a77f917ca6241bf4ee3174 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 15:42:19 +0100 Subject: Re-enable python support in BECOME-DC test. (This used to be commit ed44fd59bfa289bcef82e0650ccda381efb52268) --- source4/scripting/python/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index e4a34ece1e..3acd7321c7 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -66,7 +66,7 @@ if test $working_python = yes; then SMB_ENABLE(EXT_LIB_PYTHON,YES) SMB_ENABLE(smbpython,YES) SMB_ENABLE(LIBPYTHON,YES) - dnl AC_DEFINE(HAVE_WORKING_PYTHON, 1, [Whether we have working python support]) + AC_DEFINE(HAVE_WORKING_PYTHON, 1, [Whether we have working python support]) AC_MSG_RESULT([yes]) else SMB_ENABLE(EXT_LIB_PYTHON,NO) -- cgit From 2fa4c158580a1e3efea7f8d121305d16eda815cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 17:37:42 +0100 Subject: Fix syntax of docstrings, set project name when generating Python API documentation. (This used to be commit 68f13d87eb034fdbc712169f2d1b1a0475751ec5) --- source4/scripting/python/config.mk | 2 +- source4/scripting/python/samba/provision.py | 6 ++---- source4/scripting/python/samba/upgrade.py | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 450da0e90a..b15e1fcda7 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -33,7 +33,7 @@ pythonmods:: $(PYTHON_DSOS) $(PYTHON_PYS) PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py pydoctor:: pythonmods - LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) + LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --project-name=Samba --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) installpython:: pythonmods @$(SHELL) $(srcdir)/script/installpython.sh \ diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 7dd564fae1..4f52d36167 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -278,13 +278,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, Alternatively, provision() may call this, and then populate the database. :param erase: Remove the existing data present in the database. - :param :note: This will wipe the Sam Database! :note: This function always removes the local SAM LDB file. The erase - parameter controls whether to erase the existing data, which - may not be stored locally but in LDAP. + parameter controls whether to erase the existing data, which + may not be stored locally but in LDAP. """ assert session_info is not None @@ -479,7 +478,6 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, :param samdb: Sam Database handle :param setup_path: Obtain setup path - ... """ setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { "SCHEMADN": schemadn, diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index b332bb89ae..8bf75d776e 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -10,6 +10,7 @@ from provision import findnss, provision, FILL_DRS import grp import ldb +import time import pwd import uuid import registry @@ -162,7 +163,6 @@ def import_wins(samba4_winsdb, samba3_winsdb): :param samba3_winsdb: WINS database to import from """ version_id = 0 - import time for (name, (ttl, ips, nb_flags)) in samba3_winsdb.items(): version_id+=1 -- cgit From cf287aa831a538c9f6c95882cee382fa836756d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 17:42:31 +0100 Subject: Add docstring. (This used to be commit 073ed0dd1cc8fae9eb4a2f7ff6763124917c56e8) --- source4/scripting/python/samba/tests/provision.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index eb49f7af83..54a7782b3d 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -33,6 +33,8 @@ def setup_path(file): class ProvisionTestCase(samba.tests.TestCaseInTempDir): + """Some simple tests for individual functions in the provisioning code. + """ def test_setup_secretsdb(self): path = os.path.join(self.tempdir, "secrets.ldb") ldb = setup_secretsdb(path, setup_path, None, None, lp=lp) -- cgit From 63aa4b902144873243e37eb7d7ce91d30b886abc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 20:47:12 +0100 Subject: Remove unused define. (This used to be commit 64d6d729135e1b3b19c9bdbbe973fcdaca15e8b3) --- source4/scripting/python/config.m4 | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 1f03ec8e34..908efd1588 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -66,7 +66,6 @@ if test $working_python = yes; then SMB_ENABLE(EXT_LIB_PYTHON,YES) SMB_ENABLE(smbpython,YES) SMB_ENABLE(LIBPYTHON,YES) - AC_DEFINE(HAVE_WORKING_PYTHON, 1, [Whether we have working python support]) AC_MSG_RESULT([yes]) else AC_MSG_ERROR([Python not found. Please install Python 2.x and its development headers/libraries.]) -- cgit From 2cf29aebff0dc821487e60ce86c18c6bbf1be866 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 22:29:42 +0100 Subject: Add tests for upgrade of WINS database. (This used to be commit 7777611c0f32a693f0fa057c130e4ea491658f6b) --- source4/scripting/python/samba/tests/upgrade.py | 19 +++++++++++++++++-- source4/scripting/python/samba/upgrade.py | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/upgrade.py b/source4/scripting/python/samba/tests/upgrade.py index ddafa00691..4dc86ace8a 100644 --- a/source4/scripting/python/samba/tests/upgrade.py +++ b/source4/scripting/python/samba/tests/upgrade.py @@ -17,6 +17,21 @@ # along with this program. If not, see . # -import samba.upgrade -from unittest import TestCase +from samba import Ldb +from samba.upgrade import import_wins +from samba.tests import LdbTestCase +class WinsUpgradeTests(LdbTestCase): + def test_upgrade(self): + winsdb = { + "FOO#20": (200, ["127.0.0.1", "127.0.0.2"], 0x60) + } + import_wins(self.ldb, winsdb) + + self.assertEquals(['name=FOO,type=0x20'], + [str(m.dn) for m in self.ldb.search(expression="(objectClass=winsRecord)")]) + + def test_version(self): + import_wins(self.ldb, {}) + self.assertEquals("VERSION", + self.ldb.search(expression="(objectClass=winsMaxVersion)")[0]["cn"]) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 8bf75d776e..01b62ff984 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -18,6 +18,7 @@ from samba import Ldb from samba.samdb import SamDB def import_sam_policy(samldb, samba3_policy, domaindn): + """Import a Samba 3 policy database.""" samldb.modify_ldif(""" dn: %s changetype: modify @@ -201,7 +202,8 @@ def import_wins(samba4_winsdb, samba3_winsdb): "versionID": str(version_id), "address": ips}) - samba4_winsdb.add({"dn": "CN=VERSION", + samba4_winsdb.add({"dn": "cn=VERSION", + "cn": "VERSION", "objectClass": "winsMaxVersion", "maxVersion": str(version_id)}) -- cgit From af007e5837ac472f0527505c8013b837932136bc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 11 Feb 2008 13:20:24 +0100 Subject: Use SMB_CONF_PATH environment variable inside tests rather than hardcoded paths. (This used to be commit eb04de69c0e319e18b148191946808f81e1cc8c4) --- source4/scripting/python/samba/tests/__init__.py | 6 ++++++ source4/scripting/python/samba/tests/dcerpc/registry.py | 4 ++-- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 5 ++--- source4/scripting/python/samba/tests/dcerpc/sam.py | 3 ++- source4/scripting/python/samba/tests/provision.py | 3 +-- 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index 9402002674..c8673d3fae 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -84,3 +84,9 @@ class LdbExtensionTests(TestCaseInTempDir): del l os.unlink(path) + +def get_loadparm(): + import param + lp = param.LoadParm() + lp.load(os.getenv("SMB_CONF_PATH")) + return lp diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index f3f0b0fb1a..147acc5098 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -20,11 +20,11 @@ import winreg from param import LoadParm import unittest +from samba.tests import get_loadparm class WinregTests(unittest.TestCase): def setUp(self): - lp_ctx = LoadParm() - lp_ctx.load("st/client/client.conf") + lp_ctx = get_loadparm() self.conn = winreg.winreg("ncalrpc:", lp_ctx) def get_hklm(self): diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 52c2bb8c72..8c1a8bec71 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -18,13 +18,12 @@ # import echo -from param import LoadParm import unittest +from samba.tests import get_loadparm class RpcEchoTests(unittest.TestCase): def setUp(self): - lp_ctx = LoadParm() - lp_ctx.load("st/client/client.conf") + lp_ctx = get_loadparm() self.conn = echo.rpcecho("ncalrpc:", lp_ctx) def test_addone(self): diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index 50caaf2348..96348f2f69 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -19,10 +19,11 @@ import samr import unittest +from samba.tests import get_loadparm class SamrTests(unittest.TestCase): def setUp(self): - self.conn = samr.samr("ncalrpc:", "st/client/client.conf") + self.conn = samr.samr("ncalrpc:", get_loadparm()) def test_connect5(self): (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 54a7782b3d..514582cbe4 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -24,8 +24,7 @@ from ldb import Dn import param import unittest -lp = param.LoadParm() -lp.load("st/dc/etc/smb.conf") +lp = samba.tests.get_loadparm() setup_dir = "setup" def setup_path(file): -- cgit From fdd75e135a8cb43f946af99120566f744df2a8e0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 12 Feb 2008 21:59:23 +0100 Subject: Correctly increment counters in Subunit test runner. (This used to be commit c474a2bb83a3e28a0b83f3b8ca1b646742dfca3d) --- source4/scripting/python/subunit/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py index 4d3434a3ea..7fcb815937 100644 --- a/source4/scripting/python/subunit/__init__.py +++ b/source4/scripting/python/subunit/__init__.py @@ -218,6 +218,7 @@ class TestProtocolClient(unittest.TestResult): for line in self._exc_info_to_string(error, test).splitlines(): self._stream.write("%s\n" % line) self._stream.write("]\n") + super(TestProtocolClient, self).addError(test, error) def addFailure(self, test, error): """Report a failure in test test.""" @@ -225,14 +226,17 @@ class TestProtocolClient(unittest.TestResult): for line in self._exc_info_to_string(error, test).splitlines(): self._stream.write("%s\n" % line) self._stream.write("]\n") + super(TestProtocolClient, self).addFailure(test, error) def addSuccess(self, test): """Report a success in a test.""" self._stream.write("successful: %s\n" % (test.shortDescription() or str(test))) + super(TestProtocolClient, self).addSuccess(test) def startTest(self, test): """Mark a test as starting its test run.""" self._stream.write("test: %s\n" % (test.shortDescription() or str(test))) + super(TestProtocolClient, self).startTest(test) def RemoteError(description=""): @@ -379,6 +383,5 @@ class SubunitTestRunner: def run(self, test): "Run the given test case or test suite." result = TestProtocolClient(self.stream) - test(result) return result -- cgit From 04aef38453ff977bf260546545e968fce3ddd599 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 12 Feb 2008 22:10:25 +0100 Subject: Fix subunit runner exit codes. (This used to be commit 7911308dbc1233838e44c533302f77b03ea41148) --- source4/scripting/python/subunit/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py index 7fcb815937..3abfbf522e 100644 --- a/source4/scripting/python/subunit/__init__.py +++ b/source4/scripting/python/subunit/__init__.py @@ -209,7 +209,7 @@ class TestProtocolClient(unittest.TestResult): """A class that looks like a TestResult and informs a TestProtocolServer.""" def __init__(self, stream): - unittest.TestResult.__init__(self) + super(TestProtocolClient, self).__init__() self._stream = stream def addError(self, test, error): @@ -383,5 +383,6 @@ class SubunitTestRunner: def run(self, test): "Run the given test case or test suite." result = TestProtocolClient(self.stream) + test(result) return result -- cgit From b4ce9dc3609aafd6df17bd3b57c0da63fdaba4b1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 13 Feb 2008 01:21:06 +0100 Subject: Fix invalid symbol. (This used to be commit bd0ef811c4e6419ba05076fbc151827cea5d1ca1) --- source4/scripting/python/samba/samdb.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index c11fabf553..3c6bb23c02 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -100,12 +100,14 @@ userAccountControl: %u self.transaction_start() # find the DNs for the domain and the domain users group - res = self.search("", SCOPE_BASE, "defaultNamingContext=*", - ["defaultNamingContext"]) + res = self.search("", scope=ldb.SCOPE_BASE, + expression="(defaultNamingContext=*)", + attrs=["defaultNamingContext"]) assert(len(res) == 1 and res[0].defaultNamingContext is not None) domain_dn = res[0]["defaultNamingContext"][0] assert(domain_dn is not None) - dom_users = self.searchone(basedn=domain_dn, attribute="dn", expression="name=Domain Users") + dom_users = self.searchone(basedn=domain_dn, attribute="dn", + expression="name=Domain Users") assert(dom_users is not None) user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) -- cgit From 08e3f99f14f178e87f3543261be59a7f97f60b4f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 13 Feb 2008 02:18:45 +0100 Subject: Initial work on a test for samba.tests.samdb (This used to be commit 8b33860954ca03be1ea45fd8d40963dbbd5b162f) --- source4/scripting/python/samba/provision.py | 3 +- source4/scripting/python/samba/tests/samdb.py | 55 +++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 source4/scripting/python/samba/tests/samdb.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f52d36167..97021fceb2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -332,7 +332,6 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, schemadn_ldb = "schema.ldb" if ldap_backend is not None: schema_ldb = ldap_backend - schemadn_ldb = ldap_backend if ldap_backend_type == "fedora-ds": @@ -536,6 +535,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, :note: This will wipe the main SAM database file! """ + assert serverrole in ("domain controller", "member server") + # Also wipes the database setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, domaindn=domaindn, message=message, lp=lp, diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py new file mode 100644 index 0000000000..40e56bebb5 --- /dev/null +++ b/source4/scripting/python/samba/tests/samdb.py @@ -0,0 +1,55 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. Tests for SamDB +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# +from auth import system_session +from credentials import Credentials +import os +from samba.provision import setup_samdb +from samba.samdb import SamDB +from samba.tests import get_loadparm, TestCaseInTempDir +import security +from unittest import TestCase +import uuid + +class SamDBTestCase(TestCaseInTempDir): + def setUp(self): + super(SamDBTestCase, self).setUp() + invocationid = uuid.random() + domaindn = "DC=COM,DC=EXAMPLE" + self.domaindn = domaindn + configdn = "CN=Configuration," + domaindn + schemadn = "CN=Schema," + configdn + domainguid = uuid.random() + policyguid = uuid.random() + setup_path = lambda x: os.path.join("setup", x) + creds = Credentials() + domainsid = security.random_sid() + hostguid = uuid.random() + path = os.path.join(self.tempdir, "samdb.ldb") + self.samdb = setup_samdb(path, setup_path, system_session(), creds, + get_loadparm(), schemadn, configdn, + self.domaindn, "example.com", "EXAMPLE.COM", + "FOO", lambda x: None, "foo", domaindn, + False, domainsid, "# no aci", domainguid, + policyguid, "EXAMPLE", True, "secret", + "secret", "secret", hostguid, invocationid, + "secret", "domain controller") + + def test_add_foreign(self): + self.samdb.add_foreign(self.domaindn, "S-1-5-7", "Somedescription") + -- cgit From 85fe22a85fe7e8db7d2f6e2fdd6f02836f116b8e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 15 Feb 2008 15:14:55 +0100 Subject: Use struct for provision parameters since there are so many of them. (This used to be commit 4b9d5bc57ca4ee14c142ea720dce5e4ee97f8c16) --- source4/scripting/python/samba/provision.py | 40 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 97021fceb2..d30eaf3d7f 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -271,7 +271,7 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, configdn, schemadn, domaindn, hostname, netbiosname, dnsdomain, realm, - rootdn, serverrole, ldap_backend=None, + rootdn, serverrole, sitename, ldap_backend=None, ldap_backend_type=None, erase=False): """Setup the partitions for the SAM database. @@ -378,7 +378,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, message("Setting up sam.ldb rootDSE") setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname) + dnsdomain, realm, rootdn, configdn, netbiosname, + sitename) if erase: message("Erasing data from partitions") @@ -472,7 +473,8 @@ def setup_registry(path, setup_path, session_info, credentials, lp): def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname): + dnsdomain, realm, rootdn, configdn, netbiosname, + sitename): """Setup the SamDB rootdse. :param samdb: Sam Database handle @@ -482,7 +484,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DNSDOMAIN": dnsdomain, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "REALM": realm, "DNSNAME": "%s.%s" % (hostname, dnsdomain), "DOMAINDN": domaindn, @@ -495,7 +497,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, def setup_self_join(samdb, configdn, schemadn, domaindn, netbiosname, hostname, dnsdomain, machinepass, dnspass, realm, domainname, domainsid, invocationid, setup_path, - policyguid, hostguid=None): + policyguid, sitename, hostguid=None): """Join a host to its own domain.""" if hostguid is not None: hostguid_add = "objectGUID: %s" % hostguid @@ -508,7 +510,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, "DOMAINDN": domaindn, "INVOCATIONID": invocationid, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "DNSNAME": "%s.%s" % (hostname, dnsdomain), "MACHINEPASS_B64": b64encode(machinepass), "DNSPASS_B64": b64encode(dnspass), @@ -529,7 +531,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domainsid, aci, domainguid, policyguid, domainname, fill, adminpass, krbtgtpass, machinepass, hostguid, invocationid, dnspass, - serverrole, ldap_backend=None, ldap_backend_type=None): + serverrole, sitename, ldap_backend=None, + ldap_backend_type=None): """Setup a complete SAM Database. :note: This will wipe the main SAM database file! @@ -544,7 +547,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, hostname=hostname, netbiosname=netbiosname, dnsdomain=dnsdomain, realm=realm, rootdn=rootdn, ldap_backend=ldap_backend, serverrole=serverrole, - ldap_backend_type=ldap_backend_type, erase=erase) + ldap_backend_type=ldap_backend_type, erase=erase, + sitename=sitename) samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) @@ -562,7 +566,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if lp.get("server role") == "domain controller": samdb.set_invocation_id(invocationid) - load_schema(setup_path, samdb, schemadn, netbiosname, configdn) + load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename) samdb.transaction_start() @@ -584,7 +588,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "DOMAINSID": str(domainsid), "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, "POLICYGUID": policyguid, "DOMAINDN": domaindn, @@ -614,7 +618,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, }) @@ -629,7 +633,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { "CONFIGDN": configdn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "DNSDOMAIN": dnsdomain, "DOMAIN": domainname, "SCHEMADN": schemadn, @@ -656,7 +660,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision.ldif"), { "DOMAINDN": domaindn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, }) @@ -679,7 +683,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, machinepass=machinepass, domainname=domainname, domainsid=domainsid, policyguid=policyguid, hostname=hostname, hostguid=hostguid, - setup_path=setup_path) + setup_path=setup_path, sitename=sitename) #We want to setup the index last, as adds are faster unindexed message("Setting up sam.ldb index") @@ -702,7 +706,7 @@ def provision(lp, setup_dir, message, paths, session_info, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, erase=False, - ldap_backend=None, ldap_backend_type=None): + ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): """Provision samba4 :note: caution, this wipes all existing data! @@ -851,7 +855,7 @@ def provision(lp, setup_dir, message, paths, session_info, hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, dnspass=dnspass, serverrole=serverrole, ldap_backend=ldap_backend, - ldap_backend_type=ldap_backend_type) + ldap_backend_type=ldap_backend_type, sitename=sitename) if lp.get("server role") == "domain controller": policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", @@ -945,7 +949,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, }) -def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): +def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. @@ -962,7 +966,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE": DEFAULTSITE + "DEFAULTSITE":sitename }) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 7c96ca88c4e6fc5bd9b0c585b0700cc04e0f517c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 16 Feb 2008 15:23:26 +0100 Subject: Formatting fixes. (This used to be commit bc0fab89e325ebb6ab870b1c3f4b263c50631b70) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d30eaf3d7f..3e88b68509 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -335,9 +335,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, schemadn_ldb = ldap_backend if ldap_backend_type == "fedora-ds": - backend_modules = ["nsuniqueid","paged_searches"] + backend_modules = ["nsuniqueid", "paged_searches"] elif ldap_backend_type == "openldap": - backend_modules = ["normalise","entryuuid","paged_searches"] + backend_modules = ["normalise", "entryuuid", "paged_searches"] elif serverrole == "domain controller": backend_modules = ["repl_meta_data"] else: @@ -695,6 +695,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb.transaction_commit() return samdb + FILL_FULL = "FULL" FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" -- cgit From 7df18932f65282461ee00c1ae17712c490be84d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 16 Feb 2008 16:15:21 +0100 Subject: use gmake to handle .py file copies. (This used to be commit 33111f98df7e8f9bb7d62599c6b13a1a4479a2e1) --- source4/scripting/python/config.mk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index b15e1fcda7..16cd301aad 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -35,6 +35,10 @@ PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --project-name=Samba --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) +bin/python/%.py: + mkdir -p $(@D) + cp $< $@ + installpython:: pythonmods @$(SHELL) $(srcdir)/script/installpython.sh \ $(INSTALLPERMS) \ -- cgit From 845664e94b7bc98f6e93be6d7ff2a141d9d9e192 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 20 Feb 2008 11:32:56 +0100 Subject: Avoid python2.2-specific types. (This used to be commit d45c6b5574ea732d25e9180c83f1fa807ebe57ba) --- source4/scripting/python/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 908efd1588..2142cd9abd 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -54,7 +54,7 @@ fi if test x$PYTHON != x then - DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True), sysconfig.get_config_var('CFLAGS'))"` + DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=1), sysconfig.get_config_var('CFLAGS'))"` DISTUTILS_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"` TRY_LINK_PYTHON($DISTUTILS_LDFLAGS, $DISTUTILS_CFLAGS) fi -- cgit From 895874d9663ccb95883579d145018ec8a8add9c8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 18 Feb 2008 14:33:58 +0100 Subject: idmap: Handle uid->SID mapping (This used to be commit 6ac6de8476ba036eb041e054bc37e4503dc2fde8) --- source4/scripting/python/samba/provision.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3e88b68509..e3c47ff4a2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -59,6 +59,7 @@ class ProvisionPaths: self.hkpd = None self.hkpt = None self.samdb = None + self.idmapdb = None self.secrets = None self.keytab = None self.dns_keytab = None @@ -202,6 +203,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") + paths.idmapdb = os.path.join(private_dir, lp.get("idmap database") or "idmap.ldb") paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.dns = os.path.join(private_dir, dnsdomain + ".zone") @@ -471,6 +473,24 @@ def setup_registry(path, setup_path, session_info, credentials, lp): assert os.path.exists(provision_reg) reg.diff_apply(provision_reg) +def setup_idmapdb(path, setup_path, session_info, credentials, lp): + """Setup the idmap database. + + :param path: path to the idmap database + :param setup_path: Function that returns a path to a setup file + :param session_info: Session information + :param credentials: Credentials + :param lp: Loadparm context + """ + if os.path.exists(path): + os.unlink(path) + + idmap_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) + + idmap_ldb.erase() + idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) + return idmap_ldb def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname, @@ -844,6 +864,10 @@ def provision(lp, setup_dir, message, paths, session_info, setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) + message("Setting up idmap db") + setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, + credentials=credentials, lp=lp) + samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, lp=lp, schemadn=schemadn, configdn=configdn, domaindn=domaindn, -- cgit From ef15b28d244dcaaa38a07055c3a88f6199173611 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 26 Feb 2008 16:02:51 +0100 Subject: use make macro for python. (This used to be commit b0408abb08648c0155d8f5da5fb299b1acbc09b6) --- source4/scripting/python/config.mk | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 16cd301aad..cafbea6b6e 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -15,36 +15,9 @@ OBJ_FILES = uuidmodule.o PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i -# Swig extensions -swig:: pythonmods - -.SUFFIXES: _wrap.c .i - -.i_wrap.c: - [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $< - -realdistclean:: - @echo "Removing SWIG output files" - @-rm -f bin/python/* - # FIXME: Remove _wrap.c files - -pythonmods:: $(PYTHON_DSOS) $(PYTHON_PYS) - PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --project-name=Samba --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) -bin/python/%.py: - mkdir -p $(@D) - cp $< $@ - -installpython:: pythonmods - @$(SHELL) $(srcdir)/script/installpython.sh \ - $(INSTALLPERMS) \ - $(DESTDIR)$(PYTHONDIR) \ - scripting/python bin/python -clean:: - @echo "Removing python modules" - @rm -f bin/python/* -- cgit From 2ca7dfe20c4a86d0abacf5cafc81a2dd97acc7dd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 26 Feb 2008 16:51:50 +0100 Subject: Fix pydoctor. (This used to be commit 023025e4de119aa234f885aa6e5594660bd8f358) --- source4/scripting/python/config.mk | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index cafbea6b6e..56634736bd 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -15,9 +15,6 @@ OBJ_FILES = uuidmodule.o PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i -PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py - -pydoctor:: pythonmods - LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --project-name=Samba --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) - +_PY_FILES = $(shell find scripting/python -name "*.py") +$(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst scripting/python/%,%,$(pyfile)),$(pyfile)))) -- cgit From 9b7baec42bc00985697be895e5d21aae50322f4d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Feb 2008 08:39:45 +1100 Subject: Reorder modules to have rdn_name before objectclass. This ensures the relative DN is placed in the correct case into the DB. Andrew Bartlett (This used to be commit 16378219fbf9e8a26621f848e85426180822ea29) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e3c47ff4a2..55935b0037 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -313,9 +313,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, "server_sort", "extended_dn", "asq", - "samldb", "rdn_name", "objectclass", + "samldb", "kludge_acl", "operational"] tdb_modules_list = [ -- cgit From 2ba62662f8e2578153be3125eb557b9349ccfd3b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Feb 2008 20:04:58 +0100 Subject: Remove sDefault as static variable. (This used to be commit 16f36ce499e93860dd535034a584ec2b93e7a172) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index b15e1fcda7..0d47c8c542 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -25,7 +25,7 @@ swig:: pythonmods realdistclean:: @echo "Removing SWIG output files" - @-rm -f bin/python/* + @-rm -rf bin/python/* # FIXME: Remove _wrap.c files pythonmods:: $(PYTHON_DSOS) $(PYTHON_PYS) -- cgit From 09447777d0c1a00daced1c63c3614136acfbe53f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 16 Feb 2008 16:15:21 +0100 Subject: use gmake to handle .py file copies. (This used to be commit d54421a9eeadbd76791917c5e3c460c897259ede) --- source4/scripting/python/config.mk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 0d47c8c542..b68abdba5e 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -35,6 +35,10 @@ PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py pydoctor:: pythonmods LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --project-name=Samba --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) +bin/python/%.py: + mkdir -p $(@D) + cp $< $@ + installpython:: pythonmods @$(SHELL) $(srcdir)/script/installpython.sh \ $(INSTALLPERMS) \ -- cgit From 21208d3303ec13056f706ee74132822a7dd2f36a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Feb 2008 14:32:37 +0100 Subject: Fix typos, avoid DEPEND_LIST from growing with empty elements. (This used to be commit b30fd477ff0d97bb4de3c5301a6cdc47867451ee) --- source4/scripting/python/config.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index b68abdba5e..a16d737344 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -25,7 +25,6 @@ swig:: pythonmods realdistclean:: @echo "Removing SWIG output files" - @-rm -rf bin/python/* # FIXME: Remove _wrap.c files pythonmods:: $(PYTHON_DSOS) $(PYTHON_PYS) @@ -47,4 +46,4 @@ installpython:: pythonmods clean:: @echo "Removing python modules" - @rm -f bin/python/* + @rm -rf bin/python/* -- cgit From c20cf59768d585baf4524c54dadba1ec60673894 Mon Sep 17 00:00:00 2001 From: Douglas VanLeuven Date: Mon, 3 Mar 2008 11:08:59 +1100 Subject: Fix member server provision Can't add "member server" because the script aborts with null reference when no match on serverrole. This is fixed by checking for the keyword "member server". (This used to be commit 62536750ae06248a49c6b56c86d01b0062bb54f0) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 55935b0037..e9aded205a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -830,7 +830,7 @@ def provision(lp, setup_dir, message, paths, session_info, message("Setting up smb.conf") if serverrole == "domain controller": smbconfsuffix = "dc" - elif serverrole == "member": + elif serverrole == "member server": smbconfsuffix = "member" setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { -- cgit From 4d4a898742a0439d3f60c84194b02901412f4679 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Mar 2008 13:03:19 +1100 Subject: Fix failure to re-provision. Somewhere in the conversion from ejs we lost calling the 'delete partitions' code. However, we have to be careful not to wipe partitions when we are the second client connecting to an LDAP server. Andrew Bartlett (This used to be commit 272eb765b81e3eab216a07249334f9b7d20e530b) --- source4/scripting/python/samba/__init__.py | 11 +++++++++-- source4/scripting/python/samba/provision.py | 19 ++++++++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index b041165800..8d5f4250c9 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -127,7 +127,7 @@ class Ldb(ldb.Ldb): try: self.delete(msg.dn) except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): - # Ignor eno such object errors + # Ignore no such object errors pass res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", ["distinguishedName"]) @@ -151,7 +151,14 @@ class Ldb(ldb.Ldb): previous_remaining = current_remaining current_remaining = len(res2) for msg in res2: - self.delete(msg.dn) + try: + self.delete(msg.dn) + # Ignore no such object errors + except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): + pass + # Ignore not allowed on non leaf errors + except ldb.LdbError, (LDB_ERR_NOT_ALLOWED_ON_NON_LEAF, _): + pass def load_ldif_file_add(self, ldif_path): """Load a LDIF file. diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e9aded205a..ea2feb981b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -279,8 +279,6 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, Alternatively, provision() may call this, and then populate the database. - :param erase: Remove the existing data present in the database. - :note: This will wipe the Sam Database! :note: This function always removes the local SAM LDB file. The erase @@ -289,10 +287,15 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, """ assert session_info is not None - if os.path.exists(samdb_path): + samdb = SamDB(samdb_path, session_info=session_info, + credentials=credentials, lp=lp) + + # Wipes the database + try: + samdb.erase() + except: os.unlink(samdb_path) - # Also wipes the database samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) @@ -547,7 +550,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, def setup_samdb(path, setup_path, session_info, credentials, lp, schemadn, configdn, domaindn, dnsdomain, realm, - netbiosname, message, hostname, rootdn, erase, + netbiosname, message, hostname, rootdn, domainsid, aci, domainguid, policyguid, domainname, fill, adminpass, krbtgtpass, machinepass, hostguid, invocationid, dnspass, @@ -560,6 +563,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, assert serverrole in ("domain controller", "member server") + erase = (fill != FILL_DRS) + # Also wipes the database setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, domaindn=domaindn, message=message, lp=lp, @@ -726,7 +731,7 @@ def provision(lp, setup_dir, message, paths, session_info, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, - wheel=None, backup=None, aci=None, serverrole=None, erase=False, + wheel=None, backup=None, aci=None, serverrole=None, ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): """Provision samba4 @@ -873,7 +878,7 @@ def provision(lp, setup_dir, message, paths, session_info, configdn=configdn, domaindn=domaindn, dnsdomain=dnsdomain, netbiosname=netbiosname, realm=realm, message=message, hostname=hostname, - rootdn=rootdn, erase=erase, domainsid=domainsid, + rootdn=rootdn, domainsid=domainsid, aci=aci, domainguid=domainguid, policyguid=policyguid, domainname=domain, fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass, -- cgit From b29d47edcf2767d7f9e9f63332079c6e8e89946c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Mar 2008 18:25:28 +0100 Subject: Move object file lists to the Makefile. (This used to be commit a7e6d2a1832db388fdafa1279f84c9a8bbfc87d6) --- source4/scripting/python/config.mk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 56634736bd..8a3a637bf5 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,15 +1,18 @@ [BINARY::smbpython] PRIVATE_DEPENDENCIES = LIBPYTHON -OBJ_FILES = smbpython.o + +smbpython_OBJ_FILES = scripting/python/smbpython.o [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON INIT_FUNCTION_SENTINEL = { NULL, NULL } -OBJ_FILES = modules.o pytalloc.o + +LIBPYTHON_OBJ_FILES = $(addprefix scripting/python/, modules.o pytalloc.o) [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR -OBJ_FILES = uuidmodule.o + +python_uuid_OBJ_FILES = scripting/python/uuidmodule.o [PYTHON::python_misc] PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS -- cgit From 2d1c06c5781600a0efcf9becd3e2773dbbbf2cc7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Mar 2008 00:43:24 +0100 Subject: Fix includes. (This used to be commit 99e61dade2bd9ae2a5dfe17f766528012c09e46c) --- source4/scripting/python/config.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 8a3a637bf5..a0f5caad3b 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -18,6 +18,8 @@ python_uuid_OBJ_FILES = scripting/python/uuidmodule.o PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i +python_misc_OBJ_FILES = scripting/python/misc_wrap.o + _PY_FILES = $(shell find scripting/python -name "*.py") $(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst scripting/python/%,%,$(pyfile)),$(pyfile)))) -- cgit From 7e0ef3fd0ef4dba827f331cbe43fa0524be91130 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 6 Mar 2008 21:55:26 +1100 Subject: Make Samba4 pass the NET-API-BECOMEDC test against Win2k3 (again). To make Samba4, using the python provision system, pass this test required some major rework. Untested code is broken code, and some of the refactoring for a seperate provision test (which also now passes) broke things. Similarly, the iconv work has compiled, but these codepaths have never been run (NULL pointer de-reference). In working to use a local, rather than global, loadparm context, and to support using a target directory, a few things needed to be reworked, particularly around path handling. Andrew Bartlett (This used to be commit 1169e8d7bee20477b0efbfea3534ac63c83fb3d6) --- source4/scripting/python/samba/provision.py | 214 ++++++++++++++++++---------- 1 file changed, 138 insertions(+), 76 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ea2feb981b..ab8c51595f 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -32,6 +32,7 @@ from socket import gethostname, gethostbyname 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.samdb import SamDB import security @@ -65,6 +66,7 @@ class ProvisionPaths: self.dns_keytab = None self.dns = None self.winsdb = None + self.private_dir = None def check_install(lp, session_info, credentials): @@ -197,20 +199,20 @@ def provision_paths_from_lp(lp, dnsdomain): :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() - private_dir = lp.get("private dir") + paths.private_dir = lp.get("private dir") paths.keytab = "secrets.keytab" paths.dns_keytab = "dns.keytab" - paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") - paths.idmapdb = os.path.join(private_dir, lp.get("idmap database") or "idmap.ldb") - paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") - paths.templates = os.path.join(private_dir, "templates.ldb") - paths.dns = os.path.join(private_dir, dnsdomain + ".zone") - paths.winsdb = os.path.join(private_dir, "wins.ldb") - paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") - paths.smbconf = os.path.join(private_dir, "smb.conf") - paths.phpldapadminconfig = os.path.join(private_dir, + paths.shareconf = os.path.join(paths.private_dir, "share.ldb") + paths.samdb = os.path.join(paths.private_dir, lp.get("sam database") or "samdb.ldb") + paths.idmapdb = os.path.join(paths.private_dir, lp.get("idmap database") or "idmap.ldb") + paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb") + paths.templates = os.path.join(paths.private_dir, "templates.ldb") + paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") + paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") + paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") + paths.smbconf = os.path.join(paths.private_dir, "smb.conf") + paths.phpldapadminconfig = os.path.join(paths.private_dir, "phpldapadmin-config.php") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" @@ -588,7 +590,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": samdb.set_invocation_id(invocationid) load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename) @@ -699,7 +701,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "KRBTGTPASS_B64": b64encode(krbtgtpass), }) - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": message("Setting up self join") setup_self_join(samdb, configdn=configdn, schemadn=schemadn, domaindn=domaindn, invocationid=invocationid, @@ -725,13 +727,14 @@ FILL_FULL = "FULL" FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" -def provision(lp, setup_dir, message, paths, session_info, - credentials, samdb_fill=FILL_FULL, realm=None, rootdn=None, +def provision(setup_dir, message, session_info, + credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, hostip=None, domainsid=None, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, - wheel=None, backup=None, aci=None, serverrole=None, + wheel=None, backup=None, aci=None, serverrole=None, ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): """Provision samba4 @@ -768,6 +771,65 @@ def provision(lp, setup_dir, message, paths, session_info, backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] if aci is None: aci = "# no aci for local ldb" + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if hostip is None: + hostip = gethostbyname(hostname) + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + if targetdir is not None: + if not os.path.exists(targetdir): + os.mkdir(targetdir) + if not os.path.exists(os.path.join(targetdir, "etc")): + os.mkdir(os.path.join(targetdir, "etc")) + + if smbconf is None: + smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): + message("Setting up smb.conf") + assert serverrole is not None + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member server": + smbconfsuffix = "member" + + assert domain is not None + assert realm is not None + + default_lp = param.LoadParm() + #Load non-existant file + default_lp.load(smbconf) + + if targetdir is not None: + privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) + lockdir_line = "lock dir = " + os.path.abspath(targetdir) + + default_lp.set("lock dir", os.path.abspath(targetdir)) + + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") + netlogon = os.path.join(os.path.join(sysvol, "scripts")) + + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + smbconf, { + "HOSTNAME": hostname, + "DOMAIN_CONF": domain, + "REALM_CONF": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": netlogon, + "SYSVOLPATH": sysvol, + "PRIVATEDIR_LINE": privatedir_line, + "LOCKDIR_LINE": lockdir_line + }) + + lp = param.LoadParm() + lp.load(smbconf) + if serverrole is None: serverrole = lp.get("server role") assert serverrole in ("domain controller", "member server") @@ -777,32 +839,26 @@ def provision(lp, setup_dir, message, paths, session_info, if realm is None: realm = lp.get("realm") - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % - (lp.get("realm"), realm)) - - ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") - - if ldap_backend == "ldapi": - # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") - assert realm is not None realm = realm.upper() - if hostname is None: - hostname = gethostname().split(".")[0].lower() + dnsdomain = realm.lower() - if hostip is None: - hostip = gethostbyname(hostname) + paths = provision_paths_from_lp(lp, dnsdomain) - netbiosname = hostname.upper() - if not valid_netbios_name(netbiosname): - raise InvalidNetbiosName(netbiosname) + if targetdir is not None: + if not os.path.exists(paths.private_dir): + os.mkdir(paths.private_dir) + + ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") + + if ldap_backend == "ldapi": + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - dnsdomain = realm.lower() if serverrole == "domain controller": - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + if domaindn is None: + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if domain is None: domain = lp.get("workgroup") @@ -815,38 +871,25 @@ def provision(lp, setup_dir, message, paths, session_info, if not valid_netbios_name(domain): raise InvalidNetbiosName(domain) else: - domaindn = "CN=" + netbiosname + if domaindn is None: + domaindn = "CN=" + netbiosname domain = netbiosname if rootdn is None: rootdn = domaindn - configdn = "CN=Configuration," + rootdn - schemadn = "CN=Schema," + configdn + if configdn is None: + configdn = "CN=Configuration," + rootdn + if schemadn is None: + schemadn = "CN=Schema," + configdn message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) - assert paths.smbconf is not None - - # only install a new smb.conf if there isn't one there already - if not os.path.exists(paths.smbconf): - message("Setting up smb.conf") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member server": - smbconfsuffix = "member" - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), - paths.smbconf, { - "HOSTNAME": hostname, - "DOMAIN_CONF": domain, - "REALM_CONF": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": paths.netlogon, - "SYSVOLPATH": paths.sysvol, - }) - lp.load(paths.smbconf) + if lp.get("realm").upper() != realm.upper(): + raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % + (lp.get("realm"), realm)) # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): @@ -911,32 +954,52 @@ def provision(lp, setup_dir, message, paths, session_info, message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) + # Only make a zone file on the first DC, it should be replicated with DNS replication + if serverrole == "domain controller": + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) + + domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") + assert isinstance(domainguid, str) + hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", + expression="(&(objectClass=computer)(cn=%s))" % hostname, + scope=SCOPE_SUBTREE) + assert isinstance(hostguid, str) + + message("Setting up DNS zone: %s" % dnsdomain) + create_zone_file(paths.dns, setup_path, samdb, + hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, + domaindn=domaindn, dnspass=dnspass, realm=realm, + domainguid=domainguid, hostguid=hostguid) + message("Please install the zone located in %s into your DNS server" % paths.dns) + message("Setting up phpLDAPadmin configuration") create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - if lp.get("server role") == "domain controller": - samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials, lp=lp) - - domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") - assert isinstance(domainguid, str) - hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", - expression="(&(objectClass=computer)(cn=%s))" % hostname, - scope=SCOPE_SUBTREE) - assert isinstance(hostguid, str) - - message("Setting up DNS zone: %s" % dnsdomain) - create_zone_file(paths.dns, setup_path, samdb, - hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm, - domainguid=domainguid, hostguid=hostguid) - message("Please install the zone located in %s into your DNS server" % paths.dns) - return domaindn +def provision_become_dc(setup_dir=None, + smbconf=None, targetdir=None, realm=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, + domain=None, hostname=None, domainsid=None, + hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + policyguid=None, invocationid=None, machinepass=None, + dnspass=None, root=None, nobody=None, nogroup=None, users=None, + wheel=None, backup=None, aci=None, serverrole=None, + ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): + + def message(text): + """print a message if quiet is not set.""" + print text + + provision(setup_dir, message, system_session(), None, + smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, + rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, + domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. @@ -978,7 +1041,6 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, "HOSTGUID": hostguid, }) - def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From 8b24d248b7c928fd3b20f95ede34302ca274c4ae Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Mar 2008 07:33:14 +1100 Subject: Start to rework provision for LDAP backends This is the start of the rework of the provision script to handle an LDAP backend correctly. For example, we must not set the 'tdb modules' against an LDAP backend such as OpenLDAP that handles subtree renames. Andrew Bartlett (This used to be commit e462a107d3bafcc546ca4d53dcc8eb32e4280745) --- source4/scripting/python/samba/__init__.py | 7 ++++++- source4/scripting/python/samba/provision.py | 11 ++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 8d5f4250c9..e91b320c07 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -147,7 +147,12 @@ class Ldb(ldb.Ldb): k = 0 while ++k < 10 and (previous_remaining != current_remaining): # and the rest - res2 = self.search(basedn, ldb.SCOPE_SUBTREE, "(|(objectclass=*)(distinguishedName=*))", ["distinguishedName"]) + try: + res2 = self.search(basedn, ldb.SCOPE_SUBTREE, "(|(objectclass=*)(distinguishedName=*))", ["distinguishedName"]) + except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): + # Ignore missing dn errors + return + previous_remaining = current_remaining current_remaining = len(res2) for msg in res2: diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ea2feb981b..b140071f41 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -341,12 +341,21 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid", "paged_searches"] + # We can handle linked attributes here, as we don't have directory-side subtree operations + tdb_modules_list = ["linked_attributes"] elif ldap_backend_type == "openldap": backend_modules = ["normalise", "entryuuid", "paged_searches"] + # OpenLDAP handles subtree renames, so we don't want to do any of these things + tdb_modules_list = None elif serverrole == "domain controller": backend_modules = ["repl_meta_data"] else: backend_modules = ["objectguid"] + + if tdb_modules_list is None: + tdb_modules_list_as_string = "" + else: + tdb_modules_list_as_string = ","+",".join(tdb_modules_list) samdb.transaction_start() try: @@ -362,7 +371,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, "CONFIGDN_MOD": "naming_fsmo,instancetype", "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", "MODULES_LIST": ",".join(modules_list), - "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "TDB_MODULES_LIST": tdb_modules_list_as_string, "MODULES_LIST2": ",".join(modules_list2), "BACKEND_MOD": ",".join(backend_modules), }) -- cgit From 14c5f968e1f99ceabc5a42d9a38a00ea137b00ea Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Mar 2008 10:57:52 +1100 Subject: Rework provision scripts for more testing This fixes up some issues with testdir (was not honoured) and increases test coverage. We now check all the major provision modes. In doing so, to make it possible to call from the multiple layers of 'sh', I have allowed 'dc' to alias 'domain controller' and 'member' to alias 'member server'. Fighting shell quoting in the test system was just too hard... Also fix upgrade.py Andrew Bartlett (This used to be commit 0923de12282b0e063dd73bc3e056dd5c3663c190) --- source4/scripting/python/samba/provision.py | 29 ++++++++++++++++------------- source4/scripting/python/samba/upgrade.py | 5 +---- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 37c4c5b082..25c1a995ef 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -572,9 +572,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, :note: This will wipe the main SAM database file! """ - assert serverrole in ("domain controller", "member server") - - erase = (fill != FILL_DRS) + erase = (fill != FILL_DRS) # Also wipes the database setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, @@ -796,17 +794,22 @@ def provision(setup_dir, message, session_info, if not os.path.exists(os.path.join(targetdir, "etc")): os.mkdir(os.path.join(targetdir, "etc")) - if smbconf is None: - smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) + smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): message("Setting up smb.conf") - assert serverrole is not None + if serverrole is None: + serverrole = "standalone" + + assert serverrole in ("domain controller", "member server", "standalone") if serverrole == "domain controller": smbconfsuffix = "dc" elif serverrole == "member server": smbconfsuffix = "member" + elif serverrole == "standalone": + smbconfsuffix = "standalone" assert domain is not None assert realm is not None @@ -827,8 +830,8 @@ def provision(setup_dir, message, session_info, setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), smbconf, { "HOSTNAME": hostname, - "DOMAIN_CONF": domain, - "REALM_CONF": realm, + "DOMAIN": domain, + "REALM": realm, "SERVERROLE": serverrole, "NETLOGONPATH": netlogon, "SYSVOLPATH": sysvol, @@ -841,7 +844,7 @@ def provision(setup_dir, message, session_info, if serverrole is None: serverrole = lp.get("server role") - assert serverrole in ("domain controller", "member server") + assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": invocationid = uuid.random() @@ -851,6 +854,10 @@ def provision(setup_dir, message, session_info, assert realm is not None realm = realm.upper() + if lp.get("realm").upper() != realm.upper(): + raise Exception("realm '%s' in %s must match chosen realm '%s'" % + (lp.get("realm"), smbconf, realm)) + dnsdomain = realm.lower() paths = provision_paths_from_lp(lp, dnsdomain) @@ -896,10 +903,6 @@ def provision(setup_dir, message, session_info, message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % - (lp.get("realm"), realm)) - # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 01b62ff984..c5086846d8 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -218,11 +218,9 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, else: serverrole = "member server" - lp.set("server role", serverrole) domainname = oldconf.get("workgroup") if domainname: domainname = str(domainname) - lp.set("workgroup", domainname) realm = oldconf.get("realm") netbiosname = oldconf.get("netbios name") @@ -235,7 +233,6 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, if realm is None: realm = domainname.lower() message("No realm specified in smb.conf file, assuming '%s'\n" % realm) - lp.set("realm", realm) domainguid = secrets_db.get_domain_guid(domainname) domainsid = secrets_db.get_sid(domainname) @@ -247,7 +244,7 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, else: machinepass = None - domaindn = provision(lp=lp, setup_dir=setup_dir, message=message, + domaindn = provision(setup_dir=setup_dir, message=message, samdb_fill=FILL_DRS, paths=paths, session_info=session_info, credentials=credentials, realm=realm, domain=domainname, domainsid=domainsid, domainguid=domainguid, -- cgit From a7e1fa0bef17ecc46f642b23ef635acfb09fea04 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Mar 2008 19:20:39 +1100 Subject: Try to fix up part of the upgrade test. There are still problems with the upgrade test, but these are not related to the provision system. Andrew Bartlett (This used to be commit d331bc400fb138bc43be88d0ca8ab3bcd590d2cd) --- source4/scripting/python/samba/provision.py | 13 ++++++++++++- source4/scripting/python/samba/upgrade.py | 20 +++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 25c1a995ef..ebca1f8e40 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -68,6 +68,12 @@ class ProvisionPaths: self.winsdb = None self.private_dir = None +class ProvisionResult: + def __init__(self): + self.paths = None + self.domaindn = None + self.lp = None + self.samdb = None def check_install(lp, session_info, credentials): """Check whether the current install seems ok. @@ -991,7 +997,12 @@ def provision(setup_dir, message, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - return domaindn + result = ProvisionResult() + result.domaindn = domaindn + result.paths = paths + result.lp = lp + result.samdb = samdb + return result def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index c5086846d8..f40f2cffe7 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -207,7 +207,7 @@ def import_wins(samba4_winsdb, samba3_winsdb): "objectClass": "winsMaxVersion", "maxVersion": str(version_id)}) -def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, paths): +def upgrade_provision(samba3, setup_dir, message, credentials, session_info, smbconf, targetdir): oldconf = samba3.get_conf() if oldconf.get("domain logons") == "True": @@ -244,15 +244,13 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, else: machinepass = None - domaindn = provision(setup_dir=setup_dir, message=message, - samdb_fill=FILL_DRS, paths=paths, session_info=session_info, - credentials=credentials, realm=realm, - domain=domainname, domainsid=domainsid, domainguid=domainguid, - machinepass=machinepass, serverrole=serverrole) + result = provision(setup_dir=setup_dir, message=message, + samdb_fill=FILL_DRS, smbconf=smbconf, session_info=session_info, + credentials=credentials, realm=realm, + domain=domainname, domainsid=domainsid, domainguid=domainguid, + machinepass=machinepass, serverrole=serverrole, targetdir=targetdir) - samdb = SamDB(paths.samdb, credentials=credentials, lp=lp, session_info=session_info) - - import_wins(Ldb(paths.winsdb), samba3.get_wins_db()) + import_wins(Ldb(result.paths.winsdb), samba3.get_wins_db()) # FIXME: import_registry(registry.Registry(), samba3.get_registry()) @@ -268,12 +266,12 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, passdb = samba3.get_sam_db() for name in passdb: user = passdb[name] - #FIXME: import_sam_account(samdb, user, domaindn, domainsid) + #FIXME: import_sam_account(result.samdb, user, domaindn, domainsid) if hasattr(passdb, 'ldap_url'): message("Enabling Samba3 LDAP mappings for SAM database") - enable_samba3sam(samdb, passdb.ldap_url) + enable_samba3sam(result.samdb, passdb.ldap_url) def enable_samba3sam(samdb, ldapurl): -- cgit From 2bf39edc9d0abf3306bd25b9c40d88aceb029be7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Mar 2008 15:28:12 +0100 Subject: Push SOVERSION and VERSION out of perl code. (This used to be commit 0ba8ac6a14c62ff9edfe9f0bf43b8a7406b85291) --- source4/scripting/python/modules.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 2ecad20b8e..2c10a35c60 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -19,7 +19,6 @@ #include "includes.h" #include -#include "build.h" extern void init_ldb(void); extern void init_security(void); -- cgit From 9703948850fb6febb237d701ce6b6300e9df8e1f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 11 Mar 2008 14:41:10 +1100 Subject: Fix provision script to work without smb.conf location specified. Andrew Bartlett (This used to be commit b4da374a998caac18c288a0a6e3fcd2c50cbffa7) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ebca1f8e40..24870c2fbd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -51,7 +51,6 @@ class InvalidNetbiosName(Exception): class ProvisionPaths: def __init__(self): - self.smbconf = None self.shareconf = None self.hklm = None self.hkcu = None @@ -217,7 +216,6 @@ def provision_paths_from_lp(lp, dnsdomain): paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") - paths.smbconf = os.path.join(paths.private_dir, "smb.conf") paths.phpldapadminconfig = os.path.join(paths.private_dir, "phpldapadmin-config.php") paths.hklm = "hklm.ldb" @@ -759,6 +757,9 @@ def provision(setup_dir, message, session_info, if domainsid is None: domainsid = security.random_sid() + else: + domainsid = security.Sid(domainsid) + if policyguid is None: policyguid = uuid.random() if adminpass is None: -- cgit From 69d66e6fb09b2449dec9bf0af49408b9a6c3cc65 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Mar 2008 08:08:05 +1100 Subject: Upgrade provision-backend to python. This required a large rework of the provision code, so as to move much of the 'guess' logic into subprocedures, rather than just inline in the provision code. Andrew Bartlett (This used to be commit a0754c2a857217ca831c2295b17255d8f38dfbc2) --- source4/scripting/python/samba/provision.py | 621 ++++++++++++++++++---------- 1 file changed, 411 insertions(+), 210 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 24870c2fbd..2ede4b8d3d 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -66,7 +66,27 @@ class ProvisionPaths: self.dns = None self.winsdb = None self.private_dir = None - + self.ldapdir = None + self.slapdconf = None + self.modulesconf = None + self.memberofconf = None + self.fedoradsinf = None + self.fedoradspartitions = None + +class ProvisionNames: + def __init__(self): + self.rootdn = None + self.domaindn = None + self.configdn = None + self.schemadn = None + self.ldapmanagerdn = None + self.dnsdomain = None + self.realm = None + self.netbiosname = None + self.domain = None + self.hostname = None + self.sitename = None + class ProvisionResult: def __init__(self): self.paths = None @@ -218,6 +238,18 @@ def provision_paths_from_lp(lp, dnsdomain): paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(paths.private_dir, "phpldapadmin-config.php") + paths.ldapdir = os.path.join(paths.private_dir, + "ldap") + paths.slapdconf = os.path.join(paths.ldapdir, + "slapd.conf") + paths.modulesconf = os.path.join(paths.ldapdir, + "modules.conf") + paths.memberofconf = os.path.join(paths.ldapdir, + "memberof.conf") + paths.fedoradsinf = os.path.join(paths.ldapdir, + "fedorads.inf") + paths.fedoradspartitions = os.path.join(paths.ldapdir, + "fedorads-partitions.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -225,16 +257,142 @@ def provision_paths_from_lp(lp, dnsdomain): paths.hkpd = "hkpd.ldb" paths.hkpt = "hkpt.ldb" - paths.sysvol = lp.get("sysvol", "path") - if paths.sysvol is None: - paths.sysvol = os.path.join(lp.get("lock dir"), "sysvol") + paths.sysvol = lp.get("path", "sysvol") - paths.netlogon = lp.get("netlogon", "path") - if paths.netlogon is None: - paths.netlogon = os.path.join(os.path.join(paths.sysvol, "scripts")) + paths.netlogon = lp.get("path", "netlogon") return paths +def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, + rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + hostname = hostname.lower() + + if dnsdomain is None: + dnsdomain = lp.get("realm") + + if serverrole is None: + serverrole = lp.get("server role") + + assert dnsdomain is not None + realm = dnsdomain.upper() + + if lp.get("realm").upper() != realm: + raise Exception("realm '%s' in %s must match chosen realm '%s'" % + (lp.get("realm"), smbconf, realm)) + + dnsdomain = dnsdomain.lower() + + if (serverrole == "domain controller"): + if domain is None: + domain = lp.get("workgroup") + if domaindn is None: + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", + lp.get("workgroup"), domain) + else: + domain = netbiosname + if domaindn is None: + domaindn = "CN=" + netbiosname + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + if rootdn is None: + rootdn = domaindn + + if configdn is None: + configdn = "CN=Configuration," + rootdn + if schemadn is None: + schemadn = "CN=Schema," + configdn + + if sitename is None: + sitename=DEFAULTSITE + + names = ProvisionNames() + names.rootdn = rootdn + names.domaindn = domaindn + names.configdn = configdn + names.schemadn = schemadn + names.ldapmanagerdn = "CN=Manager," + rootdn + names.dnsdomain = dnsdomain + names.domain = domain + names.realm = realm + names.netbiosname = netbiosname + names.hostname = hostname + names.sitename = sitename + + return names + + +def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir): + if targetdir is not None: + if not os.path.exists(targetdir): + os.mkdir(targetdir) + if not os.path.exists(os.path.join(targetdir, "etc")): + os.mkdir(os.path.join(targetdir, "etc")) + + smbconf = os.path.join(targetdir, "etc", "smb.conf") + + # only install a new smb.conf if there isn't one there already + + if not os.path.exists(smbconf): + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if serverrole is None: + serverrole = "standalone" + + assert serverrole in ("domain controller", "member server", "standalone") + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member server": + smbconfsuffix = "member" + elif serverrole == "standalone": + smbconfsuffix = "standalone" + + assert domain is not None + assert realm is not None + + default_lp = param.LoadParm() + #Load non-existant file + default_lp.load(smbconf) + + if targetdir is not None: + privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) + lockdir_line = "lock dir = " + os.path.abspath(targetdir) + + default_lp.set("lock dir", os.path.abspath(targetdir)) + + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") + netlogon = os.path.join(sysvol, realm.lower(), "scripts") + + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + smbconf, { + "HOSTNAME": hostname, + "DOMAIN": domain, + "REALM": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": netlogon, + "SYSVOLPATH": sysvol, + "PRIVATEDIR_LINE": privatedir_line, + "LOCKDIR_LINE": lockdir_line + }) + + lp = param.LoadParm() + lp.load(smbconf) + + return lp def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, wheel, backup): @@ -277,9 +435,8 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, - credentials, configdn, schemadn, domaindn, - hostname, netbiosname, dnsdomain, realm, - rootdn, serverrole, sitename, ldap_backend=None, + credentials, names, + serverrole, ldap_backend=None, ldap_backend_type=None, erase=False): """Setup the partitions for the SAM database. @@ -366,12 +523,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.transaction_start() try: setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { - "SCHEMADN": schemadn, + "SCHEMADN": names.schemadn, "SCHEMADN_LDB": schemadn_ldb, "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": configdn, + "CONFIGDN": names.configdn, "CONFIGDN_LDB": configdn_ldb, - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "DOMAINDN_LDB": domaindn_ldb, "SCHEMADN_MOD": "schema_fsmo,instancetype", "CONFIGDN_MOD": "naming_fsmo,instancetype", @@ -397,9 +554,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname, - sitename) + setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, names.hostname, + names.dnsdomain, names.realm, names.rootdn, names.configdn, names.netbiosname, + names.sitename) if erase: message("Erasing data from partitions") @@ -532,10 +689,10 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, }) -def setup_self_join(samdb, configdn, schemadn, domaindn, - netbiosname, hostname, dnsdomain, machinepass, dnspass, - realm, domainname, domainsid, invocationid, setup_path, - policyguid, sitename, hostguid=None): +def setup_self_join(samdb, names, + machinepass, dnspass, + domainsid, invocationid, setup_path, + policyguid, hostguid=None): """Join a host to its own domain.""" if hostguid is not None: hostguid_add = "objectGUID: %s" % hostguid @@ -543,33 +700,32 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, hostguid_add = "" setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { - "CONFIGDN": configdn, - "SCHEMADN": schemadn, - "DOMAINDN": domaindn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + "DOMAINDN": names.domaindn, "INVOCATIONID": invocationid, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain), "MACHINEPASS_B64": b64encode(machinepass), "DNSPASS_B64": b64encode(dnspass), - "REALM": realm, - "DOMAIN": domainname, + "REALM": names.realm, + "DOMAIN": names.domain, "HOSTGUID_ADD": hostguid_add, - "DNSDOMAIN": dnsdomain}) + "DNSDOMAIN": names.dnsdomain}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { "POLICYGUID": policyguid, - "DNSDOMAIN": dnsdomain, + "DNSDOMAIN": names.dnsdomain, "DOMAINSID": str(domainsid), - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) def setup_samdb(path, setup_path, session_info, credentials, lp, - schemadn, configdn, domaindn, dnsdomain, realm, - netbiosname, message, hostname, rootdn, + names, message, domainsid, aci, domainguid, policyguid, - domainname, fill, adminpass, krbtgtpass, + fill, adminpass, krbtgtpass, machinepass, hostguid, invocationid, dnspass, - serverrole, sitename, ldap_backend=None, + serverrole, ldap_backend=None, ldap_backend_type=None): """Setup a complete SAM Database. @@ -579,14 +735,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, erase = (fill != FILL_DRS) # Also wipes the database - setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, - domaindn=domaindn, message=message, lp=lp, + setup_samdb_partitions(path, setup_path, message=message, lp=lp, credentials=credentials, session_info=session_info, - hostname=hostname, netbiosname=netbiosname, - dnsdomain=dnsdomain, realm=realm, rootdn=rootdn, + names=names, ldap_backend=ldap_backend, serverrole=serverrole, - ldap_backend_type=ldap_backend_type, erase=erase, - sitename=sitename) + ldap_backend_type=ldap_backend_type, erase=erase) samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) @@ -604,18 +757,18 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if serverrole == "domain controller": samdb.set_invocation_id(invocationid) - load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename) + load_schema(setup_path, samdb, names.schemadn, names.netbiosname, names.configdn, names.sitename) samdb.transaction_start() try: - message("Adding DomainDN: %s (permitted to fail)" % domaindn) + message("Adding DomainDN: %s (permitted to fail)" % names.domaindn) setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "ACI": aci, }) - message("Modifying DomainDN: " + domaindn + "") + message("Modifying DomainDN: " + names.domaindn + "") if domainguid is not None: domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % domainguid else: @@ -624,104 +777,102 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), { "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(domainsid), - "SCHEMADN": schemadn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "CONFIGDN": configdn, + "SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "CONFIGDN": names.configdn, "POLICYGUID": policyguid, - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "DOMAINGUID_MOD": domainguid_mod, }) message("Adding configuration container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), { - "CONFIGDN": configdn, + "CONFIGDN": names.configdn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), { - "CONFIGDN": configdn, - "SCHEMADN": schemadn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, }) message("Adding schema container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), { - "SCHEMADN": schemadn, + "SCHEMADN": names.schemadn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { - "SCHEMADN": schemadn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "CONFIGDN": configdn, + "SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "CONFIGDN": names.configdn, }) message("Setting up sam.ldb Samba4 schema") setup_add_ldif(samdb, setup_path("schema_samba4.ldif"), - {"SCHEMADN": schemadn }) + {"SCHEMADN": names.schemadn }) message("Setting up sam.ldb AD schema") setup_add_ldif(samdb, setup_path("schema.ldif"), - {"SCHEMADN": schemadn}) + {"SCHEMADN": names.schemadn}) message("Setting up sam.ldb configuration data") setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { - "CONFIGDN": configdn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "DNSDOMAIN": dnsdomain, - "DOMAIN": domainname, - "SCHEMADN": schemadn, - "DOMAINDN": domaindn, + "CONFIGDN": names.configdn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "DNSDOMAIN": names.dnsdomain, + "DOMAIN": names.domain, + "SCHEMADN": names.schemadn, + "DOMAINDN": names.domaindn, }) message("Setting up display specifiers") setup_add_ldif(samdb, setup_path("display_specifiers.ldif"), - {"CONFIGDN": configdn}) + {"CONFIGDN": names.configdn}) message("Adding users container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Modifying users container") setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Modifying computers container") setup_modify_ldif(samdb, setup_path("provision_computers_modify.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_path("provision.ldif"), { - "DOMAINDN": domaindn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "CONFIGDN": configdn, + "DOMAINDN": names.domaindn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "CONFIGDN": names.configdn, }) if fill == FILL_FULL: message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_path("provision_users.ldif"), { - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "DOMAINSID": str(domainsid), - "CONFIGDN": configdn, + "CONFIGDN": names.configdn, "ADMINPASS_B64": b64encode(adminpass), "KRBTGTPASS_B64": b64encode(krbtgtpass), }) if serverrole == "domain controller": message("Setting up self join") - setup_self_join(samdb, configdn=configdn, schemadn=schemadn, - domaindn=domaindn, invocationid=invocationid, - dnspass=dnspass, netbiosname=netbiosname, - dnsdomain=dnsdomain, realm=realm, - machinepass=machinepass, domainname=domainname, + setup_self_join(samdb, names=names, invocationid=invocationid, + dnspass=dnspass, + machinepass=machinepass, domainsid=domainsid, policyguid=policyguid, - hostname=hostname, hostguid=hostguid, - setup_path=setup_path, sitename=sitename) + hostguid=hostguid, + setup_path=setup_path) #We want to setup the index last, as adds are faster unindexed message("Setting up sam.ldb index") @@ -746,7 +897,7 @@ def provision(setup_dir, message, session_info, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, - ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): + ldap_backend=None, ldap_backend_type=None, sitename=None): """Provision samba4 :note: caution, this wipes all existing data! @@ -785,129 +936,37 @@ def provision(setup_dir, message, session_info, backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] if aci is None: aci = "# no aci for local ldb" - if hostname is None: - hostname = gethostname().split(".")[0].lower() - if hostip is None: - hostip = gethostbyname(hostname) + lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) - netbiosname = hostname.upper() - if not valid_netbios_name(netbiosname): - raise InvalidNetbiosName(netbiosname) + names = guess_names(lp=lp, hostname=hostname, domain=domain, + dnsdomain=realm, serverrole=serverrole, sitename=sitename, + rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) - if targetdir is not None: - if not os.path.exists(targetdir): - os.mkdir(targetdir) - if not os.path.exists(os.path.join(targetdir, "etc")): - os.mkdir(os.path.join(targetdir, "etc")) - - smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) - - # only install a new smb.conf if there isn't one there already - - if not os.path.exists(smbconf): - message("Setting up smb.conf") - if serverrole is None: - serverrole = "standalone" - - assert serverrole in ("domain controller", "member server", "standalone") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member server": - smbconfsuffix = "member" - elif serverrole == "standalone": - smbconfsuffix = "standalone" - - assert domain is not None - assert realm is not None - - default_lp = param.LoadParm() - #Load non-existant file - default_lp.load(smbconf) - - if targetdir is not None: - privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) - lockdir_line = "lock dir = " + os.path.abspath(targetdir) - - default_lp.set("lock dir", os.path.abspath(targetdir)) - - sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") - netlogon = os.path.join(os.path.join(sysvol, "scripts")) - - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), - smbconf, { - "HOSTNAME": hostname, - "DOMAIN": domain, - "REALM": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": netlogon, - "SYSVOLPATH": sysvol, - "PRIVATEDIR_LINE": privatedir_line, - "LOCKDIR_LINE": lockdir_line - }) + paths = provision_paths_from_lp(lp, names.dnsdomain) - lp = param.LoadParm() - lp.load(smbconf) + if hostip is None: + hostip = gethostbyname(names.hostname) if serverrole is None: serverrole = lp.get("server role") + assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": invocationid = uuid.random() - if realm is None: - realm = lp.get("realm") - - assert realm is not None - realm = realm.upper() - - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in %s must match chosen realm '%s'" % - (lp.get("realm"), smbconf, realm)) - - dnsdomain = realm.lower() - - paths = provision_paths_from_lp(lp, dnsdomain) - - if targetdir is not None: - if not os.path.exists(paths.private_dir): - os.mkdir(paths.private_dir) + if not os.path.exists(paths.private_dir): + os.mkdir(paths.private_dir) ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") - if ldap_backend == "ldapi": - # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - - if serverrole == "domain controller": - if domaindn is None: - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") - if domain is None: - domain = lp.get("workgroup") - - if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", - lp.get("workgroup"), domain) - - assert domain is not None - domain = domain.upper() - if not valid_netbios_name(domain): - raise InvalidNetbiosName(domain) - else: - if domaindn is None: - domaindn = "CN=" + netbiosname - domain = netbiosname - - if rootdn is None: - rootdn = domaindn - - if configdn is None: - configdn = "CN=Configuration," + rootdn - if schemadn is None: - schemadn = "CN=Schema," + configdn - + if ldap_backend is not None: + if ldap_backend == "ldapi": + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + message("set DOMAIN SID: %s" % str(domainsid)) - message("Provisioning for %s in realm %s" % (domain, realm)) + message("Provisioning for %s in realm %s" % (names.domain, realm)) message("Using administrator password: %s" % adminpass) # only install a new shares config db if there is none @@ -936,21 +995,19 @@ def provision(setup_dir, message, session_info, credentials=credentials, lp=lp) samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, - credentials=credentials, lp=lp, schemadn=schemadn, - configdn=configdn, domaindn=domaindn, - dnsdomain=dnsdomain, netbiosname=netbiosname, - realm=realm, message=message, hostname=hostname, - rootdn=rootdn, domainsid=domainsid, + credentials=credentials, lp=lp, names=names, + message=message, + domainsid=domainsid, aci=aci, domainguid=domainguid, policyguid=policyguid, - domainname=domain, fill=samdb_fill, + fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass, hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, dnspass=dnspass, serverrole=serverrole, ldap_backend=ldap_backend, - ldap_backend_type=ldap_backend_type, sitename=sitename) + ldap_backend_type=ldap_backend_type) if lp.get("server role") == "domain controller": - policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", + policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", "{" + policyguid + "}") os.makedirs(policy_path, 0755) os.makedirs(os.path.join(policy_path, "Machine"), 0755) @@ -959,14 +1016,14 @@ def provision(setup_dir, message, session_info, os.makedirs(paths.netlogon, 0755) secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp) - secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=realm, - netbiosname=netbiosname, domainsid=domainsid, + secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=names.realm, + netbiosname=names.netbiosname, domainsid=domainsid, keytab_path=paths.keytab, samdb_url=paths.samdb, dns_keytab_path=paths.dns_keytab, dnspass=dnspass, - machinepass=machinepass, dnsdomain=dnsdomain) + machinepass=machinepass, dnsdomain=names.dnsdomain) if samdb_fill == FILL_FULL: - setup_name_mappings(samdb, str(domainsid), domaindn, root=root, + setup_name_mappings(samdb, str(domainsid), names.domaindn, root=root, nobody=nobody, nogroup=nogroup, wheel=wheel, users=users, backup=backup) @@ -981,14 +1038,14 @@ def provision(setup_dir, message, session_info, domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") assert isinstance(domainguid, str) hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", - expression="(&(objectClass=computer)(cn=%s))" % hostname, + expression="(&(objectClass=computer)(cn=%s))" % names.hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - message("Setting up DNS zone: %s" % dnsdomain) + message("Setting up DNS zone: %s" % names.dnsdomain) create_zone_file(paths.dns, setup_path, samdb, - hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm, + hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain, + domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) @@ -1025,6 +1082,150 @@ def provision_become_dc(setup_dir=None, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); +def setup_db_config(setup_path, file, dbdir): + if not os.path.isdir(os.path.join(dbdir, "bdb-logs")): + os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700); + if not os.path.isdir(os.path.join(dbdir, "tmp")): + os.makedirs(os.path.join(dbdir, "tmp"), 0700); + + setup_file(setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"), + {"LDAPDBDIR": dbdir}) + + + +def provision_backend(setup_dir=None, message=None, + smbconf=None, targetdir=None, realm=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, + domain=None, hostname=None, adminpass=None, root=None, serverrole=None, + ldap_backend_type=None): + + def setup_path(file): + return os.path.join(setup_dir, file) + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if root is None: + root = findnss(pwd.getpwnam, ["root"])[0] + + lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + + names = guess_names(lp=lp, hostname=hostname, domain=domain, + dnsdomain=realm, serverrole=serverrole, + rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + + paths = provision_paths_from_lp(lp, names.dnsdomain) + + if not os.path.isdir(paths.ldapdir): + os.makedirs(paths.ldapdir) + schemadb_path = os.path.join(paths.ldapdir, "schema-tmp.ldb") + try: + os.unlink(schemadb_path) + except: + pass + + schemadb = Ldb(schemadb_path, lp=lp) + + setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"), + {"SCHEMADN": names.schemadn, + "ACI": "#", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" + }) + setup_modify_ldif(schemadb, + setup_path("provision_schema_basedn_modify.ldif"), \ + {"SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": names.configdn, + }) + + setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"), + {"SCHEMADN": names.schemadn }) + setup_add_ldif(schemadb, setup_path("schema.ldif"), + {"SCHEMADN": names.schemadn}) + + if ldap_backend_type == "fedora-ds": + setup_file(setup_path("fedora-ds.inf"), paths.fedoradsinf, + {"ROOT": root, + "HOSTNAME": hostname, + "DNSDOMAIN": names.dnsdomain, + "LDAPDIR": paths.ldapdir, + "DOMAINDN": names.domaindn, + "LDAPMANAGERDN": names.ldapmanagerdn, + "LDAPMANAGERPASS": adminpass, + "SERVERPORT": ""}) + + setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, + {"CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + }) + + setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, + {"CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + }) + mapping = "schema-map-fedora-ds-1.0" + backend_schema = "99_ad.ldif" + elif ldap_backend_type == "openldap": + setup_file(setup_path("slapd.conf"), paths.slapdconf, + {"DNSDOMAIN": names.dnsdomain, + "LDAPDIR": paths.ldapdir, + "DOMAINDN": names.domaindn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + "LDAPMANAGERDN": names.ldapmanagerdn, + "LDAPMANAGERPASS": adminpass}) + setup_file(setup_path("modules.conf"), paths.modulesconf, + {"REALM": names.realm}) + + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" + + attrs = ["linkID", "lDAPDisplayName"] + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); + + memberof_config = "# This is a generated file, do not edit!\n"; + refint_attributes = ""; + for i in range (0, len(res)): + linkid = res[i]["linkID"][0] + linkid = str(int(linkid) + 1) + target = schemadb.searchone(basedn=names.schemadn, + expression="(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))", + attribute="lDAPDisplayName"); + if target is not None: + refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"]; + memberof_config = memberof_config + """overlay memberof +memberof-dangling error +memberof-refint TRUE +memberof-group-oc top +memberof-member-ad """ + res[i]["lDAPDisplayName"] + """ +memberof-memberof-ad """ + target + """ +memberof-dangling-error 32 + +"""; + + memberof_config = memberof_config + """ +overlay refint +refint_attributes""" + refint_attributes + "\n"; + + if os.path.exists(paths.memberofconf): + os.unlink(paths.memberof.conf) + + open(paths.memberofconf, 'w').write(memberof_config) + + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) + + + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); + + os.system(schema_command) + + + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. -- cgit From 6f2935d082687eee23dbc9f1108162cf1670831a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Mar 2008 09:53:32 +1100 Subject: Don't talloc_free() the UUID before we return. This error caused us to put a 0x80 byte at the end of GUID, which was only detected by OpenLDAP's schema checking. Andrew Bartlett (This used to be commit fd99b7719bcb503e2695b2cbad0230fa23a094ca) --- source4/scripting/python/uuidmodule.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c index e05b286dd0..cd9a1cb4d5 100644 --- a/source4/scripting/python/uuidmodule.c +++ b/source4/scripting/python/uuidmodule.c @@ -24,6 +24,7 @@ static PyObject *uuid_random(PyObject *self, PyObject *args) { struct GUID guid; + PyObject *pyobj; char *str; if (!PyArg_ParseTuple(args, (char *)"")) @@ -37,9 +38,11 @@ static PyObject *uuid_random(PyObject *self, PyObject *args) return NULL; } + pyobj = PyString_FromString(str); + talloc_free(str); - return PyString_FromString(str); + return pyobj; } static PyMethodDef methods[] = { -- cgit From 07a7c8fa0d76cb7cb10cc88fb5bbe5439b746d01 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Mar 2008 09:55:06 +1100 Subject: Update the provision scripts and selftest for LDAP This should allow us to provision onto an OpenLDAP backend again. Also ensure we always have a sysvol and netlogon share in the selftest environment. Andrew Bartlett (This used to be commit b2d9b03ba3434e76d4d476233a198728523d17f9) --- source4/scripting/python/samba/provision.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 2ede4b8d3d..f9604a84b2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1192,16 +1192,18 @@ def provision_backend(setup_dir=None, message=None, for i in range (0, len(res)): linkid = res[i]["linkID"][0] linkid = str(int(linkid) + 1) + expression = "(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))" target = schemadb.searchone(basedn=names.schemadn, - expression="(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))", - attribute="lDAPDisplayName"); + expression=expression, + attribute="lDAPDisplayName", + scope=SCOPE_SUBTREE); if target is not None: - refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"]; + refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0]; memberof_config = memberof_config + """overlay memberof memberof-dangling error memberof-refint TRUE memberof-group-oc top -memberof-member-ad """ + res[i]["lDAPDisplayName"] + """ +memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ memberof-memberof-ad """ + target + """ memberof-dangling-error 32 @@ -1214,7 +1216,7 @@ refint_attributes""" + refint_attributes + "\n"; if os.path.exists(paths.memberofconf): os.unlink(paths.memberof.conf) - open(paths.memberofconf, 'w').write(memberof_config) + open(paths.memberofconf, 'w').write(memberof_config) ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) -- cgit From 0c882402360a10b19a038bce9f87e241051c9ba8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Mar 2008 11:36:58 +1100 Subject: Rework to have member server 'domains' be CN=NETBIOSNAME This reworks quite a few parts of our provision system to use CN=NETBIOSNAME as the domain for member servers. This makes it clear that these domains are not in the DNS structure, while complying with our own schema (found by OpenLDAP's schema validation). Andrew Bartlett (This used to be commit bda6a38b055fed2394e65cdc0b308a1442116402) --- source4/scripting/python/samba/provision.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f9604a84b2..25316e888a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -763,9 +763,15 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, try: message("Adding DomainDN: %s (permitted to fail)" % names.domaindn) + if serverrole == "domain controller": + domain_oc = "domainDNS" + else: + domain_oc = "samba4LocalDomain" + setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": names.domaindn, "ACI": aci, + "DOMAIN_OC": domain_oc }) message("Modifying DomainDN: " + names.domaindn + "") -- cgit From 1710eca2594c3b43f7b0651a2f07429dbeb2a35d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Mar 2008 14:27:10 +0100 Subject: configure: when detecting python we should disable pyconfig.h This fixes the detection on HP-UX where the pyconfig.h contains bogus defines. metze (This used to be commit 9391f6f80461be2b214a881782aecf7df8a4aba3) --- source4/scripting/python/config.m4 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 2142cd9abd..aac98ebc60 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -22,6 +22,8 @@ AC_DEFUN([TRY_LINK_PYTHON], CFLAGS="$CFLAGS $2" AC_TRY_LINK([ + /* we have our own configure tests */ + #define Py_PYCONFIG_H 1 #include #include ],[ -- cgit From 9c7c6c7049ab67bd5d0cee992180602bc71fa9d1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Mar 2008 15:55:56 +0100 Subject: build: we don't rely on bash yet:-) '==' should be just '=' metze (This used to be commit 17997dd9bcd385fcf27646d832ad824cc2a0800a) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index a16d737344..09c77813ca 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -21,7 +21,7 @@ swig:: pythonmods .SUFFIXES: _wrap.c .i .i_wrap.c: - [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $< + [ "$(SWIG)" = "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $< realdistclean:: @echo "Removing SWIG output files" -- cgit From 2fd59920381ea81734565637adcec96e5668ef86 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Mar 2008 14:33:18 +0100 Subject: swig: regenerate _wrap.c files metze (This used to be commit 08b41e10699c7bb8058ab0ab61f17a1bbfcc1ce4) --- source4/scripting/python/misc_wrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index f467f851bd..cf85e91e1e 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -3027,7 +3027,7 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE "ldb context must be non-NULL"); result = dsdb_attach_schema_from_ldif_file(arg1,(char const *)arg2,(char const *)arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", (&result)->v, win_errstr(result)); + PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); PyErr_SetObject(PyExc_RuntimeError, obj); SWIG_fail; } else if (resultobj == NULL) { -- cgit From d7299d82c31f08750d5d378b0e1f0226dbff5d05 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2008 19:03:04 +1100 Subject: Rework memberof handling in slapd.conf (used for OpenLDAP backend) Instead of using an include file, put the generated configurationd directly into slapd.conf. Andrew Bartlett (This used to be commit 95ac786136aebfe5ededeb3fb81cbd4e296e3988) --- source4/scripting/python/samba/provision.py | 41 +++++++++++++---------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 25316e888a..47d00f8871 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1173,27 +1173,10 @@ def provision_backend(setup_dir=None, message=None, mapping = "schema-map-fedora-ds-1.0" backend_schema = "99_ad.ldif" elif ldap_backend_type == "openldap": - setup_file(setup_path("slapd.conf"), paths.slapdconf, - {"DNSDOMAIN": names.dnsdomain, - "LDAPDIR": paths.ldapdir, - "DOMAINDN": names.domaindn, - "CONFIGDN": names.configdn, - "SCHEMADN": names.schemadn, - "LDAPMANAGERDN": names.ldapmanagerdn, - "LDAPMANAGERPASS": adminpass}) - setup_file(setup_path("modules.conf"), paths.modulesconf, - {"REALM": names.realm}) - - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" - attrs = ["linkID", "lDAPDisplayName"] res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); - memberof_config = "# This is a generated file, do not edit!\n"; + memberof_config = "# Generated from schema in " + schemadb_path + "\n"; refint_attributes = ""; for i in range (0, len(res)): linkid = res[i]["linkID"][0] @@ -1219,10 +1202,24 @@ memberof-dangling-error 32 overlay refint refint_attributes""" + refint_attributes + "\n"; - if os.path.exists(paths.memberofconf): - os.unlink(paths.memberof.conf) - - open(paths.memberofconf, 'w').write(memberof_config) + setup_file(setup_path("slapd.conf"), paths.slapdconf, + {"DNSDOMAIN": names.dnsdomain, + "LDAPDIR": paths.ldapdir, + "DOMAINDN": names.domaindn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + "LDAPMANAGERDN": names.ldapmanagerdn, + "LDAPMANAGERPASS": adminpass, + "MEMBEROF_CONFIG": memberof_config}) + setup_file(setup_path("modules.conf"), paths.modulesconf, + {"REALM": names.realm}) + + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) -- cgit From 786deaf9288c77b40892d6639113e580a7be6904 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 28 Mar 2008 12:08:54 +1100 Subject: Make the setup/newuser and setup/setpassword scripts actually work... These need a testsuite, but this will come soon. Andrew Bartlett (This used to be commit fbcaa622bd1929399e32326349e96b6676a49b96) --- source4/scripting/python/samba/samdb.py | 58 ++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 3c6bb23c02..de0fd4ba04 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -77,10 +77,15 @@ unixName: %s :param user_dn: Dn of the account to enable. """ - res = self.search(user_dn, SCOPE_ONELEVEL, None, ["userAccountControl"]) + res = self.search(user_dn, ldb.SCOPE_BASE, None, ["userAccountControl"]) assert len(res) == 1 - userAccountControl = res[0].userAccountControl - userAccountControl = userAccountControl - 2 # remove disabled bit + userAccountControl = res[0]["userAccountControl"][0] + userAccountControl = int(userAccountControl) + if (userAccountControl & 0x2): + userAccountControl = userAccountControl & ~0x2 # remove disabled bit + if (userAccountControl & 0x20): + userAccountControl = userAccountControl & ~0x20 # remove 'no password required' bit + mod = """ dn: %s changetype: modify @@ -103,13 +108,9 @@ userAccountControl: %u res = self.search("", scope=ldb.SCOPE_BASE, expression="(defaultNamingContext=*)", attrs=["defaultNamingContext"]) - assert(len(res) == 1 and res[0].defaultNamingContext is not None) + assert(len(res) == 1 and res[0]["defaultNamingContext"] is not None) domain_dn = res[0]["defaultNamingContext"][0] assert(domain_dn is not None) - dom_users = self.searchone(basedn=domain_dn, attribute="dn", - expression="name=Domain Users") - assert(dom_users is not None) - user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) # @@ -123,19 +124,44 @@ userAccountControl: %u "sambaPassword": password, "objectClass": "user"}) - # add the user to the users group as well - modgroup = """ + # modify the userAccountControl to remove the disabled bit + self.enable_account(user_dn) + self.transaction_commit() + + def setpassword(self, filter, password): + """Set a password on a user record + + :param filter: LDAP filter to find the user (eg samccountname=name) + :param password: Password for the user + """ + # connect to the sam + self.transaction_start() + + # find the DNs for the domain + res = self.search("", scope=ldb.SCOPE_BASE, + expression="(defaultNamingContext=*)", + attrs=["defaultNamingContext"]) + assert(len(res) == 1 and res[0]["defaultNamingContext"] is not None) + domain_dn = res[0]["defaultNamingContext"][0] + assert(domain_dn is not None) + + res = self.search(domain_dn, scope=ldb.SCOPE_SUBTREE, + expression=filter, + attrs=[]) + assert(len(res) == 1) + user_dn = res[0].dn + + setpw = """ dn: %s changetype: modify -add: member -member: %s -""" % (dom_users, user_dn) - +replace: sambaPassword +sambaPassword: %s +""" % (user_dn, password) - self.modify(modgroup) + self.modify_ldif(setpw) # modify the userAccountControl to remove the disabled bit - enable_account(self, user_dn) + self.enable_account(user_dn) self.transaction_commit() def set_domain_sid(self, sid): -- cgit From 677dc6aa897aed0919050545155fbd868c210b89 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Thu, 27 Mar 2008 17:49:56 +0100 Subject: provision: Initialize uninitialized variables if "targetdir" is not defined and there is no smb.conf file (This used to be commit 19c29f473883be0a17fa740de9feb226f347df4a) --- source4/scripting/python/samba/provision.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 47d00f8871..e97ce694b4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -373,7 +373,10 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol lockdir_line = "lock dir = " + os.path.abspath(targetdir) default_lp.set("lock dir", os.path.abspath(targetdir)) - + else: + privatedir_line = "private_dir = " + default_lp.get("private dir") + lockdir_line = "lock dir = " + default_lp.get("lock dir") + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") netlogon = os.path.join(sysvol, realm.lower(), "scripts") -- cgit From e15b35e3897e63b9e815a04101436439d4aebdef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Mar 2008 22:26:37 +0100 Subject: Remove define that appears to cause configure test breakage on Julien's machine. (This used to be commit f47df5761571dd5c36789fb2e225a1125ca0e8f7) --- source4/scripting/python/config.m4 | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index aac98ebc60..3790071ba8 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -23,9 +23,7 @@ AC_DEFUN([TRY_LINK_PYTHON], AC_TRY_LINK([ /* we have our own configure tests */ - #define Py_PYCONFIG_H 1 #include - #include ],[ Py_InitModule(NULL, NULL); ],[ -- cgit From b2c6ba69a453aaa7cbabb7be7b8c2a05b48a76c4 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Thu, 27 Mar 2008 16:30:18 -0500 Subject: provision: Increase max NetBIOS name length from 13 to 15. Issue originally reported by user Julsa-FR on IRC. (This used to be commit ee9ad77009ef5e36655a49c41730a4a963ba9d43) --- source4/scripting/python/samba/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index e91b320c07..b9d81c6c3c 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -225,7 +225,7 @@ def valid_netbios_name(name): """Check whether a name is valid as a NetBIOS name. """ # FIXME: There are probably more constraints here. # crh has a paragraph on this in his book (1.4.1.1) - if len(name) > 13: + if len(name) > 15: return False return True -- cgit From 4ddce8c28ca5abe2ac52cfb3a2956803f585b51a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 28 Mar 2008 10:38:12 +1100 Subject: Don't specify what should be a default option in the generated smb.conf Instead, sub in "", so that the default continued to come from the code. Andrew Bartlett (This used to be commit b1829da8f75175fcc569a3a9195f2358731055a9) --- source4/scripting/python/samba/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e97ce694b4..d5e66d842c 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -374,8 +374,8 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol default_lp.set("lock dir", os.path.abspath(targetdir)) else: - privatedir_line = "private_dir = " + default_lp.get("private dir") - lockdir_line = "lock dir = " + default_lp.get("lock dir") + privatedir_line = "" + lockdir_line = "" sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") netlogon = os.path.join(sysvol, realm.lower(), "scripts") -- cgit From 8f8c56bfbcbfe8f80afb09eb1d481a108b252bee Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 28 Mar 2008 01:08:49 -0500 Subject: Convert some more files to GPLv3. (This used to be commit ebe5e8399422eb7e2ff4deb546338823e2718907) --- source4/scripting/python/subunit/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py index 3abfbf522e..ac3d0c3a40 100644 --- a/source4/scripting/python/subunit/__init__.py +++ b/source4/scripting/python/subunit/__init__.py @@ -5,7 +5,7 @@ # # 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 2 of the License, or +# 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, -- cgit From 142fbfb3c1f9f8cda7f0edaa801f8345f23d805f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 28 Mar 2008 21:57:15 +1100 Subject: Fix and test python scripts and kerberos This fixes up the python credentials interface in a number of areas, with the aim of supporting '-k yes' as a command line option. (This enables the use of kerberos). As such, I've had to change the get_credentials call to take a loadparm context, so that the credentials can be initialised correctly. The test_kinit script has been modified to prove that this continues to work, as well as to provide greater code coverage of the kerberos paths. Andrew Bartlett (This used to be commit 727ef40c2b56910028ef3c1092b8eab1bfa6ce63) --- source4/scripting/python/samba/getopt.py | 15 ++++++++++++--- source4/scripting/python/samba/tests/samdb.py | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 088a5acf6f..82cb004b62 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -18,7 +18,7 @@ # import optparse -from credentials import Credentials +from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS class SambaOptions(optparse.OptionGroup): def __init__(self, parser): @@ -65,6 +65,9 @@ class CredentialsOptions(optparse.OptionGroup): 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", + action="callback", type=str, + help="Use Kerberos", callback=self._set_kerberos) self.creds = Credentials() def _parse_username(self, option, opt_str, arg, parser): @@ -76,11 +79,17 @@ class CredentialsOptions(optparse.OptionGroup): def _set_password(self, option, opt_str, arg, parser): self.creds.set_password(arg) + def _set_kerberos(self, option, opt_str, arg, parser): + if bool(arg) or arg.lower() == "yes": + self.creds.set_kerberos_state(MUST_USE_KERBEROS) + else: + self.creds.set_kerberos_state(DONT_USE_KERBEROS) + def _set_simple_bind_dn(self, option, opt_str, arg, parser): self.creds.set_bind_dn(arg) - def get_credentials(self): - self.creds.guess() + def get_credentials(self, lp): + self.creds.guess(lp) if not self.no_pass: self.creds.set_cmdline_callbacks() return self.creds diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 40e56bebb5..3745dba6fc 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -38,6 +38,7 @@ class SamDBTestCase(TestCaseInTempDir): policyguid = uuid.random() setup_path = lambda x: os.path.join("setup", x) creds = Credentials() + creds.set_anonymous() domainsid = security.random_sid() hostguid = uuid.random() path = os.path.join(self.tempdir, "samdb.ldb") -- cgit From 238a1a52f1fd3cce0a0fd980c1717c8540a1c7a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Mar 2008 17:17:56 +1100 Subject: Rework 'compleated' message in provision to be more useful. In particular, this should draw attention to accidential 'standalone' server provisions and therefore cause less frustration. Andrew Bartlett (This used to be commit e906ae041a2b589ffceff97b74f7c4b01386382a) --- source4/scripting/python/samba/provision.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d5e66d842c..b03457e57b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -974,10 +974,6 @@ def provision(setup_dir, message, session_info, # provision-backend will set this path suggested slapd command line / fedorads.inf ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - message("set DOMAIN SID: %s" % str(domainsid)) - message("Provisioning for %s in realm %s" % (names.domain, realm)) - message("Using administrator password: %s" % adminpass) - # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") @@ -1036,7 +1032,7 @@ def provision(setup_dir, message, session_info, nobody=nobody, nogroup=nogroup, wheel=wheel, users=users, backup=backup) - message("Setting up sam.ldb rootDSE marking as synchronized") + message("Compleating sam.ldb setup by marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) # Only make a zone file on the first DC, it should be replicated with DNS replication @@ -1051,19 +1047,25 @@ def provision(setup_dir, message, session_info, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - message("Setting up DNS zone: %s" % names.dnsdomain) create_zone_file(paths.dns, setup_path, samdb, hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain, domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) - message("Setting up phpLDAPadmin configuration") create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + message("Once the above files are installed, your server will be ready to use") + message("Server Type: %s" % serverrole) + message("Hostname: %s" % names.hostname) + message("NetBIOS Domain: %s" % names.domain) + message("DNS Domain: %s" % names.dnsdomain) + message("DOMAIN SID: %s" % str(domainsid)) + message("Admin password: %s" % adminpass) + result = ProvisionResult() result.domaindn = domaindn result.paths = paths -- cgit From 2ab6dd9ea58c7f09791f45077df084447fc7de69 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Apr 2008 11:38:58 +1100 Subject: Remove references to setting the host GUID, as the repl_meta_data module prohibits it anyway. Andrew Bartlett (This used to be commit c5b287c056855892f30fbbf32efe7d65da31ce91) --- source4/scripting/python/samba/provision.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b03457e57b..50d9f8d2ff 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -695,13 +695,8 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, def setup_self_join(samdb, names, machinepass, dnspass, domainsid, invocationid, setup_path, - policyguid, hostguid=None): + policyguid): """Join a host to its own domain.""" - if hostguid is not None: - hostguid_add = "objectGUID: %s" % hostguid - else: - hostguid_add = "" - setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, @@ -714,7 +709,6 @@ def setup_self_join(samdb, names, "DNSPASS_B64": b64encode(dnspass), "REALM": names.realm, "DOMAIN": names.domain, - "HOSTGUID_ADD": hostguid_add, "DNSDOMAIN": names.dnsdomain}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { "POLICYGUID": policyguid, @@ -727,7 +721,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, names, message, domainsid, aci, domainguid, policyguid, fill, adminpass, krbtgtpass, - machinepass, hostguid, invocationid, dnspass, + machinepass, invocationid, dnspass, serverrole, ldap_backend=None, ldap_backend_type=None): """Setup a complete SAM Database. @@ -880,7 +874,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, dnspass=dnspass, machinepass=machinepass, domainsid=domainsid, policyguid=policyguid, - hostguid=hostguid, setup_path=setup_path) #We want to setup the index last, as adds are faster unindexed @@ -902,7 +895,7 @@ def provision(setup_dir, message, session_info, credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, hostip=None, domainsid=None, - hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, @@ -1006,7 +999,7 @@ def provision(setup_dir, message, session_info, aci=aci, domainguid=domainguid, policyguid=policyguid, fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass, - hostguid=hostguid, invocationid=invocationid, + invocationid=invocationid, machinepass=machinepass, dnspass=dnspass, serverrole=serverrole, ldap_backend=ldap_backend, ldap_backend_type=ldap_backend_type) @@ -1077,7 +1070,7 @@ def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, domainsid=None, - hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, -- cgit From 3c0c6acc594fba1f1d28e49cb105c99fa1649a18 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Tue, 1 Apr 2008 19:51:24 -0500 Subject: provision: Add support for IPv6 (bz #4593). (This used to be commit 8585a3c77d5dfe97bca3f08716fc06ac2819f578) --- source4/scripting/python/samba/provision.py | 34 +++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b03457e57b..870f64ecc9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -28,7 +28,7 @@ import pwd import grp import time import uuid, misc -from socket import gethostname, gethostbyname +import socket import param import registry import samba @@ -267,7 +267,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): if hostname is None: - hostname = gethostname().split(".")[0].lower() + hostname = socket.gethostname().split(".")[0].lower() netbiosname = hostname.upper() if not valid_netbios_name(netbiosname): @@ -348,7 +348,7 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol if not os.path.exists(smbconf): if hostname is None: - hostname = gethostname().split(".")[0].lower() + hostname = socket.gethostname().split(".")[0].lower() if serverrole is None: serverrole = "standalone" @@ -901,7 +901,7 @@ FILL_DRS = "DRS" def provision(setup_dir, message, session_info, credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, - domain=None, hostname=None, hostip=None, domainsid=None, + domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, @@ -955,7 +955,12 @@ def provision(setup_dir, message, session_info, paths = provision_paths_from_lp(lp, names.dnsdomain) if hostip is None: - hostip = gethostbyname(names.hostname) + hostip = socket.getaddrinfo(names.hostname, None, socket.AF_INET, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] + + if hostip6 is None: + try: + hostip6 = socket.getaddrinfo(names.hostname, None, socket.AF_INET6, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] + except socket.gaierror: pass if serverrole is None: serverrole = lp.get("server role") @@ -1048,7 +1053,8 @@ def provision(setup_dir, message, session_info, assert isinstance(hostguid, str) create_zone_file(paths.dns, setup_path, samdb, - hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain, + hostname=names.hostname, hostip=hostip, + hostip6=hostip6, dnsdomain=names.dnsdomain, domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) @@ -1114,7 +1120,7 @@ def provision_backend(setup_dir=None, message=None, return os.path.join(setup_dir, file) if hostname is None: - hostname = gethostname().split(".")[0].lower() + hostname = socket.gethostname().split(".")[0].lower() if root is None: root = findnss(pwd.getpwnam, ["root"])[0] @@ -1247,7 +1253,7 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri): def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, - hostip, hostname, dnspass, realm, domainguid, hostguid): + hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): """Write out a DNS zone file, from the info in the current database. :param path: Path of the new file. @@ -1255,7 +1261,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, :param samdb: SamDB object :param dnsdomain: DNS Domain name :param domaindn: DN of the Domain - :param hostip: Local IP + :param hostip: Local IPv4 IP + :param hostip6: Local IPv6 IP :param hostname: Local hostname :param dnspass: Password for DNS :param realm: Realm name @@ -1264,6 +1271,13 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, """ assert isinstance(domainguid, str) + hostip6_base_line = "" + hostip6_host_line = "" + + if hostip6 is not None: + hostip6_base_line = " IN AAAA " + hostip6 + hostip6_host_line = hostname + " IN AAAA " + hostip6 + setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, @@ -1274,6 +1288,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, "DATESTRING": time.strftime("%Y%m%d%H"), "DEFAULTSITE": DEFAULTSITE, "HOSTGUID": hostguid, + "HOSTIP6_BASE_LINE": hostip6_base_line, + "HOSTIP6_HOST_LINE": hostip6_host_line, }) def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/scripting/python/misc.i | 1 + source4/scripting/python/misc_wrap.c | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index a11b2fb825..e04e6a6906 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -25,6 +25,7 @@ #include "auth/credentials/credentials.h" #include "dsdb/samdb/samdb.h" #include "lib/ldb-samba/ldif_handlers.h" +#include "librpc/ndr/libndr.h" %} %import "stdint.i" diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index cf85e91e1e..579d1f379f 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2533,6 +2533,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #include "auth/credentials/credentials.h" #include "dsdb/samdb/samdb.h" #include "lib/ldb-samba/ldif_handlers.h" +#include "librpc/ndr/libndr.h" SWIGINTERN int -- cgit From 8ac91d913231ecd7ead595b93032c7486f67c949 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Tue, 1 Apr 2008 00:17:00 +0200 Subject: provision: Set up id mappings in the idmap db, only map Administrator. (This used to be commit 206b7d387c6d17e5cc40fd45b489abac9235a7a4) --- source4/scripting/python/samba/idmap.py | 73 +++++++++++++++++++++ source4/scripting/python/samba/provision.py | 98 ++++++++++++++--------------- source4/scripting/python/samba/samdb.py | 19 ------ 3 files changed, 120 insertions(+), 70 deletions(-) create mode 100644 source4/scripting/python/samba/idmap.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py new file mode 100644 index 0000000000..355565968a --- /dev/null +++ b/source4/scripting/python/samba/idmap.py @@ -0,0 +1,73 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) 2008 Kai Blin +# +# +# 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 . +# + +"""Convenience functions for using the idmap database.""" + +import samba +import ldb + +class IDmapDB(samba.Ldb): + """The IDmap database.""" + + # Mappings for ID_TYPE_UID, ID_TYPE_GID and ID_TYPE_BOTH + TYPE_UID = 1 + TYPE_GID = 2 + TYPE_BOTH = 3 + + def __init__(self, url=None, session_info=None, credentials=None, + modules_dir=None, lp=None): + """Open the IDmap Database. + + :param url: URL of the database. + """ + super(IDmapDB, self).__init__(session_info=session_info, credentials=credentials, + modules_dir=modules_dir, lp=lp) + if url: + self.connect(url) + + + def setup_name_mapping(self, sid, type, unixid): + """Setup a mapping between a sam name and a unix name. + + :param sid: SID of the NT-side of the mapping. + :param unixname: Unix name to map to. + """ + type_string = "" + if type == self.TYPE_UID: + type_string = "ID_TYPE_UID" + elif type == self.TYPE_GID: + type_string = "ID_TYPE_GID" + elif type == self.TYPE_BOTH: + type_string = "ID_TYPE_BOTH" + else: + return + + mod = """ +dn: CN=%s +xidNumber: %s +objectSid: %s +objectClass: sidMap +type: %s +cn: %s + +""" % (sid, unixid, sid, type_string, sid) + self.add(self.parse_ldif(mod).next()[1]) + + diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index dfeb61e52b..a8ced61c4b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -35,6 +35,7 @@ import samba from auth import system_session from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted from samba.samdb import SamDB +from samba.idmap import IDmapDB import security import urllib from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ @@ -397,45 +398,32 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol return lp -def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, - wheel, backup): +def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, + users_gid, wheel_gid, backup_gid): """setup reasonable name mappings for sam names to unix names. - - :param ldb: SamDB object. + + :param samdb: SamDB object. + :param idmap: IDmap db object. :param sid: The domain sid. :param domaindn: The domain DN. - :param root: Name of the UNIX root user. - :param nobody: Name of the UNIX nobody user. - :param nogroup: Name of the unix nobody group. - :param users: Name of the unix users group. - :param wheel: Name of the wheel group (users that can become root). - :param backup: Name of the backup group.""" + :param root_uid: uid of the UNIX root user. + :param nobody_uid: uid of the UNIX nobody user. + :param users_gid: gid of the UNIX users group. + :param wheel_gid: gid of the UNIX wheel group. + :param backup_gid: gid of the UNIX backup group.""" # add some foreign sids if they are not present already - ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous") - ldb.add_foreign(domaindn, "S-1-1-0", "World") - ldb.add_foreign(domaindn, "S-1-5-2", "Network") - ldb.add_foreign(domaindn, "S-1-5-18", "System") - ldb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") - - # some well known sids - ldb.setup_name_mapping(domaindn, "S-1-5-7", nobody) - ldb.setup_name_mapping(domaindn, "S-1-1-0", nogroup) - ldb.setup_name_mapping(domaindn, "S-1-5-2", nogroup) - ldb.setup_name_mapping(domaindn, "S-1-5-18", root) - ldb.setup_name_mapping(domaindn, "S-1-5-11", users) - ldb.setup_name_mapping(domaindn, "S-1-5-32-544", wheel) - ldb.setup_name_mapping(domaindn, "S-1-5-32-545", users) - ldb.setup_name_mapping(domaindn, "S-1-5-32-546", nogroup) - ldb.setup_name_mapping(domaindn, "S-1-5-32-551", backup) - - # and some well known domain rids - ldb.setup_name_mapping(domaindn, sid + "-500", root) - ldb.setup_name_mapping(domaindn, sid + "-518", wheel) - ldb.setup_name_mapping(domaindn, sid + "-519", wheel) - ldb.setup_name_mapping(domaindn, sid + "-512", wheel) - ldb.setup_name_mapping(domaindn, sid + "-513", users) - ldb.setup_name_mapping(domaindn, sid + "-520", wheel) + samdb.add_foreign(domaindn, "S-1-5-7", "Anonymous") + samdb.add_foreign(domaindn, "S-1-1-0", "World") + samdb.add_foreign(domaindn, "S-1-5-2", "Network") + samdb.add_foreign(domaindn, "S-1-5-18", "System") + samdb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") + idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid) + idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid) + idmap.setup_name_mapping("S-1-5-32-551", idmap.TYPE_GID, backup_gid) + + idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) + idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, names, @@ -663,8 +651,8 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): if os.path.exists(path): os.unlink(path) - idmap_ldb = Ldb(path, session_info=session_info, credentials=credentials, - lp=lp) + idmap_ldb = IDmapDB(path, session_info=session_info, + credentials=credentials, lp=lp) idmap_ldb.erase() idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) @@ -924,18 +912,25 @@ def provision(setup_dir, message, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, ["root"])[0] + root_uid = findnss(pwd.getpwnam, ["root"])[2] + else: + root_uid = findnss(pwd.getpwnam, [root])[2] if nobody is None: - nobody = findnss(pwd.getpwnam, ["nobody"])[0] - if nogroup is None: - nogroup = findnss(grp.getgrnam, ["nogroup", "nobody"])[0] + nobody_uid = findnss(pwd.getpwnam, ["nobody"])[2] + else: + nobody_uid = findnss(pwd.getpwnam, [nobody])[2] if users is None: - users = findnss(grp.getgrnam, ["users", "guest", "other", "unknown", - "usr"])[0] + users_gid = findnss(grp.getgrnam, ["users"])[2] + else: + users_gid = findnss(grp.getgrnam, [users])[2] if wheel is None: - wheel = findnss(grp.getgrnam, ["wheel", "root", "staff", "adm"])[0] + wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] + else: + wheel_gid = findnss(grp.getgrnam, [wheel])[2] if backup is None: - backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] + backup_gid = findnss(grp.getgrnam, ["backup", "staff"])[2] + else: + backup_gid = findnss(grp.getgrnam, [backup])[2] if aci is None: aci = "# no aci for local ldb" @@ -994,8 +989,8 @@ def provision(setup_dir, message, session_info, credentials=credentials, lp=lp) message("Setting up idmap db") - setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, - credentials=credentials, lp=lp) + idmap = setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, + credentials=credentials, lp=lp) samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, lp=lp, names=names, @@ -1026,11 +1021,12 @@ def provision(setup_dir, message, session_info, machinepass=machinepass, dnsdomain=names.dnsdomain) if samdb_fill == FILL_FULL: - setup_name_mappings(samdb, str(domainsid), names.domaindn, root=root, - nobody=nobody, nogroup=nogroup, wheel=wheel, - users=users, backup=backup) - - message("Compleating sam.ldb setup by marking as synchronized") + setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn, + root_uid=root_uid, nobody_uid=nobody_uid, + users_gid=users_gid, wheel_gid=wheel_gid, + backup_gid=backup_gid) + + message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) # Only make a zone file on the first DC, it should be replicated with DNS replication diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index de0fd4ba04..bc3eef7879 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -53,25 +53,6 @@ description: %s for msg in self.parse_ldif(add): self.add(msg[1]) - def setup_name_mapping(self, domaindn, sid, unixname): - """Setup a mapping between a sam name and a unix name. - - :param domaindn: DN of the domain. - :param sid: SID of the NT-side of the mapping. - :param unixname: Unix name to map to. - """ - res = self.search(domaindn, ldb.SCOPE_SUBTREE, - "objectSid=%s" % sid, ["dn"]) - assert len(res) == 1, "Failed to find record for objectSid %s" % sid - - mod = """ -dn: %s -changetype: modify -replace: unixName -unixName: %s -""" % (res[0].dn, unixname) - self.modify(self.parse_ldif(mod).next()[1]) - def enable_account(self, user_dn): """Enable an account. -- cgit From c26387a473fd26ac51c74c001b520d7fd7d353ec Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Thu, 3 Apr 2008 00:01:34 +0200 Subject: provision: Remove backup group mapping Some distros seem to neither have a backup nor a staff group. (This used to be commit 21fcf7c419658b3ae296428ca7a4ccf2288c17fe) --- source4/scripting/python/samba/provision.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a8ced61c4b..6917aa1a54 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -399,7 +399,7 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol return lp def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, - users_gid, wheel_gid, backup_gid): + users_gid, wheel_gid): """setup reasonable name mappings for sam names to unix names. :param samdb: SamDB object. @@ -409,8 +409,7 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, :param root_uid: uid of the UNIX root user. :param nobody_uid: uid of the UNIX nobody user. :param users_gid: gid of the UNIX users group. - :param wheel_gid: gid of the UNIX wheel group. - :param backup_gid: gid of the UNIX backup group.""" + :param wheel_gid: gid of the UNIX wheel group.""" # add some foreign sids if they are not present already samdb.add_foreign(domaindn, "S-1-5-7", "Anonymous") samdb.add_foreign(domaindn, "S-1-1-0", "World") @@ -420,7 +419,6 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid) idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid) - idmap.setup_name_mapping("S-1-5-32-551", idmap.TYPE_GID, backup_gid) idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) @@ -927,10 +925,6 @@ def provision(setup_dir, message, session_info, wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] else: wheel_gid = findnss(grp.getgrnam, [wheel])[2] - if backup is None: - backup_gid = findnss(grp.getgrnam, ["backup", "staff"])[2] - else: - backup_gid = findnss(grp.getgrnam, [backup])[2] if aci is None: aci = "# no aci for local ldb" @@ -1023,8 +1017,7 @@ def provision(setup_dir, message, session_info, if samdb_fill == FILL_FULL: setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn, root_uid=root_uid, nobody_uid=nobody_uid, - users_gid=users_gid, wheel_gid=wheel_gid, - backup_gid=backup_gid) + users_gid=users_gid, wheel_gid=wheel_gid) message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) -- cgit From c764791100079ed447c07ca6b99d33f9695255c3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 4 Apr 2008 12:25:19 +1100 Subject: Clean up provision and rootdse module to hard-code less stuff. In particular, allow for the server DN to be in a different site (possible outcome of a DRS replication). Andrew Bartlett (This used to be commit 9ee4e39fe178317f42fd9a0adceea24b55dfe0f1) --- source4/scripting/python/samba/provision.py | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6917aa1a54..02460070b4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -265,7 +265,8 @@ def provision_paths_from_lp(lp, dnsdomain): return paths def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, - rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): + rootdn=None, domaindn=None, configdn=None, schemadn=None, serverdn=None, + sitename=None): if hostname is None: hostname = socket.gethostname().split(".")[0].lower() @@ -332,6 +333,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= names.netbiosname = netbiosname names.hostname = hostname names.sitename = sitename + names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (netbiosname, sitename, configdn) return names @@ -543,9 +545,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, names.hostname, - names.dnsdomain, names.realm, names.rootdn, names.configdn, names.netbiosname, - names.sitename) + setup_samdb_rootdse(samdb, setup_path, names) if erase: message("Erasing data from partitions") @@ -656,25 +656,22 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) return idmap_ldb -def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname, - sitename): +def setup_samdb_rootdse(samdb, setup_path, names): """Setup the SamDB rootdse. :param samdb: Sam Database handle :param setup_path: Obtain setup path """ setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { - "SCHEMADN": schemadn, - "NETBIOSNAME": netbiosname, - "DNSDOMAIN": dnsdomain, - "DEFAULTSITE": sitename, - "REALM": realm, - "DNSNAME": "%s.%s" % (hostname, dnsdomain), - "DOMAINDN": domaindn, - "ROOTDN": rootdn, - "CONFIGDN": configdn, - "VERSION": samba.version(), + "SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DNSDOMAIN": names.dnsdomain, + "REALM": names.realm, + "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain), + "DOMAINDN": names.domaindn, + "ROOTDN": names.rootdn, + "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn, }) @@ -879,7 +876,8 @@ FILL_DRS = "DRS" def provision(setup_dir, message, session_info, credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, - rootdn=None, domaindn=None, schemadn=None, configdn=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, + serverdn=None, domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, @@ -932,7 +930,8 @@ def provision(setup_dir, message, session_info, names = guess_names(lp=lp, hostname=hostname, domain=domain, dnsdomain=realm, serverrole=serverrole, sitename=sitename, - rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn, + serverdn=serverdn) paths = provision_paths_from_lp(lp, names.dnsdomain) @@ -1064,12 +1063,13 @@ def provision(setup_dir, message, session_info, def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, + serverdn=None, domain=None, hostname=None, domainsid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, - ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): + ldap_backend=None, ldap_backend_type=None, sitename=None): def message(text): """print a message if quiet is not set.""" @@ -1077,7 +1077,7 @@ def provision_become_dc(setup_dir=None, provision(setup_dir, message, system_session(), None, smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, - rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, + rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, serverdn=serverdn, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); -- cgit From 14e443b868f56db0b29c3221c175f1a2cd2a8d1d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Apr 2008 16:13:42 +0200 Subject: Improve PEP8 (Python code style) compliancy a bit. (This used to be commit c7d388a6e2153234fe67daf1af094fc346e1da61) --- source4/scripting/python/samba/provision.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6917aa1a54..9151f29603 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -264,8 +264,10 @@ def provision_paths_from_lp(lp, dnsdomain): return paths -def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, - rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): + +def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, + serverrole=None, rootdn=None, domaindn=None, configdn=None, + schemadn=None, sitename=None): if hostname is None: hostname = socket.gethostname().split(".")[0].lower() @@ -336,7 +338,8 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= return names -def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir): +def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, + serverrole, targetdir): if targetdir is not None: if not os.path.exists(targetdir): os.mkdir(targetdir) @@ -423,6 +426,7 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) + def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, names, serverrole, ldap_backend=None, @@ -543,8 +547,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, names.hostname, - names.dnsdomain, names.realm, names.rootdn, names.configdn, names.netbiosname, + setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, + names.hostname, names.dnsdomain, names.realm, + names.rootdn, names.configdn, names.netbiosname, names.sitename) if erase: @@ -637,6 +642,7 @@ def setup_registry(path, setup_path, session_info, credentials, lp): assert os.path.exists(provision_reg) reg.diff_apply(provision_reg) + def setup_idmapdb(path, setup_path, session_info, credentials, lp): """Setup the idmap database. @@ -656,6 +662,7 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) return idmap_ldb + def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname, sitename): @@ -740,7 +747,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if serverrole == "domain controller": samdb.set_invocation_id(invocationid) - load_schema(setup_path, samdb, names.schemadn, names.netbiosname, names.configdn, names.sitename) + load_schema(setup_path, samdb, names.schemadn, names.netbiosname, + names.configdn, names.sitename) samdb.transaction_start() -- cgit From 3e97aa73c22ea036afb586b16a1d130ee46e5697 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Apr 2008 16:32:28 +0200 Subject: Simplify some code, fix style. (This used to be commit 1c983e4e4dfb93387791c36dc96696c4fffcfeb7) --- source4/scripting/python/samba/provision.py | 201 ++++++++++++++-------------- 1 file changed, 99 insertions(+), 102 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 9151f29603..f81cedc729 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -103,7 +103,7 @@ def check_install(lp, session_info, credentials): :param credentials: Credentials """ if lp.get("realm") == "": - raise Error("Realm empty") + raise Exception("Realm empty") ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) if len(ldb.search("(cn=Administrator)")) != 1: @@ -288,8 +288,8 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, realm = dnsdomain.upper() if lp.get("realm").upper() != realm: - raise Exception("realm '%s' in %s must match chosen realm '%s'" % - (lp.get("realm"), smbconf, realm)) + raise Exception("realm '%s' must match chosen realm '%s'" % + (lp.get("realm"), realm)) dnsdomain = dnsdomain.lower() @@ -299,7 +299,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, if domaindn is None: domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", + raise Exception("workgroup '%s' in smb.conf must match chosen domain '%s'", lp.get("workgroup"), domain) else: domain = netbiosname @@ -338,68 +338,52 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, return names -def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, - serverrole, targetdir): - if targetdir is not None: - if not os.path.exists(targetdir): - os.mkdir(targetdir) - if not os.path.exists(os.path.join(targetdir, "etc")): - os.mkdir(os.path.join(targetdir, "etc")) - - smbconf = os.path.join(targetdir, "etc", "smb.conf") +def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, + targetdir): + if hostname is None: + hostname = socket.gethostname().split(".")[0].lower() - # only install a new smb.conf if there isn't one there already + if serverrole is None: + serverrole = "standalone" - if not os.path.exists(smbconf): - if hostname is None: - hostname = socket.gethostname().split(".")[0].lower() + assert serverrole in ("domain controller", "member server", "standalone") + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member server": + smbconfsuffix = "member" + elif serverrole == "standalone": + smbconfsuffix = "standalone" - if serverrole is None: - serverrole = "standalone" + assert domain is not None + assert realm is not None - assert serverrole in ("domain controller", "member server", "standalone") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member server": - smbconfsuffix = "member" - elif serverrole == "standalone": - smbconfsuffix = "standalone" - - assert domain is not None - assert realm is not None - - default_lp = param.LoadParm() - #Load non-existant file - default_lp.load(smbconf) - - if targetdir is not None: - privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) - lockdir_line = "lock dir = " + os.path.abspath(targetdir) + default_lp = param.LoadParm() + #Load non-existant file + default_lp.load(smbconf) + + if targetdir is not None: + privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) + lockdir_line = "lock dir = " + os.path.abspath(targetdir) - default_lp.set("lock dir", os.path.abspath(targetdir)) - else: - privatedir_line = "" - lockdir_line = "" - - sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") - netlogon = os.path.join(sysvol, realm.lower(), "scripts") - - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), - smbconf, { - "HOSTNAME": hostname, - "DOMAIN": domain, - "REALM": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": netlogon, - "SYSVOLPATH": sysvol, - "PRIVATEDIR_LINE": privatedir_line, - "LOCKDIR_LINE": lockdir_line - }) + default_lp.set("lock dir", os.path.abspath(targetdir)) + else: + privatedir_line = "" + lockdir_line = "" - lp = param.LoadParm() - lp.load(smbconf) + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") + netlogon = os.path.join(sysvol, realm.lower(), "scripts") - return lp + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + smbconf, { + "HOSTNAME": hostname, + "DOMAIN": domain, + "REALM": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": netlogon, + "SYSVOLPATH": sysvol, + "PRIVATEDIR_LINE": privatedir_line, + "LOCKDIR_LINE": lockdir_line + }) def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, users_gid, wheel_gid): @@ -493,8 +477,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, schemadn_ldb = "schema.ldb" if ldap_backend is not None: schema_ldb = ldap_backend - schemadn_ldb = ldap_backend - + schemadn_ldb = ldap_backend + if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid", "paged_searches"] # We can handle linked attributes here, as we don't have directory-side subtree operations @@ -886,14 +870,15 @@ FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" def provision(setup_dir, message, session_info, - credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, - rootdn=None, domaindn=None, schemadn=None, configdn=None, - domain=None, hostname=None, hostip=None, hostip6=None, - domainsid=None, adminpass=None, krbtgtpass=None, domainguid=None, - policyguid=None, invocationid=None, machinepass=None, - dnspass=None, root=None, nobody=None, nogroup=None, users=None, - wheel=None, backup=None, aci=None, serverrole=None, - ldap_backend=None, ldap_backend_type=None, sitename=None): + credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, + realm=None, rootdn=None, domaindn=None, schemadn=None, + configdn=None, domain=None, hostname=None, hostip=None, + hostip6=None, domainsid=None, adminpass=None, krbtgtpass=None, + domainguid=None, policyguid=None, invocationid=None, + machinepass=None, dnspass=None, root=None, nobody=None, + nogroup=None, users=None, wheel=None, backup=None, aci=None, + serverrole=None, ldap_backend=None, ldap_backend_type=None, + sitename=None): """Provision samba4 :note: caution, this wipes all existing data! @@ -917,18 +902,9 @@ def provision(setup_dir, message, session_info, machinepass = misc.random_password(12) if dnspass is None: dnspass = misc.random_password(12) - if root is None: - root_uid = findnss(pwd.getpwnam, ["root"])[2] - else: - root_uid = findnss(pwd.getpwnam, [root])[2] - if nobody is None: - nobody_uid = findnss(pwd.getpwnam, ["nobody"])[2] - else: - nobody_uid = findnss(pwd.getpwnam, [nobody])[2] - if users is None: - users_gid = findnss(grp.getgrnam, ["users"])[2] - else: - users_gid = findnss(grp.getgrnam, [users])[2] + root_uid = findnss(pwd.getpwnam, [root or "root"])[2] + nobody_uid = findnss(pwd.getpwnam, [nobody or "nobody"])[2] + users_gid = findnss(grp.getgrnam, [users or "users"])[2] if wheel is None: wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] else: @@ -936,7 +912,17 @@ def provision(setup_dir, message, session_info, if aci is None: aci = "# no aci for local ldb" - lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + if smbconf is None: + os.makedirs(os.path.join(targetdir, "etc")) + smbconf = os.path.join(targetdir, "etc", "smb.conf") + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): + make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, + targetdir) + + lp = param.LoadParm() + lp.load(smbconf) names = guess_names(lp=lp, hostname=hostname, domain=domain, dnsdomain=realm, serverrole=serverrole, sitename=sitename, @@ -1080,7 +1066,7 @@ def provision_become_dc(setup_dir=None, ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): def message(text): - """print a message if quiet is not set.""" + """print a message if quiet is not set.""" print text provision(setup_dir, message, system_session(), None, @@ -1115,11 +1101,22 @@ def provision_backend(setup_dir=None, message=None, if root is None: root = findnss(pwd.getpwnam, ["root"])[0] - lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + if smbconf is None: + os.makedirs(os.path.join(targetdir, "etc")) + smbconf = os.path.join(targetdir, "etc", "smb.conf") + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): + make_smbconf(smbconf, setup_path, hostname, domain, realm, + serverrole, targetdir) + + lp = param.LoadParm() + lp.load(smbconf) names = guess_names(lp=lp, hostname=hostname, domain=domain, dnsdomain=realm, serverrole=serverrole, - rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + rootdn=rootdn, domaindn=domaindn, configdn=configdn, + schemadn=schemadn) paths = provision_paths_from_lp(lp, names.dnsdomain) @@ -1175,11 +1172,11 @@ def provision_backend(setup_dir=None, message=None, backend_schema = "99_ad.ldif" elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] - res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); - memberof_config = "# Generated from schema in " + schemadb_path + "\n"; - refint_attributes = ""; - for i in range (0, len(res)): + memberof_config = "# Generated from schema in " + schemadb_path + "\n"; + refint_attributes = ""; + for i in range (0, len(res)): linkid = res[i]["linkID"][0] linkid = str(int(linkid) + 1) expression = "(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))" @@ -1199,11 +1196,11 @@ memberof-dangling-error 32 """; - memberof_config = memberof_config + """ + memberof_config = memberof_config + """ overlay refint refint_attributes""" + refint_attributes + "\n"; - - setup_file(setup_path("slapd.conf"), paths.slapdconf, + + setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, "LDAPDIR": paths.ldapdir, "DOMAINDN": names.domaindn, @@ -1212,18 +1209,18 @@ refint_attributes""" + refint_attributes + "\n"; "LDAPMANAGERDN": names.ldapmanagerdn, "LDAPMANAGERPASS": adminpass, "MEMBEROF_CONFIG": memberof_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); @@ -1265,8 +1262,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip6_host_line = "" if hostip6 is not None: - hostip6_base_line = " IN AAAA " + hostip6 - hostip6_host_line = hostname + " IN AAAA " + hostip6 + hostip6_base_line = " IN AAAA " + hostip6 + hostip6_host_line = hostname + " IN AAAA " + hostip6 setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), -- cgit From 7c7880695b02df4cbe0faab959846c63d0cc0536 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 6 Apr 2008 00:40:01 +0200 Subject: More PEP8 compliancy. (This used to be commit d16b30d005933c9cc73f9196a3b77829d23687a0) --- source4/scripting/python/samba/provision.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f81cedc729..4d5a9cb1f1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -125,6 +125,10 @@ def findnss(nssfn, names): raise KeyError("Unable to find user/group %r" % names) +findnss_uid = lambda names: findnss(pwd.getpwnam, names)[2] +findnss_gid = lambda names: findnss(grp.getgrnam, names)[2] + + def open_ldb(session_info, credentials, lp, dbname): """Open a LDB, thrashing it if it is corrupt. @@ -293,7 +297,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, dnsdomain = dnsdomain.lower() - if (serverrole == "domain controller"): + if serverrole == "domain controller": if domain is None: domain = lp.get("workgroup") if domaindn is None: @@ -385,6 +389,7 @@ def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, "LOCKDIR_LINE": lockdir_line }) + def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, users_gid, wheel_gid): """setup reasonable name mappings for sam names to unix names. @@ -902,13 +907,13 @@ def provision(setup_dir, message, session_info, machinepass = misc.random_password(12) if dnspass is None: dnspass = misc.random_password(12) - root_uid = findnss(pwd.getpwnam, [root or "root"])[2] - nobody_uid = findnss(pwd.getpwnam, [nobody or "nobody"])[2] - users_gid = findnss(grp.getgrnam, [users or "users"])[2] + root_uid = findnss_uid([root or "root"]) + nobody_uid = findnss_uid([nobody or "nobody"]) + users_gid = findnss_gid([users or "users"]) if wheel is None: - wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] + wheel_gid = findnss_gid(["wheel", "adm"]) else: - wheel_gid = findnss(grp.getgrnam, [wheel])[2] + wheel_gid = findnss_gid([wheel]) if aci is None: aci = "# no aci for local ldb" @@ -925,8 +930,9 @@ def provision(setup_dir, message, session_info, lp.load(smbconf) names = guess_names(lp=lp, hostname=hostname, domain=domain, - dnsdomain=realm, serverrole=serverrole, sitename=sitename, - rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + dnsdomain=realm, serverrole=serverrole, + sitename=sitename, rootdn=rootdn, domaindn=domaindn, + configdn=configdn, schemadn=schemadn) paths = provision_paths_from_lp(lp, names.dnsdomain) @@ -936,7 +942,8 @@ def provision(setup_dir, message, session_info, if hostip6 is None: try: hostip6 = socket.getaddrinfo(names.hostname, None, socket.AF_INET6, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] - except socket.gaierror: pass + except socket.gaierror: + pass if serverrole is None: serverrole = lp.get("server role") -- cgit From 57bf8d2e33c69c8a642070c4c4ba8c00681e42cc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 Apr 2008 02:48:54 +0200 Subject: Add Python bindings for DFS. (This used to be commit 4319971ccb42618a3298a5f26f63fa4c9b255849) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 2ecad20b8e..eccf556ab1 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -35,6 +35,7 @@ extern void init_events(void); extern void inituuid(void); extern void init_net(void); extern void initecho(void); +extern void initdfs(void); extern void initwinreg(void); extern void initepmapper(void); extern void initinitshutdown(void); -- cgit From f253c3ad91d66aeb594e8088c462257277748263 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 Apr 2008 03:18:43 +0200 Subject: Add python bindings for unixinfo. (This used to be commit 068c2f858a0c7e325cb8a1f2ca36e32b31fe1f77) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index eccf556ab1..603c1df21c 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -47,6 +47,7 @@ static void initdcerpc_security(void) {} extern void initlsa(void); extern void initsvcctl(void); extern void initwkssvc(void); +extern void initunixinfo(void); extern void init_libcli_nbt(void); extern void init_libcli_smb(void); -- cgit From 5cf6c42658755f0a126a5bd6cdd9f215779b75a8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 Apr 2008 03:23:53 +0200 Subject: Add python bindings for drsuapi. (This used to be commit ba3f0312f0dda47fb16ed9b8eee3750b209e0dad) --- source4/scripting/python/modules.c | 1 + source4/scripting/python/pyrpc.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 603c1df21c..ba85994636 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -36,6 +36,7 @@ extern void inituuid(void); extern void init_net(void); extern void initecho(void); extern void initdfs(void); +extern void initdrsuapi(void); extern void initwinreg(void); extern void initepmapper(void); extern void initinitshutdown(void); diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h index 3a5d235cfc..f4d0f37c39 100644 --- a/source4/scripting/python/pyrpc.h +++ b/source4/scripting/python/pyrpc.h @@ -26,7 +26,7 @@ #define dom_sid2_Type dom_sid_Type #define dom_sid28_Type dom_sid_Type #define dom_sid2_Check dom_sid_Check -#define dom_sid28_Check dom_sid28_Check +#define dom_sid28_Check dom_sid_Check /* This macro is only provided by Python >= 2.3 */ #ifndef PyAPI_DATA -- cgit From 1f474f4a545752f7ac0ad402d01d1e768b973dbe Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 Apr 2008 03:29:12 +0200 Subject: Add trivial test for unixinfo interface. (This used to be commit b6b7171f70114bd27ca8db09964c65cacb9cea92) --- .../scripting/python/samba/tests/dcerpc/unix.py | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 source4/scripting/python/samba/tests/dcerpc/unix.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py new file mode 100644 index 0000000000..99c84c08da --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -0,0 +1,30 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# + +import unixinfo +import unittest +from samba.tests import get_loadparm + +class UnixinfoTests(unittest.TestCase): + def setUp(self): + self.conn = unixinfo.unixinfo("ncalrpc:", get_loadparm()) + + def test_getpwuid(self): + (count, infos) = self.conn.GetPWUid(1, [0]) + self.assertEquals(1, len(infos)) -- cgit From 8db14bf26b96f47b8f937f6016d18d947b68467e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 Apr 2008 05:16:07 +0200 Subject: Add manually written Python binding for libnet_Join. (This used to be commit 374654b43d9f9e8381991cedc433ce410a914f7a) --- source4/scripting/python/modules.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index ba85994636..6cd975c1a9 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -42,6 +42,7 @@ extern void initepmapper(void); extern void initinitshutdown(void); static void initdcerpc_misc(void) {} extern void initmgmt(void); +extern void initnet(void); extern void initatsvc(void); extern void initsamr(void); static void initdcerpc_security(void) {} -- cgit From b2805c50eecddfa4cbd0945e713567eddce05895 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 8 Apr 2008 17:28:25 +1000 Subject: Re-add support for the --ldap-backend-port option to provision-backend This option allows Fedora DS multi-master replication to work. I've tried to update the wiki and scripts to the largely consistant with each other. Andrew Bartlett (This used to be commit 42393c830733b2cc99ebccdafe944fcf3d82734f) --- source4/scripting/python/samba/provision.py | 42 ++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 02460070b4..80dcd522df 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -288,7 +288,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= if lp.get("realm").upper() != realm: raise Exception("realm '%s' in %s must match chosen realm '%s'" % - (lp.get("realm"), smbconf, realm)) + (lp.get("realm"), lp.configfile(), realm)) dnsdomain = dnsdomain.lower() @@ -1045,8 +1045,8 @@ def provision(setup_dir, message, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - message("Once the above files are installed, your server will be ready to use") - message("Server Type: %s" % serverrole) + message("Once the above files are installed, your Samba4 server will be ready to use") + message("Server Role: %s" % serverrole) message("Hostname: %s" % names.hostname) message("NetBIOS Domain: %s" % names.domain) message("DNS Domain: %s" % names.dnsdomain) @@ -1096,7 +1096,7 @@ def provision_backend(setup_dir=None, message=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, - ldap_backend_type=None): + ldap_backend_type=None, ldap_backend_port=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1144,7 +1144,12 @@ def provision_backend(setup_dir=None, message=None, {"SCHEMADN": names.schemadn}) if ldap_backend_type == "fedora-ds": - setup_file(setup_path("fedora-ds.inf"), paths.fedoradsinf, + if ldap_backend_port is not None: + serverport = "ServerPort=%d" % ldap_backend_port + else: + serverport = "" + + setup_file(setup_path("fedorads.inf"), paths.fedoradsinf, {"ROOT": root, "HOSTNAME": hostname, "DNSDOMAIN": names.dnsdomain, @@ -1152,19 +1157,18 @@ def provision_backend(setup_dir=None, message=None, "DOMAINDN": names.domaindn, "LDAPMANAGERDN": names.ldapmanagerdn, "LDAPMANAGERPASS": adminpass, - "SERVERPORT": ""}) + "SERVERPORT": serverport}) - setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, + setup_file(setup_path("fedorads-partitions.ldif"), paths.fedoradspartitions, {"CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, }) - setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, - {"CONFIGDN": names.configdn, - "SCHEMADN": names.schemadn, - }) mapping = "schema-map-fedora-ds-1.0" backend_schema = "99_ad.ldif" + + slapdcommand="Initailise Fedora DS with: setup-ds.pl --file=%s" % paths.fedoradsinf + elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); @@ -1215,14 +1219,26 @@ refint_attributes""" + refint_attributes + "\n"; ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) - + if ldap_backend_port is not None: + server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port + else: + server_port_string = "" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); os.system(schema_command) + message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ( ldap_backend_type) ) + message("Server Role: %s" % serverrole) + message("Hostname: %s" % names.hostname) + message("DNS Domain: %s" % names.dnsdomain) + message("Base DN: %s" % names.domaindn) + message("LDAP admin DN: %s" % names.ldapmanagerdn) + message("LDAP admin password: %s" % adminpass) + message(slapdcommand) + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. -- cgit From ad823b04dab468379c7b42a8b849bb8a310cfb69 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 8 Apr 2008 14:58:38 +0200 Subject: Remove length arguments, add tests for unixinfo.GidToSid and unixinfo.UidToSid. (This used to be commit cae61e32e5b61a02c2986b74bd1d7e58460b1e80) --- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 2 +- source4/scripting/python/samba/tests/dcerpc/unix.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 8c1a8bec71..484af9490c 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -30,7 +30,7 @@ class RpcEchoTests(unittest.TestCase): self.assertEquals(2, self.conn.AddOne(1)) def test_echodata(self): - self.assertEquals([1,2,3], self.conn.EchoData(3, [1, 2, 3])) + self.assertEquals([1,2,3], self.conn.EchoData([1, 2, 3])) def test_call(self): self.assertEquals(u"foobar", self.conn.TestCall(u"foobar")) diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py index 99c84c08da..b2577ec898 100644 --- a/source4/scripting/python/samba/tests/dcerpc/unix.py +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -26,5 +26,11 @@ class UnixinfoTests(unittest.TestCase): self.conn = unixinfo.unixinfo("ncalrpc:", get_loadparm()) def test_getpwuid(self): - (count, infos) = self.conn.GetPWUid(1, [0]) - self.assertEquals(1, len(infos)) + infos = self.conn.GetPWUid(range(512)) + self.assertEquals(512, len(infos)) + + def test_gidtosid(self): + self.conn.GidToSid(1000) + + def test_uidtosid(self): + self.conn.UidToSid(1000) -- cgit From ac10ac62c1e9b64280f3566425af08210d57bb04 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 9 Apr 2008 03:51:41 +0200 Subject: Add docstring, PEP8. (This used to be commit f8cac3735c9a19baa313c4b61abee144da303ce1) --- source4/scripting/python/samba/provision.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 80dcd522df..c9cdcdb768 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -264,9 +264,11 @@ def provision_paths_from_lp(lp, dnsdomain): return paths + def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, rootdn=None, domaindn=None, configdn=None, schemadn=None, serverdn=None, sitename=None): + """Guess configuration settings to use.""" if hostname is None: hostname = socket.gethostname().split(".")[0].lower() @@ -400,6 +402,7 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol return lp + def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, users_gid, wheel_gid): """setup reasonable name mappings for sam names to unix names. @@ -425,6 +428,7 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) + def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, names, serverrole, ldap_backend=None, @@ -637,6 +641,7 @@ def setup_registry(path, setup_path, session_info, credentials, lp): assert os.path.exists(provision_reg) reg.diff_apply(provision_reg) + def setup_idmapdb(path, setup_path, session_info, credentials, lp): """Setup the idmap database. @@ -656,6 +661,7 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) return idmap_ldb + def setup_samdb_rootdse(samdb, setup_path, names): """Setup the SamDB rootdse. @@ -1060,6 +1066,7 @@ def provision(setup_dir, message, session_info, result.samdb = samdb return result + def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, @@ -1081,7 +1088,11 @@ def provision_become_dc(setup_dir=None, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); -def setup_db_config(setup_path, file, dbdir): +def setup_db_config(setup_path, dbdir): + """Setup a Berkeley database. + + :param setup_path: Setup path function. + :param dbdir: Database directory.""" if not os.path.isdir(os.path.join(dbdir, "bdb-logs")): os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700); if not os.path.isdir(os.path.join(dbdir, "tmp")): @@ -1211,12 +1222,11 @@ refint_attributes""" + refint_attributes + "\n"; setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "schema")) mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") if ldap_backend_port is not None: -- cgit From 9d2948f4bd5f196904d27c67bf4f0baf7eaefcb0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 Apr 2008 14:57:57 +1000 Subject: Don't fill in the secrets DB unless we make the entries. Leave filling in (we still initialise it) the secrets DB for the join or vampire code. Andrew Bartlett (This used to be commit c93208c13ce91b334eadf0ea02fa41354e761e97) --- source4/scripting/python/samba/provision.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c9cdcdb768..7b4fdb772c 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1011,13 +1011,6 @@ def provision(setup_dir, message, session_info, os.makedirs(os.path.join(policy_path, "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, - credentials=credentials, lp=lp) - secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=names.realm, - netbiosname=names.netbiosname, domainsid=domainsid, - keytab_path=paths.keytab, samdb_url=paths.samdb, - dns_keytab_path=paths.dns_keytab, dnspass=dnspass, - machinepass=machinepass, dnsdomain=names.dnsdomain) if samdb_fill == FILL_FULL: setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn, @@ -1029,6 +1022,14 @@ def provision(setup_dir, message, session_info, # Only make a zone file on the first DC, it should be replicated with DNS replication if serverrole == "domain controller": + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=names.realm, + netbiosname=names.netbiosname, domainsid=domainsid, + keytab_path=paths.keytab, samdb_url=paths.samdb, + dns_keytab_path=paths.dns_keytab, dnspass=dnspass, + machinepass=machinepass, dnsdomain=names.dnsdomain) + samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) -- cgit From b202b6e7d45cebd9b34c8d319e75f423291b30a0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 Apr 2008 15:32:49 +1000 Subject: Fix up provision to specify SERVERDN in more places. Andrew Bartlett (This used to be commit d01d542502f25d6c731204ecb3d33720a1706581) --- source4/scripting/python/samba/provision.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 7b4fdb772c..ff76681c13 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -690,6 +690,7 @@ def setup_self_join(samdb, names, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, "DOMAINDN": names.domaindn, + "SERVERDN": names.serverdn, "INVOCATIONID": invocationid, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, @@ -773,6 +774,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn, "POLICYGUID": policyguid, "DOMAINDN": names.domaindn, "DOMAINGUID_MOD": domainguid_mod, @@ -803,6 +805,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn }) message("Setting up sam.ldb Samba4 schema") @@ -821,6 +824,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "DOMAIN": names.domain, "SCHEMADN": names.schemadn, "DOMAINDN": names.domaindn, + "SERVERDN": names.serverdn }) message("Setting up display specifiers") @@ -845,6 +849,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn }) if fill == FILL_FULL: -- cgit From ad8e3e41923e20d401294eccd4da028e0f40c904 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 10 Apr 2008 05:23:17 +0200 Subject: Add infrastructure for returning ProvisionResult in C provision code. (This used to be commit 98c3d34eb233be284e8c8994cca337be25c72968) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c9cdcdb768..ccf67a0b4a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1082,7 +1082,7 @@ def provision_become_dc(setup_dir=None, """print a message if quiet is not set.""" print text - provision(setup_dir, message, system_session(), None, + return provision(setup_dir, message, system_session(), None, smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, serverdn=serverdn, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); -- cgit From 393007315d56d72cd4ebccc204da703b27eb968b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Apr 2008 19:04:43 +1000 Subject: Far less cryptic traceback when you have an existing smb.conf When the user has an existing smb.conf, but no [netlogon] or [sysvol] share, the provision script would trigger a traceback. While we still need to abort in this situation, we do so now with a useful error. Andrew Bartlett (This used to be commit 10a8b7ea487f9725f69b02c4dd9cf5e1f67a23ab) --- source4/scripting/python/samba/provision.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 16b1eb2156..4f264b6fc9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -87,6 +87,7 @@ class ProvisionNames: self.domain = None self.hostname = None self.sitename = None + self.smbconf = None class ProvisionResult: def __init__(self): @@ -262,6 +263,8 @@ def provision_paths_from_lp(lp, dnsdomain): paths.netlogon = lp.get("path", "netlogon") + paths.smbconf = lp.configfile() + return paths @@ -1009,12 +1012,24 @@ def provision(setup_dir, message, session_info, ldap_backend_type=ldap_backend_type) if lp.get("server role") == "domain controller": - policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", - "{" + policyguid + "}") - os.makedirs(policy_path, 0755) - os.makedirs(os.path.join(policy_path, "Machine"), 0755) - os.makedirs(os.path.join(policy_path, "User"), 0755) - if not os.path.isdir(paths.netlogon): + if paths.netlogon is None: + message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.") + message("Please either remove %s or see the template at %s" % + ( paths.smbconf, setup_path("provision.smb.conf.dc"))) + assert(paths.netlogon is not None) + + if paths.sysvol is None: + message("Existing smb.conf does not have a [sysvol] share, but you are configuring a DC.") + message("Please either remove %s or see the template at %s" % + (paths.smbconf, setup_path("provision.smb.conf.dc"))) + assert(paths.sysvol is not None) + + policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", + "{" + policyguid + "}") + os.makedirs(policy_path, 0755) + os.makedirs(os.path.join(policy_path, "Machine"), 0755) + os.makedirs(os.path.join(policy_path, "User"), 0755) + if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) if samdb_fill == FILL_FULL: -- cgit From e44f0e7b75a15e61427a6520999d0d79b78e9d2a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Apr 2008 19:33:52 +1000 Subject: Don't reopen the sam.ldb again Andrew Bartlett (This used to be commit b51b8a2d846284de4dff736fc18cf747c188de96) --- source4/scripting/python/samba/provision.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f264b6fc9..a8d188e7a3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -741,8 +741,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, return samdb message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(path, session_info=session_info, - credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) if serverrole == "domain controller": samdb.set_invocation_id(invocationid) -- cgit From 434e625e45a03889596999eb4301bb54128c31a9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Apr 2008 11:48:43 +0200 Subject: Add in a way to get at the private_path() function from python Andrew Bartlett (This used to be commit 416d2e3a5233f0c243e45857cfda5126c34ac265) --- source4/scripting/python/misc.i | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index e04e6a6906..6fa3bc93e3 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -78,3 +78,8 @@ bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid) return samdb_set_ntds_invocation_id(ldb, &invocation_id_in); } %} + +char *private_path(TALLOC_CTX* mem_ctx, + struct loadparm_context *lp_ctx, + const char *name); + -- cgit From 5a37b3fc5d42beffaf4bdca70b1f0c5f80f92280 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Apr 2008 11:51:02 +0200 Subject: Fix newuser and setpassword scripts, and port to idmap. The new idmap world does not use the unixUser any more, so we need to set up the entry (if wanted) in the idmap database. Users without a backing unix user will get an allocated uid by idmap later. Andrew Bartlett (This used to be commit 8bd8bc1475ddf22d4702dcd17028a9043a5e629f) --- source4/scripting/python/samba/idmap.py | 7 +++++++ source4/scripting/python/samba/samdb.py | 28 +++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py index 355565968a..16efcd0470 100644 --- a/source4/scripting/python/samba/idmap.py +++ b/source4/scripting/python/samba/idmap.py @@ -21,6 +21,7 @@ """Convenience functions for using the idmap database.""" import samba +import misc import ldb class IDmapDB(samba.Ldb): @@ -37,11 +38,17 @@ class IDmapDB(samba.Ldb): :param url: URL of the database. """ + self.lp = lp + super(IDmapDB, self).__init__(session_info=session_info, credentials=credentials, modules_dir=modules_dir, lp=lp) if url: self.connect(url) + else: + self.connect(lp.get("idmap database")) + def connect(self, url): + super(IDmapDB, self).connect(misc.private_path(self.lp, url)) def setup_name_mapping(self, sid, type, unixid): """Setup a mapping between a sam name and a unix name. diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index bc3eef7879..198d1e9f5c 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -25,20 +25,29 @@ import samba import misc import ldb +from samba.idmap import IDmapDB +import pwd class SamDB(samba.Ldb): """The SAM database.""" + def __init__(self, url=None, session_info=None, credentials=None, modules_dir=None, lp=None): """Open the Sam Database. :param url: URL of the database. """ + self.lp = lp super(SamDB, self).__init__(session_info=session_info, credentials=credentials, modules_dir=modules_dir, lp=lp) assert misc.dsdb_set_global_schema(self) == 0 if url: self.connect(url) + else: + self.connect(lp.get("sam database")) + + def connect(self, url): + super(SamDB, self).connect(misc.private_path(self.lp, url)) def add_foreign(self, domaindn, sid, desc): """Add a foreign security principle.""" @@ -101,10 +110,27 @@ userAccountControl: %u # now the real work self.add({"dn": user_dn, "sAMAccountName": username, - "unixName": unixname, "sambaPassword": password, "objectClass": "user"}) + res = self.search(user_dn, scope=ldb.SCOPE_BASE, + expression="objectclass=*", + attrs=["objectSid"]) + assert(len(res) == 1) + user_sid = self.schema_format_value("objectSid", res[0]["objectSid"][0]) + + + try: + idmap = IDmapDB(lp=self.lp) + + user = pwd.getpwnam(unixname) + # setup ID mapping for this UID + + idmap.setup_name_mapping(user_sid, idmap.TYPE_UID, user[2]) + + except KeyError: + pass + # modify the userAccountControl to remove the disabled bit self.enable_account(user_dn) self.transaction_commit() -- cgit From ca78fa8cae96099055a6ae7a0963c2b2789f2b87 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Apr 2008 11:53:28 +0200 Subject: Re-run SWIG (This used to be commit 2f8010582607ad7389cac3de4945ea0ee46941b3) --- source4/scripting/python/misc.py | 1 + source4/scripting/python/misc_wrap.c | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 2fc7fe37e7..f1da4c687a 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -71,5 +71,6 @@ version = _misc.version dsdb_set_global_schema = _misc.dsdb_set_global_schema ldb_register_samba_handlers = _misc.ldb_register_samba_handlers dsdb_set_ntds_invocation_id = _misc.dsdb_set_ntds_invocation_id +private_path = _misc.private_path diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 579d1f379f..4944515d15 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -3153,6 +3153,50 @@ fail: } +SWIGINTERN PyObject *_wrap_private_path(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; + struct loadparm_context *arg2 = (struct loadparm_context *) 0 ; + char *arg3 = (char *) 0 ; + char *result = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + int res3 ; + char *buf3 = 0 ; + int alloc3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "lp_ctx",(char *) "name", NULL + }; + + arg2 = loadparm_init(NULL); + arg1 = NULL; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|OO:private_path",kwnames,&obj0,&obj1)) SWIG_fail; + if (obj0) { + res2 = SWIG_ConvertPtr(obj0, &argp2,SWIGTYPE_p_loadparm_context, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "private_path" "', argument " "2"" of type '" "struct loadparm_context *""'"); + } + arg2 = (struct loadparm_context *)(argp2); + } + if (obj1) { + res3 = SWIG_AsCharPtrAndSize(obj1, &buf3, NULL, &alloc3); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "private_path" "', argument " "3"" of type '" "char const *""'"); + } + arg3 = (char *)(buf3); + } + result = (char *)private_path(arg1,arg2,(char const *)arg3); + resultobj = SWIG_FromCharPtr((const char *)result); + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return resultobj; +fail: + if (alloc3 == SWIG_NEWOBJ) free((char*)buf3); + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -3164,6 +3208,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"dsdb_set_global_schema", (PyCFunction) _wrap_dsdb_set_global_schema, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"dsdb_set_ntds_invocation_id", (PyCFunction) _wrap_dsdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"private_path", (PyCFunction) _wrap_private_path, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; -- cgit From f800cf250f079ab1e1bc1051c34d1d1061187447 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 14:51:57 +0200 Subject: Move standard make compilation rules to build/make. (This used to be commit ceda3312a98b069d0711f3cb33de3ae71e91ebaa) --- source4/scripting/python/config.mk | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 09c77813ca..22e9a2ff7b 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -15,24 +15,9 @@ OBJ_FILES = uuidmodule.o PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i -# Swig extensions -swig:: pythonmods - -.SUFFIXES: _wrap.c .i - -.i_wrap.c: - [ "$(SWIG)" = "no" ] || $(SWIG) -O -Wall -I$(srcdir)/scripting/swig -python -keyword $< - -realdistclean:: - @echo "Removing SWIG output files" - # FIXME: Remove _wrap.c files - -pythonmods:: $(PYTHON_DSOS) $(PYTHON_PYS) - PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py -pydoctor:: pythonmods - LD_LIBRARY_PATH=bin/shared PYTHONPATH=bin/python pydoctor --project-name=Samba --make-html --docformat=restructuredtext --add-package scripting/python/samba/ $(addprefix --add-module , $(PYDOCTOR_MODULES)) +pythonmods:: $(PYTHON_PYS) $(PYTHON_MODS) bin/python/%.py: mkdir -p $(@D) -- cgit From e9017ba418202b4b191c5a9ad4a96857558ce606 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 17:22:58 +0200 Subject: Use _OBJ_FILES variables in a couple more places. (This used to be commit 92856d5054106894b65cd1a1b5119c0facfc4cff) --- source4/scripting/python/config.mk | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 22e9a2ff7b..cb03bfaeea 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,15 +1,18 @@ [BINARY::smbpython] PRIVATE_DEPENDENCIES = LIBPYTHON -OBJ_FILES = smbpython.o + +smbpython_OBJ_FILES = smbpython.o [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON INIT_FUNCTION_SENTINEL = { NULL, NULL } -OBJ_FILES = modules.o pytalloc.o + +LIBPYTHON_OBJ_FILES = modules.o pytalloc.o [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR -OBJ_FILES = uuidmodule.o + +python_uuid_OBJ_FILES = uuidmodule.o [PYTHON::python_misc] PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS -- cgit From 02f3695897dddb013fc1268a4f1a852cd4a3465e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 18:30:07 +0200 Subject: Add convenience TestCase class for testing RPC interfaces. (This used to be commit 2f19f981449bf6f4d29f231259817c8b66104a9b) --- source4/scripting/python/samba/tests/__init__.py | 7 +++++++ source4/scripting/python/samba/tests/dcerpc/registry.py | 9 ++++----- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index c8673d3fae..ceb7dd23f3 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -90,3 +90,10 @@ def get_loadparm(): lp = param.LoadParm() lp.load(os.getenv("SMB_CONF_PATH")) return lp + +class RpcInterfaceTestCase(unittest.TestCase): + def get_loadparm(self): + return get_loadparm() + + def get_credentials(self): + return None diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 147acc5098..1afdc582a7 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -18,14 +18,13 @@ # import winreg -from param import LoadParm import unittest -from samba.tests import get_loadparm +from samba.tests import RpcInterfaceTestCase -class WinregTests(unittest.TestCase): +class WinregTests(RpcInterfaceTestCase): def setUp(self): - lp_ctx = get_loadparm() - self.conn = winreg.winreg("ncalrpc:", lp_ctx) + self.conn = winreg.winreg("ncalrpc:", self.get_loadparm(), + self.get_credentials()) def get_hklm(self): return self.conn.OpenHKLM(None, -- cgit From c1d9167fbcc5df9da4f603084ad732915c68c0c0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 19:01:32 +0200 Subject: Also look in the environment for smb.conf path. (This used to be commit 8be7d93735a357a3b73a1c4413d6fd9ec09b7555) --- source4/scripting/python/samba/getopt.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 82cb004b62..7ec684a9d6 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -35,12 +35,14 @@ class SambaOptions(optparse.OptionGroup): self._configfile = arg def get_loadparm(self): - import param + import os, param lp = param.LoadParm() - if self._configfile is None: - lp.load_default() - else: + if self._configfile is not None: lp.load(self._configfile) + elif os.getenv("SMB_CONF_PATH") is not None: + lp.load(os.getenv("SMB_CONF_PATH")) + else: + lp.load_default() return lp class VersionOptions(optparse.OptionGroup): -- cgit From 1bcbc4afcf2f9984081652c1fbe50d329c86b3b5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 19:13:41 +0200 Subject: Allow command line options in the subunitrun script. (This used to be commit 524ec0796efebd48e7b5b2eb5fcc92ecc13c0071) --- source4/scripting/python/samba/tests/__init__.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index ceb7dd23f3..e29b4a87d5 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -85,15 +85,13 @@ class LdbExtensionTests(TestCaseInTempDir): os.unlink(path) -def get_loadparm(): - import param - lp = param.LoadParm() - lp.load(os.getenv("SMB_CONF_PATH")) - return lp +cmdline_loadparm = None +cmdline_credentials = None class RpcInterfaceTestCase(unittest.TestCase): def get_loadparm(self): - return get_loadparm() + assert cmdline_loadparm is not None + return cmdline_loadparm def get_credentials(self): - return None + return cmdline_credentials -- cgit From 2cdfaedee203a726bddfb46fb10d9604de32a05f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 19:20:43 +0200 Subject: Make sure credentials are specified when running the Python winreg RPC tests. (This used to be commit 280339e3d126f5c72dc271051b72839fde0c5c9f) --- source4/scripting/python/samba/tests/dcerpc/registry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 1afdc582a7..05ac7c66ee 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -23,8 +23,8 @@ from samba.tests import RpcInterfaceTestCase class WinregTests(RpcInterfaceTestCase): def setUp(self): - self.conn = winreg.winreg("ncalrpc:", self.get_loadparm(), - self.get_credentials()) + lp = self.get_loadparm() + self.conn = winreg.winreg("ncalrpc:", lp, self.get_credentials()) def get_hklm(self): return self.conn.OpenHKLM(None, -- cgit From a15b6f1606e1c761c2c4037b734137e97f00489f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 20:00:04 +0200 Subject: Fix unresolved symbols. (This used to be commit 8573e828d1b68c47b3c1754e9be230b2e78d9d52) --- source4/scripting/python/config.mk | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index cb03bfaeea..2f010644b1 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,23 +1,25 @@ [BINARY::smbpython] PRIVATE_DEPENDENCIES = LIBPYTHON -smbpython_OBJ_FILES = smbpython.o +smbpython_OBJ_FILES = scripting/python/smbpython.o [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON INIT_FUNCTION_SENTINEL = { NULL, NULL } -LIBPYTHON_OBJ_FILES = modules.o pytalloc.o +LIBPYTHON_OBJ_FILES = $(addprefix scripting/python/, modules.o pytalloc.o) [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR -python_uuid_OBJ_FILES = uuidmodule.o +python_uuid_OBJ_FILES = scripting/python/uuidmodule.o [PYTHON::python_misc] PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i +python_misc_OBJ_FILES = scripting/python/misc_wrap.o + PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py pythonmods:: $(PYTHON_PYS) $(PYTHON_MODS) -- cgit From 1b5f32128d1867829647a4e1f20b6e8363444f66 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 23:28:14 +0200 Subject: Use RpcInterfaceTestCase everywhere. (This used to be commit 799095b4e567f4495adf7d1d7bcb81dda6782959) --- source4/scripting/python/samba/tests/dcerpc/registry.py | 4 ++-- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 7 +++---- source4/scripting/python/samba/tests/dcerpc/sam.py | 7 +++---- source4/scripting/python/samba/tests/dcerpc/unix.py | 7 +++---- source4/scripting/python/samba/tests/provision.py | 2 +- source4/scripting/python/samba/tests/samdb.py | 4 ++-- 6 files changed, 14 insertions(+), 17 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 05ac7c66ee..1afdc582a7 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -23,8 +23,8 @@ from samba.tests import RpcInterfaceTestCase class WinregTests(RpcInterfaceTestCase): def setUp(self): - lp = self.get_loadparm() - self.conn = winreg.winreg("ncalrpc:", lp, self.get_credentials()) + self.conn = winreg.winreg("ncalrpc:", self.get_loadparm(), + self.get_credentials()) def get_hklm(self): return self.conn.OpenHKLM(None, diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 484af9490c..6c43632d97 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -19,12 +19,11 @@ import echo import unittest -from samba.tests import get_loadparm +from samba.tests import RpcInterfaceTestCase -class RpcEchoTests(unittest.TestCase): +class RpcEchoTests(RpcInterfaceTestCase): def setUp(self): - lp_ctx = get_loadparm() - self.conn = echo.rpcecho("ncalrpc:", lp_ctx) + self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm()) def test_addone(self): self.assertEquals(2, self.conn.AddOne(1)) diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index 96348f2f69..8ef12dad86 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -18,12 +18,11 @@ # import samr -import unittest -from samba.tests import get_loadparm +from samba.tests import RpcInterfaceTestCase -class SamrTests(unittest.TestCase): +class SamrTests(RpcInterfaceTestCase): def setUp(self): - self.conn = samr.samr("ncalrpc:", get_loadparm()) + self.conn = samr.samr("ncalrpc:", self.get_loadparm()) def test_connect5(self): (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py index b2577ec898..bfddfdc7ec 100644 --- a/source4/scripting/python/samba/tests/dcerpc/unix.py +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -18,12 +18,11 @@ # import unixinfo -import unittest -from samba.tests import get_loadparm +from samba.tests import RpcInterfaceTestCase -class UnixinfoTests(unittest.TestCase): +class UnixinfoTests(RpcInterfaceTestCase): def setUp(self): - self.conn = unixinfo.unixinfo("ncalrpc:", get_loadparm()) + self.conn = unixinfo.unixinfo("ncalrpc:", self.get_loadparm()) def test_getpwuid(self): infos = self.conn.GetPWUid(range(512)) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 514582cbe4..b9e0e16d3c 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -24,7 +24,7 @@ from ldb import Dn import param import unittest -lp = samba.tests.get_loadparm() +lp = samba.tests.cmdline_loadparm setup_dir = "setup" def setup_path(file): diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 3745dba6fc..0e175bf936 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -21,7 +21,7 @@ from credentials import Credentials import os from samba.provision import setup_samdb from samba.samdb import SamDB -from samba.tests import get_loadparm, TestCaseInTempDir +from samba.tests import cmdline_loadparm, TestCaseInTempDir import security from unittest import TestCase import uuid @@ -43,7 +43,7 @@ class SamDBTestCase(TestCaseInTempDir): hostguid = uuid.random() path = os.path.join(self.tempdir, "samdb.ldb") self.samdb = setup_samdb(path, setup_path, system_session(), creds, - get_loadparm(), schemadn, configdn, + cmdline_loadparm, schemadn, configdn, self.domaindn, "example.com", "EXAMPLE.COM", "FOO", lambda x: None, "foo", domaindn, False, domainsid, "# no aci", domainguid, -- cgit From d04926914ad0d9ecd7dee3e156198d6baf788598 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 01:40:32 +0200 Subject: Fix the build. (This used to be commit ecaa5bb83b5cf319718d15aff96152d70fa19f7f) --- source4/scripting/python/config.mk | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 2f010644b1..59f628fe18 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -22,18 +22,8 @@ python_misc_OBJ_FILES = scripting/python/misc_wrap.o PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py -pythonmods:: $(PYTHON_PYS) $(PYTHON_MODS) - -bin/python/%.py: - mkdir -p $(@D) - cp $< $@ - installpython:: pythonmods @$(SHELL) $(srcdir)/script/installpython.sh \ $(INSTALLPERMS) \ $(DESTDIR)$(PYTHONDIR) \ scripting/python bin/python - -clean:: - @echo "Removing python modules" - @rm -rf bin/python/* -- cgit From 1a8bfba5452f7b72d9f0b2a178f7e8a66557c463 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 12:15:43 +0200 Subject: Fix warnings. (This used to be commit 88013ca9775a6ff5e5a393f9d8238dbcd197f26f) --- source4/scripting/python/uuidmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c index cd9a1cb4d5..18cfb6ce32 100644 --- a/source4/scripting/python/uuidmodule.c +++ b/source4/scripting/python/uuidmodule.c @@ -27,7 +27,7 @@ static PyObject *uuid_random(PyObject *self, PyObject *args) PyObject *pyobj; char *str; - if (!PyArg_ParseTuple(args, (char *)"")) + if (!PyArg_ParseTuple(args, "")) return NULL; guid = GUID_random(); @@ -52,7 +52,7 @@ static PyMethodDef methods[] = { void inituuid(void) { - PyObject *mod = Py_InitModule3((char *)"uuid", methods, "UUID helper routines"); + PyObject *mod = Py_InitModule3("uuid", methods, "UUID helper routines"); if (mod == NULL) return; } -- cgit From 983b66b8f16ba4e06a8b239e5c4191e3f0245481 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 12:51:31 +0200 Subject: Saner names for Python objects. (This used to be commit f4de8d2c1c956bc85b91dc7aab20e5e7671f51bc) --- source4/scripting/python/pytalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index d8d3efe69c..aa0ae9bf90 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -39,7 +39,7 @@ PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, PyObject *py_talloc_default_repr(PyObject *py_obj) { py_talloc_Object *obj = (py_talloc_Object *)py_obj; + PyTypeObject *type = (PyTypeObject*)PyObject_Type((PyObject *)obj); - return PyString_FromFormat("", - talloc_get_name(obj->talloc_ctx)); + return PyString_FromFormat("<%s>", type->tp_name); } -- cgit From fd52fe86169ddc0adda2d1cd97215c58d06f93c4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 14:32:13 +0200 Subject: Fix pointers when pushing strings to python during pidl generation. (This used to be commit ca72187b3e71a037780d42a57e46b60e75f724f6) --- source4/scripting/python/samba/tests/dcerpc/unix.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py index bfddfdc7ec..43978ac9dc 100644 --- a/source4/scripting/python/samba/tests/dcerpc/unix.py +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -27,6 +27,8 @@ class UnixinfoTests(RpcInterfaceTestCase): def test_getpwuid(self): infos = self.conn.GetPWUid(range(512)) self.assertEquals(512, len(infos)) + self.assertEquals("", infos[0].shell) + self.assertEquals("", infos[0].homedir) def test_gidtosid(self): self.conn.GidToSid(1000) -- cgit From f8f4856ab7330db865d1a35abff3ccaf2ac277ba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Apr 2008 15:52:52 +0200 Subject: Fix provision-backend script Andrew Bartlett (This used to be commit ee6e4f8da229ddeca856a6db94236367aae06f63) --- source4/scripting/python/samba/provision.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a8d188e7a3..45965a2429 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1166,6 +1166,7 @@ def provision_backend(setup_dir=None, message=None, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": DEFAULTSITE, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn }) setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"), @@ -1241,9 +1242,9 @@ refint_attributes""" + refint_attributes + "\n"; setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "schema")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "user")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "config")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "schema")) mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From 2ddd23a8754258b7322f37a0e0b97587b23f338b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Apr 2008 17:10:47 +0200 Subject: Re-add 'db' subdirectory for LDAP backend provision Andrew Bartlett (This used to be commit 19890c0d15adf4f099365f276a4bfdd3f4de52b6) --- source4/scripting/python/samba/provision.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 45965a2429..0e8840646c 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1242,9 +1242,9 @@ refint_attributes""" + refint_attributes + "\n"; setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, "user")) - setup_db_config(setup_path, os.path.join(paths.ldapdir, "config")) - setup_db_config(setup_path, os.path.join(paths.ldapdir, "schema")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From 7c4a45de26010996192912694e5a0a5a3d990fdc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 16 Apr 2008 11:43:37 +0200 Subject: make sure header can be included more than once. (This used to be commit 38ed501ac8993e84ea7f02d4633bc83b490dfe61) --- source4/scripting/python/pyrpc.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h index f4d0f37c39..93d583c10a 100644 --- a/source4/scripting/python/pyrpc.h +++ b/source4/scripting/python/pyrpc.h @@ -17,6 +17,9 @@ along with this program. If not, see . */ +#ifndef _PYRPC_H_ +#define _PYRPC_H_ + #define PY_CHECK_TYPE(type, var, fail) \ if (!type ## _Check(var)) {\ PyErr_Format(PyExc_TypeError, "Expected type %s", type ## _Type.tp_name); \ @@ -32,3 +35,5 @@ #ifndef PyAPI_DATA # define PyAPI_DATA(RTYPE) extern RTYPE #endif + +#endif /* _PYRPC_H_ */ -- cgit From 4d8f3f190215edcdbeb1725cccdc962dc68cc1a0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Apr 2008 12:03:49 +0200 Subject: Fix the expectations on the unixinfo test. Andrew Bartlett (This used to be commit 0df2b3e0b56007850cf83cfdcdb45ca29e162d34) --- source4/scripting/python/samba/tests/dcerpc/unix.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py index 43978ac9dc..78a987cedd 100644 --- a/source4/scripting/python/samba/tests/dcerpc/unix.py +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -27,8 +27,8 @@ class UnixinfoTests(RpcInterfaceTestCase): def test_getpwuid(self): infos = self.conn.GetPWUid(range(512)) self.assertEquals(512, len(infos)) - self.assertEquals("", infos[0].shell) - self.assertEquals("", infos[0].homedir) + self.assertEquals("/bin/false", infos[0].shell) + self.assertTrue(isinstance(infos[0].homedir, unicode)) def test_gidtosid(self): self.conn.GidToSid(1000) -- cgit From 6267dd78539863a5ec75b6cadba39184a2efc9b5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 10 May 2008 20:59:17 +0200 Subject: Clean up some git merges gone wrong. (This used to be commit 42eb6b33462228467e65a51bbf624c481802b090) --- source4/scripting/python/modules.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index cbff14c708..0fe15b2fda 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -39,12 +39,10 @@ extern void initdrsuapi(void); extern void initwinreg(void); extern void initepmapper(void); extern void initinitshutdown(void); -static void initdcerpc_misc(void) {} extern void initmgmt(void); extern void initnet(void); extern void initatsvc(void); extern void initsamr(void); -static void initdcerpc_security(void) {} extern void initlsa(void); extern void initsvcctl(void); extern void initwkssvc(void); -- cgit From 97fbad6480b992421862eab3b347ff6a9bd33e8f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 10 May 2008 23:25:50 +0200 Subject: Install standalone python modules (so we can use stock python rather than smbpython). (This used to be commit bb5c9fc64b6ad275abdd98a19f018953c9d79cbd) --- source4/scripting/python/config.m4 | 5 +++++ source4/scripting/python/config.mk | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 3790071ba8..a61d541049 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -71,3 +71,8 @@ else AC_MSG_ERROR([Python not found. Please install Python 2.x and its development headers/libraries.]) fi +AC_MSG_CHECKING(python library directory) +pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1, 0, '\\${prefix}')"` +AC_MSG_RESULT($pythondir) + +AC_SUBST(pythondir) diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 15be4ca309..a0f5caad3b 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -23,9 +23,3 @@ python_misc_OBJ_FILES = scripting/python/misc_wrap.o _PY_FILES = $(shell find scripting/python -name "*.py") $(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst scripting/python/%,%,$(pyfile)),$(pyfile)))) - -installpython:: pythonmods - @$(SHELL) $(srcdir)/script/installpython.sh \ - $(INSTALLPERMS) \ - $(DESTDIR)$(PYTHONDIR) \ - scripting/python bin/python -- cgit From 5319d9620b9ef68b3687d76aeaba5fa5d5c57a18 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 03:31:26 +0200 Subject: Use consistent function names with the standard Python uuid module that is available in >= 2.4. (This used to be commit 60d458e3195eef6baf655fee0da7c3f68517e8e6) --- source4/scripting/python/samba/provision.py | 4 ++-- source4/scripting/python/samba/tests/samdb.py | 8 ++++---- source4/scripting/python/uuidmodule.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0e8840646c..60fa22e6c4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -910,7 +910,7 @@ def provision(setup_dir, message, session_info, domainsid = security.Sid(domainsid) if policyguid is None: - policyguid = uuid.random() + policyguid = uuid.uuid4() if adminpass is None: adminpass = misc.random_password(12) if krbtgtpass is None: @@ -960,7 +960,7 @@ def provision(setup_dir, message, session_info, assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": - invocationid = uuid.random() + invocationid = uuid.uuid4() if not os.path.exists(paths.private_dir): os.mkdir(paths.private_dir) diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 0e175bf936..9da3358527 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -29,18 +29,18 @@ import uuid class SamDBTestCase(TestCaseInTempDir): def setUp(self): super(SamDBTestCase, self).setUp() - invocationid = uuid.random() + invocationid = uuid.uuid4() domaindn = "DC=COM,DC=EXAMPLE" self.domaindn = domaindn configdn = "CN=Configuration," + domaindn schemadn = "CN=Schema," + configdn - domainguid = uuid.random() - policyguid = uuid.random() + domainguid = uuid.uuid4() + policyguid = uuid.uuid4() setup_path = lambda x: os.path.join("setup", x) creds = Credentials() creds.set_anonymous() domainsid = security.random_sid() - hostguid = uuid.random() + hostguid = uuid.uuid4() path = os.path.join(self.tempdir, "samdb.ldb") self.samdb = setup_samdb(path, setup_path, system_session(), creds, cmdline_loadparm, schemadn, configdn, diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c index 18cfb6ce32..98ef9adaa9 100644 --- a/source4/scripting/python/uuidmodule.c +++ b/source4/scripting/python/uuidmodule.c @@ -46,7 +46,7 @@ static PyObject *uuid_random(PyObject *self, PyObject *args) } static PyMethodDef methods[] = { - { "random", (PyCFunction)uuid_random, METH_VARARGS, NULL}, + { "uuid4", (PyCFunction)uuid_random, METH_VARARGS, NULL}, { NULL, NULL } }; -- cgit From 8c926a34c8a74e446aa3c07536c1289704c6bc7a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 04:36:05 +0200 Subject: Complete dependencies for python modules (actually matters when built standalone). (This used to be commit a89b6d8ad71d71271f30d156de20129866ef6aeb) --- source4/scripting/python/config.mk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index a0f5caad3b..e57ff1d1ac 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -5,9 +5,15 @@ smbpython_OBJ_FILES = scripting/python/smbpython.o [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON +PRIVATE_DEPENDENCIES = PYTALLOC INIT_FUNCTION_SENTINEL = { NULL, NULL } -LIBPYTHON_OBJ_FILES = $(addprefix scripting/python/, modules.o pytalloc.o) +LIBPYTHON_OBJ_FILES = $(addprefix scripting/python/, modules.o) + +[SUBSYSTEM::PYTALLOC] +PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON + +PYTALLOC_OBJ_FILES = $(addprefix scripting/python/, pytalloc.o) [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR -- cgit From 251f6bd99159337b24b8aa8298a5c98de153bce0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 04:36:37 +0200 Subject: make sure to always use string version of uuid rather than object. (This used to be commit bcd5fc7dc9899deb9fa84fdeeb21ed2ddb921308) --- source4/scripting/python/samba/provision.py | 5 +++-- source4/scripting/python/samba/tests/samdb.py | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 60fa22e6c4..ad8eb8bffd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -689,6 +689,7 @@ def setup_self_join(samdb, names, domainsid, invocationid, setup_path, policyguid): """Join a host to its own domain.""" + assert isinstance(invocationid, str) setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, @@ -910,7 +911,7 @@ def provision(setup_dir, message, session_info, domainsid = security.Sid(domainsid) if policyguid is None: - policyguid = uuid.uuid4() + policyguid = str(uuid.uuid4()) if adminpass is None: adminpass = misc.random_password(12) if krbtgtpass is None: @@ -960,7 +961,7 @@ def provision(setup_dir, message, session_info, assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": - invocationid = uuid.uuid4() + invocationid = str(uuid.uuid4()) if not os.path.exists(paths.private_dir): os.mkdir(paths.private_dir) diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 9da3358527..0d4f7bde0e 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -29,18 +29,18 @@ import uuid class SamDBTestCase(TestCaseInTempDir): def setUp(self): super(SamDBTestCase, self).setUp() - invocationid = uuid.uuid4() + invocationid = str(uuid.uuid4()) domaindn = "DC=COM,DC=EXAMPLE" self.domaindn = domaindn configdn = "CN=Configuration," + domaindn schemadn = "CN=Schema," + configdn - domainguid = uuid.uuid4() - policyguid = uuid.uuid4() + domainguid = str(uuid.uuid4()) + policyguid = str(uuid.uuid4()) setup_path = lambda x: os.path.join("setup", x) creds = Credentials() creds.set_anonymous() domainsid = security.random_sid() - hostguid = uuid.uuid4() + hostguid = str(uuid.uuid4()) path = os.path.join(self.tempdir, "samdb.ldb") self.samdb = setup_samdb(path, setup_path, system_session(), creds, cmdline_loadparm, schemadn, configdn, -- cgit From 826dadf4f24765cdd437c29c035496ae6793761c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 05:46:40 +0200 Subject: Remove smbpython. (This used to be commit e83f7b11963f2996e3ced0251087a09eb55c347c) --- source4/scripting/python/config.m4 | 1 - source4/scripting/python/config.mk | 5 ----- source4/scripting/python/smbpython.c | 34 ---------------------------------- 3 files changed, 40 deletions(-) delete mode 100644 source4/scripting/python/smbpython.c (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index a61d541049..1a86951bfb 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -64,7 +64,6 @@ SMB_EXT_LIB(EXT_LIB_PYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) AC_MSG_CHECKING(working python module support) if test $working_python = yes; then SMB_ENABLE(EXT_LIB_PYTHON,YES) - SMB_ENABLE(smbpython,YES) SMB_ENABLE(LIBPYTHON,YES) AC_MSG_RESULT([yes]) else diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index e57ff1d1ac..a0ae256d9b 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,8 +1,3 @@ -[BINARY::smbpython] -PRIVATE_DEPENDENCIES = LIBPYTHON - -smbpython_OBJ_FILES = scripting/python/smbpython.o - [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON PRIVATE_DEPENDENCIES = PYTALLOC diff --git a/source4/scripting/python/smbpython.c b/source4/scripting/python/smbpython.c deleted file mode 100644 index c5de53fd60..0000000000 --- a/source4/scripting/python/smbpython.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 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 . -*/ - -#include "includes.h" -#include -#include "scripting/python/modules.h" - -int main(int argc, char **argv) -{ - py_load_samba_modules(); - Py_Initialize(); - if (strchr(argv[0], '/') != NULL) { - char *bindir = strndup(argv[0], strrchr(argv[0], '/')-argv[0]); - py_update_path(bindir); - free(bindir); - } - return Py_Main(argc,argv); -} -- cgit From d648c5849fba34b5691dcf1867ecd8f80fe35a6d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 May 2008 16:30:22 +0200 Subject: Install python modules by default. (This used to be commit 4c098e4c9f071592e134c979388891f5bf16452d) --- source4/scripting/python/config.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index a0ae256d9b..83b1b1eefb 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -24,3 +24,5 @@ python_misc_OBJ_FILES = scripting/python/misc_wrap.o _PY_FILES = $(shell find scripting/python -name "*.py") $(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst scripting/python/%,%,$(pyfile)),$(pyfile)))) + +install:: installpython -- cgit From 25ea110c3814abcb824adb3619a44622ba8d2936 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sat, 17 May 2008 23:24:48 -0500 Subject: provision: Create instructions for enabling DNS GSS-TSIG updates. Added code to the python provisioning to create the named.conf file that was previously generated by the EJS provisioning. Updated the named.conf template to provide the additional details necessary to get things working. (This used to be commit 0b7a6bfcba1b906dc4d461882b4c3fe3c91c44e0) --- source4/scripting/python/samba/provision.py | 32 ++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ad8eb8bffd..4818a79f00 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -236,6 +236,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") + paths.namedconf = os.path.join(paths.private_dir, "named.conf") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(paths.private_dir, @@ -1059,12 +1060,14 @@ def provision(setup_dir, message, session_info, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - create_zone_file(paths.dns, setup_path, samdb, + create_zone_file(paths.dns, paths.namedconf, setup_path, samdb, hostname=names.hostname, hostip=hostip, hostip6=hostip6, dnsdomain=names.dnsdomain, domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, - domainguid=domainguid, hostguid=hostguid) + domainguid=domainguid, hostguid=hostguid, + private_dir=paths.private_dir, keytab_name=paths.dns_keytab) message("Please install the zone located in %s into your DNS server" % paths.dns) + message("See %s if you want to use secure GSS-TSIG updates" % paths.namedconf) create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) @@ -1281,12 +1284,18 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri): {"S4_LDAPI_URI": ldapi_uri}) -def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, - hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): +def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaindn, + hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid, + private_dir, keytab_name): """Write out a DNS zone file, from the info in the current database. + + Also writes a file with stubs appropriate for a DNS configuration file + (including GSS-TSIG configuration), and details as to some of the other + configuration changes that may be necessary. - :param path: Path of the new file. - :param setup_path": Setup path function. + :param path_zone: Path of the new zone file. + :param path_conf: Path of the config stubs file. + :param setup_path: Setup path function. :param samdb: SamDB object :param dnsdomain: DNS Domain name :param domaindn: DN of the Domain @@ -1307,7 +1316,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip6_base_line = " IN AAAA " + hostip6 hostip6_host_line = hostname + " IN AAAA " + hostip6 - setup_file(setup_path("provision.zone"), path, { + setup_file(setup_path("provision.zone"), path_zone, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, "DNSDOMAIN": dnsdomain, @@ -1321,6 +1330,15 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, "HOSTIP6_HOST_LINE": hostip6_host_line, }) + setup_file(setup_path("named.conf"), path_conf, { + "DNSDOMAIN": dnsdomain, + "REALM": realm, + "REALM_WC": "*." + ".".join(realm.split(".")[1:]), + "HOSTNAME": hostname, + "DNS_KEYTAB": keytab_name, + "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), + }) + def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From 4d2f44163e07995949fcf915019e0a6eb7c00b24 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 19:07:07 +0200 Subject: Use variables for source path in libnet/ and scripting/python. (This used to be commit fb10a81b9484642099ecbe896eabe00a4417bc42) --- source4/scripting/python/config.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 83b1b1eefb..b5b1895793 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -3,26 +3,26 @@ PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON PRIVATE_DEPENDENCIES = PYTALLOC INIT_FUNCTION_SENTINEL = { NULL, NULL } -LIBPYTHON_OBJ_FILES = $(addprefix scripting/python/, modules.o) +LIBPYTHON_OBJ_FILES = $(addprefix $(pyscriptdir)/, modules.o) [SUBSYSTEM::PYTALLOC] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON -PYTALLOC_OBJ_FILES = $(addprefix scripting/python/, pytalloc.o) +PYTALLOC_OBJ_FILES = $(addprefix $(pyscriptdir)/, pytalloc.o) [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR -python_uuid_OBJ_FILES = scripting/python/uuidmodule.o +python_uuid_OBJ_FILES = $(pyscriptdir)/uuidmodule.o [PYTHON::python_misc] PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i -python_misc_OBJ_FILES = scripting/python/misc_wrap.o +python_misc_OBJ_FILES = $(pyscriptdir)/misc_wrap.o -_PY_FILES = $(shell find scripting/python -name "*.py") +_PY_FILES = $(shell find $(pyscriptdir) -name "*.py") -$(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst scripting/python/%,%,$(pyfile)),$(pyfile)))) +$(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst $(pyscriptdir)/%,%,$(pyfile)),$(pyfile)))) install:: installpython -- cgit From 100d3967d3e522027f72bf5071f0b385eea32e74 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 19:10:37 +0200 Subject: Use src dir. (This used to be commit 63f2b66f0e1120a516d3dfcd03b38db2e4aaddd0) --- source4/scripting/python/config.mk | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index b5b1895793..1fa273e99d 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -3,26 +3,26 @@ PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON PRIVATE_DEPENDENCIES = PYTALLOC INIT_FUNCTION_SENTINEL = { NULL, NULL } -LIBPYTHON_OBJ_FILES = $(addprefix $(pyscriptdir)/, modules.o) +LIBPYTHON_OBJ_FILES = $(addprefix $(pyscriptsrcdir)/, modules.o) [SUBSYSTEM::PYTALLOC] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON -PYTALLOC_OBJ_FILES = $(addprefix $(pyscriptdir)/, pytalloc.o) +PYTALLOC_OBJ_FILES = $(addprefix $(pyscriptsrcdir)/, pytalloc.o) [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR -python_uuid_OBJ_FILES = $(pyscriptdir)/uuidmodule.o +python_uuid_OBJ_FILES = $(pyscriptsrcdir)/uuidmodule.o [PYTHON::python_misc] PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS SWIG_FILE = misc.i -python_misc_OBJ_FILES = $(pyscriptdir)/misc_wrap.o +python_misc_OBJ_FILES = $(pyscriptsrcdir)/misc_wrap.o -_PY_FILES = $(shell find $(pyscriptdir) -name "*.py") +_PY_FILES = $(shell find $(pyscriptsrcdir) -name "*.py") -$(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst $(pyscriptdir)/%,%,$(pyfile)),$(pyfile)))) +$(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst $(pyscriptsrcdir)/%,%,$(pyfile)),$(pyfile)))) install:: installpython -- cgit From 82bcf967b79321706cd19c759ea54c4465fe0d96 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 21:32:53 +0200 Subject: Move CFLAGS overrides for SWIG modules to Makefile. (This used to be commit 58665a8a8e4b10435aebbf2c95b6a8e50db232d6) --- source4/scripting/python/config.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 1fa273e99d..cc94abb702 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -21,6 +21,8 @@ SWIG_FILE = misc.i python_misc_OBJ_FILES = $(pyscriptsrcdir)/misc_wrap.o +$(python_misc_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" + _PY_FILES = $(shell find $(pyscriptsrcdir) -name "*.py") $(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst $(pyscriptsrcdir)/%,%,$(pyfile)),$(pyfile)))) -- cgit From 49706ab19bd3ffd6125639e6a7753b2350cf54e1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 May 2008 23:59:34 +0200 Subject: Move more modules inside of the samba package. (This used to be commit 9b39e99f48266a54ed0b8890c2efde218b4b118a) --- source4/scripting/python/config.mk | 9 +++++++-- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 2 +- source4/scripting/python/samba/tests/dcerpc/unix.py | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index cc94abb702..37e346a73a 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -16,15 +16,20 @@ PRIVATE_DEPENDENCIES = LIBNDR python_uuid_OBJ_FILES = $(pyscriptsrcdir)/uuidmodule.o [PYTHON::python_misc] +LIBRARY_REALNAME = samba/_misc.$(SHLIBEXT) PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS -SWIG_FILE = misc.i python_misc_OBJ_FILES = $(pyscriptsrcdir)/misc_wrap.o $(python_misc_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" -_PY_FILES = $(shell find $(pyscriptsrcdir) -name "*.py") +_PY_FILES = $(shell find $(pyscriptsrcdir)/samba $(pyscriptsrcdir)/subunit -name "*.py") $(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst $(pyscriptsrcdir)/%,%,$(pyfile)),$(pyfile)))) +$(eval $(call python_py_module_template,samba/misc.py,$(pyscriptsrcdir)/misc.py)) + +epydoc:: pythonmods + PYTHONPATH=$(pythonbuilddir) epydoc samba dcerpc + install:: installpython diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 6c43632d97..281d5b4cdb 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -import echo +from dcerpc import echo import unittest from samba.tests import RpcInterfaceTestCase diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py index 78a987cedd..b4b2e0aeda 100644 --- a/source4/scripting/python/samba/tests/dcerpc/unix.py +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -import unixinfo +from dcerpc import unixinfo from samba.tests import RpcInterfaceTestCase class UnixinfoTests(RpcInterfaceTestCase): -- cgit From 059c012656e6369f417c11f9984ddb1925782394 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 00:56:36 +0200 Subject: Fix dependencies and imports. (This used to be commit 37ef86f8de9039b8226b190254d842e92b5faad7) --- source4/scripting/python/config.mk | 4 ++-- source4/scripting/python/samba/tests/dcerpc/registry.py | 2 +- source4/scripting/python/samba/tests/dcerpc/sam.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 37e346a73a..ddbc5674f2 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -6,7 +6,7 @@ INIT_FUNCTION_SENTINEL = { NULL, NULL } LIBPYTHON_OBJ_FILES = $(addprefix $(pyscriptsrcdir)/, modules.o) [SUBSYSTEM::PYTALLOC] -PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON +PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON LIBTALLOC PYTALLOC_OBJ_FILES = $(addprefix $(pyscriptsrcdir)/, pytalloc.o) @@ -30,6 +30,6 @@ $(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubs $(eval $(call python_py_module_template,samba/misc.py,$(pyscriptsrcdir)/misc.py)) epydoc:: pythonmods - PYTHONPATH=$(pythonbuilddir) epydoc samba dcerpc + PYTHONPATH=$(pythonbuilddir) epydoc --no-private samba dcerpc tdb ldb subunit install:: installpython diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 1afdc582a7..0a1b5ecd10 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -import winreg +from dcerpc import winreg import unittest from samba.tests import RpcInterfaceTestCase diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index 8ef12dad86..50871114c0 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -import samr +from dcerpc import samr from samba.tests import RpcInterfaceTestCase class SamrTests(RpcInterfaceTestCase): -- cgit From 6e14d44d27d208bb22e6345fff8785c74a435a59 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 01:50:38 +0200 Subject: Make sure the default ldb modules dir gets initialized. (This used to be commit 937456c69d23ece85bdb7415f52d722c2aa6b6b5) --- source4/scripting/python/samba/__init__.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index b9d81c6c3c..29afdb931d 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -33,6 +33,8 @@ if _in_source_tree(): srcdir = "%s/../../.." % os.path.dirname(__file__) sys.path.append("%s/bin/python" % srcdir) default_ldb_modules_dir = "%s/bin/modules/ldb" % srcdir +else: + default_ldb_modules_dir = None import ldb -- cgit From 5ce59419a07c8e147daf51b77ffe2117f3d6a505 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 02:13:26 +0200 Subject: Fix CFLAGS for SWIG files. (This used to be commit 8ee4f075046e0b181ec8a4ac1eaf3ea5621a56bf) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index ddbc5674f2..73607eb76c 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -21,7 +21,7 @@ PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS python_misc_OBJ_FILES = $(pyscriptsrcdir)/misc_wrap.o -$(python_misc_OBJ_FILES): CFLAGS+="$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)" +$(python_misc_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) _PY_FILES = $(shell find $(pyscriptsrcdir)/samba $(pyscriptsrcdir)/subunit -name "*.py") -- cgit From d77745e6920038f3b6c7c25fa6cd6549e1c24d17 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 02:21:25 +0200 Subject: Move DCE/RPC python bindings into samba package. (This used to be commit 8dafd4ce40b7348fd5f2b1f2f5d2106ef4cc0dd1) --- source4/scripting/python/samba/tests/dcerpc/registry.py | 2 +- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 2 +- source4/scripting/python/samba/tests/dcerpc/sam.py | 2 +- source4/scripting/python/samba/tests/dcerpc/unix.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 0a1b5ecd10..81133ff641 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -from dcerpc import winreg +from samba.dcerpc import winreg import unittest from samba.tests import RpcInterfaceTestCase diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 281d5b4cdb..3b37f8a9bc 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -from dcerpc import echo +from samba.dcerpc import echo import unittest from samba.tests import RpcInterfaceTestCase diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index 50871114c0..a6816153c0 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -from dcerpc import samr +from samba.dcerpc import samr from samba.tests import RpcInterfaceTestCase class SamrTests(RpcInterfaceTestCase): diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py index b4b2e0aeda..aa47b71b16 100644 --- a/source4/scripting/python/samba/tests/dcerpc/unix.py +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -17,7 +17,7 @@ # along with this program. If not, see . # -from dcerpc import unixinfo +from samba.dcerpc import unixinfo from samba.tests import RpcInterfaceTestCase class UnixinfoTests(RpcInterfaceTestCase): -- cgit From d8459e3e1c87577768a2a250f701f14a64c22541 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 03:09:40 +0200 Subject: Fix import in provision test. (This used to be commit 96501be38da947f02ad57217e0bc23f7a66d36f9) --- source4/scripting/python/samba/tests/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index b9e0e16d3c..76c10145f0 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -21,7 +21,7 @@ import os from samba.provision import setup_secretsdb, secretsdb_become_dc, findnss import samba.tests from ldb import Dn -import param +from samba import param import unittest lp = samba.tests.cmdline_loadparm -- cgit From bf3f3af92677bce8f03b0dd2be552d6c8c730ca1 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Wed, 21 May 2008 18:12:36 -0500 Subject: provision: Generate krb5.conf template separate from named.conf template. (This used to be commit ebf130e9e57b640129cf0d05dbd7d210b71ea371) --- source4/scripting/python/samba/provision.py | 74 ++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 22 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4818a79f00..69c7e8846d 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -237,6 +237,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") paths.namedconf = os.path.join(paths.private_dir, "named.conf") + paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(paths.private_dir, @@ -1059,16 +1060,23 @@ def provision(setup_dir, message, session_info, expression="(&(objectClass=computer)(cn=%s))" % names.hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - - create_zone_file(paths.dns, paths.namedconf, setup_path, samdb, - hostname=names.hostname, hostip=hostip, - hostip6=hostip6, dnsdomain=names.dnsdomain, - domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, - domainguid=domainguid, hostguid=hostguid, - private_dir=paths.private_dir, keytab_name=paths.dns_keytab) + + create_zone_file(paths.dns, setup_path, dnsdomain=names.dnsdomain, + domaindn=names.domaindn, hostip=hostip, + hostip6=hostip6, hostname=names.hostname, + dnspass=dnspass, realm=names.realm, + domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) - message("See %s if you want to use secure GSS-TSIG updates" % paths.namedconf) - + + create_named_conf(paths.namedconf, setup_path, realm=names.realm, + dnsdomain=names.dnsdomain, private_dir=paths.private_dir, + keytab_name=paths.dns_keytab) + message("See %s for example configuration statements for secure GSS-TSIG updates" % paths.namedconf) + + create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain, + hostname=names.hostname, realm=names.realm) + message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf) + create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) @@ -1284,19 +1292,12 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri): {"S4_LDAPI_URI": ldapi_uri}) -def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaindn, - hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid, - private_dir, keytab_name): +def create_zone_file(path, setup_path, dnsdomain, domaindn, + hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): """Write out a DNS zone file, from the info in the current database. - Also writes a file with stubs appropriate for a DNS configuration file - (including GSS-TSIG configuration), and details as to some of the other - configuration changes that may be necessary. - - :param path_zone: Path of the new zone file. - :param path_conf: Path of the config stubs file. + :param path: Path of the new zone file. :param setup_path: Setup path function. - :param samdb: SamDB object :param dnsdomain: DNS Domain name :param domaindn: DN of the Domain :param hostip: Local IPv4 IP @@ -1316,7 +1317,7 @@ def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaind hostip6_base_line = " IN AAAA " + hostip6 hostip6_host_line = hostname + " IN AAAA " + hostip6 - setup_file(setup_path("provision.zone"), path_zone, { + setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, "DNSDOMAIN": dnsdomain, @@ -1330,15 +1331,44 @@ def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaind "HOSTIP6_HOST_LINE": hostip6_host_line, }) - setup_file(setup_path("named.conf"), path_conf, { +def create_named_conf(path, setup_path, realm, dnsdomain, + private_dir, keytab_name): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param realm: Realm name + :param dnsdomain: DNS Domain name + :param private_dir: Path to private directory + :param keytab_name: File name of DNS keytab file + """ + + setup_file(setup_path("named.conf"), path, { "DNSDOMAIN": dnsdomain, "REALM": realm, "REALM_WC": "*." + ".".join(realm.split(".")[1:]), - "HOSTNAME": hostname, "DNS_KEYTAB": keytab_name, "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), }) +def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param dnsdomain: DNS Domain name + :param hostname: Local hostname + :param realm: Realm name + """ + + setup_file(setup_path("krb5.conf"), path, { + "DNSDOMAIN": dnsdomain, + "HOSTNAME": hostname, + "REALM": realm, + }) + def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From 73e2fc95901afbc71000461e7613515ca906bcff Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 17:33:23 +0200 Subject: Add docstrings in misc python module. (This used to be commit 5bf15122e6bb6dcbc2abd325db9522b2084d975f) --- source4/scripting/python/misc.i | 15 ++++++ source4/scripting/python/misc.py | 50 ++++++++++++++++--- source4/scripting/python/misc_wrap.c | 97 ++++++++++++++++++++++++++---------- 3 files changed, 129 insertions(+), 33 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 6fa3bc93e3..9a4c124121 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -40,6 +40,15 @@ %rename(random_password) generate_random_str; char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); +%feature("docstring") ldb_set_credentials "S.set_credentials(credentials)\n" + "Set credentials to use when connecting."; + +%feature("docstring") ldb_set_session_info "S.set_session_info(session_info)\n" + "Set session info to use when connecting."; + +%feature("docstring") ldb_set_loadparm "S.set_loadparm(session_info)\n" + "Set loadparm context to use when connecting."; + %inline %{ void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) { @@ -58,14 +67,20 @@ void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) %} +%feature("docstring") samdb_set_domain_sid "S.set_domain_sid(sid)\n" + "Set SID of domain to use."; bool samdb_set_domain_sid(struct ldb_context *ldb, const struct dom_sid *dom_sid_in); WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df); +%feature("docstring") samba_version_string "version()\n" + "Obtain the Samba version."; %rename(version) samba_version_string; const char *samba_version_string(void); int dsdb_set_global_schema(struct ldb_context *ldb); +%feature("docstring") ldb_register_samba_handlers "register_samba_handlers()\n" + "Register Samba-specific LDB modules and schemas."; int ldb_register_samba_handlers(struct ldb_context *ldb); %inline %{ diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index f1da4c687a..25e8d2de8c 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.33 +# Version 1.3.35 # # Don't modify this file, modify the SWIG interface instead. @@ -62,14 +62,50 @@ import credentials import param import security random_password = _misc.random_password -ldb_set_credentials = _misc.ldb_set_credentials -ldb_set_session_info = _misc.ldb_set_session_info -ldb_set_loadparm = _misc.ldb_set_loadparm -samdb_set_domain_sid = _misc.samdb_set_domain_sid + +def ldb_set_credentials(*args, **kwargs): + """ + S.set_credentials(credentials) + Set credentials to use when connecting. + """ + return _misc.ldb_set_credentials(*args, **kwargs) + +def ldb_set_session_info(*args, **kwargs): + """ + S.set_session_info(session_info) + Set session info to use when connecting. + """ + return _misc.ldb_set_session_info(*args, **kwargs) + +def ldb_set_loadparm(*args, **kwargs): + """ + S.set_loadparm(session_info) + Set loadparm context to use when connecting. + """ + return _misc.ldb_set_loadparm(*args, **kwargs) + +def samdb_set_domain_sid(*args, **kwargs): + """ + S.set_domain_sid(sid) + Set SID of domain to use. + """ + return _misc.samdb_set_domain_sid(*args, **kwargs) dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file -version = _misc.version + +def version(*args): + """ + version() + Obtain the Samba version. + """ + return _misc.version(*args) dsdb_set_global_schema = _misc.dsdb_set_global_schema -ldb_register_samba_handlers = _misc.ldb_register_samba_handlers + +def ldb_register_samba_handlers(*args, **kwargs): + """ + register_samba_handlers() + Register Samba-specific LDB modules and schemas. + """ + return _misc.ldb_register_samba_handlers(*args, **kwargs) dsdb_set_ntds_invocation_id = _misc.dsdb_set_ntds_invocation_id private_path = _misc.private_path diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 4944515d15..22a072fc6f 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.33 + * Version 1.3.35 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -126,7 +126,7 @@ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" +#define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE @@ -161,6 +161,7 @@ /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 @@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { extern "C" { #endif -typedef void *(*swig_converter_func)(void *); +typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); -/* Structure to store inforomation on one type */ +/* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ @@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* @@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg) Py_DECREF(old_str); Py_DECREF(value); } else { - PyErr_Format(PyExc_RuntimeError, mesg); + PyErr_SetString(PyExc_RuntimeError, mesg); } } @@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v) { PySwigObject *sobj = (PySwigObject *) v; PyObject *next = sobj->next; - if (sobj->own) { + if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; @@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v) res = ((*meth)(mself, v)); } Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); + } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } +#endif } Py_XDECREF(next); PyObject_DEL(v); @@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { + if (own == SWIG_POINTER_OWN) { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; @@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int return SWIG_OK; } else { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { @@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int if (!tc) { sobj = (PySwigObject *)sobj->next; } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } break; } } @@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int } } if (sobj) { - if (own) *own = sobj->own; + if (own) + *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } @@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { } if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } } else { *ptr = vptr; } @@ -2519,7 +2537,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #define SWIG_name "_misc" -#define SWIGVERSION 0x010333 +#define SWIGVERSION 0x010335 #define SWIG_VERSION SWIGVERSION @@ -3199,14 +3217,32 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_set_session_info", (PyCFunction) _wrap_ldb_set_session_info, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"samdb_set_domain_sid", (PyCFunction) _wrap_samdb_set_domain_sid, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_credentials(credentials)\n" + "Set credentials to use when connecting.\n" + ""}, + { (char *)"ldb_set_session_info", (PyCFunction) _wrap_ldb_set_session_info, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_session_info(session_info)\n" + "Set session info to use when connecting.\n" + ""}, + { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_loadparm(session_info)\n" + "Set loadparm context to use when connecting.\n" + ""}, + { (char *)"samdb_set_domain_sid", (PyCFunction) _wrap_samdb_set_domain_sid, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_domain_sid(sid)\n" + "Set SID of domain to use.\n" + ""}, { (char *)"dsdb_attach_schema_from_ldif_file", (PyCFunction) _wrap_dsdb_attach_schema_from_ldif_file, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, NULL}, + { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, (char *)"\n" + "version()\n" + "Obtain the Samba version.\n" + ""}, { (char *)"dsdb_set_global_schema", (PyCFunction) _wrap_dsdb_set_global_schema, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "register_samba_handlers()\n" + "Register Samba-specific LDB modules and schemas.\n" + ""}, { (char *)"dsdb_set_ntds_invocation_id", (PyCFunction) _wrap_dsdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"private_path", (PyCFunction) _wrap_private_path, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } @@ -3225,7 +3261,7 @@ static swig_type_info _swigt__p_ldb_context = {"_p_ldb_context", "struct ldb_con static swig_type_info _swigt__p_ldb_dn = {"_p_ldb_dn", "struct ldb_dn *|ldb_dn *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_ldif = {"_p_ldb_ldif", "struct ldb_ldif *|ldb_ldif *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_message = {"_p_ldb_message", "ldb_msg *|struct ldb_message *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element", "struct ldb_message_element *|ldb_msg_element *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element", "struct ldb_message_element *|ldb_message_element *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0}; @@ -3397,7 +3433,7 @@ SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; - int found; + int found, init; clientdata = clientdata; @@ -3407,6 +3443,9 @@ SWIG_InitializeModule(void *clientdata) { swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; + init = 1; + } else { + init = 0; } /* Try and load any already created modules */ @@ -3435,6 +3474,12 @@ SWIG_InitializeModule(void *clientdata) { module_head->next = &swig_module; } + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); -- cgit From c401aa93573460f10256218a6a1902839b17b884 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 17:42:18 +0200 Subject: Use restructuredText formatting for docstrings. (This used to be commit 0cc58decd74d20f3d7dff93ddef1c8bce4d49ad0) --- source4/scripting/python/samba/__init__.py | 2 ++ source4/scripting/python/samba/idmap.py | 2 ++ source4/scripting/python/samba/provision.py | 2 ++ source4/scripting/python/samba/samba3.py | 2 ++ source4/scripting/python/samba/samdb.py | 2 ++ source4/scripting/python/samba/upgrade.py | 2 ++ 6 files changed, 12 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 29afdb931d..c7d71d3747 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -20,6 +20,8 @@ # along with this program. If not, see . # +__docformat__ = "restructuredText" + import os def _in_source_tree(): diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py index 16efcd0470..755ec52c7b 100644 --- a/source4/scripting/python/samba/idmap.py +++ b/source4/scripting/python/samba/idmap.py @@ -20,6 +20,8 @@ """Convenience functions for using the idmap database.""" +__docformat__ = "restructuredText" + import samba import misc import ldb diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 69c7e8846d..68b43eff40 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -43,6 +43,8 @@ from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ """Functions for setting up a Samba configuration.""" +__docformat__ = "restructuredText" + DEFAULTSITE = "Default-First-Site-Name" class InvalidNetbiosName(Exception): diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index cffedb54af..9e802fa093 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -19,6 +19,8 @@ """Support for reading Samba 3 data files.""" +__docformat__ = "restructuredText" + REGISTRY_VALUE_PREFIX = "SAMBA_REGVAL" REGISTRY_DB_VERSION = 1 diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 198d1e9f5c..6465f49519 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -28,6 +28,8 @@ import ldb from samba.idmap import IDmapDB import pwd +__docformat__ = "restructuredText" + class SamDB(samba.Ldb): """The SAM database.""" diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index f40f2cffe7..0c83604e82 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -7,6 +7,8 @@ """Support code for upgrading from Samba 3 to Samba 4.""" +__docformat__ = "restructuredText" + from provision import findnss, provision, FILL_DRS import grp import ldb -- cgit From c159d1221bddec5c855fda9236913c18fc7a49fa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 18:47:32 +0200 Subject: Add docstrings to samba3 and getopt modules. (This used to be commit bdf1c039db6c184a9f275a6e4bf3786570cc924a) --- source4/scripting/python/samba/getopt.py | 15 +++++++++++++++ source4/scripting/python/samba/samba3.py | 3 +++ 2 files changed, 18 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 7ec684a9d6..9ecb66e21c 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -17,10 +17,15 @@ # along with this program. If not, see . # +"""Support for parsing Samba-related command-line options.""" + import optparse from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS +__docformat__ = "restructuredText" + class SambaOptions(optparse.OptionGroup): + """General Samba-related command line options.""" def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Samba Common Options") self.add_option("-s", "--configfile", action="callback", @@ -29,12 +34,14 @@ class SambaOptions(optparse.OptionGroup): self._configfile = None def get_loadparm_path(self): + """Return the path to the smb.conf file specified on the command line. """ return self._configfile def _load_configfile(self, option, opt_str, arg, parser): self._configfile = arg def get_loadparm(self): + """Return a loadparm object with data specified on the command line. """ import os, param lp = param.LoadParm() if self._configfile is not None: @@ -45,12 +52,15 @@ class SambaOptions(optparse.OptionGroup): lp.load_default() return lp + class VersionOptions(optparse.OptionGroup): + """Command line option for printing Samba version.""" def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Version Options") class CredentialsOptions(optparse.OptionGroup): + """Command line options for specifying credentials.""" def __init__(self, parser): self.no_pass = False optparse.OptionGroup.__init__(self, parser, "Credentials Options") @@ -91,6 +101,11 @@ class CredentialsOptions(optparse.OptionGroup): self.creds.set_bind_dn(arg) def get_credentials(self, lp): + """Obtain the credentials set on the command-line. + + :param lp: Loadparm object to use. + :return: Credentials object + """ self.creds.guess(lp) if not self.no_pass: self.creds.set_cmdline_callbacks() diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index 9e802fa093..c1340b7760 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -309,6 +309,7 @@ class ShareInfoDatabase(TdbDatabase): class Shares: + """Container for share objects.""" def __init__(self, lp, shareinfo): self.lp = lp self.shareinfo = shareinfo @@ -494,6 +495,7 @@ class TdbSam(TdbDatabase): assert self.version in (0, 1, 2) def usernames(self): + """Iterate over the usernames in this Tdb database.""" for k in self.tdb.keys(): if k.startswith(TDBSAM_USER_PREFIX): yield k[len(TDBSAM_USER_PREFIX):].rstrip("\0") @@ -635,6 +637,7 @@ class WinsDatabase: return iter(self.entries) def items(self): + """Return the entries in this WINS database.""" return self.entries.items() def close(self): # for consistency -- cgit From 1a42178166e07add705da42ed1f936f95a7a4382 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 00:45:50 +0200 Subject: dcerpc is now samba.dcerpc, avoid including source code in API documentation. (This used to be commit a28a8ed53557451749007a119e979f561c6b0f59) --- source4/scripting/python/config.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 73607eb76c..b494ee6e8d 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -29,7 +29,9 @@ $(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubs $(eval $(call python_py_module_template,samba/misc.py,$(pyscriptsrcdir)/misc.py)) +EPYDOC_OPTIONS = --no-private --url http://www.samba.org/ --no-sourcecode + epydoc:: pythonmods - PYTHONPATH=$(pythonbuilddir) epydoc --no-private samba dcerpc tdb ldb subunit + PYTHONPATH=$(pythonbuilddir) epydoc $(EPYDOC_OPTIONS) samba tdb ldb subunit install:: installpython -- cgit From 166105b0b6b4c23eeb563562c75abcd6fa8e01e2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 03:20:37 +0200 Subject: Fix bug after reprocessing swig files with newer version of SWIG. (This used to be commit 2155d76646f4235c8857460f562a9cc4cafe3ab1) --- source4/scripting/python/config.m4 | 2 +- source4/scripting/python/samba/__init__.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 1a86951bfb..b599aaefb0 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -5,7 +5,7 @@ AC_ARG_VAR([PYTHON_VERSION],[The installed Python will be appended to the Python interpreter canonical name.]) -AC_PROG_SWIG(1.3.31) +AC_PROG_SWIG(1.3.35) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index c7d71d3747..94f9e4d005 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -73,15 +73,15 @@ class Ldb(ldb.Ldb): self.set_modules_dir(default_ldb_modules_dir) if credentials is not None: - self.set_credentials(self, credentials) + self.set_credentials(credentials) if session_info is not None: - self.set_session_info(self, session_info) + self.set_session_info(session_info) assert misc.ldb_register_samba_handlers(self) == 0 if lp is not None: - self.set_loadparm(self, lp) + self.set_loadparm(lp) def msg(l,text): print text -- cgit From 27005cb7a2182c50c8bf9e683de1bea2613a3078 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 05:13:31 +0200 Subject: Convert samr test to python. (This used to be commit 88d473b202e82b462ef82ffdeb4f1710918ffda5) --- source4/scripting/python/samba/tests/dcerpc/sam.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index a6816153c0..81300c9e81 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -26,3 +26,5 @@ class SamrTests(RpcInterfaceTestCase): def test_connect5(self): (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) + + -- cgit From 6ccb9785e7e1b2374a0121b5c70a2969b120a926 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 12:21:26 +0200 Subject: Add another test toe the python samr testsuite. (This used to be commit 480884c696c676bb978e9197271b99cc03bb66e6) --- source4/scripting/python/samba/tests/dcerpc/sam.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index 81300c9e81..e685f9b4f4 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -1,7 +1,8 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- # Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij 2008 +# Copyright © Jelmer Vernooij 2008 # # 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 @@ -17,9 +18,17 @@ # along with this program. If not, see . # -from samba.dcerpc import samr +from samba.dcerpc import samr, security from samba.tests import RpcInterfaceTestCase +# FIXME: Pidl should be doing this for us +def toArray((handle, array, num_entries)): + ret = [] + for x in range(num_entries): + ret.append((array.entries[x].idx, array.entries[x].name)) + return ret + + class SamrTests(RpcInterfaceTestCase): def setUp(self): self.conn = samr.samr("ncalrpc:", self.get_loadparm()) @@ -27,4 +36,11 @@ class SamrTests(RpcInterfaceTestCase): def test_connect5(self): (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) + def test_connect2(self): + (level, info, handle) = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) + + def test_EnumDomains(self): + handle = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) + domains = toArray(self.conn.EnumDomains(handle, 0, -1)) + self.conn.Close(handle) -- cgit From 9adcd8c25e7e51ac7e4767763750c67e334bcdbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 13:13:36 +0200 Subject: UFollow conventions for __repr__ contents for talloc python wrapper. (This used to be commit f2d437d646d0694498c14bc951f9745c4ecd902d) --- source4/scripting/python/pytalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index aa0ae9bf90..d669eb0f24 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -41,5 +41,5 @@ PyObject *py_talloc_default_repr(PyObject *py_obj) py_talloc_Object *obj = (py_talloc_Object *)py_obj; PyTypeObject *type = (PyTypeObject*)PyObject_Type((PyObject *)obj); - return PyString_FromFormat("<%s>", type->tp_name); + return PyString_FromFormat("<%s talloc object at 0x%x>", type->tp_name, (intptr_t)py_obj); } -- cgit From dff31b1dc0ec1aea8cec9d5764f4f3a4c109a848 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 15:09:51 +0200 Subject: Create new context in pytalloc to avoid problems with talloc_free() freeing the wrong parent of a pointer. (This used to be commit 3f628f4dc9a57326442ebe2d2eaac9d279043aa6) --- source4/scripting/python/pytalloc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index d669eb0f24..ca476e9604 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -24,6 +24,7 @@ void py_talloc_dealloc(PyObject* self) { py_talloc_Object *obj = (py_talloc_Object *)self; talloc_free(obj->talloc_ctx); + obj->talloc_ctx = NULL; PyObject_Del(self); } @@ -31,7 +32,13 @@ PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { py_talloc_Object *ret = PyObject_New(py_talloc_Object, py_type); - ret->talloc_ctx = talloc_reference(NULL, mem_ctx); + ret->talloc_ctx = talloc_new(NULL); + if (ret->talloc_ctx == NULL) { + return NULL; + } + if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) { + return NULL; + } ret->ptr = ptr; return (PyObject *)ret; } -- cgit From 5eed56d0ad5245a346ea564bc34e882828394611 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 15:10:35 +0200 Subject: Fix bugs in samr python tests. (This used to be commit 09c6b106ac144820b8c072bda4dad3d8e2145ff0) --- source4/scripting/python/samba/tests/dcerpc/sam.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index e685f9b4f4..50e00a3f9e 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -37,7 +37,7 @@ class SamrTests(RpcInterfaceTestCase): (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) def test_connect2(self): - (level, info, handle) = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) + handle = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) def test_EnumDomains(self): handle = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) -- cgit From e3d000f3bfad4126ab781f15848fff3bbd8abcc5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 16:29:08 +0200 Subject: Some more PEP improvements. (This used to be commit 015ca850df9b4c8112b033130023909b1d0b78b7) --- source4/scripting/python/samba/provision.py | 35 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index fe9b582d56..fdcc3dad77 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1111,7 +1111,7 @@ def provision_become_dc(setup_dir=None, return provision(setup_dir, message, system_session(), None, smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, serverdn=serverdn, - domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); + domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename) def setup_db_config(setup_path, dbdir): @@ -1120,9 +1120,9 @@ def setup_db_config(setup_path, dbdir): :param setup_path: Setup path function. :param dbdir: Database directory.""" if not os.path.isdir(os.path.join(dbdir, "bdb-logs")): - os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700); + os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700) if not os.path.isdir(os.path.join(dbdir, "tmp")): - os.makedirs(os.path.join(dbdir, "tmp"), 0700); + os.makedirs(os.path.join(dbdir, "tmp"), 0700) setup_file(setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"), {"LDAPDBDIR": dbdir}) @@ -1145,8 +1145,9 @@ def provision_backend(setup_dir=None, message=None, root = findnss(pwd.getpwnam, ["root"])[0] if smbconf is None: - os.makedirs(os.path.join(targetdir, "etc")) - smbconf = os.path.join(targetdir, "etc", "smb.conf") + etcdir = os.path.join(targetdir, "etc") + os.makedirs(etcdir) + smbconf = os.path.join(etcdir, "smb.conf") # only install a new smb.conf if there isn't one there already if not os.path.exists(smbconf): @@ -1220,20 +1221,18 @@ def provision_backend(setup_dir=None, message=None, elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] - res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) - memberof_config = "# Generated from schema in " + schemadb_path + "\n"; - refint_attributes = ""; + memberof_config = "# Generated from schema in %s\n" % schemadb_path + refint_attributes = "" for i in range (0, len(res)): - linkid = res[i]["linkID"][0] - linkid = str(int(linkid) + 1) - expression = "(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))" + expression = "(&(objectclass=attributeSchema)(linkID=%d))" % (int(res[i]["linkID"][0])+1) target = schemadb.searchone(basedn=names.schemadn, expression=expression, attribute="lDAPDisplayName", - scope=SCOPE_SUBTREE); + scope=SCOPE_SUBTREE) if target is not None: - refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0]; + refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0] memberof_config = memberof_config + """overlay memberof memberof-dangling error memberof-refint TRUE @@ -1242,11 +1241,11 @@ memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ memberof-memberof-ad """ + target + """ memberof-dangling-error 32 -"""; +""" memberof_config = memberof_config + """ overlay refint -refint_attributes""" + refint_attributes + "\n"; +refint_attributes""" + refint_attributes + "\n" setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, @@ -1273,12 +1272,12 @@ refint_attributes""" + refint_attributes + "\n"; server_port_string = "" slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string - schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) os.system(schema_command) - message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ( ldap_backend_type) ) + message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ldap_backend_type) message("Server Role: %s" % serverrole) message("Hostname: %s" % names.hostname) message("DNS Domain: %s" % names.dnsdomain) @@ -1337,6 +1336,7 @@ def create_zone_file(path, setup_path, dnsdomain, domaindn, "HOSTIP6_HOST_LINE": hostip6_host_line, }) + def create_named_conf(path, setup_path, realm, dnsdomain, private_dir, keytab_name): """Write out a file containing zone statements suitable for inclusion in a @@ -1375,6 +1375,7 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): "REALM": realm, }) + def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From a203ee1ab18ea68c6df436f8bb9fc0772611d5d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 16:43:26 +0200 Subject: Fix indentation, add docstring in provisioning script. (This used to be commit 86a8a085496c292b390c0d6362e3e4d9980df83f) --- source4/scripting/python/samba/provision.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index fdcc3dad77..a4730d8a07 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -48,6 +48,7 @@ __docformat__ = "restructuredText" DEFAULTSITE = "Default-First-Site-Name" class InvalidNetbiosName(Exception): + """A specified name was not a valid NetBIOS name.""" def __init__(self, name): super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) @@ -1233,7 +1234,7 @@ def provision_backend(setup_dir=None, message=None, scope=SCOPE_SUBTREE) if target is not None: refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0] - memberof_config = memberof_config + """overlay memberof + memberof_config += """overlay memberof memberof-dangling error memberof-refint TRUE memberof-group-oc top @@ -1243,7 +1244,7 @@ memberof-dangling-error 32 """ - memberof_config = memberof_config + """ + memberof_config += """ overlay refint refint_attributes""" + refint_attributes + "\n" @@ -1259,18 +1260,18 @@ refint_attributes""" + refint_attributes + "\n" setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" - - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - if ldap_backend_port is not None: - server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port - else: - server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" + + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + if ldap_backend_port is not None: + server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port + else: + server_port_string = "" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) -- cgit From 73b789b6d25698dba15c867c71d0cdd8c264f352 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 04:01:57 +0200 Subject: Add docstrings to a couple more python modules. (This used to be commit b4560c90e5e8d3a35367d3a21d361dc4c9c0de23) --- source4/scripting/python/misc.i | 5 ++++- source4/scripting/python/misc.py | 12 +++++++++++- source4/scripting/python/misc_wrap.c | 5 ++++- source4/scripting/python/samba/__init__.py | 2 ++ source4/scripting/python/samba/provision.py | 4 ++-- 5 files changed, 23 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 9a4c124121..56b862552a 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -16,7 +16,7 @@ along with this program. If not, see . */ -%module(package="samba.misc") misc +%module(docstring="Python bindings for miscellaneous Samba functions.",package="samba.misc") misc %{ #include "includes.h" @@ -37,6 +37,9 @@ %import "../../libcli/security/security.i" %import "../../libcli/util/errors.i" +%feature("docstring") generate_random_str "S.random_password(len) -> string\n" \ + "Generate random password with specified length."; + %rename(random_password) generate_random_str; char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 25e8d2de8c..0c14944001 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -3,6 +3,10 @@ # # Don't modify this file, modify the SWIG interface instead. +""" +Python bindings for miscellaneous Samba functions. +""" + import _misc import new new_instancemethod = new.instancemethod @@ -61,7 +65,13 @@ import ldb import credentials import param import security -random_password = _misc.random_password + +def random_password(*args, **kwargs): + """ + S.random_password(len) -> string + Generate random password with specified length. + """ + return _misc.random_password(*args, **kwargs) def ldb_set_credentials(*args, **kwargs): """ diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 22a072fc6f..8c57237e5b 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -3216,7 +3216,10 @@ fail: static PyMethodDef SwigMethods[] = { - { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.random_password(len) -> string\n" + "Generate random password with specified length.\n" + ""}, { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, (char *)"\n" "S.set_credentials(credentials)\n" "Set credentials to use when connecting.\n" diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index 94f9e4d005..e191227108 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -20,6 +20,8 @@ # along with this program. If not, see . # +"""Samba 4.""" + __docformat__ = "restructuredText" import os diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a4730d8a07..3914fa8376 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -22,6 +22,8 @@ # along with this program. If not, see . # +"""Functions for setting up a Samba configuration.""" + from base64 import b64encode import os import pwd @@ -41,8 +43,6 @@ import urllib from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE -"""Functions for setting up a Samba configuration.""" - __docformat__ = "restructuredText" DEFAULTSITE = "Default-First-Site-Name" -- cgit From f76697ce89606aa4e5ba1bb13f1fda6e33998695 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 18:57:15 +0200 Subject: Add convenience functions for packing/unpacking structs in python. (This used to be commit c5d7d48b32bcebf8a0495cbd4556e30587fa589f) --- source4/scripting/python/samba/ndr.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 source4/scripting/python/samba/ndr.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/ndr.py b/source4/scripting/python/samba/ndr.py new file mode 100644 index 0000000000..e93fbc3c2e --- /dev/null +++ b/source4/scripting/python/samba/ndr.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright © Jelmer Vernooij 2008 +# +# 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 . +# + +def ndr_pack(object): + return object.__ndr_pack__() + + +def ndr_unpack(cls, data): + object = cls() + object.__ndr_unpack__(data) + return object -- cgit From 05194ccdf875ee70cb9ee3f7c27147503d585a6d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 19:50:09 +0200 Subject: Add tests for new NDR pack/unpack functionality in Python DCE/RPC bindings. (This used to be commit 468d35827fd055c82c6d43d6ce6d3d561abed54d) --- source4/scripting/python/samba/ndr.py | 1 + source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/ndr.py b/source4/scripting/python/samba/ndr.py index e93fbc3c2e..e718ff3422 100644 --- a/source4/scripting/python/samba/ndr.py +++ b/source4/scripting/python/samba/ndr.py @@ -1,4 +1,5 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- # Unix SMB/CIFS implementation. # Copyright © Jelmer Vernooij 2008 diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 3b37f8a9bc..9157f83fc9 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -18,6 +18,7 @@ # from samba.dcerpc import echo +from samba.ndr import ndr_pack, ndr_unpack import unittest from samba.tests import RpcInterfaceTestCase @@ -40,3 +41,14 @@ class RpcEchoTests(RpcInterfaceTestCase): surrounding_struct.surrounding = [1,2,3,4] y = self.conn.TestSurrounding(surrounding_struct) self.assertEquals(8 * [0], y.surrounding) + + +class NdrEchoTests(unittest.TestCase): + def test_info1_push(self): + x = echo.info1() + x.v = 42 + self.assertEquals("\x2a", ndr_pack(x)) + + def test_info1_pull(self): + x = ndr_unpack(echo.info1, "\x42") + self.assertEquals(x.v, 66) -- cgit From 515b6ed5867bba8180bd0eeadbeab1c52bffc0ab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 20:00:37 +0200 Subject: Share struct used for interfaces in Python code. (This used to be commit 8501a3fc31e688dba696667a187821480e8cb714) --- source4/scripting/python/pyrpc.h | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 source4/scripting/python/pyrpc.h (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h deleted file mode 100644 index 93d583c10a..0000000000 --- a/source4/scripting/python/pyrpc.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 2008 - - 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 . -*/ - -#ifndef _PYRPC_H_ -#define _PYRPC_H_ - -#define PY_CHECK_TYPE(type, var, fail) \ - if (!type ## _Check(var)) {\ - PyErr_Format(PyExc_TypeError, "Expected type %s", type ## _Type.tp_name); \ - fail; \ - } - -#define dom_sid2_Type dom_sid_Type -#define dom_sid28_Type dom_sid_Type -#define dom_sid2_Check dom_sid_Check -#define dom_sid28_Check dom_sid_Check - -/* This macro is only provided by Python >= 2.3 */ -#ifndef PyAPI_DATA -# define PyAPI_DATA(RTYPE) extern RTYPE -#endif - -#endif /* _PYRPC_H_ */ -- cgit From f9c36fae757d197ee4de06f0ecf94ae13faad0de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 21:38:33 +0200 Subject: Export functions for setting NTSTATUS and WERRORs in python. (This used to be commit 4bcb92d2d49d90863b1e64b15d055517fbfd263c) --- source4/scripting/python/misc.i | 7 +++---- source4/scripting/python/misc_wrap.c | 6 ++++-- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 56b862552a..1d331215b5 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -35,7 +35,7 @@ %import "../../auth/credentials/credentials.i" %import "../../param/param.i" %import "../../libcli/security/security.i" -%import "../../libcli/util/errors.i" +%include "../../libcli/util/errors.i" %feature("docstring") generate_random_str "S.random_password(len) -> string\n" \ "Generate random password with specified length."; @@ -97,7 +97,6 @@ bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid) } %} -char *private_path(TALLOC_CTX* mem_ctx, - struct loadparm_context *lp_ctx, - const char *name); +char *private_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, + const char *name); diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 8c57237e5b..888918ef53 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -2554,6 +2554,9 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #include "librpc/ndr/libndr.h" +#include "libcli/util/pyerrors.h" + + SWIGINTERN int SWIG_AsVal_double (PyObject *obj, double *val) { @@ -3046,8 +3049,7 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE "ldb context must be non-NULL"); result = dsdb_attach_schema_from_ldif_file(arg1,(char const *)arg2,(char const *)arg3); if (!W_ERROR_IS_OK(result)) { - PyObject *obj = Py_BuildValue((char *)"(i,s)", W_ERROR_V(result), win_errstr(result)); - PyErr_SetObject(PyExc_RuntimeError, obj); + PyErr_SetWERROR(result); SWIG_fail; } else if (resultobj == NULL) { resultobj = Py_None; -- cgit From 75e7962d2efb1aa6e45ca999b1a93829406de540 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 22:13:32 +0200 Subject: Add convenience functions for setting Python objects from errors. (This used to be commit f1de723b89251cbc8140b838941f304a34871bf3) --- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 9157f83fc9..83279a0b30 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -42,6 +42,11 @@ class RpcEchoTests(RpcInterfaceTestCase): y = self.conn.TestSurrounding(surrounding_struct) self.assertEquals(8 * [0], y.surrounding) + def test_manual_request(self): + self.assertEquals("\x01\x00\x00\x00", self.conn.request(0, chr(0) * 4)) + + def test_server_name(self): + self.assertEquals(None, self.conn.server_name) class NdrEchoTests(unittest.TestCase): def test_info1_push(self): -- cgit From 21ce0ff00688c560e60efd6c392c71f85229c9d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 22:56:49 +0200 Subject: Allow connecting to a DCE/RPC interface with Python for which we don't have IDL. (This used to be commit e3178d522c95871f1db35d7e058906502387a553) --- .../scripting/python/samba/tests/dcerpc/bare.py | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 source4/scripting/python/samba/tests/dcerpc/bare.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/bare.py b/source4/scripting/python/samba/tests/dcerpc/bare.py new file mode 100644 index 0000000000..dae1dedeb3 --- /dev/null +++ b/source4/scripting/python/samba/tests/dcerpc/bare.py @@ -0,0 +1,30 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Unix SMB/CIFS implementation. +# Copyright © Jelmer Vernooij 2008 +# +# 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 . +# + +from samba.dcerpc import ClientConnection +from unittest import TestCase + +class BareTestCase(TestCase): + def test_bare(self): + # Connect to the echo pipe + x = ClientConnection("ncalrpc:localhost[DEFAULT]", + ("60a15ec5-4de8-11d7-a637-005056a20182", 1)) + self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) + -- cgit From 928ecbaebbde00515d08fd530db7c99169c905ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 25 May 2008 04:23:03 +0200 Subject: Add support for secondary contexts from Python. (This used to be commit 16d1ad050546ae6500153438db8d3c857e6f3ad5) --- source4/scripting/python/samba/tests/dcerpc/bare.py | 13 +++++++++++++ source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 4 ++++ 2 files changed, 17 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/bare.py b/source4/scripting/python/samba/tests/dcerpc/bare.py index dae1dedeb3..eea6744e42 100644 --- a/source4/scripting/python/samba/tests/dcerpc/bare.py +++ b/source4/scripting/python/samba/tests/dcerpc/bare.py @@ -28,3 +28,16 @@ class BareTestCase(TestCase): ("60a15ec5-4de8-11d7-a637-005056a20182", 1)) self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) + #def test_alter_context(self): + # x = ClientConnection("ncalrpc:localhost[DEFAULT]", + # ("12345778-1234-abcd-ef00-0123456789ac", 1)) + # x.alter_context(("60a15ec5-4de8-11d7-a637-005056a20182", 1)) + # self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) + + def test_two_connections(self): + x = ClientConnection("ncalrpc:localhost[DEFAULT]", + ("60a15ec5-4de8-11d7-a637-005056a20182", 1)) + y = ClientConnection("ncalrpc:localhost", + ("60a15ec5-4de8-11d7-a637-005056a20182", 1), + basis_connection=x) + self.assertEquals("\x01\x00\x00\x00", y.request(0, chr(0) * 4)) diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 83279a0b30..7fd1bcc5b8 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -26,6 +26,10 @@ class RpcEchoTests(RpcInterfaceTestCase): def setUp(self): self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm()) + def test_two_contexts(self): + self.conn2 = echo.rpcecho("ncalrpc", basis_connection=self.conn) + self.assertEquals(3, self.conn2.AddOne(2)) + def test_addone(self): self.assertEquals(2, self.conn.AddOne(1)) -- cgit From 74126bc6d0211a7674156dfda8ab13054b403a1d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 25 May 2008 04:54:38 +0200 Subject: Expose transfer and abstract syntax. (This used to be commit a875e07a37568b7e51c290074d5e3834c2caa4d6) --- source4/scripting/python/samba/tests/dcerpc/bare.py | 13 ++++++++----- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 4 ++++ 2 files changed, 12 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/bare.py b/source4/scripting/python/samba/tests/dcerpc/bare.py index eea6744e42..d75ffc381e 100644 --- a/source4/scripting/python/samba/tests/dcerpc/bare.py +++ b/source4/scripting/python/samba/tests/dcerpc/bare.py @@ -28,11 +28,14 @@ class BareTestCase(TestCase): ("60a15ec5-4de8-11d7-a637-005056a20182", 1)) self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) - #def test_alter_context(self): - # x = ClientConnection("ncalrpc:localhost[DEFAULT]", - # ("12345778-1234-abcd-ef00-0123456789ac", 1)) - # x.alter_context(("60a15ec5-4de8-11d7-a637-005056a20182", 1)) - # self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) + def test_alter_context(self): + x = ClientConnection("ncalrpc:localhost[DEFAULT]", + ("12345778-1234-abcd-ef00-0123456789ac", 1)) + y = ClientConnection("ncalrpc:localhost", + ("60a15ec5-4de8-11d7-a637-005056a20182", 1), + basis_connection=x) + x.alter_context(("60a15ec5-4de8-11d7-a637-005056a20182", 1)) + # FIXME: self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) def test_two_connections(self): x = ClientConnection("ncalrpc:localhost[DEFAULT]", diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 7fd1bcc5b8..68b7a42d52 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -30,6 +30,10 @@ class RpcEchoTests(RpcInterfaceTestCase): self.conn2 = echo.rpcecho("ncalrpc", basis_connection=self.conn) self.assertEquals(3, self.conn2.AddOne(2)) + def test_abstract_syntax(self): + self.assertEquals(("60a15ec5-4de8-11d7-a637-005056a20182", 1), + self.conn.abstract_syntax) + def test_addone(self): self.assertEquals(2, self.conn.AddOne(1)) -- cgit From 5df9e0576ebd8ad737bb2580b52788601b6cf854 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 25 May 2008 14:41:54 +0200 Subject: Fix missing colon. (This used to be commit 6b1576f544e2ea2b5ea0b234b724c4989dd49cca) --- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 68b7a42d52..bbbd0d76ec 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -27,7 +27,7 @@ class RpcEchoTests(RpcInterfaceTestCase): self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm()) def test_two_contexts(self): - self.conn2 = echo.rpcecho("ncalrpc", basis_connection=self.conn) + self.conn2 = echo.rpcecho("ncalrpc:", basis_connection=self.conn) self.assertEquals(3, self.conn2.AddOne(2)) def test_abstract_syntax(self): -- cgit From 976eca077d2ea9b44b4b62ae851ca9cc470e3729 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 17:56:49 +0200 Subject: Move some scripts to examples directory since they're not really generically useful. (This used to be commit 4026493e91f8096e5d602cd42f9a83d2d75042db) --- source4/scripting/python/examples/samr.py | 114 ++++++++++++++++++++++++++++ source4/scripting/python/examples/winreg.py | 87 +++++++++++++++++++++ 2 files changed, 201 insertions(+) create mode 100755 source4/scripting/python/examples/samr.py create mode 100755 source4/scripting/python/examples/winreg.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/examples/samr.py b/source4/scripting/python/examples/samr.py new file mode 100755 index 0000000000..1f2afbe688 --- /dev/null +++ b/source4/scripting/python/examples/samr.py @@ -0,0 +1,114 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Unix SMB/CIFS implementation. +# Copyright © Jelmer Vernooij 2008 +# +# Based on samr.js © Andrew Tridgell +# +# 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 . +# + +import sys + +sys.path.insert(0, "bin/python") + +from samba.dcerpc import samr, security, lsa + +def FillUserInfo(samr, dom_handle, users, level): + """fill a user array with user information from samrQueryUserInfo""" + for i in range(len(users)): + user_handle = samr.OpenUser(handle, security.SEC_FLAG_MAXIMUM_ALLOWED, users[i].idx) + info = samr.QueryUserInfo(user_handle, level) + info.name = users[i].name + info.idx = users[i].idx + users[i] = info + samr.Close(user_handle) + +def toArray((handle, array, num_entries)): + ret = [] + for x in range(num_entries): + ret.append((array.entries[x].idx, array.entries[x].name)) + return ret + + +def test_Connect(samr): + """test the samr_Connect interface""" + print "Testing samr_Connect" + return samr.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) + +def test_LookupDomain(samr, handle, domain): + """test the samr_LookupDomain interface""" + print "Testing samr_LookupDomain" + return samr.LookupDomain(handle, domain) + +def test_OpenDomain(samr, handle, sid): + """test the samr_OpenDomain interface""" + print "Testing samr_OpenDomain" + return samr.OpenDomain(handle, security.SEC_FLAG_MAXIMUM_ALLOWED, sid) + +def test_EnumDomainUsers(samr, dom_handle): + """test the samr_EnumDomainUsers interface""" + print "Testing samr_EnumDomainUsers" + users = toArray(samr.EnumDomainUsers(dom_handle, 0, 0, -1)) + print "Found %d users" % len(users) + for idx, user in users: + print "\t%s\t(%d)" % (user, idx) + +def test_EnumDomainGroups(samr, dom_handle): + """test the samr_EnumDomainGroups interface""" + print "Testing samr_EnumDomainGroups" + groups = toArray(samr.EnumDomainGroups(dom_handle, 0, 0)) + print "Found %d groups" % len(groups) + for idx, group in groups: + print "\t%s\t(%d)" % (group, idx) + +def test_domain_ops(samr, dom_handle): + """test domain specific ops""" + test_EnumDomainUsers(samr, dom_handle) + test_EnumDomainGroups(samr, dom_handle) + +def test_EnumDomains(samr, handle): + """test the samr_EnumDomains interface""" + print "Testing samr_EnumDomains" + + domains = toArray(samr.EnumDomains(handle, 0, -1)) + print "Found %d domains" % len(domains) + for idx, domain in domains: + print "\t%s (%d)" % (domain, idx) + for idx, domain in domains: + print "Testing domain %s" % domain + sid = samr.LookupDomain(handle, domain) + dom_handle = test_OpenDomain(samr, handle, sid) + test_domain_ops(samr, dom_handle) + samr.Close(dom_handle) + +if len(sys.argv) != 2: + print "Usage: samr.js " + sys.exit(1) + +binding = sys.argv[1] + +print "Connecting to %s" % binding +try: + samr = samr.samr(binding) +except Exception, e: + print "Failed to connect to %s: %s" % (binding, e.message) + sys.exit(1) + +handle = test_Connect(samr) +test_EnumDomains(samr, handle) +samr.Close(handle) + +print "All OK" diff --git a/source4/scripting/python/examples/winreg.py b/source4/scripting/python/examples/winreg.py new file mode 100755 index 0000000000..19d39e56ab --- /dev/null +++ b/source4/scripting/python/examples/winreg.py @@ -0,0 +1,87 @@ +#!/usr/bin/python +# +# tool to manipulate a remote registry +# Copyright Andrew Tridgell 2005 +# Copyright Jelmer Vernooij 2007 +# Released under the GNU GPL v3 or later +# + +import sys + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + +import winreg +import optparse +import samba.getopt as options + +parser = optparse.OptionParser("%s [path]" % sys.argv[0]) +sambaopts = options.SambaOptions(parser) +parser.add_option_group(sambaopts) +parser.add_option("--createkey", type="string", metavar="KEYNAME", + help="create a key") + +opts, args = parser.parse_args() + +if len(args) < 1: + parser.print_usage() + sys.exit(-1) + +binding = args[0] + +print "Connecting to " + binding +conn = winreg.winreg(binding, sambaopts.get_loadparm()) + +def list_values(key): + (num_values, max_valnamelen, max_valbufsize) = conn.QueryInfoKey(key, winreg.String())[4:8] + for i in range(num_values): + name = winreg.StringBuf() + name.size = max_valnamelen + (name, type, data, _, data_len) = conn.EnumValue(key, i, name, 0, "", max_valbufsize, 0) + print "\ttype=%-30s size=%4d '%s'" % type, len, name + if type in (winreg.REG_SZ, winreg.REG_EXPAND_SZ): + print "\t\t'%s'" % data +# if (v.type == reg.REG_MULTI_SZ) { +# for (j in v.value) { +# printf("\t\t'%s'\n", v.value[j]) +# } +# } +# if (v.type == reg.REG_DWORD || v.type == reg.REG_DWORD_BIG_ENDIAN) { +# printf("\t\t0x%08x (%d)\n", v.value, v.value) +# } +# if (v.type == reg.REG_QWORD) { +# printf("\t\t0x%llx (%lld)\n", v.value, v.value) +# } + +def list_path(key, path): + count = 0 + (num_subkeys, max_subkeylen, max_subkeysize) = conn.QueryInfoKey(key, winreg.String())[1:4] + for i in range(num_subkeys): + name = winreg.StringBuf() + name.size = max_subkeysize + keyclass = winreg.StringBuf() + keyclass.size = max_subkeysize + (name, _, _) = conn.EnumKey(key, i, name, keyclass=keyclass, last_changed_time=None)[0] + subkey = conn.OpenKey(key, name, 0, winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + count += list_path(subkey, "%s\\%s" % (path, name)) + list_values(subkey) + return count + +if len(args) > 1: + root = args[1] +else: + root = "HKLM" + +if opts.createkey: + reg.create_key("HKLM\\SOFTWARE", opt.createkey) +else: + print "Listing registry tree '%s'" % root + try: + root_key = getattr(conn, "Open%s" % root)(None, winreg.KEY_QUERY_VALUE | winreg.KEY_ENUMERATE_SUB_KEYS) + except AttributeError: + print "Unknown root key name %s" % root + sys.exit(1) + count = list_path(root_key, root) + if count == 0: + print "No entries found" + sys.exit(1) -- cgit From 58b1ab92a117cfcb311bdcb41fe563077ad39500 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 17:52:44 +0200 Subject: Fix import. (This used to be commit 17231443a0e3b0ebc4b75db3d721fe0b4e1170c6) --- source4/scripting/python/examples/winreg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/examples/winreg.py b/source4/scripting/python/examples/winreg.py index 19d39e56ab..80b48ecfd7 100755 --- a/source4/scripting/python/examples/winreg.py +++ b/source4/scripting/python/examples/winreg.py @@ -11,7 +11,7 @@ import sys # Find right directory when running from source tree sys.path.insert(0, "bin/python") -import winreg +from samba.dcerpc import winreg import optparse import samba.getopt as options -- cgit From 815c0ef2ed3bafe44c687dffe97b309b00df7a8c Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 23 May 2008 02:20:35 -0500 Subject: provision: Add missing string parameter token when assigning ldap_backend. (This used to be commit 7d26145a7fba22b2e1c7c57053aab3180a22089d) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3914fa8376..4a9def8aa9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -969,7 +969,7 @@ def provision(setup_dir, message, session_info, if ldap_backend is not None: if ldap_backend == "ldapi": # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + ldap_backend = "ldapi://%s" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): -- cgit From b7c8e020a6f7221d6d10f2dd7610a232edeedf83 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 May 2008 18:38:17 +1000 Subject: Print prefixMap in a human-readable format. This should allow the prefixMap to be edited, until we find the right way to autogenerate it. Andrew Bartlett (This used to be commit 24ae9a55ec326807afd8d5bfa0a422a6668bd7c3) --- source4/scripting/python/samba/provision.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4a9def8aa9..71c1ac3187 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -797,13 +797,17 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") + + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": names.schemadn, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, - "SERVERDN": names.serverdn + "SERVERDN": names.serverdn, + "PREFIXMAP_B64": b64encode(prefixmap) }) message("Setting up sam.ldb Samba4 schema") @@ -1389,12 +1393,16 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + prefixmap = b64encode(prefixmap) + head_data = open(setup_path("provision_schema_basedn_modify.ldif"), 'r').read() head_data = substitute_var(head_data, { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE":sitename + "DEFAULTSITE":sitename, + "PREFIXMAP_B64":prefixmap }) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 90aeca8ebdd74250038a11d4c523c01072711092 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 May 2008 17:29:56 +0200 Subject: Check test directory is cleaned up by Python tests. (This used to be commit c338269b4b9f2bf4d3386880c1d733a8e47e2c8d) --- source4/scripting/python/samba/tests/__init__.py | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index e29b4a87d5..d827bfa004 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -47,6 +47,7 @@ class TestCaseInTempDir(unittest.TestCase): def tearDown(self): super(TestCaseInTempDir, self).tearDown() + self.assertEquals([], os.listdir(self.tempdir)) os.rmdir(self.tempdir) -- cgit From e16f0e15b40229e7a42311dddfb391cf6142462e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 May 2008 17:31:16 +0200 Subject: Update after changes to the provision API, make sure temp dir gets cleaned up. (This used to be commit 064e9ddb3786bd7df8785b39754b1e6674496b66) --- source4/scripting/python/samba/tests/samdb.py | 29 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 0d4f7bde0e..a022d7bb51 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -16,13 +16,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # -from auth import system_session -from credentials import Credentials +from samba.auth import system_session +from samba.credentials import Credentials import os -from samba.provision import setup_samdb +from samba.provision import setup_samdb, guess_names from samba.samdb import SamDB from samba.tests import cmdline_loadparm, TestCaseInTempDir -import security +from samba import security from unittest import TestCase import uuid @@ -42,14 +42,23 @@ class SamDBTestCase(TestCaseInTempDir): domainsid = security.random_sid() hostguid = str(uuid.uuid4()) path = os.path.join(self.tempdir, "samdb.ldb") + names = guess_names(lp=cmdline_loadparm, hostname="foo", + domain="EXAMPLE.COM", dnsdomain="example.com", + serverrole="domain controller", + domaindn=self.domaindn, configdn=configdn, + schemadn=schemadn) self.samdb = setup_samdb(path, setup_path, system_session(), creds, - cmdline_loadparm, schemadn, configdn, - self.domaindn, "example.com", "EXAMPLE.COM", - "FOO", lambda x: None, "foo", domaindn, - False, domainsid, "# no aci", domainguid, - policyguid, "EXAMPLE", True, "secret", - "secret", "secret", hostguid, invocationid, + cmdline_loadparm, names, + lambda x: None, domainsid, + "# no aci", domainguid, + policyguid, False, "secret", + "secret", "secret", invocationid, "secret", "domain controller") + def tearDown(self): + for f in ['templates.ldb', 'schema.ldb', 'configuration.ldb', + 'users.ldb', 'samdb.ldb']: + os.remove(os.path.join(self.tempdir, f)) + super(SamDBTestCase, self).tearDown() def test_add_foreign(self): self.samdb.add_foreign(self.domaindn, "S-1-5-7", "Somedescription") -- cgit From 6f7b2b69333230016a9538b024faec0d97095c69 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 29 May 2008 17:38:12 +0200 Subject: Fix samdb test and enable it. (This used to be commit 6b202d3780f8ff50e0bdfa4a749c43b5639e4880) --- source4/scripting/python/samba/tests/samdb.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index a022d7bb51..7e8ba053d4 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -19,7 +19,7 @@ from samba.auth import system_session from samba.credentials import Credentials import os -from samba.provision import setup_samdb, guess_names +from samba.provision import setup_samdb, guess_names, setup_templatesdb from samba.samdb import SamDB from samba.tests import cmdline_loadparm, TestCaseInTempDir from samba import security @@ -42,12 +42,16 @@ class SamDBTestCase(TestCaseInTempDir): domainsid = security.random_sid() hostguid = str(uuid.uuid4()) path = os.path.join(self.tempdir, "samdb.ldb") + session_info = system_session() names = guess_names(lp=cmdline_loadparm, hostname="foo", domain="EXAMPLE.COM", dnsdomain="example.com", serverrole="domain controller", domaindn=self.domaindn, configdn=configdn, schemadn=schemadn) - self.samdb = setup_samdb(path, setup_path, system_session(), creds, + setup_templatesdb(os.path.join(self.tempdir, "templates.ldb"), + setup_path, session_info=session_info, + credentials=creds, lp=cmdline_loadparm) + self.samdb = setup_samdb(path, setup_path, session_info, creds, cmdline_loadparm, names, lambda x: None, domainsid, "# no aci", domainguid, -- cgit From 39f50afc579f208300c3c1fcc612ca9b69bb76e3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 May 2008 02:07:28 +0200 Subject: Move CFLAGS handling out of smb_build. (This used to be commit e2b71a0ecbf10a78a59a8ec6371bdee57b1bfa6c) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index b494ee6e8d..af014a8c9e 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -21,7 +21,7 @@ PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS python_misc_OBJ_FILES = $(pyscriptsrcdir)/misc_wrap.o -$(python_misc_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) +$(python_misc_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) $(LDB_CFLAGS) _PY_FILES = $(shell find $(pyscriptsrcdir)/samba $(pyscriptsrcdir)/subunit -name "*.py") -- cgit From b9babfe4cc70b96f4f1df037244cd27eae580c94 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 30 May 2008 14:26:47 +1000 Subject: Fix up provision and samdb tests. This fixes up the provision to operate with a target directory - it must override the smb.conf in this case. Andrew Bartlett (This used to be commit 89fc39f7edb214065aff461bc225f41443eae3c7) --- source4/scripting/python/samba/provision.py | 5 +++-- source4/scripting/python/samba/tests/samdb.py | 25 ++++++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 71c1ac3187..b7112e16c3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -930,8 +930,9 @@ def provision(setup_dir, message, session_info, if aci is None: aci = "# no aci for local ldb" - if smbconf is None: - os.makedirs(os.path.join(targetdir, "etc")) + if targetdir is not None: + if (not os.path.exists(os.path.join(targetdir, "etc"))): + os.makedirs(os.path.join(targetdir, "etc")) smbconf = os.path.join(targetdir, "etc", "smb.conf") # only install a new smb.conf if there isn't one there already diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 7e8ba053d4..fcf93a3fc6 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -19,12 +19,13 @@ from samba.auth import system_session from samba.credentials import Credentials import os -from samba.provision import setup_samdb, guess_names, setup_templatesdb +from samba.provision import setup_samdb, guess_names, setup_templatesdb, make_smbconf from samba.samdb import SamDB from samba.tests import cmdline_loadparm, TestCaseInTempDir from samba import security from unittest import TestCase import uuid +import param class SamDBTestCase(TestCaseInTempDir): def setUp(self): @@ -43,9 +44,22 @@ class SamDBTestCase(TestCaseInTempDir): hostguid = str(uuid.uuid4()) path = os.path.join(self.tempdir, "samdb.ldb") session_info = system_session() - names = guess_names(lp=cmdline_loadparm, hostname="foo", - domain="EXAMPLE.COM", dnsdomain="example.com", - serverrole="domain controller", + + hostname="foo" + domain="EXAMPLE" + dnsdomain="example.com" + serverrole="domain controller" + + smbconf = os.path.join(self.tempdir, "smb.conf") + make_smbconf(smbconf, setup_path, hostname, domain, dnsdomain, serverrole, + self.tempdir) + + lp = param.LoadParm() + lp.load(smbconf) + + names = guess_names(lp=lp, hostname=hostname, + domain=domain, dnsdomain=dnsdomain, + serverrole=severrole, domaindn=self.domaindn, configdn=configdn, schemadn=schemadn) setup_templatesdb(os.path.join(self.tempdir, "templates.ldb"), @@ -58,9 +72,10 @@ class SamDBTestCase(TestCaseInTempDir): policyguid, False, "secret", "secret", "secret", invocationid, "secret", "domain controller") + def tearDown(self): for f in ['templates.ldb', 'schema.ldb', 'configuration.ldb', - 'users.ldb', 'samdb.ldb']: + 'users.ldb', 'samdb.ldb', 'smb.conf']: os.remove(os.path.join(self.tempdir, f)) super(SamDBTestCase, self).tearDown() -- cgit From d579540085133d3a3b273a653cea7f8da10ed5db Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 30 May 2008 15:09:59 +1000 Subject: Fix rpcecho test. (This used to be commit df8399ba9dee9d1c706a3e56451c9f2cade96dae) --- source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index bbbd0d76ec..96bb3923a6 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -27,7 +27,7 @@ class RpcEchoTests(RpcInterfaceTestCase): self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm()) def test_two_contexts(self): - self.conn2 = echo.rpcecho("ncalrpc:", basis_connection=self.conn) + self.conn2 = echo.rpcecho("ncalrpc:", self.get_loadparm(), basis_connection=self.conn) self.assertEquals(3, self.conn2.AddOne(2)) def test_abstract_syntax(self): -- cgit From 21377a7ea9800636a8bc96b3863f97062d7bf9d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 30 May 2008 15:26:10 +1000 Subject: Fix the samba4.dcerpc.bare.python test. The loadparm context isn't really optional, as otherwise we can't find the right server to connect to. Andrew Bartlett (This used to be commit 2b5acb5e95b46dd39c6f54b5bb7e15ddb180f7ec) --- source4/scripting/python/samba/tests/dcerpc/bare.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/tests/dcerpc/bare.py b/source4/scripting/python/samba/tests/dcerpc/bare.py index d75ffc381e..fae699a249 100644 --- a/source4/scripting/python/samba/tests/dcerpc/bare.py +++ b/source4/scripting/python/samba/tests/dcerpc/bare.py @@ -20,27 +20,28 @@ from samba.dcerpc import ClientConnection from unittest import TestCase +from samba.tests import cmdline_loadparm class BareTestCase(TestCase): def test_bare(self): # Connect to the echo pipe x = ClientConnection("ncalrpc:localhost[DEFAULT]", - ("60a15ec5-4de8-11d7-a637-005056a20182", 1)) + ("60a15ec5-4de8-11d7-a637-005056a20182", 1), lp_ctx=cmdline_loadparm) self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) def test_alter_context(self): x = ClientConnection("ncalrpc:localhost[DEFAULT]", - ("12345778-1234-abcd-ef00-0123456789ac", 1)) + ("12345778-1234-abcd-ef00-0123456789ac", 1), lp_ctx=cmdline_loadparm) y = ClientConnection("ncalrpc:localhost", ("60a15ec5-4de8-11d7-a637-005056a20182", 1), - basis_connection=x) + basis_connection=x, lp_ctx=cmdline_loadparm) x.alter_context(("60a15ec5-4de8-11d7-a637-005056a20182", 1)) # FIXME: self.assertEquals("\x01\x00\x00\x00", x.request(0, chr(0) * 4)) def test_two_connections(self): x = ClientConnection("ncalrpc:localhost[DEFAULT]", - ("60a15ec5-4de8-11d7-a637-005056a20182", 1)) + ("60a15ec5-4de8-11d7-a637-005056a20182", 1), lp_ctx=cmdline_loadparm) y = ClientConnection("ncalrpc:localhost", ("60a15ec5-4de8-11d7-a637-005056a20182", 1), - basis_connection=x) + basis_connection=x, lp_ctx=cmdline_loadparm) self.assertEquals("\x01\x00\x00\x00", y.request(0, chr(0) * 4)) -- cgit From 277287114679addc2ef26fbe6a82963f9cf1b196 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 May 2008 14:15:40 +0200 Subject: Fix samdb python test. (This used to be commit 0e3d488cc108174ca0f875aab16b9771c2933f19) --- source4/scripting/python/samba/provision.py | 6 +++--- source4/scripting/python/samba/tests/samdb.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b7112e16c3..3f936c3301 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1321,12 +1321,12 @@ def create_zone_file(path, setup_path, dnsdomain, domaindn, """ assert isinstance(domainguid, str) - hostip6_base_line = "" - hostip6_host_line = "" - if hostip6 is not None: hostip6_base_line = " IN AAAA " + hostip6 hostip6_host_line = hostname + " IN AAAA " + hostip6 + else: + hostip6_base_line = "" + hostip6_host_line = "" setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index fcf93a3fc6..97be5672ce 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -25,7 +25,7 @@ from samba.tests import cmdline_loadparm, TestCaseInTempDir from samba import security from unittest import TestCase import uuid -import param +from samba import param class SamDBTestCase(TestCaseInTempDir): def setUp(self): @@ -59,7 +59,7 @@ class SamDBTestCase(TestCaseInTempDir): names = guess_names(lp=lp, hostname=hostname, domain=domain, dnsdomain=dnsdomain, - serverrole=severrole, + serverrole=serverrole, domaindn=self.domaindn, configdn=configdn, schemadn=schemadn) setup_templatesdb(os.path.join(self.tempdir, "templates.ldb"), -- cgit From be14efbdf9de964d36b1fdbc8dec909ad1d2601f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 31 May 2008 08:35:55 +1000 Subject: Revert Jelmer's CFLAGS commit e2b71a0ecbf10a78a59a8ec6371bdee57b1bfa6c This commit broke the build, because not all files (libreplace, popt) were updated. Andrew Bartlett (This used to be commit 3faacf4351d68a10aea78b53768571d2059772ae) --- source4/scripting/python/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index af014a8c9e..b494ee6e8d 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -21,7 +21,7 @@ PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS python_misc_OBJ_FILES = $(pyscriptsrcdir)/misc_wrap.o -$(python_misc_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) $(LDB_CFLAGS) +$(python_misc_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) _PY_FILES = $(shell find $(pyscriptsrcdir)/samba $(pyscriptsrcdir)/subunit -name "*.py") -- cgit From 230503ad847f9514e95b57c48eeacbd619a1c9f5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 11 Jun 2008 00:05:58 +0200 Subject: Add working Python bindings for NBT. (This used to be commit 9c88f5e1de9db34751f16c2247fa91ae2445c5f7) --- source4/scripting/python/examples/netbios.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 source4/scripting/python/examples/netbios.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/examples/netbios.py b/source4/scripting/python/examples/netbios.py new file mode 100644 index 0000000000..3671076a59 --- /dev/null +++ b/source4/scripting/python/examples/netbios.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# + +from samba.netbios import Node + +n = Node() +(reply_from, names, addresses) = n.query_name("GANIEDA", "192.168.4.0", + timeout=4) + +print "Received reply from %s:" % (reply_from, ) +print "Names: %r" % (names, ) +print "Addresses: %r" % (addresses, ) -- cgit From 4c144bbc9ede305616a2f2fb91695f94d589c85e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 11 Jun 2008 00:11:11 +0200 Subject: Clarify error when SWIG can't be found - it's not required unless you intend to do development. (This used to be commit 0f57fcaa2e8af3e2b03ba401f4fda812fe55745b) --- source4/scripting/python/ac_pkg_swig.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/ac_pkg_swig.m4 b/source4/scripting/python/ac_pkg_swig.m4 index 013743c1a0..8d3561a0a7 100644 --- a/source4/scripting/python/ac_pkg_swig.m4 +++ b/source4/scripting/python/ac_pkg_swig.m4 @@ -109,7 +109,7 @@ AC_DEFUN([AC_PROG_SWIG],[ if test $available_major -ne $required_major \ -o $available_minor -ne $required_minor \ -o $available_patch -lt $required_patch ; then - AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org]) + AC_MSG_WARN([SWIG version >= $1 is required if you would like to work on the SWIG bindings. You have $swig_version. ]) SWIG='no' else AC_MSG_NOTICE([SWIG executable is '$SWIG']) -- cgit From 370f95acfc197759f9140876b31ac127d3a0e10c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 16 Jun 2008 17:51:42 -0400 Subject: Try to get a bit further with provisioning (This used to be commit 649f6c0c1084828dda7d50bd2904208192de77da) --- source4/scripting/python/samba/provision.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3f936c3301..93a4c8f502 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1180,6 +1180,8 @@ def provision_backend(setup_dir=None, message=None, schemadb = Ldb(schemadb_path, lp=lp) + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"), {"SCHEMADN": names.schemadn, "ACI": "#", @@ -1191,7 +1193,8 @@ def provision_backend(setup_dir=None, message=None, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": DEFAULTSITE, "CONFIGDN": names.configdn, - "SERVERDN": names.serverdn + "SERVERDN": names.serverdn, + "PREFIXMAP_B64": b64encode(prefixmap) }) setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"), -- cgit From 9ea25cacf1c564a485897432b73beebf2e634f55 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 19 Jun 2008 11:05:20 +1000 Subject: Add a blackbox test for the provision-backend script. This test (as most tests do :-) found a few bugs, also fixed in this commit. Andrew Bartlett (This used to be commit d96a6482dad54d1d27a87107865e833a9c32cf53) --- source4/scripting/python/samba/provision.py | 57 +++++++++++++++-------------- 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 93a4c8f502..504044253e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1150,15 +1150,18 @@ def provision_backend(setup_dir=None, message=None, if root is None: root = findnss(pwd.getpwnam, ["root"])[0] - if smbconf is None: - etcdir = os.path.join(targetdir, "etc") - os.makedirs(etcdir) - smbconf = os.path.join(etcdir, "smb.conf") + if adminpass is None: + adminpass = misc.random_password(12) + + if targetdir is not None: + if (not os.path.exists(os.path.join(targetdir, "etc"))): + os.makedirs(os.path.join(targetdir, "etc")) + smbconf = os.path.join(targetdir, "etc", "smb.conf") # only install a new smb.conf if there isn't one there already if not os.path.exists(smbconf): - make_smbconf(smbconf, setup_path, hostname, domain, realm, - serverrole, targetdir) + make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, + targetdir) lp = param.LoadParm() lp.load(smbconf) @@ -1230,11 +1233,11 @@ def provision_backend(setup_dir=None, message=None, elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] - res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) - memberof_config = "# Generated from schema in %s\n" % schemadb_path - refint_attributes = "" - for i in range (0, len(res)): + memberof_config = "# Generated from schema in %s\n" % schemadb_path + refint_attributes = "" + for i in range (0, len(res)): expression = "(&(objectclass=attributeSchema)(linkID=%d))" % (int(res[i]["linkID"][0])+1) target = schemadb.searchone(basedn=names.schemadn, expression=expression, @@ -1252,11 +1255,11 @@ memberof-dangling-error 32 """ - memberof_config += """ + memberof_config += """ overlay refint refint_attributes""" + refint_attributes + "\n" - setup_file(setup_path("slapd.conf"), paths.slapdconf, + setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, "LDAPDIR": paths.ldapdir, "DOMAINDN": names.domaindn, @@ -1265,27 +1268,27 @@ refint_attributes""" + refint_attributes + "\n" "LDAPMANAGERDN": names.ldapmanagerdn, "LDAPMANAGERPASS": adminpass, "MEMBEROF_CONFIG": memberof_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" - - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - if ldap_backend_port is not None: - server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port - else: - server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" - schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + if ldap_backend_port is not None: + server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port + else: + server_port_string = "" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) + os.system(schema_command) - message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ldap_backend_type) message("Server Role: %s" % serverrole) message("Hostname: %s" % names.hostname) -- cgit From 44ea6a26fd088f0f8c86817510ebe5a6cddf9158 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 12 Jul 2008 15:26:42 +1000 Subject: rename sambaPassword -> userPassword. This attribute is used in a very similar way (virtual attribute updating the password) in AD on Win2003, so eliminate the difference. This should not cause a problem for on-disk passwords, as by default we do not store the plaintext at all. Andrew Bartlett (This used to be commit 1cf0d751493b709ef6b2234ec8847a7499f48ab3) --- source4/scripting/python/samba/samdb.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 6465f49519..c47cf4a0dc 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -112,7 +112,7 @@ userAccountControl: %u # now the real work self.add({"dn": user_dn, "sAMAccountName": username, - "sambaPassword": password, + "userPassword": password, "objectClass": "user"}) res = self.search(user_dn, scope=ldb.SCOPE_BASE, @@ -163,8 +163,8 @@ userAccountControl: %u setpw = """ dn: %s changetype: modify -replace: sambaPassword -sambaPassword: %s +replace: userPassword +userPassword: %s """ % (user_dn, password) self.modify_ldif(setpw) -- cgit From a6b842f9634cbeb4075c2bbaf7e49c19104602be Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:15:12 +1000 Subject: Connect to the LDAP backend with SASL credentials. This reworks our LDAP backend code to move from anonymous access to a shared-secret SASL-protected connection. (SASL selects NTLM or DIGEST-MD5 on my system). To get this working, we must pre-populate the LDAP backend with a DN to store ths SASL secret on, and we use back-ldif for this. This gives us a reasonable basis to deploy a replicated OpenLDAP backend solution. Andrew Bartlett (This used to be commit cd0745253c4a9ec59a035e830e54d74a05b71aaa) --- source4/scripting/python/samba/provision.py | 47 +++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 504044253e..d0f612c7a8 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -604,6 +604,20 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) + + if credentials.authentication_requested: + if credentials.get_bind_dn() is not None: + setup_add_ldif(secrets_ldb, setup_path("secrets_simple_ldap.ldif"), { + "LDAPMANAGERDN": credentials.get_bind_dn(), + "LDAPMANAGERPASS_B64": b64encode(credentials.get_password()) + }) + else: + setup_add_ldif(secrets_ldb, setup_path("secrets_sasl_ldap.ldif"), { + "LDAPADMINUSER": credentials.get_username(), + "LDAPADMINREALM": credentials.get_realm(), + "LDAPADMINPASS_B64": b64encode(credentials.get_password()) + }) + return secrets_ldb @@ -754,10 +768,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domain_oc = "samba4LocalDomain" setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { - "DOMAINDN": names.domaindn, - "ACI": aci, - "DOMAIN_OC": domain_oc - }) + "DOMAINDN": names.domaindn, + "ACI": aci, + "DOMAIN_OC": domain_oc + }) message("Modifying DomainDN: " + names.domaindn + "") if domainguid is not None: @@ -1265,15 +1279,30 @@ refint_attributes""" + refint_attributes + "\n" "DOMAINDN": names.domaindn, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, - "LDAPMANAGERDN": names.ldapmanagerdn, - "LDAPMANAGERPASS": adminpass, "MEMBEROF_CONFIG": memberof_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "schema")) + + if not os.path.exists(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")): + os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")) + + setup_file(setup_path("cn=samba.ldif"), + os.path.join(paths.ldapdir, "db", "samba", "cn=samba.ldif"), + { "UUID": str(uuid.uuid4()), + "LDAPTIME": timestring(int(time.time()))} ) + setup_file(setup_path("cn=samba-admin.ldif"), + os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=samba-admin.ldif"), + {"LDAPADMINPASS_B64": b64encode(adminpass), + "UUID": str(uuid.uuid4()), + "LDAPTIME": timestring(int(time.time()))} ) + +#"LDAPMANAGERDN": names.ldapmanagerdn, + + mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From 0f1eea267257eff0d75a702ee0793a86834fb76a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:46:32 +1000 Subject: Rework provision to handle both simple and SASL binds. Fedora DS is still setup for simple binds only, at this point. (it also fails on other issues). Andrew Bartlett (This used to be commit b24c572d5a38c1f6906751c2ad2f809e1995b510) --- source4/scripting/python/samba/provision.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d0f612c7a8..f27cc17290 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1300,9 +1300,6 @@ refint_attributes""" + refint_attributes + "\n" "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) -#"LDAPMANAGERDN": names.ldapmanagerdn, - - mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" @@ -1323,7 +1320,12 @@ refint_attributes""" + refint_attributes + "\n" message("Hostname: %s" % names.hostname) message("DNS Domain: %s" % names.dnsdomain) message("Base DN: %s" % names.domaindn) - message("LDAP admin DN: %s" % names.ldapmanagerdn) + + if ldap_backend_type == "openldap": + message("LDAP admin user: samba-admin") + else: + message("LDAP admin DN: %s" % names.ldapmanagerdn) + message("LDAP admin password: %s" % adminpass) message(slapdcommand) -- cgit From e400b3ec4e7f32406ed8803ed22612033511d99a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 18:44:58 +1000 Subject: Fix asking for credentials for non-LDAP provisions. (This used to be commit 78416f4840df4f8d1f9cc5e46a48b19c86888050) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f27cc17290..6102dc77ff 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -605,7 +605,7 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) - if credentials.authentication_requested: + if credentials is not None and credentials.authentication_requested(): if credentials.get_bind_dn() is not None: setup_add_ldif(secrets_ldb, setup_path("secrets_simple_ldap.ldif"), { "LDAPMANAGERDN": credentials.get_bind_dn(), -- cgit From fe9fa62a0529f8c8ebdbfee9b994e3787d4db58f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jul 2008 14:04:24 +1000 Subject: Reorder whitespace in generated slapd.conf This helps us see the real groupings in the generated memberOf handling. Andrew Bartlett (This used to be commit ec70ebb8310e563324233662f8e779c55fb87514) --- source4/scripting/python/samba/provision.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6102dc77ff..17e7e0fed0 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1266,12 +1266,12 @@ memberof-group-oc top memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ memberof-memberof-ad """ + target + """ memberof-dangling-error 32 - """ - memberof_config += """ -overlay refint -refint_attributes""" + refint_attributes + "\n" + memberof_config += """overlay refint +refint_attributes""" + refint_attributes + """ + +""" setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, -- cgit From cfc2063f230491865edb8f73174e0b12ab4dc158 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jul 2008 18:44:07 +1000 Subject: Put the memberof template into a seperate setup/ file. Set a memberof-dn in a fruitless attempt to fix the ACL problem I'm having with OpenLDAP Andrew Bartlett (This used to be commit 6d6e03834a1a77a8ceba41fbe8c9d49680065ba3) --- source4/scripting/python/samba/provision.py | 60 +++++++++++++---------------- 1 file changed, 27 insertions(+), 33 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 17e7e0fed0..301c6ef728 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -153,6 +153,19 @@ def open_ldb(session_info, credentials, lp, dbname): lp=lp) +def read_and_sub_file(file, subst_vars): + """Read a file and sub in variables found in it + + :param file: File to be read (typically from setup directory) + param subst_vars: Optional variables to subsitute in the file. + """ + data = open(file, 'r').read() + if subst_vars is not None: + data = substitute_var(data, subst_vars) + check_all_substituted(data) + return data + + def setup_add_ldif(ldb, ldif_path, subst_vars=None): """Setup a ldb in the private dir. @@ -162,27 +175,18 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None): """ assert isinstance(ldif_path, str) - data = open(ldif_path, 'r').read() - if subst_vars is not None: - data = substitute_var(data, subst_vars) - - check_all_substituted(data) - + data = read_and_sub_file(ldif_path, subst_vars) ldb.add_ldif(data) -def setup_modify_ldif(ldb, ldif_path, substvars=None): +def setup_modify_ldif(ldb, ldif_path, subst_vars=None): """Modify a ldb in the private dir. :param ldb: LDB object. :param ldif_path: LDIF file path. - :param substvars: Optional dictionary with substitution variables. + :param subst_vars: Optional dictionary with substitution variables. """ - data = open(ldif_path, 'r').read() - if substvars is not None: - data = substitute_var(data, substvars) - - check_all_substituted(data) + data = read_and_sub_file(ldif_path, subst_vars) ldb.modify_ldif(data) @@ -206,23 +210,19 @@ def setup_ldb(ldb, ldif_path, subst_vars): ldb.transaction_commit() -def setup_file(template, fname, substvars): +def setup_file(template, fname, subst_vars): """Setup a file in the private dir. :param template: Path of the template file. :param fname: Path of the file to create. - :param substvars: Substitution variables. + :param subst_vars: Substitution variables. """ f = fname if os.path.exists(f): os.unlink(f) - data = open(template, 'r').read() - if substvars: - data = substitute_var(data, substvars) - check_all_substituted(data) - + data = read_and_sub_file(template, subst_vars) open(f, 'w').write(data) @@ -1259,19 +1259,13 @@ def provision_backend(setup_dir=None, message=None, scope=SCOPE_SUBTREE) if target is not None: refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0] - memberof_config += """overlay memberof -memberof-dangling error -memberof-refint TRUE -memberof-group-oc top -memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ -memberof-memberof-ad """ + target + """ -memberof-dangling-error 32 -""" - - memberof_config += """overlay refint -refint_attributes""" + refint_attributes + """ - -""" + + memberof_config += read_and_sub_file(setup_path("memberof.conf"), + { "MEMBER_ATTR" : str(res[i]["lDAPDisplayName"][0]), + "MEMBEROF_ATTR" : str(target) }) + + memberof_config += """overlay refint +refint_attributes""" + refint_attributes setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, -- cgit From 3408a2d18fa61e2a7e3b3e05cc3c454e5e15f2ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jul 2008 18:58:56 +1000 Subject: Make a seperate template for the refint configuration too (This used to be commit d2a527acc5ee6fe9b943657dc9c3ace920b2d619) --- source4/scripting/python/samba/provision.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 301c6ef728..6eb47c8595 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1264,8 +1264,8 @@ def provision_backend(setup_dir=None, message=None, { "MEMBER_ATTR" : str(res[i]["lDAPDisplayName"][0]), "MEMBEROF_ATTR" : str(target) }) - memberof_config += """overlay refint -refint_attributes""" + refint_attributes + refint_config = read_and_sub_file(setup_path("refint.conf"), + { "LINK_ATTRS" : refint_attributes}) setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, @@ -1273,7 +1273,8 @@ refint_attributes""" + refint_attributes "DOMAINDN": names.domaindn, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, - "MEMBEROF_CONFIG": memberof_config}) + "MEMBEROF_CONFIG": memberof_config, + "REFINT_CONFIG": refint_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) -- cgit From fb3e663678be412df4668b05e76480908da2c080 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 22 Jul 2008 11:06:47 +1000 Subject: Improve DNS and Group poicy configurations. - fixes bug #4813 (simplify DNS setup) - This reworks the named.conf to be a fully fledged include - This also moves the documentation into named.txt - improves bug #4900 (Group policy support in Samba) - by creating an empty GPT.INI - fixes bug #5582 (DNS: Enhanced zone file) - This is now closer to the zone file AD creates committed by Andrew Bartlett (This used to be commit 74d684f6b329d7dd573cdc55e16bb8e629474b02) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6eb47c8595..40b61a0ac4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1043,6 +1043,7 @@ def provision(setup_dir, message, session_info, policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", "{" + policyguid + "}") os.makedirs(policy_path, 0755) + open(os.path.join(policy_path, "GPT.INI"), 'w').write("") os.makedirs(os.path.join(policy_path, "Machine"), 0755) os.makedirs(os.path.join(policy_path, "User"), 0755) if not os.path.isdir(paths.netlogon): @@ -1081,12 +1082,11 @@ def provision(setup_dir, message, session_info, hostip6=hostip6, hostname=names.hostname, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) - message("Please install the zone located in %s into your DNS server" % paths.dns) create_named_conf(paths.namedconf, setup_path, realm=names.realm, dnsdomain=names.dnsdomain, private_dir=paths.private_dir, keytab_name=paths.dns_keytab) - message("See %s for example configuration statements for secure GSS-TSIG updates" % paths.namedconf) + message("See %s for an example configuration include file for BIND" % paths.namedconf) create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain, hostname=names.hostname, realm=names.realm) @@ -1394,6 +1394,7 @@ def create_named_conf(path, setup_path, realm, dnsdomain, "REALM_WC": "*." + ".".join(realm.split(".")[1:]), "DNS_KEYTAB": keytab_name, "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), + "PRIVATE_DIR": private_dir, }) def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): -- cgit From c9c296b6bbe178502e8aded8fa5e38a0f338ee18 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Jul 2008 11:09:18 +1000 Subject: Install'named.txt' to private/ as documentation. This document is much more use when subbed with all the right things. Andrew Bartlett (This used to be commit 136a85599815670c807f212d7d4003ec53a13729) --- source4/scripting/python/samba/provision.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 40b61a0ac4..4b310381ef 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -244,6 +244,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") paths.namedconf = os.path.join(paths.private_dir, "named.conf") + paths.namedtxt = os.path.join(paths.private_dir, "named.txt") paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") @@ -1084,9 +1085,13 @@ def provision(setup_dir, message, session_info, domainguid=domainguid, hostguid=hostguid) create_named_conf(paths.namedconf, setup_path, realm=names.realm, + dnsdomain=names.dnsdomain, private_dir=paths.private_dir) + + create_named_txt(paths.namedtxt, setup_path, realm=names.realm, dnsdomain=names.dnsdomain, private_dir=paths.private_dir, keytab_name=paths.dns_keytab) message("See %s for an example configuration include file for BIND" % paths.namedconf) + message("and %s for further documentation required for secure DNS updates" % paths.namedtxt) create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain, hostname=names.hostname, realm=names.realm) @@ -1376,7 +1381,7 @@ def create_zone_file(path, setup_path, dnsdomain, domaindn, def create_named_conf(path, setup_path, realm, dnsdomain, - private_dir, keytab_name): + private_dir): """Write out a file containing zone statements suitable for inclusion in a named.conf file (including GSS-TSIG configuration). @@ -1392,9 +1397,28 @@ def create_named_conf(path, setup_path, realm, dnsdomain, "DNSDOMAIN": dnsdomain, "REALM": realm, "REALM_WC": "*." + ".".join(realm.split(".")[1:]), + "PRIVATE_DIR": private_dir + }) + +def create_named_txt(path, setup_path, realm, dnsdomain, + private_dir, keytab_name): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param realm: Realm name + :param dnsdomain: DNS Domain name + :param private_dir: Path to private directory + :param keytab_name: File name of DNS keytab file + """ + + setup_file(setup_path("named.txt"), path, { + "DNSDOMAIN": dnsdomain, + "REALM": realm, "DNS_KEYTAB": keytab_name, "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), - "PRIVATE_DIR": private_dir, + "PRIVATE_DIR": private_dir }) def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): -- cgit From 11798902dc51cd9eea3b7e8a0c94d0c0c08ed828 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jul 2008 08:45:16 +1000 Subject: Complain if we are told to use an ldap backend, without the type (This used to be commit e9c3c9ad8289ee48efa998ab6b486250dcd40b52) --- source4/scripting/python/samba/provision.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6eb47c8595..67f8cf7cc2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -503,6 +503,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, backend_modules = ["normalise", "entryuuid", "paged_searches"] # OpenLDAP handles subtree renames, so we don't want to do any of these things tdb_modules_list = None + elif ldap_backend is not None: + raise "LDAP Backend specified, but LDAP Backend Type not specified" elif serverrole == "domain controller": backend_modules = ["repl_meta_data"] else: -- cgit From cff30c6da666abcb4ad8c587defa63883ce86c23 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 08:04:15 +1000 Subject: Remove unused function and make sensitive directories private. (This used to be commit e23333d16397606d38e90684d2d916b5b967cde4) --- source4/scripting/python/samba/provision.py | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0119f40c7f..068fe5ad9b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -133,26 +133,6 @@ findnss_uid = lambda names: findnss(pwd.getpwnam, names)[2] findnss_gid = lambda names: findnss(grp.getgrnam, names)[2] -def open_ldb(session_info, credentials, lp, dbname): - """Open a LDB, thrashing it if it is corrupt. - - :param session_info: auth session information - :param credentials: credentials - :param lp: Loadparm context - :param dbname: Path of the database to open. - :return: a Ldb object - """ - assert session_info is not None - try: - return Ldb(dbname, session_info=session_info, credentials=credentials, - lp=lp) - except LdbError, e: - print e - os.unlink(dbname) - return Ldb(dbname, session_info=session_info, credentials=credentials, - lp=lp) - - def read_and_sub_file(file, subst_vars): """Read a file and sub in variables found in it @@ -1195,7 +1175,7 @@ def provision_backend(setup_dir=None, message=None, paths = provision_paths_from_lp(lp, names.dnsdomain) if not os.path.isdir(paths.ldapdir): - os.makedirs(paths.ldapdir) + os.makedirs(paths.ldapdir, 0700) schemadb_path = os.path.join(paths.ldapdir, "schema-tmp.ldb") try: os.unlink(schemadb_path) @@ -1290,7 +1270,7 @@ def provision_backend(setup_dir=None, message=None, setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "schema")) if not os.path.exists(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")): - os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")) + os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba"), 0700) setup_file(setup_path("cn=samba.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba.ldif"), -- cgit From 45d60f5bd9be53ae4d4399664500709f1b2801a5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 20:18:17 +1000 Subject: Always print the slapd startup command (This used to be commit b1d05e7d14c65133e8ab0ff9d41a26fa7e3d41d3) --- source4/scripting/python/samba/provision.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 068fe5ad9b..8437909da1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1290,7 +1290,8 @@ def provision_backend(setup_dir=None, message=None, server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port else: server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) -- cgit From 08795db6d6af69442dfbfa7d39532e898d4c0ea6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 20:26:14 +1000 Subject: Make it even clearer what to do next in the LDAP backend setup (This used to be commit bace931ad674b5071d53bf9c99c383f1d8957e1b) --- source4/scripting/python/samba/provision.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8437909da1..13329e8b10 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1232,6 +1232,8 @@ def provision_backend(setup_dir=None, message=None, slapdcommand="Initailise Fedora DS with: setup-ds.pl --file=%s" % paths.fedoradsinf + ldapuser = "--simple-bind-dn=" + names.ldapmanagerdn + elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) @@ -1293,6 +1295,8 @@ def provision_backend(setup_dir=None, message=None, slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + ldapuser = "--username=samba-admin" + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) @@ -1311,7 +1315,7 @@ def provision_backend(setup_dir=None, message=None, message("LDAP admin password: %s" % adminpass) message(slapdcommand) - + message("Run provision with: --ldap-backend=ldapi --ldap-backend-type=" + ldap_backend_type + " --password=" + adminpass + " " + ldapuser) def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. -- cgit From e80115deb9f57d827f915b57b52961f1e2df682e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 20:51:02 +1000 Subject: We don't use EXTENSIBLEOBJECT any more. (This used to be commit 4b137085c8b89773d4639372bbffd516a41dfc8f) --- source4/scripting/python/samba/provision.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 13329e8b10..441d662b23 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -779,7 +779,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), { "CONFIGDN": names.configdn, "ACI": aci, - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), { @@ -791,7 +790,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), { "SCHEMADN": names.schemadn, "ACI": aci, - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") @@ -1189,7 +1187,6 @@ def provision_backend(setup_dir=None, message=None, setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"), {"SCHEMADN": names.schemadn, "ACI": "#", - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) setup_modify_ldif(schemadb, setup_path("provision_schema_basedn_modify.ldif"), \ -- cgit From 3573420d7d108d796e0b424c131061dc74c23033 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 20:17:29 +0200 Subject: Fix some forgotten substitute variables in provision, add check to prevent this sort of regression in the future. (This used to be commit a461118f3b668779f907c4d77cebe1e76fa4e39f) --- source4/scripting/python/samba/provision.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0119f40c7f..33aeff2008 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1453,6 +1453,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) + check_all_substituted(schema_data) prefixmap = open(setup_path("prefixMap.txt"), 'r').read() prefixmap = b64encode(prefixmap) @@ -1464,5 +1465,6 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): "DEFAULTSITE":sitename, "PREFIXMAP_B64":prefixmap }) + check_all_substituted(head_data) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 3b4ff07ded89703b2a58ae2c9ca6f0ea82bb5a52 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 20:47:03 +0200 Subject: Actually fix missing substitution variables. (This used to be commit 783412ecb27d646b171993da0ac2f11a821901d3) --- source4/scripting/python/samba/provision.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6b1fd33b9f..6dd9f3b8bd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -739,7 +739,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb.set_invocation_id(invocationid) load_schema(setup_path, samdb, names.schemadn, names.netbiosname, - names.configdn, names.sitename) + names.configdn, names.sitename, names.serverdn, + names.hostname) samdb.transaction_start() @@ -1423,7 +1424,8 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): }) -def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): +def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename, + serverdn, servername): """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. @@ -1431,6 +1433,8 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): :param schemadn: DN of the schema :param netbiosname: NetBIOS name of the host. :param configdn: DN of the configuration + :param serverdn: DN of the server + :param servername: Host name of the server """ schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() @@ -1444,8 +1448,10 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE":sitename, - "PREFIXMAP_B64":prefixmap + "DEFAULTSITE": sitename, + "PREFIXMAP_B64": prefixmap, + "SERVERDN": serverdn, + "SERVERNAME": servername, }) check_all_substituted(head_data) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From fff006bd84fc3fd1d9fdd22e3c20110285b2c144 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 20:47:22 +0200 Subject: Move domain DN determination out of newuser function. (This used to be commit cbac27e6faa99ebaa3e6d653017c968db836560a) --- source4/scripting/python/samba/samdb.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index c47cf4a0dc..c7d93d6aff 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -86,6 +86,14 @@ userAccountControl: %u """ % (user_dn, userAccountControl) self.modify_ldif(mod) + def domain_dn(self): + # find the DNs for the domain and the domain users group + res = self.search("", scope=ldb.SCOPE_BASE, + expression="(defaultNamingContext=*)", + attrs=["defaultNamingContext"]) + assert(len(res) == 1 and res[0]["defaultNamingContext"] is not None) + return res[0]["defaultNamingContext"][0] + def newuser(self, username, unixname, password): """add a new user record. @@ -96,12 +104,7 @@ userAccountControl: %u # connect to the sam self.transaction_start() - # find the DNs for the domain and the domain users group - res = self.search("", scope=ldb.SCOPE_BASE, - expression="(defaultNamingContext=*)", - attrs=["defaultNamingContext"]) - assert(len(res) == 1 and res[0]["defaultNamingContext"] is not None) - domain_dn = res[0]["defaultNamingContext"][0] + domain_dn = self.domain_dn() assert(domain_dn is not None) user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) -- cgit From 1c94f3e95da5b520ee631670a30f96e487f12ac8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 21:00:09 +0200 Subject: Use new style python classes. (This used to be commit 2a39aae0cef310a79427feb1b85f6794ea36849a) --- source4/scripting/python/samba/provision.py | 8 +++++--- source4/scripting/python/samba/samba3.py | 14 ++++++++------ source4/scripting/python/samba/samr.py | 8 +++++++- source4/scripting/python/samba/tests/dcerpc/bare.py | 1 + source4/scripting/python/samba/tests/dcerpc/registry.py | 1 + source4/scripting/python/samba/tests/dcerpc/rpcecho.py | 2 ++ source4/scripting/python/samba/tests/provision.py | 2 +- source4/scripting/python/samba/tests/samba3.py | 1 + source4/scripting/python/subunit/__init__.py | 2 +- 9 files changed, 27 insertions(+), 12 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6dd9f3b8bd..4f7fbfc6e6 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -53,7 +53,7 @@ class InvalidNetbiosName(Exception): super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) -class ProvisionPaths: +class ProvisionPaths(object): def __init__(self): self.shareconf = None self.hklm = None @@ -77,7 +77,8 @@ class ProvisionPaths: self.fedoradsinf = None self.fedoradspartitions = None -class ProvisionNames: + +class ProvisionNames(object): def __init__(self): self.rootdn = None self.domaindn = None @@ -92,7 +93,8 @@ class ProvisionNames: self.sitename = None self.smbconf = None -class ProvisionResult: + +class ProvisionResult(object): def __init__(self): self.paths = None self.domaindn = None diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index c1340b7760..0e0c29dac8 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -308,7 +308,7 @@ class ShareInfoDatabase(TdbDatabase): return secdesc -class Shares: +class Shares(object): """Container for share objects.""" def __init__(self, lp, shareinfo): self.lp = lp @@ -371,7 +371,7 @@ def decode_acb(text): return ret -class SAMUser: +class SAMUser(object): """Samba 3 SAM User. :note: Unknown or unset fields are set to None. @@ -421,7 +421,8 @@ class SAMUser: return False return self.__dict__ == other.__dict__ -class SmbpasswdFile: + +class SmbpasswdFile(object): """Samba 3 smbpasswd file reader.""" def __init__(self, file): self.users = {} @@ -482,7 +483,7 @@ TDBSAM_FORMAT_STRING_V2 = "dddddddBBBBBBBBBBBBddBBBwwdBwwd" TDBSAM_USER_PREFIX = "USER_" -class LdapSam: +class LdapSam(object): """Samba 3 LDAP passdb backend reader.""" def __init__(self, url): self.ldap_url = ldap_url @@ -605,7 +606,7 @@ def shellsplit(text): return ret -class WinsDatabase: +class WinsDatabase(object): """Samba 3 WINS database reader.""" def __init__(self, file): self.entries = {} @@ -643,7 +644,8 @@ class WinsDatabase: def close(self): # for consistency pass -class Samba3: + +class Samba3(object): """Samba 3 configuration and state data reader.""" def __init__(self, libdir, smbconfpath): """Open the configuration and data for a Samba 3 installation. diff --git a/source4/scripting/python/samba/samr.py b/source4/scripting/python/samba/samr.py index 314f78b8ad..62a7c6eb3d 100644 --- a/source4/scripting/python/samba/samr.py +++ b/source4/scripting/python/samba/samr.py @@ -97,7 +97,8 @@ def call_fn(fn, pipe, args): return result; -class SamrHandle: + +class SamrHandle(object): def __init__(self, pipe, handle): @@ -137,6 +138,7 @@ class SamrHandle: call_fn(dcerpc.dcerpc_samr_SetSecurity, self.pipe, r) + class ConnectHandle(SamrHandle): def EnumDomains(self): @@ -212,6 +214,7 @@ class ConnectHandle(SamrHandle): call_fn(dcerpc.dcerpc_samr_SetBootKeyInformation, self.pipe, r) + class DomainHandle(SamrHandle): def QueryDomainInfo(self, level = 2): @@ -517,6 +520,7 @@ class DomainHandle(SamrHandle): call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsDomain, self.pipe, r) + class UserHandle(SamrHandle): def DeleteUser(self): @@ -576,6 +580,7 @@ class UserHandle(SamrHandle): call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsUser, self.pipe, r) + class GroupHandle(SamrHandle): def QueryGroupInfo(self, level): @@ -608,6 +613,7 @@ class GroupHandle(SamrHandle): dcerpc.uint32_array_getitem(r.data_out.rids.unknown, x)) for x in range(r.data_out.rids.count)] + class AliasHandle(SamrHandle): def DeleteDomAlias(self): diff --git a/source4/scripting/python/samba/tests/dcerpc/bare.py b/source4/scripting/python/samba/tests/dcerpc/bare.py index fae699a249..cd939b8098 100644 --- a/source4/scripting/python/samba/tests/dcerpc/bare.py +++ b/source4/scripting/python/samba/tests/dcerpc/bare.py @@ -22,6 +22,7 @@ from samba.dcerpc import ClientConnection from unittest import TestCase from samba.tests import cmdline_loadparm + class BareTestCase(TestCase): def test_bare(self): # Connect to the echo pipe diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 81133ff641..526b2340cc 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -21,6 +21,7 @@ from samba.dcerpc import winreg import unittest from samba.tests import RpcInterfaceTestCase + class WinregTests(RpcInterfaceTestCase): def setUp(self): self.conn = winreg.winreg("ncalrpc:", self.get_loadparm(), diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 96bb3923a6..12638e2397 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -22,6 +22,7 @@ from samba.ndr import ndr_pack, ndr_unpack import unittest from samba.tests import RpcInterfaceTestCase + class RpcEchoTests(RpcInterfaceTestCase): def setUp(self): self.conn = echo.rpcecho("ncalrpc:", self.get_loadparm()) @@ -56,6 +57,7 @@ class RpcEchoTests(RpcInterfaceTestCase): def test_server_name(self): self.assertEquals(None, self.conn.server_name) + class NdrEchoTests(unittest.TestCase): def test_info1_push(self): x = echo.info1() diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 76c10145f0..352357f694 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -87,7 +87,7 @@ class FindNssTests(unittest.TestCase): self.assertEquals("ha", findnss(x, ["bloe", "bla"])) -class Disabled: +class Disabled(object): def test_setup_templatesdb(self): raise NotImplementedError(self.test_setup_templatesdb) diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index 175aa90497..1755cbdcf0 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -153,6 +153,7 @@ class WinsDatabaseTestCase(unittest.TestCase): def tearDown(self): self.winsdb.close() + class SmbpasswdTestCase(unittest.TestCase): def setUp(self): self.samdb = SmbpasswdFile(os.path.join(DATADIR, "smbpasswd")) diff --git a/source4/scripting/python/subunit/__init__.py b/source4/scripting/python/subunit/__init__.py index ac3d0c3a40..406cd8765b 100644 --- a/source4/scripting/python/subunit/__init__.py +++ b/source4/scripting/python/subunit/__init__.py @@ -376,7 +376,7 @@ def run_isolated(klass, self, result): return result -class SubunitTestRunner: +class SubunitTestRunner(object): def __init__(self, stream=sys.stdout): self.stream = stream -- cgit From 47124efe420f4f4f08494cbb2255eacdc9625c8d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 21:12:37 +0200 Subject: Add helper object Hostconfig to make it easier to get to e.g. the SAM database. (This used to be commit be75b2a36ee49f66ada3ec3ababa82d74085d559) --- source4/scripting/python/samba/getopt.py | 4 ++++ source4/scripting/python/samba/hostconfig.py | 33 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 source4/scripting/python/samba/hostconfig.py (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 9ecb66e21c..c12245f6c5 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -21,6 +21,7 @@ import optparse from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS +from hostconfig import Hostconfig __docformat__ = "restructuredText" @@ -52,6 +53,9 @@ class SambaOptions(optparse.OptionGroup): lp.load_default() return lp + def get_hostconfig(self): + return Hostconfig(self.get_loadparm()) + class VersionOptions(optparse.OptionGroup): """Command line option for printing Samba version.""" diff --git a/source4/scripting/python/samba/hostconfig.py b/source4/scripting/python/samba/hostconfig.py new file mode 100644 index 0000000000..313e3420b0 --- /dev/null +++ b/source4/scripting/python/samba/hostconfig.py @@ -0,0 +1,33 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Jelmer Vernooij 2008 +# +# 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 . +# + +from samdb import SamDB + +class Hostconfig(object): + """Aggregate object that contains all information about the configuration + of a Samba host.""" + + def __init__(self, lp): + self.lp = lp + + def get_samdb(self, session_info, credentials): + return SamDB(url=self.lp.get("sam database"), + session_info=session_info, credentials=credentials, + lp=self.lp) + -- cgit From 47d80366bef5e62b6727a574b2300cc94a2e18f7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2008 11:43:41 +1000 Subject: Fix templates.ldb reprovision handling. This sets the attributes in a seperate transaction, and allows a forced delete of the whole file. Andrew Bartlett (This used to be commit 423db2468ba3dac89cebc59c8498c0b08c5f3d7b) --- source4/scripting/python/samba/provision.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f7fbfc6e6..836509a620 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -617,7 +617,17 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): """ templates_ldb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) - templates_ldb.erase() + # Wipes the database + try: + templates_ldb.erase() + except: + os.unlink(path) + + templates_ldb.load_ldif_file_add(setup_path("provision_templates_init.ldif")) + + templates_ldb = SamDB(path, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif")) -- cgit From 805dd85291fa55695ee7ae2b8f6d3c168d9186e8 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Tue, 19 Aug 2008 12:03:04 +1000 Subject: Generate Multi-Master Replication configuration for OpenLDAP This patches provision-backend and the related scripts to generate the correct configuration blobs for N-way multi-master replication using OpenLDAP. Signed-off-by: Andrew Bartlett (This used to be commit 6ed0b3f2475022288f636605492ca27fde97cd52) --- source4/scripting/python/samba/provision.py | 86 ++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f7fbfc6e6..8abcc2f2e3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -76,7 +76,9 @@ class ProvisionPaths(object): self.memberofconf = None self.fedoradsinf = None self.fedoradspartitions = None - + self.olmmron = None + self.olmmrserveridsconf = None + self.olmmrsyncreplconf = None class ProvisionNames(object): def __init__(self): @@ -242,8 +244,12 @@ def provision_paths_from_lp(lp, dnsdomain): "memberof.conf") paths.fedoradsinf = os.path.join(paths.ldapdir, "fedorads.inf") - paths.fedoradspartitions = os.path.join(paths.ldapdir, - "fedorads-partitions.ldif") + paths.olmmrserveridsconf = os.path.join(paths.ldapdir, + "mmr_serverids.conf") + paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, + "mmr_syncrepl.conf") + paths.olmmron = os.path.join(paths.ldapdir, + "mmr_on.conf") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -331,7 +337,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= names.hostname = hostname names.sitename = sitename names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (netbiosname, sitename, configdn) - + return names @@ -1141,7 +1147,11 @@ def provision_backend(setup_dir=None, message=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, - ldap_backend_type=None, ldap_backend_port=None): + ldap_backend_type=None, ldap_backend_port=None, + ol_mmr_urls=None, mmr_serverids_config=None, mmr_on_config=None, + mmr_syncrepl_schema_config=None, + mmr_syncrepl_config_config=None, + mmr_syncrepl_user_config=None ): def setup_path(file): return os.path.join(setup_dir, file) @@ -1255,7 +1265,64 @@ def provision_backend(setup_dir=None, message=None, refint_config = read_and_sub_file(setup_path("refint.conf"), { "LINK_ATTRS" : refint_attributes}) - + +######################################################## +### generate serverids and ldap-urls for mmr hosts ### +######################################################## + + mmr_on_config = " " + mmr_serverids_config = " " + + if ol_mmr_urls is not None: + mmr_hosts=ol_mmr_urls + mmr_hosts=filter(None,mmr_hosts.split(' ')) + + mmr_serverids_config = "# Generated from template mmr_serverids.conf\n" + z=0 + for i in mmr_hosts: + z=z+1 + mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), + { "SERVERID" : str(z), + "LDAPSERVER" : i }) + mmr_on_config = "MirrorMode On" + +######################################################## +### generate syncrepl-blocks for mmr hosts ### +######################################################## + + mmr_syncrepl_schema_config = " " + mmr_syncrepl_config_config = " " + mmr_syncrepl_user_config = " " + + if ol_mmr_urls is not None: + mmr_hosts=ol_mmr_urls + mmr_hosts=filter(None,mmr_hosts.split(' ')) + mmr_syncrepl_schema_config = "# Generated from template mmr_syncrepl.conf\n" + mmr_syncrepl_config_config = "# Generated from template mmr_syncrepl.conf\n" + mmr_syncrepl_user_config = "# Generated from template mmr_syncrepl.conf\n" + z=0 + for i in mmr_hosts: + z=z+1 + mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(z), + "MMRDN": names.schemadn, + "LDAPSERVER" : i }) + + for i in mmr_hosts: + z=z+1 + mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(z), + "MMRDN": names.configdn, + "LDAPSERVER" : i }) + + for i in mmr_hosts: + z=z+1 + mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(z), + "MMRDN": names.domaindn, + "LDAPSERVER" : i }) + + setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, "LDAPDIR": paths.ldapdir, @@ -1263,8 +1330,13 @@ def provision_backend(setup_dir=None, message=None, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, "MEMBEROF_CONFIG": memberof_config, + "MIRRORMODE": mmr_on_config, + "MMR_SERVERIDS_CONFIG": mmr_serverids_config, + "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, + "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, + "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, "REFINT_CONFIG": refint_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) -- cgit From 7ef21658fbb519859aa7d23a614e1fdbcae95693 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2008 14:10:14 +1000 Subject: Fix up new OpenLDAP MMR code. This changes the MMR password from hard-coded value of 'linux', adds tests and fixes the Fedora DS backend. Currently the MMR password matches the admin password, but we can change this to be another random value if required. Also require the port to be specified on the command line, so we don't hard-code a port of 9000. Andrew Bartlett (This used to be commit 08257c6d6ce809fcd53f9b2b4d558fef616b74ce) --- source4/scripting/python/samba/provision.py | 67 +++++++++++------------------ 1 file changed, 26 insertions(+), 41 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8abcc2f2e3..f48a49dcfa 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -243,13 +243,13 @@ def provision_paths_from_lp(lp, dnsdomain): paths.memberofconf = os.path.join(paths.ldapdir, "memberof.conf") paths.fedoradsinf = os.path.join(paths.ldapdir, - "fedorads.inf") + "fedorads.inf") + paths.fedoradspartitions = os.path.join(paths.ldapdir, + "fedorads-partitions.ldif") paths.olmmrserveridsconf = os.path.join(paths.ldapdir, - "mmr_serverids.conf") + "mmr_serverids.conf") paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, - "mmr_syncrepl.conf") - paths.olmmron = os.path.join(paths.ldapdir, - "mmr_on.conf") + "mmr_syncrepl.conf") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1148,10 +1148,7 @@ def provision_backend(setup_dir=None, message=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, ldap_backend_type=None, ldap_backend_port=None, - ol_mmr_urls=None, mmr_serverids_config=None, mmr_on_config=None, - mmr_syncrepl_schema_config=None, - mmr_syncrepl_config_config=None, - mmr_syncrepl_user_config=None ): + ol_mmr_urls=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1266,61 +1263,48 @@ def provision_backend(setup_dir=None, message=None, refint_config = read_and_sub_file(setup_path("refint.conf"), { "LINK_ATTRS" : refint_attributes}) -######################################################## -### generate serverids and ldap-urls for mmr hosts ### -######################################################## - - mmr_on_config = " " - mmr_serverids_config = " " - +# generate serverids, ldap-urls and syncrepl-blocks for mmr hosts + mmr_on_config = "" + mmr_serverids_config = "" + mmr_syncrepl_schema_config = "" + mmr_syncrepl_config_config = "" + mmr_syncrepl_user_config = "" + if ol_mmr_urls is not None: - mmr_hosts=ol_mmr_urls - mmr_hosts=filter(None,mmr_hosts.split(' ')) + mmr_hosts=filter(None,ol_mmr_urls.split(' ')) + if (len(mmr_hosts) == 1): + mmr_hosts=filter(None,ol_mmr_urls.split(',')) + + + mmr_on_config = "MirrorMode On" - mmr_serverids_config = "# Generated from template mmr_serverids.conf\n" z=0 for i in mmr_hosts: z=z+1 mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), { "SERVERID" : str(z), "LDAPSERVER" : i }) - mmr_on_config = "MirrorMode On" - -######################################################## -### generate syncrepl-blocks for mmr hosts ### -######################################################## - mmr_syncrepl_schema_config = " " - mmr_syncrepl_config_config = " " - mmr_syncrepl_user_config = " " - - if ol_mmr_urls is not None: - mmr_hosts=ol_mmr_urls - mmr_hosts=filter(None,mmr_hosts.split(' ')) - mmr_syncrepl_schema_config = "# Generated from template mmr_syncrepl.conf\n" - mmr_syncrepl_config_config = "# Generated from template mmr_syncrepl.conf\n" - mmr_syncrepl_user_config = "# Generated from template mmr_syncrepl.conf\n" - z=0 - for i in mmr_hosts: z=z+1 mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(z), "MMRDN": names.schemadn, - "LDAPSERVER" : i }) + "LDAPSERVER" : i, + "MMR_PASSWORD": adminpass}) - for i in mmr_hosts: z=z+1 mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(z), "MMRDN": names.configdn, - "LDAPSERVER" : i }) + "LDAPSERVER" : i, + "MMR_PASSWORD": adminpass}) - for i in mmr_hosts: z=z+1 mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(z), "MMRDN": names.domaindn, - "LDAPSERVER" : i }) + "LDAPSERVER" : i, + "MMR_PASSWORD": adminpass }) setup_file(setup_path("slapd.conf"), paths.slapdconf, @@ -1335,6 +1319,7 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, + "MMR_PASSWORD": adminpass, "REFINT_CONFIG": refint_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) -- cgit From 41493cbe680e0b8dff3b84937b3005c72c39dec6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Aug 2008 12:21:36 +1000 Subject: Update OpenLDAP MMR configuration per comments by Oliver Liebel This changes the RIDs to be , to ease later debugging. The need to specify the port on the MMR URLs is now included in the help. Andrew Bartlett (This used to be commit a5cbe8c09c6f14f95ff9ba9b8782e2100fc55695) --- source4/scripting/python/samba/provision.py | 37 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0855efe3bb..d14ce58f04 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1281,39 +1281,38 @@ def provision_backend(setup_dir=None, message=None, mmr_syncrepl_user_config = "" if ol_mmr_urls is not None: - mmr_hosts=filter(None,ol_mmr_urls.split(' ')) - if (len(mmr_hosts) == 1): - mmr_hosts=filter(None,ol_mmr_urls.split(',')) + url_list=filter(None,ol_mmr_urls.split(' ')) + if (len(url_list) == 1): + url_list=filter(None,ol_mmr_urls.split(',')) mmr_on_config = "MirrorMode On" - - z=0 - for i in mmr_hosts: - z=z+1 + serverid=0 + for url in url_list: + serverid=serverid+1 mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), - { "SERVERID" : str(z), - "LDAPSERVER" : i }) - - z=z+1 + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) + rid=serverid*10 + rid=rid+1 mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(z), + { "RID" : str(rid), "MMRDN": names.schemadn, - "LDAPSERVER" : i, + "LDAPSERVER" : url, "MMR_PASSWORD": adminpass}) - z=z+1 + rid=rid+1 mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(z), + { "RID" : str(rid), "MMRDN": names.configdn, - "LDAPSERVER" : i, + "LDAPSERVER" : url, "MMR_PASSWORD": adminpass}) - z=z+1 + rid=rid+1 mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(z), + { "RID" : str(rid), "MMRDN": names.domaindn, - "LDAPSERVER" : i, + "LDAPSERVER" : url, "MMR_PASSWORD": adminpass }) -- cgit From 8237c0ba83e2b47bb7879ba68d3a50da887397b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Aug 2008 12:59:16 +1000 Subject: The index handling is now configured from the schema load, not by a template. Andrew Bartlett (This used to be commit b36c6a21ad12fdc1b53efdc3f29cde7614b4fa9e) --- source4/scripting/python/samba/provision.py | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d14ce58f04..9c2a208460 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -745,12 +745,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) - if fill == FILL_DRS: - # We want to finish here, but setup the index before we do so - message("Setting up sam.ldb index") - samdb.load_ldif_file_add(setup_path("provision_index.ldif")) - return samdb - message("Pre-loading the Samba 4 and AD schema") samdb.set_domain_sid(domainsid) if serverrole == "domain controller": @@ -886,9 +880,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domainsid=domainsid, policyguid=policyguid, setup_path=setup_path) - #We want to setup the index last, as adds are faster unindexed - message("Setting up sam.ldb index") - samdb.load_ldif_file_add(setup_path("provision_index.ldif")) except: samdb.transaction_cancel() raise -- cgit From 9817f3d785ceb67819a9def0e8030272e4ba9e14 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Aug 2008 07:32:44 +1000 Subject: Add a setexpiry operation in samdb.py This makes it easy to set the expiry (or no expiry) for a samdb user (This used to be commit 25171f18a4b242b5a731f4ac1eefc51cc82efd74) --- source4/scripting/python/misc.i | 13 +++++ source4/scripting/python/misc.py | 3 +- source4/scripting/python/misc_wrap.c | 84 +++++++++++++++++++++++++++++---- source4/scripting/python/samba/samdb.py | 33 +++++++++++++ 4 files changed, 123 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 1d331215b5..f0bc156abd 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -100,3 +100,16 @@ bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid) char *private_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, const char *name); +typedef unsigned long time_t; + +/* + convert from unix time to NT time +*/ +%inline %{ +uint64_t unix2nttime(time_t t) +{ + NTTIME nt; + unix_to_nt_time(&nt, t); + return (uint64_t)nt; +} +%} diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 0c14944001..e52d7df11d 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.35 +# Version 1.3.36 # # Don't modify this file, modify the SWIG interface instead. @@ -118,5 +118,6 @@ def ldb_register_samba_handlers(*args, **kwargs): return _misc.ldb_register_samba_handlers(*args, **kwargs) dsdb_set_ntds_invocation_id = _misc.dsdb_set_ntds_invocation_id private_path = _misc.private_path +unix2nttime = _misc.unix2nttime diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 888918ef53..4b5bfb0174 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.35 + * Version 1.3.36 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -52,6 +52,12 @@ # endif #endif +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) @@ -2537,7 +2543,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #define SWIG_name "_misc" -#define SWIGVERSION 0x010335 +#define SWIGVERSION 0x010336 #define SWIG_VERSION SWIGVERSION @@ -2826,6 +2832,40 @@ bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid) return samdb_set_ntds_invocation_id(ldb, &invocation_id_in); } + +uint64_t unix2nttime(time_t t) +{ + NTTIME nt; + unix_to_nt_time(&nt, t); + return (uint64_t)nt; +} + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERNINLINE PyObject* +SWIG_From_long_SS_long (long long value) +{ + return ((value < LONG_MIN) || (value > LONG_MAX)) ? + PyLong_FromLongLong(value) : PyInt_FromLong((long)(value)); +} + + +SWIGINTERNINLINE PyObject* +SWIG_From_unsigned_SS_long_SS_long (unsigned long long value) +{ + return (value > LONG_MAX) ? + PyLong_FromUnsignedLongLong(value) : PyInt_FromLong((long)(value)); +} + #ifdef __cplusplus extern "C" { #endif @@ -2833,13 +2873,13 @@ SWIGINTERN PyObject *_wrap_random_password(PyObject *SWIGUNUSEDPARM(self), PyObj PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; size_t arg2 ; - char *result = 0 ; size_t val2 ; int ecode2 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "len", NULL }; + char *result = 0 ; arg1 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:random_password",kwnames,&obj0)) SWIG_fail; @@ -2974,7 +3014,6 @@ SWIGINTERN PyObject *_wrap_samdb_set_domain_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; struct dom_sid *arg2 = (struct dom_sid *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -2984,6 +3023,7 @@ SWIGINTERN PyObject *_wrap_samdb_set_domain_sid(PyObject *SWIGUNUSEDPARM(self), char * kwnames[] = { (char *) "ldb",(char *) "dom_sid_in", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:samdb_set_domain_sid",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3012,7 +3052,6 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE struct ldb_context *arg1 = (struct ldb_context *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -3027,6 +3066,7 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE char * kwnames[] = { (char *) "ldb",(char *) "pf",(char *) "df", NULL }; + WERROR result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:dsdb_attach_schema_from_ldif_file",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3080,13 +3120,13 @@ fail: SWIGINTERN PyObject *_wrap_dsdb_set_global_schema(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; - int result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "ldb", NULL }; + int result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:dsdb_set_global_schema",kwnames,&obj0)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3108,13 +3148,13 @@ fail: SWIGINTERN PyObject *_wrap_ldb_register_samba_handlers(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; - int result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "ldb", NULL }; + int result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:ldb_register_samba_handlers",kwnames,&obj0)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3137,7 +3177,6 @@ SWIGINTERN PyObject *_wrap_dsdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM( PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; char *arg2 = (char *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -3148,6 +3187,7 @@ SWIGINTERN PyObject *_wrap_dsdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM( char * kwnames[] = { (char *) "ldb",(char *) "guid", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:dsdb_set_ntds_invocation_id",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3178,7 +3218,6 @@ SWIGINTERN PyObject *_wrap_private_path(PyObject *SWIGUNUSEDPARM(self), PyObject TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; struct loadparm_context *arg2 = (struct loadparm_context *) 0 ; char *arg3 = (char *) 0 ; - char *result = 0 ; void *argp2 = 0 ; int res2 = 0 ; int res3 ; @@ -3189,6 +3228,7 @@ SWIGINTERN PyObject *_wrap_private_path(PyObject *SWIGUNUSEDPARM(self), PyObject char * kwnames[] = { (char *) "lp_ctx",(char *) "name", NULL }; + char *result = 0 ; arg2 = loadparm_init(NULL); arg1 = NULL; @@ -3217,6 +3257,31 @@ fail: } +SWIGINTERN PyObject *_wrap_unix2nttime(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + time_t arg1 ; + unsigned long val1 ; + int ecode1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "t", NULL + }; + uint64_t result; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:unix2nttime",kwnames,&obj0)) SWIG_fail; + ecode1 = SWIG_AsVal_unsigned_SS_long(obj0, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "unix2nttime" "', argument " "1"" of type '" "time_t""'"); + } + arg1 = (time_t)(val1); + result = (uint64_t)unix2nttime(arg1); + resultobj = SWIG_From_unsigned_SS_long_SS_long((unsigned long long)(result)); + return resultobj; +fail: + return NULL; +} + + static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, (char *)"\n" "S.random_password(len) -> string\n" @@ -3250,6 +3315,7 @@ static PyMethodDef SwigMethods[] = { ""}, { (char *)"dsdb_set_ntds_invocation_id", (PyCFunction) _wrap_dsdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"private_path", (PyCFunction) _wrap_private_path, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"unix2nttime", (PyCFunction) _wrap_unix2nttime, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } }; diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index c7d93d6aff..4a64c2f76d 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -27,6 +27,7 @@ import misc import ldb from samba.idmap import IDmapDB import pwd +import time __docformat__ = "restructuredText" @@ -192,3 +193,35 @@ userPassword: %s :param invocation_id: GUID of the invocation id. """ misc.dsdb_set_ntds_invocation_id(self, invocation_id) + + def setexpiry(self, user, expiry_seconds, noexpiry): + """Set the password expiry for a user + + :param expiry_seconds: expiry time from now in seconds + :param noexpiry: if set, then don't expire password + """ + self.transaction_start(); + res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE, + expression=("(samAccountName=%s)" % user), + attrs=["userAccountControl", "accountExpires"]) + assert len(res) == 1 + userAccountControl = int(res[0]["userAccountControl"][0]) + accountExpires = int(res[0]["accountExpires"][0]) + if noexpiry: + userAccountControl = userAccountControl | 0x10000 + accountExpires = 0 + else: + userAccountControl = userAccountControl & ~0x10000 + accountExpires = misc.unix2nttime(expiry_seconds + int(time.time())) + + mod = """ +dn: %s +changetype: modify +replace: userAccountControl +userAccountControl: %u +replace: accountExpires +accountExpires: %u +""" % (res[0].dn, userAccountControl, accountExpires) + # now change the database + self.modify_ldif(mod) + self.transaction_commit(); -- cgit From 24a9181f25a64937ec0c81ed40e9744de0f164e9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 3 Sep 2008 22:29:53 +0200 Subject: Avoid using version call for version string. (This used to be commit 1897cef508c8bea817c510bd9023d794cb983864) --- source4/scripting/python/misc.i | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 1d331215b5..437f02a1ee 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -77,10 +77,9 @@ bool samdb_set_domain_sid(struct ldb_context *ldb, WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df); -%feature("docstring") samba_version_string "version()\n" - "Obtain the Samba version."; -%rename(version) samba_version_string; -const char *samba_version_string(void); +%feature("docstring") version "version()\n" + "Obtain the Samba version."; +const char *version(void) { return SAMBA_VERSION_STRING; } int dsdb_set_global_schema(struct ldb_context *ldb); %feature("docstring") ldb_register_samba_handlers "register_samba_handlers()\n" "Register Samba-specific LDB modules and schemas."; -- cgit From fbbe799e4e68d79846614c6648307cc6b3f76906 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 3 Sep 2008 22:55:24 +0200 Subject: Regenerate SWIG file. (This used to be commit e8ba65c4db986fcedf7008d05d8f8846f78a98f1) --- source4/scripting/python/misc.i | 9 ++++++++- source4/scripting/python/misc.py | 2 +- source4/scripting/python/misc_wrap.c | 33 +++++++++++++++++++++++---------- 3 files changed, 32 insertions(+), 12 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 437f02a1ee..19318cdb17 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -26,6 +26,7 @@ #include "dsdb/samdb/samdb.h" #include "lib/ldb-samba/ldif_handlers.h" #include "librpc/ndr/libndr.h" +#include "version.h" %} %import "stdint.i" @@ -79,7 +80,13 @@ WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf %feature("docstring") version "version()\n" "Obtain the Samba version."; -const char *version(void) { return SAMBA_VERSION_STRING; } + +%inline { +const char *version(void) +{ + return SAMBA_VERSION_STRING; +} +} int dsdb_set_global_schema(struct ldb_context *ldb); %feature("docstring") ldb_register_samba_handlers "register_samba_handlers()\n" "Register Samba-specific LDB modules and schemas."; diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index 0c14944001..933ceef35f 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.35 +# Version 1.3.36 # # Don't modify this file, modify the SWIG interface instead. diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 888918ef53..c7cdb86c35 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.35 + * Version 1.3.36 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -52,6 +52,12 @@ # endif #endif +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + #ifndef SWIGUNUSEDPARM # ifdef __cplusplus # define SWIGUNUSEDPARM(p) @@ -2537,7 +2543,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #define SWIG_name "_misc" -#define SWIGVERSION 0x010335 +#define SWIGVERSION 0x010336 #define SWIG_VERSION SWIGVERSION @@ -2552,6 +2558,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #include "dsdb/samdb/samdb.h" #include "lib/ldb-samba/ldif_handlers.h" #include "librpc/ndr/libndr.h" +#include "version.h" #include "libcli/util/pyerrors.h" @@ -2807,6 +2814,12 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) +const char *version(void) +{ + return SAMBA_VERSION_STRING; +} + + #define SWIG_From_long PyInt_FromLong @@ -2833,13 +2846,13 @@ SWIGINTERN PyObject *_wrap_random_password(PyObject *SWIGUNUSEDPARM(self), PyObj PyObject *resultobj = 0; TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; size_t arg2 ; - char *result = 0 ; size_t val2 ; int ecode2 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "len", NULL }; + char *result = 0 ; arg1 = NULL; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:random_password",kwnames,&obj0)) SWIG_fail; @@ -2974,7 +2987,6 @@ SWIGINTERN PyObject *_wrap_samdb_set_domain_sid(PyObject *SWIGUNUSEDPARM(self), PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; struct dom_sid *arg2 = (struct dom_sid *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; void *argp2 = 0 ; @@ -2984,6 +2996,7 @@ SWIGINTERN PyObject *_wrap_samdb_set_domain_sid(PyObject *SWIGUNUSEDPARM(self), char * kwnames[] = { (char *) "ldb",(char *) "dom_sid_in", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:samdb_set_domain_sid",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3012,7 +3025,6 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE struct ldb_context *arg1 = (struct ldb_context *) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; - WERROR result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -3027,6 +3039,7 @@ SWIGINTERN PyObject *_wrap_dsdb_attach_schema_from_ldif_file(PyObject *SWIGUNUSE char * kwnames[] = { (char *) "ldb",(char *) "pf",(char *) "df", NULL }; + WERROR result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:dsdb_attach_schema_from_ldif_file",kwnames,&obj0,&obj1,&obj2)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3069,7 +3082,7 @@ SWIGINTERN PyObject *_wrap_version(PyObject *SWIGUNUSEDPARM(self), PyObject *arg char *result = 0 ; if (!SWIG_Python_UnpackTuple(args,"version",0,0,0)) SWIG_fail; - result = (char *)samba_version_string(); + result = (char *)version(); resultobj = SWIG_FromCharPtr((const char *)result); return resultobj; fail: @@ -3080,13 +3093,13 @@ fail: SWIGINTERN PyObject *_wrap_dsdb_set_global_schema(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; - int result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "ldb", NULL }; + int result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:dsdb_set_global_schema",kwnames,&obj0)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3108,13 +3121,13 @@ fail: SWIGINTERN PyObject *_wrap_ldb_register_samba_handlers(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; - int result; void *argp1 = 0 ; int res1 = 0 ; PyObject * obj0 = 0 ; char * kwnames[] = { (char *) "ldb", NULL }; + int result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O:ldb_register_samba_handlers",kwnames,&obj0)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3137,7 +3150,6 @@ SWIGINTERN PyObject *_wrap_dsdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM( PyObject *resultobj = 0; struct ldb_context *arg1 = (struct ldb_context *) 0 ; char *arg2 = (char *) 0 ; - bool result; void *argp1 = 0 ; int res1 = 0 ; int res2 ; @@ -3148,6 +3160,7 @@ SWIGINTERN PyObject *_wrap_dsdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM( char * kwnames[] = { (char *) "ldb",(char *) "guid", NULL }; + bool result; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:dsdb_set_ntds_invocation_id",kwnames,&obj0,&obj1)) SWIG_fail; res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); @@ -3178,7 +3191,6 @@ SWIGINTERN PyObject *_wrap_private_path(PyObject *SWIGUNUSEDPARM(self), PyObject TALLOC_CTX *arg1 = (TALLOC_CTX *) 0 ; struct loadparm_context *arg2 = (struct loadparm_context *) 0 ; char *arg3 = (char *) 0 ; - char *result = 0 ; void *argp2 = 0 ; int res2 = 0 ; int res3 ; @@ -3189,6 +3201,7 @@ SWIGINTERN PyObject *_wrap_private_path(PyObject *SWIGUNUSEDPARM(self), PyObject char * kwnames[] = { (char *) "lp_ctx",(char *) "name", NULL }; + char *result = 0 ; arg2 = loadparm_init(NULL); arg1 = NULL; -- cgit From b76f383eefe961e8a2f42ac782031e3e09ff7192 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Mon, 8 Sep 2008 14:39:54 +1000 Subject: Use DIGEST-MD5 authentication for OpenLDAP replication This avoids passing rootdn passwords or replicated data in cleartext across the network. Signed-of-by: Andrew Bartlett (This used to be commit 67373c143a1d8a9f310fd116dbf81c1dd123b75f) --- source4/scripting/python/samba/provision.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 9c2a208460..f37d09d5e0 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1266,6 +1266,7 @@ def provision_backend(setup_dir=None, message=None, # generate serverids, ldap-urls and syncrepl-blocks for mmr hosts mmr_on_config = "" + mmr_replicator_acl = "" mmr_serverids_config = "" mmr_syncrepl_schema_config = "" mmr_syncrepl_config_config = "" @@ -1278,6 +1279,7 @@ def provision_backend(setup_dir=None, message=None, mmr_on_config = "MirrorMode On" + mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" serverid=0 for url in url_list: serverid=serverid+1 @@ -1315,6 +1317,7 @@ def provision_backend(setup_dir=None, message=None, "SCHEMADN": names.schemadn, "MEMBEROF_CONFIG": memberof_config, "MIRRORMODE": mmr_on_config, + "REPLICATOR_ACL": mmr_replicator_acl, "MMR_SERVERIDS_CONFIG": mmr_serverids_config, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, @@ -1340,6 +1343,15 @@ def provision_backend(setup_dir=None, message=None, {"LDAPADMINPASS_B64": b64encode(adminpass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) + + if ol_mmr_urls is not None: + setup_file(setup_path("cn=replicator.ldif"), + os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), + {"LDAPADMINPASS_B64": b64encode(adminpass), + "UUID": str(uuid.uuid4()), + "LDAPTIME": timestring(int(time.time()))} ) + + mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From ef9169bfa6fcaa682ff5baf729301dd63f6bb029 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Sep 2008 15:09:06 +1000 Subject: Make it clear that the MMR password can differ from the admin passsword In the future, we might simply randomly generate this, or allow the admin to specify it seperate to the admin password. However, both are highly sensitive, as they imply read access to the krbtgt. Andrew Bartlett (This used to be commit 57d19ad002c523fb9a09694e6710ab7f588d44ec) --- source4/scripting/python/samba/provision.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f37d09d5e0..68f61532ad 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1273,7 +1273,10 @@ def provision_backend(setup_dir=None, message=None, mmr_syncrepl_user_config = "" if ol_mmr_urls is not None: - url_list=filter(None,ol_mmr_urls.split(' ')) + # For now, make these equal + mmr_pass = adminpass + + url_list=filter(None,ol_mmr_urls.split(' ')) if (len(url_list) == 1): url_list=filter(None,ol_mmr_urls.split(',')) @@ -1292,21 +1295,21 @@ def provision_backend(setup_dir=None, message=None, { "RID" : str(rid), "MMRDN": names.schemadn, "LDAPSERVER" : url, - "MMR_PASSWORD": adminpass}) + "MMR_PASSWORD": mmr_pass}) rid=rid+1 mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(rid), "MMRDN": names.configdn, "LDAPSERVER" : url, - "MMR_PASSWORD": adminpass}) + "MMR_PASSWORD": mmr_pass}) rid=rid+1 mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(rid), "MMRDN": names.domaindn, "LDAPSERVER" : url, - "MMR_PASSWORD": adminpass }) + "MMR_PASSWORD": mmr_pass }) setup_file(setup_path("slapd.conf"), paths.slapdconf, @@ -1322,7 +1325,6 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, - "MMR_PASSWORD": adminpass, "REFINT_CONFIG": refint_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) @@ -1347,7 +1349,7 @@ def provision_backend(setup_dir=None, message=None, if ol_mmr_urls is not None: setup_file(setup_path("cn=replicator.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), - {"LDAPADMINPASS_B64": b64encode(adminpass), + {"MMR_PASSWORD_B64": b64encode(mmr_pass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) -- cgit From 1d8973a82eda362d19dbfe79529d10baf6f97d9d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 23:35:17 +0200 Subject: Attempt to correctly find python on host sunx (This used to be commit 59b62280d27a9e0a72241e4b60022be07e4cbce2) --- source4/scripting/python/config.m4 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index b599aaefb0..5607accb7c 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -48,8 +48,9 @@ fi if test -z "$PYTHON_CONFIG"; then AC_MSG_WARN([No python-config found]) else - TRY_LINK_PYTHON([`$PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --includes`]) - TRY_LINK_PYTHON([`$PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --cflags`]) + base=`$PYTHON_CONFIG --prefix` + TRY_LINK_PYTHON([`echo -n -L${base}/lib " "; $PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --includes`]) + TRY_LINK_PYTHON([`echo -n -L${base}/lib " "; $PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --cflags`]) fi if test x$PYTHON != x -- cgit From 4f266dff13d2937b1800954a9ddb536df4d14a5f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 9 Sep 2008 23:49:07 +0200 Subject: Only try with -LPYTHONDIR/lib when python-config output didn't work. (This used to be commit 62d76356c10b4223236425c4db32c2fc5105d155) --- source4/scripting/python/config.m4 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python') diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 5607accb7c..af13b6ae69 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -48,9 +48,14 @@ fi if test -z "$PYTHON_CONFIG"; then AC_MSG_WARN([No python-config found]) else - base=`$PYTHON_CONFIG --prefix` - TRY_LINK_PYTHON([`echo -n -L${base}/lib " "; $PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --includes`]) - TRY_LINK_PYTHON([`echo -n -L${base}/lib " "; $PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --cflags`]) + TRY_LINK_PYTHON([`$PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --includes`]) + TRY_LINK_PYTHON([`$PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --cflags`]) + if x$working_python = xno; then + # It seems the library path isn't included on some systems + base=`$PYTHON_CONFIG --prefix` + TRY_LINK_PYTHON([`echo -n -L${base}/lib " "; $PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --includes`]) + TRY_LINK_PYTHON([`echo -n -L${base}/lib " "; $PYTHON_CONFIG --ldflags`], [`$PYTHON_CONFIG --cflags`]) + fi fi if test x$PYTHON != x -- cgit