Move drop_smbconf_internal() to libnet_conf.c
[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
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 the configuration stored inside the
23  * samba registry. In the future there might be support for other
24  * configuration backends as well.
25  */
26
27 #include "includes.h"
28 #include "utils/net.h"
29 #include "libnet/libnet.h"
30
31 /*
32  * usage functions
33  */
34
35 static int net_conf_list_usage(int argc, const char **argv)
36 {
37         d_printf("USAGE: net conf list\n");
38         return -1;
39 }
40
41 static int net_conf_import_usage(int argc, const char**argv)
42 {
43         d_printf("USAGE: net conf import [--test|-T] <filename> "
44                  "[<servicename>]\n"
45                  "\t[--test|-T]    testmode - do not act, just print "
46                                    "what would be done\n"
47                  "\t<servicename>  only import service <servicename>, "
48                                    "ignore the rest\n");
49         return -1;
50 }
51
52 static int net_conf_listshares_usage(int argc, const char **argv)
53 {
54         d_printf("USAGE: net conf listshares\n");
55         return -1;
56 }
57
58 static int net_conf_drop_usage(int argc, const char **argv)
59 {
60         d_printf("USAGE: net conf drop\n");
61         return -1;
62 }
63
64 static int net_conf_showshare_usage(int argc, const char **argv)
65 {
66         d_printf("USAGE: net conf showshare <sharename>\n");
67         return -1;
68 }
69
70 static int net_conf_addshare_usage(int argc, const char **argv)
71 {
72         d_printf("USAGE: net conf addshare <sharename> <path> "
73                  "[writeable={y|N} [guest_ok={y|N} [<comment>]]\n"
74                  "\t<sharename>      the new share name.\n"
75                  "\t<path>           the path on the filesystem to export.\n"
76                  "\twriteable={y|N}  set \"writeable to \"yes\" or "
77                  "\"no\" (default) on this share.\n"
78                  "\tguest_ok={y|N}   set \"guest ok\" to \"yes\" or "
79                  "\"no\" (default)   on this share.\n"
80                  "\t<comment>        optional comment for the new share.\n");
81         return -1;
82 }
83
84 static int net_conf_delshare_usage(int argc, const char **argv)
85 {
86         d_printf("USAGE: net conf delshare <sharename>\n");
87         return -1;
88 }
89
90 static int net_conf_setparm_usage(int argc, const char **argv)
91 {
92         d_printf("USAGE: net conf setparm <section> <param> <value>\n");
93         return -1;
94 }
95
96 static int net_conf_getparm_usage(int argc, const char **argv)
97 {
98         d_printf("USAGE: net conf getparm <section> <param>\n");
99         return -1;
100 }
101
102 static int net_conf_delparm_usage(int argc, const char **argv)
103 {
104         d_printf("USAGE: net conf delparm <section> <param>\n");
105         return -1;
106 }
107
108
109 /*
110  * Helper functions
111  */
112
113 static char *format_value(TALLOC_CTX *mem_ctx, struct registry_value *value)
114 {
115         char *result = NULL;
116
117         /* what if mem_ctx = NULL? */
118
119         switch (value->type) {
120         case REG_DWORD:
121                 result = talloc_asprintf(mem_ctx, "%d", value->v.dword);
122                 break;
123         case REG_SZ:
124         case REG_EXPAND_SZ:
125                 result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str);
126                 break;
127         case REG_MULTI_SZ: {
128                 uint32 j;
129                 for (j = 0; j < value->v.multi_sz.num_strings; j++) {
130                         result = talloc_asprintf(mem_ctx, "\"%s\" ",
131                                                  value->v.multi_sz.strings[j]);
132                 }
133                 break;
134         }
135         case REG_BINARY:
136                 result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
137                                          (int)value->v.binary.length);
138                 break;
139         default:
140                 result = talloc_asprintf(mem_ctx, "<unprintable>");
141                 break;
142         }
143         return result;
144 }
145
146 static WERROR list_values(TALLOC_CTX *ctx, struct registry_key *key)
147 {
148         WERROR werr = WERR_OK;
149         uint32 idx = 0;
150         struct registry_value *valvalue = NULL;
151         char *valname = NULL;
152
153         for (idx = 0;
154              W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
155                                                 &valvalue));
156              idx++)
157         {
158                 d_printf("\t%s = %s\n", valname, format_value(ctx, valvalue));
159         }
160         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
161                 d_fprintf(stderr, "Error enumerating values: %s\n",
162                           dos_errstr(werr));
163                 goto done;
164         }
165         werr = WERR_OK;
166
167 done:
168         return werr;
169 }
170
171 static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm,
172                          struct share_params *share)
173 {
174         char *valstr = NULL;
175         int i = 0;
176         void *ptr = parm->ptr;
177
178         if (parm->p_class == P_LOCAL && share->service >= 0) {
179                 ptr = lp_local_ptr(share->service, ptr);
180         }
181
182         switch (parm->type) {
183         case P_CHAR:
184                 valstr = talloc_asprintf(ctx, "%c", *(char *)ptr);
185                 break;
186         case P_STRING:
187         case P_USTRING:
188                 valstr = talloc_asprintf(ctx, "%s", *(char **)ptr);
189                 break;
190         case P_BOOL:
191                 valstr = talloc_asprintf(ctx, "%s", BOOLSTR(*(bool *)ptr));
192                 break;
193         case P_BOOLREV:
194                 valstr = talloc_asprintf(ctx, "%s", BOOLSTR(!*(bool *)ptr));
195                 break;
196         case P_ENUM:
197                 for (i = 0; parm->enum_list[i].name; i++) {
198                         if (*(int *)ptr == parm->enum_list[i].value)
199                         {
200                                 valstr = talloc_asprintf(ctx, "%s",
201                                          parm->enum_list[i].name);
202                                 break;
203                         }
204                 }
205                 break;
206         case P_OCTAL: {
207                 char *o = octal_string(*(int *)ptr);
208                 valstr = talloc_move(ctx, &o);
209                 break;
210         }
211         case P_LIST:
212                 valstr = talloc_strdup(ctx, "");
213                 if ((char ***)ptr && *(char ***)ptr) {
214                         char **list = *(char ***)ptr;
215                         for (; *list; list++) {
216                                 /* surround strings with whitespace
217                                  * in double quotes */
218                                 if (strchr_m(*list, ' '))
219                                 {
220                                         valstr = talloc_asprintf_append(
221                                                 valstr, "\"%s\"%s",
222                                                 *list,
223                                                  ((*(list+1))?", ":""));
224                                 } else {
225                                         valstr = talloc_asprintf_append(
226                                                 valstr, "%s%s", *list,
227                                                  ((*(list+1))?", ":""));
228                                 }
229                         }
230                 }
231                 break;
232         case P_INTEGER:
233                 valstr = talloc_asprintf(ctx, "%d", *(int *)ptr);
234                 break;
235         case P_SEP:
236                 break;
237         default:
238                 valstr = talloc_asprintf(ctx, "<type unimplemented>\n");
239                 break;
240         }
241
242         return valstr;
243 }
244
245 static int import_process_service(TALLOC_CTX *ctx,
246                                   struct share_params *share)
247 {
248         int ret = -1;
249         struct parm_struct *parm;
250         int pnum = 0;
251         const char *servicename;
252         struct registry_key *key;
253         WERROR werr;
254         char *valstr = NULL;
255         TALLOC_CTX *tmp_ctx = NULL;
256
257         tmp_ctx = talloc_new(ctx);
258         if (tmp_ctx == NULL) {
259                 werr = WERR_NOMEM;
260                 goto done;
261         }
262
263         servicename = (share->service == GLOBAL_SECTION_SNUM)?
264                 GLOBAL_NAME : lp_servicename(share->service);
265
266         if (opt_testmode) {
267                 d_printf("[%s]\n", servicename);
268         } else {
269                 if (libnet_smbconf_key_exists(servicename)) {
270                         werr = libnet_smbconf_delshare(servicename);
271                         if (!W_ERROR_IS_OK(werr)) {
272                                 goto done;
273                         }
274                 }
275                 werr = libnet_smbconf_reg_createkey_internal(tmp_ctx, servicename, &key);
276                 if (!W_ERROR_IS_OK(werr)) {
277                         goto done;
278                 }
279         }
280
281         while ((parm = lp_next_parameter(share->service, &pnum, 0)))
282         {
283                 if ((share->service < 0 && parm->p_class == P_LOCAL)
284                     && !(parm->flags & FLAG_GLOBAL))
285                         continue;
286
287                 valstr = parm_valstr(tmp_ctx, parm, share);
288
289                 if (parm->type != P_SEP) {
290                         if (opt_testmode) {
291                                 d_printf("\t%s = %s\n", parm->label, valstr);
292                         } else {
293                                 werr = libnet_smbconf_reg_setvalue_internal(key,
294                                                         parm->label, valstr);
295                                 if (!W_ERROR_IS_OK(werr)) {
296                                         goto done;
297                                 }
298                         }
299                 }
300         }
301
302         if (opt_testmode) {
303                 d_printf("\n");
304         }
305
306         ret = 0;
307
308 done:
309         TALLOC_FREE(tmp_ctx);
310         return ret;
311 }
312
313 /* return true iff there are nondefault globals */
314 static bool globals_exist(void)
315 {
316         int i = 0;
317         struct parm_struct *parm;
318
319         while ((parm = lp_next_parameter(GLOBAL_SECTION_SNUM, &i, 0)) != NULL) {
320                 if (parm->type != P_SEP) {
321                         return true;
322                 }
323         }
324         return false;
325 }
326
327 /*
328  * the conf functions
329  */
330
331 int net_conf_list(int argc, const char **argv)
332 {
333         WERROR werr = WERR_OK;
334         int ret = -1;
335         TALLOC_CTX *ctx;
336         struct registry_key *base_key = NULL;
337         struct registry_key *sub_key = NULL;
338         uint32 idx_key = 0;
339         char *subkey_name = NULL;
340
341         ctx = talloc_init("list");
342
343         if (argc != 0) {
344                 net_conf_list_usage(argc, argv);
345                 goto done;
346         }
347
348         werr = libnet_smbconf_open_basepath(ctx, REG_KEY_READ, &base_key);
349         if (!W_ERROR_IS_OK(werr)) {
350                 goto done;
351         }
352
353         if (libnet_smbconf_key_exists(GLOBAL_NAME))  {
354                 werr = reg_openkey(ctx, base_key, GLOBAL_NAME,
355                                    REG_KEY_READ, &sub_key);
356                 if (!W_ERROR_IS_OK(werr)) {
357                         d_fprintf(stderr, "Error opening subkey '%s' : %s\n",
358                                   subkey_name, dos_errstr(werr));
359                         goto done;
360                 }
361                 d_printf("[%s]\n", GLOBAL_NAME);
362                 if (!W_ERROR_IS_OK(list_values(ctx, sub_key))) {
363                         goto done;
364                 }
365                 d_printf("\n");
366         }
367
368         for (idx_key = 0;
369              W_ERROR_IS_OK(werr = reg_enumkey(ctx, base_key, idx_key,
370                                               &subkey_name, NULL));
371              idx_key++)
372         {
373                 if (strequal(subkey_name, GLOBAL_NAME)) {
374                         continue;
375                 }
376                 d_printf("[%s]\n", subkey_name);
377
378                 werr = reg_openkey(ctx, base_key, subkey_name,
379                                    REG_KEY_READ, &sub_key);
380                 if (!W_ERROR_IS_OK(werr)) {
381                         d_fprintf(stderr,
382                                   "Error opening subkey '%s': %s\n",
383                                   subkey_name, dos_errstr(werr));
384                         goto done;
385                 }
386                 if (!W_ERROR_IS_OK(list_values(ctx, sub_key))) {
387                         goto done;
388                 }
389                 d_printf("\n");
390         }
391         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
392                 d_fprintf(stderr, "Error enumerating subkeys: %s\n",
393                           dos_errstr(werr));
394                 goto done;
395         }
396
397         ret = 0;
398
399 done:
400         TALLOC_FREE(ctx);
401         return ret;
402 }
403
404 int net_conf_import(int argc, const char **argv)
405 {
406         int ret = -1;
407         const char *filename = NULL;
408         const char *servicename = NULL;
409         bool service_found = false;
410         TALLOC_CTX *ctx;
411         struct share_iterator *shares;
412         struct share_params *share;
413         struct share_params global_share = { GLOBAL_SECTION_SNUM };
414
415         ctx = talloc_init("net_conf_import");
416
417         switch (argc) {
418                 case 0:
419                 default:
420                         net_conf_import_usage(argc, argv);
421                         goto done;
422                 case 2:
423                         servicename = argv[1];
424                 case 1:
425                         filename = argv[0];
426                         break;
427         }
428
429         DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
430                 filename));
431
432         if (!lp_load(filename,
433                      false,     /* global_only */
434                      true,      /* save_defaults */
435                      false,     /* add_ipc */
436                      true))     /* initialize_globals */
437         {
438                 d_fprintf(stderr, "Error parsing configuration file.\n");
439                 goto done;
440         }
441
442         if (opt_testmode) {
443                 d_printf("\nTEST MODE - "
444                          "would import the following configuration:\n\n");
445         }
446
447         if (((servicename == NULL) && globals_exist()) ||
448             strequal(servicename, GLOBAL_NAME))
449         {
450                 service_found = true;
451                 if (import_process_service(ctx, &global_share) != 0) {
452                         goto done;
453                 }
454         }
455
456         if (service_found && (servicename != NULL)) {
457                 ret = 0;
458                 goto done;
459         }
460
461         if (!(shares = share_list_all(ctx))) {
462                 d_fprintf(stderr, "Could not list shares...\n");
463                 goto done;
464         }
465         while ((share = next_share(shares)) != NULL) {
466                 if ((servicename == NULL)
467                     || strequal(servicename, lp_servicename(share->service)))
468                 {
469                         service_found = true;
470                         if (import_process_service(ctx, share)!= 0) {
471                                 goto done;
472                         }
473                 }
474         }
475
476         if ((servicename != NULL) && !service_found) {
477                 d_printf("Share %s not found in file %s\n",
478                          servicename, filename);
479                 goto done;
480
481         }
482
483         ret = 0;
484
485 done:
486         TALLOC_FREE(ctx);
487         return ret;
488 }
489
490 int net_conf_listshares(int argc, const char **argv)
491 {
492         WERROR werr = WERR_OK;
493         int ret = -1;
494         struct registry_key *key;
495         uint32 idx = 0;
496         char *subkey_name = NULL;
497         TALLOC_CTX *ctx;
498
499         ctx = talloc_init("listshares");
500
501         if (argc != 0) {
502                 net_conf_listshares_usage(argc, argv);
503                 goto done;
504         }
505
506         werr = libnet_smbconf_open_basepath(ctx, SEC_RIGHTS_ENUM_SUBKEYS, &key);
507         if (!W_ERROR_IS_OK(werr)) {
508                 goto done;
509         }
510
511         for (idx = 0;
512              W_ERROR_IS_OK(werr = reg_enumkey(ctx, key, idx,
513                                               &subkey_name, NULL));
514              idx++)
515         {
516                 d_printf("%s\n", subkey_name);
517         }
518         if (! W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
519                 d_fprintf(stderr, "Error enumerating subkeys: %s\n",
520                           dos_errstr(werr));
521                 goto done;
522         }
523
524         ret = 0;
525
526 done:
527         TALLOC_FREE(ctx);
528         return ret;
529 }
530
531 int net_conf_drop(int argc, const char **argv)
532 {
533         int ret = -1;
534         WERROR werr;
535
536         if (argc != 0) {
537                 net_conf_drop_usage(argc, argv);
538                 goto done;
539         }
540
541         werr = drop_smbconf_internal(NULL);
542         if (!W_ERROR_IS_OK(werr)) {
543                 d_fprintf(stderr, "Error deleting configuration: %s\n",
544                           dos_errstr(werr));
545                 goto done;
546         }
547
548         ret = 0;
549
550 done:
551         return ret;
552 }
553
554 int net_conf_showshare(int argc, const char **argv)
555 {
556         int ret = -1;
557         WERROR werr = WERR_OK;
558         struct registry_key *key = NULL;
559         TALLOC_CTX *ctx;
560
561         ctx = talloc_init("showshare");
562
563         if (argc != 1) {
564                 net_conf_showshare_usage(argc, argv);
565                 goto done;
566         }
567
568         werr = libnet_smbconf_open_path(ctx, argv[0], REG_KEY_READ, &key);
569         if (!W_ERROR_IS_OK(werr)) {
570                 goto done;
571         }
572
573         d_printf("[%s]\n", argv[0]);
574
575         if (!W_ERROR_IS_OK(list_values(ctx, key))) {
576                 goto done;
577         }
578
579         ret = 0;
580
581 done:
582         TALLOC_FREE(ctx);
583         return ret;
584 }
585
586 int net_conf_addshare(int argc, const char **argv)
587 {
588         int ret = -1;
589         WERROR werr = WERR_OK;
590         struct registry_key *newkey = NULL;
591         char *sharename = NULL;
592         const char *path = NULL;
593         const char *comment = NULL;
594         const char *guest_ok = "no";
595         const char *writeable = "no";
596         SMB_STRUCT_STAT sbuf;
597
598         switch (argc) {
599                 case 0:
600                 case 1:
601                 default:
602                         net_conf_addshare_usage(argc, argv);
603                         goto done;
604                 case 5:
605                         comment = argv[4];
606                 case 4:
607                         if (!strnequal(argv[3], "guest_ok=", 9)) {
608                                 net_conf_addshare_usage(argc, argv);
609                                 goto done;
610                         }
611                         switch (argv[3][9]) {
612                                 case 'y':
613                                 case 'Y':
614                                         guest_ok = "yes";
615                                         break;
616                                 case 'n':
617                                 case 'N':
618                                         guest_ok = "no";
619                                         break;
620                                 default:
621                                         net_conf_addshare_usage(argc, argv);
622                                         goto done;
623                         }
624                 case 3:
625                         if (!strnequal(argv[2], "writeable=", 10)) {
626                                 net_conf_addshare_usage(argc, argv);
627                                 goto done;
628                         }
629                         switch (argv[2][10]) {
630                                 case 'y':
631                                 case 'Y':
632                                         writeable = "yes";
633                                         break;
634                                 case 'n':
635                                 case 'N':
636                                         writeable = "no";
637                                         break;
638                                 default:
639                                         net_conf_addshare_usage(argc, argv);
640                                         goto done;
641                         }
642
643                 case 2:
644                         path = argv[1];
645                         sharename = strdup_lower(argv[0]);
646                         break;
647         }
648
649         /*
650          * validate arguments
651          */
652
653         /* validate share name */
654
655         if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
656                                strlen(sharename)))
657         {
658                 d_fprintf(stderr, "ERROR: share name %s contains "
659                         "invalid characters (any of %s)\n",
660                         sharename, INVALID_SHARENAME_CHARS);
661                 goto done;
662         }
663
664         if (getpwnam(sharename)) {
665                 d_fprintf(stderr, "ERROR: share name %s is already a valid "
666                           "system user name.\n", sharename);
667                 goto done;
668         }
669
670         if (strequal(sharename, GLOBAL_NAME)) {
671                 d_fprintf(stderr,
672                           "ERROR: 'global' is not a valid share name.\n");
673                 goto done;
674         }
675
676         /* validate path */
677
678         if (path[0] != '/') {
679                 d_fprintf(stderr,
680                           "Error: path '%s' is not an absolute path.\n",
681                           path);
682                 goto done;
683         }
684
685         if (sys_stat(path, &sbuf) != 0) {
686                 d_fprintf(stderr,
687                           "ERROR: cannot stat path '%s' to ensure "
688                           "this is a directory.\n"
689                           "Error was '%s'.\n",
690                           path, strerror(errno));
691                 goto done;
692         }
693
694         if (!S_ISDIR(sbuf.st_mode)) {
695                 d_fprintf(stderr,
696                           "ERROR: path '%s' is not a directory.\n",
697                           path);
698                 goto done;
699         }
700
701         /*
702          * create the share
703          */
704
705         werr = libnet_smbconf_reg_createkey_internal(NULL, argv[0], &newkey);
706         if (!W_ERROR_IS_OK(werr)) {
707                 goto done;
708         }
709
710         /* add config params as values */
711
712         werr = libnet_smbconf_reg_setvalue_internal(newkey, "path", path);
713         if (!W_ERROR_IS_OK(werr))
714                 goto done;
715
716         if (comment != NULL) {
717                 werr = libnet_smbconf_reg_setvalue_internal(newkey, "comment",
718                                                             comment);
719                 if (!W_ERROR_IS_OK(werr))
720                         goto done;
721         }
722
723         werr = libnet_smbconf_reg_setvalue_internal(newkey, "guest ok",
724                                                     guest_ok);
725         if (!W_ERROR_IS_OK(werr))
726                 goto done;
727
728         werr = libnet_smbconf_reg_setvalue_internal(newkey, "writeable",
729                                                     writeable);
730         if (!W_ERROR_IS_OK(werr))
731                 goto done;
732
733         ret = 0;
734
735 done:
736         TALLOC_FREE(newkey);
737         SAFE_FREE(sharename);
738         return ret;
739 }
740
741 int net_conf_delshare(int argc, const char **argv)
742 {
743         int ret = -1;
744         const char *sharename = NULL;
745         WERROR werr = WERR_OK;
746
747         if (argc != 1) {
748                 net_conf_delshare_usage(argc, argv);
749                 goto done;
750         }
751         sharename = argv[0];
752
753         werr = libnet_smbconf_delshare(sharename);
754         if (!W_ERROR_IS_OK(werr)) {
755                 d_fprintf(stderr, "Error deleting share %s: %s\n",
756                           sharename, dos_errstr(werr));
757                 goto done;
758         }
759
760         ret = 0;
761 done:
762         return ret;
763 }
764
765 static int net_conf_setparm(int argc, const char **argv)
766 {
767         int ret = -1;
768         WERROR werr = WERR_OK;
769         char *service = NULL;
770         char *param = NULL;
771         const char *value_str = NULL;
772         TALLOC_CTX *ctx;
773
774         ctx = talloc_init("setparm");
775
776         if (argc != 3) {
777                 net_conf_setparm_usage(argc, argv);
778                 goto done;
779         }
780         service = strdup_lower(argv[0]);
781         param = strdup_lower(argv[1]);
782         value_str = argv[2];
783
784         werr = libnet_smbconf_setparm(ctx, service, param, value_str);
785
786         if (!W_ERROR_IS_OK(werr)) {
787                 d_fprintf(stderr, "Error setting value '%s': %s\n",
788                           param, dos_errstr(werr));
789                 goto done;
790         }
791
792         ret = 0;
793
794 done:
795         SAFE_FREE(service);
796         TALLOC_FREE(ctx);
797         return ret;
798 }
799
800 static int net_conf_getparm(int argc, const char **argv)
801 {
802         int ret = -1;
803         WERROR werr = WERR_OK;
804         char *service = NULL;
805         char *param = NULL;
806         struct registry_value *value = NULL;
807         TALLOC_CTX *ctx;
808
809         ctx = talloc_init("getparm");
810
811         if (argc != 2) {
812                 net_conf_getparm_usage(argc, argv);
813                 goto done;
814         }
815         service = strdup_lower(argv[0]);
816         param = strdup_lower(argv[1]);
817
818         werr = libnet_smbconf_getparm(ctx, service, param, &value);
819
820         if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
821                 d_fprintf(stderr,
822                           "Error: given service '%s' does not exist.\n",
823                           service);
824                 goto done;
825         } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
826                 d_fprintf(stderr,
827                           "Error: given parameter '%s' is not set.\n",
828                           param);
829                 goto done;
830         } else if (!W_ERROR_IS_OK(werr)) {
831                 d_fprintf(stderr, "Error getting value '%s': %s.\n",
832                           param, dos_errstr(werr));
833                 goto done;
834         }
835
836         d_printf("%s\n", format_value(ctx, value));
837
838         ret = 0;
839 done:
840         SAFE_FREE(service);
841         SAFE_FREE(param);
842         TALLOC_FREE(ctx);
843         return ret;
844 }
845
846 static int net_conf_delparm(int argc, const char **argv)
847 {
848         int ret = -1;
849         WERROR werr = WERR_OK;
850         char *service = NULL;
851         char *param = NULL;
852         TALLOC_CTX *ctx;
853
854         ctx = talloc_init("delparm");
855
856         if (argc != 2) {
857                 net_conf_delparm_usage(argc, argv);
858                 goto done;
859         }
860         service = strdup_lower(argv[0]);
861         param = strdup_lower(argv[1]);
862
863         werr = libnet_smbconf_delparm(ctx, service, param);
864
865         if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
866                 d_fprintf(stderr,
867                           "Error: given service '%s' does not exist.\n",
868                           service);
869                 goto done;
870         } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
871                 d_fprintf(stderr,
872                           "Error: given parameter '%s' is not set.\n",
873                           param);
874                 goto done;
875         } else if (!W_ERROR_IS_OK(werr)) {
876                 d_fprintf(stderr, "Error deleting value '%s': %s.\n",
877                           param, dos_errstr(werr));
878                 goto done;
879         }
880
881         ret = 0;
882
883 done:
884         return ret;
885 }
886
887 /*
888  * Entry-point for all the CONF functions.
889  */
890
891 int net_conf(int argc, const char **argv)
892 {
893         int ret = -1;
894         struct functable2 func[] = {
895                 {"list", net_conf_list,
896                  "Dump the complete configuration in smb.conf like format."},
897                 {"import", net_conf_import,
898                  "Import configuration from file in smb.conf format."},
899                 {"listshares", net_conf_listshares,
900                  "List the registry shares."},
901                 {"drop", net_conf_drop,
902                  "Delete the complete configuration from registry."},
903                 {"showshare", net_conf_showshare,
904                  "Show the definition of a registry share."},
905                 {"addshare", net_conf_addshare,
906                  "Create a new registry share."},
907                 {"delshare", net_conf_delshare,
908                  "Delete a registry share."},
909                 {"setparm", net_conf_setparm,
910                  "Store a parameter."},
911                 {"getparm", net_conf_getparm,
912                  "Retrieve the value of a parameter."},
913                 {"delparm", net_conf_delparm,
914                  "Delete a parameter."},
915                 {NULL, NULL, NULL}
916         };
917
918         if (!registry_init_regdb()) {
919                 d_fprintf(stderr, "Error initializing the registry!\n");
920                 goto done;
921         }
922
923         ret = net_run_function2(argc, argv, "net conf", func);
924
925         regdb_close();
926
927 done:
928         return ret;
929 }
930