From bfddb6816f50f629d29e476327a921212fd63a2d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Sep 2009 16:27:24 -0700 Subject: s4:provision Use code to store domain join in 'net join' as well This ensures we only have one codepath to store the secret, and therefore that we have a single choke point for setting the saltPrincipal, which we were previously skipping. Andrew Bartlett --- source4/param/provision.c | 131 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) (limited to 'source4/param/provision.c') diff --git a/source4/param/provision.c b/source4/param/provision.c index bbc6837a90..355af794d8 100644 --- a/source4/param/provision.c +++ b/source4/param/provision.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij 2008 - + Copyright (C) Andrew Bartlett 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 @@ -20,15 +21,21 @@ #include "includes.h" #include "auth/auth.h" #include "lib/ldb_wrap.h" +#include "ldb/include/ldb.h" +#include "ldb_errors.h" #include "libcli/raw/libcliraw.h" #include "librpc/ndr/libndr.h" #include "param/param.h" #include "param/provision.h" +#include "param/secrets.h" #include +#include "lib/talloc/pytalloc.h" +#include "librpc/rpc/pyrpc.h" #include "scripting/python/modules.h" #include "lib/ldb/pyldb.h" #include "param/pyparam.h" +#include "librpc/ndr/py_security.h" NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct provision_settings *settings, @@ -144,3 +151,125 @@ NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, return NT_STATUS_OK; } + +extern void initldb(void); +extern void initsecurity(void); + +NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct tevent_context *event_ctx, + struct provision_store_self_join_settings *settings, + const char **error_string) +{ + int ret; + PyObject *provision_mod, *provision_dict, *provision_fn, *py_result, *parameters, *py_sid; + struct ldb_context *ldb; + TALLOC_CTX *tmp_mem = talloc_new(mem_ctx); + if (!tmp_mem) { + return NT_STATUS_NO_MEMORY; + } + + /* Open the secrets database */ + ldb = secrets_db_connect(tmp_mem, event_ctx, lp_ctx); + if (!ldb) { + *error_string + = talloc_asprintf(mem_ctx, + "Could not open secrets database"); + talloc_free(tmp_mem); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + ret = ldb_transaction_start(ldb); + + if (ret != LDB_SUCCESS) { + *error_string + = talloc_asprintf(mem_ctx, + "Could not start transaction on secrets database: %s", ldb_errstring(ldb)); + talloc_free(tmp_mem); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + py_load_samba_modules(); + Py_Initialize(); + py_update_path("bin"); /* FIXME: Can't assume this is always the case */ + initldb(); + initsecurity(); + provision_mod = PyImport_Import(PyString_FromString("samba.provision")); + + if (provision_mod == NULL) { + PyErr_Print(); + *error_string + = talloc_asprintf(mem_ctx, "Unable to import provision Python module."); + talloc_free(tmp_mem); + return NT_STATUS_UNSUCCESSFUL; + } + + provision_dict = PyModule_GetDict(provision_mod); + + if (provision_dict == NULL) { + *error_string + = talloc_asprintf(mem_ctx, "Unable to get dictionary for provision module"); + talloc_free(tmp_mem); + return NT_STATUS_UNSUCCESSFUL; + } + + provision_fn = PyDict_GetItemString(provision_dict, "secretsdb_self_join"); + if (provision_fn == NULL) { + PyErr_Print(); + *error_string + = talloc_asprintf(mem_ctx, "Unable to get provision_become_dc function"); + talloc_free(tmp_mem); + return NT_STATUS_UNSUCCESSFUL; + } + + parameters = PyDict_New(); + + PyDict_SetItemString(parameters, "secretsdb", + PyLdb_FromLdbContext(ldb)); + PyDict_SetItemString(parameters, "domain", + PyString_FromString(settings->domain_name)); + PyDict_SetItemString(parameters, "domain", + PyString_FromString(settings->domain_name)); + PyDict_SetItemString(parameters, "realm", + PyString_FromString(settings->realm)); + PyDict_SetItemString(parameters, "machinepass", + PyString_FromString(settings->machine_password)); + PyDict_SetItemString(parameters, "netbiosname", + PyString_FromString(settings->netbios_name)); + + py_sid = py_dom_sid_FromSid(settings->domain_sid); + + PyDict_SetItemString(parameters, "domainsid", + py_sid); + + PyDict_SetItemString(parameters, "secure_channel_type", + PyInt_FromLong(settings->secure_channel_type)); + + PyDict_SetItemString(parameters, "key_version_number", + PyInt_FromLong(settings->key_version_number)); + + py_result = PyEval_CallObjectWithKeywords(provision_fn, NULL, parameters); + + Py_DECREF(parameters); + + if (py_result == NULL) { + ldb_transaction_cancel(ldb); + talloc_free(tmp_mem); + + PyErr_Print(); + PyErr_Clear(); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = ldb_transaction_commit(ldb); + if (ret != LDB_SUCCESS) { + *error_string + = talloc_asprintf(mem_ctx, + "Could not commit transaction on secrets database: %s", ldb_errstring(ldb)); + talloc_free(tmp_mem); + return NT_STATUS_INTERNAL_DB_ERROR; + } + + talloc_free(tmp_mem); + + return NT_STATUS_OK; +} -- cgit