diff options
author | Vicentiu Ciorbaru <cvicentiu@gmail.com> | 2011-07-26 00:11:15 +0300 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2011-08-22 13:59:24 +0200 |
commit | 08be91b0119fbc5fff8ad80b1f8dedc79d467dda (patch) | |
tree | 9d967380f15a5dc29ed2c251928274a50a79ce73 | |
parent | 283da12a73ea3edc49a63f7375bc2c64ed36e2b1 (diff) | |
download | samba-08be91b0119fbc5fff8ad80b1f8dedc79d467dda.tar.gz samba-08be91b0119fbc5fff8ad80b1f8dedc79d467dda.tar.bz2 samba-08be91b0119fbc5fff8ad80b1f8dedc79d467dda.zip |
s3-net: Added the net rpc conf list command.
The command make use of the smbconf_service struct,
via the function rpc_conf_get_share(). This allows for
further expansion with the use of smbconf.
Signed-off-by: Michael Adam <obnox@samba.org>
-rw-r--r-- | source3/utils/net_rpc_conf.c | 383 |
1 files changed, 382 insertions, 1 deletions
diff --git a/source3/utils/net_rpc_conf.c b/source3/utils/net_rpc_conf.c index e27201904a..fe2ca4410d 100644 --- a/source3/utils/net_rpc_conf.c +++ b/source3/utils/net_rpc_conf.c @@ -36,11 +36,392 @@ #include "rpc_client/cli_winreg.h" #include "../lib/smbconf/smbconf.h" +/* internal functions */ +/********************************************************** + * + * usage functions + * + **********************************************************/ +const char confpath[100] = "Software\\Samba\\smbconf"; + +static int rpc_conf_list_usage(struct net_context *c, int argc, + const char **argv) +{ + d_printf("%s net rpc conf list\n", _("Usage:")); + return -1; +} + +static NTSTATUS rpc_conf_get_share(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *b, + struct policy_handle *parent_hnd, + const char *share_name, + struct smbconf_service *share, + WERROR *werr) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + NTSTATUS status = NT_STATUS_OK; + WERROR result = WERR_OK; + WERROR _werr; + struct policy_handle child_hnd; + int32_t includes_cnt, includes_idx = -1; + uint32_t num_vals, i, param_cnt = 0; + const char **val_names; + enum winreg_Type *types; + DATA_BLOB *data; + struct winreg_String key; + const char **multi_s = NULL; + const char *s = NULL; + struct smbconf_service tmp_share; + + ZERO_STRUCT(tmp_share); + + key.name = share_name; + status = dcerpc_winreg_OpenKey(b, frame, parent_hnd, key, 0, + REG_KEY_READ, &child_hnd, &result); + + if (!(NT_STATUS_IS_OK(status))) { + d_fprintf(stderr, _("Failed to open subkey: %s\n"), + nt_errstr(status)); + goto error; + } + if (!(W_ERROR_IS_OK(result))) { + d_fprintf(stderr, _("Failed to open subkey: %s\n"), + win_errstr(result)); + goto error; + } + /* get all the info from the share key */ + status = dcerpc_winreg_enumvals(frame, + b, + &child_hnd, + &num_vals, + &val_names, + &types, + &data, + &result); + + if (!(NT_STATUS_IS_OK(status))) { + d_fprintf(stderr, _("Failed to enumerate values: %s\n"), + nt_errstr(status)); + goto error; + } + if (!(W_ERROR_IS_OK(result))) { + d_fprintf(stderr, _("Failed to enumerate values: %s\n"), + win_errstr(result)); + goto error; + } + /* check for includes */ + for (i = 0; i < num_vals; i++) { + if (strcmp(val_names[i], "includes") == 0){ + if (!pull_reg_multi_sz(frame, + &data[i], + &multi_s)) + { + result = WERR_NOMEM; + d_fprintf(stderr, + _("Failed to enumerate values: %s\n"), + win_errstr(result)); + goto error; + } + includes_idx = i; + } + } + /* count the number of includes */ + includes_cnt = 0; + if (includes_idx != -1) { + for (includes_cnt = 0; + multi_s[includes_cnt] != NULL; + includes_cnt ++); + } + /* place the name of the share in the smbconf_service struct */ + tmp_share.name = talloc_strdup(frame, share_name); + if (tmp_share.name == NULL) { + result = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create share: %s\n"), + win_errstr(result)); + goto error; + } + /* place the number of parameters in the smbconf_service struct */ + tmp_share.num_params = num_vals; + if (includes_idx != -1) { + tmp_share.num_params = num_vals + includes_cnt - 1; + } + /* allocate memory for the param_names and param_values lists */ + tmp_share.param_names = talloc_zero_array(frame, char *, tmp_share.num_params); + if (tmp_share.param_names == NULL) { + result = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create share: %s\n"), + win_errstr(result)); + goto error; + } + tmp_share.param_values = talloc_zero_array(frame, char *, tmp_share.num_params); + if (tmp_share.param_values == NULL) { + result = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create share: %s\n"), + win_errstr(result)); + goto error; + } + /* place all params except includes */ + for (i = 0; i < num_vals; i++) { + if (strcmp(val_names[i], "includes") != 0) { + if (!pull_reg_sz(frame, &data[i], &s)) { + result = WERR_NOMEM; + d_fprintf(stderr, + _("Failed to enumerate values: %s\n"), + win_errstr(result)); + goto error; + } + /* place param_names */ + tmp_share.param_names[param_cnt] = talloc_strdup(frame, val_names[i]); + if (tmp_share.param_names[param_cnt] == NULL) { + result = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create share: %s\n"), + win_errstr(result)); + goto error; + } + + /* place param_values */ + tmp_share.param_values[param_cnt++] = talloc_strdup(frame, s); + if (tmp_share.param_values[param_cnt - 1] == NULL) { + result = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create share: %s\n"), + win_errstr(result)); + goto error; + } + } + } + /* place the includes last */ + for (i = 0; i < includes_cnt; i++) { + tmp_share.param_names[param_cnt] = talloc_strdup(frame, "include"); + if (tmp_share.param_names[param_cnt] == NULL) { + result = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create share: %s\n"), + win_errstr(result)); + goto error; + } + + tmp_share.param_values[param_cnt++] = talloc_strdup(frame, multi_s[i]); + if (tmp_share.param_values[param_cnt - 1] == NULL) { + result = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create share: %s\n"), + win_errstr(result)); + goto error; + } + } + + /* move everything to the main memory ctx */ + for (i = 0; i < param_cnt; i++) { + tmp_share.param_names[i] = talloc_move(mem_ctx, &tmp_share.param_names[i]); + tmp_share.param_values[i] = talloc_move(mem_ctx, &tmp_share.param_values[i]); + } + + tmp_share.name = talloc_move(mem_ctx, &tmp_share.name); + tmp_share.param_names = talloc_move(mem_ctx, &tmp_share.param_names); + tmp_share.param_values = talloc_move(mem_ctx, &tmp_share.param_values); + /* out parameter */ + *share = tmp_share; +error: + /* close child */ + dcerpc_winreg_CloseKey(b, frame, &child_hnd, &_werr); + *werr = result; + TALLOC_FREE(frame); + return status; +} + +static int rpc_conf_print_shares(uint32_t num_shares, + struct smbconf_service *shares) +{ + + uint32_t share_count, param_count; + const char *indent = "\t"; + + if (num_shares == 0) { + return 0; + } + + for (share_count = 0; share_count < num_shares; share_count++) { + d_printf("\n"); + if (shares[share_count].name != NULL) { + d_printf("[%s]\n", shares[share_count].name); + } + + for (param_count = 0; + param_count < shares[share_count].num_params; + param_count++) + { + d_printf("%s%s = %s\n", + indent, + shares[share_count].param_names[param_count], + shares[share_count].param_values[param_count]); + } + } + d_printf("\n"); + + return 0; + +} +static NTSTATUS rpc_conf_list_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 winreg_String key; + + struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; + + /* key info */ + struct policy_handle hive_hnd, key_hnd; + uint32_t num_subkeys; + uint32_t i; + struct smbconf_service *shares; + const char **subkeys = NULL; + + + ZERO_STRUCT(key); + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + + if (argc != 0 || c->display_usage) { + rpc_conf_list_usage(c, argc, argv); + goto error; + } + + status = dcerpc_winreg_OpenHKLM(b, frame, NULL, + REG_KEY_READ, &hive_hnd, &werr); + + if (!(NT_STATUS_IS_OK(status))) { + d_fprintf(stderr, _("Failed to open hive: %s\n"), + nt_errstr(status)); + goto error; + } + if (!W_ERROR_IS_OK(werr)) { + d_fprintf(stderr, _("Failed to open hive: %s\n"), + win_errstr(werr)); + goto error; + } + + key.name = confpath; + status = dcerpc_winreg_OpenKey(b, frame, &hive_hnd, key, 0, + REG_KEY_READ, &key_hnd, &werr); + + if (!(NT_STATUS_IS_OK(status))) { + d_fprintf(stderr, _("Failed to open smbconf key: %s\n"), + nt_errstr(status)); + dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr); + goto error; + } + if (!(W_ERROR_IS_OK(werr))) { + d_fprintf(stderr, _("Failed to open smbconf key: %s\n"), + win_errstr(werr)); + dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr); + goto error; + } + + status = dcerpc_winreg_enum_keys(frame, + b, + &key_hnd, + &num_subkeys, + &subkeys, + &werr); + + if (!(NT_STATUS_IS_OK(status))) { + d_fprintf(stderr, _("Failed to enumerate keys: %s\n"), + nt_errstr(status)); + goto error; + } + + if (!(W_ERROR_IS_OK(werr))) { + d_fprintf(stderr, _("Failed to enumerate keys: %s\n"), + win_errstr(werr)); + goto error; + } + + if (num_subkeys == 0) { + dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr); + dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr); + TALLOC_FREE(frame); + return NT_STATUS_OK; + } + + /* get info from each subkey */ + shares = talloc_zero_array(frame, struct smbconf_service, num_subkeys); + if (shares == NULL) { + werr = WERR_NOMEM; + d_fprintf(stderr, _("Failed to create shares: %s\n"), + win_errstr(werr)); + goto error; + + } + + for (i = 0; i < num_subkeys; i++) { + /* get each share and place it in the shares array */ + status = rpc_conf_get_share(frame, + b, + &key_hnd, + subkeys[i], + &shares[i], + &werr); + if (!(NT_STATUS_IS_OK(status))) { + goto error; + } + if (!(W_ERROR_IS_OK(werr))) { + goto error; + } + + } + /* print the shares array */ + rpc_conf_print_shares(num_subkeys, shares); + +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_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 ); +} /* function calls */ int net_rpc_conf(struct net_context *c, int argc, const char **argv) { - return 0; + 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.") + + }, + {NULL, NULL, 0, NULL, NULL} + }; + + return net_run_function(c, argc, argv, "net rpc conf", func_table); } |