diff options
-rw-r--r-- | source4/samba4-knownfail | 1 | ||||
-rw-r--r-- | source4/scripting/python/samba/provision.py | 40 | ||||
-rw-r--r-- | source4/torture/config.mk | 8 | ||||
-rw-r--r-- | source4/torture/libnet/libnet_BecomeDC.c | 341 | ||||
-rw-r--r-- | source4/torture/local/torture.c | 37 | ||||
-rw-r--r-- | source4/torture/util_provision.c | 355 | ||||
-rw-r--r-- | source4/torture/util_provision.h | 51 |
7 files changed, 501 insertions, 332 deletions
diff --git a/source4/samba4-knownfail b/source4/samba4-knownfail index ab03145354..376d627764 100644 --- a/source4/samba4-knownfail +++ b/source4/samba4-knownfail @@ -36,3 +36,4 @@ BASE-CHARSET.*.Testing partial surrogate RAP.*netservergetinfo kinit with pkinit # fails with: salt type 3 not supported samba4.blackbox.provision.py.reprovision # Fails with entry already exists +LOCAL-TORTURE.provision diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 97021fceb2..d30eaf3d7f 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -271,7 +271,7 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, configdn, schemadn, domaindn, hostname, netbiosname, dnsdomain, realm, - rootdn, serverrole, ldap_backend=None, + rootdn, serverrole, sitename, ldap_backend=None, ldap_backend_type=None, erase=False): """Setup the partitions for the SAM database. @@ -378,7 +378,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, message("Setting up sam.ldb rootDSE") setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname) + dnsdomain, realm, rootdn, configdn, netbiosname, + sitename) if erase: message("Erasing data from partitions") @@ -472,7 +473,8 @@ def setup_registry(path, setup_path, session_info, credentials, lp): def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname): + dnsdomain, realm, rootdn, configdn, netbiosname, + sitename): """Setup the SamDB rootdse. :param samdb: Sam Database handle @@ -482,7 +484,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DNSDOMAIN": dnsdomain, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "REALM": realm, "DNSNAME": "%s.%s" % (hostname, dnsdomain), "DOMAINDN": domaindn, @@ -495,7 +497,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, def setup_self_join(samdb, configdn, schemadn, domaindn, netbiosname, hostname, dnsdomain, machinepass, dnspass, realm, domainname, domainsid, invocationid, setup_path, - policyguid, hostguid=None): + policyguid, sitename, hostguid=None): """Join a host to its own domain.""" if hostguid is not None: hostguid_add = "objectGUID: %s" % hostguid @@ -508,7 +510,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, "DOMAINDN": domaindn, "INVOCATIONID": invocationid, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "DNSNAME": "%s.%s" % (hostname, dnsdomain), "MACHINEPASS_B64": b64encode(machinepass), "DNSPASS_B64": b64encode(dnspass), @@ -529,7 +531,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domainsid, aci, domainguid, policyguid, domainname, fill, adminpass, krbtgtpass, machinepass, hostguid, invocationid, dnspass, - serverrole, ldap_backend=None, ldap_backend_type=None): + serverrole, sitename, ldap_backend=None, + ldap_backend_type=None): """Setup a complete SAM Database. :note: This will wipe the main SAM database file! @@ -544,7 +547,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, hostname=hostname, netbiosname=netbiosname, dnsdomain=dnsdomain, realm=realm, rootdn=rootdn, ldap_backend=ldap_backend, serverrole=serverrole, - ldap_backend_type=ldap_backend_type, erase=erase) + ldap_backend_type=ldap_backend_type, erase=erase, + sitename=sitename) samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) @@ -562,7 +566,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if lp.get("server role") == "domain controller": samdb.set_invocation_id(invocationid) - load_schema(setup_path, samdb, schemadn, netbiosname, configdn) + load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename) samdb.transaction_start() @@ -584,7 +588,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "DOMAINSID": str(domainsid), "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, "POLICYGUID": policyguid, "DOMAINDN": domaindn, @@ -614,7 +618,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, }) @@ -629,7 +633,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { "CONFIGDN": configdn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "DNSDOMAIN": dnsdomain, "DOMAIN": domainname, "SCHEMADN": schemadn, @@ -656,7 +660,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision.ldif"), { "DOMAINDN": domaindn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, }) @@ -679,7 +683,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, machinepass=machinepass, domainname=domainname, domainsid=domainsid, policyguid=policyguid, hostname=hostname, hostguid=hostguid, - setup_path=setup_path) + setup_path=setup_path, sitename=sitename) #We want to setup the index last, as adds are faster unindexed message("Setting up sam.ldb index") @@ -702,7 +706,7 @@ def provision(lp, setup_dir, message, paths, session_info, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, erase=False, - ldap_backend=None, ldap_backend_type=None): + ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): """Provision samba4 :note: caution, this wipes all existing data! @@ -851,7 +855,7 @@ def provision(lp, setup_dir, message, paths, session_info, hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, dnspass=dnspass, serverrole=serverrole, ldap_backend=ldap_backend, - ldap_backend_type=ldap_backend_type) + ldap_backend_type=ldap_backend_type, sitename=sitename) if lp.get("server role") == "domain controller": policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", @@ -945,7 +949,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, }) -def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): +def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. @@ -962,7 +966,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE": DEFAULTSITE + "DEFAULTSITE":sitename }) samdb.attach_schema_from_ldif(head_data, schema_data) diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 18e5ea70ec..5a3e3d0658 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -14,8 +14,8 @@ PUBLIC_DEPENDENCIES = \ LIBTALLOC [SUBSYSTEM::TORTURE_UTIL] -OBJ_FILES = util_smb.o -PRIVATE_DEPENDENCIES = LIBCLI_RAW +OBJ_FILES = util_smb.o util_provision.o +PRIVATE_DEPENDENCIES = LIBCLI_RAW LIBPYTHON smbcalls PUBLIC_PROTO_HEADER = util.h PUBLIC_DEPENDENCIES = POPT_CREDENTIALS @@ -295,10 +295,8 @@ OBJ_FILES = \ libnet/libnet_BecomeDC.o PRIVATE_DEPENDENCIES = \ LIBSAMBA-NET \ - smbcalls \ POPT_CREDENTIALS \ - torture_rpc \ - LIBPYTHON + torture_rpc # End SUBSYSTEM TORTURE_NET ################################# diff --git a/source4/torture/libnet/libnet_BecomeDC.c b/source4/torture/libnet/libnet_BecomeDC.c index 997dbc93b8..13e1aec6d0 100644 --- a/source4/torture/libnet/libnet_BecomeDC.c +++ b/source4/torture/libnet/libnet_BecomeDC.c @@ -34,8 +34,10 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "librpc/gen_ndr/ndr_misc.h" #include "system/time.h" -#include "auth/auth.h" #include "lib/ldb_wrap.h" +#include "auth/auth.h" +#include "param/param.h" +#include "torture/util_provision.h" struct test_become_dc_state { struct libnet_context *ctx; @@ -66,6 +68,35 @@ struct test_become_dc_state { } path; }; +static NTSTATUS test_become_dc_prepare_db(void *private_data, + const struct libnet_BecomeDC_PrepareDB *p) +{ + struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state); + struct provision_settings settings; + + settings.dns_name = p->dest_dsa->dns_name; + settings.site_name = p->dest_dsa->site_name; + settings.root_dn_str = p->forest->root_dn_str; + settings.domain_dn_str = p->domain->dn_str; + settings.config_dn_str = p->forest->config_dn_str; + settings.schema_dn_str = p->forest->schema_dn_str; + settings.invocation_id = &p->dest_dsa->invocation_id; + settings.netbios_name = p->dest_dsa->netbios_name; + settings.realm = torture_join_dom_dns_name(s->tj); + settings.domain = torture_join_dom_netbios_name(s->tj); + settings.ntds_guid = &p->dest_dsa->ntds_guid; + settings.ntds_dn_str = p->dest_dsa->ntds_dn_str; + settings.machine_password = cli_credentials_get_password(s->machine_account); + settings.samdb_ldb = s->path.samdb_ldb; + settings.secrets_ldb = s->path.secrets_ldb; + settings.secrets_keytab = s->path.secrets_keytab; + settings.schemadn_ldb = s->path.schemadn_ldb; + settings.configdn_ldb = s->path.configdn_ldb; + settings.domaindn_ldb = s->path.domaindn_ldb; + + return provision_bare(s, s->tctx->lp_ctx, &settings); +} + static NTSTATUS test_become_dc_check_options(void *private_data, const struct libnet_BecomeDC_CheckOptions *o) { @@ -90,309 +121,6 @@ static NTSTATUS test_become_dc_check_options(void *private_data, return NT_STATUS_OK; } -#include "lib/appweb/ejs/ejs.h" -#include "lib/appweb/ejs/ejsInternal.h" -#include "scripting/ejs/smbcalls.h" - -static EjsId eid; -static int ejs_error; - -static void test_ejs_exception(const char *reason) -{ - Ejs *ep = ejsPtr(eid); - ejsSetErrorMsg(eid, "%s", reason); - fprintf(stderr, "%s", ep->error); - ejs_error = 127; -} - -static int test_run_ejs(char *script) -{ - EjsHandle handle = 0; - MprVar result; - char *emsg; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct MprVar *return_var; - - mprSetCtx(mem_ctx); - - if (ejsOpen(NULL, NULL, NULL) != 0) { - d_printf("ejsOpen(): unable to initialise EJS subsystem\n"); - ejs_error = 127; - goto failed; - } - - smb_setup_ejs_functions(test_ejs_exception); - - if ((eid = ejsOpenEngine(handle, 0)) == (EjsId)-1) { - d_printf("smbscript: ejsOpenEngine(): unable to initialise an EJS engine\n"); - ejs_error = 127; - goto failed; - } - - mprSetVar(ejsGetGlobalObject(eid), "ARGV", mprList("ARGV", NULL)); - - /* run the script */ - if (ejsEvalScript(eid, script, &result, &emsg) == -1) { - d_printf("smbscript: ejsEvalScript(): %s\n", emsg); - if (ejs_error == 0) ejs_error = 127; - goto failed; - } - - return_var = ejsGetReturnValue(eid); - ejs_error = mprVarToNumber(return_var); - -failed: - ejsClose(); - talloc_free(mem_ctx); - return ejs_error; -} - -static NTSTATUS test_become_dc_prepare_db_ejs(void *private_data, - const struct libnet_BecomeDC_PrepareDB *p) -{ - struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state); - char *ejs; - int ret; - bool ok; - - DEBUG(0,("Provision for Become-DC test using EJS\n")); - - DEBUG(0,("New Server[%s] in Site[%s]\n", - p->dest_dsa->dns_name, p->dest_dsa->site_name)); - - DEBUG(0,("DSA Instance [%s]\n" - "\tobjectGUID[%s]\n" - "\tinvocationId[%s]\n", - p->dest_dsa->ntds_dn_str, - GUID_string(s, &p->dest_dsa->ntds_guid), - GUID_string(s, &p->dest_dsa->invocation_id))); - - DEBUG(0,("Pathes under PRIVATEDIR[%s]\n" - "SAMDB[%s] SECRETS[%s] KEYTAB[%s]\n", - lp_private_dir(s->tctx->lp_ctx), - s->path.samdb_ldb, - s->path.secrets_ldb, - s->path.secrets_keytab)); - - DEBUG(0,("Schema Partition[%s => %s]\n", - p->forest->schema_dn_str, s->path.schemadn_ldb)); - - DEBUG(0,("Config Partition[%s => %s]\n", - p->forest->config_dn_str, s->path.configdn_ldb)); - - DEBUG(0,("Domain Partition[%s => %s]\n", - p->domain->dn_str, s->path.domaindn_ldb)); - - ejs = talloc_asprintf(s, - "libinclude(\"base.js\");\n" - "libinclude(\"provision.js\");\n" - "\n" - "function message() { print(vsprintf(arguments)); }\n" - "\n" - "var subobj = provision_guess();\n" - "subobj.ROOTDN = \"%s\";\n" - "subobj.DOMAINDN = \"%s\";\n" - "subobj.DOMAINDN_LDB = \"%s\";\n" - "subobj.CONFIGDN = \"%s\";\n" - "subobj.CONFIGDN_LDB = \"%s\";\n" - "subobj.SCHEMADN = \"%s\";\n" - "subobj.SCHEMADN_LDB = \"%s\";\n" - "subobj.HOSTNAME = \"%s\";\n" - "subobj.REALM = \"%s\";\n" - "subobj.DOMAIN = \"%s\";\n" - "subobj.DEFAULTSITE = \"%s\";\n" - "\n" - "subobj.KRBTGTPASS = \"_NOT_USED_\";\n" - "subobj.MACHINEPASS = \"%s\";\n" - "subobj.ADMINPASS = \"_NOT_USED_\";\n" - "\n" - "var paths = provision_default_paths(subobj);\n" - "paths.samdb = \"%s\";\n" - "paths.secrets = \"%s\";\n" - "paths.templates = \"%s\";\n" - "paths.keytab = \"%s\";\n" - "paths.dns_keytab = \"%s\";\n" - "\n" - "var system_session = system_session();\n" - "\n" - "var ok = provision_become_dc(subobj, message, true, paths, system_session);\n" - "assert(ok);\n" - "\n" - "return 0;\n", - p->forest->root_dn_str, /* subobj.ROOTDN */ - p->domain->dn_str, /* subobj.DOMAINDN */ - s->path.domaindn_ldb, /* subobj.DOMAINDN_LDB */ - p->forest->config_dn_str, /* subobj.CONFIGDN */ - s->path.configdn_ldb, /* subobj.CONFIGDN_LDB */ - p->forest->schema_dn_str, /* subobj.SCHEMADN */ - s->path.schemadn_ldb, /* subobj.SCHEMADN_LDB */ - p->dest_dsa->netbios_name, /* subobj.HOSTNAME */ - torture_join_dom_dns_name(s->tj),/* subobj.REALM */ - torture_join_dom_netbios_name(s->tj),/* subobj.DOMAIN */ - p->dest_dsa->site_name, /* subobj.DEFAULTSITE */ - cli_credentials_get_password(s->machine_account),/* subobj.MACHINEPASS */ - s->path.samdb_ldb, /* paths.samdb */ - s->path.templates_ldb, /* paths.templates */ - s->path.secrets_ldb, /* paths.secrets */ - s->path.secrets_keytab, /* paths.keytab */ - s->path.dns_keytab); /* paths.dns_keytab */ - NT_STATUS_HAVE_NO_MEMORY(ejs); - - ret = test_run_ejs(ejs); - if (ret != 0) { - DEBUG(0,("Failed to run ejs script: %d:\n%s", - ret, ejs)); - talloc_free(ejs); - return NT_STATUS_FOOBAR; - } - talloc_free(ejs); - - talloc_free(s->ldb); - - DEBUG(0,("Open the SAM LDB with system credentials: %s\n", - s->path.samdb_ldb)); - - s->ldb = ldb_wrap_connect(s, s->tctx->lp_ctx, s->path.samdb_ldb, - system_session(s, s->tctx->lp_ctx), - NULL, 0, NULL); - if (!s->ldb) { - DEBUG(0,("Failed to open '%s'\n", - s->path.samdb_ldb)); - return NT_STATUS_INTERNAL_DB_ERROR; - } - - ok = samdb_set_ntds_invocation_id(s->ldb, &p->dest_dsa->invocation_id); - if (!ok) { - DEBUG(0,("Failed to set cached ntds invocationId\n")); - return NT_STATUS_FOOBAR; - } - ok = samdb_set_ntds_objectGUID(s->ldb, &p->dest_dsa->ntds_guid); - if (!ok) { - DEBUG(0,("Failed to set cached ntds objectGUID\n")); - return NT_STATUS_FOOBAR; - } - - return NT_STATUS_OK; -} - -#include "param/param.h" -#include <Python.h> -#include "scripting/python/modules.h" - -static NTSTATUS test_become_dc_prepare_db_py(void *private_data, - const struct libnet_BecomeDC_PrepareDB *p) -{ - struct test_become_dc_state *s = talloc_get_type(private_data, struct test_become_dc_state); - bool ok; - PyObject *module, *module_dict; - PyObject *provision_fn, *result, *parameters; - - DEBUG(0,("Provision for Become-DC test using PYTHON\n")); - - py_load_samba_modules(); - Py_Initialize(); - - py_update_path("bin"); /* FIXME: Can't assume this always runs in source/... */ - - module = PyImport_Import(PyString_FromString("samba.provision")); - if (module == NULL) { - DEBUG(0, ("Unable to import 'samba.provision' Python module.\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - module_dict = PyModule_GetDict(module); - if (module_dict == NULL) { - DEBUG(0, ("Unable to GetDict of 'samba.provision'.\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - provision_fn = PyDict_GetItemString(module_dict, "provision"); - if (provision_fn == NULL) { - DEBUG(0, ("Unable to get function 'provision' of 'samba.provision'.\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(0,("New Server[%s] in Site[%s]\n", - p->dest_dsa->dns_name, p->dest_dsa->site_name)); - - DEBUG(0,("DSA Instance [%s]\n" - "\tobjectGUID[%s]\n" - "\tinvocationId[%s]\n", - p->dest_dsa->ntds_dn_str, - GUID_string(s, &p->dest_dsa->ntds_guid), - GUID_string(s, &p->dest_dsa->invocation_id))); - - DEBUG(0,("Pathes under PRIVATEDIR[%s]\n" - "SAMDB[%s] SECRETS[%s] KEYTAB[%s]\n", - lp_private_dir(s->tctx->lp_ctx), - s->path.samdb_ldb, - s->path.secrets_ldb, - s->path.secrets_keytab)); - - DEBUG(0,("Schema Partition[%s => %s]\n", - p->forest->schema_dn_str, s->path.schemadn_ldb)); - - DEBUG(0,("Config Partition[%s => %s]\n", - p->forest->config_dn_str, s->path.configdn_ldb)); - - DEBUG(0,("Domain Partition[%s => %s]\n", - p->domain->dn_str, s->path.domaindn_ldb)); - - parameters = PyDict_New(); - - PyDict_SetItemString(parameters, "rootdn", PyString_FromString(p->forest->root_dn_str)); - PyDict_SetItemString(parameters, "domaindn", PyString_FromString(p->domain->dn_str)); - PyDict_SetItemString(parameters, "domaindn_ldb", PyString_FromString(s->path.domaindn_ldb)); - PyDict_SetItemString(parameters, "configdn", PyString_FromString(p->forest->config_dn_str)); - PyDict_SetItemString(parameters, "configdn_ldb", PyString_FromString(s->path.configdn_ldb)); - PyDict_SetItemString(parameters, "schema_dn_str", PyString_FromString(p->forest->schema_dn_str)); - PyDict_SetItemString(parameters, "schemadn_ldb", PyString_FromString(s->path.schemadn_ldb)); - PyDict_SetItemString(parameters, "netbios_name", PyString_FromString(p->dest_dsa->netbios_name)); - PyDict_SetItemString(parameters, "dnsname", PyString_FromString(p->dest_dsa->dns_name)); - PyDict_SetItemString(parameters, "defaultsite", PyString_FromString(p->dest_dsa->site_name)); - PyDict_SetItemString(parameters, "machinepass", PyString_FromString(cli_credentials_get_password(s->machine_account))); - PyDict_SetItemString(parameters, "samdb", PyString_FromString(s->path.samdb_ldb)); - PyDict_SetItemString(parameters, "secrets_ldb", PyString_FromString(s->path.secrets_ldb)); - PyDict_SetItemString(parameters, "secrets_keytab", PyString_FromString(s->path.secrets_keytab)); - - result = PyEval_CallObjectWithKeywords(provision_fn, NULL, parameters); - - Py_DECREF(parameters); - - if (result == NULL) { - PyErr_Print(); - PyErr_Clear(); - return NT_STATUS_UNSUCCESSFUL; - } - - talloc_free(s->ldb); - - DEBUG(0,("Open the SAM LDB with system credentials: %s\n", - s->path.samdb_ldb)); - - s->ldb = ldb_wrap_connect(s, s->tctx->lp_ctx, s->path.samdb_ldb, - system_session(s, s->tctx->lp_ctx), - NULL, 0, NULL); - if (!s->ldb) { - DEBUG(0,("Failed to open '%s'\n", - s->path.samdb_ldb)); - return NT_STATUS_INTERNAL_DB_ERROR; - } - - ok = samdb_set_ntds_invocation_id(s->ldb, &p->dest_dsa->invocation_id); - if (!ok) { - DEBUG(0,("Failed to set cached ntds invocationId\n")); - return NT_STATUS_FOOBAR; - } - ok = samdb_set_ntds_objectGUID(s->ldb, &p->dest_dsa->ntds_guid); - if (!ok) { - DEBUG(0,("Failed to set cached ntds objectGUID\n")); - return NT_STATUS_FOOBAR; - } - - return NT_STATUS_OK; -} - static NTSTATUS test_apply_schema(struct test_become_dc_state *s, const struct libnet_BecomeDC_StoreChunk *c) { @@ -888,10 +616,7 @@ bool torture_net_become_dc(struct torture_context *torture) b.in.callbacks.private_data = s; b.in.callbacks.check_options = test_become_dc_check_options; - b.in.callbacks.prepare_db = test_become_dc_prepare_db_py; - if (getenv("PROVISION_EJS")) { - b.in.callbacks.prepare_db = test_become_dc_prepare_db_ejs; - } + b.in.callbacks.prepare_db = test_become_dc_prepare_db; b.in.callbacks.schema_chunk = test_become_dc_schema_chunk; b.in.callbacks.config_chunk = test_become_dc_store_chunk; b.in.callbacks.domain_chunk = test_become_dc_store_chunk; diff --git a/source4/torture/local/torture.c b/source4/torture/local/torture.c index b57361bc8d..0c9931be03 100644 --- a/source4/torture/local/torture.c +++ b/source4/torture/local/torture.c @@ -24,7 +24,7 @@ #include "system/wait.h" #include "lib/events/events.h" #include "libcli/raw/libcliraw.h" -#include "torture/util.h" +#include "torture/util_provision.h" static bool test_tempdir(struct torture_context *tctx) { @@ -39,12 +39,47 @@ static bool test_tempdir(struct torture_context *tctx) return true; } +static bool test_provision(struct torture_context *tctx) +{ + NTSTATUS status; + struct provision_settings settings; + + settings.dns_name = "example.com"; + settings.site_name = "SOME-SITE-NAME"; + settings.root_dn_str = "DC=EXAMPLE,DC=COM"; + settings.domain_dn_str = "DC=EXAMPLE,DC=COM"; + settings.config_dn_str = NULL; + settings.schema_dn_str = NULL; + settings.invocation_id = NULL; + settings.netbios_name = "FOO"; + settings.realm = "EXAMPLE.COM"; + settings.domain = "EXAMPLE"; + settings.ntds_guid = NULL; + settings.ntds_dn_str = NULL; + settings.machine_password = "geheim"; + settings.samdb_ldb = NULL; + settings.secrets_ldb = NULL; + settings.secrets_keytab = NULL; + settings.schemadn_ldb = NULL; + settings.configdn_ldb = NULL; + settings.domaindn_ldb = NULL; + settings.templates_ldb = NULL; + settings.dns_keytab = NULL; + + status = provision_bare(tctx, tctx->lp_ctx, &settings); + + torture_assert_ntstatus_ok(tctx, status, "provision"); + + return true; +} + struct torture_suite *torture_local_torture(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "TORTURE"); torture_suite_add_simple_test(suite, "tempdir", test_tempdir); + torture_suite_add_simple_test(suite, "provision", test_provision); return suite; } diff --git a/source4/torture/util_provision.c b/source4/torture/util_provision.c new file mode 100644 index 0000000000..a5c564b05c --- /dev/null +++ b/source4/torture/util_provision.c @@ -0,0 +1,355 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "dsdb/samdb/samdb.h" +#include "lib/appweb/ejs/ejs.h" +#include "lib/appweb/ejs/ejsInternal.h" +#include "scripting/ejs/smbcalls.h" +#include "auth/auth.h" +#include "lib/ldb_wrap.h" +#include "torture/util_provision.h" + +static EjsId eid; +static int ejs_error; + +static void test_ejs_exception(const char *reason) +{ + Ejs *ep = ejsPtr(eid); + ejsSetErrorMsg(eid, "%s", reason); + fprintf(stderr, "%s", ep->error); + ejs_error = 127; +} + +static int test_run_ejs(char *script) +{ + EjsHandle handle = 0; + MprVar result; + char *emsg; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct MprVar *return_var; + + mprSetCtx(mem_ctx); + + if (ejsOpen(NULL, NULL, NULL) != 0) { + d_printf("ejsOpen(): unable to initialise EJS subsystem\n"); + ejs_error = 127; + goto failed; + } + + smb_setup_ejs_functions(test_ejs_exception); + + if ((eid = ejsOpenEngine(handle, 0)) == (EjsId)-1) { + d_printf("smbscript: ejsOpenEngine(): unable to initialise an EJS engine\n"); + ejs_error = 127; + goto failed; + } + + mprSetVar(ejsGetGlobalObject(eid), "ARGV", mprList("ARGV", NULL)); + + /* run the script */ + if (ejsEvalScript(eid, script, &result, &emsg) == -1) { + d_printf("smbscript: ejsEvalScript(): %s\n", emsg); + if (ejs_error == 0) ejs_error = 127; + goto failed; + } + + return_var = ejsGetReturnValue(eid); + ejs_error = mprVarToNumber(return_var); + +failed: + ejsClose(); + talloc_free(mem_ctx); + return ejs_error; +} + +static NTSTATUS provision_bare_ejs(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct provision_settings *settings) +{ + char *ejs; + int ret; + bool ok; + struct ldb_context *ldb; + + DEBUG(0,("Provision for Become-DC test using EJS\n")); + + DEBUG(0,("New Server[%s] in Site[%s]\n", settings->dns_name, + settings->site_name)); + + DEBUG(0,("DSA Instance [%s]\n" + "\tobjectGUID[%s]\n" + "\tinvocationId[%s]\n", + settings->ntds_dn_str, + GUID_string(mem_ctx, settings->ntds_guid), + GUID_string(mem_ctx, settings->invocation_id))); + + DEBUG(0,("Pathes under PRIVATEDIR[%s]\n" + "SAMDB[%s] SECRETS[%s] KEYTAB[%s]\n", + lp_private_dir(lp_ctx), + settings->samdb_ldb, + settings->secrets_ldb, + settings->secrets_keytab)); + + DEBUG(0,("Schema Partition[%s => %s]\n", + settings->schema_dn_str, settings->schemadn_ldb)); + + DEBUG(0,("Config Partition[%s => %s]\n", + settings->config_dn_str, settings->configdn_ldb)); + + DEBUG(0,("Domain Partition[%s => %s]\n", + settings->domain_dn_str, settings->domaindn_ldb)); + + ejs = talloc_asprintf(mem_ctx, + "libinclude(\"base.js\");\n" + "libinclude(\"provision.js\");\n" + "\n" + "function message() { print(vsprintf(arguments)); }\n" + "\n" + "var subobj = provision_guess();\n" + "subobj.ROOTDN = \"%s\";\n" + "subobj.DOMAINDN = \"%s\";\n" + "subobj.DOMAINDN_LDB = \"%s\";\n" + "subobj.CONFIGDN = \"%s\";\n" + "subobj.CONFIGDN_LDB = \"%s\";\n" + "subobj.SCHEMADN = \"%s\";\n" + "subobj.SCHEMADN_LDB = \"%s\";\n" + "subobj.HOSTNAME = \"%s\";\n" + "subobj.REALM = \"%s\";\n" + "subobj.DOMAIN = \"%s\";\n" + "subobj.DEFAULTSITE = \"%s\";\n" + "\n" + "subobj.KRBTGTPASS = \"_NOT_USED_\";\n" + "subobj.MACHINEPASS = \"%s\";\n" + "subobj.ADMINPASS = \"_NOT_USED_\";\n" + "\n" + "var paths = provision_default_paths(subobj);\n" + "paths.samdb = \"%s\";\n" + "paths.secrets = \"%s\";\n" + "paths.templates = \"%s\";\n" + "paths.keytab = \"%s\";\n" + "paths.dns_keytab = \"%s\";\n" + "\n" + "var system_session = system_session();\n" + "\n" + "var ok = provision_become_dc(subobj, message, true, paths, system_session);\n" + "assert(ok);\n" + "\n" + "return 0;\n", + settings->root_dn_str, /* subobj.ROOTDN */ + settings->domain_dn_str, /* subobj.DOMAINDN */ + settings->domaindn_ldb, /* subobj.DOMAINDN_LDB */ + settings->config_dn_str, /* subobj.CONFIGDN */ + settings->configdn_ldb, /* subobj.CONFIGDN_LDB */ + settings->schema_dn_str, /* subobj.SCHEMADN */ + settings->schemadn_ldb, /* subobj.SCHEMADN_LDB */ + settings->netbios_name, /* subobj.HOSTNAME */ + settings->realm,/* subobj.REALM */ + settings->domain,/* subobj.DOMAIN */ + settings->site_name, /* subobj.DEFAULTSITE */ + settings->machine_password,/* subobj.MACHINEPASS */ + settings->samdb_ldb, /* paths.samdb */ + settings->templates_ldb, /* paths.templates */ + settings->secrets_ldb, /* paths.secrets */ + settings->secrets_keytab, /* paths.keytab */ + settings->dns_keytab); /* paths.dns_keytab */ + NT_STATUS_HAVE_NO_MEMORY(ejs); + + ret = test_run_ejs(ejs); + if (ret != 0) { + DEBUG(0,("Failed to run ejs script: %d:\n%s", + ret, ejs)); + talloc_free(ejs); + return NT_STATUS_FOOBAR; + } + talloc_free(ejs); + + DEBUG(0,("Open the SAM LDB with system credentials: %s\n", + settings->samdb_ldb)); + + ldb = ldb_wrap_connect(mem_ctx, lp_ctx, settings->samdb_ldb, + system_session(mem_ctx, lp_ctx), + NULL, 0, NULL); + if (!ldb) { + DEBUG(0,("Failed to open '%s'\n", + settings->samdb_ldb)); + return NT_STATUS_INTERNAL_DB_ERROR; + } + + ok = samdb_set_ntds_invocation_id(ldb, settings->invocation_id); + if (!ok) { + DEBUG(0,("Failed to set cached ntds invocationId\n")); + return NT_STATUS_FOOBAR; + } + ok = samdb_set_ntds_objectGUID(ldb, settings->ntds_guid); + if (!ok) { + DEBUG(0,("Failed to set cached ntds objectGUID\n")); + return NT_STATUS_FOOBAR; + } + + return NT_STATUS_OK; +} + +#include "param/param.h" +#include <Python.h> +#include "scripting/python/modules.h" + +static NTSTATUS provision_bare_py(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + struct provision_settings *settings) +{ + bool ok; + PyObject *provision_mod, *provision_dict, *provision_fn, *result, *parameters; + struct ldb_context *ldb; + + DEBUG(0,("Provision for Become-DC test using python\n")); + + py_load_samba_modules(); + Py_Initialize(); + py_update_path("bin"); /* FIXME: Can't assume this is always the case */ + + provision_mod = PyImport_Import(PyString_FromString("samba.provision")); + + if (provision_mod == NULL) { + PyErr_Print(); + DEBUG(0, ("Unable to import provision Python module.\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + provision_dict = PyModule_GetDict(provision_mod); + + if (provision_dict == NULL) { + DEBUG(0, ("Unable to get dictionary for provision module\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + provision_fn = PyDict_GetItemString(provision_dict, "provision"); + if (provision_fn == NULL) { + PyErr_Print(); + DEBUG(0, ("Unable to get provision function\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(0,("New Server[%s] in Site[%s]\n", settings->dns_name, + settings->site_name)); + + DEBUG(0,("DSA Instance [%s]\n" + "\tobjectGUID[%s]\n" + "\tinvocationId[%s]\n", + settings->ntds_dn_str, + settings->ntds_guid == NULL?"None":GUID_string(mem_ctx, settings->ntds_guid), + settings->invocation_id == NULL?"None":GUID_string(mem_ctx, settings->invocation_id))); + + DEBUG(0,("Pathes under PRIVATEDIR[%s]\n" + "SAMDB[%s] SECRETS[%s] KEYTAB[%s]\n", + lp_private_dir(lp_ctx), + settings->samdb_ldb, + settings->secrets_ldb, + settings->secrets_keytab)); + + DEBUG(0,("Schema Partition[%s => %s]\n", + settings->schema_dn_str, settings->schemadn_ldb)); + + DEBUG(0,("Config Partition[%s => %s]\n", + settings->config_dn_str, settings->configdn_ldb)); + + DEBUG(0,("Domain Partition[%s => %s]\n", + settings->domain_dn_str, settings->domaindn_ldb)); + + parameters = PyDict_New(); + + PyDict_SetItemString(parameters, "rootdn", + PyString_FromString(settings->root_dn_str)); + if (settings->domaindn_ldb != NULL) + PyDict_SetItemString(parameters, "domaindn_ldb", + PyString_FromString(settings->domaindn_ldb)); + if (settings->config_dn_str != NULL) + PyDict_SetItemString(parameters, "configdn", + PyString_FromString(settings->config_dn_str)); + if (settings->configdn_ldb != NULL) + PyDict_SetItemString(parameters, "configdn_ldb", + PyString_FromString(settings->configdn_ldb)); + if (settings->schema_dn_str != NULL) + PyDict_SetItemString(parameters, "schema_dn_str", + PyString_FromString(settings->schema_dn_str)); + if (settings->schemadn_ldb != NULL) + PyDict_SetItemString(parameters, "schemadn_ldb", + PyString_FromString(settings->schemadn_ldb)); + PyDict_SetItemString(parameters, "hostname", + PyString_FromString(settings->netbios_name)); + PyDict_SetItemString(parameters, "sitename", + PyString_FromString(settings->site_name)); + PyDict_SetItemString(parameters, "machinepass", + PyString_FromString(settings->machine_password)); + if (settings->samdb_ldb != NULL) + PyDict_SetItemString(parameters, "samdb", + PyString_FromString(settings->samdb_ldb)); + if (settings->secrets_ldb != NULL) + PyDict_SetItemString(parameters, "secrets_ldb", + PyString_FromString(settings->secrets_ldb)); + if (settings->secrets_keytab != NULL) + PyDict_SetItemString(parameters, "secrets_keytab", + PyString_FromString(settings->secrets_keytab)); + + result = PyEval_CallObjectWithKeywords(provision_fn, NULL, parameters); + + Py_DECREF(parameters); + + if (result == NULL) { + PyErr_Print(); + PyErr_Clear(); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(0,("Open the SAM LDB with system credentials: %s\n", + settings->samdb_ldb)); + + ldb = ldb_wrap_connect(mem_ctx, lp_ctx, settings->samdb_ldb, + system_session(mem_ctx, lp_ctx), + NULL, 0, NULL); + if (!ldb) { + DEBUG(0,("Failed to open '%s'\n", settings->samdb_ldb)); + return NT_STATUS_INTERNAL_DB_ERROR; + } + + ok = samdb_set_ntds_invocation_id(ldb, settings->invocation_id); + if (!ok) { + DEBUG(0,("Failed to set cached ntds invocationId\n")); + return NT_STATUS_FOOBAR; + } + ok = samdb_set_ntds_objectGUID(ldb, settings->ntds_guid); + if (!ok) { + DEBUG(0,("Failed to set cached ntds objectGUID\n")); + return NT_STATUS_FOOBAR; + } + + return NT_STATUS_OK; +} + +NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct provision_settings *settings) +{ + if (getenv("PROVISION_EJS")) { + return provision_bare_ejs(mem_ctx, lp_ctx, settings); + } else { + return provision_bare_py(mem_ctx, lp_ctx, settings); + } +} + + diff --git a/source4/torture/util_provision.h b/source4/torture/util_provision.h new file mode 100644 index 0000000000..28467080b1 --- /dev/null +++ b/source4/torture/util_provision.h @@ -0,0 +1,51 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _TORTURE_PROVISION_H_ +#define _TORTURE_PROVISION_H_ + +struct provision_settings { + const char *dns_name; + const char *site_name; + const char *root_dn_str; + const char *domain_dn_str; + const char *config_dn_str; + const char *schema_dn_str; + const struct GUID *invocation_id; + const char *netbios_name; + const char *realm; + const char *domain; + const struct GUID *ntds_guid; + const char *ntds_dn_str; + const char *machine_password; + const char *samdb_ldb; + const char *secrets_ldb; + const char *secrets_keytab; + const char *schemadn_ldb; + const char *configdn_ldb; + const char *domaindn_ldb; + const char *templates_ldb; + const char *dns_keytab; +}; + +NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct provision_settings *settings); + + +#endif /* _TORTURE_PROVISION_H_ */ |