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