2 * Unix SMB/CIFS implementation.
3 * libnet smbconf registry Support
4 * Copyright (C) Michael Adam 2007-2008
5 * Copyright (C) Guenther Deschner 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 #include "smbconf_private.h"
24 /**********************************************************************
26 * Helper functions (mostly registry related)
28 **********************************************************************/
31 * add a string to a talloced array of strings.
33 static WERROR smbconf_add_string_to_array(TALLOC_CTX *mem_ctx,
38 char **new_array = NULL;
40 if ((array == NULL) || (string == NULL)) {
41 return WERR_INVALID_PARAM;
44 new_array = TALLOC_REALLOC_ARRAY(mem_ctx, *array, char *, count + 1);
45 if (new_array == NULL) {
49 new_array[count] = talloc_strdup(new_array, string);
50 if (new_array[count] == NULL) {
51 TALLOC_FREE(new_array);
61 * Open a registry key specified by "path"
63 static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx,
64 struct smbconf_ctx *ctx,
66 uint32 desired_access,
67 struct registry_key **key)
69 WERROR werr = WERR_OK;
72 DEBUG(1, ("Error: configuration is not open!\n"));
73 werr = WERR_INVALID_PARAM;
77 if (ctx->token == NULL) {
78 DEBUG(1, ("Error: token missing from smbconf_ctx. "
79 "was smbconf_open() called?\n"));
80 werr = WERR_INVALID_PARAM;
85 DEBUG(1, ("Error: NULL path string given\n"));
86 werr = WERR_INVALID_PARAM;
90 werr = reg_open_path(mem_ctx, path, desired_access, ctx->token, key);
92 if (!W_ERROR_IS_OK(werr)) {
93 DEBUG(1, ("Error opening registry path '%s': %s\n",
94 path, dos_errstr(werr)));
102 * Open a subkey of KEY_SMBCONF (i.e a service)
104 static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
105 struct smbconf_ctx *ctx,
106 const char *servicename,
107 uint32 desired_access,
108 struct registry_key **key)
110 WERROR werr = WERR_OK;
113 if (servicename == NULL) {
114 DEBUG(3, ("Error: NULL servicename given.\n"));
115 werr = WERR_INVALID_PARAM;
119 path = talloc_asprintf(mem_ctx, "%s\\%s", KEY_SMBCONF, servicename);
125 werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key);
133 * open the base key KEY_SMBCONF
135 static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx,
136 struct smbconf_ctx *ctx,
137 uint32 desired_access,
138 struct registry_key **key)
140 return smbconf_reg_open_path(mem_ctx, ctx, KEY_SMBCONF, desired_access,
145 * check if a value exists in a given registry key
147 static bool smbconf_value_exists(struct registry_key *key, const char *param)
150 WERROR werr = WERR_OK;
151 TALLOC_CTX *ctx = talloc_stackframe();
152 struct registry_value *value = NULL;
154 werr = reg_queryvalue(ctx, key, param, &value);
155 if (W_ERROR_IS_OK(werr)) {
164 * create a subkey of KEY_SMBCONF
166 static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
167 struct smbconf_ctx *ctx,
168 const char * subkeyname,
169 struct registry_key **newkey)
171 WERROR werr = WERR_OK;
172 struct registry_key *create_parent = NULL;
173 TALLOC_CTX *create_ctx;
174 enum winreg_CreateAction action = REG_ACTION_NONE;
176 /* create a new talloc ctx for creation. it will hold
177 * the intermediate parent key (SMBCONF) for creation
178 * and will be destroyed when leaving this function... */
179 if (!(create_ctx = talloc_stackframe())) {
184 werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE,
186 if (!W_ERROR_IS_OK(werr)) {
190 werr = reg_createkey(mem_ctx, create_parent, subkeyname,
191 REG_KEY_WRITE, newkey, &action);
192 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
193 DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
194 werr = WERR_ALREADY_EXISTS;
196 if (!W_ERROR_IS_OK(werr)) {
197 DEBUG(5, ("Error creating key %s: %s\n",
198 subkeyname, dos_errstr(werr)));
202 TALLOC_FREE(create_ctx);
207 * add a value to a key.
209 static WERROR smbconf_reg_set_value(struct registry_key *key,
213 struct registry_value val;
214 WERROR werr = WERR_OK;
216 const char *canon_valname;
217 const char *canon_valstr;
219 if (!lp_canonicalize_parameter_with_value(valname, valstr,
223 if (canon_valname == NULL) {
224 DEBUG(5, ("invalid parameter '%s' given\n",
227 DEBUG(5, ("invalid value '%s' given for "
228 "parameter '%s'\n", valstr, valname));
230 werr = WERR_INVALID_PARAM;
237 val.v.sz.str = CONST_DISCARD(char *, canon_valstr);
238 val.v.sz.len = strlen(canon_valstr) + 1;
240 if (registry_smbconf_valname_forbidden(canon_valname)) {
241 DEBUG(5, ("Parameter '%s' not allowed in registry.\n",
243 werr = WERR_INVALID_PARAM;
247 subkeyname = strrchr_m(key->key->name, '\\');
248 if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
249 DEBUG(5, ("Invalid registry key '%s' given as "
250 "smbconf section.\n", key->key->name));
251 werr = WERR_INVALID_PARAM;
255 if (!strequal(subkeyname, GLOBAL_NAME) &&
256 lp_parameter_is_global(valname))
258 DEBUG(5, ("Global paramter '%s' not allowed in "
259 "service definition ('%s').\n", canon_valname,
261 werr = WERR_INVALID_PARAM;
265 werr = reg_setvalue(key, canon_valname, &val);
266 if (!W_ERROR_IS_OK(werr)) {
267 DEBUG(5, ("Error adding value '%s' to "
269 canon_valname, key->key->name, dos_errstr(werr)));
277 * format a registry_value into a string.
279 * This is intended to be used for smbconf registry values,
280 * which are ar stored as REG_SZ values, so the incomplete
281 * handling should be ok.
283 static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx,
284 struct registry_value *value)
288 /* alternatively, create a new talloc context? */
289 if (mem_ctx == NULL) {
293 switch (value->type) {
295 result = talloc_asprintf(mem_ctx, "%d", value->v.dword);
299 result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str);
303 for (j = 0; j < value->v.multi_sz.num_strings; j++) {
304 result = talloc_asprintf(mem_ctx, "%s \"%s\" ",
306 value->v.multi_sz.strings[j]);
307 if (result == NULL) {
314 result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
315 (int)value->v.binary.length);
318 result = talloc_asprintf(mem_ctx, "<unprintable>");
325 * Get the values of a key as a list of value names
326 * and a list of value strings (ordered)
328 static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx,
329 struct registry_key *key,
330 uint32_t *num_values,
332 char ***value_strings)
334 TALLOC_CTX *tmp_ctx = NULL;
335 WERROR werr = WERR_OK;
337 struct registry_value *valvalue = NULL;
338 char *valname = NULL;
339 char **tmp_valnames = NULL;
340 char **tmp_valstrings = NULL;
342 if ((num_values == NULL) || (value_names == NULL) ||
343 (value_strings == NULL))
345 werr = WERR_INVALID_PARAM;
349 tmp_ctx = talloc_stackframe();
350 if (tmp_ctx == NULL) {
356 W_ERROR_IS_OK(werr = reg_enumvalue(tmp_ctx, key, count, &valname,
362 werr = smbconf_add_string_to_array(tmp_ctx,
365 if (!W_ERROR_IS_OK(werr)) {
369 valstring = smbconf_format_registry_value(tmp_ctx, valvalue);
370 werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings,
372 if (!W_ERROR_IS_OK(werr)) {
376 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
384 *value_names = talloc_move(mem_ctx, &tmp_valnames);
385 *value_strings = talloc_move(mem_ctx, &tmp_valstrings);
388 *value_strings = NULL;
392 TALLOC_FREE(tmp_ctx);
396 static int smbconf_destroy_ctx(struct smbconf_ctx *ctx)
398 return regdb_close();
401 static WERROR smbconf_global_check(struct smbconf_ctx *ctx)
403 if (!smbconf_share_exists(ctx, GLOBAL_NAME)) {
404 return smbconf_create_share(ctx, GLOBAL_NAME);
410 /**********************************************************************
412 * smbconf operations: registry implementations
414 **********************************************************************/
417 * initialize the registry smbconf backend
419 static WERROR smbconf_reg_init(struct smbconf_ctx *ctx)
421 WERROR werr = WERR_OK;
423 if (!registry_init_smbconf()) {
424 werr = WERR_REG_IO_FAILURE;
428 werr = ntstatus_to_werror(registry_create_admin_token(ctx,
430 if (!W_ERROR_IS_OK(werr)) {
431 DEBUG(1, ("Error creating admin token\n"));
440 * Get the change sequence number of the given service/parameter.
441 * service and parameter strings may be NULL.
443 static void smbconf_reg_get_csn(struct smbconf_ctx *ctx,
444 struct smbconf_csn *csn,
445 const char *service, const char *param)
450 csn->csn = (uint64_t)regdb_get_seqnum();
454 * Drop the whole configuration (restarting empty) - registry version
456 static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
459 WERROR werr = WERR_OK;
460 struct registry_key *parent_key = NULL;
461 struct registry_key *new_key = NULL;
462 TALLOC_CTX* mem_ctx = talloc_stackframe();
463 enum winreg_CreateAction action;
465 path = talloc_strdup(mem_ctx, KEY_SMBCONF);
470 p = strrchr(path, '\\');
472 werr = smbconf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE,
475 if (!W_ERROR_IS_OK(werr)) {
479 werr = reg_deletekey_recursive(mem_ctx, parent_key, p+1);
481 if (!W_ERROR_IS_OK(werr)) {
485 werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE,
489 TALLOC_FREE(mem_ctx);
494 * get the list of share names defined in the configuration.
497 static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
499 uint32_t *num_shares,
503 uint32_t added_count = 0;
504 TALLOC_CTX *tmp_ctx = NULL;
505 WERROR werr = WERR_OK;
506 struct registry_key *key = NULL;
507 char *subkey_name = NULL;
508 char **tmp_share_names = NULL;
510 if ((num_shares == NULL) || (share_names == NULL)) {
511 werr = WERR_INVALID_PARAM;
515 tmp_ctx = talloc_stackframe();
516 if (tmp_ctx == NULL) {
521 /* make sure "global" is always listed first */
522 if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
523 werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
525 if (!W_ERROR_IS_OK(werr)) {
531 werr = smbconf_reg_open_base_key(tmp_ctx, ctx,
532 SEC_RIGHTS_ENUM_SUBKEYS, &key);
533 if (!W_ERROR_IS_OK(werr)) {
538 W_ERROR_IS_OK(werr = reg_enumkey(tmp_ctx, key, count,
539 &subkey_name, NULL));
542 if (strequal(subkey_name, GLOBAL_NAME)) {
546 werr = smbconf_add_string_to_array(tmp_ctx,
550 if (!W_ERROR_IS_OK(werr)) {
555 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
560 *num_shares = added_count;
561 if (added_count > 0) {
562 *share_names = talloc_move(mem_ctx, &tmp_share_names);
568 TALLOC_FREE(tmp_ctx);
573 * check if a share/service of a given name exists - registry version
575 static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx,
576 const char *servicename)
579 WERROR werr = WERR_OK;
580 TALLOC_CTX *mem_ctx = talloc_stackframe();
581 struct registry_key *key = NULL;
583 werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
585 if (W_ERROR_IS_OK(werr)) {
589 TALLOC_FREE(mem_ctx);
594 * Add a service if it does not already exist - registry version
596 static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx,
597 const char *servicename)
600 TALLOC_CTX *mem_ctx = talloc_stackframe();
601 struct registry_key *key = NULL;
603 werr = smbconf_reg_create_service_key(mem_ctx, ctx, servicename, &key);
605 TALLOC_FREE(mem_ctx);
610 * get a definition of a share (service) from configuration.
612 static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx,
614 const char *servicename,
615 uint32_t *num_params,
616 char ***param_names, char ***param_values)
618 WERROR werr = WERR_OK;
619 struct registry_key *key = NULL;
621 werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename,
623 if (!W_ERROR_IS_OK(werr)) {
627 werr = smbconf_reg_get_values(mem_ctx, key, num_params,
628 param_names, param_values);
636 * delete a service from configuration
638 static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx,
639 const char *servicename)
641 WERROR werr = WERR_OK;
642 struct registry_key *key = NULL;
643 TALLOC_CTX *mem_ctx = talloc_stackframe();
645 werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key);
646 if (!W_ERROR_IS_OK(werr)) {
650 werr = reg_deletekey_recursive(key, key, servicename);
653 TALLOC_FREE(mem_ctx);
658 * set a configuration parameter to the value provided.
660 static WERROR smbconf_reg_set_parameter(struct smbconf_ctx *ctx,
666 struct registry_key *key = NULL;
667 TALLOC_CTX *mem_ctx = talloc_stackframe();
669 werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
670 REG_KEY_WRITE, &key);
671 if (!W_ERROR_IS_OK(werr)) {
675 werr = smbconf_reg_set_value(key, param, valstr);
678 TALLOC_FREE(mem_ctx);
683 * get the value of a configuration parameter as a string
685 static WERROR smbconf_reg_get_parameter(struct smbconf_ctx *ctx,
691 WERROR werr = WERR_OK;
692 struct registry_key *key = NULL;
693 struct registry_value *value = NULL;
695 werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
697 if (!W_ERROR_IS_OK(werr)) {
701 if (!smbconf_value_exists(key, param)) {
702 werr = WERR_INVALID_PARAM;
706 werr = reg_queryvalue(mem_ctx, key, param, &value);
707 if (!W_ERROR_IS_OK(werr)) {
711 *valstr = smbconf_format_registry_value(mem_ctx, value);
713 if (*valstr == NULL) {
724 * delete a parameter from configuration
726 static WERROR smbconf_reg_delete_parameter(struct smbconf_ctx *ctx,
730 struct registry_key *key = NULL;
731 WERROR werr = WERR_OK;
732 TALLOC_CTX *mem_ctx = talloc_stackframe();
734 werr = smbconf_reg_open_service_key(mem_ctx, ctx, service,
736 if (!W_ERROR_IS_OK(werr)) {
740 if (!smbconf_value_exists(key, param)) {
741 werr = WERR_INVALID_PARAM;
745 werr = reg_deletevalue(key, param);
748 TALLOC_FREE(mem_ctx);
752 struct smbconf_ops smbconf_ops_reg = {
753 .init = smbconf_reg_init,
754 .get_csn = smbconf_reg_get_csn,
755 .drop = smbconf_reg_drop,
756 .get_share_names = smbconf_reg_get_share_names,
757 .share_exists = smbconf_reg_share_exists,
758 .create_share = smbconf_reg_create_share,
759 .get_share = smbconf_reg_get_share,
760 .delete_share = smbconf_reg_delete_share,
761 .set_parameter = smbconf_reg_set_parameter,
762 .get_parameter = smbconf_reg_get_parameter,
763 .delete_parameter = smbconf_reg_delete_parameter
767 /**********************************************************************
769 * The actual libsmbconf API functions that are exported.
771 **********************************************************************/
774 * Open the configuration.
776 * This should be the first function in a sequence of calls to smbconf
779 * Upon success, this creates and returns the conf context
780 * that should be passed around in subsequent calls to the other
783 * After the work with the configuration is completed, smbconf_close()
786 WERROR smbconf_open(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx)
788 WERROR werr = WERR_OK;
789 struct smbconf_ctx *ctx;
791 if (conf_ctx == NULL) {
792 return WERR_INVALID_PARAM;
795 ctx = TALLOC_ZERO_P(mem_ctx, struct smbconf_ctx);
800 ctx->ops = &smbconf_ops_reg;
802 werr = ctx->ops->init(ctx);
803 if (!W_ERROR_IS_OK(werr)) {
807 talloc_set_destructor(ctx, smbconf_destroy_ctx);
818 * Close the configuration.
820 void smbconf_close(struct smbconf_ctx *ctx)
822 /* this also closes the registry (by destructor): */
827 * Detect changes in the configuration.
828 * The given csn struct is filled with the current csn.
829 * smbconf_changed() can also be used for initial retrieval
832 bool smbconf_changed(struct smbconf_ctx *ctx, struct smbconf_csn *csn,
833 const char *service, const char *param)
835 struct smbconf_csn old_csn;
843 ctx->ops->get_csn(ctx, csn, service, param);
844 return (csn->csn != old_csn.csn);
848 * Drop the whole configuration (restarting empty).
850 WERROR smbconf_drop(struct smbconf_ctx *ctx)
852 return ctx->ops->drop(ctx);
856 * Get the whole configuration as lists of strings with counts:
858 * num_shares : number of shares
859 * share_names : list of length num_shares of share names
860 * num_params : list of length num_shares of parameter counts for each share
861 * param_names : list of lists of parameter names for each share
862 * param_values : list of lists of parameter values for each share
864 WERROR smbconf_get_config(struct smbconf_ctx *ctx,
866 uint32_t *num_shares,
867 char ***share_names, uint32_t **num_params,
868 char ****param_names, char ****param_values)
870 WERROR werr = WERR_OK;
871 TALLOC_CTX *tmp_ctx = NULL;
872 uint32_t tmp_num_shares;
873 char **tmp_share_names;
874 uint32_t *tmp_num_params;
875 char ***tmp_param_names;
876 char ***tmp_param_values;
879 if ((num_shares == NULL) || (share_names == NULL) ||
880 (num_params == NULL) || (param_names == NULL) ||
881 (param_values == NULL))
883 werr = WERR_INVALID_PARAM;
887 tmp_ctx = talloc_stackframe();
888 if (tmp_ctx == NULL) {
893 werr = smbconf_get_share_names(ctx, tmp_ctx, &tmp_num_shares,
895 if (!W_ERROR_IS_OK(werr)) {
899 tmp_num_params = TALLOC_ARRAY(tmp_ctx, uint32_t, tmp_num_shares);
900 tmp_param_names = TALLOC_ARRAY(tmp_ctx, char **, tmp_num_shares);
901 tmp_param_values = TALLOC_ARRAY(tmp_ctx, char **, tmp_num_shares);
903 if ((tmp_num_params == NULL) || (tmp_param_names == NULL) ||
904 (tmp_param_values == NULL))
910 for (count = 0; count < tmp_num_shares; count++) {
911 werr = smbconf_get_share(ctx, mem_ctx,
912 tmp_share_names[count],
913 &tmp_num_params[count],
914 &tmp_param_names[count],
915 &tmp_param_values[count]);
916 if (!W_ERROR_IS_OK(werr)) {
923 *num_shares = tmp_num_shares;
924 if (tmp_num_shares > 0) {
925 *share_names = talloc_move(mem_ctx, &tmp_share_names);
926 *num_params = talloc_move(mem_ctx, &tmp_num_params);
927 *param_names = talloc_move(mem_ctx, &tmp_param_names);
928 *param_values = talloc_move(mem_ctx, &tmp_param_values);
933 *param_values = NULL;
937 TALLOC_FREE(tmp_ctx);
942 * get the list of share names defined in the configuration.
944 WERROR smbconf_get_share_names(struct smbconf_ctx *ctx,
946 uint32_t *num_shares,
949 return ctx->ops->get_share_names(ctx, mem_ctx, num_shares,
954 * check if a share/service of a given name exists
956 bool smbconf_share_exists(struct smbconf_ctx *ctx,
957 const char *servicename)
959 if (servicename == NULL) {
962 return ctx->ops->share_exists(ctx, servicename);
966 * Add a service if it does not already exist.
968 WERROR smbconf_create_share(struct smbconf_ctx *ctx,
969 const char *servicename)
971 if (smbconf_share_exists(ctx, servicename)) {
972 return WERR_ALREADY_EXISTS;
975 return ctx->ops->create_share(ctx, servicename);
979 * get a definition of a share (service) from configuration.
981 WERROR smbconf_get_share(struct smbconf_ctx *ctx,
983 const char *servicename, uint32_t *num_params,
984 char ***param_names, char ***param_values)
986 if (!smbconf_share_exists(ctx, servicename)) {
987 return WERR_NO_SUCH_SERVICE;
990 return ctx->ops->get_share(ctx, mem_ctx, servicename, num_params,
991 param_names, param_values);
995 * delete a service from configuration
997 WERROR smbconf_delete_share(struct smbconf_ctx *ctx, const char *servicename)
999 if (!smbconf_share_exists(ctx, servicename)) {
1000 return WERR_NO_SUCH_SERVICE;
1003 return ctx->ops->delete_share(ctx, servicename);
1007 * set a configuration parameter to the value provided.
1009 WERROR smbconf_set_parameter(struct smbconf_ctx *ctx,
1010 const char *service,
1014 if (!smbconf_share_exists(ctx, service)) {
1015 return WERR_NO_SUCH_SERVICE;
1018 return ctx->ops->set_parameter(ctx, service, param, valstr);
1022 * Set a global parameter
1023 * (i.e. a parameter in the [global] service).
1025 * This also creates [global] when it does not exist.
1027 WERROR smbconf_set_global_parameter(struct smbconf_ctx *ctx,
1028 const char *param, const char *val)
1032 werr = smbconf_global_check(ctx);
1033 if (W_ERROR_IS_OK(werr)) {
1034 werr = smbconf_set_parameter(ctx, GLOBAL_NAME, param, val);
1041 * get the value of a configuration parameter as a string
1043 WERROR smbconf_get_parameter(struct smbconf_ctx *ctx,
1044 TALLOC_CTX *mem_ctx,
1045 const char *service,
1049 if (valstr == NULL) {
1050 return WERR_INVALID_PARAM;
1053 if (!smbconf_share_exists(ctx, service)) {
1054 return WERR_NO_SUCH_SERVICE;
1057 return ctx->ops->get_parameter(ctx, mem_ctx, service, param, valstr);
1061 * Get the value of a global parameter.
1063 * Create [global] if it does not exist.
1065 WERROR smbconf_get_global_parameter(struct smbconf_ctx *ctx,
1066 TALLOC_CTX *mem_ctx,
1072 werr = smbconf_global_check(ctx);
1073 if (W_ERROR_IS_OK(werr)) {
1074 werr = smbconf_get_parameter(ctx, mem_ctx, GLOBAL_NAME, param,
1082 * delete a parameter from configuration
1084 WERROR smbconf_delete_parameter(struct smbconf_ctx *ctx,
1085 const char *service, const char *param)
1087 if (!smbconf_share_exists(ctx, service)) {
1088 return WERR_NO_SUCH_SERVICE;
1091 return ctx->ops->delete_parameter(ctx, service, param);
1095 * Delete a global parameter.
1097 * Create [global] if it does not exist.
1099 WERROR smbconf_delete_global_parameter(struct smbconf_ctx *ctx,
1104 werr = smbconf_global_check(ctx);
1105 if (W_ERROR_IS_OK(werr)) {
1106 werr = smbconf_delete_parameter(ctx, GLOBAL_NAME, param);