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/config.mk | 2 +- source4/param/provision.c | 131 +++++++++++++++++++++++++++++++++++++++++++++- source4/param/provision.h | 16 ++++++ 3 files changed, 147 insertions(+), 2 deletions(-) (limited to 'source4/param') diff --git a/source4/param/config.mk b/source4/param/config.mk index 6e5290b64d..45eb836bb4 100644 --- a/source4/param/config.mk +++ b/source4/param/config.mk @@ -13,7 +13,7 @@ PUBLIC_HEADERS += param/param.h PC_FILES += $(paramsrcdir)/samba-hostconfig.pc [SUBSYSTEM::PROVISION] -PRIVATE_DEPENDENCIES = LIBPYTHON pyldb pyparam_util +PRIVATE_DEPENDENCIES = LIBPYTHON pyldb pyparam_util python_dcerpc_security PROVISION_OBJ_FILES = $(paramsrcdir)/provision.o $(param_OBJ_FILES) 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; +} diff --git a/source4/param/provision.h b/source4/param/provision.h index af9685d292..c3b3bb88d8 100644 --- a/source4/param/provision.h +++ b/source4/param/provision.h @@ -44,8 +44,24 @@ struct provision_result { struct loadparm_context *lp_ctx; }; +struct provision_store_self_join_settings { + const char *domain_name; + const char *realm; + const char *netbios_name; + const char *account_name; + enum netr_SchannelType secure_channel_type; + const char *machine_password; + int key_version_number; + struct dom_sid *domain_sid; +}; + NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct provision_settings *settings, struct provision_result *result); +NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct tevent_context *ev_ctx, + struct provision_store_self_join_settings *settings, + const char **error_string); + #endif /* _PROVISION_H_ */ -- cgit