diff options
-rw-r--r-- | source3/utils/net_rpc_conf.c | 203 |
1 files changed, 201 insertions, 2 deletions
diff --git a/source3/utils/net_rpc_conf.c b/source3/utils/net_rpc_conf.c index 7fffbe601b..bfcd9959df 100644 --- a/source3/utils/net_rpc_conf.c +++ b/source3/utils/net_rpc_conf.c @@ -91,6 +91,15 @@ static int rpc_conf_getparm_usage(struct net_context *c, int argc, return -1; } +static int rpc_conf_setparm_usage(struct net_context *c, int argc, + const char **argv) +{ + d_printf("%s\n%s", + _("Usage:"), + _(" net rpc conf setparm <section> <param> <value>\n")); + return -1; +} + static int rpc_conf_delparm_usage(struct net_context *c, int argc, const char **argv) { @@ -115,6 +124,26 @@ static int rpc_conf_delincludes_usage(struct net_context *c, int argc, return -1; } +static bool rpc_conf_reg_valname_forbidden(const char * valname) +{ + const char *forbidden_valnames[] = { + "lock directory", + "lock dir", + "config backend", + "include", + "includes", /* this has a special meaning internally */ + NULL + }; + const char **forbidden = NULL; + + for (forbidden = forbidden_valnames; *forbidden != NULL; forbidden++) { + if (strwicmp(valname, *forbidden) == 0) { + return true; + } + } + return false; + +} static NTSTATUS rpc_conf_del_value(TALLOC_CTX *mem_ctx, struct dcerpc_binding_handle *b, struct policy_handle *parent_hnd, @@ -1066,6 +1095,176 @@ error: } +static NTSTATUS rpc_conf_setparm_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 ) +{ + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status = NT_STATUS_OK; + WERROR werr = WERR_OK; + WERROR _werr; + + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; + + /* key info */ + struct policy_handle hive_hnd, key_hnd, share_hnd; + + struct winreg_String key, keyclass; + enum winreg_CreateAction action = 0; + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + ZERO_STRUCT(share_hnd); + + ZERO_STRUCT(key); + ZERO_STRUCT(keyclass); + + if (argc != 3 || c->display_usage) { + rpc_conf_setparm_usage(c, argc, argv); + status = NT_STATUS_INVALID_PARAMETER; + 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; + } + + key.name = argv[0]; + keyclass.name = ""; + + status = dcerpc_winreg_CreateKey(b, frame, &key_hnd, key, keyclass, + 0, REG_KEY_READ, NULL, &share_hnd, + &action, &werr); + + if (!(NT_STATUS_IS_OK(status))) { + d_fprintf(stderr, _("ERROR: Could not create share key '%s'\n%s\n"), + argv[0], nt_errstr(status)); + goto error; + } + + if (!W_ERROR_IS_OK(werr)) { + d_fprintf(stderr, _("ERROR: Could not create share key '%s'\n%s\n"), + argv[0], win_errstr(werr)); + goto error; + } + + switch (action) { + case REG_ACTION_NONE: + werr = WERR_CREATE_FAILED; + d_fprintf(stderr, _("ERROR: Could not create share key '%s'\n%s\n"), + argv[0], win_errstr(werr)); + goto error; + case REG_CREATED_NEW_KEY: + DEBUG(5, ("net rpc conf setparm:" + "createkey created %s\n", argv[0])); + break; + case REG_OPENED_EXISTING_KEY: + DEBUG(5, ("net rpc conf setparm:" + "createkey opened existing %s\n", argv[0])); + + /* delete posibly existing value */ + status = rpc_conf_del_value(frame, + b, + &key_hnd, + argv[0], + argv[1], + &werr); + + if (!(NT_STATUS_IS_OK(status))) { + goto error; + } + + if (!(W_ERROR_IS_OK(werr))) { + goto error; + } + + break; + } + + + const char *canon_valname; + const char *canon_valstr; + /* check if parameter is valid for writing */ + if (!lp_canonicalize_parameter_with_value(argv[1], argv[2], + &canon_valname, + &canon_valstr)) + { + if (canon_valname == NULL) { + d_fprintf(stderr, "invalid parameter '%s' given\n", + argv[1]); + } else { + d_fprintf(stderr, "invalid value '%s' given for " + "parameter '%s'\n", argv[1], argv[2]); + } + werr = WERR_INVALID_PARAM; + goto error; + } + + if (rpc_conf_reg_valname_forbidden(canon_valname)) { + d_fprintf(stderr, "Parameter '%s' not allowed in registry.\n", + canon_valname); + werr = WERR_INVALID_PARAM; + goto error; + } + + if (!strequal(argv[0], "global") && + lp_parameter_is_global(argv[1])) + { + d_fprintf(stderr, "Global parameter '%s' not allowed in " + "service definition ('%s').\n", canon_valname, + argv[0]); + werr = WERR_INVALID_PARAM; + goto error; + } + + /* set the parameter */ + status = dcerpc_winreg_set_sz(frame, b, &share_hnd, + argv[1], argv[2], &werr); + + if (!(NT_STATUS_IS_OK(status))) { + d_fprintf(stderr, "ERROR: Could not set parameter '%s'" + " with value %s\n %s\n", + argv[1], argv[2], nt_errstr(status)); + goto error; + } + + if (!(W_ERROR_IS_OK(werr))) { + d_fprintf(stderr, "ERROR: Could not set parameter '%s'" + " with value %s\n %s\n", + argv[1], argv[2], win_errstr(werr)); + goto error; + } + +error: + + if (!(W_ERROR_IS_OK(werr))) { + status = werror_to_ntstatus(werr); + } + + dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr); + dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr); + dcerpc_winreg_CloseKey(b, frame, &share_hnd, &_werr); + + TALLOC_FREE(frame); + return status; +} + static NTSTATUS rpc_conf_delparm_internal(struct net_context *c, const struct dom_sid *domain_sid, const char *domain_name, @@ -1334,8 +1533,8 @@ static int rpc_conf_getparm(struct net_context *c, int argc, static int rpc_conf_setparm(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_setparm_internal, argc, argv ); } static int rpc_conf_delparm(struct net_context *c, int argc, const char **argv) |