2 * Samba Unix/Linux SMB client library
3 * Distributed SMB/CIFS Server Management Utility
4 * Local configuration interface
5 * Copyright (C) Vicentiu Ciorbaru 2011
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 * This is an interface to Samba's configuration.
24 * This tool supports local as well as remote interaction via rpc
25 * with the configuration stored in the registry.
30 #include "utils/net.h"
31 #include "rpc_client/cli_pipe.h"
32 #include "../librpc/gen_ndr/ndr_samr_c.h"
33 #include "rpc_client/init_samr.h"
34 #include "../librpc/gen_ndr/ndr_winreg_c.h"
35 #include "../libcli/registry/util_reg.h"
36 #include "rpc_client/cli_winreg.h"
37 #include "../lib/smbconf/smbconf.h"
39 /* internal functions */
40 /**********************************************************
44 **********************************************************/
45 const char confpath[100] = "Software\\Samba\\smbconf";
47 static int rpc_conf_list_usage(struct net_context *c, int argc,
50 d_printf("%s net rpc conf list\n", _("Usage:"));
54 static int rpc_conf_listshares_usage(struct net_context *c, int argc,
57 d_printf("%s net rpc conf listshares\n", _("Usage:"));
61 static int rpc_conf_showshare_usage(struct net_context *c, int argc,
66 _("net rpc conf showshare <sharename>\n"));
70 static NTSTATUS rpc_conf_get_share(TALLOC_CTX *mem_ctx,
71 struct dcerpc_binding_handle *b,
72 struct policy_handle *parent_hnd,
73 const char *share_name,
74 struct smbconf_service *share,
77 TALLOC_CTX *frame = talloc_stackframe();
79 NTSTATUS status = NT_STATUS_OK;
80 WERROR result = WERR_OK;
82 struct policy_handle child_hnd;
83 int32_t includes_cnt, includes_idx = -1;
84 uint32_t num_vals, i, param_cnt = 0;
85 const char **val_names;
86 enum winreg_Type *types;
88 struct winreg_String key;
89 const char **multi_s = NULL;
91 struct smbconf_service tmp_share;
93 ZERO_STRUCT(tmp_share);
95 key.name = share_name;
96 status = dcerpc_winreg_OpenKey(b, frame, parent_hnd, key, 0,
97 REG_KEY_READ, &child_hnd, &result);
99 if (!(NT_STATUS_IS_OK(status))) {
100 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
104 if (!(W_ERROR_IS_OK(result))) {
105 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
109 /* get all the info from the share key */
110 status = dcerpc_winreg_enumvals(frame,
119 if (!(NT_STATUS_IS_OK(status))) {
120 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
124 if (!(W_ERROR_IS_OK(result))) {
125 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
129 /* check for includes */
130 for (i = 0; i < num_vals; i++) {
131 if (strcmp(val_names[i], "includes") == 0){
132 if (!pull_reg_multi_sz(frame,
138 _("Failed to enumerate values: %s\n"),
145 /* count the number of includes */
147 if (includes_idx != -1) {
148 for (includes_cnt = 0;
149 multi_s[includes_cnt] != NULL;
152 /* place the name of the share in the smbconf_service struct */
153 tmp_share.name = talloc_strdup(frame, share_name);
154 if (tmp_share.name == NULL) {
156 d_fprintf(stderr, _("Failed to create share: %s\n"),
160 /* place the number of parameters in the smbconf_service struct */
161 tmp_share.num_params = num_vals;
162 if (includes_idx != -1) {
163 tmp_share.num_params = num_vals + includes_cnt - 1;
165 /* allocate memory for the param_names and param_values lists */
166 tmp_share.param_names = talloc_zero_array(frame, char *, tmp_share.num_params);
167 if (tmp_share.param_names == NULL) {
169 d_fprintf(stderr, _("Failed to create share: %s\n"),
173 tmp_share.param_values = talloc_zero_array(frame, char *, tmp_share.num_params);
174 if (tmp_share.param_values == NULL) {
176 d_fprintf(stderr, _("Failed to create share: %s\n"),
180 /* place all params except includes */
181 for (i = 0; i < num_vals; i++) {
182 if (strcmp(val_names[i], "includes") != 0) {
183 if (!pull_reg_sz(frame, &data[i], &s)) {
186 _("Failed to enumerate values: %s\n"),
190 /* place param_names */
191 tmp_share.param_names[param_cnt] = talloc_strdup(frame, val_names[i]);
192 if (tmp_share.param_names[param_cnt] == NULL) {
194 d_fprintf(stderr, _("Failed to create share: %s\n"),
199 /* place param_values */
200 tmp_share.param_values[param_cnt++] = talloc_strdup(frame, s);
201 if (tmp_share.param_values[param_cnt - 1] == NULL) {
203 d_fprintf(stderr, _("Failed to create share: %s\n"),
209 /* place the includes last */
210 for (i = 0; i < includes_cnt; i++) {
211 tmp_share.param_names[param_cnt] = talloc_strdup(frame, "include");
212 if (tmp_share.param_names[param_cnt] == NULL) {
214 d_fprintf(stderr, _("Failed to create share: %s\n"),
219 tmp_share.param_values[param_cnt++] = talloc_strdup(frame, multi_s[i]);
220 if (tmp_share.param_values[param_cnt - 1] == NULL) {
222 d_fprintf(stderr, _("Failed to create share: %s\n"),
228 /* move everything to the main memory ctx */
229 for (i = 0; i < param_cnt; i++) {
230 tmp_share.param_names[i] = talloc_move(mem_ctx, &tmp_share.param_names[i]);
231 tmp_share.param_values[i] = talloc_move(mem_ctx, &tmp_share.param_values[i]);
234 tmp_share.name = talloc_move(mem_ctx, &tmp_share.name);
235 tmp_share.param_names = talloc_move(mem_ctx, &tmp_share.param_names);
236 tmp_share.param_values = talloc_move(mem_ctx, &tmp_share.param_values);
241 dcerpc_winreg_CloseKey(b, frame, &child_hnd, &_werr);
247 static int rpc_conf_print_shares(uint32_t num_shares,
248 struct smbconf_service *shares)
251 uint32_t share_count, param_count;
252 const char *indent = "\t";
254 if (num_shares == 0) {
258 for (share_count = 0; share_count < num_shares; share_count++) {
260 if (shares[share_count].name != NULL) {
261 d_printf("[%s]\n", shares[share_count].name);
264 for (param_count = 0;
265 param_count < shares[share_count].num_params;
268 d_printf("%s%s = %s\n",
270 shares[share_count].param_names[param_count],
271 shares[share_count].param_values[param_count]);
279 static NTSTATUS rpc_conf_open_conf(TALLOC_CTX *mem_ctx,
280 struct dcerpc_binding_handle *b,
281 uint32_t access_mask,
282 struct policy_handle *hive_hnd,
283 struct policy_handle *key_hnd,
286 TALLOC_CTX *frame = talloc_stackframe();
287 NTSTATUS status = NT_STATUS_OK;
288 WERROR result = WERR_OK;
290 struct policy_handle tmp_hive_hnd, tmp_key_hnd;
291 struct winreg_String key;
295 status = dcerpc_winreg_OpenHKLM(b, frame, NULL,
296 access_mask, &tmp_hive_hnd, &result);
299 * print no error messages if it is a read only open
300 * and key does not exist
301 * error still gets returned
304 if (access_mask == REG_KEY_READ &&
305 W_ERROR_EQUAL(result, WERR_BADFILE))
310 if (!(NT_STATUS_IS_OK(status))) {
311 d_fprintf(stderr, _("Failed to open hive: %s\n"),
315 if (!W_ERROR_IS_OK(result)) {
316 d_fprintf(stderr, _("Failed to open hive: %s\n"),
322 status = dcerpc_winreg_OpenKey(b, frame, &tmp_hive_hnd, key, 0,
323 access_mask, &tmp_key_hnd, &result);
326 * print no error messages if it is a read only open
327 * and key does not exist
328 * error still gets returned
331 if (access_mask == REG_KEY_READ &&
332 W_ERROR_EQUAL(result, WERR_BADFILE))
337 if (!(NT_STATUS_IS_OK(status))) {
338 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
340 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
343 if (!(W_ERROR_IS_OK(result))) {
344 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
346 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
350 *hive_hnd = tmp_hive_hnd;
351 *key_hnd = tmp_key_hnd;
360 static NTSTATUS rpc_conf_listshares_internal(struct net_context *c,
361 const struct dom_sid *domain_sid,
362 const char *domain_name,
363 struct cli_state *cli,
364 struct rpc_pipe_client *pipe_hnd,
370 TALLOC_CTX *frame = talloc_stackframe();
371 NTSTATUS status = NT_STATUS_OK;
372 WERROR werr = WERR_OK;
375 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
378 struct policy_handle hive_hnd, key_hnd;
379 uint32_t num_subkeys;
381 const char **subkeys = NULL;
384 ZERO_STRUCT(hive_hnd);
385 ZERO_STRUCT(key_hnd);
388 if (argc != 0 || c->display_usage) {
389 rpc_conf_listshares_usage(c, argc, argv);
390 status = NT_STATUS_INVALID_PARAMETER;
395 status = rpc_conf_open_conf(frame,
402 if (!(NT_STATUS_IS_OK(status))) {
406 if (!(W_ERROR_IS_OK(werr))) {
410 status = dcerpc_winreg_enum_keys(frame,
417 if (!(NT_STATUS_IS_OK(status))) {
418 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
423 if (!(W_ERROR_IS_OK(werr))) {
424 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
429 for (i = 0; i < num_subkeys; i++) {
430 d_printf("%s\n", subkeys[i]);
434 if (!(W_ERROR_IS_OK(werr))) {
435 status = werror_to_ntstatus(werr);
438 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
439 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
445 static NTSTATUS rpc_conf_list_internal(struct net_context *c,
446 const struct dom_sid *domain_sid,
447 const char *domain_name,
448 struct cli_state *cli,
449 struct rpc_pipe_client *pipe_hnd,
455 TALLOC_CTX *frame = talloc_stackframe();
456 NTSTATUS status = NT_STATUS_OK;
457 WERROR werr = WERR_OK;
460 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
463 struct policy_handle hive_hnd, key_hnd;
464 uint32_t num_subkeys;
466 struct smbconf_service *shares;
467 const char **subkeys = NULL;
470 ZERO_STRUCT(hive_hnd);
471 ZERO_STRUCT(key_hnd);
474 if (argc != 0 || c->display_usage) {
475 rpc_conf_list_usage(c, argc, argv);
476 status = NT_STATUS_INVALID_PARAMETER;
480 status = rpc_conf_open_conf(frame,
487 if (!(NT_STATUS_IS_OK(status))) {
491 if (!(W_ERROR_IS_OK(werr))) {
495 status = dcerpc_winreg_enum_keys(frame,
502 if (!(NT_STATUS_IS_OK(status))) {
503 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
508 if (!(W_ERROR_IS_OK(werr))) {
509 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
514 if (num_subkeys == 0) {
515 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
516 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
521 /* get info from each subkey */
522 shares = talloc_zero_array(frame, struct smbconf_service, num_subkeys);
523 if (shares == NULL) {
525 d_fprintf(stderr, _("Failed to create shares: %s\n"),
531 for (i = 0; i < num_subkeys; i++) {
532 /* get each share and place it in the shares array */
533 status = rpc_conf_get_share(frame,
539 if (!(NT_STATUS_IS_OK(status))) {
542 if (!(W_ERROR_IS_OK(werr))) {
547 /* print the shares array */
548 rpc_conf_print_shares(num_subkeys, shares);
551 if (!(W_ERROR_IS_OK(werr))) {
552 status = werror_to_ntstatus(werr);
555 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
556 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
563 static NTSTATUS rpc_conf_showshare_internal(struct net_context *c,
564 const struct dom_sid *domain_sid,
565 const char *domain_name,
566 struct cli_state *cli,
567 struct rpc_pipe_client *pipe_hnd,
572 TALLOC_CTX *frame = talloc_stackframe();
573 NTSTATUS status = NT_STATUS_OK;
574 WERROR werr = WERR_OK;
577 struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
580 struct policy_handle hive_hnd, key_hnd;
581 struct smbconf_service *service = NULL;
582 const char *sharename = NULL;
585 ZERO_STRUCT(hive_hnd);
586 ZERO_STRUCT(key_hnd);
589 if (argc != 1 || c->display_usage) {
590 rpc_conf_showshare_usage(c, argc, argv);
591 status = NT_STATUS_INVALID_PARAMETER;
595 status = rpc_conf_open_conf(frame,
602 if (!(NT_STATUS_IS_OK(status))) {
606 if (!(W_ERROR_IS_OK(werr))) {
610 sharename = talloc_strdup(frame, argv[0]);
611 if (sharename == NULL) {
613 d_fprintf(stderr, _("Failed to create share: %s\n"),
618 service = talloc(frame, struct smbconf_service);
619 if (service == NULL) {
621 d_fprintf(stderr, _("Failed to create share: %s\n"),
626 status = rpc_conf_get_share(frame,
633 if (!(NT_STATUS_IS_OK(status))) {
636 if (!(W_ERROR_IS_OK(werr))) {
640 rpc_conf_print_shares(1, service);
643 if (!(W_ERROR_IS_OK(werr))) {
644 status = werror_to_ntstatus(werr);
647 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
648 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
654 static int rpc_conf_drop(struct net_context *c, int argc,
657 d_printf("Function not implemented yet\n");
661 static int rpc_conf_showshare(struct net_context *c, int argc,
664 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
665 rpc_conf_showshare_internal, argc, argv );
668 static int rpc_conf_listshares(struct net_context *c, int argc,
671 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
672 rpc_conf_listshares_internal, argc, argv );
675 static int rpc_conf_list(struct net_context *c, int argc,
678 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
679 rpc_conf_list_internal, argc, argv );
683 int net_rpc_conf(struct net_context *c, int argc,
686 struct functable func_table[] = {
691 N_("Dump the complete remote configuration in smb.conf like "
693 N_("net rpc conf list\n"
694 " Dump the complete remote configuration in smb.conf "
702 N_("List the remote share names."),
703 N_("net rpc conf list\n"
704 " List the remote share names.")
711 N_("Delete the complete remote configuration."),
712 N_("net rpc conf drop\n"
713 " Delete the complete remote configuration.")
720 N_("Show the definition of a remote share."),
721 N_("net rpc conf showshare\n"
722 " Show the definition of a remote share.")
725 {NULL, NULL, 0, NULL, NULL}
728 return net_run_function(c, argc, argv, "net rpc conf", func_table);