These should be char *, but replace them with [1024] for now
[Samba/vl.git] / source3 / utils / net_conf.c
blob4ff4bd9a2983a618ef7b2884285d4464176e2c28
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
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 the configuration stored inside the
23 * samba registry. In the future there might be support for other
24 * configuration backends as well.
27 #include "includes.h"
28 #include "utils/net.h"
31 * usage functions
34 static int net_conf_list_usage(int argc, const char **argv)
36 d_printf("USAGE: net conf list\n");
37 return -1;
40 static int net_conf_import_usage(int argc, const char**argv)
42 d_printf("USAGE: net conf import [--test|-T] <filename> "
43 "[<servicename>]\n"
44 "\t[--test|-T] testmode - do not act, just print "
45 "what would be done\n"
46 "\t<servicename> only import service <servicename>, "
47 "ignore the rest\n");
48 return -1;
51 static int net_conf_listshares_usage(int argc, const char **argv)
53 d_printf("USAGE: net conf listshares\n");
54 return -1;
57 static int net_conf_drop_usage(int argc, const char **argv)
59 d_printf("USAGE: net conf drop\n");
60 return -1;
63 static int net_conf_showshare_usage(int argc, const char **argv)
65 d_printf("USAGE: net conf showshare <sharename>\n");
66 return -1;
69 static int net_conf_addshare_usage(int argc, const char **argv)
71 d_printf("USAGE: net conf addshare <sharename> <path> "
72 "[writeable={y|N} [guest_ok={y|N} [<comment>]]\n"
73 "\t<sharename> the new share name.\n"
74 "\t<path> the path on the filesystem to export.\n"
75 "\twriteable={y|N} set \"writeable to \"yes\" or "
76 "\"no\" (default) on this share.\n"
77 "\tguest_ok={y|N} set \"guest ok\" to \"yes\" or "
78 "\"no\" (default) on this share.\n"
79 "\t<comment> optional comment for the new share.\n");
80 return -1;
83 static int net_conf_delshare_usage(int argc, const char **argv)
85 d_printf("USAGE: net conf delshare <sharename>\n");
86 return -1;
89 static int net_conf_setparm_usage(int argc, const char **argv)
91 d_printf("USAGE: net conf setparm <section> <param> <value>\n");
92 return -1;
95 static int net_conf_getparm_usage(int argc, const char **argv)
97 d_printf("USAGE: net conf getparm <section> <param>\n");
98 return -1;
101 static int net_conf_delparm_usage(int argc, const char **argv)
103 d_printf("USAGE: net conf delparm <section> <param>\n");
104 return -1;
109 * Helper functions
112 static char *format_value(TALLOC_CTX *mem_ctx, struct registry_value *value)
114 char *result = NULL;
116 /* what if mem_ctx = NULL? */
118 switch (value->type) {
119 case REG_DWORD:
120 result = talloc_asprintf(mem_ctx, "%d", value->v.dword);
121 break;
122 case REG_SZ:
123 case REG_EXPAND_SZ:
124 result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str);
125 break;
126 case REG_MULTI_SZ: {
127 uint32 j;
128 for (j = 0; j < value->v.multi_sz.num_strings; j++) {
129 result = talloc_asprintf(mem_ctx, "\"%s\" ",
130 value->v.multi_sz.strings[j]);
132 break;
134 case REG_BINARY:
135 result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
136 (int)value->v.binary.length);
137 break;
138 default:
139 result = talloc_asprintf(mem_ctx, "<unprintable>");
140 break;
142 return result;
146 * add a value to a key.
148 static WERROR reg_setvalue_internal(struct registry_key *key,
149 const char *valname,
150 const char *valstr)
152 struct registry_value val;
153 WERROR werr = WERR_OK;
154 char *subkeyname;
155 const char *canon_valname;
156 const char *canon_valstr;
158 if (!lp_canonicalize_parameter_with_value(valname, valstr,
159 &canon_valname,
160 &canon_valstr))
162 if (canon_valname == NULL) {
163 d_fprintf(stderr, "invalid parameter '%s' given\n",
164 valname);
165 } else {
166 d_fprintf(stderr, "invalid value '%s' given for "
167 "parameter '%s'\n", valstr, valname);
169 werr = WERR_INVALID_PARAM;
170 goto done;
173 ZERO_STRUCT(val);
175 val.type = REG_SZ;
176 val.v.sz.str = CONST_DISCARD(char *, canon_valstr);
177 val.v.sz.len = strlen(canon_valstr) + 1;
179 if (registry_smbconf_valname_forbidden(canon_valname)) {
180 d_fprintf(stderr, "Parameter '%s' not allowed in registry.\n",
181 canon_valname);
182 werr = WERR_INVALID_PARAM;
183 goto done;
186 subkeyname = strrchr_m(key->key->name, '\\');
187 if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
188 d_fprintf(stderr, "Invalid registry key '%s' given as "
189 "smbconf section.\n", key->key->name);
190 werr = WERR_INVALID_PARAM;
191 goto done;
193 subkeyname++;
194 if (!strequal(subkeyname, GLOBAL_NAME) &&
195 lp_parameter_is_global(valname))
197 d_fprintf(stderr, "Global paramter '%s' not allowed in "
198 "service definition ('%s').\n", canon_valname,
199 subkeyname);
200 werr = WERR_INVALID_PARAM;
201 goto done;
204 werr = reg_setvalue(key, canon_valname, &val);
205 if (!W_ERROR_IS_OK(werr)) {
206 d_fprintf(stderr,
207 "Error adding value '%s' to "
208 "key '%s': %s\n",
209 canon_valname, key->key->name, dos_errstr(werr));
212 done:
213 return werr;
217 * Open a subkey of KEY_SMBCONF (i.e a service)
218 * - variant without error output (q = quiet)-
220 static WERROR smbconf_open_path_q(TALLOC_CTX *ctx, const char *subkeyname,
221 uint32 desired_access,
222 struct registry_key **key)
224 WERROR werr = WERR_OK;
225 char *path = NULL;
226 NT_USER_TOKEN *token;
228 if (!(token = registry_create_admin_token(ctx))) {
229 DEBUG(1, ("Error creating admin token\n"));
230 goto done;
233 if (subkeyname == NULL) {
234 path = talloc_strdup(ctx, KEY_SMBCONF);
235 } else {
236 path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, subkeyname);
239 werr = reg_open_path(ctx, path, desired_access,
240 token, key);
242 done:
243 TALLOC_FREE(path);
244 return werr;
248 * Open a subkey of KEY_SMBCONF (i.e a service)
249 * - variant with error output -
251 static WERROR smbconf_open_path(TALLOC_CTX *ctx, const char *subkeyname,
252 uint32 desired_access,
253 struct registry_key **key)
255 WERROR werr = WERR_OK;
257 werr = smbconf_open_path_q(ctx, subkeyname, desired_access, key);
258 if (!W_ERROR_IS_OK(werr)) {
259 d_fprintf(stderr, "Error opening registry path '%s\\%s': %s\n",
260 KEY_SMBCONF,
261 (subkeyname == NULL) ? "" : subkeyname,
262 dos_errstr(werr));
265 return werr;
269 * open the base key KEY_SMBCONF
271 static WERROR smbconf_open_basepath(TALLOC_CTX *ctx, uint32 desired_access,
272 struct registry_key **key)
274 return smbconf_open_path(ctx, NULL, desired_access, key);
278 * delete a subkey of KEY_SMBCONF
280 static WERROR reg_delkey_internal(TALLOC_CTX *ctx, const char *keyname)
282 WERROR werr = WERR_OK;
283 struct registry_key *key = NULL;
285 werr = smbconf_open_basepath(ctx, REG_KEY_WRITE, &key);
286 if (!W_ERROR_IS_OK(werr)) {
287 goto done;
290 werr = reg_deletekey_recursive(key, key, keyname);
291 if (!W_ERROR_IS_OK(werr)) {
292 d_fprintf(stderr, "Error deleting registry key %s\\%s: %s\n",
293 KEY_SMBCONF, keyname, dos_errstr(werr));
296 done:
297 TALLOC_FREE(key);
298 return werr;
302 * create a subkey of KEY_SMBCONF
304 static WERROR reg_createkey_internal(TALLOC_CTX *ctx,
305 const char * subkeyname,
306 struct registry_key **newkey)
308 WERROR werr = WERR_OK;
309 struct registry_key *create_parent = NULL;
310 TALLOC_CTX *create_ctx;
311 enum winreg_CreateAction action = REG_ACTION_NONE;
313 /* create a new talloc ctx for creation. it will hold
314 * the intermediate parent key (SMBCONF) for creation
315 * and will be destroyed when leaving this function... */
316 if (!(create_ctx = talloc_new(ctx))) {
317 werr = WERR_NOMEM;
318 goto done;
321 werr = smbconf_open_basepath(create_ctx, REG_KEY_WRITE, &create_parent);
322 if (!W_ERROR_IS_OK(werr)) {
323 goto done;
326 werr = reg_createkey(ctx, create_parent, subkeyname,
327 REG_KEY_WRITE, newkey, &action);
328 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
329 d_fprintf(stderr, "Key '%s' already exists.\n", subkeyname);
330 werr = WERR_ALREADY_EXISTS;
332 if (!W_ERROR_IS_OK(werr)) {
333 d_fprintf(stderr, "Error creating key %s: %s\n",
334 subkeyname, dos_errstr(werr));
337 done:
338 TALLOC_FREE(create_ctx);
339 return werr;
343 * check if a subkey of KEY_SMBCONF of a given name exists
345 static bool smbconf_key_exists(TALLOC_CTX *ctx, const char *subkeyname)
347 bool ret = False;
348 WERROR werr = WERR_OK;
349 TALLOC_CTX *mem_ctx;
350 struct registry_key *key;
352 if (!(mem_ctx = talloc_new(ctx))) {
353 d_fprintf(stderr, "ERROR: Out of memory...!\n");
354 goto done;
357 werr = smbconf_open_path_q(mem_ctx, subkeyname, REG_KEY_READ, &key);
358 if (W_ERROR_IS_OK(werr)) {
359 ret = True;
362 done:
363 TALLOC_FREE(mem_ctx);
364 return ret;
367 static bool smbconf_value_exists(TALLOC_CTX *ctx, struct registry_key *key,
368 const char *param)
370 bool ret = False;
371 WERROR werr = WERR_OK;
372 struct registry_value *value = NULL;
374 werr = reg_queryvalue(ctx, key, param, &value);
375 if (W_ERROR_IS_OK(werr)) {
376 ret = True;
379 TALLOC_FREE(value);
380 return ret;
383 static WERROR list_values(TALLOC_CTX *ctx, struct registry_key *key)
385 WERROR werr = WERR_OK;
386 uint32 idx = 0;
387 struct registry_value *valvalue = NULL;
388 char *valname = NULL;
390 for (idx = 0;
391 W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
392 &valvalue));
393 idx++)
395 d_printf("\t%s = %s\n", valname, format_value(ctx, valvalue));
397 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
398 d_fprintf(stderr, "Error enumerating values: %s\n",
399 dos_errstr(werr));
400 goto done;
402 werr = WERR_OK;
404 done:
405 return werr;
408 static WERROR drop_smbconf_internal(TALLOC_CTX *ctx)
410 char *path, *p;
411 WERROR werr = WERR_OK;
412 NT_USER_TOKEN *token;
413 struct registry_key *parent_key = NULL;
414 struct registry_key *new_key = NULL;
415 TALLOC_CTX* tmp_ctx = NULL;
416 enum winreg_CreateAction action;
418 tmp_ctx = talloc_new(ctx);
419 if (tmp_ctx == NULL) {
420 werr = WERR_NOMEM;
421 goto done;
424 if (!(token = registry_create_admin_token(tmp_ctx))) {
425 /* what is the appropriate error code here? */
426 werr = WERR_CAN_NOT_COMPLETE;
427 goto done;
430 path = talloc_strdup(tmp_ctx, KEY_SMBCONF);
431 if (path == NULL) {
432 d_fprintf(stderr, "ERROR: out of memory!\n");
433 werr = WERR_NOMEM;
434 goto done;
436 p = strrchr(path, '\\');
437 *p = '\0';
438 werr = reg_open_path(tmp_ctx, path, REG_KEY_WRITE, token, &parent_key);
440 if (!W_ERROR_IS_OK(werr)) {
441 goto done;
444 werr = reg_deletekey_recursive(tmp_ctx, parent_key, p+1);
446 if (!W_ERROR_IS_OK(werr)) {
447 goto done;
450 werr = reg_createkey(tmp_ctx, parent_key, p+1, REG_KEY_WRITE,
451 &new_key, &action);
453 done:
454 TALLOC_FREE(tmp_ctx);
455 return werr;
458 static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm,
459 struct share_params *share)
461 char *valstr = NULL;
462 int i = 0;
463 void *ptr = parm->ptr;
465 if (parm->p_class == P_LOCAL && share->service >= 0) {
466 ptr = lp_local_ptr(share->service, ptr);
469 switch (parm->type) {
470 case P_CHAR:
471 valstr = talloc_asprintf(ctx, "%c", *(char *)ptr);
472 break;
473 case P_STRING:
474 case P_USTRING:
475 valstr = talloc_asprintf(ctx, "%s", *(char **)ptr);
476 break;
477 case P_GSTRING:
478 case P_UGSTRING:
479 valstr = talloc_asprintf(ctx, "%s", (char *)ptr);
480 break;
481 case P_BOOL:
482 valstr = talloc_asprintf(ctx, "%s", BOOLSTR(*(bool *)ptr));
483 break;
484 case P_BOOLREV:
485 valstr = talloc_asprintf(ctx, "%s", BOOLSTR(!*(bool *)ptr));
486 break;
487 case P_ENUM:
488 for (i = 0; parm->enum_list[i].name; i++) {
489 if (*(int *)ptr == parm->enum_list[i].value)
491 valstr = talloc_asprintf(ctx, "%s",
492 parm->enum_list[i].name);
493 break;
496 break;
497 case P_OCTAL: {
498 char *o = octal_string(*(int *)ptr);
499 valstr = talloc_move(ctx, &o);
500 break;
502 case P_LIST:
503 valstr = talloc_strdup(ctx, "");
504 if ((char ***)ptr && *(char ***)ptr) {
505 char **list = *(char ***)ptr;
506 for (; *list; list++) {
507 /* surround strings with whitespace
508 * in double quotes */
509 if (strchr_m(*list, ' '))
511 valstr = talloc_asprintf_append(
512 valstr, "\"%s\"%s",
513 *list,
514 ((*(list+1))?", ":""));
515 } else {
516 valstr = talloc_asprintf_append(
517 valstr, "%s%s", *list,
518 ((*(list+1))?", ":""));
522 break;
523 case P_INTEGER:
524 valstr = talloc_asprintf(ctx, "%d", *(int *)ptr);
525 break;
526 case P_SEP:
527 break;
528 default:
529 valstr = talloc_asprintf(ctx, "<type unimplemented>\n");
530 break;
533 return valstr;
536 static int import_process_service(TALLOC_CTX *ctx,
537 struct share_params *share)
539 int ret = -1;
540 struct parm_struct *parm;
541 int pnum = 0;
542 const char *servicename;
543 struct registry_key *key;
544 WERROR werr;
545 char *valstr = NULL;
546 TALLOC_CTX *tmp_ctx = NULL;
548 tmp_ctx = talloc_new(ctx);
549 if (tmp_ctx == NULL) {
550 werr = WERR_NOMEM;
551 goto done;
554 servicename = (share->service == GLOBAL_SECTION_SNUM)?
555 GLOBAL_NAME : lp_servicename(share->service);
557 if (opt_testmode) {
558 d_printf("[%s]\n", servicename);
559 } else {
560 if (smbconf_key_exists(tmp_ctx, servicename)) {
561 werr = reg_delkey_internal(tmp_ctx, servicename);
562 if (!W_ERROR_IS_OK(werr)) {
563 goto done;
566 werr = reg_createkey_internal(tmp_ctx, servicename, &key);
567 if (!W_ERROR_IS_OK(werr)) {
568 goto done;
572 while ((parm = lp_next_parameter(share->service, &pnum, 0)))
574 if ((share->service < 0 && parm->p_class == P_LOCAL)
575 && !(parm->flags & FLAG_GLOBAL))
576 continue;
578 valstr = parm_valstr(tmp_ctx, parm, share);
580 if (parm->type != P_SEP) {
581 if (opt_testmode) {
582 d_printf("\t%s = %s\n", parm->label, valstr);
583 } else {
584 werr = reg_setvalue_internal(key, parm->label,
585 valstr);
586 if (!W_ERROR_IS_OK(werr)) {
587 goto done;
593 if (opt_testmode) {
594 d_printf("\n");
597 ret = 0;
599 done:
600 TALLOC_FREE(tmp_ctx);
601 return ret;
604 /* return True iff there are nondefault globals */
605 static bool globals_exist(void)
607 int i = 0;
608 struct parm_struct *parm;
610 while ((parm = lp_next_parameter(GLOBAL_SECTION_SNUM, &i, 0)) != NULL) {
611 if (parm->type != P_SEP) {
612 return True;
615 return False;
619 * the conf functions
622 int net_conf_list(int argc, const char **argv)
624 WERROR werr = WERR_OK;
625 int ret = -1;
626 TALLOC_CTX *ctx;
627 struct registry_key *base_key = NULL;
628 struct registry_key *sub_key = NULL;
629 uint32 idx_key = 0;
630 char *subkey_name = NULL;
632 ctx = talloc_init("list");
634 if (argc != 0) {
635 net_conf_list_usage(argc, argv);
636 goto done;
639 werr = smbconf_open_basepath(ctx, REG_KEY_READ, &base_key);
640 if (!W_ERROR_IS_OK(werr)) {
641 goto done;
644 if (smbconf_key_exists(ctx, GLOBAL_NAME)) {
645 werr = reg_openkey(ctx, base_key, GLOBAL_NAME,
646 REG_KEY_READ, &sub_key);
647 if (!W_ERROR_IS_OK(werr)) {
648 d_fprintf(stderr, "Error opening subkey '%s' : %s\n",
649 subkey_name, dos_errstr(werr));
650 goto done;
652 d_printf("[%s]\n", GLOBAL_NAME);
653 if (!W_ERROR_IS_OK(list_values(ctx, sub_key))) {
654 goto done;
656 d_printf("\n");
659 for (idx_key = 0;
660 W_ERROR_IS_OK(werr = reg_enumkey(ctx, base_key, idx_key,
661 &subkey_name, NULL));
662 idx_key++)
664 if (strequal(subkey_name, GLOBAL_NAME)) {
665 continue;
667 d_printf("[%s]\n", subkey_name);
669 werr = reg_openkey(ctx, base_key, subkey_name,
670 REG_KEY_READ, &sub_key);
671 if (!W_ERROR_IS_OK(werr)) {
672 d_fprintf(stderr,
673 "Error opening subkey '%s': %s\n",
674 subkey_name, dos_errstr(werr));
675 goto done;
677 if (!W_ERROR_IS_OK(list_values(ctx, sub_key))) {
678 goto done;
680 d_printf("\n");
682 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
683 d_fprintf(stderr, "Error enumerating subkeys: %s\n",
684 dos_errstr(werr));
685 goto done;
688 ret = 0;
690 done:
691 TALLOC_FREE(ctx);
692 return ret;
695 int net_conf_import(int argc, const char **argv)
697 int ret = -1;
698 const char *filename = NULL;
699 const char *servicename = NULL;
700 bool service_found = False;
701 TALLOC_CTX *ctx;
702 struct share_iterator *shares;
703 struct share_params *share;
704 struct share_params global_share = { GLOBAL_SECTION_SNUM };
706 ctx = talloc_init("net_conf_import");
708 switch (argc) {
709 case 0:
710 default:
711 net_conf_import_usage(argc, argv);
712 goto done;
713 case 2:
714 servicename = argv[1];
715 case 1:
716 filename = argv[0];
717 break;
720 DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
721 filename));
723 if (!lp_load(filename,
724 False, /* global_only */
725 True, /* save_defaults */
726 False, /* add_ipc */
727 True)) /* initialize_globals */
729 d_fprintf(stderr, "Error parsing configuration file.\n");
730 goto done;
733 if (opt_testmode) {
734 d_printf("\nTEST MODE - "
735 "would import the following configuration:\n\n");
738 if (((servicename == NULL) && globals_exist()) ||
739 strequal(servicename, GLOBAL_NAME))
741 service_found = True;
742 if (import_process_service(ctx, &global_share) != 0) {
743 goto done;
747 if (service_found && (servicename != NULL)) {
748 ret = 0;
749 goto done;
752 if (!(shares = share_list_all(ctx))) {
753 d_fprintf(stderr, "Could not list shares...\n");
754 goto done;
756 while ((share = next_share(shares)) != NULL) {
757 if ((servicename == NULL)
758 || strequal(servicename, lp_servicename(share->service)))
760 service_found = True;
761 if (import_process_service(ctx, share)!= 0) {
762 goto done;
767 if ((servicename != NULL) && !service_found) {
768 d_printf("Share %s not found in file %s\n",
769 servicename, filename);
770 goto done;
774 ret = 0;
776 done:
777 TALLOC_FREE(ctx);
778 return ret;
781 int net_conf_listshares(int argc, const char **argv)
783 WERROR werr = WERR_OK;
784 int ret = -1;
785 struct registry_key *key;
786 uint32 idx = 0;
787 char *subkey_name = NULL;
788 TALLOC_CTX *ctx;
790 ctx = talloc_init("listshares");
792 if (argc != 0) {
793 net_conf_listshares_usage(argc, argv);
794 goto done;
797 werr = smbconf_open_basepath(ctx, SEC_RIGHTS_ENUM_SUBKEYS, &key);
798 if (!W_ERROR_IS_OK(werr)) {
799 goto done;
802 for (idx = 0;
803 W_ERROR_IS_OK(werr = reg_enumkey(ctx, key, idx,
804 &subkey_name, NULL));
805 idx++)
807 d_printf("%s\n", subkey_name);
809 if (! W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
810 d_fprintf(stderr, "Error enumerating subkeys: %s\n",
811 dos_errstr(werr));
812 goto done;
815 ret = 0;
817 done:
818 TALLOC_FREE(ctx);
819 return ret;
822 int net_conf_drop(int argc, const char **argv)
824 int ret = -1;
825 WERROR werr;
827 if (argc != 0) {
828 net_conf_drop_usage(argc, argv);
829 goto done;
832 werr = drop_smbconf_internal(NULL);
833 if (!W_ERROR_IS_OK(werr)) {
834 d_fprintf(stderr, "Error deleting configuration: %s\n",
835 dos_errstr(werr));
836 goto done;
839 ret = 0;
841 done:
842 return ret;
845 int net_conf_showshare(int argc, const char **argv)
847 int ret = -1;
848 WERROR werr = WERR_OK;
849 struct registry_key *key = NULL;
850 TALLOC_CTX *ctx;
852 ctx = talloc_init("showshare");
854 if (argc != 1) {
855 net_conf_showshare_usage(argc, argv);
856 goto done;
859 werr = smbconf_open_path(ctx, argv[0], REG_KEY_READ, &key);
860 if (!W_ERROR_IS_OK(werr)) {
861 goto done;
864 d_printf("[%s]\n", argv[0]);
866 if (!W_ERROR_IS_OK(list_values(ctx, key))) {
867 goto done;
870 ret = 0;
872 done:
873 TALLOC_FREE(ctx);
874 return ret;
877 int net_conf_addshare(int argc, const char **argv)
879 int ret = -1;
880 WERROR werr = WERR_OK;
881 struct registry_key *newkey = NULL;
882 char *sharename = NULL;
883 const char *path = NULL;
884 const char *comment = NULL;
885 const char *guest_ok = "no";
886 const char *writeable = "no";
887 SMB_STRUCT_STAT sbuf;
889 switch (argc) {
890 case 0:
891 case 1:
892 default:
893 net_conf_addshare_usage(argc, argv);
894 goto done;
895 case 5:
896 comment = argv[4];
897 case 4:
898 if (!strnequal(argv[3], "guest_ok=", 9)) {
899 net_conf_addshare_usage(argc, argv);
900 goto done;
902 switch (argv[3][9]) {
903 case 'y':
904 case 'Y':
905 guest_ok = "yes";
906 break;
907 case 'n':
908 case 'N':
909 guest_ok = "no";
910 break;
911 default:
912 net_conf_addshare_usage(argc, argv);
913 goto done;
915 case 3:
916 if (!strnequal(argv[2], "writeable=", 10)) {
917 net_conf_addshare_usage(argc, argv);
918 goto done;
920 switch (argv[2][10]) {
921 case 'y':
922 case 'Y':
923 writeable = "yes";
924 break;
925 case 'n':
926 case 'N':
927 writeable = "no";
928 break;
929 default:
930 net_conf_addshare_usage(argc, argv);
931 goto done;
934 case 2:
935 path = argv[1];
936 sharename = strdup_lower(argv[0]);
937 break;
941 * validate arguments
944 /* validate share name */
946 if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
947 strlen(sharename)))
949 d_fprintf(stderr, "ERROR: share name %s contains "
950 "invalid characters (any of %s)\n",
951 sharename, INVALID_SHARENAME_CHARS);
952 goto done;
955 if (getpwnam(sharename)) {
956 d_fprintf(stderr, "ERROR: share name %s is already a valid "
957 "system user name.\n", sharename);
958 goto done;
961 if (strequal(sharename, GLOBAL_NAME)) {
962 d_fprintf(stderr,
963 "ERROR: 'global' is not a valid share name.\n");
964 goto done;
967 /* validate path */
969 if (path[0] != '/') {
970 d_fprintf(stderr,
971 "Error: path '%s' is not an absolute path.\n",
972 path);
973 goto done;
976 if (sys_stat(path, &sbuf) != 0) {
977 d_fprintf(stderr,
978 "ERROR: cannot stat path '%s' to ensure "
979 "this is a directory.\n"
980 "Error was '%s'.\n",
981 path, strerror(errno));
982 goto done;
985 if (!S_ISDIR(sbuf.st_mode)) {
986 d_fprintf(stderr,
987 "ERROR: path '%s' is not a directory.\n",
988 path);
989 goto done;
993 * create the share
996 werr = reg_createkey_internal(NULL, argv[0], &newkey);
997 if (!W_ERROR_IS_OK(werr)) {
998 goto done;
1001 /* add config params as values */
1003 werr = reg_setvalue_internal(newkey, "path", path);
1004 if (!W_ERROR_IS_OK(werr))
1005 goto done;
1007 if (comment != NULL) {
1008 werr = reg_setvalue_internal(newkey, "comment", comment);
1009 if (!W_ERROR_IS_OK(werr))
1010 goto done;
1013 werr = reg_setvalue_internal(newkey, "guest ok", guest_ok);
1014 if (!W_ERROR_IS_OK(werr))
1015 goto done;
1017 werr = reg_setvalue_internal(newkey, "writeable", writeable);
1018 if (!W_ERROR_IS_OK(werr))
1019 goto done;
1021 ret = 0;
1023 done:
1024 TALLOC_FREE(newkey);
1025 SAFE_FREE(sharename);
1026 return ret;
1029 int net_conf_delshare(int argc, const char **argv)
1031 int ret = -1;
1032 const char *sharename = NULL;
1034 if (argc != 1) {
1035 net_conf_delshare_usage(argc, argv);
1036 goto done;
1038 sharename = argv[0];
1040 if (W_ERROR_IS_OK(reg_delkey_internal(NULL, sharename))) {
1041 ret = 0;
1043 done:
1044 return ret;
1047 static int net_conf_setparm(int argc, const char **argv)
1049 int ret = -1;
1050 WERROR werr = WERR_OK;
1051 struct registry_key *key = NULL;
1052 char *service = NULL;
1053 char *param = NULL;
1054 const char *value_str = NULL;
1055 TALLOC_CTX *ctx;
1057 ctx = talloc_init("setparm");
1059 if (argc != 3) {
1060 net_conf_setparm_usage(argc, argv);
1061 goto done;
1063 service = strdup_lower(argv[0]);
1064 param = strdup_lower(argv[1]);
1065 value_str = argv[2];
1067 if (!smbconf_key_exists(ctx, service)) {
1068 werr = reg_createkey_internal(ctx, service, &key);
1069 } else {
1070 werr = smbconf_open_path(ctx, service, REG_KEY_READ, &key);
1072 if (!W_ERROR_IS_OK(werr)) {
1073 goto done;
1076 werr = reg_setvalue_internal(key, param, value_str);
1077 if (!W_ERROR_IS_OK(werr)) {
1078 d_fprintf(stderr, "Error setting value '%s': %s\n",
1079 param, dos_errstr(werr));
1080 goto done;
1084 ret = 0;
1086 done:
1087 SAFE_FREE(service);
1088 TALLOC_FREE(ctx);
1089 return ret;
1092 static int net_conf_getparm(int argc, const char **argv)
1094 int ret = -1;
1095 WERROR werr = WERR_OK;
1096 struct registry_key *key = NULL;
1097 char *service = NULL;
1098 char *param = NULL;
1099 struct registry_value *value = NULL;
1100 TALLOC_CTX *ctx;
1102 ctx = talloc_init("getparm");
1104 if (argc != 2) {
1105 net_conf_getparm_usage(argc, argv);
1106 goto done;
1108 service = strdup_lower(argv[0]);
1109 param = strdup_lower(argv[1]);
1111 if (!smbconf_key_exists(ctx, service)) {
1112 d_fprintf(stderr,
1113 "ERROR: given service '%s' does not exist.\n",
1114 service);
1115 goto done;
1118 werr = smbconf_open_path(ctx, service, REG_KEY_READ, &key);
1119 if (!W_ERROR_IS_OK(werr)) {
1120 goto done;
1123 werr = reg_queryvalue(ctx, key, param, &value);
1124 if (!W_ERROR_IS_OK(werr)) {
1125 d_fprintf(stderr, "Error querying value '%s': %s.\n",
1126 param, dos_errstr(werr));
1127 goto done;
1130 d_printf("%s\n", format_value(ctx, value));
1132 ret = 0;
1133 done:
1134 SAFE_FREE(service);
1135 SAFE_FREE(param);
1136 TALLOC_FREE(ctx);
1137 return ret;
1140 static int net_conf_delparm(int argc, const char **argv)
1142 int ret = -1;
1143 WERROR werr = WERR_OK;
1144 struct registry_key *key = NULL;
1145 char *service = NULL;
1146 char *param = NULL;
1147 TALLOC_CTX *ctx;
1149 ctx = talloc_init("delparm");
1151 if (argc != 2) {
1152 net_conf_delparm_usage(argc, argv);
1153 goto done;
1155 service = strdup_lower(argv[0]);
1156 param = strdup_lower(argv[1]);
1158 if (!smbconf_key_exists(ctx, service)) {
1159 d_fprintf(stderr,
1160 "Error: given service '%s' does not exist.\n",
1161 service);
1162 goto done;
1165 werr = smbconf_open_path(ctx, service, REG_KEY_READ, &key);
1166 if (!W_ERROR_IS_OK(werr)) {
1167 goto done;
1170 if (!smbconf_value_exists(ctx, key, param)) {
1171 d_fprintf(stderr,
1172 "Error: given parameter '%s' is not set.\n",
1173 param);
1174 goto done;
1176 werr = reg_deletevalue(key, param);
1177 if (!W_ERROR_IS_OK(werr)) {
1178 d_fprintf(stderr, "Error deleting value '%s': %s.\n",
1179 param, dos_errstr(werr));
1180 goto done;
1183 ret = 0;
1185 done:
1186 return ret;
1190 * Entry-point for all the CONF functions.
1193 int net_conf(int argc, const char **argv)
1195 int ret = -1;
1196 struct functable2 func[] = {
1197 {"list", net_conf_list,
1198 "Dump the complete configuration in smb.conf like format."},
1199 {"import", net_conf_import,
1200 "Import configuration from file in smb.conf format."},
1201 {"listshares", net_conf_listshares,
1202 "List the registry shares."},
1203 {"drop", net_conf_drop,
1204 "Delete the complete configuration from registry."},
1205 {"showshare", net_conf_showshare,
1206 "Show the definition of a registry share."},
1207 {"addshare", net_conf_addshare,
1208 "Create a new registry share."},
1209 {"delshare", net_conf_delshare,
1210 "Delete a registry share."},
1211 {"setparm", net_conf_setparm,
1212 "Store a parameter."},
1213 {"getparm", net_conf_getparm,
1214 "Retrieve the value of a parameter."},
1215 {"delparm", net_conf_delparm,
1216 "Delete a parameter."},
1217 {NULL, NULL, NULL}
1220 if (!registry_init_regdb()) {
1221 d_fprintf(stderr, "Error initializing the registry!\n");
1222 goto done;
1225 ret = net_run_function2(argc, argv, "net conf", func);
1227 regdb_close();
1229 done:
1230 return ret;