s3-net: Added net rpc conf getparm command to net rpc conf
[samba.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 NTSTATUS rpc_conf_get_share(TALLOC_CTX *mem_ctx,
87                                    struct dcerpc_binding_handle *b,
88                                    struct policy_handle *parent_hnd,
89                                    const char *share_name,
90                                    struct smbconf_service *share,
91                                    WERROR *werr)
92 {
93         TALLOC_CTX *frame = talloc_stackframe();
94
95         NTSTATUS status = NT_STATUS_OK;
96         WERROR result = WERR_OK;
97         WERROR _werr;
98         struct policy_handle child_hnd;
99         int32_t includes_cnt, includes_idx = -1;
100         uint32_t num_vals, i, param_cnt = 0;
101         const char **val_names;
102         enum winreg_Type *types;
103         DATA_BLOB *data;
104         struct winreg_String key;
105         const char **multi_s = NULL;
106         const char *s = NULL;
107         struct smbconf_service tmp_share;
108
109         ZERO_STRUCT(tmp_share);
110
111         key.name = share_name;
112         status = dcerpc_winreg_OpenKey(b, frame, parent_hnd, key, 0,
113                                REG_KEY_READ, &child_hnd, &result);
114
115         if (!(NT_STATUS_IS_OK(status))) {
116                 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
117                                 nt_errstr(status));
118                 goto error;
119         }
120         if (!(W_ERROR_IS_OK(result))) {
121                 d_fprintf(stderr, _("Failed to open subkey: %s\n"),
122                                 win_errstr(result));
123                 goto error;
124         }
125         /* get all the info from the share key */
126         status = dcerpc_winreg_enumvals(frame,
127                         b,
128                         &child_hnd,
129                         &num_vals,
130                         &val_names,
131                         &types,
132                         &data,
133                         &result);
134
135         if (!(NT_STATUS_IS_OK(status))) {
136                 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
137                                 nt_errstr(status));
138                 goto error;
139         }
140         if (!(W_ERROR_IS_OK(result))) {
141                 d_fprintf(stderr, _("Failed to enumerate values: %s\n"),
142                                 win_errstr(result));
143                 goto error;
144         }
145         /* check for includes */
146         for (i = 0; i < num_vals; i++) {
147                 if (strcmp(val_names[i], "includes") == 0){
148                         if (!pull_reg_multi_sz(frame,
149                                                &data[i],
150                                                &multi_s))
151                         {
152                                 result = WERR_NOMEM;
153                                 d_fprintf(stderr,
154                                           _("Failed to enumerate values: %s\n"),
155                                           win_errstr(result));
156                                 goto error;
157                         }
158                         includes_idx = i;
159                 }
160         }
161         /* count the number of includes */
162         includes_cnt = 0;
163         if (includes_idx != -1) {
164                 for (includes_cnt = 0;
165                      multi_s[includes_cnt] != NULL;
166                      includes_cnt ++);
167         }
168         /* place the name of the share in the smbconf_service struct */
169         tmp_share.name = talloc_strdup(frame, share_name);
170         if (tmp_share.name == NULL) {
171                 result = WERR_NOMEM;
172                 d_fprintf(stderr, _("Failed to create share: %s\n"),
173                                 win_errstr(result));
174                 goto error;
175         }
176         /* place the number of parameters in the smbconf_service struct */
177         tmp_share.num_params = num_vals;
178         if (includes_idx != -1) {
179                 tmp_share.num_params = num_vals + includes_cnt - 1;
180         }
181         /* allocate memory for the param_names and param_values lists */
182         tmp_share.param_names = talloc_zero_array(frame, char *, tmp_share.num_params);
183         if (tmp_share.param_names == NULL) {
184                 result = WERR_NOMEM;
185                 d_fprintf(stderr, _("Failed to create share: %s\n"),
186                                 win_errstr(result));
187                 goto error;
188         }
189         tmp_share.param_values = talloc_zero_array(frame, char *, tmp_share.num_params);
190         if (tmp_share.param_values == NULL) {
191                 result = WERR_NOMEM;
192                 d_fprintf(stderr, _("Failed to create share: %s\n"),
193                                 win_errstr(result));
194                 goto error;
195         }
196         /* place all params except includes */
197         for (i = 0; i < num_vals; i++) {
198                 if (strcmp(val_names[i], "includes") != 0) {
199                         if (!pull_reg_sz(frame, &data[i], &s)) {
200                                 result = WERR_NOMEM;
201                                 d_fprintf(stderr,
202                                           _("Failed to enumerate values: %s\n"),
203                                           win_errstr(result));
204                                 goto error;
205                         }
206                         /* place param_names */
207                         tmp_share.param_names[param_cnt] = talloc_strdup(frame, val_names[i]);
208                         if (tmp_share.param_names[param_cnt] == NULL) {
209                                 result = WERR_NOMEM;
210                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
211                                                 win_errstr(result));
212                                 goto error;
213                         }
214
215                         /* place param_values */
216                         tmp_share.param_values[param_cnt++] = talloc_strdup(frame, s);
217                         if (tmp_share.param_values[param_cnt - 1] == NULL) {
218                                 result = WERR_NOMEM;
219                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
220                                                 win_errstr(result));
221                                 goto error;
222                         }
223                 }
224         }
225         /* place the includes last */
226         for (i = 0; i < includes_cnt; i++) {
227                 tmp_share.param_names[param_cnt] = talloc_strdup(frame, "include");
228                 if (tmp_share.param_names[param_cnt] == NULL) {
229                                 result = WERR_NOMEM;
230                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
231                                                 win_errstr(result));
232                                 goto error;
233                 }
234
235                 tmp_share.param_values[param_cnt++] = talloc_strdup(frame, multi_s[i]);
236                 if (tmp_share.param_values[param_cnt - 1] == NULL) {
237                                 result = WERR_NOMEM;
238                                 d_fprintf(stderr, _("Failed to create share: %s\n"),
239                                                 win_errstr(result));
240                                 goto error;
241                 }
242         }
243
244         /* move everything to the main memory ctx */
245         for (i = 0; i < param_cnt; i++) {
246                 tmp_share.param_names[i] = talloc_move(mem_ctx, &tmp_share.param_names[i]);
247                 tmp_share.param_values[i] = talloc_move(mem_ctx, &tmp_share.param_values[i]);
248         }
249
250         tmp_share.name = talloc_move(mem_ctx, &tmp_share.name);
251         tmp_share.param_names = talloc_move(mem_ctx, &tmp_share.param_names);
252         tmp_share.param_values = talloc_move(mem_ctx, &tmp_share.param_values);
253         /* out parameter */
254         *share = tmp_share;
255 error:
256         /* close child */
257         dcerpc_winreg_CloseKey(b, frame, &child_hnd, &_werr);
258         *werr = result;
259         TALLOC_FREE(frame);
260         return status;
261 }
262
263 static int rpc_conf_print_shares(uint32_t num_shares,
264                                  struct smbconf_service *shares)
265 {
266
267         uint32_t share_count, param_count;
268         const char *indent = "\t";
269
270         if (num_shares == 0) {
271                 return 0;
272         }
273
274         for (share_count = 0; share_count < num_shares; share_count++) {
275                 d_printf("\n");
276                 if (shares[share_count].name != NULL) {
277                 d_printf("[%s]\n", shares[share_count].name);
278                 }
279
280                 for (param_count = 0;
281                      param_count < shares[share_count].num_params;
282                      param_count++)
283                 {
284                         d_printf("%s%s = %s\n",
285                                  indent,
286                                  shares[share_count].param_names[param_count],
287                                  shares[share_count].param_values[param_count]);
288                 }
289         }
290         d_printf("\n");
291
292         return 0;
293
294 }
295 static NTSTATUS rpc_conf_open_conf(TALLOC_CTX *mem_ctx,
296                                    struct dcerpc_binding_handle *b,
297                                    uint32_t access_mask,
298                                    struct policy_handle *hive_hnd,
299                                    struct policy_handle *key_hnd,
300                                    WERROR *werr)
301 {
302         TALLOC_CTX *frame = talloc_stackframe();
303         NTSTATUS status = NT_STATUS_OK;
304         WERROR result = WERR_OK;
305         WERROR _werr;
306         struct policy_handle tmp_hive_hnd, tmp_key_hnd;
307         struct winreg_String key;
308
309         ZERO_STRUCT(key);
310
311         status = dcerpc_winreg_OpenHKLM(b, frame, NULL,
312                         access_mask, &tmp_hive_hnd, &result);
313
314         /*
315          * print no error messages if it is a read only open
316          * and key does not exist
317          * error still gets returned
318          */
319
320         if (access_mask == REG_KEY_READ &&
321             W_ERROR_EQUAL(result, WERR_BADFILE))
322         {
323                 goto error;
324         }
325
326         if (!(NT_STATUS_IS_OK(status))) {
327                 d_fprintf(stderr, _("Failed to open hive: %s\n"),
328                                 nt_errstr(status));
329                 goto error;
330         }
331         if (!W_ERROR_IS_OK(result)) {
332                 d_fprintf(stderr, _("Failed to open hive: %s\n"),
333                                 win_errstr(result));
334                 goto error;
335         }
336
337         key.name = confpath;
338         status = dcerpc_winreg_OpenKey(b, frame, &tmp_hive_hnd, key, 0,
339                                        access_mask, &tmp_key_hnd, &result);
340
341         /*
342          * print no error messages if it is a read only open
343          * and key does not exist
344          * error still gets returned
345          */
346
347         if (access_mask == REG_KEY_READ &&
348             W_ERROR_EQUAL(result, WERR_BADFILE))
349         {
350                 goto error;
351         }
352
353         if (!(NT_STATUS_IS_OK(status))) {
354                 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
355                                 nt_errstr(status));
356                 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
357                 goto error;
358         }
359         if (!(W_ERROR_IS_OK(result))) {
360                 d_fprintf(stderr, _("Failed to open smbconf key: %s\n"),
361                         win_errstr(result));
362                 dcerpc_winreg_CloseKey(b, frame, &tmp_hive_hnd, &_werr);
363                 goto error;
364         }
365
366         *hive_hnd = tmp_hive_hnd;
367         *key_hnd = tmp_key_hnd;
368
369 error:
370         TALLOC_FREE(frame);
371         *werr = result;
372
373         return status;
374 }
375
376 static NTSTATUS rpc_conf_listshares_internal(struct net_context *c,
377                                              const struct dom_sid *domain_sid,
378                                              const char *domain_name,
379                                              struct cli_state *cli,
380                                              struct rpc_pipe_client *pipe_hnd,
381                                              TALLOC_CTX *mem_ctx,
382                                              int argc,
383                                              const char **argv )
384 {
385
386         TALLOC_CTX *frame = talloc_stackframe();
387         NTSTATUS status = NT_STATUS_OK;
388         WERROR werr = WERR_OK;
389         WERROR _werr;
390
391         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
392
393         /* key info */
394         struct policy_handle hive_hnd, key_hnd;
395         uint32_t num_subkeys;
396         uint32_t i;
397         const char **subkeys = NULL;
398
399
400         ZERO_STRUCT(hive_hnd);
401         ZERO_STRUCT(key_hnd);
402
403
404         if (argc != 0 || c->display_usage) {
405                 rpc_conf_listshares_usage(c, argc, argv);
406                 status = NT_STATUS_INVALID_PARAMETER;
407                 goto error;
408         }
409
410
411         status = rpc_conf_open_conf(frame,
412                                     b,
413                                     REG_KEY_READ,
414                                     &hive_hnd,
415                                     &key_hnd,
416                                     &werr);
417
418         if (!(NT_STATUS_IS_OK(status))) {
419                 goto error;
420         }
421
422         if (!(W_ERROR_IS_OK(werr))) {
423                 goto error;
424         }
425
426         status = dcerpc_winreg_enum_keys(frame,
427                                          b,
428                                          &key_hnd,
429                                          &num_subkeys,
430                                          &subkeys,
431                                          &werr);
432
433         if (!(NT_STATUS_IS_OK(status))) {
434                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
435                                 nt_errstr(status));
436                 goto error;
437         }
438
439         if (!(W_ERROR_IS_OK(werr))) {
440                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
441                                 win_errstr(werr));
442                 goto error;
443         }
444
445         for (i = 0; i < num_subkeys; i++) {
446                 d_printf("%s\n", subkeys[i]);
447         }
448
449 error:
450         if (!(W_ERROR_IS_OK(werr))) {
451                 status =  werror_to_ntstatus(werr);
452         }
453
454         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
455         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
456
457         TALLOC_FREE(frame);
458         return status;;
459 }
460
461 static NTSTATUS rpc_conf_delshare_internal(struct net_context *c,
462                                            const struct dom_sid *domain_sid,
463                                            const char *domain_name,
464                                            struct cli_state *cli,
465                                            struct rpc_pipe_client *pipe_hnd,
466                                            TALLOC_CTX *mem_ctx,
467                                            int argc,
468                                            const char **argv )
469 {
470
471         TALLOC_CTX *frame = talloc_stackframe();
472         NTSTATUS status = NT_STATUS_OK;
473         WERROR werr = WERR_OK;
474         WERROR _werr;
475
476         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
477
478         /* key info */
479         struct policy_handle hive_hnd, key_hnd;
480
481         ZERO_STRUCT(hive_hnd);
482         ZERO_STRUCT(key_hnd);
483
484
485         if (argc != 1 || c->display_usage) {
486                 rpc_conf_delshare_usage(c, argc, argv);
487                 status = NT_STATUS_INVALID_PARAMETER;
488                 goto error;
489         }
490
491         status = rpc_conf_open_conf(frame,
492                                     b,
493                                     REG_KEY_ALL,
494                                     &hive_hnd,
495                                     &key_hnd,
496                                     &werr);
497
498         if (!(NT_STATUS_IS_OK(status))) {
499                 goto error;
500         }
501
502         if (!(W_ERROR_IS_OK(werr))) {
503                 goto error;
504         }
505
506         status = dcerpc_winreg_delete_subkeys_recursive(frame,
507                                                         b,
508                                                         &key_hnd,
509                                                         REG_KEY_ALL,
510                                                         argv[0],
511                                                         &werr);
512
513         if (!NT_STATUS_IS_OK(status)) {
514                 d_fprintf(stderr,
515                           "winreg_delete_subkeys: Could not delete key %s: %s\n",
516                           argv[0], nt_errstr(status));
517                 goto error;
518         }
519
520         if (W_ERROR_EQUAL(werr, WERR_BADFILE)){
521                 d_fprintf(stderr, _("ERROR: Key does not exist\n"));
522         }
523
524
525         if (!W_ERROR_IS_OK(werr)) {
526                 d_fprintf(stderr,
527                           "winreg_delete_subkeys: Could not delete key %s: %s\n",
528                           argv[0], win_errstr(werr));
529                 goto error;
530         }
531
532 error:
533         if (!(W_ERROR_IS_OK(werr))) {
534                 status =  werror_to_ntstatus(werr);
535         }
536
537         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
538         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
539
540         TALLOC_FREE(frame);
541
542         return status;
543 }
544
545 static NTSTATUS rpc_conf_list_internal(struct net_context *c,
546                                        const struct dom_sid *domain_sid,
547                                        const char *domain_name,
548                                        struct cli_state *cli,
549                                        struct rpc_pipe_client *pipe_hnd,
550                                        TALLOC_CTX *mem_ctx,
551                                        int argc,
552                                        const char **argv )
553 {
554
555         TALLOC_CTX *frame = talloc_stackframe();
556         NTSTATUS status = NT_STATUS_OK;
557         WERROR werr = WERR_OK;
558         WERROR _werr;
559
560         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
561
562         /* key info */
563         struct policy_handle hive_hnd, key_hnd;
564         uint32_t num_subkeys;
565         uint32_t i;
566         struct smbconf_service *shares;
567         const char **subkeys = NULL;
568
569
570         ZERO_STRUCT(hive_hnd);
571         ZERO_STRUCT(key_hnd);
572
573
574         if (argc != 0 || c->display_usage) {
575                 rpc_conf_list_usage(c, argc, argv);
576                 status = NT_STATUS_INVALID_PARAMETER;
577                 goto error;
578         }
579
580         status = rpc_conf_open_conf(frame,
581                                     b,
582                                     REG_KEY_READ,
583                                     &hive_hnd,
584                                     &key_hnd,
585                                     &werr);
586
587         if (!(NT_STATUS_IS_OK(status))) {
588                 goto error;
589         }
590
591         if (!(W_ERROR_IS_OK(werr))) {
592                 goto error;
593         }
594
595         status = dcerpc_winreg_enum_keys(frame,
596                                          b,
597                                          &key_hnd,
598                                          &num_subkeys,
599                                          &subkeys,
600                                          &werr);
601
602         if (!(NT_STATUS_IS_OK(status))) {
603                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
604                                 nt_errstr(status));
605                 goto error;
606         }
607
608         if (!(W_ERROR_IS_OK(werr))) {
609                 d_fprintf(stderr, _("Failed to enumerate keys: %s\n"),
610                                 win_errstr(werr));
611                 goto error;
612         }
613
614         if (num_subkeys == 0) {
615                 dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
616                 dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
617                 TALLOC_FREE(frame);
618                 return NT_STATUS_OK;
619         }
620
621         /* get info from each subkey */
622         shares = talloc_zero_array(frame, struct smbconf_service, num_subkeys);
623         if (shares == NULL) {
624                 werr = WERR_NOMEM;
625                 d_fprintf(stderr, _("Failed to create shares: %s\n"),
626                                 win_errstr(werr));
627                 goto error;
628
629         }
630
631         for (i = 0; i < num_subkeys; i++) {
632                 /* get each share and place it in the shares array */
633                 status = rpc_conf_get_share(frame,
634                                 b,
635                                 &key_hnd,
636                                 subkeys[i],
637                                 &shares[i],
638                                 &werr);
639                 if (!(NT_STATUS_IS_OK(status))) {
640                         goto error;
641                 }
642                 if (!(W_ERROR_IS_OK(werr))) {
643                         goto error;
644                 }
645
646         }
647         /* print the shares array */
648         rpc_conf_print_shares(num_subkeys, shares);
649
650 error:
651         if (!(W_ERROR_IS_OK(werr))) {
652                 status =  werror_to_ntstatus(werr);
653         }
654
655         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
656         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
657
658         TALLOC_FREE(frame);
659         return status;
660
661 }
662
663 static NTSTATUS rpc_conf_drop_internal(struct net_context *c,
664                                        const struct dom_sid *domain_sid,
665                                        const char *domain_name,
666                                        struct cli_state *cli,
667                                        struct rpc_pipe_client *pipe_hnd,
668                                        TALLOC_CTX *mem_ctx,
669                                        int argc,
670                                        const char **argv )
671 {
672         TALLOC_CTX *frame = talloc_stackframe();
673         NTSTATUS status = NT_STATUS_OK;
674         WERROR werr = WERR_OK;
675         WERROR _werr;
676
677         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
678
679         /* key info */
680         struct policy_handle hive_hnd, key_hnd;
681         const char *keyname = confpath;
682         struct winreg_String wkey, wkeyclass;
683         enum winreg_CreateAction action = REG_ACTION_NONE;
684
685
686         ZERO_STRUCT(hive_hnd);
687         ZERO_STRUCT(key_hnd);
688
689
690         if (argc != 0 || c->display_usage) {
691                 rpc_conf_drop_usage(c, argc, argv);
692                 status = NT_STATUS_INVALID_PARAMETER;
693                 goto error;
694         }
695
696         status = rpc_conf_open_conf(frame,
697                                     b,
698                                     REG_KEY_ALL,
699                                     &hive_hnd,
700                                     &key_hnd,
701                                     &werr);
702
703         if (!(NT_STATUS_IS_OK(status))) {
704                 goto error;
705         }
706
707         if (!(W_ERROR_IS_OK(werr))) {
708                 goto error;
709         }
710
711         status = dcerpc_winreg_delete_subkeys_recursive(frame,
712                                                         b,
713                                                         &hive_hnd,
714                                                         REG_KEY_ALL,
715                                                         keyname,
716                                                         &werr);
717
718         if (!NT_STATUS_IS_OK(status)) {
719                 d_printf("winreg_delete_subkeys: Could not delete key %s: %s\n",
720                           keyname, nt_errstr(status));
721                 goto error;
722         }
723
724         if (!W_ERROR_IS_OK(werr)) {
725                 d_printf("winreg_delete_subkeys: Could not delete key %s: %s\n",
726                           keyname, win_errstr(werr));
727                 goto error;
728         }
729
730         wkey.name = keyname;
731         ZERO_STRUCT(wkeyclass);
732         wkeyclass.name = "";
733         action = REG_ACTION_NONE;
734
735         status = dcerpc_winreg_CreateKey(b,
736                                          frame,
737                                          &hive_hnd,
738                                          wkey,
739                                          wkeyclass,
740                                          0,
741                                          REG_KEY_ALL,
742                                          NULL,
743                                          &key_hnd,
744                                          &action,
745                                          &werr);
746
747         if (!NT_STATUS_IS_OK(status)) {
748                 d_printf("winreg_CreateKey: Could not create smbconf key\n");
749                 goto error;
750         }
751
752         if (!W_ERROR_IS_OK(werr)) {
753                 d_printf("winreg_CreateKey: Could not create smbconf key\n");
754                 goto error;
755         }
756
757
758 error:
759         if (!(W_ERROR_IS_OK(werr))) {
760                 status =  werror_to_ntstatus(werr);
761         }
762
763         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
764         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
765
766         TALLOC_FREE(frame);
767         return status;
768 }
769
770 static NTSTATUS rpc_conf_showshare_internal(struct net_context *c,
771                                             const struct dom_sid *domain_sid,
772                                             const char *domain_name,
773                                             struct cli_state *cli,
774                                             struct rpc_pipe_client *pipe_hnd,
775                                             TALLOC_CTX *mem_ctx,
776                                             int argc,
777                                             const char **argv )
778 {
779         TALLOC_CTX *frame = talloc_stackframe();
780         NTSTATUS status = NT_STATUS_OK;
781         WERROR werr = WERR_OK;
782         WERROR _werr;
783
784         struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
785
786         /* key info */
787         struct policy_handle hive_hnd, key_hnd;
788         struct smbconf_service *service = NULL;
789         const char *sharename = NULL;
790
791
792         ZERO_STRUCT(hive_hnd);
793         ZERO_STRUCT(key_hnd);
794
795
796         if (argc != 1 || c->display_usage) {
797                 rpc_conf_showshare_usage(c, argc, argv);
798                 status = NT_STATUS_INVALID_PARAMETER;
799                 goto error;
800         }
801
802         status = rpc_conf_open_conf(frame,
803                                     b,
804                                     REG_KEY_READ,
805                                     &hive_hnd,
806                                     &key_hnd,
807                                     &werr);
808
809         if (!(NT_STATUS_IS_OK(status))) {
810                 goto error;
811         }
812
813         if (!(W_ERROR_IS_OK(werr))) {
814                 goto error;
815         }
816
817         sharename = talloc_strdup(frame, argv[0]);
818         if (sharename == NULL) {
819                 werr = WERR_NOMEM;
820                 d_fprintf(stderr, _("Failed to create share: %s\n"),
821                                 win_errstr(werr));
822                 goto error;
823         }
824
825         service = talloc(frame, struct smbconf_service);
826         if (service == NULL) {
827                 werr = WERR_NOMEM;
828                 d_fprintf(stderr, _("Failed to create share: %s\n"),
829                                 win_errstr(werr));
830                 goto error;
831         }
832
833         status = rpc_conf_get_share(frame,
834                         b,
835                         &key_hnd,
836                         sharename,
837                         service,
838                         &werr);
839
840         if (!(NT_STATUS_IS_OK(status))) {
841                 goto error;
842         }
843         if (!(W_ERROR_IS_OK(werr))) {
844                 goto error;
845         }
846
847         rpc_conf_print_shares(1, service);
848
849 error:
850         if (!(W_ERROR_IS_OK(werr))) {
851                 status =  werror_to_ntstatus(werr);
852         }
853
854         dcerpc_winreg_CloseKey(b, frame, &hive_hnd, &_werr);
855         dcerpc_winreg_CloseKey(b, frame, &key_hnd, &_werr);
856
857         TALLOC_FREE(frame);
858         return status;
859 }
860
861 static int rpc_conf_drop(struct net_context *c, int argc,
862                                 const char **argv)
863 {
864         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
865                 rpc_conf_drop_internal, argc, argv );
866
867 }
868
869 static int rpc_conf_showshare(struct net_context *c, int argc,
870                                 const char **argv)
871 {
872         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
873                 rpc_conf_showshare_internal, argc, argv );
874 }
875
876 static int rpc_conf_listshares(struct net_context *c, int argc,
877                                 const char **argv)
878 {
879         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
880                 rpc_conf_listshares_internal, argc, argv );
881 }
882
883 static int rpc_conf_list(struct net_context *c, int argc,
884                              const char **argv)
885 {
886         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
887                 rpc_conf_list_internal, argc, argv );
888 }
889
890 static int rpc_conf_delshare(struct net_context *c, int argc,
891                              const char **argv)
892 {
893         return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
894                 rpc_conf_delshare_internal, argc, argv );
895 }
896
897 static int rpc_conf_getparm(struct net_context *c, int argc,
898                              const char **argv)
899 {
900
901         return 0;
902 }
903 /* function calls */
904 int net_rpc_conf(struct net_context *c, int argc,
905                  const char **argv)
906 {
907         struct functable func_table[] = {
908                 {
909                         "list",
910                         rpc_conf_list,
911                         NET_TRANSPORT_RPC,
912                         N_("Dump the complete remote configuration in smb.conf like "
913                            "format."),
914                         N_("net rpc conf list\n"
915                            "    Dump the complete remote configuration in smb.conf "
916                            "like format.")
917
918                 },
919                 {
920                         "listshares",
921                         rpc_conf_listshares,
922                         NET_TRANSPORT_RPC,
923                         N_("List the remote share names."),
924                         N_("net rpc conf list\n"
925                            "    List the remote share names.")
926
927                 },
928                 {
929                         "drop",
930                         rpc_conf_drop,
931                         NET_TRANSPORT_RPC,
932                         N_("Delete the complete remote configuration."),
933                         N_("net rpc conf drop\n"
934                            "    Delete the complete remote configuration.")
935
936                 },
937                 {
938                         "showshare",
939                         rpc_conf_showshare,
940                         NET_TRANSPORT_RPC,
941                         N_("Show the definition of a remote share."),
942                         N_("net rpc conf showshare\n"
943                            "    Show the definition of a remote share.")
944
945                 },
946                 {
947                         "delshare",
948                         rpc_conf_delshare,
949                         NET_TRANSPORT_RPC,
950                         N_("Delete a remote share."),
951                         N_("net rpc conf delshare\n"
952                            "    Delete a remote share.")
953                 },
954                 {
955                         "getparm",
956                         rpc_conf_getparm,
957                         NET_TRANSPORT_RPC,
958                         N_("Retrieve the value of a parameter."),
959                         N_("net rpc conf getparm\n"
960                            "    Retrieve the value of a parameter.")
961                 },
962                 {NULL, NULL, 0, NULL, NULL}
963         };
964
965         return net_run_function(c, argc, argv, "net rpc conf", func_table);
966
967 }