net conf: use the new smbconf_init() dispatcher instead of explicit backend init.
[ira/wip.git] / source3 / utils / net_conf.c
1 /*
2  *  Samba Unix/Linux SMB client library
3  *  Distributed SMB/CIFS Server Management Utility
4  *  Local configuration interface
5  *  Copyright (C) Michael Adam 2007-2008
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 as made available
23  * by the libsmbconf interface (source/lib/smbconf/smbconf.c).
24  *
25  * This currently supports local interaction with the configuration
26  * stored in the registry. But other backends and remote access via
27  * rpc might get implemented in the future.
28  */
29
30 #include "includes.h"
31 #include "utils/net.h"
32
33 /**********************************************************************
34  *
35  * usage functions
36  *
37  **********************************************************************/
38
39 static int net_conf_list_usage(int argc, const char **argv)
40 {
41         d_printf("USAGE: net conf list\n");
42         return -1;
43 }
44
45 static int net_conf_import_usage(int argc, const char**argv)
46 {
47         d_printf("USAGE: net conf import [--test|-T] <filename> "
48                  "[<servicename>]\n"
49                  "\t[--test|-T]    testmode - do not act, just print "
50                         "what would be done\n"
51                  "\t<servicename>  only import service <servicename>, "
52                         "ignore the rest\n");
53         return -1;
54 }
55
56 static int net_conf_listshares_usage(int argc, const char **argv)
57 {
58         d_printf("USAGE: net conf listshares\n");
59         return -1;
60 }
61
62 static int net_conf_drop_usage(int argc, const char **argv)
63 {
64         d_printf("USAGE: net conf drop\n");
65         return -1;
66 }
67
68 static int net_conf_showshare_usage(int argc, const char **argv)
69 {
70         d_printf("USAGE: net conf showshare <sharename>\n");
71         return -1;
72 }
73
74 static int net_conf_addshare_usage(int argc, const char **argv)
75 {
76         d_printf("USAGE: net conf addshare <sharename> <path> "
77                  "[writeable={y|N} [guest_ok={y|N} [<comment>]]\n"
78                  "\t<sharename>      the new share name.\n"
79                  "\t<path>           the path on the filesystem to export.\n"
80                  "\twriteable={y|N}  set \"writeable to \"yes\" or "
81                  "\"no\" (default) on this share.\n"
82                  "\tguest_ok={y|N}   set \"guest ok\" to \"yes\" or "
83                  "\"no\" (default)   on this share.\n"
84                  "\t<comment>        optional comment for the new share.\n");
85         return -1;
86 }
87
88 static int net_conf_delshare_usage(int argc, const char **argv)
89 {
90         d_printf("USAGE: net conf delshare <sharename>\n");
91         return -1;
92 }
93
94 static int net_conf_setparm_usage(int argc, const char **argv)
95 {
96         d_printf("USAGE: net conf setparm <section> <param> <value>\n");
97         return -1;
98 }
99
100 static int net_conf_getparm_usage(int argc, const char **argv)
101 {
102         d_printf("USAGE: net conf getparm <section> <param>\n");
103         return -1;
104 }
105
106 static int net_conf_delparm_usage(int argc, const char **argv)
107 {
108         d_printf("USAGE: net conf delparm <section> <param>\n");
109         return -1;
110 }
111
112 static int net_conf_getincludes_usage(int argc, const char **argv)
113 {
114         d_printf("USAGE: net conf getincludes <section>\n");
115         return -1;
116 }
117
118 static int net_conf_setincludes_usage(int argc, const char **argv)
119 {
120         d_printf("USAGE: net conf setincludes <section> [<filename>]*\n");
121         return -1;
122 }
123
124 static int net_conf_delincludes_usage(int argc, const char **argv)
125 {
126         d_printf("USAGE: net conf delincludes <section>\n");
127         return -1;
128 }
129
130
131 /**********************************************************************
132  *
133  * Helper functions
134  *
135  **********************************************************************/
136
137 /**
138  * This functions process a service previously loaded with libsmbconf.
139  */
140 static WERROR import_process_service(struct smbconf_ctx *conf_ctx,
141                                      const char *servicename,
142                                      const uint32_t num_params,
143                                      const char **param_names,
144                                      const char **param_values)
145 {
146         uint32_t idx;
147         WERROR werr = WERR_OK;
148         uint32_t num_includes = 0;
149         char **includes = NULL;
150         TALLOC_CTX *mem_ctx = talloc_stackframe();
151
152         if (opt_testmode) {
153                 d_printf("[%s]\n", servicename);
154                 for (idx = 0; idx < num_params; idx ++) {
155                         d_printf("\t%s = %s\n", param_names[idx],
156                                  param_values[idx]);
157                 }
158                 d_printf("\n");
159                 goto done;
160         }
161
162         if (smbconf_share_exists(conf_ctx, servicename)) {
163                 werr = smbconf_delete_share(conf_ctx, servicename);
164                 if (!W_ERROR_IS_OK(werr)) {
165                         goto done;
166                 }
167         }
168         werr = smbconf_create_share(conf_ctx, servicename);
169         if (!W_ERROR_IS_OK(werr)) {
170                 goto done;
171         }
172
173         for (idx = 0; idx < num_params; idx ++) {
174                 if (strequal(param_names[idx], "include")) {
175                         includes = TALLOC_REALLOC_ARRAY(mem_ctx,
176                                                         includes,
177                                                         char *,
178                                                         num_includes+1);
179                         if (includes == NULL) {
180                                 werr = WERR_NOMEM;
181                                 goto done;
182                         }
183                         includes[num_includes] = talloc_strdup(includes,
184                                                         param_values[idx]);
185                         if (includes[num_includes] == NULL) {
186                                 werr = WERR_NOMEM;
187                                 goto done;
188                         }
189                         num_includes++;
190                 } else {
191                         werr = smbconf_set_parameter(conf_ctx,
192                                                      servicename,
193                                                      param_names[idx],
194                                                      param_values[idx]);
195                         if (!W_ERROR_IS_OK(werr)) {
196                                 goto done;
197                         }
198                 }
199         }
200
201         werr = smbconf_set_includes(conf_ctx, servicename, num_includes,
202                                     (const char **)includes);
203
204 done:
205         TALLOC_FREE(mem_ctx);
206         return werr;
207 }
208
209
210 /**********************************************************************
211  *
212  * the main conf functions
213  *
214  **********************************************************************/
215
216 static int net_conf_list(struct smbconf_ctx *conf_ctx,
217                          int argc, const char **argv)
218 {
219         WERROR werr = WERR_OK;
220         int ret = -1;
221         TALLOC_CTX *mem_ctx;
222         uint32_t num_shares;
223         char **share_names;
224         uint32_t *num_params;
225         char ***param_names;
226         char ***param_values;
227         uint32_t share_count, param_count;
228
229         mem_ctx = talloc_stackframe();
230
231         if (argc != 0) {
232                 net_conf_list_usage(argc, argv);
233                 goto done;
234         }
235
236         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &share_names,
237                                   &num_params, &param_names, &param_values);
238         if (!W_ERROR_IS_OK(werr)) {
239                 d_fprintf(stderr, "Error getting config: %s\n",
240                           dos_errstr(werr));
241                 goto done;
242         }
243
244         for (share_count = 0; share_count < num_shares; share_count++) {
245                 d_printf("[%s]\n", share_names[share_count]);
246                 for (param_count = 0; param_count < num_params[share_count];
247                      param_count++)
248                 {
249                         d_printf("\t%s = %s\n",
250                                  param_names[share_count][param_count],
251                                  param_values[share_count][param_count]);
252                 }
253                 d_printf("\n");
254         }
255
256         ret = 0;
257
258 done:
259         TALLOC_FREE(mem_ctx);
260         return ret;
261 }
262
263 static int net_conf_import(struct smbconf_ctx *conf_ctx,
264                            int argc, const char **argv)
265 {
266         int ret = -1;
267         const char *filename = NULL;
268         const char *servicename = NULL;
269         char *conf_source = NULL;
270         TALLOC_CTX *mem_ctx;
271         struct smbconf_ctx *txt_ctx;
272         WERROR werr;
273
274         mem_ctx = talloc_stackframe();
275
276         switch (argc) {
277                 case 0:
278                 default:
279                         net_conf_import_usage(argc, argv);
280                         goto done;
281                 case 2:
282                         servicename = talloc_strdup_lower(mem_ctx, argv[1]);
283                         if (servicename == NULL) {
284                                 d_printf("error: out of memory!\n");
285                                 goto done;
286                         }
287                 case 1:
288                         filename = argv[0];
289                         break;
290         }
291
292         DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
293                 filename));
294
295         conf_source = talloc_asprintf(mem_ctx, "file:%s", filename);
296         if (conf_source == NULL) {
297                 d_printf("error: out of memory!\n");
298                 goto done;
299         }
300
301         werr = smbconf_init(mem_ctx, &txt_ctx, conf_source);
302         if (!W_ERROR_IS_OK(werr)) {
303                 d_printf("error loading file '%s': %s\n", filename,
304                          dos_errstr(werr));
305                 goto done;
306         }
307
308         if (opt_testmode) {
309                 d_printf("\nTEST MODE - "
310                          "would import the following configuration:\n\n");
311         }
312
313         if (servicename != NULL) {
314                 char **param_names, **param_values;
315                 uint32_t num_params;
316
317                 werr = smbconf_get_share(txt_ctx, mem_ctx,
318                                          servicename,
319                                          &num_params,
320                                          &param_names,
321                                          &param_values);
322                 if (!W_ERROR_IS_OK(werr)) {
323                         goto done;
324                 }
325                 werr = import_process_service(conf_ctx,
326                                               servicename,
327                                               num_params,
328                                               (const char **)param_names,
329                                               (const char **)param_values);
330                 if (!W_ERROR_IS_OK(werr)) {
331                         goto done;
332                 }
333         } else {
334                 char **share_names, ***param_names, ***param_values;
335                 uint32_t num_shares, *num_params, sidx;
336
337                 werr = smbconf_get_config(txt_ctx, mem_ctx,
338                                           &num_shares,
339                                           &share_names,
340                                           &num_params,
341                                           &param_names,
342                                           &param_values);
343                 if (!W_ERROR_IS_OK(werr)) {
344                         goto done;
345                 }
346                 if (!opt_testmode) {
347                         werr = smbconf_drop(conf_ctx);
348                         if (!W_ERROR_IS_OK(werr)) {
349                                 goto done;
350                         }
351                 }
352                 for (sidx = 0; sidx < num_shares; sidx++) {
353                         werr = import_process_service(conf_ctx,
354                                         share_names[sidx],
355                                         num_params[sidx],
356                                         (const char **)param_names[sidx],
357                                         (const char **)param_values[sidx]);
358                         if (!W_ERROR_IS_OK(werr)) {
359                                 goto done;
360                         }
361                 }
362         }
363
364         ret = 0;
365
366 done:
367         TALLOC_FREE(mem_ctx);
368         return ret;
369 }
370
371 static int net_conf_listshares(struct smbconf_ctx *conf_ctx,
372                                int argc, const char **argv)
373 {
374         WERROR werr = WERR_OK;
375         int ret = -1;
376         uint32_t count, num_shares = 0;
377         char **share_names = NULL;
378         TALLOC_CTX *mem_ctx;
379
380         mem_ctx = talloc_stackframe();
381
382         if (argc != 0) {
383                 net_conf_listshares_usage(argc, argv);
384                 goto done;
385         }
386
387         werr = smbconf_get_share_names(conf_ctx, mem_ctx, &num_shares,
388                                        &share_names);
389         if (!W_ERROR_IS_OK(werr)) {
390                 goto done;
391         }
392
393         for (count = 0; count < num_shares; count++)
394         {
395                 d_printf("%s\n", share_names[count]);
396         }
397
398         ret = 0;
399
400 done:
401         TALLOC_FREE(mem_ctx);
402         return ret;
403 }
404
405 static int net_conf_drop(struct smbconf_ctx *conf_ctx,
406                          int argc, const char **argv)
407 {
408         int ret = -1;
409         WERROR werr;
410
411         if (argc != 0) {
412                 net_conf_drop_usage(argc, argv);
413                 goto done;
414         }
415
416         werr = smbconf_drop(conf_ctx);
417         if (!W_ERROR_IS_OK(werr)) {
418                 d_fprintf(stderr, "Error deleting configuration: %s\n",
419                           dos_errstr(werr));
420                 goto done;
421         }
422
423         ret = 0;
424
425 done:
426         return ret;
427 }
428
429 static int net_conf_showshare(struct smbconf_ctx *conf_ctx,
430                               int argc, const char **argv)
431 {
432         int ret = -1;
433         WERROR werr = WERR_OK;
434         const char *sharename = NULL;
435         TALLOC_CTX *mem_ctx;
436         uint32_t num_params;
437         uint32_t count;
438         char **param_names;
439         char **param_values;
440
441         mem_ctx = talloc_stackframe();
442
443         if (argc != 1) {
444                 net_conf_showshare_usage(argc, argv);
445                 goto done;
446         }
447
448         sharename = talloc_strdup_lower(mem_ctx, argv[0]);
449         if (sharename == NULL) {
450                 d_printf("error: out of memory!\n");
451                 goto done;
452         }
453
454         werr = smbconf_get_share(conf_ctx, mem_ctx, sharename, &num_params,
455                                  &param_names, &param_values);
456         if (!W_ERROR_IS_OK(werr)) {
457                 d_printf("error getting share parameters: %s\n",
458                          dos_errstr(werr));
459                 goto done;
460         }
461
462         d_printf("[%s]\n", sharename);
463
464         for (count = 0; count < num_params; count++) {
465                 d_printf("\t%s = %s\n", param_names[count],
466                          param_values[count]);
467         }
468
469         ret = 0;
470
471 done:
472         TALLOC_FREE(mem_ctx);
473         return ret;
474 }
475
476 /**
477  * Add a share, with a couple of standard parameters, partly optional.
478  *
479  * This is a high level utility function of the net conf utility,
480  * not a direct frontend to the smbconf API.
481  */
482 static int net_conf_addshare(struct smbconf_ctx *conf_ctx,
483                              int argc, const char **argv)
484 {
485         int ret = -1;
486         WERROR werr = WERR_OK;
487         char *sharename = NULL;
488         const char *path = NULL;
489         const char *comment = NULL;
490         const char *guest_ok = "no";
491         const char *writeable = "no";
492         SMB_STRUCT_STAT sbuf;
493         TALLOC_CTX *mem_ctx = talloc_stackframe();
494
495         switch (argc) {
496                 case 0:
497                 case 1:
498                 default:
499                         net_conf_addshare_usage(argc, argv);
500                         goto done;
501                 case 5:
502                         comment = argv[4];
503                 case 4:
504                         if (!strnequal(argv[3], "guest_ok=", 9)) {
505                                 net_conf_addshare_usage(argc, argv);
506                                 goto done;
507                         }
508                         switch (argv[3][9]) {
509                                 case 'y':
510                                 case 'Y':
511                                         guest_ok = "yes";
512                                         break;
513                                 case 'n':
514                                 case 'N':
515                                         guest_ok = "no";
516                                         break;
517                                 default:
518                                         net_conf_addshare_usage(argc, argv);
519                                         goto done;
520                         }
521                 case 3:
522                         if (!strnequal(argv[2], "writeable=", 10)) {
523                                 net_conf_addshare_usage(argc, argv);
524                                 goto done;
525                         }
526                         switch (argv[2][10]) {
527                                 case 'y':
528                                 case 'Y':
529                                         writeable = "yes";
530                                         break;
531                                 case 'n':
532                                 case 'N':
533                                         writeable = "no";
534                                         break;
535                                 default:
536                                         net_conf_addshare_usage(argc, argv);
537                                         goto done;
538                         }
539                 case 2:
540                         path = argv[1];
541                         sharename = talloc_strdup_lower(mem_ctx, argv[0]);
542                         if (sharename == NULL) {
543                                 d_printf("error: out of memory!\n");
544                                 goto done;
545                         }
546
547                         break;
548         }
549
550         /*
551          * validate arguments
552          */
553
554         /* validate share name */
555
556         if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
557                                strlen(sharename)))
558         {
559                 d_fprintf(stderr, "ERROR: share name %s contains "
560                         "invalid characters (any of %s)\n",
561                         sharename, INVALID_SHARENAME_CHARS);
562                 goto done;
563         }
564
565         if (getpwnam(sharename)) {
566                 d_fprintf(stderr, "ERROR: share name %s is already a valid "
567                           "system user name.\n", sharename);
568                 goto done;
569         }
570
571         if (strequal(sharename, GLOBAL_NAME)) {
572                 d_fprintf(stderr,
573                           "ERROR: 'global' is not a valid share name.\n");
574                 goto done;
575         }
576
577         if (smbconf_share_exists(conf_ctx, sharename)) {
578                 d_fprintf(stderr, "ERROR: share %s already exists.\n",
579                           sharename);
580                 goto done;
581         }
582
583         /* validate path */
584
585         if (path[0] != '/') {
586                 d_fprintf(stderr,
587                           "Error: path '%s' is not an absolute path.\n",
588                           path);
589                 goto done;
590         }
591
592         if (sys_stat(path, &sbuf) != 0) {
593                 d_fprintf(stderr,
594                           "ERROR: cannot stat path '%s' to ensure "
595                           "this is a directory.\n"
596                           "Error was '%s'.\n",
597                           path, strerror(errno));
598                 goto done;
599         }
600
601         if (!S_ISDIR(sbuf.st_mode)) {
602                 d_fprintf(stderr,
603                           "ERROR: path '%s' is not a directory.\n",
604                           path);
605                 goto done;
606         }
607
608         /*
609          * create the share
610          */
611
612         werr = smbconf_create_share(conf_ctx, sharename);
613         if (!W_ERROR_IS_OK(werr)) {
614                 d_fprintf(stderr, "Error creating share %s: %s\n",
615                           sharename, dos_errstr(werr));
616                 goto done;
617         }
618
619         /*
620          * fill the share with parameters
621          */
622
623         werr = smbconf_set_parameter(conf_ctx, sharename, "path", path);
624         if (!W_ERROR_IS_OK(werr)) {
625                 d_fprintf(stderr, "Error setting parameter %s: %s\n",
626                           "path", dos_errstr(werr));
627                 goto done;
628         }
629
630         if (comment != NULL) {
631                 werr = smbconf_set_parameter(conf_ctx, sharename, "comment",
632                                              comment);
633                 if (!W_ERROR_IS_OK(werr)) {
634                         d_fprintf(stderr, "Error setting parameter %s: %s\n",
635                                   "comment", dos_errstr(werr));
636                         goto done;
637                 }
638         }
639
640         werr = smbconf_set_parameter(conf_ctx, sharename, "guest ok", guest_ok);
641         if (!W_ERROR_IS_OK(werr)) {
642                 d_fprintf(stderr, "Error setting parameter %s: %s\n",
643                           "'guest ok'", dos_errstr(werr));
644                 goto done;
645         }
646
647         werr = smbconf_set_parameter(conf_ctx, sharename, "writeable",
648                                      writeable);
649         if (!W_ERROR_IS_OK(werr)) {
650                 d_fprintf(stderr, "Error setting parameter %s: %s\n",
651                           "writeable", dos_errstr(werr));
652                 goto done;
653         }
654
655         ret = 0;
656
657 done:
658         TALLOC_FREE(mem_ctx);
659         return ret;
660 }
661
662 static int net_conf_delshare(struct smbconf_ctx *conf_ctx,
663                              int argc, const char **argv)
664 {
665         int ret = -1;
666         const char *sharename = NULL;
667         WERROR werr = WERR_OK;
668         TALLOC_CTX *mem_ctx = talloc_stackframe();
669
670         if (argc != 1) {
671                 net_conf_delshare_usage(argc, argv);
672                 goto done;
673         }
674         sharename = talloc_strdup_lower(mem_ctx, argv[0]);
675         if (sharename == NULL) {
676                 d_printf("error: out of memory!\n");
677                 goto done;
678         }
679
680         werr = smbconf_delete_share(conf_ctx, sharename);
681         if (!W_ERROR_IS_OK(werr)) {
682                 d_fprintf(stderr, "Error deleting share %s: %s\n",
683                           sharename, dos_errstr(werr));
684                 goto done;
685         }
686
687         ret = 0;
688 done:
689         TALLOC_FREE(mem_ctx);
690         return ret;
691 }
692
693 static int net_conf_setparm(struct smbconf_ctx *conf_ctx,
694                             int argc, const char **argv)
695 {
696         int ret = -1;
697         WERROR werr = WERR_OK;
698         char *service = NULL;
699         char *param = NULL;
700         const char *value_str = NULL;
701         TALLOC_CTX *mem_ctx = talloc_stackframe();
702
703         if (argc != 3) {
704                 net_conf_setparm_usage(argc, argv);
705                 goto done;
706         }
707         service = talloc_strdup_lower(mem_ctx, argv[0]);
708         if (service == NULL) {
709                 d_printf("error: out of memory!\n");
710                 goto done;
711         }
712         param = talloc_strdup_lower(mem_ctx, argv[1]);
713         if (param == NULL) {
714                 d_printf("error: out of memory!\n");
715                 goto done;
716         }
717         value_str = argv[2];
718
719         if (!smbconf_share_exists(conf_ctx, service)) {
720                 werr = smbconf_create_share(conf_ctx, service);
721                 if (!W_ERROR_IS_OK(werr)) {
722                         d_fprintf(stderr, "Error creating share '%s': %s\n",
723                                   service, dos_errstr(werr));
724                         goto done;
725                 }
726         }
727
728         werr = smbconf_set_parameter(conf_ctx, service, param, value_str);
729
730         if (!W_ERROR_IS_OK(werr)) {
731                 d_fprintf(stderr, "Error setting value '%s': %s\n",
732                           param, dos_errstr(werr));
733                 goto done;
734         }
735
736         ret = 0;
737
738 done:
739         TALLOC_FREE(mem_ctx);
740         return ret;
741 }
742
743 static int net_conf_getparm(struct smbconf_ctx *conf_ctx,
744                             int argc, const char **argv)
745 {
746         int ret = -1;
747         WERROR werr = WERR_OK;
748         char *service = NULL;
749         char *param = NULL;
750         char *valstr = NULL;
751         TALLOC_CTX *mem_ctx;
752
753         mem_ctx = talloc_stackframe();
754
755         if (argc != 2) {
756                 net_conf_getparm_usage(argc, argv);
757                 goto done;
758         }
759         service = talloc_strdup_lower(mem_ctx, argv[0]);
760         if (service == NULL) {
761                 d_printf("error: out of memory!\n");
762                 goto done;
763         }
764         param = talloc_strdup_lower(mem_ctx, argv[1]);
765         if (param == NULL) {
766                 d_printf("error: out of memory!\n");
767                 goto done;
768         }
769
770         werr = smbconf_get_parameter(conf_ctx, mem_ctx, service, param, &valstr);
771
772         if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
773                 d_fprintf(stderr,
774                           "Error: given service '%s' does not exist.\n",
775                           service);
776                 goto done;
777         } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
778                 d_fprintf(stderr,
779                           "Error: given parameter '%s' is not set.\n",
780                           param);
781                 goto done;
782         } else if (!W_ERROR_IS_OK(werr)) {
783                 d_fprintf(stderr, "Error getting value '%s': %s.\n",
784                           param, dos_errstr(werr));
785                 goto done;
786         }
787
788         d_printf("%s\n", valstr);
789
790         ret = 0;
791 done:
792         TALLOC_FREE(mem_ctx);
793         return ret;
794 }
795
796 static int net_conf_delparm(struct smbconf_ctx *conf_ctx,
797                             int argc, const char **argv)
798 {
799         int ret = -1;
800         WERROR werr = WERR_OK;
801         char *service = NULL;
802         char *param = NULL;
803         TALLOC_CTX *mem_ctx = talloc_stackframe();
804
805         if (argc != 2) {
806                 net_conf_delparm_usage(argc, argv);
807                 goto done;
808         }
809         service = talloc_strdup_lower(mem_ctx, argv[0]);
810         if (service == NULL) {
811                 d_printf("error: out of memory!\n");
812                 goto done;
813         }
814         param = talloc_strdup_lower(mem_ctx, argv[1]);
815         if (param == NULL) {
816                 d_printf("error: out of memory!\n");
817                 goto done;
818         }
819
820         werr = smbconf_delete_parameter(conf_ctx, service, param);
821
822         if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
823                 d_fprintf(stderr,
824                           "Error: given service '%s' does not exist.\n",
825                           service);
826                 goto done;
827         } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
828                 d_fprintf(stderr,
829                           "Error: given parameter '%s' is not set.\n",
830                           param);
831                 goto done;
832         } else if (!W_ERROR_IS_OK(werr)) {
833                 d_fprintf(stderr, "Error deleting value '%s': %s.\n",
834                           param, dos_errstr(werr));
835                 goto done;
836         }
837
838         ret = 0;
839
840 done:
841         TALLOC_FREE(mem_ctx);
842         return ret;
843 }
844
845 static int net_conf_getincludes(struct smbconf_ctx *conf_ctx,
846                                 int argc, const char **argv)
847 {
848         WERROR werr;
849         uint32_t num_includes;
850         uint32_t count;
851         char *service;
852         char **includes = NULL;
853         int ret = -1;
854         TALLOC_CTX *mem_ctx = talloc_stackframe();
855
856         if (argc != 1) {
857                 net_conf_getincludes_usage(argc, argv);
858                 goto done;
859         }
860
861         service = talloc_strdup_lower(mem_ctx, argv[0]);
862         if (service == NULL) {
863                 d_printf("error: out of memory!\n");
864                 goto done;
865         }
866
867         werr = smbconf_get_includes(conf_ctx, mem_ctx, service,
868                                     &num_includes, &includes);
869         if (!W_ERROR_IS_OK(werr)) {
870                 d_printf("error getting includes: %s\n", dos_errstr(werr));
871                 goto done;
872         }
873
874         for (count = 0; count < num_includes; count++) {
875                 d_printf("include = %s\n", includes[count]);
876         }
877
878         ret = 0;
879
880 done:
881         TALLOC_FREE(mem_ctx);
882         return ret;
883 }
884
885 static int net_conf_setincludes(struct smbconf_ctx *conf_ctx,
886                                 int argc, const char **argv)
887 {
888         WERROR werr;
889         char *service;
890         uint32_t num_includes;
891         const char **includes;
892         int ret = -1;
893         TALLOC_CTX *mem_ctx = talloc_stackframe();
894
895         if (argc < 1) {
896                 net_conf_setincludes_usage(argc, argv);
897                 goto done;
898         }
899
900         service = talloc_strdup_lower(mem_ctx, argv[0]);
901         if (service == NULL) {
902                 d_printf("error: out of memory!\n");
903                 goto done;
904         }
905
906         num_includes = argc - 1;
907         if (num_includes == 0) {
908                 includes = NULL;
909         } else {
910                 includes = argv + 1;
911         }
912
913         werr = smbconf_set_includes(conf_ctx, service, num_includes, includes);
914         if (!W_ERROR_IS_OK(werr)) {
915                 d_printf("error setting includes: %s\n", dos_errstr(werr));
916                 goto done;
917         }
918
919         ret = 0;
920
921 done:
922         TALLOC_FREE(mem_ctx);
923         return ret;
924 }
925
926 static int net_conf_delincludes(struct smbconf_ctx *conf_ctx,
927                                 int argc, const char **argv)
928 {
929         WERROR werr;
930         char *service;
931         int ret = -1;
932         TALLOC_CTX *mem_ctx = talloc_stackframe();
933
934         if (argc != 1) {
935                 net_conf_delincludes_usage(argc, argv);
936                 goto done;
937         }
938
939         service = talloc_strdup_lower(mem_ctx, argv[0]);
940         if (service == NULL) {
941                 d_printf("error: out of memory!\n");
942                 goto done;
943         }
944
945         werr = smbconf_delete_includes(conf_ctx, service);
946         if (!W_ERROR_IS_OK(werr)) {
947                 d_printf("error deleting includes: %s\n", dos_errstr(werr));
948                 goto done;
949         }
950
951         ret = 0;
952
953 done:
954         TALLOC_FREE(mem_ctx);
955         return ret;
956 }
957
958
959 /**********************************************************************
960  *
961  * Wrapper and net_conf_run_function mechanism.
962  *
963  **********************************************************************/
964
965 /**
966  * Wrapper function to call the main conf functions.
967  * The wrapper calls handles opening and closing of the
968  * configuration.
969  */
970 static int net_conf_wrap_function(int (*fn)(struct smbconf_ctx *,
971                                             int, const char **),
972                                   int argc, const char **argv)
973 {
974         WERROR werr;
975         TALLOC_CTX *mem_ctx = talloc_stackframe();
976         struct smbconf_ctx *conf_ctx;
977         int ret = -1;
978
979         werr = smbconf_init(mem_ctx, &conf_ctx, "registry:");
980
981         if (!W_ERROR_IS_OK(werr)) {
982                 return -1;
983         }
984
985         ret = fn(conf_ctx, argc, argv);
986
987         smbconf_shutdown(conf_ctx);
988
989         return ret;
990 }
991
992 /*
993  * We need a functable struct of our own, because the
994  * functions are called through a wrapper that handles
995  * the opening and closing of the configuration, and so on.
996  */
997 struct conf_functable {
998         const char *funcname;
999         int (*fn)(struct smbconf_ctx *ctx, int argc, const char **argv);
1000         const char *helptext;
1001 };
1002
1003 /**
1004  * This imitates net_run_function2 but calls the main functions
1005  * through the wrapper net_conf_wrap_function().
1006  */
1007 static int net_conf_run_function(int argc, const char **argv,
1008                                  const char *whoami,
1009                                  struct conf_functable *table)
1010 {
1011         int i;
1012
1013         if (argc != 0) {
1014                 for (i=0; table[i].funcname; i++) {
1015                         if (StrCaseCmp(argv[0], table[i].funcname) == 0)
1016                                 return net_conf_wrap_function(table[i].fn,
1017                                                               argc-1,
1018                                                               argv+1);
1019                 }
1020         }
1021
1022         for (i=0; table[i].funcname; i++) {
1023                 d_printf("%s %-15s %s\n", whoami, table[i].funcname,
1024                          table[i].helptext);
1025         }
1026
1027         return -1;
1028 }
1029
1030 /*
1031  * Entry-point for all the CONF functions.
1032  */
1033
1034 int net_conf(int argc, const char **argv)
1035 {
1036         int ret = -1;
1037         struct conf_functable func_table[] = {
1038                 {"list", net_conf_list,
1039                  "Dump the complete configuration in smb.conf like format."},
1040                 {"import", net_conf_import,
1041                  "Import configuration from file in smb.conf format."},
1042                 {"listshares", net_conf_listshares,
1043                  "List the share names."},
1044                 {"drop", net_conf_drop,
1045                  "Delete the complete configuration."},
1046                 {"showshare", net_conf_showshare,
1047                  "Show the definition of a share."},
1048                 {"addshare", net_conf_addshare,
1049                  "Create a new share."},
1050                 {"delshare", net_conf_delshare,
1051                  "Delete a share."},
1052                 {"setparm", net_conf_setparm,
1053                  "Store a parameter."},
1054                 {"getparm", net_conf_getparm,
1055                  "Retrieve the value of a parameter."},
1056                 {"delparm", net_conf_delparm,
1057                  "Delete a parameter."},
1058                 {"getincludes", net_conf_getincludes,
1059                  "Show the includes of a share definition."},
1060                 {"setincludes", net_conf_setincludes,
1061                  "Set includes for a share."},
1062                 {"delincludes", net_conf_delincludes,
1063                  "Delete includes from a share definition."},
1064                 {NULL, NULL, NULL}
1065         };
1066
1067         ret = net_conf_run_function(argc, argv, "net conf", func_table);
1068
1069         return ret;
1070 }
1071