s3-net: Added net rpc conf setparm command to net rpc conf
[ira/wip.git] / source3 / utils / net_rpc_conf.c
1 /*
2  *  Samba Unix/Linux SMB client library
3  *  Distributed SMB/CIFS Server Management Utility
4  *  Local configuration interface
5  *  Copyright (C) Vicentiu Ciorbaru 2011
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 /*
22  * This is an interface to Samba's configuration.
23  *
24  * This tool supports local as well as remote interaction via rpc
25  * with the configuration stored in the registry.
26  */
27
28
29 #include "includes.h"
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"
38
39 /* internal functions */
40 /**********************************************************
41  *
42  * usage functions
43  *
44  **********************************************************/
45 const char confpath[100] = "Software\\Samba\\smbconf";
46
47 static int rpc_conf_list_usage(struct net_context *c, int argc,
48                                const char **argv)
49 {
50         d_printf("%s net rpc conf list\n", _("Usage:"));
51         return -1;
52 }
53
54 static int rpc_conf_listshares_usage(struct net_context *c, int argc,
55                                      const char **argv)
56 {
57         d_printf("%s net rpc conf listshares\n", _("Usage:"));
58         return -1;
59 }
60
61 static int rpc_conf_delshare_usage(struct net_context *c, int argc,
62                                    const char **argv)
63 {
64         d_printf("%s\n%s",
65                  _("Usage:"),
66                  _("net rpc conf delshare <sharename>\n"));
67         return -1;
68 }
69
70 static int rpc_conf_showshare_usage(struct net_context *c, int argc,
71                                     const char **argv)
72 {
73         d_printf("%s\n%s",
74                  _("Usage:"),
75                  _("net rpc conf showshare <sharename>\n"));
76         return -1;
77 }
78
79 static int rpc_conf_drop_usage(struct net_context *c, int argc,
80                                const char **argv)
81 {
82         d_printf("%s\nnet rpc conf drop\n", _("Usage:"));
83         return -1;
84 }
85
86 static int rpc_conf_getparm_usage(struct net_context *c, int argc,
87                                const char **argv)
88 {
89         d_printf("%s\nnet rpc conf getparm <sharename> <parameter>\n",
90                         _("Usage:"));
91         return -1;
92 }
93
94 static int rpc_conf_delparm_usage(struct net_context *c, int argc,
95                                 const char **argv)
96 {
97         d_printf("%s\nnet rpc conf delparm <sharename> <parameter>\n",
98                         _("Usage:"));
99         return -1;
100 }
101
102 static int rpc_conf_getincludes_usage(struct net_context *c, int argc,
103                                 const char **argv)
104 {
105         d_printf("%s\nnet rpc conf getincludes <sharename>\n",
106                         _("Usage:"));
107         return -1;
108 }
109
110 static int rpc_conf_delincludes_usage(struct net_context *c, int argc,
111                                 const char **argv)
112 {
113         d_printf("%s\nnet rpc conf delincludes <sharename>\n",
114                         _("Usage:"));
115         return -1;
116 }
117
118 static NTSTATUS rpc_conf_del_value(TALLOC_CTX *mem_ctx,
119                                    struct dcerpc_binding_handle *b,
120                                    struct policy_handle *parent_hnd,
121                                    const char *share_name,
122                                    const char *value,
123                                    WERROR *werr)
124 {
125
126         TALLOC_CTX *frame = talloc_stackframe();
127         NTSTATUS status = NT_STATUS_OK;
128         WERROR result = WERR_OK;
129         WERROR _werr;
130
131         struct winreg_String keyname, valuename;
132         struct policy_handle child_hnd;
133
134         ZERO_STRUCT(child_hnd);
135         ZERO_STRUCT(keyname);
136         ZERO_STRUCT(valuename);
137
138         keyname.name = share_name;
139         valuename.name = value;
140
141         status = dcerpc_winreg_OpenKey(b, frame, parent_hnd, keyname, 0,
142                                        REG_KEY_WRITE, &child_hnd, &result);
143
144         if (!(NT_STATUS_IS_OK(status))) {
145                 d_fprintf(stderr, _("Failed to open key '%s': %s\n"),
146                                 keyname.name, nt_errstr(status));
147                 goto error;
148         }
149
150         if (!(W_ERROR_IS_OK(result))) {
151                 d_fprintf(stderr, _("Failed to open key '%s': %s\n"),
152                                 keyname.name, win_errstr(result));
153                 goto error;
154         }
155
156         status = dcerpc_winreg_DeleteValue(b,
157                                            frame,
158                                            &child_hnd,
159                                            valuename,
160                                            &result);
161
162         if (!(NT_STATUS_IS_OK(status))) {
163                 d_fprintf(stderr, _("Failed to delete value %s\n"),
164                                 nt_errstr(status));
165                 goto error;
166         }
167
168         if (!(W_ERROR_IS_OK(result))) {
169                 if (W_ERROR_EQUAL(result, WERR_BADFILE)){
170                         result = WERR_OK;
171                         goto error;
172                 }
173
174                 d_fprintf(stderr, _("Failed to delete value  %s\n"),
175                                 win_errstr(result));
176                 goto error;
177         }
178
179 error:
180         *werr = result;
181
182         dcerpc_winreg_CloseKey(b, frame, &child_hnd, &_werr);
183
184         TALLOC_FREE(frame);
185         return status;;
186
187 }
188
189 static NTSTATUS rpc_conf_get_share(TALLOC_CTX *mem_ctx,
190                                    struct dcerpc_binding_handle *b,
191                                    struct policy_handle *parent_hnd,
192                                    const char *share_name,
193                                    struct smbconf_service *share,
194                                    WERROR *werr)
195 {
196         TALLOC_CTX *frame = talloc_stackframe();
197
198         NTSTATUS status = NT_STATUS_OK;
199         WERROR result = WERR_OK;
200         WERROR _werr;
201         struct policy_handle child_hnd;
202         int32_t includes_cnt, includes_idx = -1;
203         uint32_t num_vals, i, param_cnt = 0;
204         const char **val_names;
205         enum winreg_Type *types;
206         DATA_BLOB *data;
207         struct winreg_String key;
208         const char **multi_s = NULL;
209         const char *s = NULL;
210         struct smbconf_service tmp_share;
211
212         ZERO_STRUCT(tmp_share);
213
214         key.name = share_name;
215         status = dcerpc_winreg_OpenKey(b, frame, parent_hnd, key, 0,
216                                REG_KEY_READ, &child_hnd, &result);
217
218         if (!(NT_STATUS_IS_OK(status))) {
219                 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
220                                 nt_errstr(status));
221                 goto error;
222         }
223         if (!(W_ERROR_IS_OK(result))) {
224                 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
225                                 win_errstr(result));
226                 goto error;
227         }
228         /* get all the info from the share key */
229         status = dcerpc_winreg_enumvals(frame,
230                         b,
231                         &child_hnd,
232                         &num_vals,
233                         &val_names,
234                         &types,
235                         &data,
236                         &result);
237
238         if (!(NT_STATUS_IS_OK(status))) {
239                 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
240                                 nt_errstr(status));
241                 goto error;
242         }
243         if (!(W_ERROR_IS_OK(result))) {
244                 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
245                                 win_errstr(result));
246                 goto error;
247         }
248         /* check for includes */
249         for (i = 0; i < num_vals; i++) {
250                 if (strcmp(val_names[i], "includes") == 0){
251                         if (!pull_reg_multi_sz(frame,
252                                                &data[i],
253                                                &multi_s))
254                         {
255                                 result = WERR_NOMEM;
256                                 d_fprintf(stderr,
257                                           _("Failed to enumerate values: %s\n"),
258                                           win_errstr(result));
259                                 goto error;
260                         }
261                         includes_idx = i;
262                 }
263         }
264         /* count the number of includes */
265         includes_cnt = 0;
266         if (includes_idx != -1) {
267                 for (includes_cnt = 0;
268                      multi_s[includes_cnt] != NULL;
269                      includes_cnt ++);
270         }
271         /* place the name of the share in the smbconf_service struct */
272         tmp_share.name = talloc_strdup(frame, share_name);
273         if (tmp_share.name == NULL) {
274                 result = WERR_NOMEM;
275                 d_fprintf(stderr, _("Failed to create share: %s\n"),
276                                 win_errstr(result));
277                 goto error;
278         }
279         /* place the number of parameters in the smbconf_service struct */
280         tmp_share.num_params = num_vals;
281         if (includes_idx != -1) {
282                 tmp_share.num_params = num_vals + includes_cnt - 1;
283         }
284         /* allocate memory for the param_names and param_values lists */
285         tmp_share.param_names = talloc_zero_array(frame, char *, tmp_share.num_params);
286         if (tmp_share.param_names == NULL) {
287                 result = WERR_NOMEM;
288                 d_fprintf(stderr, _("Failed to create share: %s\n"),
289                                 win_errstr(result));
290                 goto error;
291         }
292         tmp_share.param_values = talloc_zero_array(frame, char *, tmp_share.num_params);
293         if (tmp_share.param_values == NULL) {
294                 result = WERR_NOMEM;
295                 d_fprintf(stderr, _("Failed to create share: %s\n"),
296                                 win_errstr(result));
297                 goto error;
298         }
299         /* place all params except includes */
300         for (i = 0; i < num_vals; i++) {
301                 if (strcmp(val_names[i], "includes") != 0) {
302                         if (!pull_reg_sz(frame, &data[i], &s)) {
303                                 result = WERR_NOMEM;
304                                 d_fprintf(stderr,
305                                           _("Failed to enumerate values: %s\n"),
306                                           win_errstr(result));
307                                 goto error;
308                         }
309                         /* place param_names */
310                         tmp_share.param_names[param_cnt] = talloc_strdup(frame, val_names[i]);
311                         if (tmp_share.param_names[param_cnt] == NULL) {
312                                 result = WERR_NOMEM;
313                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
314                                                 win_errstr(result));
315                                 goto error;
316                         }
317
318                         /* place param_values */
319                         tmp_share.param_values[param_cnt++] = talloc_strdup(frame, s);
320                         if (tmp_share.param_values[param_cnt - 1] == NULL) {
321                                 result = WERR_NOMEM;
322                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
323                                                 win_errstr(result));
324                                 goto error;
325                         }
326                 }
327         }
328         /* place the includes last */
329         for (i = 0; i < includes_cnt; i++) {
330                 tmp_share.param_names[param_cnt] = talloc_strdup(frame, "include");
331                 if (tmp_share.param_names[param_cnt] == NULL) {
332                                 result = WERR_NOMEM;
333                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
334                                                 win_errstr(result));
335                                 goto error;
336                 }
337
338                 tmp_share.param_values[param_cnt++] = talloc_strdup(frame, multi_s[i]);
339                 if (tmp_share.param_values[param_cnt - 1] == NULL) {
340                                 result = WERR_NOMEM;
341                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
342                                                 win_errstr(result));
343                                 goto error;
344                 }
345         }
346
347         /* move everything to the main memory ctx */
348         for (i = 0; i < param_cnt; i++) {
349                 tmp_share.param_names[i] = talloc_move(mem_ctx, &tmp_share.param_names[i]);
350                 tmp_share.param_values[i] = talloc_move(mem_ctx, &tmp_share.param_values[i]);
351         }
352
353         tmp_share.name = talloc_move(mem_ctx, &tmp_share.name);
354         tmp_share.param_names = talloc_move(mem_ctx, &tmp_share.param_names);
355         tmp_share.param_values = talloc_move(mem_ctx, &tmp_share.param_values);
356         /* out parameter */
357         *share = tmp_share;
358 error:
359         /* close child */
360         dcerpc_winreg_CloseKey(b, frame, &child_hnd, &_werr);
361         *werr = result;
362         TALLOC_FREE(frame);
363         return status;
364 }
365
366 static int rpc_conf_print_shares(uint32_t num_shares,
367                                  struct smbconf_service *shares)
368 {
369
370         uint32_t share_count, param_count;
371         const char *indent = "\t";
372
373         if (num_shares == 0) {
374                 return 0;
375         }
376
377         for (share_count = 0; share_count < num_shares; share_count++) {
378                 d_printf("\n");
379                 if (shares[share_count].name != NULL) {
380                 d_printf("[%s]\n", shares[share_count].name);
381                 }
382
383                 for (param_count = 0;
384                      param_count < shares[share_count].num_params;
385                      param_count++)
386                 {
387                         d_printf("%s%s = %s\n",
388                                  indent,
389                                  shares[share_count].param_names[param_count],
390                                  shares[share_count].param_values[param_count]);
391                 }
392         }
393         d_printf("\n");
394
395         return 0;
396
397 }
398 static NTSTATUS rpc_conf_open_conf(TALLOC_CTX *mem_ctx,
399                                    struct dcerpc_binding_handle *b,
400                                    uint32_t access_mask,
401                                    struct policy_handle *hive_hnd,
402                                    struct policy_handle *key_hnd,
403                                    WERROR *werr)
404 {
405         TALLOC_CTX *frame = talloc_stackframe();
406         NTSTATUS status = NT_STATUS_OK;
407         WERROR result = WERR_OK;
408         WERROR _werr;
409         struct policy_handle tmp_hive_hnd, tmp_key_hnd;
410         struct winreg_String key;
411
412         ZERO_STRUCT(key);
413
414         status = dcerpc_winreg_OpenHKLM(b, frame, NULL,
415                         access_mask, &tmp_hive_hnd, &result);
416
417         /*
418          * print no error messages if it is a read only open
419          * and key does not exist
420          * error still gets returned
421          */
422
423         if (access_mask == REG_KEY_READ &&
424             W_ERROR_EQUAL(result, WERR_BADFILE))
425         {
426                 goto error;
427         }
428
429         if (!(NT_STATUS_IS_OK(status))) {
430                 d_fprintf(stderr, _("Failed to open hive: %s\n"),
431                                 nt_errstr(status));
432                 goto error;
433         }
434         if (!W_ERROR_IS_OK(result)) {
435                 d_fprintf(stderr, _("Failed to open hive: %s\n"),
436                                 win_errstr(result));
437                 goto error;
438         }
439
440         key.name = confpath;
441         status = dcerpc_winreg_OpenKey(b, frame, &tmp_hive_hnd, key, 0,
442                                        access_mask, &tmp_key_hnd, &result);
443
444         /*
445          * print no error messages if it is a read only open
446          * and key does not exist
447          * error still gets returned
448          */
449
450         if (access_mask == REG_KEY_READ &&
451             W_ERROR_EQUAL(result, WERR_BADFILE))
452         {
453                 goto error;
454         }
455
456         if (!(NT_STATUS_IS_OK(status))) {
457                 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
458                                 nt_errstr(status));
459                 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
460                 goto error;
461         }
462         if (!(W_ERROR_IS_OK(result))) {
463                 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
464                         win_errstr(result));
465                 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
466                 goto error;
467         }
468
469         *hive_hnd = tmp_hive_hnd;
470         *key_hnd = tmp_key_hnd;
471
472 error:
473         TALLOC_FREE(frame);
474         *werr = result;
475
476         return status;
477 }
478
479 static NTSTATUS rpc_conf_listshares_internal(struct net_context *c,
480                                              const struct dom_sid *domain_sid,
481                                              const char *domain_name,
482                                              struct cli_state *cli,
483                                              struct rpc_pipe_client *pipe_hnd,
484                                              TALLOC_CTX *mem_ctx,
485                                              int argc,
486                                              const char **argv )
487 {
488
489         TALLOC_CTX *frame = talloc_stackframe();
490         NTSTATUS status = NT_STATUS_OK;
491         WERROR werr = WERR_OK;
492         WERROR _werr;
493
494         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
495
496         /* key info */
497         struct policy_handle hive_hnd, key_hnd;
498         uint32_t num_subkeys;
499         uint32_t i;
500         const char **subkeys = NULL;
501
502
503         ZERO_STRUCT(hive_hnd);
504         ZERO_STRUCT(key_hnd);
505
506
507         if (argc != 0 || c->display_usage) {
508                 rpc_conf_listshares_usage(c, argc, argv);
509                 status = NT_STATUS_INVALID_PARAMETER;
510                 goto error;
511         }
512
513
514         status = rpc_conf_open_conf(frame,
515                                     b,
516                                     REG_KEY_READ,
517                                     &hive_hnd,
518                                     &key_hnd,
519                                     &werr);
520
521         if (!(NT_STATUS_IS_OK(status))) {
522                 goto error;
523         }
524
525         if (!(W_ERROR_IS_OK(werr))) {
526                 goto error;
527         }
528
529         status = dcerpc_winreg_enum_keys(frame,
530                                          b,
531                                          &key_hnd,
532                                          &num_subkeys,
533                                          &subkeys,
534                                          &werr);
535
536         if (!(NT_STATUS_IS_OK(status))) {
537                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
538                                 nt_errstr(status));
539                 goto error;
540         }
541
542         if (!(W_ERROR_IS_OK(werr))) {
543                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
544                                 win_errstr(werr));
545                 goto error;
546         }
547
548         for (i = 0; i < num_subkeys; i++) {
549                 d_printf("%s\n", subkeys[i]);
550         }
551
552 error:
553         if (!(W_ERROR_IS_OK(werr))) {
554                 status =  werror_to_ntstatus(werr);
555         }
556
557         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
558         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
559
560         TALLOC_FREE(frame);
561         return status;;
562 }
563
564 static NTSTATUS rpc_conf_delshare_internal(struct net_context *c,
565                                            const struct dom_sid *domain_sid,
566                                            const char *domain_name,
567                                            struct cli_state *cli,
568                                            struct rpc_pipe_client *pipe_hnd,
569                                            TALLOC_CTX *mem_ctx,
570                                            int argc,
571                                            const char **argv )
572 {
573
574         TALLOC_CTX *frame = talloc_stackframe();
575         NTSTATUS status = NT_STATUS_OK;
576         WERROR werr = WERR_OK;
577         WERROR _werr;
578
579         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
580
581         /* key info */
582         struct policy_handle hive_hnd, key_hnd;
583
584         ZERO_STRUCT(hive_hnd);
585         ZERO_STRUCT(key_hnd);
586
587
588         if (argc != 1 || c->display_usage) {
589                 rpc_conf_delshare_usage(c, argc, argv);
590                 status = NT_STATUS_INVALID_PARAMETER;
591                 goto error;
592         }
593
594         status = rpc_conf_open_conf(frame,
595                                     b,
596                                     REG_KEY_ALL,
597                                     &hive_hnd,
598                                     &key_hnd,
599                                     &werr);
600
601         if (!(NT_STATUS_IS_OK(status))) {
602                 goto error;
603         }
604
605         if (!(W_ERROR_IS_OK(werr))) {
606                 goto error;
607         }
608
609         status = dcerpc_winreg_delete_subkeys_recursive(frame,
610                                                         b,
611                                                         &key_hnd,
612                                                         REG_KEY_ALL,
613                                                         argv[0],
614                                                         &werr);
615
616         if (!NT_STATUS_IS_OK(status)) {
617                 d_fprintf(stderr,
618                           "winreg_delete_subkeys: Could not delete key %s: %s\n",
619                           argv[0], nt_errstr(status));
620                 goto error;
621         }
622
623         if (W_ERROR_EQUAL(werr, WERR_BADFILE)){
624                 d_fprintf(stderr, _("ERROR: Key does not exist\n"));
625         }
626
627
628         if (!W_ERROR_IS_OK(werr)) {
629                 d_fprintf(stderr,
630                           "winreg_delete_subkeys: Could not delete key %s: %s\n",
631                           argv[0], win_errstr(werr));
632                 goto error;
633         }
634
635 error:
636         if (!(W_ERROR_IS_OK(werr))) {
637                 status =  werror_to_ntstatus(werr);
638         }
639
640         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
641         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
642
643         TALLOC_FREE(frame);
644
645         return status;
646 }
647
648 static NTSTATUS rpc_conf_list_internal(struct net_context *c,
649                                        const struct dom_sid *domain_sid,
650                                        const char *domain_name,
651                                        struct cli_state *cli,
652                                        struct rpc_pipe_client *pipe_hnd,
653                                        TALLOC_CTX *mem_ctx,
654                                        int argc,
655                                        const char **argv )
656 {
657
658         TALLOC_CTX *frame = talloc_stackframe();
659         NTSTATUS status = NT_STATUS_OK;
660         WERROR werr = WERR_OK;
661         WERROR _werr;
662
663         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
664
665         /* key info */
666         struct policy_handle hive_hnd, key_hnd;
667         uint32_t num_subkeys;
668         uint32_t i;
669         struct smbconf_service *shares;
670         const char **subkeys = NULL;
671
672
673         ZERO_STRUCT(hive_hnd);
674         ZERO_STRUCT(key_hnd);
675
676
677         if (argc != 0 || c->display_usage) {
678                 rpc_conf_list_usage(c, argc, argv);
679                 status = NT_STATUS_INVALID_PARAMETER;
680                 goto error;
681         }
682
683         status = rpc_conf_open_conf(frame,
684                                     b,
685                                     REG_KEY_READ,
686                                     &hive_hnd,
687                                     &key_hnd,
688                                     &werr);
689
690         if (!(NT_STATUS_IS_OK(status))) {
691                 goto error;
692         }
693
694         if (!(W_ERROR_IS_OK(werr))) {
695                 goto error;
696         }
697
698         status = dcerpc_winreg_enum_keys(frame,
699                                          b,
700                                          &key_hnd,
701                                          &num_subkeys,
702                                          &subkeys,
703                                          &werr);
704
705         if (!(NT_STATUS_IS_OK(status))) {
706                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
707                                 nt_errstr(status));
708                 goto error;
709         }
710
711         if (!(W_ERROR_IS_OK(werr))) {
712                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
713                                 win_errstr(werr));
714                 goto error;
715         }
716
717         if (num_subkeys == 0) {
718                 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
719                 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
720                 TALLOC_FREE(frame);
721                 return NT_STATUS_OK;
722         }
723
724         /* get info from each subkey */
725         shares = talloc_zero_array(frame, struct smbconf_service, num_subkeys);
726         if (shares == NULL) {
727                 werr = WERR_NOMEM;
728                 d_fprintf(stderr, _("Failed to create shares: %s\n"),
729                                 win_errstr(werr));
730                 goto error;
731
732         }
733
734         for (i = 0; i < num_subkeys; i++) {
735                 /* get each share and place it in the shares array */
736                 status = rpc_conf_get_share(frame,
737                                 b,
738                                 &key_hnd,
739                                 subkeys[i],
740                                 &shares[i],
741                                 &werr);
742                 if (!(NT_STATUS_IS_OK(status))) {
743                         goto error;
744                 }
745                 if (!(W_ERROR_IS_OK(werr))) {
746                         goto error;
747                 }
748
749         }
750         /* print the shares array */
751         rpc_conf_print_shares(num_subkeys, shares);
752
753 error:
754         if (!(W_ERROR_IS_OK(werr))) {
755                 status =  werror_to_ntstatus(werr);
756         }
757
758         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
759         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
760
761         TALLOC_FREE(frame);
762         return status;
763
764 }
765
766 static NTSTATUS rpc_conf_drop_internal(struct net_context *c,
767                                        const struct dom_sid *domain_sid,
768                                        const char *domain_name,
769                                        struct cli_state *cli,
770                                        struct rpc_pipe_client *pipe_hnd,
771                                        TALLOC_CTX *mem_ctx,
772                                        int argc,
773                                        const char **argv )
774 {
775         TALLOC_CTX *frame = talloc_stackframe();
776         NTSTATUS status = NT_STATUS_OK;
777         WERROR werr = WERR_OK;
778         WERROR _werr;
779
780         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
781
782         /* key info */
783         struct policy_handle hive_hnd, key_hnd;
784         const char *keyname = confpath;
785         struct winreg_String wkey, wkeyclass;
786         enum winreg_CreateAction action = REG_ACTION_NONE;
787
788
789         ZERO_STRUCT(hive_hnd);
790         ZERO_STRUCT(key_hnd);
791
792
793         if (argc != 0 || c->display_usage) {
794                 rpc_conf_drop_usage(c, argc, argv);
795                 status = NT_STATUS_INVALID_PARAMETER;
796                 goto error;
797         }
798
799         status = rpc_conf_open_conf(frame,
800                                     b,
801                                     REG_KEY_ALL,
802                                     &hive_hnd,
803                                     &key_hnd,
804                                     &werr);
805
806         if (!(NT_STATUS_IS_OK(status))) {
807                 goto error;
808         }
809
810         if (!(W_ERROR_IS_OK(werr))) {
811                 goto error;
812         }
813
814         status = dcerpc_winreg_delete_subkeys_recursive(frame,
815                                                         b,
816                                                         &hive_hnd,
817                                                         REG_KEY_ALL,
818                                                         keyname,
819                                                         &werr);
820
821         if (!NT_STATUS_IS_OK(status)) {
822                 d_printf("winreg_delete_subkeys: Could not delete key %s: %s\n",
823                           keyname, nt_errstr(status));
824                 goto error;
825         }
826
827         if (!W_ERROR_IS_OK(werr)) {
828                 d_printf("winreg_delete_subkeys: Could not delete key %s: %s\n",
829                           keyname, win_errstr(werr));
830                 goto error;
831         }
832
833         wkey.name = keyname;
834         ZERO_STRUCT(wkeyclass);
835         wkeyclass.name = "";
836         action = REG_ACTION_NONE;
837
838         status = dcerpc_winreg_CreateKey(b,
839                                          frame,
840                                          &hive_hnd,
841                                          wkey,
842                                          wkeyclass,
843                                          0,
844                                          REG_KEY_ALL,
845                                          NULL,
846                                          &key_hnd,
847                                          &action,
848                                          &werr);
849
850         if (!NT_STATUS_IS_OK(status)) {
851                 d_printf("winreg_CreateKey: Could not create smbconf key\n");
852                 goto error;
853         }
854
855         if (!W_ERROR_IS_OK(werr)) {
856                 d_printf("winreg_CreateKey: Could not create smbconf key\n");
857                 goto error;
858         }
859
860
861 error:
862         if (!(W_ERROR_IS_OK(werr))) {
863                 status =  werror_to_ntstatus(werr);
864         }
865
866         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
867         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
868
869         TALLOC_FREE(frame);
870         return status;
871 }
872
873 static NTSTATUS rpc_conf_showshare_internal(struct net_context *c,
874                                             const struct dom_sid *domain_sid,
875                                             const char *domain_name,
876                                             struct cli_state *cli,
877                                             struct rpc_pipe_client *pipe_hnd,
878                                             TALLOC_CTX *mem_ctx,
879                                             int argc,
880                                             const char **argv )
881 {
882         TALLOC_CTX *frame = talloc_stackframe();
883         NTSTATUS status = NT_STATUS_OK;
884         WERROR werr = WERR_OK;
885         WERROR _werr;
886
887         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
888
889         /* key info */
890         struct policy_handle hive_hnd, key_hnd;
891         struct smbconf_service *service = NULL;
892         const char *sharename = NULL;
893
894
895         ZERO_STRUCT(hive_hnd);
896         ZERO_STRUCT(key_hnd);
897
898
899         if (argc != 1 || c->display_usage) {
900                 rpc_conf_showshare_usage(c, argc, argv);
901                 status = NT_STATUS_INVALID_PARAMETER;
902                 goto error;
903         }
904
905         status = rpc_conf_open_conf(frame,
906                                     b,
907                                     REG_KEY_READ,
908                                     &hive_hnd,
909                                     &key_hnd,
910                                     &werr);
911
912         if (!(NT_STATUS_IS_OK(status))) {
913                 goto error;
914         }
915
916         if (!(W_ERROR_IS_OK(werr))) {
917                 goto error;
918         }
919
920         sharename = talloc_strdup(frame, argv[0]);
921         if (sharename == NULL) {
922                 werr = WERR_NOMEM;
923                 d_fprintf(stderr, _("Failed to create share: %s\n"),
924                                 win_errstr(werr));
925                 goto error;
926         }
927
928         service = talloc(frame, struct smbconf_service);
929         if (service == NULL) {
930                 werr = WERR_NOMEM;
931                 d_fprintf(stderr, _("Failed to create share: %s\n"),
932                                 win_errstr(werr));
933                 goto error;
934         }
935
936         status = rpc_conf_get_share(frame,
937                         b,
938                         &key_hnd,
939                         sharename,
940                         service,
941                         &werr);
942
943         if (!(NT_STATUS_IS_OK(status))) {
944                 goto error;
945         }
946         if (!(W_ERROR_IS_OK(werr))) {
947                 goto error;
948         }
949
950         rpc_conf_print_shares(1, service);
951
952 error:
953         if (!(W_ERROR_IS_OK(werr))) {
954                 status =  werror_to_ntstatus(werr);
955         }
956
957         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
958         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
959
960         TALLOC_FREE(frame);
961         return status;
962 }
963
964 static NTSTATUS rpc_conf_getparm_internal(struct net_context *c,
965                                           const struct dom_sid *domain_sid,
966                                           const char *domain_name,
967                                           struct cli_state *cli,
968                                           struct rpc_pipe_client *pipe_hnd,
969                                           TALLOC_CTX *mem_ctx,
970                                           int argc,
971                                           const char **argv )
972 {
973         TALLOC_CTX *frame = talloc_stackframe();
974         NTSTATUS status = NT_STATUS_OK;
975         WERROR werr = WERR_OK;
976         WERROR _werr;
977
978         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
979
980         /* key info */
981         struct policy_handle hive_hnd, key_hnd;
982         struct smbconf_service *service = NULL;
983
984         bool param_is_set = false;
985         uint32_t param_count;
986
987         ZERO_STRUCT(hive_hnd);
988         ZERO_STRUCT(key_hnd);
989
990
991         if (argc != 2 || c->display_usage) {
992                 rpc_conf_getparm_usage(c, argc, argv);
993                 status = NT_STATUS_INVALID_PARAMETER;
994                 goto error;
995         }
996
997         status = rpc_conf_open_conf(frame,
998                                     b,
999                                     REG_KEY_READ,
1000                                     &hive_hnd,
1001                                     &key_hnd,
1002                                     &werr);
1003
1004         if (!(NT_STATUS_IS_OK(status))) {
1005                 goto error;
1006         }
1007
1008         if (!(W_ERROR_IS_OK(werr))) {
1009                 goto error;
1010         }
1011
1012
1013         service = talloc(frame, struct smbconf_service);
1014
1015         status = rpc_conf_get_share(frame,
1016                                     b,
1017                                     &key_hnd,
1018                                     argv[0],
1019                                     service,
1020                                     &werr);
1021
1022         if (!(NT_STATUS_IS_OK(status))) {
1023                         goto error;
1024         }
1025
1026         if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
1027                 d_fprintf(stderr, _("ERROR: Share %s does not exist\n"),
1028                                 argv[0]);
1029                 goto error;
1030         }
1031
1032         if (!(W_ERROR_IS_OK(werr))) {
1033                         goto error;
1034         }
1035
1036         for (param_count = 0;
1037              param_count < service->num_params;
1038              param_count++)
1039         {
1040                 /* should includes also be printed? */
1041                 if (strcmp(service->param_names[param_count], argv[1]) == 0) {
1042                         d_printf(_("%s\n"),
1043                                 service->param_values[param_count]);
1044                         param_is_set = true;
1045                 }
1046         }
1047
1048         if (!param_is_set) {
1049                 d_fprintf(stderr, _("ERROR: Given parameter '%s' has not been set\n"),
1050                                 argv[1]);
1051                 werr = WERR_BADFILE;
1052                 goto error;
1053         }
1054
1055 error:
1056
1057         if (!(W_ERROR_IS_OK(werr))) {
1058                 status =  werror_to_ntstatus(werr);
1059         }
1060
1061         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
1062         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
1063
1064         TALLOC_FREE(frame);
1065         return status;
1066
1067 }
1068
1069 static NTSTATUS rpc_conf_delparm_internal(struct net_context *c,
1070                                           const struct dom_sid *domain_sid,
1071                                           const char *domain_name,
1072                                           struct cli_state *cli,
1073                                           struct rpc_pipe_client *pipe_hnd,
1074                                           TALLOC_CTX *mem_ctx,
1075                                           int argc,
1076                                           const char **argv )
1077 {
1078         TALLOC_CTX *frame = talloc_stackframe();
1079         NTSTATUS status = NT_STATUS_OK;
1080         WERROR werr = WERR_OK;
1081         WERROR _werr;
1082
1083         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1084
1085         /* key info */
1086         struct policy_handle hive_hnd, key_hnd;
1087
1088
1089         ZERO_STRUCT(hive_hnd);
1090         ZERO_STRUCT(key_hnd);
1091
1092
1093         if (argc != 2 || c->display_usage) {
1094                 rpc_conf_delparm_usage(c, argc, argv);
1095                 status = NT_STATUS_INVALID_PARAMETER;
1096                 goto error;
1097         }
1098
1099         status = rpc_conf_open_conf(frame,
1100                                     b,
1101                                     REG_KEY_READ,
1102                                     &hive_hnd,
1103                                     &key_hnd,
1104                                     &werr);
1105
1106         if (!(NT_STATUS_IS_OK(status))) {
1107                 goto error;
1108         }
1109
1110         if (!(W_ERROR_IS_OK(werr))) {
1111                 goto error;
1112         }
1113
1114         status = rpc_conf_del_value(frame,
1115                                     b,
1116                                     &key_hnd,
1117                                     argv[0],
1118                                     argv[1],
1119                                     &werr);
1120
1121 error:
1122
1123         if (!(W_ERROR_IS_OK(werr))) {
1124                 status =  werror_to_ntstatus(werr);
1125         }
1126
1127         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
1128         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
1129
1130         TALLOC_FREE(frame);
1131         return status;
1132
1133 }
1134
1135 static NTSTATUS rpc_conf_getincludes_internal(struct net_context *c,
1136                                               const struct dom_sid *domain_sid,
1137                                               const char *domain_name,
1138                                               struct cli_state *cli,
1139                                               struct rpc_pipe_client *pipe_hnd,
1140                                               TALLOC_CTX *mem_ctx,
1141                                               int argc,
1142                                               const char **argv )
1143 {
1144         TALLOC_CTX *frame = talloc_stackframe();
1145         NTSTATUS status = NT_STATUS_OK;
1146         WERROR werr = WERR_OK;
1147         WERROR _werr;
1148
1149         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1150
1151         /* key info */
1152         struct policy_handle hive_hnd, key_hnd;
1153         struct smbconf_service *service = NULL;
1154
1155         uint32_t param_count;
1156
1157
1158         ZERO_STRUCT(hive_hnd);
1159         ZERO_STRUCT(key_hnd);
1160
1161
1162         if (argc != 1 || c->display_usage) {
1163                 rpc_conf_getincludes_usage(c, argc, argv);
1164                 status = NT_STATUS_INVALID_PARAMETER;
1165                 goto error;
1166         }
1167
1168         status = rpc_conf_open_conf(frame,
1169                                     b,
1170                                     REG_KEY_READ,
1171                                     &hive_hnd,
1172                                     &key_hnd,
1173                                     &werr);
1174
1175         if (!(NT_STATUS_IS_OK(status))) {
1176                 goto error;
1177         }
1178
1179         if (!(W_ERROR_IS_OK(werr))) {
1180                 goto error;
1181         }
1182
1183         service = talloc(frame, struct smbconf_service);
1184
1185         status = rpc_conf_get_share(frame,
1186                                     b,
1187                                     &key_hnd,
1188                                     argv[0],
1189                                     service,
1190                                     &werr);
1191
1192         if (!(NT_STATUS_IS_OK(status))) {
1193                         goto error;
1194         }
1195
1196         if (!(W_ERROR_IS_OK(werr))) {
1197                         goto error;
1198         }
1199
1200         for (param_count = 0;
1201              param_count < service->num_params;
1202              param_count++)
1203         {
1204                 if (strcmp(service->param_names[param_count], "include") == 0) {
1205                         d_printf(_("%s = %s\n"),
1206                                 service->param_names[param_count],
1207                                 service->param_values[param_count]);
1208                 }
1209         }
1210
1211 error:
1212
1213         if (!(W_ERROR_IS_OK(werr))) {
1214                 status =  werror_to_ntstatus(werr);
1215         }
1216
1217         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
1218         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
1219
1220         TALLOC_FREE(frame);
1221         return status;
1222
1223 }
1224
1225 static NTSTATUS rpc_conf_delincludes_internal(struct net_context *c,
1226                                               const struct dom_sid *domain_sid,
1227                                               const char *domain_name,
1228                                               struct cli_state *cli,
1229                                               struct rpc_pipe_client *pipe_hnd,
1230                                               TALLOC_CTX *mem_ctx,
1231                                               int argc,
1232                                               const char **argv )
1233 {
1234         TALLOC_CTX *frame = talloc_stackframe();
1235         NTSTATUS status = NT_STATUS_OK;
1236         WERROR werr = WERR_OK;
1237         WERROR _werr;
1238
1239         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
1240
1241         /* key info */
1242         struct policy_handle hive_hnd, key_hnd;
1243
1244
1245         ZERO_STRUCT(hive_hnd);
1246         ZERO_STRUCT(key_hnd);
1247
1248
1249         if (argc != 1 || c->display_usage) {
1250                 rpc_conf_delincludes_usage(c, argc, argv);
1251                 status = NT_STATUS_INVALID_PARAMETER;
1252                 goto error;
1253         }
1254 /* try REG_KEY_WRITE */
1255         status = rpc_conf_open_conf(frame,
1256                                     b,
1257                                     REG_KEY_READ,
1258                                     &hive_hnd,
1259                                     &key_hnd,
1260                                     &werr);
1261
1262         if (!(NT_STATUS_IS_OK(status))) {
1263                 goto error;
1264         }
1265
1266         if (!(W_ERROR_IS_OK(werr))) {
1267                 goto error;
1268         }
1269
1270         status = rpc_conf_del_value(frame,
1271                                     b,
1272                                     &key_hnd,
1273                                     argv[0],
1274                                     "includes",
1275                                     &werr);
1276
1277 error:
1278
1279         if (!(W_ERROR_IS_OK(werr))) {
1280                 status =  werror_to_ntstatus(werr);
1281         }
1282
1283         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
1284         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
1285
1286         TALLOC_FREE(frame);
1287         return status;
1288
1289 }
1290
1291 static int rpc_conf_drop(struct net_context *c, int argc,
1292                                 const char **argv)
1293 {
1294         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1295                 rpc_conf_drop_internal, argc, argv );
1296
1297 }
1298
1299 static int rpc_conf_showshare(struct net_context *c, int argc,
1300                                 const char **argv)
1301 {
1302         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1303                 rpc_conf_showshare_internal, argc, argv );
1304 }
1305
1306 static int rpc_conf_listshares(struct net_context *c, int argc,
1307                                 const char **argv)
1308 {
1309         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1310                 rpc_conf_listshares_internal, argc, argv );
1311 }
1312
1313 static int rpc_conf_list(struct net_context *c, int argc,
1314                              const char **argv)
1315 {
1316         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1317                 rpc_conf_list_internal, argc, argv );
1318 }
1319
1320 static int rpc_conf_delshare(struct net_context *c, int argc,
1321                              const char **argv)
1322 {
1323         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1324                 rpc_conf_delshare_internal, argc, argv );
1325 }
1326
1327 static int rpc_conf_getparm(struct net_context *c, int argc,
1328                              const char **argv)
1329 {
1330         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1331                 rpc_conf_getparm_internal, argc, argv );
1332 }
1333
1334 static int rpc_conf_setparm(struct net_context *c, int argc,
1335                                 const char **argv)
1336 {
1337         d_printf("Function not yet implemented\n");
1338         return 0;
1339 }
1340 static int rpc_conf_delparm(struct net_context *c, int argc,
1341                                 const char **argv)
1342 {
1343         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1344                 rpc_conf_delparm_internal, argc, argv );
1345 }
1346
1347 static int rpc_conf_getincludes(struct net_context *c, int argc,
1348                              const char **argv)
1349 {
1350         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1351                 rpc_conf_getincludes_internal, argc, argv );
1352 }
1353
1354 static int rpc_conf_delincludes(struct net_context *c, int argc,
1355                                 const char **argv)
1356 {
1357         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1358                 rpc_conf_delincludes_internal, argc, argv );
1359 }
1360 /* function calls */
1361 int net_rpc_conf(struct net_context *c, int argc,
1362                  const char **argv)
1363 {
1364         struct functable func_table[] = {
1365                 {
1366                         "list",
1367                         rpc_conf_list,
1368                         NET_TRANSPORT_RPC,
1369                         N_("Dump the complete remote configuration in smb.conf like "
1370                            "format."),
1371                         N_("net rpc conf list\n"
1372                            "    Dump the complete remote configuration in smb.conf "
1373                            "like format.")
1374
1375                 },
1376                 {
1377                         "listshares",
1378                         rpc_conf_listshares,
1379                         NET_TRANSPORT_RPC,
1380                         N_("List the remote share names."),
1381                         N_("net rpc conf list\n"
1382                            "    List the remote share names.")
1383
1384                 },
1385                 {
1386                         "drop",
1387                         rpc_conf_drop,
1388                         NET_TRANSPORT_RPC,
1389                         N_("Delete the complete remote configuration."),
1390                         N_("net rpc conf drop\n"
1391                            "    Delete the complete remote configuration.")
1392
1393                 },
1394                 {
1395                         "showshare",
1396                         rpc_conf_showshare,
1397                         NET_TRANSPORT_RPC,
1398                         N_("Show the definition of a remote share."),
1399                         N_("net rpc conf showshare\n"
1400                            "    Show the definition of a remote share.")
1401
1402                 },
1403                 {
1404                         "delshare",
1405                         rpc_conf_delshare,
1406                         NET_TRANSPORT_RPC,
1407                         N_("Delete a remote share."),
1408                         N_("net rpc conf delshare\n"
1409                            "    Delete a remote share.")
1410                 },
1411                 {
1412                         "getparm",
1413                         rpc_conf_getparm,
1414                         NET_TRANSPORT_RPC,
1415                         N_("Retrieve the value of a parameter."),
1416                         N_("net rpc conf getparm\n"
1417                            "    Retrieve the value of a parameter.")
1418                 },
1419                 {
1420                         "setparm",
1421                         rpc_conf_setparm,
1422                         NET_TRANSPORT_RPC,
1423                         N_("Store a parameter."),
1424                         N_("net rpc conf setparm\n"
1425                            "    Store a parameter.")
1426                 },
1427                 {
1428                         "delparm",
1429                         rpc_conf_delparm,
1430                         NET_TRANSPORT_RPC,
1431                         N_("Delete a parameter."),
1432                         N_("net rpc conf delparm\n"
1433                            "    Delete a parameter.")
1434                 },
1435                 {
1436                         "getincludes",
1437                         rpc_conf_getincludes,
1438                         NET_TRANSPORT_RPC,
1439                         N_("Show the includes of a share definition."),
1440                         N_("net rpc conf getincludes\n"
1441                            "    Show the includes of a share definition.")
1442                 },
1443                 {
1444                         "delincludes",
1445                         rpc_conf_delincludes,
1446                         NET_TRANSPORT_RPC,
1447                         N_("Delete includes from a share definition."),
1448                         N_("net rpc conf delincludes\n"
1449                            "    Delete includes from a share definition.")
1450                 },
1451                 {NULL, NULL, 0, NULL, NULL}
1452         };
1453
1454         return net_run_function(c, argc, argv, "net rpc conf", func_table);
1455
1456 }