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 2 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, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * This is an interface to the configuration stored inside the
24 * samba registry. In the future there might be support for other
25 * configuration backends as well.
29 #include "utils/net.h"
35 static int net_conf_list_usage(int argc
, const char **argv
)
37 d_printf("USAGE: net conf list\n");
41 static int net_conf_import_usage(int argc
, const char**argv
)
43 d_printf("USAGE: net conf import [--test|-T] <filename> [<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>, "
51 static int net_conf_listshares_usage(int argc
, const char **argv
)
53 d_printf("USAGE: net conf listshares\n");
57 static int net_conf_drop_usage(int argc
, const char **argv
)
59 d_printf("USAGE: net conf drop\n");
63 static int net_conf_showshare_usage(int argc
, const char **argv
)
65 d_printf("USAGE: net conf showshare <sharename>\n");
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");
83 static int net_conf_delshare_usage(int argc
, const char **argv
)
85 d_printf("USAGE: net conf delshare <sharename>\n");
89 static int net_conf_setparm_usage(int argc
, const char **argv
)
91 d_printf("USAGE: net conf setparm <section> <param> <value>\n");
95 static int net_conf_getparm_usage(int argc
, const char **argv
)
97 d_printf("USAGE: net conf getparm <section> <param>\n");
101 static int net_conf_delparm_usage(int argc
, const char **argv
)
103 d_printf("USAGE: net conf delparm <section> <param>\n");
112 static char *format_value(TALLOC_CTX
*mem_ctx
, struct registry_value
*value
)
116 /* what if mem_ctx = NULL? */
118 switch (value
->type
) {
120 result
= talloc_asprintf(mem_ctx
, "%d", value
->v
.dword
);
124 result
= talloc_asprintf(mem_ctx
, "%s", value
->v
.sz
.str
);
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
]);
135 result
= talloc_asprintf(mem_ctx
, "binary (%d bytes)",
136 (int)value
->v
.binary
.length
);
139 result
= talloc_asprintf(mem_ctx
, "<unprintable>");
146 * add a value to a key.
148 static WERROR
reg_setvalue_internal(struct registry_key
*key
,
153 struct registry_value val
;
154 WERROR werr
= WERR_OK
;
158 if (strequal(valtype
, "dword")) {
159 val
.type
= REG_DWORD
;
160 val
.v
.dword
= strtoul(valstr
, NULL
, 10);
162 else if (strequal(valtype
, "sz")) {
164 val
.v
.sz
.str
= CONST_DISCARD(char *, valstr
);
165 val
.v
.sz
.len
= strlen(valstr
) + 1;
168 d_fprintf(stderr
, "Sorry, only value types DWORD and SZ implementd currently for setting values.\n");
172 werr
= reg_setvalue(key
, valname
, &val
);
173 if (!W_ERROR_IS_OK(werr
)) {
175 "Error adding value '%s' to "
177 valname
, key
->key
->name
, dos_errstr(werr
));
185 * Open a subkey of KEY_SMBCONF (i.e a service)
186 * - variant without error output (q = quiet)-
188 static WERROR
smbconf_open_path_q(TALLOC_CTX
*ctx
, const char *subkeyname
,
189 uint32 desired_access
,
190 struct registry_key
**key
)
192 WERROR werr
= WERR_OK
;
194 NT_USER_TOKEN
*token
;
196 if (!(token
= registry_create_admin_token(ctx
))) {
197 DEBUG(1, ("Error creating admin token\n"));
201 if (subkeyname
== NULL
) {
202 path
= talloc_strdup(ctx
, KEY_SMBCONF
);
205 path
= talloc_asprintf(ctx
, "%s\\%s", KEY_SMBCONF
, subkeyname
);
208 werr
= reg_open_path(ctx
, path
, desired_access
,
217 * Open a subkey of KEY_SMBCONF (i.e a service)
218 * - variant with error output -
220 static WERROR
smbconf_open_path(TALLOC_CTX
*ctx
, const char *subkeyname
,
221 uint32 desired_access
,
222 struct registry_key
**key
)
224 WERROR werr
= WERR_OK
;
226 werr
= smbconf_open_path_q(ctx
, subkeyname
, desired_access
, key
);
227 if (!W_ERROR_IS_OK(werr
)) {
228 d_fprintf(stderr
, "Error opening registry path '%s\\%s': %s\n",
230 (subkeyname
== NULL
) ? "" : subkeyname
,
238 * open the base key KEY_SMBCONF
240 static WERROR
smbconf_open_basepath(TALLOC_CTX
*ctx
, uint32 desired_access
,
241 struct registry_key
**key
)
243 return smbconf_open_path(ctx
, NULL
, desired_access
, key
);
247 * delete a subkey of KEY_SMBCONF
249 static WERROR
reg_delkey_internal(TALLOC_CTX
*ctx
, const char *keyname
)
251 WERROR werr
= WERR_OK
;
252 struct registry_key
*key
= NULL
;
254 werr
= smbconf_open_basepath(ctx
, REG_KEY_WRITE
, &key
);
255 if (!W_ERROR_IS_OK(werr
)) {
259 werr
= reg_deletekey(key
, keyname
);
260 if (!W_ERROR_IS_OK(werr
)) {
261 d_fprintf(stderr
, "Error deleting registry key %s\\%s: %s\n",
262 KEY_SMBCONF
, keyname
, dos_errstr(werr
));
271 * create a subkey of KEY_SMBCONF
273 static WERROR
reg_createkey_internal(TALLOC_CTX
*ctx
,
274 const char * subkeyname
,
275 struct registry_key
**newkey
)
277 WERROR werr
= WERR_OK
;
278 struct registry_key
*create_parent
= NULL
;
279 TALLOC_CTX
*create_ctx
;
280 enum winreg_CreateAction action
= REG_ACTION_NONE
;
282 /* create a new talloc ctx for creation. it will hold
283 * the intermediate parent key (SMBCONF) for creation
284 * and will be destroyed when leaving this function... */
285 if (!(create_ctx
= talloc_new(ctx
))) {
290 werr
= smbconf_open_basepath(create_ctx
, REG_KEY_WRITE
, &create_parent
);
291 if (!W_ERROR_IS_OK(werr
)) {
295 werr
= reg_createkey(ctx
, create_parent
, subkeyname
,
296 REG_KEY_WRITE
, newkey
, &action
);
297 if (W_ERROR_IS_OK(werr
) && (action
!= REG_CREATED_NEW_KEY
)) {
298 d_fprintf(stderr
, "Key '%s' already exists.\n", subkeyname
);
299 werr
= WERR_ALREADY_EXISTS
;
301 if (!W_ERROR_IS_OK(werr
)) {
302 d_fprintf(stderr
, "Error creating key %s: %s\n",
303 subkeyname
, dos_errstr(werr
));
307 TALLOC_FREE(create_ctx
);
312 * check if a subkey of KEY_SMBCONF of a given name exists
314 static BOOL
smbconf_key_exists(TALLOC_CTX
*ctx
, const char *subkeyname
)
317 WERROR werr
= WERR_OK
;
319 struct registry_key
*key
;
321 if (!(mem_ctx
= talloc_new(ctx
))) {
322 d_fprintf(stderr
, "ERROR: Out of memory...!\n");
326 werr
= smbconf_open_path_q(mem_ctx
, subkeyname
, REG_KEY_READ
, &key
);
327 if (W_ERROR_IS_OK(werr
)) {
332 TALLOC_FREE(mem_ctx
);
336 static BOOL
smbconf_value_exists(TALLOC_CTX
*ctx
, struct registry_key
*key
,
340 WERROR werr
= WERR_OK
;
341 struct registry_value
*value
= NULL
;
343 werr
= reg_queryvalue(ctx
, key
, param
, &value
);
344 if (W_ERROR_IS_OK(werr
)) {
352 static WERROR
list_values(TALLOC_CTX
*ctx
, struct registry_key
*key
)
354 WERROR werr
= WERR_OK
;
356 struct registry_value
*valvalue
= NULL
;
357 char *valname
= NULL
;
360 W_ERROR_IS_OK(werr
= reg_enumvalue(ctx
, key
, idx
, &valname
,
364 d_printf("\t%s = %s\n", valname
, format_value(ctx
, valvalue
));
366 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
367 d_fprintf(stderr
, "Error enumerating values: %s\n",
377 static WERROR
drop_smbconf_internal(TALLOC_CTX
*ctx
)
380 WERROR werr
= WERR_OK
;
381 NT_USER_TOKEN
*token
;
382 struct registry_key
*parent_key
= NULL
;
383 struct registry_key
*new_key
= NULL
;
384 TALLOC_CTX
* tmp_ctx
= NULL
;
385 enum winreg_CreateAction action
;
387 tmp_ctx
= talloc_new(ctx
);
388 if (tmp_ctx
== NULL
) {
393 if (!(token
= registry_create_admin_token(tmp_ctx
))) {
394 /* what is the appropriate error code here? */
395 werr
= WERR_CAN_NOT_COMPLETE
;
399 path
= talloc_strdup(tmp_ctx
, KEY_SMBCONF
);
401 d_fprintf(stderr
, "ERROR: out of memory!\n");
405 p
= strrchr(path
, '\\');
407 werr
= reg_open_path(tmp_ctx
, path
, REG_KEY_WRITE
, token
, &parent_key
);
409 if (!W_ERROR_IS_OK(werr
)) {
413 werr
= reg_deletekey_recursive(tmp_ctx
, parent_key
, p
+1);
415 if (!W_ERROR_IS_OK(werr
)) {
419 werr
= reg_createkey(tmp_ctx
, parent_key
, p
+1, REG_KEY_WRITE
,
423 TALLOC_FREE(tmp_ctx
);
427 static int import_process_service(TALLOC_CTX
*ctx
,
428 struct share_params
*share
)
431 struct parm_struct
*parm
;
433 const char *servicename
;
434 struct registry_key
*key
;
436 const char *valtype
= NULL
;
439 servicename
= (share
->service
== GLOBAL_SECTION_SNUM
)?
440 GLOBAL_NAME
: lp_servicename(share
->service
);
443 d_printf("[%s]\n", servicename
);
446 if (smbconf_key_exists(ctx
, servicename
)) {
447 werr
= reg_delkey_internal(ctx
, servicename
);
448 if (!W_ERROR_IS_OK(werr
)) {
452 werr
= reg_createkey_internal(ctx
, servicename
, &key
);
453 if (!W_ERROR_IS_OK(werr
)) {
458 while ((parm
= lp_next_parameter(share
->service
, &pnum
, 0)))
460 void *ptr
= parm
->ptr
;
463 if ((share
->service
< 0 && parm
->p_class
== P_LOCAL
)
464 && !(parm
->flags
& FLAG_GLOBAL
))
467 if (parm
->p_class
== P_LOCAL
&& share
->service
>= 0) {
468 ptr
= lp_local_ptr(share
->service
, ptr
);
473 switch (parm
->type
) {
475 valstr
= talloc_asprintf(ctx
, "%c", *(char *)ptr
);
479 valstr
= talloc_asprintf(ctx
, "%s", *(char **)ptr
);
483 valstr
= talloc_asprintf(ctx
, "%s", (char *)ptr
);
486 valstr
= talloc_asprintf(ctx
, "%s",
487 BOOLSTR(*(BOOL
*)ptr
));
490 valstr
= talloc_asprintf(ctx
, "%s",
491 BOOLSTR(!*(BOOL
*)ptr
));
494 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
496 parm
->enum_list
[i
].value
)
498 valstr
= talloc_asprintf(ctx
, "%s",
499 parm
->enum_list
[i
].name
);
505 talloc_asprintf(ctx
, "%s", octal_string(*(int *)ptr
));
508 valstr
= talloc_strdup(ctx
, "");
509 if ((char ***)ptr
&& *(char ***)ptr
) {
510 char **list
= *(char ***)ptr
;
511 for (; *list
; list
++) {
512 /* surround strings with whitespace
513 * in double quotes */
514 if (strchr_m(*list
, ' '))
516 valstr
= talloc_asprintf_append(
519 ((*(list
+1))?", ":""));
522 valstr
= talloc_asprintf_append(
523 valstr
, "%s%s", *list
,
524 ((*(list
+1))?", ":""));
531 talloc_asprintf(ctx
, "%d", *(int *)ptr
);
536 valstr
= talloc_asprintf(ctx
, "<type unimplemented>\n");
540 if (parm
->type
!= P_SEP
) {
542 d_printf("\t%s = %s\n", parm
->label
, valstr
);
545 werr
= reg_setvalue_internal(key
, parm
->label
,
547 if (!W_ERROR_IS_OK(werr
)) {
568 int net_conf_list(int argc
, const char **argv
)
570 WERROR werr
= WERR_OK
;
573 struct registry_key
*base_key
= NULL
;
574 struct registry_key
*sub_key
= NULL
;
576 char *subkey_name
= NULL
;
578 ctx
= talloc_init("list");
581 net_conf_list_usage(argc
, argv
);
585 werr
= smbconf_open_basepath(ctx
, REG_KEY_READ
, &base_key
);
586 if (!W_ERROR_IS_OK(werr
)) {
590 if (smbconf_key_exists(ctx
, GLOBAL_NAME
)) {
591 werr
= reg_openkey(ctx
, base_key
, GLOBAL_NAME
,
592 REG_KEY_READ
, &sub_key
);
593 if (!W_ERROR_IS_OK(werr
)) {
594 d_fprintf(stderr
, "Error opening subkey '%s' : %s\n",
595 subkey_name
, dos_errstr(werr
));
598 d_printf("[%s]\n", GLOBAL_NAME
);
599 if (!W_ERROR_IS_OK(list_values(ctx
, sub_key
))) {
606 W_ERROR_IS_OK(werr
= reg_enumkey(ctx
, base_key
, idx_key
,
607 &subkey_name
, NULL
));
610 if (strequal(subkey_name
, GLOBAL_NAME
)) {
613 d_printf("[%s]\n", subkey_name
);
615 werr
= reg_openkey(ctx
, base_key
, subkey_name
,
616 REG_KEY_READ
, &sub_key
);
617 if (!W_ERROR_IS_OK(werr
)) {
619 "Error opening subkey '%s': %s\n",
620 subkey_name
, dos_errstr(werr
));
623 if (!W_ERROR_IS_OK(list_values(ctx
, sub_key
))) {
628 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
629 d_fprintf(stderr
, "Error enumerating subkeys: %s\n",
641 int net_conf_import(int argc
, const char **argv
)
644 const char *filename
= NULL
;
645 const char *servicename
= NULL
;
646 BOOL service_found
= False
;
648 struct share_iterator
*shares
;
649 struct share_params
*share
;
650 struct share_params global_share
= { GLOBAL_SECTION_SNUM
};
652 ctx
= talloc_init("net_conf_import");
657 net_conf_import_usage(argc
, argv
);
660 servicename
= argv
[1];
666 DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
669 /* TODO: check for existence and readability */
671 if (!lp_load(filename
,
672 False
, /* global_only */
673 True
, /* save_defaults */
675 True
)) /* initialize_globals */
677 d_fprintf(stderr
, "Error parsing configuration file.\n");
682 d_printf("\nTEST MODE - would import the following configuration:\n\n");
685 if ((servicename
== NULL
) || strequal(servicename
, GLOBAL_NAME
)) {
686 service_found
= True
;
687 if (import_process_service(ctx
, &global_share
) != 0) {
692 if (service_found
&& (servicename
!= NULL
)) {
697 if (!(shares
= share_list_all(ctx
))) {
698 d_fprintf(stderr
, "Could not list shares...\n");
701 while ((share
= next_share(shares
)) != NULL
) {
702 if ((servicename
== NULL
)
703 || strequal(servicename
, lp_servicename(share
->service
)))
705 service_found
= True
;
706 if (import_process_service(ctx
, share
)!= 0) {
712 if ((servicename
!= NULL
) && !service_found
) {
713 d_printf("Share %s not found in file %s\n",
714 servicename
, filename
);
726 int net_conf_listshares(int argc
, const char **argv
)
728 WERROR werr
= WERR_OK
;
730 struct registry_key
*key
;
732 char *subkey_name
= NULL
;
735 ctx
= talloc_init("listshares");
738 net_conf_listshares_usage(argc
, argv
);
742 werr
= smbconf_open_basepath(ctx
, SEC_RIGHTS_ENUM_SUBKEYS
, &key
);
743 if (!W_ERROR_IS_OK(werr
)) {
748 W_ERROR_IS_OK(werr
= reg_enumkey(ctx
, key
, idx
,
749 &subkey_name
, NULL
));
752 d_printf("%s\n", subkey_name
);
754 if (! W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
755 d_fprintf(stderr
, "Error enumerating subkeys: %s\n",
767 int net_conf_drop(int argc
, const char **argv
)
773 net_conf_drop_usage(argc
, argv
);
777 werr
= drop_smbconf_internal(NULL
);
778 if (!W_ERROR_IS_OK(werr
)) {
779 d_fprintf(stderr
, "Error deleting configuration: %s\n",
790 int net_conf_showshare(int argc
, const char **argv
)
793 WERROR werr
= WERR_OK
;
794 struct registry_key
*key
= NULL
;
797 ctx
= talloc_init("showshare");
800 net_conf_showshare_usage(argc
, argv
);
804 werr
= smbconf_open_path(ctx
, argv
[0], REG_KEY_READ
, &key
);
805 if (!W_ERROR_IS_OK(werr
)) {
809 d_printf("[%s]\n", argv
[0]);
811 if (!W_ERROR_IS_OK(list_values(ctx
, key
))) {
822 int net_conf_addshare(int argc
, const char **argv
)
825 WERROR werr
= WERR_OK
;
826 struct registry_key
*newkey
= NULL
;
827 char *sharename
= NULL
;
828 const char *path
= NULL
;
829 const char *comment
= NULL
;
830 const char *guest_ok
= "no";
831 const char *writeable
= "no";
832 SMB_STRUCT_STAT sbuf
;
838 net_conf_addshare_usage(argc
, argv
);
843 if (!strnequal(argv
[3], "guest_ok=", 9)) {
844 net_conf_addshare_usage(argc
, argv
);
847 switch (argv
[3][9]) {
857 net_conf_addshare_usage(argc
, argv
);
861 if (!strnequal(argv
[2], "writeable=", 10)) {
862 net_conf_addshare_usage(argc
, argv
);
865 switch (argv
[2][10]) {
875 net_conf_addshare_usage(argc
, argv
);
881 sharename
= strdup_lower(argv
[0]);
889 /* validate share name */
891 if (!validate_net_name(sharename
, INVALID_SHARENAME_CHARS
,
894 d_fprintf(stderr
, "ERROR: share name %s contains "
895 "invalid characters (any of %s)\n",
896 sharename
, INVALID_SHARENAME_CHARS
);
900 if (getpwnam(sharename
)) {
901 d_fprintf(stderr
, "ERROR: share name %s is already a valid "
902 "system user name.\n", sharename
);
906 if (strequal(sharename
, GLOBAL_NAME
)) {
908 "ERROR: 'global' is not a valid share name.\n");
914 if (path
[0] != '/') {
916 "Error: path '%s' is not an absolute path.\n",
921 if (sys_stat(path
, &sbuf
) != 0) {
923 "ERROR: cannot stat path '%s' to ensure "
924 "this is a directory.\n"
926 path
, strerror(errno
));
930 if (!S_ISDIR(sbuf
.st_mode
)) {
932 "ERROR: path '%s' is not a directory.\n",
941 werr
= reg_createkey_internal(NULL
, argv
[0], &newkey
);
942 if (!W_ERROR_IS_OK(werr
)) {
946 /* add config params as values */
948 werr
= reg_setvalue_internal(newkey
, "path", "sz", path
);
949 if (!W_ERROR_IS_OK(werr
))
952 if (comment
!= NULL
) {
953 werr
= reg_setvalue_internal(newkey
, "comment", "sz", comment
);
954 if (!W_ERROR_IS_OK(werr
))
958 werr
= reg_setvalue_internal(newkey
, "guest ok", "sz", guest_ok
);
959 if (!W_ERROR_IS_OK(werr
))
962 werr
= reg_setvalue_internal(newkey
, "writeable", "sz", writeable
);
963 if (!W_ERROR_IS_OK(werr
))
970 SAFE_FREE(sharename
);
974 int net_conf_delshare(int argc
, const char **argv
)
977 const char *sharename
= NULL
;
980 net_conf_delshare_usage(argc
, argv
);
985 if (W_ERROR_IS_OK(reg_delkey_internal(NULL
, sharename
))) {
992 static int net_conf_setparm(int argc
, const char **argv
)
995 WERROR werr
= WERR_OK
;
996 struct registry_key
*key
= NULL
;
997 char *service
= NULL
;
999 const char *value_str
= NULL
;
1002 ctx
= talloc_init("setparm");
1005 net_conf_setparm_usage(argc
, argv
);
1008 service
= strdup_lower(argv
[0]);
1009 param
= strdup_lower(argv
[1]);
1010 value_str
= argv
[2];
1012 if (!smbconf_key_exists(ctx
, service
)) {
1013 werr
= reg_createkey_internal(ctx
, service
, &key
);
1016 werr
= smbconf_open_path(ctx
, service
, REG_KEY_READ
, &key
);
1018 if (!W_ERROR_IS_OK(werr
)) {
1022 werr
= reg_setvalue_internal(key
, param
, "sz", value_str
);
1023 if (!W_ERROR_IS_OK(werr
)) {
1024 d_fprintf(stderr
, "Error setting value '%s': %s\n",
1025 param
, dos_errstr(werr
));
1038 static int net_conf_getparm(int argc
, const char **argv
)
1041 WERROR werr
= WERR_OK
;
1042 struct registry_key
*key
= NULL
;
1043 char *service
= NULL
;
1045 struct registry_value
*value
= NULL
;
1048 ctx
= talloc_init("getparm");
1051 net_conf_getparm_usage(argc
, argv
);
1054 service
= strdup_lower(argv
[0]);
1055 param
= strdup_lower(argv
[1]);
1057 if (!smbconf_key_exists(ctx
, service
)) {
1059 "ERROR: given service '%s' does not exist.\n",
1064 werr
= smbconf_open_path(ctx
, service
, REG_KEY_READ
, &key
);
1065 if (!W_ERROR_IS_OK(werr
)) {
1069 werr
= reg_queryvalue(ctx
, key
, param
, &value
);
1070 if (!W_ERROR_IS_OK(werr
)) {
1071 d_fprintf(stderr
, "Error querying value '%s': %s.\n",
1072 param
, dos_errstr(werr
));
1076 d_printf("%s\n", format_value(ctx
, value
));
1086 static int net_conf_delparm(int argc
, const char **argv
)
1089 WERROR werr
= WERR_OK
;
1090 struct registry_key
*key
= NULL
;
1091 char *service
= NULL
;
1095 ctx
= talloc_init("delparm");
1098 net_conf_delparm_usage(argc
, argv
);
1101 service
= strdup_lower(argv
[0]);
1102 param
= strdup_lower(argv
[1]);
1104 if (!smbconf_key_exists(ctx
, service
)) {
1106 "Error: given service '%s' does not exist.\n",
1111 werr
= smbconf_open_path(ctx
, service
, REG_KEY_READ
, &key
);
1112 if (!W_ERROR_IS_OK(werr
)) {
1116 if (!smbconf_value_exists(ctx
, key
, param
)) {
1118 "Error: given parameter '%s' is not set.\n",
1122 werr
= reg_deletevalue(key
, param
);
1123 if (!W_ERROR_IS_OK(werr
)) {
1124 d_fprintf(stderr
, "Error deleting value '%s': %s.\n",
1125 param
, dos_errstr(werr
));
1136 * Entry-point for all the CONF functions.
1139 int net_conf(int argc
, const char **argv
)
1142 struct functable2 func
[] = {
1143 {"list", net_conf_list
,
1144 "Dump the complete configuration in smb.conf like format."},
1145 {"import", net_conf_import
,
1146 "Import configuration from file in smb.conf format."},
1147 {"listshares", net_conf_listshares
,
1148 "List the registry shares."},
1149 {"drop", net_conf_drop
,
1150 "Delete the complete configuration from registry."},
1151 {"showshare", net_conf_showshare
,
1152 "Show the definition of a registry share."},
1153 {"addshare", net_conf_addshare
,
1154 "Create a new registry share."},
1155 {"delshare", net_conf_delshare
,
1156 "Delete a registry share."},
1157 {"setparm", net_conf_setparm
,
1158 "Store a parameter."},
1159 {"getparm", net_conf_getparm
,
1160 "Retrieve the value of a parameter."},
1161 {"delparm", net_conf_delparm
,
1162 "Delete a parameter."},
1166 if (!registry_init_regdb()) {
1167 d_fprintf(stderr
, "Error initializing the registry!\n");
1171 ret
= net_run_function2(argc
, argv
, "net conf", func
);