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