summaryrefslogtreecommitdiff
path: root/source3/utils/net_rpc_conf.c
diff options
context:
space:
mode:
authorVicentiu Ciorbaru <cvicentiu@gmail.com>2011-08-03 23:19:21 +0300
committerMichael Adam <obnox@samba.org>2011-08-22 13:59:28 +0200
commit57b7fb7256e0d4e09c29e48950820f80d5c613dc (patch)
tree88c441b68813042f5886d897f47eaed830586f27 /source3/utils/net_rpc_conf.c
parenta00851f33767f466e9d95b4bcac6fecaf26b0fbf (diff)
downloadsamba-57b7fb7256e0d4e09c29e48950820f80d5c613dc.tar.gz
samba-57b7fb7256e0d4e09c29e48950820f80d5c613dc.tar.bz2
samba-57b7fb7256e0d4e09c29e48950820f80d5c613dc.zip
s3-net: Implemented net rpc conf import command
The function takes a local file in smb.conf format, uses calls to smbconf to create smbconf_service structs, which are then placed in the remote registry. The function also provides a test module to only print the changes that it would make. Signed-off-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'source3/utils/net_rpc_conf.c')
-rw-r--r--source3/utils/net_rpc_conf.c350
1 files changed, 347 insertions, 3 deletions
diff --git a/source3/utils/net_rpc_conf.c b/source3/utils/net_rpc_conf.c
index 02cfc33490..d33b2bca15 100644
--- a/source3/utils/net_rpc_conf.c
+++ b/source3/utils/net_rpc_conf.c
@@ -34,7 +34,12 @@
#include "../librpc/gen_ndr/ndr_winreg_c.h"
#include "../libcli/registry/util_reg.h"
#include "rpc_client/cli_winreg.h"
-#include "../lib/smbconf/smbconf.h"
+#include "lib/smbconf/smbconf.h"
+#include "lib/smbconf/smbconf_init.h"
+#include "lib/smbconf/smbconf_reg.h"
+#include "lib/param/loadparm.h"
+
+
/* internal functions */
/**********************************************************
@@ -84,6 +89,21 @@ static int rpc_conf_addshare_usage(struct net_context *c, int argc,
return -1;
}
+
+static int rpc_conf_import_usage(struct net_context *c, int argc,
+ const char**argv)
+{
+ d_printf("%s\n%s",
+ _("Usage:"),
+ _(" net rpc conf import [--test|-T] <filename> "
+ "[<servicename>]\n"
+ "\t[--test|-T] testmode - do not act, just print "
+ "what would be done\n"
+ "\t<servicename> only import service <servicename>, "
+ "ignore the rest\n"));
+ return -1;
+}
+
static int rpc_conf_showshare_usage(struct net_context *c, int argc,
const char **argv)
{
@@ -239,6 +259,149 @@ error:
return status;;
}
+static NTSTATUS rpc_conf_set_share(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *parent_hnd,
+ struct smbconf_service *service,
+ WERROR *werr)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ NTSTATUS status = NT_STATUS_OK;
+ WERROR result = WERR_OK;
+ WERROR _werr;
+ enum winreg_CreateAction action;
+ uint32_t i, j;
+
+ const char **includes;
+
+ struct winreg_String wkey, wkeyclass;
+ struct policy_handle share_hnd;
+
+ ZERO_STRUCT(share_hnd);
+ ZERO_STRUCT(wkey);
+ ZERO_STRUCT(wkeyclass);
+
+ wkey.name = service->name;
+ wkeyclass.name = "";
+ action = REG_ACTION_NONE;
+
+ status = dcerpc_winreg_CreateKey(b,
+ frame,
+ parent_hnd,
+ wkey,
+ wkeyclass,
+ 0,
+ REG_KEY_ALL,
+ NULL,
+ &share_hnd,
+ &action,
+ &result);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("winreg_CreateKey: Could not create smbconf key\n");
+ goto error;
+ }
+
+ if (!W_ERROR_IS_OK(result)) {
+ d_printf("winreg_CreateKey: Could not create smbconf key\n");
+ goto error;
+ }
+
+ for (i = 0; i < service->num_params; i++) {
+ if (strequal(service->param_names[i], "include") == 0)
+ {
+
+ status = dcerpc_winreg_set_sz(frame, b, &share_hnd,
+ service->param_names[i],
+ service->param_values[i],
+ &result);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr,
+ "ERROR: Share: '%s'\n"
+ "Could not set parameter '%s'"
+ " with value %s\n %s\n",
+ service->name,
+ service->param_names[i],
+ service->param_values[i],
+ nt_errstr(status));
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(result))) {
+ d_fprintf(stderr,
+ "ERROR: Share: '%s'\n"
+ "Could not set parameter '%s'"
+ " with value %s\n %s\n",
+ service->name,
+ service->param_names[i],
+ service->param_values[i],
+ win_errstr(result));
+ goto error;
+ }
+ } else {
+
+ includes = talloc_zero_array(frame,
+ const char *,
+ service->num_params + 1);
+ if (includes == NULL) {
+ result = WERR_NOMEM;
+ d_fprintf(stderr, "ERROR: out of memory\n");
+ goto error;
+ }
+
+ for (j = i; j < service->num_params; j++) {
+
+ includes[j - i] = talloc_strdup(
+ frame,
+ service->param_values[j]);
+
+ if (includes[j-i] == NULL) {
+ result = WERR_NOMEM;
+ d_fprintf(stderr, "ERROR: out of memory\n");
+ goto error;
+ }
+ }
+
+ status = dcerpc_winreg_set_multi_sz(frame, b, &share_hnd,
+ "includes",
+ includes,
+ &result);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, "ERROR: Share: '%s'\n"
+ "Could not set includes\n %s\n",
+ service->name,
+ nt_errstr(status));
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(result))) {
+ d_fprintf(stderr, "ERROR: Share: '%s'\n"
+ "Could not set includes\n %s\n",
+ service->name,
+ win_errstr(result));
+ goto error;
+ }
+
+ i = service->num_params;
+ }
+ }
+
+error:
+ /* in case of error, should it delete the created key? */
+ if (!(W_ERROR_IS_OK(result))) {
+ status = werror_to_ntstatus(result);
+
+ }
+
+ dcerpc_winreg_CloseKey(b, frame, &share_hnd, &_werr);
+
+ TALLOC_FREE(frame);
+ return status;
+
+}
static NTSTATUS rpc_conf_get_share(TALLOC_CTX *mem_ctx,
struct dcerpc_binding_handle *b,
@@ -924,6 +1087,187 @@ error:
return status;
}
+static NTSTATUS rpc_conf_import_internal(struct net_context *c,
+ const struct dom_sid *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ struct rpc_pipe_client *pipe_hnd,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv )
+{
+
+ struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
+
+ struct policy_handle hive_hnd, key_hnd;
+
+ const char *filename = NULL;
+ const char *servicename = NULL;
+ char *conf_source = NULL;
+ TALLOC_CTX *frame;
+ struct smbconf_ctx *txt_ctx;
+ struct smbconf_service *service = NULL;
+ struct smbconf_service **services = NULL;
+ uint32_t num_shares, i;
+ sbcErr err;
+
+ WERROR werr = WERR_OK;
+ NTSTATUS status = NT_STATUS_OK;
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+ frame = talloc_stackframe();
+
+ if (c->display_usage) {
+ rpc_conf_import_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+
+ switch (argc) {
+ case 0:
+ default:
+ rpc_conf_import_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ case 2:
+ servicename = talloc_strdup(frame, argv[1]);
+ if (servicename == NULL) {
+ d_printf(_("error: out of memory!\n"));
+ goto error;
+ }
+ case 1:
+ filename = argv[0];
+ break;
+ }
+
+ DEBUG(3,("rpc_conf_import: reading configuration from file %s.\n",
+ filename));
+
+ conf_source = talloc_asprintf(frame, "file:%s", filename);
+ if (conf_source == NULL) {
+ d_fprintf(stderr, _("error: out of memory!\n"));
+ goto error;
+ }
+
+ err = smbconf_init(frame, &txt_ctx, conf_source);
+ if (!SBC_ERROR_IS_OK(err)) {
+ d_fprintf(stderr, _("error loading file '%s': %s\n"), filename,
+ sbcErrorString(err));
+ goto error;
+ }
+
+ if (c->opt_testmode) {
+ d_printf(_("\nTEST MODE - "
+ "would import the following configuration:\n\n"));
+ }
+
+ if (servicename != NULL) {
+ err = smbconf_get_share(txt_ctx, frame,
+ servicename,
+ &service);
+ if (!SBC_ERROR_IS_OK(err)) {
+ goto error;
+ }
+
+ num_shares = 1;
+
+ } else {
+
+ err = smbconf_get_config(txt_ctx, frame,
+ &num_shares,
+ &services);
+ if (!SBC_ERROR_IS_OK(err)) {
+ goto error;
+ }
+ }
+
+ if (c->opt_testmode) {
+ if (servicename != NULL) {
+ rpc_conf_print_shares(1, service);
+ }
+ for (i = 0; i < num_shares; i++) {
+ rpc_conf_print_shares(1, services[i]);
+ }
+ goto error;
+ }
+
+ status = rpc_conf_drop_internal(c,
+ domain_sid,
+ domain_name,
+ cli,
+ pipe_hnd,
+ frame,
+ 0,
+ NULL );
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ status = rpc_conf_open_conf(frame,
+ b,
+ REG_KEY_READ,
+ &hive_hnd,
+ &key_hnd,
+ &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ goto error;
+ }
+
+ if (servicename != NULL) {
+ status = rpc_conf_set_share(frame,
+ b,
+ &key_hnd,
+ service,
+ &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ goto error;
+ }
+
+ } else {
+
+ for (i = 0; i < num_shares; i++) {
+ status = rpc_conf_set_share(frame,
+ b,
+ &key_hnd,
+ services[i],
+ &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ goto error;
+ }
+
+ }
+ }
+
+error:
+ if (!SBC_ERROR_IS_OK(err)) {
+ d_fprintf(stderr, "ERROR: %s\n", sbcErrorString(err));
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ status = werror_to_ntstatus(werr);
+ }
+ TALLOC_FREE(frame);
+ return status;
+}
+
static NTSTATUS rpc_conf_showshare_internal(struct net_context *c,
const struct dom_sid *domain_sid,
const char *domain_name,
@@ -1918,8 +2262,8 @@ static int rpc_conf_list(struct net_context *c, int argc,
static int rpc_conf_import(struct net_context *c, int argc,
const char **argv)
{
- d_printf("Function not yet implemented\n");
- return 0;
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_import_internal, argc, argv );
}
static int rpc_conf_delshare(struct net_context *c, int argc,
const char **argv)