return -1;
}
+static int rpc_conf_delshare_usage(struct net_context *c, int argc,
+ const char **argv)
+{
+ d_printf("%s\n%s",
+ _("Usage:"),
+ _("net rpc conf delshare <sharename>\n"));
+ return -1;
+}
+
+static int rpc_conf_addshare_usage(struct net_context *c, int argc,
+ const char **argv)
+{
+ d_printf("%s\n%s",
+ _("Usage:"),
+ _(" net rpc conf addshare <sharename> <path> "
+ "[writeable={y|N} [guest_ok={y|N} [<comment>]]]\n"
+ "\t<sharename> the new share name.\n"
+ "\t<path> the path on the filesystem to export.\n"
+ "\twriteable={y|N} set \"writeable to \"yes\" or "
+ "\"no\" (default) on this share.\n"
+ "\tguest_ok={y|N} set \"guest ok\" to \"yes\" or "
+ "\"no\" (default) on this share.\n"
+ "\t<comment> optional comment for the new share.\n"));
+ return -1;
+
+}
static int rpc_conf_showshare_usage(struct net_context *c, int argc,
const char **argv)
{
return -1;
}
+static int rpc_conf_getparm_usage(struct net_context *c, int argc,
+ const char **argv)
+{
+ d_printf("%s\nnet rpc conf getparm <sharename> <parameter>\n",
+ _("Usage:"));
+ 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)
+{
+ d_printf("%s\nnet rpc conf delparm <sharename> <parameter>\n",
+ _("Usage:"));
+ return -1;
+}
+
+static int rpc_conf_getincludes_usage(struct net_context *c, int argc,
+ const char **argv)
+{
+ d_printf("%s\nnet rpc conf getincludes <sharename>\n",
+ _("Usage:"));
+ return -1;
+}
+
+static int rpc_conf_setincludes_usage(struct net_context *c, int argc,
+ const char **argv)
+{
+ d_printf("%s\nnet rpc conf setincludes <sharename> [<filename>]*\n",
+ _("Usage:"));
+ return -1;
+}
+
+static int rpc_conf_delincludes_usage(struct net_context *c, int argc,
+ const char **argv)
+{
+ d_printf("%s\nnet rpc conf delincludes <sharename>\n",
+ _("Usage:"));
+ 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,
+ const char *share_name,
+ const char *value,
+ WERROR *werr)
+{
+
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status = NT_STATUS_OK;
+ WERROR result = WERR_OK;
+ WERROR _werr;
+
+ struct winreg_String keyname, valuename;
+ struct policy_handle child_hnd;
+
+ ZERO_STRUCT(child_hnd);
+ ZERO_STRUCT(keyname);
+ ZERO_STRUCT(valuename);
+
+ keyname.name = share_name;
+ valuename.name = value;
+
+ status = dcerpc_winreg_OpenKey(b, frame, parent_hnd, keyname, 0,
+ REG_KEY_WRITE, &child_hnd, &result);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, _("Failed to open key '%s': %s\n"),
+ keyname.name, nt_errstr(status));
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(result))) {
+ d_fprintf(stderr, _("Failed to open key '%s': %s\n"),
+ keyname.name, win_errstr(result));
+ goto error;
+ }
+
+ status = dcerpc_winreg_DeleteValue(b,
+ frame,
+ &child_hnd,
+ valuename,
+ &result);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, _("Failed to delete value %s\n"),
+ nt_errstr(status));
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(result))) {
+ if (W_ERROR_EQUAL(result, WERR_BADFILE)){
+ result = WERR_OK;
+ goto error;
+ }
+
+ d_fprintf(stderr, _("Failed to delete value %s\n"),
+ win_errstr(result));
+ goto error;
+ }
+
+error:
+ *werr = result;
+
+ dcerpc_winreg_CloseKey(b, frame, &child_hnd, &_werr);
+
+ TALLOC_FREE(frame);
+ return status;;
+
+}
+
static NTSTATUS rpc_conf_get_share(TALLOC_CTX *mem_ctx,
struct dcerpc_binding_handle *b,
struct policy_handle *parent_hnd,
return status;;
}
+static NTSTATUS rpc_conf_delshare_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;
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+
+ if (argc != 1 || c->display_usage) {
+ rpc_conf_delshare_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+
+ status = rpc_conf_open_conf(frame,
+ b,
+ REG_KEY_ALL,
+ &hive_hnd,
+ &key_hnd,
+ &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ goto error;
+ }
+
+ status = dcerpc_winreg_delete_subkeys_recursive(frame,
+ b,
+ &key_hnd,
+ REG_KEY_ALL,
+ argv[0],
+ &werr);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_fprintf(stderr,
+ "winreg_delete_subkeys: Could not delete key %s: %s\n",
+ argv[0], nt_errstr(status));
+ goto error;
+ }
+
+ if (W_ERROR_EQUAL(werr, WERR_BADFILE)){
+ d_fprintf(stderr, _("ERROR: Key does not exist\n"));
+ }
+
+
+ if (!W_ERROR_IS_OK(werr)) {
+ d_fprintf(stderr,
+ "winreg_delete_subkeys: Could not delete key %s: %s\n",
+ argv[0], 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);
+
+ TALLOC_FREE(frame);
+
+ return status;
+}
+
static NTSTATUS rpc_conf_list_internal(struct net_context *c,
const struct dom_sid *domain_sid,
const char *domain_name,
return status;
}
-static int rpc_conf_drop(struct net_context *c, int argc,
- const char **argv)
+static NTSTATUS rpc_conf_addshare_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 )
{
- return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
- rpc_conf_drop_internal, argc, 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;
-static int rpc_conf_showshare(struct net_context *c, int argc,
- const char **argv)
-{
- return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
- rpc_conf_showshare_internal, argc, argv );
-}
+ /* key info */
+ struct policy_handle hive_hnd, key_hnd, share_hnd;
+ char *sharename = NULL;
+ const char *path = NULL;
+ const char *comment = NULL;
+ const char *guest_ok = "no";
+ const char *read_only = "yes";
+ struct winreg_String key, keyclass;
+ enum winreg_CreateAction action = 0;
-static int rpc_conf_listshares(struct net_context *c, int argc,
- const char **argv)
-{
- return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
- rpc_conf_listshares_internal, argc, argv );
-}
-static int rpc_conf_list(struct net_context *c, int argc,
- const char **argv)
-{
- return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
- rpc_conf_list_internal, argc, argv );
-}
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+ ZERO_STRUCT(share_hnd);
-static int rpc_conf_delshare(struct net_context *c, int argc,
- const char **argv)
-{
- d_printf("Function not yet implemented\n");
- return 0;
-};
+ ZERO_STRUCT(key);
+ ZERO_STRUCT(keyclass);
-/* function calls */
-int net_rpc_conf(struct net_context *c, int argc,
- const char **argv)
-{
- struct functable func_table[] = {
- {
- "list",
- rpc_conf_list,
- NET_TRANSPORT_RPC,
- N_("Dump the complete remote configuration in smb.conf like "
- "format."),
- N_("net rpc conf list\n"
- " Dump the complete remote configuration in smb.conf "
- "like format.")
+ if (c->display_usage) {
+ rpc_conf_addshare_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
- },
- {
- "listshares",
- rpc_conf_listshares,
- NET_TRANSPORT_RPC,
- N_("List the remote share names."),
- N_("net rpc conf list\n"
- " List the remote share names.")
+ switch (argc) {
+ case 0:
+ case 1:
+ default:
+ rpc_conf_addshare_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ case 5:
+ comment = argv[4];
+ case 4:
+ if (!strnequal(argv[3], "guest_ok=", 9)) {
+ rpc_conf_addshare_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+ switch (argv[3][9]) {
+ case 'y':
+ case 'Y':
+ guest_ok = "yes";
+ break;
+ case 'n':
+ case 'N':
+ guest_ok = "no";
+ break;
+ default:
+ rpc_conf_addshare_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+ case 3:
+ if (!strnequal(argv[2], "writeable=", 10)) {
+ rpc_conf_addshare_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+ switch (argv[2][10]) {
+ case 'y':
+ case 'Y':
+ read_only = "no";
+ break;
+ case 'n':
+ case 'N':
+ read_only = "yes";
+ break;
+ default:
+ rpc_conf_addshare_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+ case 2:
+ path = argv[1];
+ sharename = talloc_strdup(frame, argv[0]);
+ if (sharename == NULL) {
+ d_printf(_("error: out of memory!\n"));
+ goto error;
+ }
- },
- {
- "drop",
- rpc_conf_drop,
- NET_TRANSPORT_RPC,
- N_("Delete the complete remote configuration."),
- N_("net rpc conf drop\n"
- " Delete the complete remote configuration.")
+ break;
+ }
- },
- {
- "showshare",
- rpc_conf_showshare,
- NET_TRANSPORT_RPC,
- N_("Show the definition of a remote share."),
- N_("net rpc conf showshare\n"
- " Show the definition of a remote share.")
+ 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 setincludes:"
+ "createkey created %s\n", argv[0]));
+ break;
+ case REG_OPENED_EXISTING_KEY:
+ d_fprintf(stderr, _("ERROR: Share '%s' already exists\n"), argv[0]);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+
+ /* set the path parameter */
+ status = dcerpc_winreg_set_sz(frame, b, &share_hnd,
+ "path", path, &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, "ERROR: Could not set parameter '%s'"
+ " with value %s\n %s\n",
+ "path", path, 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",
+ "path", path, win_errstr(werr));
+ goto error;
+ }
+
+ /* set the writeable parameter */
+ status = dcerpc_winreg_set_sz(frame, b, &share_hnd,
+ "read only", read_only, &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, "ERROR: Could not set parameter '%s'"
+ " with value %s\n %s\n",
+ "read only", read_only, 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",
+ "read only", read_only, win_errstr(werr));
+ goto error;
+ }
+
+ /* set the guest ok parameter */
+ status = dcerpc_winreg_set_sz(frame, b, &share_hnd,
+ "guest ok", guest_ok, &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, "ERROR: Could not set parameter '%s'"
+ " with value %s\n %s\n",
+ "guest ok", guest_ok, 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",
+ "guest ok", guest_ok, win_errstr(werr));
+ goto error;
+ }
+
+ if (argc == 5) {
+ /* set the comment parameter */
+ status = dcerpc_winreg_set_sz(frame, b, &share_hnd,
+ "comment", comment, &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, "ERROR: Could not set parameter '%s'"
+ " with value %s\n %s\n",
+ "comment", comment, 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",
+ "comment", comment, 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_getparm_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;
+ struct smbconf_service *service = NULL;
+
+ bool param_is_set = false;
+ uint32_t param_count;
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+
+ if (argc != 2 || c->display_usage) {
+ rpc_conf_getparm_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;
+ }
+
+
+ service = talloc(frame, struct smbconf_service);
+
+ status = rpc_conf_get_share(frame,
+ b,
+ &key_hnd,
+ argv[0],
+ service,
+ &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
+ d_fprintf(stderr, _("ERROR: Share %s does not exist\n"),
+ argv[0]);
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ goto error;
+ }
+
+ for (param_count = 0;
+ param_count < service->num_params;
+ param_count++)
+ {
+ /* should includes also be printed? */
+ if (strcmp(service->param_names[param_count], argv[1]) == 0) {
+ d_printf(_("%s\n"),
+ service->param_values[param_count]);
+ param_is_set = true;
+ }
+ }
+
+ if (!param_is_set) {
+ d_fprintf(stderr, _("ERROR: Given parameter '%s' has not been set\n"),
+ argv[1]);
+ werr = WERR_BADFILE;
+ 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);
+
+ TALLOC_FREE(frame);
+ return status;
+
+}
+
+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,
+ 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;
+
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+
+ if (argc != 2 || c->display_usage) {
+ rpc_conf_delparm_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;
+ }
+
+ status = rpc_conf_del_value(frame,
+ b,
+ &key_hnd,
+ argv[0],
+ argv[1],
+ &werr);
+
+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);
+
+ TALLOC_FREE(frame);
+ return status;
+
+}
+
+static NTSTATUS rpc_conf_getincludes_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;
+ struct smbconf_service *service = NULL;
+
+ uint32_t param_count;
+
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+
+ if (argc != 1 || c->display_usage) {
+ rpc_conf_getincludes_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;
+ }
+
+ service = talloc(frame, struct smbconf_service);
+
+ status = rpc_conf_get_share(frame,
+ b,
+ &key_hnd,
+ argv[0],
+ service,
+ &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ goto error;
+ }
+
+ for (param_count = 0;
+ param_count < service->num_params;
+ param_count++)
+ {
+ if (strcmp(service->param_names[param_count], "include") == 0) {
+ d_printf(_("%s = %s\n"),
+ service->param_names[param_count],
+ service->param_values[param_count]);
+ }
+ }
+
+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);
+
+ TALLOC_FREE(frame);
+ return status;
+
+}
+
+static NTSTATUS rpc_conf_setincludes_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 < 1 || c->display_usage) {
+ rpc_conf_setincludes_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:
+ /* Is there any other way to treat this? */
+ 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 setincludes:"
+ "createkey created %s\n", argv[0]));
+ break;
+ case REG_OPENED_EXISTING_KEY:
+ DEBUG(5, ("net rpc conf setincludes:"
+ "createkey opened existing %s\n", argv[0]));
+
+ /* delete posibly existing value */
+ status = rpc_conf_del_value(frame,
+ b,
+ &key_hnd,
+ argv[0],
+ "includes",
+ &werr);
+
+ if (!(NT_STATUS_IS_OK(status))) {
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ goto error;
+ }
+ break;
+ }
+
+ /* set the 'includes' values */
+ status = dcerpc_winreg_set_multi_sz(frame, b, &share_hnd,
+ "includes", argv + 1, &werr);
+ if (!(NT_STATUS_IS_OK(status))) {
+ d_fprintf(stderr, "ERROR: Could not set includes\n %s\n",
+ nt_errstr(status));
+ goto error;
+ }
+
+ if (!(W_ERROR_IS_OK(werr))) {
+ d_fprintf(stderr, "ERROR: Could not set includes\n %s\n",
+ 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_delincludes_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;
+
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+
+ if (argc != 1 || c->display_usage) {
+ rpc_conf_delincludes_usage(c, argc, argv);
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto error;
+ }
+/* try REG_KEY_WRITE */
+ 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;
+ }
+
+ status = rpc_conf_del_value(frame,
+ b,
+ &key_hnd,
+ argv[0],
+ "includes",
+ &werr);
+
+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);
+
+ TALLOC_FREE(frame);
+ return status;
+
+}
+
+static int rpc_conf_drop(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_drop_internal, argc, argv );
+
+}
+
+static int rpc_conf_showshare(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_showshare_internal, argc, argv );
+}
+
+static int rpc_conf_addshare(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_addshare_internal, argc, argv );
+}
+
+static int rpc_conf_listshares(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_listshares_internal, argc, argv );
+}
+
+static int rpc_conf_list(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_list_internal, argc, argv );
+}
+
+static int rpc_conf_delshare(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_delshare_internal, argc, argv );
+}
+
+static int rpc_conf_getparm(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_getparm_internal, argc, argv );
+}
+
+static int rpc_conf_setparm(struct net_context *c, int argc,
+ const char **argv)
+{
+ 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)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_delparm_internal, argc, argv );
+}
+
+static int rpc_conf_getincludes(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_getincludes_internal, argc, argv );
+}
+
+static int rpc_conf_setincludes(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_setincludes_internal, argc, argv );
+}
+
+static int rpc_conf_delincludes(struct net_context *c, int argc,
+ const char **argv)
+{
+ return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
+ rpc_conf_delincludes_internal, argc, argv );
+}
+
+/* function calls */
+int net_rpc_conf(struct net_context *c, int argc,
+ const char **argv)
+{
+ struct functable func_table[] = {
+ {
+ "list",
+ rpc_conf_list,
+ NET_TRANSPORT_RPC,
+ N_("Dump the complete remote configuration in smb.conf like "
+ "format."),
+ N_("net rpc conf list\n"
+ " Dump the complete remote configuration in smb.conf "
+ "like format.")
+
+ },
+ {
+ "listshares",
+ rpc_conf_listshares,
+ NET_TRANSPORT_RPC,
+ N_("List the remote share names."),
+ N_("net rpc conf list\n"
+ " List the remote share names.")
+
+ },
+ {
+ "drop",
+ rpc_conf_drop,
+ NET_TRANSPORT_RPC,
+ N_("Delete the complete remote configuration."),
+ N_("net rpc conf drop\n"
+ " Delete the complete remote configuration.")
+
+ },
+ {
+ "showshare",
+ rpc_conf_showshare,
+ NET_TRANSPORT_RPC,
+ N_("Show the definition of a remote share."),
+ N_("net rpc conf showshare\n"
+ " Show the definition of a remote share.")
+
+ },
+ {
+ "addshare",
+ rpc_conf_addshare,
+ NET_TRANSPORT_RPC,
+ N_("Create a new remote share."),
+ N_("net rpc conf addshare\n"
+ " Create a new remote share.")
},
{
"delshare",
N_("net rpc conf delshare\n"
" Delete a remote share.")
},
+ {
+ "getparm",
+ rpc_conf_getparm,
+ NET_TRANSPORT_RPC,
+ N_("Retrieve the value of a parameter."),
+ N_("net rpc conf getparm\n"
+ " Retrieve the value of a parameter.")
+ },
+ {
+ "setparm",
+ rpc_conf_setparm,
+ NET_TRANSPORT_RPC,
+ N_("Store a parameter."),
+ N_("net rpc conf setparm\n"
+ " Store a parameter.")
+ },
+ {
+ "delparm",
+ rpc_conf_delparm,
+ NET_TRANSPORT_RPC,
+ N_("Delete a parameter."),
+ N_("net rpc conf delparm\n"
+ " Delete a parameter.")
+ },
+ {
+ "getincludes",
+ rpc_conf_getincludes,
+ NET_TRANSPORT_RPC,
+ N_("Show the includes of a share definition."),
+ N_("net rpc conf getincludes\n"
+ " Show the includes of a share definition.")
+ },
+ {
+ "setincludes",
+ rpc_conf_setincludes,
+ NET_TRANSPORT_RPC,
+ N_("Set includes for a share."),
+ N_("net rpc conf setincludes\n"
+ " Set includes for a share.")
+ },
+ {
+ "delincludes",
+ rpc_conf_delincludes,
+ NET_TRANSPORT_RPC,
+ N_("Delete includes from a share definition."),
+ N_("net rpc conf delincludes\n"
+ " Delete includes from a share definition.")
+ },
{NULL, NULL, 0, NULL, NULL}
};