s3:utils: Remove pointless if-clause for remote_machine
[samba.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 "system/filesys.h"
32 #include "utils/net.h"
33 #include "utils/net_conf_util.h"
34 #include "lib/smbconf/smbconf.h"
35 #include "lib/smbconf/smbconf_init.h"
36 #include "lib/smbconf/smbconf_reg.h"
37 #include "lib/param/loadparm.h"
38
39 /**********************************************************************
40  *
41  * usage functions
42  *
43  **********************************************************************/
44
45 static int net_conf_list_usage(struct net_context *c, int argc,
46                                const char **argv)
47 {
48         d_printf("%s net conf list\n", _("Usage:"));
49         return -1;
50 }
51
52 static int net_conf_import_usage(struct net_context *c, int argc,
53                                  const char**argv)
54 {
55         d_printf("%s\n%s",
56                  _("Usage:"),
57                  _(" net conf import [--test|-T] <filename> "
58                    "[<servicename>]\n"
59                    "\t[--test|-T]    testmode - do not act, just print "
60                         "what would be done\n"
61                    "\t<servicename>  only import service <servicename>, "
62                         "ignore the rest\n"));
63         return -1;
64 }
65
66 static int net_conf_listshares_usage(struct net_context *c, int argc,
67                                      const char **argv)
68 {
69         d_printf("%s\nnet conf listshares\n", _("Usage:"));
70         return -1;
71 }
72
73 static int net_conf_drop_usage(struct net_context *c, int argc,
74                                const char **argv)
75 {
76         d_printf("%s\nnet conf drop\n", _("Usage:"));
77         return -1;
78 }
79
80 static int net_conf_showshare_usage(struct net_context *c, int argc,
81                                     const char **argv)
82 {
83         d_printf("%s\n%s",
84                  _("Usage:"),
85                  _("net conf showshare <sharename>\n"));
86         return -1;
87 }
88
89 static int net_conf_addshare_usage(struct net_context *c, int argc,
90                                    const char **argv)
91 {
92         d_printf("%s\n%s",
93                  _("Usage:"),
94                  _(" net conf addshare <sharename> <path> "
95                    "[writeable={y|N} [guest_ok={y|N} [<comment>]]]\n"
96                    "\t<sharename>      the new share name.\n"
97                    "\t<path>           the path on the filesystem to export.\n"
98                    "\twriteable={y|N}  set \"writeable to \"yes\" or "
99                    "\"no\" (default) on this share.\n"
100                    "\tguest_ok={y|N}   set \"guest ok\" to \"yes\" or "
101                    "\"no\" (default)   on this share.\n"
102                    "\t<comment>        optional comment for the new share.\n"));
103         return -1;
104 }
105
106 static int net_conf_delshare_usage(struct net_context *c, int argc,
107                                    const char **argv)
108 {
109         d_printf("%s\n%s",
110                  _("Usage:"),
111                  _("net conf delshare <sharename>\n"));
112         return -1;
113 }
114
115 static int net_conf_setparm_usage(struct net_context *c, int argc,
116                                   const char **argv)
117 {
118         d_printf("%s\n%s",
119                  _("Usage:"),
120                  _(" net conf setparm <section> <param> <value>\n"));
121         return -1;
122 }
123
124 static int net_conf_getparm_usage(struct net_context *c, int argc,
125                                   const char **argv)
126 {
127         d_printf("%s\n%s",
128                  _("Usage:"),
129                  _(" net conf getparm <section> <param>\n"));
130         return -1;
131 }
132
133 static int net_conf_delparm_usage(struct net_context *c, int argc,
134                                   const char **argv)
135 {
136         d_printf("%s\n%s",
137                  _("Usage:"),
138                  _(" net conf delparm <section> <param>\n"));
139         return -1;
140 }
141
142 static int net_conf_getincludes_usage(struct net_context *c, int argc,
143                                       const char **argv)
144 {
145         d_printf("%s\n%s",
146                  _("Usage:"),
147                  _(" net conf getincludes <section>\n"));
148         return -1;
149 }
150
151 static int net_conf_setincludes_usage(struct net_context *c, int argc,
152                                       const char **argv)
153 {
154         d_printf("%s\n%s",
155                  _("Usage:"),
156                  _(" net conf setincludes <section> [<filename>]*\n"));
157         return -1;
158 }
159
160 static int net_conf_delincludes_usage(struct net_context *c, int argc,
161                                       const char **argv)
162 {
163         d_printf("%s\n%s",
164                 _("Usage:"),
165                 _(" net conf delincludes <section>\n"));
166         return -1;
167 }
168
169
170 /**********************************************************************
171  *
172  * Helper functions
173  *
174  **********************************************************************/
175
176 /**
177  * This functions process a service previously loaded with libsmbconf.
178  */
179 static sbcErr import_process_service(struct net_context *c,
180                                      struct smbconf_ctx *conf_ctx,
181                                      struct smbconf_service *service)
182 {
183         sbcErr err = SBC_ERR_OK;
184
185         if (c->opt_testmode) {
186                 uint32_t idx;
187                 const char *indent = "";
188                 if (service->name != NULL) {
189                         d_printf("[%s]\n", service->name);
190                         indent = "\t";
191                 }
192                 for (idx = 0; idx < service->num_params; idx++) {
193                         d_printf("%s%s = %s\n", indent,
194                                  service->param_names[idx],
195                                  service->param_values[idx]);
196                 }
197                 d_printf("\n");
198                 goto done;
199         }
200
201         if (smbconf_share_exists(conf_ctx, service->name)) {
202                 err = smbconf_delete_share(conf_ctx, service->name);
203                 if (!SBC_ERROR_IS_OK(err)) {
204                         goto done;
205                 }
206         }
207
208         err = smbconf_create_set_share(conf_ctx, service);
209
210 done:
211         return err;
212 }
213
214
215 /**********************************************************************
216  *
217  * the main conf functions
218  *
219  **********************************************************************/
220
221 static int net_conf_list(struct net_context *c, struct smbconf_ctx *conf_ctx,
222                          int argc, const char **argv)
223 {
224         sbcErr err;
225         int ret = -1;
226         TALLOC_CTX *mem_ctx;
227         uint32_t num_shares;
228         uint32_t share_count, param_count;
229         struct smbconf_service **shares = NULL;
230
231         mem_ctx = talloc_stackframe();
232
233         if (argc != 0 || c->display_usage) {
234                 net_conf_list_usage(c, argc, argv);
235                 goto done;
236         }
237
238         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &shares);
239         if (!SBC_ERROR_IS_OK(err)) {
240                 d_fprintf(stderr, _("Error getting config: %s\n"),
241                           sbcErrorString(err));
242                 goto done;
243         }
244
245         for (share_count = 0; share_count < num_shares; share_count++) {
246                 const char *indent = "";
247                 if (shares[share_count]->name != NULL) {
248                         d_printf("[%s]\n", shares[share_count]->name);
249                         indent = "\t";
250                 }
251                 for (param_count = 0;
252                      param_count < shares[share_count]->num_params;
253                      param_count++)
254                 {
255                         d_printf("%s%s = %s\n",
256                                  indent,
257                                  shares[share_count]->param_names[param_count],
258                                  shares[share_count]->param_values[param_count]);
259                 }
260                 d_printf("\n");
261         }
262
263         ret = 0;
264
265 done:
266         TALLOC_FREE(mem_ctx);
267         return ret;
268 }
269
270 static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
271                            int argc, const char **argv)
272 {
273         int ret = -1;
274         const char *filename = NULL;
275         const char *servicename = NULL;
276         char *conf_source = NULL;
277         TALLOC_CTX *mem_ctx;
278         struct smbconf_ctx *txt_ctx;
279         sbcErr err;
280
281         if (c->display_usage)
282                 return net_conf_import_usage(c, argc, argv);
283
284         mem_ctx = talloc_stackframe();
285
286         switch (argc) {
287                 case 0:
288                 default:
289                         net_conf_import_usage(c, argc, argv);
290                         goto done;
291                 case 2:
292                         servicename = talloc_strdup(mem_ctx, argv[1]);
293                         if (servicename == NULL) {
294                                 d_printf(_("error: out of memory!\n"));
295                                 goto done;
296                         }
297                 case 1:
298                         filename = argv[0];
299                         break;
300         }
301
302         DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
303                 filename));
304
305         conf_source = talloc_asprintf(mem_ctx, "file:%s", filename);
306         if (conf_source == NULL) {
307                 d_printf(_("error: out of memory!\n"));
308                 goto done;
309         }
310
311         err = smbconf_init(mem_ctx, &txt_ctx, conf_source);
312         if (!SBC_ERROR_IS_OK(err)) {
313                 d_printf(_("error loading file '%s': %s\n"), filename,
314                          sbcErrorString(err));
315                 goto done;
316         }
317
318         if (c->opt_testmode) {
319                 d_printf(_("\nTEST MODE - "
320                          "would import the following configuration:\n\n"));
321         }
322
323         if (servicename != NULL) {
324                 struct smbconf_service *service = NULL;
325
326                 err = smbconf_get_share(txt_ctx, mem_ctx,
327                                         servicename,
328                                         &service);
329                 if (!SBC_ERROR_IS_OK(err)) {
330                         goto cancel;
331                 }
332
333                 err = smbconf_transaction_start(conf_ctx);
334                 if (!SBC_ERROR_IS_OK(err)) {
335                         d_printf(_("error starting transaction: %s\n"),
336                                  sbcErrorString(err));
337                         goto done;
338                 }
339
340                 err = import_process_service(c, conf_ctx, service);
341                 if (!SBC_ERROR_IS_OK(err)) {
342                         d_printf(_("error importing service %s: %s\n"),
343                                  servicename, sbcErrorString(err));
344                         goto cancel;
345                 }
346         } else {
347                 struct smbconf_service **services = NULL;
348                 uint32_t num_shares, sidx;
349
350                 err = smbconf_get_config(txt_ctx, mem_ctx,
351                                           &num_shares,
352                                           &services);
353                 if (!SBC_ERROR_IS_OK(err)) {
354                         goto cancel;
355                 }
356                 if (!c->opt_testmode) {
357                         if (!SBC_ERROR_IS_OK(smbconf_drop(conf_ctx))) {
358                                 goto cancel;
359                         }
360                 }
361
362                 /*
363                  * Wrap the importing of shares into a transaction,
364                  * but only 100 at a time, in order to save memory.
365                  * The allocated memory accumulates across the actions
366                  * within the transaction, and for me, some 1500
367                  * imported shares, the MAX_TALLOC_SIZE of 256 MB
368                  * was exceeded.
369                  */
370                 err = smbconf_transaction_start(conf_ctx);
371                 if (!SBC_ERROR_IS_OK(err)) {
372                         d_printf(_("error starting transaction: %s\n"),
373                                  sbcErrorString(err));
374                         goto done;
375                 }
376
377                 for (sidx = 0; sidx < num_shares; sidx++) {
378                         err = import_process_service(c, conf_ctx,
379                                                      services[sidx]);
380                         if (!SBC_ERROR_IS_OK(err)) {
381                                 d_printf(_("error importing service %s: %s\n"),
382                                          services[sidx]->name,
383                                          sbcErrorString(err));
384                                 goto cancel;
385                         }
386
387                         if (sidx % 100) {
388                                 continue;
389                         }
390
391                         err = smbconf_transaction_commit(conf_ctx);
392                         if (!SBC_ERROR_IS_OK(err)) {
393                                 d_printf(_("error committing transaction: "
394                                            "%s\n"),
395                                          sbcErrorString(err));
396                                 goto done;
397                         }
398                         err = smbconf_transaction_start(conf_ctx);
399                         if (!SBC_ERROR_IS_OK(err)) {
400                                 d_printf(_("error starting transaction: %s\n"),
401                                          sbcErrorString(err));
402                                 goto done;
403                         }
404                 }
405         }
406
407         err = smbconf_transaction_commit(conf_ctx);
408         if (!SBC_ERROR_IS_OK(err)) {
409                 d_printf(_("error committing transaction: %s\n"),
410                          sbcErrorString(err));
411         } else {
412                 ret = 0;
413         }
414
415         goto done;
416
417 cancel:
418         err = smbconf_transaction_cancel(conf_ctx);
419         if (!SBC_ERROR_IS_OK(err)) {
420                 d_printf(_("error cancelling transaction: %s\n"),
421                          sbcErrorString(err));
422         }
423
424 done:
425         TALLOC_FREE(mem_ctx);
426         return ret;
427 }
428
429 static int net_conf_listshares(struct net_context *c,
430                                struct smbconf_ctx *conf_ctx, int argc,
431                                const char **argv)
432 {
433         sbcErr err;
434         int ret = -1;
435         uint32_t count, num_shares = 0;
436         char **share_names = NULL;
437         TALLOC_CTX *mem_ctx;
438
439         mem_ctx = talloc_stackframe();
440
441         if (argc != 0 || c->display_usage) {
442                 net_conf_listshares_usage(c, argc, argv);
443                 goto done;
444         }
445
446         err = smbconf_get_share_names(conf_ctx, mem_ctx, &num_shares,
447                                       &share_names);
448         if (!SBC_ERROR_IS_OK(err)) {
449                 goto done;
450         }
451
452         for (count = 0; count < num_shares; count++)
453         {
454                 d_printf("%s\n", share_names[count]);
455         }
456
457         ret = 0;
458
459 done:
460         TALLOC_FREE(mem_ctx);
461         return ret;
462 }
463
464 static int net_conf_drop(struct net_context *c, struct smbconf_ctx *conf_ctx,
465                          int argc, const char **argv)
466 {
467         int ret = -1;
468         sbcErr err;
469
470         if (argc != 0 || c->display_usage) {
471                 net_conf_drop_usage(c, argc, argv);
472                 goto done;
473         }
474
475         err = smbconf_drop(conf_ctx);
476         if (!SBC_ERROR_IS_OK(err)) {
477                 d_fprintf(stderr, _("Error deleting configuration: %s\n"),
478                           sbcErrorString(err));
479                 goto done;
480         }
481
482         ret = 0;
483
484 done:
485         return ret;
486 }
487
488 static int net_conf_showshare(struct net_context *c,
489                               struct smbconf_ctx *conf_ctx, int argc,
490                               const char **argv)
491 {
492         int ret = -1;
493         sbcErr err;
494         const char *sharename = NULL;
495         TALLOC_CTX *mem_ctx;
496         uint32_t count;
497         struct smbconf_service *service = NULL;
498
499         mem_ctx = talloc_stackframe();
500
501         if (argc != 1 || c->display_usage) {
502                 net_conf_showshare_usage(c, argc, argv);
503                 goto done;
504         }
505
506         sharename = talloc_strdup(mem_ctx, argv[0]);
507         if (sharename == NULL) {
508                 d_printf("error: out of memory!\n");
509                 goto done;
510         }
511
512         err = smbconf_get_share(conf_ctx, mem_ctx, sharename, &service);
513         if (!SBC_ERROR_IS_OK(err)) {
514                 d_printf(_("error getting share parameters: %s\n"),
515                          sbcErrorString(err));
516                 goto done;
517         }
518
519         d_printf("[%s]\n", service->name);
520
521         for (count = 0; count < service->num_params; count++) {
522                 d_printf("\t%s = %s\n", service->param_names[count],
523                          service->param_values[count]);
524         }
525
526         ret = 0;
527
528 done:
529         TALLOC_FREE(mem_ctx);
530         return ret;
531 }
532
533 /**
534  * Add a share, with a couple of standard parameters, partly optional.
535  *
536  * This is a high level utility function of the net conf utility,
537  * not a direct frontend to the smbconf API.
538  */
539 static int net_conf_addshare(struct net_context *c,
540                              struct smbconf_ctx *conf_ctx, int argc,
541                              const char **argv)
542 {
543         int ret = -1;
544         sbcErr err;
545         char *sharename = NULL;
546         const char *path = NULL;
547         const char *comment = NULL;
548         const char *guest_ok = "no";
549         const char *writeable = "no";
550         TALLOC_CTX *mem_ctx = talloc_stackframe();
551
552         if (c->display_usage) {
553                 net_conf_addshare_usage(c, argc, argv);
554                 ret = 0;
555                 goto done;
556         }
557
558         switch (argc) {
559                 case 0:
560                 case 1:
561                 default:
562                         net_conf_addshare_usage(c, argc, argv);
563                         goto done;
564                 case 5:
565                         comment = argv[4];
566                 case 4:
567                         if (!strnequal(argv[3], "guest_ok=", 9)) {
568                                 net_conf_addshare_usage(c, argc, argv);
569                                 goto done;
570                         }
571                         switch (argv[3][9]) {
572                                 case 'y':
573                                 case 'Y':
574                                         guest_ok = "yes";
575                                         break;
576                                 case 'n':
577                                 case 'N':
578                                         guest_ok = "no";
579                                         break;
580                                 default:
581                                         net_conf_addshare_usage(c, argc, argv);
582                                         goto done;
583                         }
584                 case 3:
585                         if (!strnequal(argv[2], "writeable=", 10)) {
586                                 net_conf_addshare_usage(c, argc, argv);
587                                 goto done;
588                         }
589                         switch (argv[2][10]) {
590                                 case 'y':
591                                 case 'Y':
592                                         writeable = "yes";
593                                         break;
594                                 case 'n':
595                                 case 'N':
596                                         writeable = "no";
597                                         break;
598                                 default:
599                                         net_conf_addshare_usage(c, argc, argv);
600                                         goto done;
601                         }
602                 case 2:
603                         path = argv[1];
604                         sharename = talloc_strdup(mem_ctx, argv[0]);
605                         if (sharename == NULL) {
606                                 d_printf(_("error: out of memory!\n"));
607                                 goto done;
608                         }
609
610                         break;
611         }
612
613         /*
614          * validate arguments
615          */
616
617         /* validate share name */
618
619         if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
620                                strlen(sharename)))
621         {
622                 d_fprintf(stderr, _("ERROR: share name %s contains "
623                         "invalid characters (any of %s)\n"),
624                         sharename, INVALID_SHARENAME_CHARS);
625                 goto done;
626         }
627
628         if (strequal(sharename, GLOBAL_NAME)) {
629                 d_fprintf(stderr,
630                           _("ERROR: 'global' is not a valid share name.\n"));
631                 goto done;
632         }
633
634         if (smbconf_share_exists(conf_ctx, sharename)) {
635                 d_fprintf(stderr, _("ERROR: share %s already exists.\n"),
636                           sharename);
637                 goto done;
638         }
639
640         /* validate path */
641
642         if (path[0] != '/') {
643                 d_fprintf(stderr,
644                           _("Error: path '%s' is not an absolute path.\n"),
645                           path);
646                 goto done;
647         }
648
649         /*
650          * start a transaction
651          */
652
653         err = smbconf_transaction_start(conf_ctx);
654         if (!SBC_ERROR_IS_OK(err)) {
655                 d_printf("error starting transaction: %s\n",
656                          sbcErrorString(err));
657                 goto done;
658         }
659
660         /*
661          * create the share
662          */
663
664         err = smbconf_create_share(conf_ctx, sharename);
665         if (!SBC_ERROR_IS_OK(err)) {
666                 d_fprintf(stderr, _("Error creating share %s: %s\n"),
667                           sharename, sbcErrorString(err));
668                 goto cancel;
669         }
670
671         /*
672          * fill the share with parameters
673          */
674
675         err = smbconf_set_parameter(conf_ctx, sharename, "path", path);
676         if (!SBC_ERROR_IS_OK(err)) {
677                 d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
678                           "path", sbcErrorString(err));
679                 goto cancel;
680         }
681
682         if (comment != NULL) {
683                 err = smbconf_set_parameter(conf_ctx, sharename, "comment",
684                                             comment);
685                 if (!SBC_ERROR_IS_OK(err)) {
686                         d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
687                                   "comment", sbcErrorString(err));
688                         goto cancel;
689                 }
690         }
691
692         err = smbconf_set_parameter(conf_ctx, sharename, "guest ok", guest_ok);
693         if (!SBC_ERROR_IS_OK(err)) {
694                 d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
695                           "'guest ok'", sbcErrorString(err));
696                 goto cancel;
697         }
698
699         err = smbconf_set_parameter(conf_ctx, sharename, "writeable",
700                                     writeable);
701         if (!SBC_ERROR_IS_OK(err)) {
702                 d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
703                           "writeable", sbcErrorString(err));
704                 goto cancel;
705         }
706
707         /*
708          * commit the whole thing
709          */
710
711         err = smbconf_transaction_commit(conf_ctx);
712         if (!SBC_ERROR_IS_OK(err)) {
713                 d_printf("error committing transaction: %s\n",
714                          sbcErrorString(err));
715         } else {
716                 ret = 0;
717         }
718
719         goto done;
720
721 cancel:
722         err = smbconf_transaction_cancel(conf_ctx);
723         if (!SBC_ERROR_IS_OK(err)) {
724                 d_printf("error cancelling transaction: %s\n",
725                          sbcErrorString(err));
726         }
727
728 done:
729         TALLOC_FREE(mem_ctx);
730         return ret;
731 }
732
733 static int net_conf_delshare(struct net_context *c,
734                              struct smbconf_ctx *conf_ctx, int argc,
735                              const char **argv)
736 {
737         int ret = -1;
738         const char *sharename = NULL;
739         sbcErr err;
740         TALLOC_CTX *mem_ctx = talloc_stackframe();
741
742         if (argc != 1 || c->display_usage) {
743                 net_conf_delshare_usage(c, argc, argv);
744                 goto done;
745         }
746         sharename = talloc_strdup(mem_ctx, argv[0]);
747         if (sharename == NULL) {
748                 d_printf(_("error: out of memory!\n"));
749                 goto done;
750         }
751
752         err = smbconf_delete_share(conf_ctx, sharename);
753         if (!SBC_ERROR_IS_OK(err)) {
754                 d_fprintf(stderr, _("Error deleting share %s: %s\n"),
755                           sharename, sbcErrorString(err));
756                 goto done;
757         }
758
759         ret = 0;
760 done:
761         TALLOC_FREE(mem_ctx);
762         return ret;
763 }
764
765 static int net_conf_setparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
766                             int argc, const char **argv)
767 {
768         int ret = -1;
769         sbcErr err;
770         char *service = NULL;
771         char *param = NULL;
772         const char *value_str = NULL;
773         TALLOC_CTX *mem_ctx = talloc_stackframe();
774
775         if (argc != 3 || c->display_usage) {
776                 net_conf_setparm_usage(c, argc, argv);
777                 goto done;
778         }
779         /*
780          * NULL service name means "dangling parameters" to libsmbconf.
781          * We use the empty string from the command line for this purpose.
782          */
783         if (strlen(argv[0]) != 0) {
784                 service = talloc_strdup(mem_ctx, argv[0]);
785                 if (service == NULL) {
786                         d_printf(_("error: out of memory!\n"));
787                         goto done;
788                 }
789         }
790         param = strlower_talloc(mem_ctx, argv[1]);
791         if (param == NULL) {
792                 d_printf(_("error: out of memory!\n"));
793                 goto done;
794         }
795         value_str = argv[2];
796
797         if (!net_conf_param_valid(service,param, value_str)) {
798                 goto done;
799         }
800
801         err = smbconf_transaction_start(conf_ctx);
802         if (!SBC_ERROR_IS_OK(err)) {
803                 d_printf(_("error starting transaction: %s\n"),
804                          sbcErrorString(err));
805                 goto done;
806         }
807
808         if (!smbconf_share_exists(conf_ctx, service)) {
809                 err = smbconf_create_share(conf_ctx, service);
810                 if (!SBC_ERROR_IS_OK(err)) {
811                         d_fprintf(stderr, _("Error creating share '%s': %s\n"),
812                                   service, sbcErrorString(err));
813                         goto cancel;
814                 }
815         }
816
817         err = smbconf_set_parameter(conf_ctx, service, param, value_str);
818         if (!SBC_ERROR_IS_OK(err)) {
819                 d_fprintf(stderr, _("Error setting value '%s': %s\n"),
820                           param, sbcErrorString(err));
821                 goto cancel;
822         }
823
824         err = smbconf_transaction_commit(conf_ctx);
825         if (!SBC_ERROR_IS_OK(err)) {
826                 d_printf(_("error committing transaction: %s\n"),
827                          sbcErrorString(err));
828         } else {
829                 ret = 0;
830         }
831
832         goto done;
833
834 cancel:
835         err = smbconf_transaction_cancel(conf_ctx);
836         if (!SBC_ERROR_IS_OK(err)) {
837                 d_printf(_("error cancelling transaction: %s\n"),
838                          sbcErrorString(err));
839         }
840
841 done:
842         TALLOC_FREE(mem_ctx);
843         return ret;
844 }
845
846 static int net_conf_getparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
847                             int argc, const char **argv)
848 {
849         int ret = -1;
850         sbcErr err;
851         char *service = NULL;
852         char *param = NULL;
853         char *valstr = NULL;
854         TALLOC_CTX *mem_ctx;
855
856         mem_ctx = talloc_stackframe();
857
858         if (argc != 2 || c->display_usage) {
859                 net_conf_getparm_usage(c, argc, argv);
860                 goto done;
861         }
862         /*
863          * NULL service name means "dangling parameters" to libsmbconf.
864          * We use the empty string from the command line for this purpose.
865          */
866         if (strlen(argv[0]) != 0) {
867                 service = talloc_strdup(mem_ctx, argv[0]);
868                 if (service == NULL) {
869                         d_printf(_("error: out of memory!\n"));
870                         goto done;
871                 }
872         }
873         param = strlower_talloc(mem_ctx, argv[1]);
874         if (param == NULL) {
875                 d_printf(_("error: out of memory!\n"));
876                 goto done;
877         }
878
879         err = smbconf_get_parameter(conf_ctx, mem_ctx, service, param, &valstr);
880         if (SBC_ERROR_EQUAL(err, SBC_ERR_NO_SUCH_SERVICE)) {
881                 d_fprintf(stderr,
882                           _("Error: given service '%s' does not exist.\n"),
883                           service);
884                 goto done;
885         } else if (SBC_ERROR_EQUAL(err, SBC_ERR_INVALID_PARAM)) {
886                 d_fprintf(stderr,
887                           _("Error: given parameter '%s' is not set.\n"),
888                           param);
889                 goto done;
890         } else if (!SBC_ERROR_IS_OK(err)) {
891                 d_fprintf(stderr, _("Error getting value '%s': %s.\n"),
892                           param, sbcErrorString(err));
893                 goto done;
894         }
895
896         d_printf("%s\n", valstr);
897
898         ret = 0;
899 done:
900         TALLOC_FREE(mem_ctx);
901         return ret;
902 }
903
904 static int net_conf_delparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
905                             int argc, const char **argv)
906 {
907         int ret = -1;
908         sbcErr err;
909         char *service = NULL;
910         char *param = NULL;
911         TALLOC_CTX *mem_ctx = talloc_stackframe();
912
913         if (argc != 2 || c->display_usage) {
914                 net_conf_delparm_usage(c, argc, argv);
915                 goto done;
916         }
917         /*
918          * NULL service name means "dangling parameters" to libsmbconf.
919          * We use the empty string from the command line for this purpose.
920          */
921         if (strlen(argv[0]) != 0) {
922                 service = talloc_strdup(mem_ctx, argv[0]);
923                 if (service == NULL) {
924                         d_printf(_("error: out of memory!\n"));
925                         goto done;
926                 }
927         }
928         param = strlower_talloc(mem_ctx, argv[1]);
929         if (param == NULL) {
930                 d_printf("error: out of memory!\n");
931                 goto done;
932         }
933
934         err = smbconf_delete_parameter(conf_ctx, service, param);
935         if (SBC_ERROR_EQUAL(err, SBC_ERR_NO_SUCH_SERVICE)) {
936                 d_fprintf(stderr,
937                           _("Error: given service '%s' does not exist.\n"),
938                           service);
939                 goto done;
940         } else if (SBC_ERROR_EQUAL(err, SBC_ERR_INVALID_PARAM)) {
941                 d_fprintf(stderr,
942                           _("Error: given parameter '%s' is not set.\n"),
943                           param);
944                 goto done;
945         } else if (!SBC_ERROR_IS_OK(err)) {
946                 d_fprintf(stderr, _("Error deleting value '%s': %s.\n"),
947                           param, sbcErrorString(err));
948                 goto done;
949         }
950
951         ret = 0;
952
953 done:
954         TALLOC_FREE(mem_ctx);
955         return ret;
956 }
957
958 static int net_conf_getincludes(struct net_context *c,
959                                 struct smbconf_ctx *conf_ctx,
960                                 int argc, const char **argv)
961 {
962         sbcErr err;
963         uint32_t num_includes;
964         uint32_t count;
965         char *service;
966         char **includes = NULL;
967         int ret = -1;
968         TALLOC_CTX *mem_ctx = talloc_stackframe();
969
970         if (argc != 1 || c->display_usage) {
971                 net_conf_getincludes_usage(c, argc, argv);
972                 goto done;
973         }
974
975         service = talloc_strdup(mem_ctx, argv[0]);
976         if (service == NULL) {
977                 d_printf(_("error: out of memory!\n"));
978                 goto done;
979         }
980
981         err = smbconf_get_includes(conf_ctx, mem_ctx, service,
982                                     &num_includes, &includes);
983         if (!SBC_ERROR_IS_OK(err)) {
984                 d_printf(_("error getting includes: %s\n"), sbcErrorString(err));
985                 goto done;
986         }
987
988         for (count = 0; count < num_includes; count++) {
989                 d_printf("include = %s\n", includes[count]);
990         }
991
992         ret = 0;
993
994 done:
995         TALLOC_FREE(mem_ctx);
996         return ret;
997 }
998
999 static int net_conf_setincludes(struct net_context *c,
1000                                 struct smbconf_ctx *conf_ctx,
1001                                 int argc, const char **argv)
1002 {
1003         sbcErr err;
1004         char *service;
1005         uint32_t num_includes;
1006         const char **includes;
1007         int ret = -1;
1008         TALLOC_CTX *mem_ctx = talloc_stackframe();
1009
1010         if (argc < 1 || c->display_usage) {
1011                 net_conf_setincludes_usage(c, argc, argv);
1012                 goto done;
1013         }
1014
1015         service = talloc_strdup(mem_ctx, argv[0]);
1016         if (service == NULL) {
1017                 d_printf(_("error: out of memory!\n"));
1018                 goto done;
1019         }
1020
1021         num_includes = argc - 1;
1022         if (num_includes == 0) {
1023                 includes = NULL;
1024         } else {
1025                 includes = argv + 1;
1026         }
1027
1028         err = smbconf_set_includes(conf_ctx, service, num_includes, includes);
1029         if (!SBC_ERROR_IS_OK(err)) {
1030                 d_printf(_("error setting includes: %s\n"), sbcErrorString(err));
1031                 goto done;
1032         }
1033
1034         ret = 0;
1035
1036 done:
1037         TALLOC_FREE(mem_ctx);
1038         return ret;
1039 }
1040
1041 static int net_conf_delincludes(struct net_context *c,
1042                                 struct smbconf_ctx *conf_ctx,
1043                                 int argc, const char **argv)
1044 {
1045         sbcErr err;
1046         char *service;
1047         int ret = -1;
1048         TALLOC_CTX *mem_ctx = talloc_stackframe();
1049
1050         if (argc != 1 || c->display_usage) {
1051                 net_conf_delincludes_usage(c, argc, argv);
1052                 goto done;
1053         }
1054
1055         service = talloc_strdup(mem_ctx, argv[0]);
1056         if (service == NULL) {
1057                 d_printf(_("error: out of memory!\n"));
1058                 goto done;
1059         }
1060
1061         err = smbconf_delete_includes(conf_ctx, service);
1062         if (!SBC_ERROR_IS_OK(err)) {
1063                 d_printf(_("error deleting includes: %s\n"), sbcErrorString(err));
1064                 goto done;
1065         }
1066
1067         ret = 0;
1068
1069 done:
1070         TALLOC_FREE(mem_ctx);
1071         return ret;
1072 }
1073
1074
1075 /**********************************************************************
1076  *
1077  * Wrapper and net_conf_run_function mechanism.
1078  *
1079  **********************************************************************/
1080
1081 /**
1082  * Wrapper function to call the main conf functions.
1083  * The wrapper calls handles opening and closing of the
1084  * configuration.
1085  */
1086 static int net_conf_wrap_function(struct net_context *c,
1087                                   int (*fn)(struct net_context *,
1088                                             struct smbconf_ctx *,
1089                                             int, const char **),
1090                                   int argc, const char **argv)
1091 {
1092         sbcErr err;
1093         TALLOC_CTX *mem_ctx = talloc_stackframe();
1094         struct smbconf_ctx *conf_ctx;
1095         int ret = -1;
1096
1097         err = smbconf_init(mem_ctx, &conf_ctx, "registry:");
1098         if (!SBC_ERROR_IS_OK(err)) {
1099                 talloc_free(mem_ctx);
1100                 return -1;
1101         }
1102
1103         ret = fn(c, conf_ctx, argc, argv);
1104
1105         smbconf_shutdown(conf_ctx);
1106
1107         talloc_free(mem_ctx);
1108         return ret;
1109 }
1110
1111 /*
1112  * We need a functable struct of our own, because the
1113  * functions are called through a wrapper that handles
1114  * the opening and closing of the configuration, and so on.
1115  */
1116 struct conf_functable {
1117         const char *funcname;
1118         int (*fn)(struct net_context *c, struct smbconf_ctx *ctx, int argc,
1119                   const char **argv);
1120         int valid_transports;
1121         const char *description;
1122         const char *usage;
1123 };
1124
1125 /**
1126  * This imitates net_run_function but calls the main functions
1127  * through the wrapper net_conf_wrap_function().
1128  */
1129 static int net_conf_run_function(struct net_context *c, int argc,
1130                                  const char **argv, const char *whoami,
1131                                  struct conf_functable *table)
1132 {
1133         int i;
1134
1135         if (argc != 0) {
1136                 for (i=0; table[i].funcname; i++) {
1137                         if (strcasecmp_m(argv[0], table[i].funcname) == 0)
1138                                 return net_conf_wrap_function(c, table[i].fn,
1139                                                               argc-1,
1140                                                               argv+1);
1141                 }
1142         }
1143
1144         d_printf(_("Usage:\n"));
1145         for (i=0; table[i].funcname; i++) {
1146                 if (c->display_usage == false)
1147                         d_printf("%s %-15s %s\n", whoami, table[i].funcname,
1148                                  table[i].description);
1149                 else
1150                         d_printf("%s\n", table[i].usage);
1151         }
1152
1153         return c->display_usage?0:-1;
1154 }
1155
1156 /*
1157  * Entry-point for all the CONF functions.
1158  */
1159
1160 int net_conf(struct net_context *c, int argc, const char **argv)
1161 {
1162         int ret = -1;
1163         struct conf_functable func_table[] = {
1164                 {
1165                         "list",
1166                         net_conf_list,
1167                         NET_TRANSPORT_LOCAL,
1168                         N_("Dump the complete configuration in smb.conf like "
1169                            "format."),
1170                         N_("net conf list\n"
1171                            "    Dump the complete configuration in smb.conf "
1172                            "like format.")
1173
1174                 },
1175                 {
1176                         "import",
1177                         net_conf_import,
1178                         NET_TRANSPORT_LOCAL,
1179                         N_("Import configuration from file in smb.conf "
1180                            "format."),
1181                         N_("net conf import\n"
1182                            "    Import configuration from file in smb.conf "
1183                            "format.")
1184                 },
1185                 {
1186                         "listshares",
1187                         net_conf_listshares,
1188                         NET_TRANSPORT_LOCAL,
1189                         N_("List the share names."),
1190                         N_("net conf listshares\n"
1191                            "    List the share names.")
1192                 },
1193                 {
1194                         "drop",
1195                         net_conf_drop,
1196                         NET_TRANSPORT_LOCAL,
1197                         N_("Delete the complete configuration."),
1198                         N_("net conf drop\n"
1199                            "    Delete the complete configuration.")
1200                 },
1201                 {
1202                         "showshare",
1203                         net_conf_showshare,
1204                         NET_TRANSPORT_LOCAL,
1205                         N_("Show the definition of a share."),
1206                         N_("net conf showshare\n"
1207                            "    Show the definition of a share.")
1208                 },
1209                 {
1210                         "addshare",
1211                         net_conf_addshare,
1212                         NET_TRANSPORT_LOCAL,
1213                         N_("Create a new share."),
1214                         N_("net conf addshare\n"
1215                            "    Create a new share.")
1216                 },
1217                 {
1218                         "delshare",
1219                         net_conf_delshare,
1220                         NET_TRANSPORT_LOCAL,
1221                         N_("Delete a share."),
1222                         N_("net conf delshare\n"
1223                            "    Delete a share.")
1224                 },
1225                 {
1226                         "setparm",
1227                         net_conf_setparm,
1228                         NET_TRANSPORT_LOCAL,
1229                         N_("Store a parameter."),
1230                         N_("net conf setparm\n"
1231                            "    Store a parameter.")
1232                 },
1233                 {
1234                         "getparm",
1235                         net_conf_getparm,
1236                         NET_TRANSPORT_LOCAL,
1237                         N_("Retrieve the value of a parameter."),
1238                         N_("net conf getparm\n"
1239                            "    Retrieve the value of a parameter.")
1240                 },
1241                 {
1242                         "delparm",
1243                         net_conf_delparm,
1244                         NET_TRANSPORT_LOCAL,
1245                         N_("Delete a parameter."),
1246                         N_("net conf delparm\n"
1247                            "    Delete a parameter.")
1248                 },
1249                 {
1250                         "getincludes",
1251                         net_conf_getincludes,
1252                         NET_TRANSPORT_LOCAL,
1253                         N_("Show the includes of a share definition."),
1254                         N_("net conf getincludes\n"
1255                            "    Show the includes of a share definition.")
1256                 },
1257                 {
1258                         "setincludes",
1259                         net_conf_setincludes,
1260                         NET_TRANSPORT_LOCAL,
1261                         N_("Set includes for a share."),
1262                         N_("net conf setincludes\n"
1263                            "    Set includes for a share.")
1264                 },
1265                 {
1266                         "delincludes",
1267                         net_conf_delincludes,
1268                         NET_TRANSPORT_LOCAL,
1269                         N_("Delete includes from a share definition."),
1270                         N_("net conf delincludes\n"
1271                            "    Delete includes from a share definition.")
1272                 },
1273                 {NULL, NULL, 0, NULL, NULL}
1274         };
1275
1276         ret = net_conf_run_function(c, argc, argv, "net conf", func_table);
1277
1278         return ret;
1279 }
1280