From 9a3cbd276bc60afa254a64216435f7448b8c453f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 24 Jan 2008 01:05:19 +0100 Subject: python: Add bindings for cli_credentials_set_cmdline_callbacks(). (This used to be commit 557207f86ba901262e76704df5c51888b2737ddf) --- source4/auth/credentials/config.mk | 2 +- source4/auth/credentials/credentials.i | 3 +++ source4/auth/credentials/credentials.py | 1 + source4/auth/credentials/credentials_wrap.c | 30 +++++++++++++++++++++++++++++ source4/auth/credentials/tests/bindings.py | 3 +++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/source4/auth/credentials/config.mk b/source4/auth/credentials/config.mk index 8d33bdbd55..fee9519ae5 100644 --- a/source4/auth/credentials/config.mk +++ b/source4/auth/credentials/config.mk @@ -14,5 +14,5 @@ PRIVATE_DEPENDENCIES = \ SECRETS [PYTHON::swig_credentials] -PUBLIC_DEPENDENCIES = CREDENTIALS +PUBLIC_DEPENDENCIES = CREDENTIALS LIBCMDLINE_CREDENTIALS SWIG_FILE = credentials.i diff --git a/source4/auth/credentials/credentials.i b/source4/auth/credentials/credentials.i index fedb8bd1d7..41ec67580e 100644 --- a/source4/auth/credentials/credentials.i +++ b/source4/auth/credentials/credentials.i @@ -27,6 +27,7 @@ #include "includes.h" #include "auth/credentials/credentials.h" #include "param/param.h" +#include "lib/cmdline/credentials.h" typedef struct cli_credentials cli_credentials; %} @@ -93,6 +94,8 @@ typedef struct cli_credentials { bool authentication_requested(void); bool wrong_password(void); + + bool set_cmdline_callbacks(); } } cli_credentials; diff --git a/source4/auth/credentials/credentials.py b/source4/auth/credentials/credentials.py index 0d91526b8f..14526af910 100644 --- a/source4/auth/credentials/credentials.py +++ b/source4/auth/credentials/credentials.py @@ -82,6 +82,7 @@ Credentials.is_anonymous = new_instancemethod(_credentials.Credentials_is_anonym Credentials.get_nt_hash = new_instancemethod(_credentials.Credentials_get_nt_hash,None,Credentials) Credentials.authentication_requested = new_instancemethod(_credentials.Credentials_authentication_requested,None,Credentials) Credentials.wrong_password = new_instancemethod(_credentials.Credentials_wrong_password,None,Credentials) +Credentials.set_cmdline_callbacks = new_instancemethod(_credentials.Credentials_set_cmdline_callbacks,None,Credentials) Credentials_swigregister = _credentials.Credentials_swigregister Credentials_swigregister(Credentials) diff --git a/source4/auth/credentials/credentials_wrap.c b/source4/auth/credentials/credentials_wrap.c index 849b28ebff..b1b904c8a3 100644 --- a/source4/auth/credentials/credentials_wrap.c +++ b/source4/auth/credentials/credentials_wrap.c @@ -2521,6 +2521,7 @@ static swig_module_info swig_module = {swig_types, 16, 0, 0, 0, 0}; #include "includes.h" #include "auth/credentials/credentials.h" #include "param/param.h" +#include "lib/cmdline/credentials.h" typedef struct cli_credentials cli_credentials; @@ -3486,6 +3487,34 @@ fail: } +SWIGINTERN PyObject *_wrap_Credentials_set_cmdline_callbacks(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + cli_credentials *arg1 = (cli_credentials *) 0 ; + bool result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + char * kwnames[] = { + (char *) "self", NULL + }; + + arg1 = NULL; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|O:Credentials_set_cmdline_callbacks",kwnames,&obj0)) SWIG_fail; + if (obj0) { + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_cli_credentials, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Credentials_set_cmdline_callbacks" "', argument " "1"" of type '" "cli_credentials *""'"); + } + arg1 = (cli_credentials *)(argp1); + } + result = (bool)cli_credentials_set_cmdline_callbacks(arg1); + resultobj = SWIG_From_bool((bool)(result)); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_delete_Credentials(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; cli_credentials *arg1 = (cli_credentials *) 0 ; @@ -3545,6 +3574,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"Credentials_get_nt_hash", (PyCFunction) _wrap_Credentials_get_nt_hash, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Credentials_authentication_requested", (PyCFunction) _wrap_Credentials_authentication_requested, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Credentials_wrong_password", (PyCFunction) _wrap_Credentials_wrong_password, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Credentials_set_cmdline_callbacks", (PyCFunction) _wrap_Credentials_set_cmdline_callbacks, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"delete_Credentials", (PyCFunction) _wrap_delete_Credentials, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Credentials_swigregister", Credentials_swigregister, METH_VARARGS, NULL}, { (char *)"Credentials_swiginit", Credentials_swiginit, METH_VARARGS, NULL}, diff --git a/source4/auth/credentials/tests/bindings.py b/source4/auth/credentials/tests/bindings.py index 8312e77e9e..d2ca68d115 100644 --- a/source4/auth/credentials/tests/bindings.py +++ b/source4/auth/credentials/tests/bindings.py @@ -83,6 +83,9 @@ class CredentialsTests(unittest.TestCase): # Just check the method is there and doesn't raise an exception self.creds.guess() + def test_set_cmdline_callbacks(self): + self.creds.set_cmdline_callbacks() + def test_authentication_requested(self): self.creds.set_username("") self.assertFalse(self.creds.authentication_requested()) -- 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(+) 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(-) 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(-) 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(+) 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(-) 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 +- source4/setup/provision.py | 83 ++-- 6 files changed, 317 insertions(+), 254 deletions(-) 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) diff --git a/source4/setup/provision.py b/source4/setup/provision.py index b9a11bdd78..743a94700d 100755 --- a/source4/setup/provision.py +++ b/source4/setup/provision.py @@ -33,8 +33,10 @@ import samba from auth import system_session import samba.getopt as options import param -from samba.provision import (provision, - provision_paths_from_lp) +from samba.provision import (provision, + provision_paths_from_lp, + FILL_FULL, FILL_NT4SYNC, + FILL_DRS) parser = optparse.OptionParser("provision [options]") sambaopts = options.SambaOptions(parser) @@ -84,8 +86,9 @@ parser.add_option("--blank", action="store_true", help="do not add users or groups, just the structure") parser.add_option("--ldap-backend", type="string", metavar="LDAPSERVER", help="LDAP server to use for this provision") -parser.add_option("--ldap-module=", type="string", metavar="MODULE", - help="LDB mapping module to use for the LDAP backend") +parser.add_option("--ldap-backend-type", type="choice", metavar="LDAP-BACKEND-TYPE", + help="LDB mapping module to use for the LDAP backend", + choices=["fedora-ds", "openldap"]) parser.add_option("--aci", type="string", metavar="ACI", help="An arbitary LDIF fragment, particularly useful to loading a backend ACI value into a target LDAP server. You must provide at least a realm and domain") parser.add_option("--server-role", type="choice", metavar="ROLE", @@ -122,51 +125,47 @@ lp.set("realm", opts.realm) lp.set("workgroup", opts.domain) lp.set("server role", opts.server_role or "domain controller") + if opts.aci is not None: print "set ACI: %s" % opts.aci -paths = provision_paths_from_lp(lp, opts.realm.lower()) +private_dir = None +if opts.targetdir is not None: + private_dir = os.path.join(opts.targetdir, "private") +paths = provision_paths_from_lp(lp, opts.realm.lower(), private_dir) paths.smbconf = sambaopts.get_loadparm_path() -if opts.ldap_backend: - if opts.ldap_backend == "ldapi": - subobj.ldap_backend = subobj.ldapi_uri - - if not opts.ldap_module: - subobj.ldapmodule = "entryuuid" - - subobj.domaindn_ldb = subobj.ldap_backend - subobj.domaindn_mod2 = ",%s,paged_searches" % subobj.ldapmodule - subobj.configdn_ldb = subobj.ldap_backend - subobj.configdn_mod2 = ",%s,paged_searches" % subobj.ldapmodule - subobj.schemadn_ldb = subobj.ldap_backend - subobj.schemadn_mod2 = ",%s,paged_searches" % subobj.ldapmodule - message("LDAP module: %s on backend: %s" % (subobj.ldapmodule, subobj.ldap_backend)) - creds = credopts.get_credentials() setup_dir = opts.setupdir if setup_dir is None: setup_dir = "setup" -if opts.partitions_only: - provision_become_dc(setup_dir, message, False, - paths, lp, system_session(), creds) -else: - provision(lp, setup_dir, message, opts.blank, paths, - system_session(), creds, opts.ldap_backend, realm=opts.realm, - domainguid=opts.domain_guid, domainsid=opts.domain_sid, - policyguid=opts.policy_guid, hostname=opts.host_name, - hostip=opts.host_ip, hostguid=opts.host_guid, - invocationid=opts.invocationid, adminpass=opts.adminpass, - krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass, - dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody, - nogroup=opts.nogroup, wheel=opts.wheel, users=opts.users, - aci=opts.aci, serverrole=opts.server_role) - message("To reproduce this provision, run with:") - def shell_escape(arg): - if " " in arg: - return '"%s"' % arg - return arg - message(" ".join([shell_escape(arg) for arg in sys.argv])) - -message("All OK") + +samdb_fill = FILL_FULL +if opts.blank: + samdb_fill = FILL_NT4SYNC +elif opts.partitions_only: + samdb_fill = FILL_DRS + +provision(lp, setup_dir, message, paths, + system_session(), creds, opts.ldap_backend, + samdb_fill=samdb_fill, realm=opts.realm, + domainguid=opts.domain_guid, domainsid=opts.domain_sid, + policyguid=opts.policy_guid, hostname=opts.host_name, + hostip=opts.host_ip, hostguid=opts.host_guid, + invocationid=opts.invocationid, adminpass=opts.adminpass, + krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass, + dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody, + nogroup=opts.nogroup, wheel=opts.wheel, users=opts.users, + aci=opts.aci, serverrole=opts.server_role, + ldap_backend=opts.ldap_backend, + ldap_backend_type=opts.ldap_backend_type) + +message("To reproduce this provision, run with:") +def shell_escape(arg): + if " " in arg: + return '"%s"' % arg + return arg +message(" ".join([shell_escape(arg) for arg in sys.argv])) + +message("All OK") \ No newline at end of file -- 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(-) 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(-) 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 dbf400c3da853e6845f0d0b667f713639b29582e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 01:41:06 +0100 Subject: python/provision: Create private dir if it didn't exist yet. (This used to be commit 66df250ff355d3c1b7f0252fc1f95a8c79a28c6d) --- source4/setup/provision.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source4/setup/provision.py b/source4/setup/provision.py index 743a94700d..c8087f7bd7 100755 --- a/source4/setup/provision.py +++ b/source4/setup/provision.py @@ -2,7 +2,8 @@ # # Unix SMB/CIFS implementation. # provision a Samba4 server -# Copyright (C) Jelmer Vernooij 2007 +# Copyright (C) Jelmer Vernooij 2007-2008 +# Copyright (C) Andrew Bartlett 2008 # # Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 @@ -115,11 +116,15 @@ if opts.realm is None or opts.domain is None: sys.exit(1) # cope with an initially blank smb.conf +private_dir = None lp = sambaopts.get_loadparm() if opts.targetdir is not None: if not os.path.exists(opts.targetdir): os.mkdir(opts.targetdir) - lp.set("private dir", os.path.abspath(opts.targetdir)) + private_dir = os.path.join(opts.targetdir, "private") + if not os.path.exists(private_dir): + os.mkdir(private_dir) + lp.set("private dir", os.path.abspath(private_dir)) lp.set("lock dir", os.path.abspath(opts.targetdir)) lp.set("realm", opts.realm) lp.set("workgroup", opts.domain) @@ -129,9 +134,6 @@ lp.set("server role", opts.server_role or "domain controller") if opts.aci is not None: print "set ACI: %s" % opts.aci -private_dir = None -if opts.targetdir is not None: - private_dir = os.path.join(opts.targetdir, "private") paths = provision_paths_from_lp(lp, opts.realm.lower(), private_dir) paths.smbconf = sambaopts.get_loadparm_path() @@ -168,4 +170,4 @@ def shell_escape(arg): return arg message(" ".join([shell_escape(arg) for arg in sys.argv])) -message("All OK") \ No newline at end of file +message("All OK") -- cgit From c28c683208aad1a136c8c6decc3297bf1995aa90 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 03:46:47 +0100 Subject: ldb/python: Add bindings for schema functions. (This used to be commit 9f6ea4692ca79c607538871c597698b98abf13d0) --- source4/lib/ldb/ldb.i | 88 ++++++++++-- source4/lib/ldb/ldb.py | 5 + source4/lib/ldb/ldb_wrap.c | 333 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 393 insertions(+), 33 deletions(-) diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i index 560142eb6d..336100c4f0 100644 --- a/source4/lib/ldb/ldb.i +++ b/source4/lib/ldb/ldb.i @@ -5,7 +5,7 @@ Copyright (C) 2005,2006 Tim Potter Copyright (C) 2006 Simo Sorce - Copyright (C) 2007 Jelmer Vernooij + Copyright (C) 2007-2008 Jelmer Vernooij ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -102,8 +102,44 @@ typedef int ldb_error; $1->data = PyString_AsString($input); } +%inline %{ +PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx, + struct ldb_message_element *el, + struct ldb_val *val) +{ + const struct ldb_schema_attribute *a; + struct ldb_val new_val; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + PyObject *ret; + + new_val = *val; + + if (ldb_ctx != NULL) { + a = ldb_schema_attribute_by_name(ldb_ctx, el->name); + + if (a != NULL) { + if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) { + talloc_free(mem_ctx); + return NULL; + } + } + } + + ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); + + talloc_free(mem_ctx); + + return ret; +} + +%} + +%typemap(out,noblock=1) struct ldb_val * { + $result = PyString_FromStringAndSize((const char *)$1->data, $1->length) +} + %typemap(out,noblock=1) struct ldb_val { - $result = PyString_FromStringAndSize((const char *)$1.data, $1.length); + $result = PyString_FromStringAndSize((const char *)$1.data, $1.length) } /* @@ -259,7 +295,8 @@ ldb_msg_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx, return me; } -PyObject *ldb_msg_element_to_set(ldb_msg_element *me) +PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, + ldb_msg_element *me) { int i; PyObject *result; @@ -269,8 +306,7 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me) for (i = 0; i < me->num_values; i++) { PyList_SetItem(result, i, - PyString_FromStringAndSize((const char *)me->values[i].data, - me->values[i].length)); + ldb_val_to_py_object(ldb_ctx, me, &me->values[i])); } return result; @@ -287,12 +323,12 @@ typedef struct ldb_message_element { #ifdef SWIGPYTHON PyObject *__iter__(void) { - return PyObject_GetIter(ldb_msg_element_to_set($self)); + return PyObject_GetIter(ldb_msg_element_to_set(NULL, $self)); } PyObject *__set__(void) { - return ldb_msg_element_to_set($self); + return ldb_msg_element_to_set(NULL, $self); } ldb_msg_element(PyObject *set_obj, int flags=0, const char *name = NULL) @@ -311,9 +347,7 @@ typedef struct ldb_message_element { if (i < 0 || i >= $self->num_values) return Py_None; - return PyString_FromStringAndSize( - (const char *)$self->values[i].data, - $self->values[i].length); + return ldb_val_to_py_object(NULL, $self, &$self->values[i]); } ~ldb_msg_element() { talloc_free($self); } @@ -622,6 +656,35 @@ typedef struct ldb_context { ldb_dn *get_root_basedn(); ldb_dn *get_schema_basedn(); ldb_dn *get_default_basedn(); + PyObject *schema_format_value(const char *element_name, PyObject *val) + { + const struct ldb_schema_attribute *a; + struct ldb_val old_val; + struct ldb_val new_val; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + PyObject *ret; + + old_val.data = PyString_AsString(val); + old_val.length = PyString_Size(val); + + a = ldb_schema_attribute_by_name($self, element_name); + + if (a == NULL) { + return Py_None; + } + + if (a->syntax->ldif_write_fn($self, mem_ctx, &old_val, &new_val) != 0) { + talloc_free(mem_ctx); + return Py_None; + } + + ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); + + talloc_free(mem_ctx); + + return ret; + } + const char *errstring(); void set_create_perms(unsigned int perms); void set_modules_dir(const char *path); @@ -633,7 +696,10 @@ typedef struct ldb_context { ldb_error transaction_start(); ldb_error transaction_commit(); ldb_error transaction_cancel(); - + void schema_attribute_remove(const char *name); + ldb_error schema_attribute_add(const char *attribute, unsigned flags, const char *syntax); + ldb_error setup_wellknown_attributes(void); + #ifdef SWIGPYTHON %typemap(in,numinputs=0,noblock=1) struct ldb_result **result_as_bool (struct ldb_result *tmp) { $1 = &tmp; } %typemap(argout,noblock=1) struct ldb_result **result_as_bool { $result = ((*$1)->count > 0)?Py_True:Py_False; } diff --git a/source4/lib/ldb/ldb.py b/source4/lib/ldb/ldb.py index ab2a68a4b3..0bcfd36779 100644 --- a/source4/lib/ldb/ldb.py +++ b/source4/lib/ldb/ldb.py @@ -65,6 +65,7 @@ CHANGETYPE_NONE = _ldb.CHANGETYPE_NONE CHANGETYPE_ADD = _ldb.CHANGETYPE_ADD CHANGETYPE_DELETE = _ldb.CHANGETYPE_DELETE CHANGETYPE_MODIFY = _ldb.CHANGETYPE_MODIFY +ldb_val_to_py_object = _ldb.ldb_val_to_py_object class Dn(object): thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag') __repr__ = _swig_repr @@ -218,6 +219,7 @@ Ldb.get_config_basedn = new_instancemethod(_ldb.Ldb_get_config_basedn,None,Ldb) Ldb.get_root_basedn = new_instancemethod(_ldb.Ldb_get_root_basedn,None,Ldb) Ldb.get_schema_basedn = new_instancemethod(_ldb.Ldb_get_schema_basedn,None,Ldb) Ldb.get_default_basedn = new_instancemethod(_ldb.Ldb_get_default_basedn,None,Ldb) +Ldb.schema_format_value = new_instancemethod(_ldb.Ldb_schema_format_value,None,Ldb) Ldb.errstring = new_instancemethod(_ldb.Ldb_errstring,None,Ldb) Ldb.set_create_perms = new_instancemethod(_ldb.Ldb_set_create_perms,None,Ldb) Ldb.set_modules_dir = new_instancemethod(_ldb.Ldb_set_modules_dir,None,Ldb) @@ -227,6 +229,9 @@ Ldb.get_opaque = new_instancemethod(_ldb.Ldb_get_opaque,None,Ldb) Ldb.transaction_start = new_instancemethod(_ldb.Ldb_transaction_start,None,Ldb) Ldb.transaction_commit = new_instancemethod(_ldb.Ldb_transaction_commit,None,Ldb) Ldb.transaction_cancel = new_instancemethod(_ldb.Ldb_transaction_cancel,None,Ldb) +Ldb.schema_attribute_remove = new_instancemethod(_ldb.Ldb_schema_attribute_remove,None,Ldb) +Ldb.schema_attribute_add = new_instancemethod(_ldb.Ldb_schema_attribute_add,None,Ldb) +Ldb.setup_wellknown_attributes = new_instancemethod(_ldb.Ldb_setup_wellknown_attributes,None,Ldb) Ldb.__contains__ = new_instancemethod(_ldb.Ldb___contains__,None,Ldb) Ldb.parse_ldif = new_instancemethod(_ldb.Ldb_parse_ldif,None,Ldb) Ldb_swigregister = _ldb.Ldb_swigregister diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c index c833246ead..51022e5930 100644 --- a/source4/lib/ldb/ldb_wrap.c +++ b/source4/lib/ldb/ldb_wrap.c @@ -2470,20 +2470,21 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) #define SWIGTYPE_p_ldb_message_element swig_types[8] #define SWIGTYPE_p_ldb_module_ops swig_types[9] #define SWIGTYPE_p_ldb_result swig_types[10] -#define SWIGTYPE_p_long_long swig_types[11] -#define SWIGTYPE_p_p_char swig_types[12] -#define SWIGTYPE_p_p_ldb_control swig_types[13] -#define SWIGTYPE_p_p_ldb_result 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] -#define SWIGTYPE_p_void 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_ldb_val swig_types[11] +#define SWIGTYPE_p_long_long swig_types[12] +#define SWIGTYPE_p_p_char swig_types[13] +#define SWIGTYPE_p_p_ldb_control swig_types[14] +#define SWIGTYPE_p_p_ldb_result 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] +#define SWIGTYPE_p_void 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) @@ -2550,6 +2551,37 @@ SWIG_From_int (int value) } +PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx, + struct ldb_message_element *el, + struct ldb_val *val) +{ + const struct ldb_schema_attribute *a; + struct ldb_val new_val; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + PyObject *ret; + + new_val = *val; + + if (ldb_ctx != NULL) { + a = ldb_schema_attribute_by_name(ldb_ctx, el->name); + + if (a != NULL) { + if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) { + talloc_free(mem_ctx); + return NULL; + } + } + } + + ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); + + talloc_free(mem_ctx); + + return ret; +} + + + SWIGINTERN swig_type_info* SWIG_pchar_descriptor(void) { @@ -2719,7 +2751,8 @@ ldb_msg_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx, return me; } -PyObject *ldb_msg_element_to_set(ldb_msg_element *me) +PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, + ldb_msg_element *me) { int i; PyObject *result; @@ -2729,8 +2762,7 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me) for (i = 0; i < me->num_values; i++) { PyList_SetItem(result, i, - PyString_FromStringAndSize((const char *)me->values[i].data, - me->values[i].length)); + ldb_val_to_py_object(ldb_ctx, me, &me->values[i])); } return result; @@ -2738,10 +2770,10 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me) SWIGINTERN PyObject *ldb_msg_element___iter__(ldb_msg_element *self){ - return PyObject_GetIter(ldb_msg_element_to_set(self)); + return PyObject_GetIter(ldb_msg_element_to_set(NULL, self)); } SWIGINTERN PyObject *ldb_msg_element___set__(ldb_msg_element *self){ - return ldb_msg_element_to_set(self); + return ldb_msg_element_to_set(NULL, self); } #include @@ -2898,9 +2930,7 @@ SWIGINTERN PyObject *ldb_msg_element_get(ldb_msg_element *self,int i){ if (i < 0 || i >= self->num_values) return Py_None; - return PyString_FromStringAndSize( - (const char *)self->values[i].data, - self->values[i].length); + return ldb_val_to_py_object(NULL, self, &self->values[i]); } SWIGINTERN void delete_ldb_msg_element(ldb_msg_element *self){ talloc_free(self); } @@ -3129,6 +3159,33 @@ SWIGINTERN ldb_error ldb_add__SWIG_1(ldb *self,PyObject *py_msg){ fail: return 80; } +SWIGINTERN PyObject *ldb_schema_format_value(ldb *self,char const *element_name,PyObject *val){ + const struct ldb_schema_attribute *a; + struct ldb_val old_val; + struct ldb_val new_val; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + PyObject *ret; + + old_val.data = PyString_AsString(val); + old_val.length = PyString_Size(val); + + a = ldb_schema_attribute_by_name(self, element_name); + + if (a == NULL) { + return Py_None; + } + + if (a->syntax->ldif_write_fn(self, mem_ctx, &old_val, &new_val) != 0) { + talloc_free(mem_ctx); + return Py_None; + } + + ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); + + talloc_free(mem_ctx); + + return ret; + } SWIGINTERN ldb_error ldb___contains__(ldb *self,ldb_dn *dn,struct ldb_result **result_as_bool){ return ldb_search(self, dn, LDB_SCOPE_BASE, NULL, NULL, result_as_bool); @@ -3153,6 +3210,52 @@ static char *timestring(time_t t) #ifdef __cplusplus extern "C" { #endif +SWIGINTERN PyObject *_wrap_ldb_val_to_py_object(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + struct ldb_context *arg1 = (struct ldb_context *) 0 ; + struct ldb_message_element *arg2 = (struct ldb_message_element *) 0 ; + struct ldb_val *arg3 = (struct ldb_val *) 0 ; + PyObject *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + void *argp2 = 0 ; + int res2 = 0 ; + void *argp3 = 0 ; + int res3 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "ldb_ctx",(char *) "el",(char *) "val", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:ldb_val_to_py_object",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 '" "ldb_val_to_py_object" "', argument " "1"" of type '" "struct ldb_context *""'"); + } + arg1 = (struct ldb_context *)(argp1); + res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_message_element, 0 | 0 ); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_val_to_py_object" "', argument " "2"" of type '" "struct ldb_message_element *""'"); + } + arg2 = (struct ldb_message_element *)(argp2); + res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_ldb_val, 0 | 0 ); + if (!SWIG_IsOK(res3)) { + SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ldb_val_to_py_object" "', argument " "3"" of type '" "struct ldb_val *""'"); + } + arg3 = (struct ldb_val *)(argp3); + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + result = (PyObject *)ldb_val_to_py_object(arg1,arg2,arg3); + resultobj = result; + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_new_Dn(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; ldb *arg1 = (ldb *) 0 ; @@ -4875,6 +4978,49 @@ fail: } +SWIGINTERN PyObject *_wrap_Ldb_schema_format_value(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + ldb *arg1 = (ldb *) 0 ; + char *arg2 = (char *) 0 ; + PyObject *arg3 = (PyObject *) 0 ; + PyObject *result = 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "element_name",(char *) "val", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:Ldb_schema_format_value",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 '" "Ldb_schema_format_value" "', argument " "1"" of type '" "ldb *""'"); + } + arg1 = (ldb *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Ldb_schema_format_value" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + arg3 = obj2; + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + result = (PyObject *)ldb_schema_format_value(arg1,(char const *)arg2,arg3); + resultobj = result; + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + SWIGINTERN PyObject *_wrap_Ldb_errstring(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; ldb *arg1 = (ldb *) 0 ; @@ -5197,6 +5343,140 @@ fail: } +SWIGINTERN PyObject *_wrap_Ldb_schema_attribute_remove(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + ldb *arg1 = (ldb *) 0 ; + char *arg2 = (char *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "name", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_schema_attribute_remove",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_schema_attribute_remove" "', argument " "1"" of type '" "ldb *""'"); + } + arg1 = (ldb *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Ldb_schema_attribute_remove" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + ldb_schema_attribute_remove(arg1,(char const *)arg2); + resultobj = SWIG_Py_Void(); + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Ldb_schema_attribute_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { + PyObject *resultobj = 0; + ldb *arg1 = (ldb *) 0 ; + char *arg2 = (char *) 0 ; + unsigned int arg3 ; + char *arg4 = (char *) 0 ; + ldb_error result; + void *argp1 = 0 ; + int res1 = 0 ; + int res2 ; + char *buf2 = 0 ; + int alloc2 = 0 ; + unsigned int val3 ; + int ecode3 = 0 ; + int res4 ; + char *buf4 = 0 ; + int alloc4 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + char * kwnames[] = { + (char *) "self",(char *) "attribute",(char *) "flags",(char *) "syntax", NULL + }; + + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:Ldb_schema_attribute_add",kwnames,&obj0,&obj1,&obj2,&obj3)) 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_schema_attribute_add" "', argument " "1"" of type '" "ldb *""'"); + } + arg1 = (ldb *)(argp1); + res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Ldb_schema_attribute_add" "', argument " "2"" of type '" "char const *""'"); + } + arg2 = (char *)(buf2); + ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Ldb_schema_attribute_add" "', argument " "3"" of type '" "unsigned int""'"); + } + arg3 = (unsigned int)(val3); + res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4); + if (!SWIG_IsOK(res4)) { + SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Ldb_schema_attribute_add" "', argument " "4"" of type '" "char const *""'"); + } + arg4 = (char *)(buf4); + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + result = ldb_schema_attribute_add(arg1,(char const *)arg2,arg3,(char const *)arg4); + if (result != 0) { + PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_strerror(result))); + SWIG_fail; + } + resultobj = Py_None; + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc4 == SWIG_NEWOBJ) free((char*)buf4); + return resultobj; +fail: + if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); + if (alloc4 == SWIG_NEWOBJ) free((char*)buf4); + return NULL; +} + + +SWIGINTERN PyObject *_wrap_Ldb_setup_wellknown_attributes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + ldb *arg1 = (ldb *) 0 ; + ldb_error result; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject *swig_obj[1] ; + + if (!args) SWIG_fail; + swig_obj[0] = args; + res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ldb_context, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb_setup_wellknown_attributes" "', argument " "1"" of type '" "ldb *""'"); + } + arg1 = (ldb *)(argp1); + if (arg1 == NULL) + SWIG_exception(SWIG_ValueError, + "ldb context must be non-NULL"); + result = ldb_setup_wellknown_attributes(arg1); + if (result != 0) { + PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_strerror(result))); + SWIG_fail; + } + resultobj = Py_None; + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_Ldb___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) { PyObject *resultobj = 0; ldb *arg1 = (ldb *) 0 ; @@ -5400,6 +5680,7 @@ fail: static PyMethodDef SwigMethods[] = { + { (char *)"ldb_val_to_py_object", (PyCFunction) _wrap_ldb_val_to_py_object, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"new_Dn", (PyCFunction) _wrap_new_Dn, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"delete_Dn", (PyCFunction)_wrap_delete_Dn, METH_O, NULL}, { (char *)"Dn_validate", (PyCFunction)_wrap_Dn_validate, METH_O, NULL}, @@ -5454,6 +5735,7 @@ static PyMethodDef SwigMethods[] = { { (char *)"Ldb_get_root_basedn", (PyCFunction)_wrap_Ldb_get_root_basedn, METH_O, NULL}, { (char *)"Ldb_get_schema_basedn", (PyCFunction)_wrap_Ldb_get_schema_basedn, METH_O, NULL}, { (char *)"Ldb_get_default_basedn", (PyCFunction)_wrap_Ldb_get_default_basedn, METH_O, NULL}, + { (char *)"Ldb_schema_format_value", (PyCFunction) _wrap_Ldb_schema_format_value, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Ldb_errstring", (PyCFunction)_wrap_Ldb_errstring, METH_O, NULL}, { (char *)"Ldb_set_create_perms", (PyCFunction) _wrap_Ldb_set_create_perms, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Ldb_set_modules_dir", (PyCFunction) _wrap_Ldb_set_modules_dir, METH_VARARGS | METH_KEYWORDS, NULL}, @@ -5463,6 +5745,9 @@ static PyMethodDef SwigMethods[] = { { (char *)"Ldb_transaction_start", (PyCFunction)_wrap_Ldb_transaction_start, METH_O, NULL}, { (char *)"Ldb_transaction_commit", (PyCFunction)_wrap_Ldb_transaction_commit, METH_O, NULL}, { (char *)"Ldb_transaction_cancel", (PyCFunction)_wrap_Ldb_transaction_cancel, METH_O, NULL}, + { (char *)"Ldb_schema_attribute_remove", (PyCFunction) _wrap_Ldb_schema_attribute_remove, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Ldb_schema_attribute_add", (PyCFunction) _wrap_Ldb_schema_attribute_add, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"Ldb_setup_wellknown_attributes", (PyCFunction)_wrap_Ldb_setup_wellknown_attributes, METH_O, NULL}, { (char *)"Ldb___contains__", (PyCFunction) _wrap_Ldb___contains__, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Ldb_parse_ldif", (PyCFunction) _wrap_Ldb_parse_ldif, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"Ldb_swigregister", Ldb_swigregister, METH_VARARGS, NULL}, @@ -5488,6 +5773,7 @@ static swig_type_info _swigt__p_ldb_message = {"_p_ldb_message", "ldb_msg *|stru 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_module_ops = {"_p_ldb_module_ops", "struct ldb_module_ops *", 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_ldb_val = {"_p_ldb_val", "struct ldb_val *", 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_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_p_ldb_control = {"_p_p_ldb_control", "struct ldb_control **", 0, 0, (void*)0, 0}; @@ -5513,6 +5799,7 @@ static swig_type_info *swig_type_initial[] = { &_swigt__p_ldb_message_element, &_swigt__p_ldb_module_ops, &_swigt__p_ldb_result, + &_swigt__p_ldb_val, &_swigt__p_long_long, &_swigt__p_p_char, &_swigt__p_p_ldb_control, @@ -5538,6 +5825,7 @@ static swig_cast_info _swigc__p_ldb_message[] = { {&_swigt__p_ldb_message, 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_module_ops[] = { {&_swigt__p_ldb_module_ops, 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_ldb_val[] = { {&_swigt__p_ldb_val, 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_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}}; static swig_cast_info _swigc__p_p_ldb_control[] = { {&_swigt__p_p_ldb_control, 0, 0, 0},{0, 0, 0, 0}}; @@ -5563,6 +5851,7 @@ static swig_cast_info *swig_cast_initial[] = { _swigc__p_ldb_message_element, _swigc__p_ldb_module_ops, _swigc__p_ldb_result, + _swigc__p_ldb_val, _swigc__p_long_long, _swigc__p_p_char, _swigc__p_p_ldb_control, -- 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(-) 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(-) 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 b0e286a5be6137a0c5cd4029cdb3ae7abbd48b25 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jan 2008 08:08:33 +0100 Subject: repl_meta_data: add some TODOs to replmd_modify_originating() metze (This used to be commit ba495f9d19e7c7cfc9135a5d40e1050dd8f9ebc6) --- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 5100b7cb7c..441dbc9598 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -509,6 +509,18 @@ static int replmd_modify_originating(struct ldb_module *module, return LDB_ERR_OPERATIONS_ERROR; } + /* TODO: + * - get the whole old object + * - if the old object doesn't exist report an error + * - give an error when a readonly attribute should + * be modified + * - merge the changed into the old object + * if the caller set values to the same value + * ignore the attribute, return success when no + * attribute was changed + * - calculate the new replPropertyMetaData attribute + */ + if (add_time_element(msg, "whenChanged", t) != 0) { talloc_free(down_req); return LDB_ERR_OPERATIONS_ERROR; @@ -523,6 +535,11 @@ static int replmd_modify_originating(struct ldb_module *module, } } + /* TODO: + * - sort the attributes by attid with replmd_ldb_message_sort() + * - replace the old object with the newly constructed one + */ + ldb_set_timeout_from_prev_req(module->ldb, req, down_req); /* go on with the call chain */ -- cgit From 125311d92948ef600eb11d411ede9e1966922f76 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jan 2008 08:40:03 +0100 Subject: configure.ac: we should only create ldb.pc when use the internal ldb metze (This used to be commit 2c75bd5009020171e31b56ab3d8d6a86f19f3b49) --- source4/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/configure.ac b/source4/configure.ac index 23fc1023ad..e4e205e626 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -60,7 +60,6 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1, SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) SMB_SUBSYSTEM(ldb_map, [], [LIBLDB]) - AC_OUTPUT(lib/ldb/ldb.pc) define_ldb_modulesdir=no ], [ @@ -84,6 +83,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1, m4_include(lib/ldb/sqlite3.m4) m4_include(lib/ldb/libldb.m4) SMB_INCLUDE_MK(lib/ldb/config.mk) + AC_OUTPUT(lib/ldb/ldb.pc) ] ) SMB_INCLUDE_MK(lib/ldb/python.mk) -- cgit From 876fdde645de89123eac812ca694750e0022f1a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jan 2008 08:42:30 +0100 Subject: configure.ac: we should use AC_CONFIG_FILES() in order to use AC_OUTPUT only once metze (This used to be commit bcaba3cb725e1cbbe164132179a0849c7b546a73) --- source4/configure.ac | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source4/configure.ac b/source4/configure.ac index e4e205e626..ed74bc1251 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -27,20 +27,20 @@ m4_include(lib/charset/config.m4) m4_include(lib/socket/config.m4) m4_include(nsswitch/nsstest.m4) -AC_OUTPUT(lib/registry/registry.pc) -AC_OUTPUT(librpc/dcerpc.pc) -AC_OUTPUT(librpc/ndr.pc) -AC_OUTPUT(torture/torture.pc) -AC_OUTPUT(auth/gensec/gensec.pc) -AC_OUTPUT(param/samba-config.pc) -AC_OUTPUT(librpc/dcerpc_samr.pc) +AC_CONFIG_FILES(lib/registry/registry.pc) +AC_CONFIG_FILES(librpc/dcerpc.pc) +AC_CONFIG_FILES(librpc/ndr.pc) +AC_CONFIG_FILES(torture/torture.pc) +AC_CONFIG_FILES(auth/gensec/gensec.pc) +AC_CONFIG_FILES(param/samba-config.pc) +AC_CONFIG_FILES(librpc/dcerpc_samr.pc) SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.1.0, [], [ m4_include(lib/talloc/libtalloc.m4) SMB_INCLUDE_MK(lib/talloc/config.mk) - AC_OUTPUT(lib/talloc/talloc.pc) + AC_CONFIG_FILES(lib/talloc/talloc.pc) ] ) @@ -49,7 +49,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.0, [ m4_include(lib/tdb/libtdb.m4) SMB_INCLUDE_MK(lib/tdb/config.mk) - AC_OUTPUT(lib/tdb/tdb.pc) + AC_CONFIG_FILES(lib/tdb/tdb.pc) ] ) @@ -83,7 +83,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1, m4_include(lib/ldb/sqlite3.m4) m4_include(lib/ldb/libldb.m4) SMB_INCLUDE_MK(lib/ldb/config.mk) - AC_OUTPUT(lib/ldb/ldb.pc) + AC_CONFIG_FILES(lib/ldb/ldb.pc) ] ) SMB_INCLUDE_MK(lib/ldb/python.mk) -- cgit From 5d55aa99e6488244208d7d84b188f92306c083f6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 25 Jan 2008 10:07:43 +0100 Subject: pidl/Samba4::Header: fix typedefs of unions and structs without elements metze (This used to be commit 3131847cb67dadd8ee6fcbca5055927b8ba8a219) --- source4/pidl/lib/Parse/Pidl/Samba4/Header.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm index 14f472340c..2e77ff01b8 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -86,6 +86,7 @@ sub HeaderStruct($$;$) { my($struct,$name,$tail) = @_; pidl "struct $name"; + pidl $tail if defined($tail) and not defined($struct->{ELEMENTS}); return if (not defined($struct->{ELEMENTS})); pidl " {\n"; $tab_depth++; @@ -178,6 +179,7 @@ sub HeaderUnion($$;$) my %done = (); pidl "union $name"; + pidl $tail if defined($tail) and not defined($union->{ELEMENTS}); return if (not defined($union->{ELEMENTS})); pidl " {\n"; $tab_depth++; -- 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(-) 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(-) 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