s3-net_conf: Display an error on net conf import failures.
[Samba.git] / source3 / utils / net_conf.c
blob6fc03bfd86b360d758b9bb22bc5c46ce1e75771e
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
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.
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.
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/>.
22 * This is an interface to Samba's configuration as made available
23 * by the libsmbconf interface (source/lib/smbconf/smbconf.c).
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.
30 #include "includes.h"
31 #include "utils/net.h"
33 /**********************************************************************
35 * usage functions
37 **********************************************************************/
39 static int net_conf_list_usage(struct net_context *c, int argc,
40 const char **argv)
42 d_printf("%s net conf list\n", _("Usage:"));
43 return -1;
46 static int net_conf_import_usage(struct net_context *c, int argc,
47 const char**argv)
49 d_printf("%s\n%s",
50 _("Usage:"),
51 _(" net conf import [--test|-T] <filename> "
52 "[<servicename>]\n"
53 "\t[--test|-T] testmode - do not act, just print "
54 "what would be done\n"
55 "\t<servicename> only import service <servicename>, "
56 "ignore the rest\n"));
57 return -1;
60 static int net_conf_listshares_usage(struct net_context *c, int argc,
61 const char **argv)
63 d_printf("%s\nnet conf listshares\n", _("Usage:"));
64 return -1;
67 static int net_conf_drop_usage(struct net_context *c, int argc,
68 const char **argv)
70 d_printf("%s\nnet conf drop\n", _("Usage:"));
71 return -1;
74 static int net_conf_showshare_usage(struct net_context *c, int argc,
75 const char **argv)
77 d_printf("%s\n%s",
78 _("Usage:"),
79 _("net conf showshare <sharename>\n"));
80 return -1;
83 static int net_conf_addshare_usage(struct net_context *c, int argc,
84 const char **argv)
86 d_printf("%s\n%s",
87 _("Usage:"),
88 _(" net conf addshare <sharename> <path> "
89 "[writeable={y|N} [guest_ok={y|N} [<comment>]]\n"
90 "\t<sharename> the new share name.\n"
91 "\t<path> the path on the filesystem to export.\n"
92 "\twriteable={y|N} set \"writeable to \"yes\" or "
93 "\"no\" (default) on this share.\n"
94 "\tguest_ok={y|N} set \"guest ok\" to \"yes\" or "
95 "\"no\" (default) on this share.\n"
96 "\t<comment> optional comment for the new share.\n"));
97 return -1;
100 static int net_conf_delshare_usage(struct net_context *c, int argc,
101 const char **argv)
103 d_printf("%s\n%s",
104 _("Usage:"),
105 _("net conf delshare <sharename>\n"));
106 return -1;
109 static int net_conf_setparm_usage(struct net_context *c, int argc,
110 const char **argv)
112 d_printf("%s\n%s",
113 _("Usage:"),
114 _(" net conf setparm <section> <param> <value>\n"));
115 return -1;
118 static int net_conf_getparm_usage(struct net_context *c, int argc,
119 const char **argv)
121 d_printf("%s\n%s",
122 _("Usage:"),
123 _(" net conf getparm <section> <param>\n"));
124 return -1;
127 static int net_conf_delparm_usage(struct net_context *c, int argc,
128 const char **argv)
130 d_printf("%s\n%s",
131 _("Usage:"),
132 _(" net conf delparm <section> <param>\n"));
133 return -1;
136 static int net_conf_getincludes_usage(struct net_context *c, int argc,
137 const char **argv)
139 d_printf("%s\n%s",
140 _("Usage:"),
141 _(" net conf getincludes <section>\n"));
142 return -1;
145 static int net_conf_setincludes_usage(struct net_context *c, int argc,
146 const char **argv)
148 d_printf("%s\n%s",
149 _("Usage:"),
150 _(" net conf setincludes <section> [<filename>]*\n"));
151 return -1;
154 static int net_conf_delincludes_usage(struct net_context *c, int argc,
155 const char **argv)
157 d_printf("%s\n%s",
158 _("Usage:"),
159 _(" net conf delincludes <section>\n"));
160 return -1;
164 /**********************************************************************
166 * Helper functions
168 **********************************************************************/
171 * This functions process a service previously loaded with libsmbconf.
173 static WERROR import_process_service(struct net_context *c,
174 struct smbconf_ctx *conf_ctx,
175 struct smbconf_service *service)
177 uint32_t idx;
178 WERROR werr = WERR_OK;
179 uint32_t num_includes = 0;
180 char **includes = NULL;
181 TALLOC_CTX *mem_ctx = talloc_stackframe();
183 if (c->opt_testmode) {
184 const char *indent = "";
185 if (service->name != NULL) {
186 d_printf("[%s]\n", service->name);
187 indent = "\t";
189 for (idx = 0; idx < service->num_params; idx++) {
190 d_printf("%s%s = %s\n", indent,
191 service->param_names[idx],
192 service->param_values[idx]);
194 d_printf("\n");
195 goto done;
198 if (smbconf_share_exists(conf_ctx, service->name)) {
199 werr = smbconf_delete_share(conf_ctx, service->name);
200 if (!W_ERROR_IS_OK(werr)) {
201 goto done;
204 werr = smbconf_create_share(conf_ctx, service->name);
205 if (!W_ERROR_IS_OK(werr)) {
206 goto done;
209 for (idx = 0; idx < service->num_params; idx ++) {
210 if (strequal(service->param_names[idx], "include")) {
211 includes = TALLOC_REALLOC_ARRAY(mem_ctx,
212 includes,
213 char *,
214 num_includes+1);
215 if (includes == NULL) {
216 werr = WERR_NOMEM;
217 goto done;
219 includes[num_includes] = talloc_strdup(includes,
220 service->param_values[idx]);
221 if (includes[num_includes] == NULL) {
222 werr = WERR_NOMEM;
223 goto done;
225 num_includes++;
226 } else {
227 werr = smbconf_set_parameter(conf_ctx,
228 service->name,
229 service->param_names[idx],
230 service->param_values[idx]);
231 if (!W_ERROR_IS_OK(werr)) {
232 d_fprintf(stderr,
233 _("Error in section [%s], parameter \"%s\": %s\n"),
234 service->name, service->param_names[idx],
235 win_errstr(werr));
236 goto done;
241 werr = smbconf_set_includes(conf_ctx, service->name, num_includes,
242 (const char **)includes);
244 done:
245 TALLOC_FREE(mem_ctx);
246 return werr;
250 /**********************************************************************
252 * the main conf functions
254 **********************************************************************/
256 static int net_conf_list(struct net_context *c, struct smbconf_ctx *conf_ctx,
257 int argc, const char **argv)
259 WERROR werr = WERR_OK;
260 int ret = -1;
261 TALLOC_CTX *mem_ctx;
262 uint32_t num_shares;
263 uint32_t share_count, param_count;
264 struct smbconf_service **shares = NULL;
266 mem_ctx = talloc_stackframe();
268 if (argc != 0 || c->display_usage) {
269 net_conf_list_usage(c, argc, argv);
270 goto done;
273 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &shares);
274 if (!W_ERROR_IS_OK(werr)) {
275 d_fprintf(stderr, _("Error getting config: %s\n"),
276 win_errstr(werr));
277 goto done;
280 for (share_count = 0; share_count < num_shares; share_count++) {
281 const char *indent = "";
282 if (shares[share_count]->name != NULL) {
283 d_printf("[%s]\n", shares[share_count]->name);
284 indent = "\t";
286 for (param_count = 0;
287 param_count < shares[share_count]->num_params;
288 param_count++)
290 d_printf("%s%s = %s\n",
291 indent,
292 shares[share_count]->param_names[param_count],
293 shares[share_count]->param_values[param_count]);
295 d_printf("\n");
298 ret = 0;
300 done:
301 TALLOC_FREE(mem_ctx);
302 return ret;
305 static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
306 int argc, const char **argv)
308 int ret = -1;
309 const char *filename = NULL;
310 const char *servicename = NULL;
311 char *conf_source = NULL;
312 TALLOC_CTX *mem_ctx;
313 struct smbconf_ctx *txt_ctx;
314 WERROR werr;
316 if (c->display_usage)
317 return net_conf_import_usage(c, argc, argv);
319 mem_ctx = talloc_stackframe();
321 switch (argc) {
322 case 0:
323 default:
324 net_conf_import_usage(c, argc, argv);
325 goto done;
326 case 2:
327 servicename = talloc_strdup(mem_ctx, argv[1]);
328 if (servicename == NULL) {
329 d_printf(_("error: out of memory!\n"));
330 goto done;
332 case 1:
333 filename = argv[0];
334 break;
337 DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
338 filename));
340 conf_source = talloc_asprintf(mem_ctx, "file:%s", filename);
341 if (conf_source == NULL) {
342 d_printf(_("error: out of memory!\n"));
343 goto done;
346 werr = smbconf_init(mem_ctx, &txt_ctx, conf_source);
347 if (!W_ERROR_IS_OK(werr)) {
348 d_printf(_("error loading file '%s': %s\n"), filename,
349 win_errstr(werr));
350 goto done;
353 if (c->opt_testmode) {
354 d_printf(_("\nTEST MODE - "
355 "would import the following configuration:\n\n"));
358 if (servicename != NULL) {
359 struct smbconf_service *service = NULL;
361 werr = smbconf_get_share(txt_ctx, mem_ctx,
362 servicename,
363 &service);
364 if (!W_ERROR_IS_OK(werr)) {
365 goto cancel;
368 werr = smbconf_transaction_start(conf_ctx);
369 if (!W_ERROR_IS_OK(werr)) {
370 d_printf(_("error starting transaction: %s\n"),
371 win_errstr(werr));
372 goto done;
375 werr = import_process_service(c, conf_ctx, service);
376 if (!W_ERROR_IS_OK(werr)) {
377 goto cancel;
379 } else {
380 struct smbconf_service **services = NULL;
381 uint32_t num_shares, sidx;
383 werr = smbconf_get_config(txt_ctx, mem_ctx,
384 &num_shares,
385 &services);
386 if (!W_ERROR_IS_OK(werr)) {
387 goto cancel;
389 if (!c->opt_testmode) {
390 werr = smbconf_drop(conf_ctx);
391 if (!W_ERROR_IS_OK(werr)) {
392 goto cancel;
397 * Wrap the importing of shares into a transaction,
398 * but only 100 at a time, in order to serve memory.
399 * The allocated memory accumulates across the actions
400 * within the transaction, and for me, some 1500
401 * imported shares, the MAX_TALLOC_SIZE of 256 MB
402 * was exceeded.
404 werr = smbconf_transaction_start(conf_ctx);
405 if (!W_ERROR_IS_OK(werr)) {
406 d_printf(_("error starting transaction: %s\n"),
407 win_errstr(werr));
408 goto done;
411 for (sidx = 0; sidx < num_shares; sidx++) {
412 werr = import_process_service(c, conf_ctx,
413 services[sidx]);
414 if (!W_ERROR_IS_OK(werr)) {
415 goto cancel;
418 if (sidx % 100) {
419 continue;
422 werr = smbconf_transaction_commit(conf_ctx);
423 if (!W_ERROR_IS_OK(werr)) {
424 d_printf(_("error committing transaction: "
425 "%s\n"),
426 win_errstr(werr));
427 goto done;
429 werr = smbconf_transaction_start(conf_ctx);
430 if (!W_ERROR_IS_OK(werr)) {
431 d_printf(_("error starting transaction: %s\n"),
432 win_errstr(werr));
433 goto done;
438 werr = smbconf_transaction_commit(conf_ctx);
439 if (!W_ERROR_IS_OK(werr)) {
440 d_printf(_("error committing transaction: %s\n"),
441 win_errstr(werr));
442 } else {
443 ret = 0;
446 goto done;
448 cancel:
449 werr = smbconf_transaction_cancel(conf_ctx);
450 if (!W_ERROR_IS_OK(werr)) {
451 d_printf(_("error cancelling transaction: %s\n"),
452 win_errstr(werr));
455 done:
456 TALLOC_FREE(mem_ctx);
457 return ret;
460 static int net_conf_listshares(struct net_context *c,
461 struct smbconf_ctx *conf_ctx, int argc,
462 const char **argv)
464 WERROR werr = WERR_OK;
465 int ret = -1;
466 uint32_t count, num_shares = 0;
467 char **share_names = NULL;
468 TALLOC_CTX *mem_ctx;
470 mem_ctx = talloc_stackframe();
472 if (argc != 0 || c->display_usage) {
473 net_conf_listshares_usage(c, argc, argv);
474 goto done;
477 werr = smbconf_get_share_names(conf_ctx, mem_ctx, &num_shares,
478 &share_names);
479 if (!W_ERROR_IS_OK(werr)) {
480 goto done;
483 for (count = 0; count < num_shares; count++)
485 d_printf("%s\n", share_names[count]);
488 ret = 0;
490 done:
491 TALLOC_FREE(mem_ctx);
492 return ret;
495 static int net_conf_drop(struct net_context *c, struct smbconf_ctx *conf_ctx,
496 int argc, const char **argv)
498 int ret = -1;
499 WERROR werr;
501 if (argc != 0 || c->display_usage) {
502 net_conf_drop_usage(c, argc, argv);
503 goto done;
506 werr = smbconf_drop(conf_ctx);
507 if (!W_ERROR_IS_OK(werr)) {
508 d_fprintf(stderr, _("Error deleting configuration: %s\n"),
509 win_errstr(werr));
510 goto done;
513 ret = 0;
515 done:
516 return ret;
519 static int net_conf_showshare(struct net_context *c,
520 struct smbconf_ctx *conf_ctx, int argc,
521 const char **argv)
523 int ret = -1;
524 WERROR werr = WERR_OK;
525 const char *sharename = NULL;
526 TALLOC_CTX *mem_ctx;
527 uint32_t count;
528 struct smbconf_service *service = NULL;
530 mem_ctx = talloc_stackframe();
532 if (argc != 1 || c->display_usage) {
533 net_conf_showshare_usage(c, argc, argv);
534 goto done;
537 sharename = talloc_strdup(mem_ctx, argv[0]);
538 if (sharename == NULL) {
539 d_printf("error: out of memory!\n");
540 goto done;
543 werr = smbconf_get_share(conf_ctx, mem_ctx, sharename, &service);
544 if (!W_ERROR_IS_OK(werr)) {
545 d_printf(_("error getting share parameters: %s\n"),
546 win_errstr(werr));
547 goto done;
550 d_printf("[%s]\n", service->name);
552 for (count = 0; count < service->num_params; count++) {
553 d_printf("\t%s = %s\n", service->param_names[count],
554 service->param_values[count]);
557 ret = 0;
559 done:
560 TALLOC_FREE(mem_ctx);
561 return ret;
565 * Add a share, with a couple of standard parameters, partly optional.
567 * This is a high level utility function of the net conf utility,
568 * not a direct frontend to the smbconf API.
570 static int net_conf_addshare(struct net_context *c,
571 struct smbconf_ctx *conf_ctx, int argc,
572 const char **argv)
574 int ret = -1;
575 WERROR werr = WERR_OK;
576 char *sharename = NULL;
577 const char *path = NULL;
578 const char *comment = NULL;
579 const char *guest_ok = "no";
580 const char *writeable = "no";
581 SMB_STRUCT_STAT sbuf;
582 TALLOC_CTX *mem_ctx = talloc_stackframe();
584 if (c->display_usage) {
585 net_conf_addshare_usage(c, argc, argv);
586 ret = 0;
587 goto done;
590 switch (argc) {
591 case 0:
592 case 1:
593 default:
594 net_conf_addshare_usage(c, argc, argv);
595 goto done;
596 case 5:
597 comment = argv[4];
598 case 4:
599 if (!strnequal(argv[3], "guest_ok=", 9)) {
600 net_conf_addshare_usage(c, argc, argv);
601 goto done;
603 switch (argv[3][9]) {
604 case 'y':
605 case 'Y':
606 guest_ok = "yes";
607 break;
608 case 'n':
609 case 'N':
610 guest_ok = "no";
611 break;
612 default:
613 net_conf_addshare_usage(c, argc, argv);
614 goto done;
616 case 3:
617 if (!strnequal(argv[2], "writeable=", 10)) {
618 net_conf_addshare_usage(c, argc, argv);
619 goto done;
621 switch (argv[2][10]) {
622 case 'y':
623 case 'Y':
624 writeable = "yes";
625 break;
626 case 'n':
627 case 'N':
628 writeable = "no";
629 break;
630 default:
631 net_conf_addshare_usage(c, argc, argv);
632 goto done;
634 case 2:
635 path = argv[1];
636 sharename = talloc_strdup(mem_ctx, argv[0]);
637 if (sharename == NULL) {
638 d_printf(_("error: out of memory!\n"));
639 goto done;
642 break;
646 * validate arguments
649 /* validate share name */
651 if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
652 strlen(sharename)))
654 d_fprintf(stderr, _("ERROR: share name %s contains "
655 "invalid characters (any of %s)\n"),
656 sharename, INVALID_SHARENAME_CHARS);
657 goto done;
660 if (strequal(sharename, GLOBAL_NAME)) {
661 d_fprintf(stderr,
662 _("ERROR: 'global' is not a valid share name.\n"));
663 goto done;
666 if (smbconf_share_exists(conf_ctx, sharename)) {
667 d_fprintf(stderr, _("ERROR: share %s already exists.\n"),
668 sharename);
669 goto done;
672 /* validate path */
674 if (path[0] != '/') {
675 d_fprintf(stderr,
676 _("Error: path '%s' is not an absolute path.\n"),
677 path);
678 goto done;
681 if (sys_stat(path, &sbuf, false) != 0) {
682 d_fprintf(stderr,
683 _("ERROR: cannot stat path '%s' to ensure "
684 "this is a directory.\n"
685 "Error was '%s'.\n"),
686 path, strerror(errno));
687 goto done;
690 if (!S_ISDIR(sbuf.st_ex_mode)) {
691 d_fprintf(stderr,
692 _("ERROR: path '%s' is not a directory.\n"),
693 path);
694 goto done;
698 * start a transaction
701 werr = smbconf_transaction_start(conf_ctx);
702 if (!W_ERROR_IS_OK(werr)) {
703 d_printf("error starting transaction: %s\n",
704 win_errstr(werr));
705 goto done;
709 * create the share
712 werr = smbconf_create_share(conf_ctx, sharename);
713 if (!W_ERROR_IS_OK(werr)) {
714 d_fprintf(stderr, _("Error creating share %s: %s\n"),
715 sharename, win_errstr(werr));
716 goto cancel;
720 * fill the share with parameters
723 werr = smbconf_set_parameter(conf_ctx, sharename, "path", path);
724 if (!W_ERROR_IS_OK(werr)) {
725 d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
726 "path", win_errstr(werr));
727 goto cancel;
730 if (comment != NULL) {
731 werr = smbconf_set_parameter(conf_ctx, sharename, "comment",
732 comment);
733 if (!W_ERROR_IS_OK(werr)) {
734 d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
735 "comment", win_errstr(werr));
736 goto cancel;
740 werr = smbconf_set_parameter(conf_ctx, sharename, "guest ok", guest_ok);
741 if (!W_ERROR_IS_OK(werr)) {
742 d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
743 "'guest ok'", win_errstr(werr));
744 goto cancel;
747 werr = smbconf_set_parameter(conf_ctx, sharename, "writeable",
748 writeable);
749 if (!W_ERROR_IS_OK(werr)) {
750 d_fprintf(stderr, _("Error setting parameter %s: %s\n"),
751 "writeable", win_errstr(werr));
752 goto cancel;
756 * commit the whole thing
759 werr = smbconf_transaction_commit(conf_ctx);
760 if (!W_ERROR_IS_OK(werr)) {
761 d_printf("error committing transaction: %s\n",
762 win_errstr(werr));
763 } else {
764 ret = 0;
767 goto done;
769 cancel:
770 werr = smbconf_transaction_cancel(conf_ctx);
771 if (!W_ERROR_IS_OK(werr)) {
772 d_printf("error cancelling transaction: %s\n",
773 win_errstr(werr));
776 done:
777 TALLOC_FREE(mem_ctx);
778 return ret;
781 static int net_conf_delshare(struct net_context *c,
782 struct smbconf_ctx *conf_ctx, int argc,
783 const char **argv)
785 int ret = -1;
786 const char *sharename = NULL;
787 WERROR werr = WERR_OK;
788 TALLOC_CTX *mem_ctx = talloc_stackframe();
790 if (argc != 1 || c->display_usage) {
791 net_conf_delshare_usage(c, argc, argv);
792 goto done;
794 sharename = talloc_strdup(mem_ctx, argv[0]);
795 if (sharename == NULL) {
796 d_printf(_("error: out of memory!\n"));
797 goto done;
800 werr = smbconf_delete_share(conf_ctx, sharename);
801 if (!W_ERROR_IS_OK(werr)) {
802 d_fprintf(stderr, _("Error deleting share %s: %s\n"),
803 sharename, win_errstr(werr));
804 goto done;
807 ret = 0;
808 done:
809 TALLOC_FREE(mem_ctx);
810 return ret;
813 static int net_conf_setparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
814 int argc, const char **argv)
816 int ret = -1;
817 WERROR werr = WERR_OK;
818 char *service = NULL;
819 char *param = NULL;
820 const char *value_str = NULL;
821 TALLOC_CTX *mem_ctx = talloc_stackframe();
823 if (argc != 3 || c->display_usage) {
824 net_conf_setparm_usage(c, argc, argv);
825 goto done;
828 * NULL service name means "dangling parameters" to libsmbconf.
829 * We use the empty string from the command line for this purpose.
831 if (strlen(argv[0]) != 0) {
832 service = talloc_strdup(mem_ctx, argv[0]);
833 if (service == NULL) {
834 d_printf(_("error: out of memory!\n"));
835 goto done;
838 param = strlower_talloc(mem_ctx, argv[1]);
839 if (param == NULL) {
840 d_printf(_("error: out of memory!\n"));
841 goto done;
843 value_str = argv[2];
845 werr = smbconf_transaction_start(conf_ctx);
846 if (!W_ERROR_IS_OK(werr)) {
847 d_printf(_("error starting transaction: %s\n"),
848 win_errstr(werr));
849 goto done;
852 if (!smbconf_share_exists(conf_ctx, service)) {
853 werr = smbconf_create_share(conf_ctx, service);
854 if (!W_ERROR_IS_OK(werr)) {
855 d_fprintf(stderr, _("Error creating share '%s': %s\n"),
856 service, win_errstr(werr));
857 goto cancel;
861 werr = smbconf_set_parameter(conf_ctx, service, param, value_str);
863 if (!W_ERROR_IS_OK(werr)) {
864 d_fprintf(stderr, _("Error setting value '%s': %s\n"),
865 param, win_errstr(werr));
866 goto cancel;
869 werr = smbconf_transaction_commit(conf_ctx);
870 if (!W_ERROR_IS_OK(werr)) {
871 d_printf(_("error committing transaction: %s\n"),
872 win_errstr(werr));
873 } else {
874 ret = 0;
877 goto done;
879 cancel:
880 werr = smbconf_transaction_cancel(conf_ctx);
881 if (!W_ERROR_IS_OK(werr)) {
882 d_printf(_("error cancelling transaction: %s\n"),
883 win_errstr(werr));
886 done:
887 TALLOC_FREE(mem_ctx);
888 return ret;
891 static int net_conf_getparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
892 int argc, const char **argv)
894 int ret = -1;
895 WERROR werr = WERR_OK;
896 char *service = NULL;
897 char *param = NULL;
898 char *valstr = NULL;
899 TALLOC_CTX *mem_ctx;
901 mem_ctx = talloc_stackframe();
903 if (argc != 2 || c->display_usage) {
904 net_conf_getparm_usage(c, argc, argv);
905 goto done;
908 * NULL service name means "dangling parameters" to libsmbconf.
909 * We use the empty string from the command line for this purpose.
911 if (strlen(argv[0]) != 0) {
912 service = talloc_strdup(mem_ctx, argv[0]);
913 if (service == NULL) {
914 d_printf(_("error: out of memory!\n"));
915 goto done;
918 param = strlower_talloc(mem_ctx, argv[1]);
919 if (param == NULL) {
920 d_printf(_("error: out of memory!\n"));
921 goto done;
924 werr = smbconf_get_parameter(conf_ctx, mem_ctx, service, param, &valstr);
926 if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
927 d_fprintf(stderr,
928 _("Error: given service '%s' does not exist.\n"),
929 service);
930 goto done;
931 } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
932 d_fprintf(stderr,
933 _("Error: given parameter '%s' is not set.\n"),
934 param);
935 goto done;
936 } else if (!W_ERROR_IS_OK(werr)) {
937 d_fprintf(stderr, _("Error getting value '%s': %s.\n"),
938 param, win_errstr(werr));
939 goto done;
942 d_printf("%s\n", valstr);
944 ret = 0;
945 done:
946 TALLOC_FREE(mem_ctx);
947 return ret;
950 static int net_conf_delparm(struct net_context *c, struct smbconf_ctx *conf_ctx,
951 int argc, const char **argv)
953 int ret = -1;
954 WERROR werr = WERR_OK;
955 char *service = NULL;
956 char *param = NULL;
957 TALLOC_CTX *mem_ctx = talloc_stackframe();
959 if (argc != 2 || c->display_usage) {
960 net_conf_delparm_usage(c, argc, argv);
961 goto done;
964 * NULL service name means "dangling parameters" to libsmbconf.
965 * We use the empty string from the command line for this purpose.
967 if (strlen(argv[0]) != 0) {
968 service = talloc_strdup(mem_ctx, argv[0]);
969 if (service == NULL) {
970 d_printf(_("error: out of memory!\n"));
971 goto done;
974 param = strlower_talloc(mem_ctx, argv[1]);
975 if (param == NULL) {
976 d_printf("error: out of memory!\n");
977 goto done;
980 werr = smbconf_delete_parameter(conf_ctx, service, param);
982 if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
983 d_fprintf(stderr,
984 _("Error: given service '%s' does not exist.\n"),
985 service);
986 goto done;
987 } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
988 d_fprintf(stderr,
989 _("Error: given parameter '%s' is not set.\n"),
990 param);
991 goto done;
992 } else if (!W_ERROR_IS_OK(werr)) {
993 d_fprintf(stderr, _("Error deleting value '%s': %s.\n"),
994 param, win_errstr(werr));
995 goto done;
998 ret = 0;
1000 done:
1001 TALLOC_FREE(mem_ctx);
1002 return ret;
1005 static int net_conf_getincludes(struct net_context *c,
1006 struct smbconf_ctx *conf_ctx,
1007 int argc, const char **argv)
1009 WERROR werr;
1010 uint32_t num_includes;
1011 uint32_t count;
1012 char *service;
1013 char **includes = NULL;
1014 int ret = -1;
1015 TALLOC_CTX *mem_ctx = talloc_stackframe();
1017 if (argc != 1 || c->display_usage) {
1018 net_conf_getincludes_usage(c, argc, argv);
1019 goto done;
1022 service = talloc_strdup(mem_ctx, argv[0]);
1023 if (service == NULL) {
1024 d_printf(_("error: out of memory!\n"));
1025 goto done;
1028 werr = smbconf_get_includes(conf_ctx, mem_ctx, service,
1029 &num_includes, &includes);
1030 if (!W_ERROR_IS_OK(werr)) {
1031 d_printf(_("error getting includes: %s\n"), win_errstr(werr));
1032 goto done;
1035 for (count = 0; count < num_includes; count++) {
1036 d_printf("include = %s\n", includes[count]);
1039 ret = 0;
1041 done:
1042 TALLOC_FREE(mem_ctx);
1043 return ret;
1046 static int net_conf_setincludes(struct net_context *c,
1047 struct smbconf_ctx *conf_ctx,
1048 int argc, const char **argv)
1050 WERROR werr;
1051 char *service;
1052 uint32_t num_includes;
1053 const char **includes;
1054 int ret = -1;
1055 TALLOC_CTX *mem_ctx = talloc_stackframe();
1057 if (argc < 1 || c->display_usage) {
1058 net_conf_setincludes_usage(c, argc, argv);
1059 goto done;
1062 service = talloc_strdup(mem_ctx, argv[0]);
1063 if (service == NULL) {
1064 d_printf(_("error: out of memory!\n"));
1065 goto done;
1068 num_includes = argc - 1;
1069 if (num_includes == 0) {
1070 includes = NULL;
1071 } else {
1072 includes = argv + 1;
1075 werr = smbconf_set_includes(conf_ctx, service, num_includes, includes);
1076 if (!W_ERROR_IS_OK(werr)) {
1077 d_printf(_("error setting includes: %s\n"), win_errstr(werr));
1078 goto done;
1081 ret = 0;
1083 done:
1084 TALLOC_FREE(mem_ctx);
1085 return ret;
1088 static int net_conf_delincludes(struct net_context *c,
1089 struct smbconf_ctx *conf_ctx,
1090 int argc, const char **argv)
1092 WERROR werr;
1093 char *service;
1094 int ret = -1;
1095 TALLOC_CTX *mem_ctx = talloc_stackframe();
1097 if (argc != 1 || c->display_usage) {
1098 net_conf_delincludes_usage(c, argc, argv);
1099 goto done;
1102 service = talloc_strdup(mem_ctx, argv[0]);
1103 if (service == NULL) {
1104 d_printf(_("error: out of memory!\n"));
1105 goto done;
1108 werr = smbconf_delete_includes(conf_ctx, service);
1109 if (!W_ERROR_IS_OK(werr)) {
1110 d_printf(_("error deleting includes: %s\n"), win_errstr(werr));
1111 goto done;
1114 ret = 0;
1116 done:
1117 TALLOC_FREE(mem_ctx);
1118 return ret;
1122 /**********************************************************************
1124 * Wrapper and net_conf_run_function mechanism.
1126 **********************************************************************/
1129 * Wrapper function to call the main conf functions.
1130 * The wrapper calls handles opening and closing of the
1131 * configuration.
1133 static int net_conf_wrap_function(struct net_context *c,
1134 int (*fn)(struct net_context *,
1135 struct smbconf_ctx *,
1136 int, const char **),
1137 int argc, const char **argv)
1139 WERROR werr;
1140 TALLOC_CTX *mem_ctx = talloc_stackframe();
1141 struct smbconf_ctx *conf_ctx;
1142 int ret = -1;
1144 werr = smbconf_init(mem_ctx, &conf_ctx, "registry:");
1146 if (!W_ERROR_IS_OK(werr)) {
1147 return -1;
1150 ret = fn(c, conf_ctx, argc, argv);
1152 smbconf_shutdown(conf_ctx);
1154 return ret;
1158 * We need a functable struct of our own, because the
1159 * functions are called through a wrapper that handles
1160 * the opening and closing of the configuration, and so on.
1162 struct conf_functable {
1163 const char *funcname;
1164 int (*fn)(struct net_context *c, struct smbconf_ctx *ctx, int argc,
1165 const char **argv);
1166 int valid_transports;
1167 const char *description;
1168 const char *usage;
1172 * This imitates net_run_function but calls the main functions
1173 * through the wrapper net_conf_wrap_function().
1175 static int net_conf_run_function(struct net_context *c, int argc,
1176 const char **argv, const char *whoami,
1177 struct conf_functable *table)
1179 int i;
1181 if (argc != 0) {
1182 for (i=0; table[i].funcname; i++) {
1183 if (StrCaseCmp(argv[0], table[i].funcname) == 0)
1184 return net_conf_wrap_function(c, table[i].fn,
1185 argc-1,
1186 argv+1);
1190 d_printf(_("Usage:\n"));
1191 for (i=0; table[i].funcname; i++) {
1192 if (c->display_usage == false)
1193 d_printf("%s %-15s %s\n", whoami, table[i].funcname,
1194 table[i].description);
1195 else
1196 d_printf("%s\n", table[i].usage);
1199 return c->display_usage?0:-1;
1203 * Entry-point for all the CONF functions.
1206 int net_conf(struct net_context *c, int argc, const char **argv)
1208 int ret = -1;
1209 struct conf_functable func_table[] = {
1211 "list",
1212 net_conf_list,
1213 NET_TRANSPORT_LOCAL,
1214 N_("Dump the complete configuration in smb.conf like "
1215 "format."),
1216 N_("net conf list\n"
1217 " Dump the complete configuration in smb.conf "
1218 "like format.")
1222 "import",
1223 net_conf_import,
1224 NET_TRANSPORT_LOCAL,
1225 N_("Import configuration from file in smb.conf "
1226 "format."),
1227 N_("net conf import\n"
1228 " Import configuration from file in smb.conf "
1229 "format.")
1232 "listshares",
1233 net_conf_listshares,
1234 NET_TRANSPORT_LOCAL,
1235 N_("List the share names."),
1236 N_("net conf listshares\n"
1237 " List the share names.")
1240 "drop",
1241 net_conf_drop,
1242 NET_TRANSPORT_LOCAL,
1243 N_("Delete the complete configuration."),
1244 N_("net conf drop\n"
1245 " Delete the complete configuration.")
1248 "showshare",
1249 net_conf_showshare,
1250 NET_TRANSPORT_LOCAL,
1251 N_("Show the definition of a share."),
1252 N_("net conf showshare\n"
1253 " Show the definition of a share.")
1256 "addshare",
1257 net_conf_addshare,
1258 NET_TRANSPORT_LOCAL,
1259 N_("Create a new share."),
1260 N_("net conf addshare\n"
1261 " Create a new share.")
1264 "delshare",
1265 net_conf_delshare,
1266 NET_TRANSPORT_LOCAL,
1267 N_("Delete a share."),
1268 N_("net conf delshare\n"
1269 " Delete a share.")
1272 "setparm",
1273 net_conf_setparm,
1274 NET_TRANSPORT_LOCAL,
1275 N_("Store a parameter."),
1276 N_("net conf setparm\n"
1277 " Store a parameter.")
1280 "getparm",
1281 net_conf_getparm,
1282 NET_TRANSPORT_LOCAL,
1283 N_("Retrieve the value of a parameter."),
1284 N_("net conf getparm\n"
1285 " Retrieve the value of a parameter.")
1288 "delparm",
1289 net_conf_delparm,
1290 NET_TRANSPORT_LOCAL,
1291 N_("Delete a parameter."),
1292 N_("net conf delparm\n"
1293 " Delete a parameter.")
1296 "getincludes",
1297 net_conf_getincludes,
1298 NET_TRANSPORT_LOCAL,
1299 N_("Show the includes of a share definition."),
1300 N_("net conf getincludes\n"
1301 " Show the includes of a share definition.")
1304 "setincludes",
1305 net_conf_setincludes,
1306 NET_TRANSPORT_LOCAL,
1307 N_("Set includes for a share."),
1308 N_("net conf setincludes\n"
1309 " Set includes for a share.")
1312 "delincludes",
1313 net_conf_delincludes,
1314 NET_TRANSPORT_LOCAL,
1315 N_("Delete includes from a share definition."),
1316 N_("net conf setincludes\n"
1317 " Delete includes from a share definition.")
1319 {NULL, NULL, 0, NULL, NULL}
1322 ret = net_conf_run_function(c, argc, argv, "net conf", func_table);
1324 return ret;