From 890d1d8f78e27493c95103b828e3536e4565b344 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Mar 2008 16:26:50 +0100 Subject: libsmbconf: move registry implementation to a module of its own. Michael (This used to be commit 431b10bfe0dba0a49e50bebfb3f8ad1a00955837) --- source3/lib/smbconf/smbconf_reg.c | 744 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 744 insertions(+) create mode 100644 source3/lib/smbconf/smbconf_reg.c (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c new file mode 100644 index 0000000000..d260be8552 --- /dev/null +++ b/source3/lib/smbconf/smbconf_reg.c @@ -0,0 +1,744 @@ +/* + * Unix SMB/CIFS implementation. + * libsmbconf - Samba configuration library, registry backend + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "includes.h" +#include "smbconf_private.h" + + +/********************************************************************** + * + * helper functions + * + **********************************************************************/ + +/** + * Open a registry key specified by "path" + */ +static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, + struct smbconf_ctx *ctx, + const char *path, + uint32 desired_access, + struct registry_key **key) +{ + WERROR werr = WERR_OK; + + if (ctx == NULL) { + DEBUG(1, ("Error: configuration is not open!\n")); + werr = WERR_INVALID_PARAM; + goto done; + } + + if (ctx->token == NULL) { + DEBUG(1, ("Error: token missing from smbconf_ctx. " + "was smbconf_init() called?\n")); + werr = WERR_INVALID_PARAM; + goto done; + } + + if (path == NULL) { + DEBUG(1, ("Error: NULL path string given\n")); + werr = WERR_INVALID_PARAM; + goto done; + } + + werr = reg_open_path(mem_ctx, path, desired_access, ctx->token, key); + + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error opening registry path '%s': %s\n", + path, dos_errstr(werr))); + } + +done: + return werr; +} + +/** + * Open a subkey of KEY_SMBCONF (i.e a service) + */ +static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, + struct smbconf_ctx *ctx, + const char *servicename, + uint32 desired_access, + struct registry_key **key) +{ + WERROR werr = WERR_OK; + char *path = NULL; + + if (servicename == NULL) { + DEBUG(3, ("Error: NULL servicename given.\n")); + werr = WERR_INVALID_PARAM; + goto done; + } + + path = talloc_asprintf(mem_ctx, "%s\\%s", KEY_SMBCONF, servicename); + if (path == NULL) { + werr = WERR_NOMEM; + goto done; + } + + werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key); + +done: + TALLOC_FREE(path); + return werr; +} + +/** + * open the base key KEY_SMBCONF + */ +static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx, + struct smbconf_ctx *ctx, + uint32 desired_access, + struct registry_key **key) +{ + return smbconf_reg_open_path(mem_ctx, ctx, KEY_SMBCONF, desired_access, + key); +} + +/** + * check if a value exists in a given registry key + */ +static bool smbconf_value_exists(struct registry_key *key, const char *param) +{ + bool ret = false; + WERROR werr = WERR_OK; + TALLOC_CTX *ctx = talloc_stackframe(); + struct registry_value *value = NULL; + + werr = reg_queryvalue(ctx, key, param, &value); + if (W_ERROR_IS_OK(werr)) { + ret = true; + } + + TALLOC_FREE(ctx); + return ret; +} + +/** + * create a subkey of KEY_SMBCONF + */ +static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, + struct smbconf_ctx *ctx, + const char * subkeyname, + struct registry_key **newkey) +{ + WERROR werr = WERR_OK; + struct registry_key *create_parent = NULL; + TALLOC_CTX *create_ctx; + enum winreg_CreateAction action = REG_ACTION_NONE; + + /* create a new talloc ctx for creation. it will hold + * the intermediate parent key (SMBCONF) for creation + * and will be destroyed when leaving this function... */ + if (!(create_ctx = talloc_stackframe())) { + werr = WERR_NOMEM; + goto done; + } + + werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE, + &create_parent); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = reg_createkey(mem_ctx, create_parent, subkeyname, + REG_KEY_WRITE, newkey, &action); + if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) { + DEBUG(10, ("Key '%s' already exists.\n", subkeyname)); + werr = WERR_ALREADY_EXISTS; + } + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5, ("Error creating key %s: %s\n", + subkeyname, dos_errstr(werr))); + } + +done: + TALLOC_FREE(create_ctx); + return werr; +} + +/** + * add a value to a key. + */ +static WERROR smbconf_reg_set_value(struct registry_key *key, + const char *valname, + const char *valstr) +{ + struct registry_value val; + WERROR werr = WERR_OK; + char *subkeyname; + const char *canon_valname; + const char *canon_valstr; + + if (!lp_canonicalize_parameter_with_value(valname, valstr, + &canon_valname, + &canon_valstr)) + { + if (canon_valname == NULL) { + DEBUG(5, ("invalid parameter '%s' given\n", + valname)); + } else { + DEBUG(5, ("invalid value '%s' given for " + "parameter '%s'\n", valstr, valname)); + } + werr = WERR_INVALID_PARAM; + goto done; + } + + ZERO_STRUCT(val); + + val.type = REG_SZ; + val.v.sz.str = CONST_DISCARD(char *, canon_valstr); + val.v.sz.len = strlen(canon_valstr) + 1; + + if (registry_smbconf_valname_forbidden(canon_valname)) { + DEBUG(5, ("Parameter '%s' not allowed in registry.\n", + canon_valname)); + werr = WERR_INVALID_PARAM; + goto done; + } + + subkeyname = strrchr_m(key->key->name, '\\'); + if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) { + DEBUG(5, ("Invalid registry key '%s' given as " + "smbconf section.\n", key->key->name)); + werr = WERR_INVALID_PARAM; + goto done; + } + subkeyname++; + if (!strequal(subkeyname, GLOBAL_NAME) && + lp_parameter_is_global(valname)) + { + DEBUG(5, ("Global paramter '%s' not allowed in " + "service definition ('%s').\n", canon_valname, + subkeyname)); + werr = WERR_INVALID_PARAM; + goto done; + } + + werr = reg_setvalue(key, canon_valname, &val); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5, ("Error adding value '%s' to " + "key '%s': %s\n", + canon_valname, key->key->name, dos_errstr(werr))); + } + +done: + return werr; +} + +/** + * format a registry_value into a string. + * + * This is intended to be used for smbconf registry values, + * which are ar stored as REG_SZ values, so the incomplete + * handling should be ok. + */ +static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx, + struct registry_value *value) +{ + char *result = NULL; + + /* alternatively, create a new talloc context? */ + if (mem_ctx == NULL) { + return result; + } + + switch (value->type) { + case REG_DWORD: + result = talloc_asprintf(mem_ctx, "%d", value->v.dword); + break; + case REG_SZ: + case REG_EXPAND_SZ: + result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str); + break; + case REG_MULTI_SZ: { + uint32 j; + for (j = 0; j < value->v.multi_sz.num_strings; j++) { + result = talloc_asprintf(mem_ctx, "%s \"%s\" ", + result, + value->v.multi_sz.strings[j]); + if (result == NULL) { + break; + } + } + break; + } + case REG_BINARY: + result = talloc_asprintf(mem_ctx, "binary (%d bytes)", + (int)value->v.binary.length); + break; + default: + result = talloc_asprintf(mem_ctx, ""); + break; + } + return result; +} + +/** + * Get the values of a key as a list of value names + * and a list of value strings (ordered) + */ +static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, + struct registry_key *key, + uint32_t *num_values, + char ***value_names, + char ***value_strings) +{ + TALLOC_CTX *tmp_ctx = NULL; + WERROR werr = WERR_OK; + uint32_t count; + struct registry_value *valvalue = NULL; + char *valname = NULL; + char **tmp_valnames = NULL; + char **tmp_valstrings = NULL; + + if ((num_values == NULL) || (value_names == NULL) || + (value_strings == NULL)) + { + werr = WERR_INVALID_PARAM; + goto done; + } + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + werr = WERR_NOMEM; + goto done; + } + + for (count = 0; + W_ERROR_IS_OK(werr = reg_enumvalue(tmp_ctx, key, count, &valname, + &valvalue)); + count++) + { + char *valstring; + + werr = smbconf_add_string_to_array(tmp_ctx, + &tmp_valnames, + count, valname); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + valstring = smbconf_format_registry_value(tmp_ctx, valvalue); + werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings, + count, valstring); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + } + if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { + goto done; + } + + werr = WERR_OK; + + *num_values = count; + if (count > 0) { + *value_names = talloc_move(mem_ctx, &tmp_valnames); + *value_strings = talloc_move(mem_ctx, &tmp_valstrings); + } else { + *value_names = NULL; + *value_strings = NULL; + } + +done: + TALLOC_FREE(tmp_ctx); + return werr; +} + +/********************************************************************** + * + * smbconf operations: registry implementations + * + **********************************************************************/ + +/** + * initialize the registry smbconf backend + */ +static WERROR smbconf_reg_init(struct smbconf_ctx *ctx) +{ + WERROR werr = WERR_OK; + + if (!registry_init_smbconf()) { + werr = WERR_REG_IO_FAILURE; + goto done; + } + + werr = ntstatus_to_werror(registry_create_admin_token(ctx, + &(ctx->token))); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error creating admin token\n")); + goto done; + } + +done: + return werr; +} + +static int smbconf_reg_shutdown(struct smbconf_ctx *ctx) +{ + return regdb_close(); +} + +static WERROR smbconf_reg_open(struct smbconf_ctx *ctx) +{ + return regdb_open(); +} + +static int smbconf_reg_close(struct smbconf_ctx *ctx) +{ + return regdb_close(); +} + +/** + * Get the change sequence number of the given service/parameter. + * service and parameter strings may be NULL. + */ +static void smbconf_reg_get_csn(struct smbconf_ctx *ctx, + struct smbconf_csn *csn, + const char *service, const char *param) +{ + if (csn == NULL) { + return; + } + csn->csn = (uint64_t)regdb_get_seqnum(); +} + +/** + * Drop the whole configuration (restarting empty) - registry version + */ +static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx) +{ + char *path, *p; + WERROR werr = WERR_OK; + struct registry_key *parent_key = NULL; + struct registry_key *new_key = NULL; + TALLOC_CTX* mem_ctx = talloc_stackframe(); + enum winreg_CreateAction action; + + path = talloc_strdup(mem_ctx, KEY_SMBCONF); + if (path == NULL) { + werr = WERR_NOMEM; + goto done; + } + p = strrchr(path, '\\'); + *p = '\0'; + werr = smbconf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE, + &parent_key); + + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = reg_deletekey_recursive(mem_ctx, parent_key, p+1); + + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE, + &new_key, &action); + +done: + TALLOC_FREE(mem_ctx); + return werr; +} + +/** + * get the list of share names defined in the configuration. + * registry version. + */ +static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, + TALLOC_CTX *mem_ctx, + uint32_t *num_shares, + char ***share_names) +{ + uint32_t count; + uint32_t added_count = 0; + TALLOC_CTX *tmp_ctx = NULL; + WERROR werr = WERR_OK; + struct registry_key *key = NULL; + char *subkey_name = NULL; + char **tmp_share_names = NULL; + + if ((num_shares == NULL) || (share_names == NULL)) { + werr = WERR_INVALID_PARAM; + goto done; + } + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + werr = WERR_NOMEM; + goto done; + } + + /* make sure "global" is always listed first */ + if (smbconf_share_exists(ctx, GLOBAL_NAME)) { + werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, + 0, GLOBAL_NAME); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + added_count++; + } + + werr = smbconf_reg_open_base_key(tmp_ctx, ctx, + SEC_RIGHTS_ENUM_SUBKEYS, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + for (count = 0; + W_ERROR_IS_OK(werr = reg_enumkey(tmp_ctx, key, count, + &subkey_name, NULL)); + count++) + { + if (strequal(subkey_name, GLOBAL_NAME)) { + continue; + } + + werr = smbconf_add_string_to_array(tmp_ctx, + &tmp_share_names, + added_count, + subkey_name); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + added_count++; + } + if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { + goto done; + } + werr = WERR_OK; + + *num_shares = added_count; + if (added_count > 0) { + *share_names = talloc_move(mem_ctx, &tmp_share_names); + } else { + *share_names = NULL; + } + +done: + TALLOC_FREE(tmp_ctx); + return werr; +} + +/** + * check if a share/service of a given name exists - registry version + */ +static bool smbconf_reg_share_exists(struct smbconf_ctx *ctx, + const char *servicename) +{ + bool ret = false; + WERROR werr = WERR_OK; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + struct registry_key *key = NULL; + + werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename, + REG_KEY_READ, &key); + if (W_ERROR_IS_OK(werr)) { + ret = true; + } + + TALLOC_FREE(mem_ctx); + return ret; +} + +/** + * Add a service if it does not already exist - registry version + */ +static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx, + const char *servicename) +{ + WERROR werr; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + struct registry_key *key = NULL; + + werr = smbconf_reg_create_service_key(mem_ctx, ctx, servicename, &key); + + TALLOC_FREE(mem_ctx); + return werr; +} + +/** + * get a definition of a share (service) from configuration. + */ +static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx, + TALLOC_CTX *mem_ctx, + const char *servicename, + uint32_t *num_params, + char ***param_names, char ***param_values) +{ + WERROR werr = WERR_OK; + struct registry_key *key = NULL; + + werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename, + REG_KEY_READ, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = smbconf_reg_get_values(mem_ctx, key, num_params, + param_names, param_values); + +done: + TALLOC_FREE(key); + return werr; +} + +/** + * delete a service from configuration + */ +static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx, + const char *servicename) +{ + WERROR werr = WERR_OK; + struct registry_key *key = NULL; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = reg_deletekey_recursive(key, key, servicename); + +done: + TALLOC_FREE(mem_ctx); + return werr; +} + +/** + * set a configuration parameter to the value provided. + */ +static WERROR smbconf_reg_set_parameter(struct smbconf_ctx *ctx, + const char *service, + const char *param, + const char *valstr) +{ + WERROR werr; + struct registry_key *key = NULL; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + werr = smbconf_reg_open_service_key(mem_ctx, ctx, service, + REG_KEY_WRITE, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = smbconf_reg_set_value(key, param, valstr); + +done: + TALLOC_FREE(mem_ctx); + return werr; +} + +/** + * get the value of a configuration parameter as a string + */ +static WERROR smbconf_reg_get_parameter(struct smbconf_ctx *ctx, + TALLOC_CTX *mem_ctx, + const char *service, + const char *param, + char **valstr) +{ + WERROR werr = WERR_OK; + struct registry_key *key = NULL; + struct registry_value *value = NULL; + + werr = smbconf_reg_open_service_key(mem_ctx, ctx, service, + REG_KEY_READ, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (!smbconf_value_exists(key, param)) { + werr = WERR_INVALID_PARAM; + goto done; + } + + werr = reg_queryvalue(mem_ctx, key, param, &value); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + *valstr = smbconf_format_registry_value(mem_ctx, value); + + if (*valstr == NULL) { + werr = WERR_NOMEM; + } + +done: + TALLOC_FREE(key); + TALLOC_FREE(value); + return werr; +} + +/** + * delete a parameter from configuration + */ +static WERROR smbconf_reg_delete_parameter(struct smbconf_ctx *ctx, + const char *service, + const char *param) +{ + struct registry_key *key = NULL; + WERROR werr = WERR_OK; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + werr = smbconf_reg_open_service_key(mem_ctx, ctx, service, + REG_KEY_ALL, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (!smbconf_value_exists(key, param)) { + werr = WERR_INVALID_PARAM; + goto done; + } + + werr = reg_deletevalue(key, param); + +done: + TALLOC_FREE(mem_ctx); + return werr; +} + +struct smbconf_ops smbconf_ops_reg = { + .init = smbconf_reg_init, + .shutdown = smbconf_reg_shutdown, + .open_conf = smbconf_reg_open, + .close_conf = smbconf_reg_close, + .get_csn = smbconf_reg_get_csn, + .drop = smbconf_reg_drop, + .get_share_names = smbconf_reg_get_share_names, + .share_exists = smbconf_reg_share_exists, + .create_share = smbconf_reg_create_share, + .get_share = smbconf_reg_get_share, + .delete_share = smbconf_reg_delete_share, + .set_parameter = smbconf_reg_set_parameter, + .get_parameter = smbconf_reg_get_parameter, + .delete_parameter = smbconf_reg_delete_parameter +}; + +WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx) +{ + return smbconf_init(mem_ctx, conf_ctx, &smbconf_ops_reg); +} + -- cgit From 44dc10d808474e669f86337fff73738f97110a0f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Mar 2008 16:35:52 +0100 Subject: libsmbconf: add a comment. Michael (This used to be commit 8974b283683799bc51223d27b7e6aecac741fbc2) --- source3/lib/smbconf/smbconf_reg.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index d260be8552..f0a1f17f8e 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -737,8 +737,12 @@ struct smbconf_ops smbconf_ops_reg = { .delete_parameter = smbconf_reg_delete_parameter }; + +/** + * initialize the smbconf registry backend + * the only function that is exported from this module + */ WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx) { return smbconf_init(mem_ctx, conf_ctx, &smbconf_ops_reg); } - -- cgit From 6f7cfeddd61f728e2452a7b89f5ee2ff36ca394f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Mar 2008 17:55:31 +0100 Subject: libsmbconf: add a "path" variable to the conf context. This is passed to the module init routines. In case of the registry, this is the path of the basekey in registry, that is to be used, defaulting to KEY_SMBCONF (HKLM\software\samba\smbconf), when NULL is given. This is the only case currently used. In order to support other keys, registry initialization for smbconf has to be changed to support different keys. Michael (This used to be commit 96434d9dc7a66773e313cc128af57493dee245a1) --- source3/lib/smbconf/smbconf_reg.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index f0a1f17f8e..beb1c20de6 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -69,7 +69,7 @@ done: } /** - * Open a subkey of KEY_SMBCONF (i.e a service) + * Open a subkey of the base key (i.e a service) */ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, struct smbconf_ctx *ctx, @@ -86,7 +86,7 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, goto done; } - path = talloc_asprintf(mem_ctx, "%s\\%s", KEY_SMBCONF, servicename); + path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path, servicename); if (path == NULL) { werr = WERR_NOMEM; goto done; @@ -100,14 +100,14 @@ done: } /** - * open the base key KEY_SMBCONF + * open the base key */ static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx, struct smbconf_ctx *ctx, uint32 desired_access, struct registry_key **key) { - return smbconf_reg_open_path(mem_ctx, ctx, KEY_SMBCONF, desired_access, + return smbconf_reg_open_path(mem_ctx, ctx, ctx->path, desired_access, key); } @@ -131,7 +131,7 @@ static bool smbconf_value_exists(struct registry_key *key, const char *param) } /** - * create a subkey of KEY_SMBCONF + * create a subkey of the base key (i.e. a service...) */ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, struct smbconf_ctx *ctx, @@ -372,10 +372,19 @@ done: /** * initialize the registry smbconf backend */ -static WERROR smbconf_reg_init(struct smbconf_ctx *ctx) +static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) { WERROR werr = WERR_OK; + if (path == NULL) { + path = KEY_SMBCONF; + } + ctx->path = talloc_strdup(ctx, path); + if (ctx->path == NULL) { + werr = WERR_NOMEM; + goto done; + } + if (!registry_init_smbconf()) { werr = WERR_REG_IO_FAILURE; goto done; @@ -433,7 +442,7 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx) TALLOC_CTX* mem_ctx = talloc_stackframe(); enum winreg_CreateAction action; - path = talloc_strdup(mem_ctx, KEY_SMBCONF); + path = talloc_strdup(mem_ctx, ctx->path); if (path == NULL) { werr = WERR_NOMEM; goto done; @@ -742,7 +751,8 @@ struct smbconf_ops smbconf_ops_reg = { * initialize the smbconf registry backend * the only function that is exported from this module */ -WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx) +WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx, + const char *path) { - return smbconf_init(mem_ctx, conf_ctx, &smbconf_ops_reg); + return smbconf_init(mem_ctx, conf_ctx, path, &smbconf_ops_reg); } -- cgit From be97af0edb085e1e33e3e8fbc97760249a720b52 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Mar 2008 22:52:27 +0100 Subject: libsmbconf: add private_data section to smbconf_ctx. This private data should be used by backends. The token for the registry backend is moved from the context to the private data section, since this is registry specific. Michael (This used to be commit a02163356bdd0c17a25a45e9904f8bd1e1c4bee4) --- source3/lib/smbconf/smbconf_reg.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index beb1c20de6..aaa03e21e8 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -20,6 +20,9 @@ #include "includes.h" #include "smbconf_private.h" +struct reg_private_data { + NT_USER_TOKEN *token; +}; /********************************************************************** * @@ -27,6 +30,11 @@ * **********************************************************************/ +static struct reg_private_data *rpd(struct smbconf_ctx *ctx) +{ + return (struct reg_private_data *)(ctx->data); +} + /** * Open a registry key specified by "path" */ @@ -44,7 +52,7 @@ static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, goto done; } - if (ctx->token == NULL) { + if (rpd(ctx)->token == NULL) { DEBUG(1, ("Error: token missing from smbconf_ctx. " "was smbconf_init() called?\n")); werr = WERR_INVALID_PARAM; @@ -57,7 +65,8 @@ static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, goto done; } - werr = reg_open_path(mem_ctx, path, desired_access, ctx->token, key); + werr = reg_open_path(mem_ctx, path, desired_access, rpd(ctx)->token, + key); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Error opening registry path '%s': %s\n", @@ -385,18 +394,21 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) goto done; } - if (!registry_init_smbconf()) { - werr = WERR_REG_IO_FAILURE; - goto done; - } + ctx->data = TALLOC_ZERO_P(ctx, struct reg_private_data); werr = ntstatus_to_werror(registry_create_admin_token(ctx, - &(ctx->token))); + &(rpd(ctx)->token))); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Error creating admin token\n")); goto done; } + if (!registry_init_smbconf()) { + werr = WERR_REG_IO_FAILURE; + goto done; + } + + done: return werr; } -- cgit From aa3e4d56cb6070a433afe4f460fc426e60882103 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Mar 2008 22:55:20 +0100 Subject: libsmbconf: add a comment. Michael (This used to be commit 513ae78ef78d3ddcb155f9c38b9a0c82809e0998) --- source3/lib/smbconf/smbconf_reg.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index aaa03e21e8..98613efc2a 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -30,6 +30,9 @@ struct reg_private_data { * **********************************************************************/ +/** + * a convenience helper to cast the private data structure + */ static struct reg_private_data *rpd(struct smbconf_ctx *ctx) { return (struct reg_private_data *)(ctx->data); -- cgit From a81ed36e86cf9c275538aea03c80c1ee00122f4a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Mar 2008 23:39:01 +0100 Subject: libsmbconf: add internal open/close handling to registry backend. This internally keeps track of opened registry in the private data struct. The first call that really accesses data, opens the registry and it is kept open until the destructor is called. This behaviour might be changed in the future. Michael (This used to be commit 03e72e13076e3215eb8ae51cfb4e7cd3d3683d3e) --- source3/lib/smbconf/smbconf_reg.c | 42 +++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 98613efc2a..1f113c835f 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -22,6 +22,7 @@ struct reg_private_data { NT_USER_TOKEN *token; + bool open; /* did _we_ open the registry? */ }; /********************************************************************** @@ -62,6 +63,12 @@ static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, goto done; } + werr = ctx->ops->open_conf(ctx); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error opening the registry.\n")); + goto done; + } + if (path == NULL) { DEBUG(1, ("Error: NULL path string given\n")); werr = WERR_INVALID_PARAM; @@ -405,12 +412,14 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) DEBUG(1, ("Error creating admin token\n")); goto done; } + rpd(ctx)->open = false; if (!registry_init_smbconf()) { werr = WERR_REG_IO_FAILURE; goto done; } - + /* we know registry_init_smbconf() leaves registry open */ + regdb_close(); done: return werr; @@ -418,17 +427,37 @@ done: static int smbconf_reg_shutdown(struct smbconf_ctx *ctx) { - return regdb_close(); + return ctx->ops->close_conf(ctx); } static WERROR smbconf_reg_open(struct smbconf_ctx *ctx) { - return regdb_open(); + WERROR werr; + + if (rpd(ctx)->open) { + return WERR_OK; + } + + werr = regdb_open(); + if (W_ERROR_IS_OK(werr)) { + rpd(ctx)->open = true; + } + return werr; } static int smbconf_reg_close(struct smbconf_ctx *ctx) { - return regdb_close(); + int ret; + + if (!rpd(ctx)->open) { + return 0; + } + + ret = regdb_close(); + if (ret == 0) { + rpd(ctx)->open = false; + } + return ret; } /** @@ -442,6 +471,11 @@ static void smbconf_reg_get_csn(struct smbconf_ctx *ctx, if (csn == NULL) { return; } + + if (!W_ERROR_IS_OK(ctx->ops->open_conf(ctx))) { + return; + } + csn->csn = (uint64_t)regdb_get_seqnum(); } -- cgit From 9ec7af58c62d8ead447fc6da6db76db8dc5b96dc Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Mar 2008 23:50:49 +0100 Subject: registry: fix registry_init_smbconf() to close the registry at the end. Michael (This used to be commit f4d87fdbf266a36fbb50dae863ee0784165c2fe1) --- source3/lib/smbconf/smbconf_reg.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 1f113c835f..77e6233cb4 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -418,8 +418,6 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) werr = WERR_REG_IO_FAILURE; goto done; } - /* we know registry_init_smbconf() leaves registry open */ - regdb_close(); done: return werr; -- cgit From 24c54ee4fbe8d093d3f4d729ef2b055b82798f9a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 3 Apr 2008 15:16:01 +0200 Subject: libsmbconf: move initialization of registry value down after error checks. Michael (This used to be commit 2a8029985f9bde4da8ca20bc24d937150eab444c) --- source3/lib/smbconf/smbconf_reg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 77e6233cb4..b40c37e60e 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -220,12 +220,6 @@ static WERROR smbconf_reg_set_value(struct registry_key *key, goto done; } - ZERO_STRUCT(val); - - val.type = REG_SZ; - val.v.sz.str = CONST_DISCARD(char *, canon_valstr); - val.v.sz.len = strlen(canon_valstr) + 1; - if (registry_smbconf_valname_forbidden(canon_valname)) { DEBUG(5, ("Parameter '%s' not allowed in registry.\n", canon_valname)); @@ -251,6 +245,12 @@ static WERROR smbconf_reg_set_value(struct registry_key *key, goto done; } + ZERO_STRUCT(val); + + val.type = REG_SZ; + val.v.sz.str = CONST_DISCARD(char *, canon_valstr); + val.v.sz.len = strlen(canon_valstr) + 1; + werr = reg_setvalue(key, canon_valname, &val); if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error adding value '%s' to " -- cgit From ec12f0a25aaf7fca5417a7fe6f3c6182c41d80a0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Apr 2008 15:15:57 +0200 Subject: libsmbconf: untangle assignment and test in for-loop condition. Michael (This used to be commit 4339caff09e1277ae33d3810043bcb3f4e7c4e45) --- source3/lib/smbconf/smbconf_reg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index b40c37e60e..f25382769d 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -342,8 +342,8 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, } for (count = 0; - W_ERROR_IS_OK(werr = reg_enumvalue(tmp_ctx, key, count, &valname, - &valvalue)); + werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue), + W_ERROR_IS_OK(werr); count++) { char *valstring; @@ -562,8 +562,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, } for (count = 0; - W_ERROR_IS_OK(werr = reg_enumkey(tmp_ctx, key, count, - &subkey_name, NULL)); + werr = reg_enumkey(tmp_ctx, key, count, &subkey_name, NULL), + W_ERROR_IS_OK(werr); count++) { if (strequal(subkey_name, GLOBAL_NAME)) { -- cgit From 0acf338503eb22640be3e02f66ce9543b775fe15 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Apr 2008 15:29:11 +0200 Subject: libsmbconf: reformat smbconf_format_registry_value() - indentations/tabs Michael (This used to be commit b79a33eb2f370b8d8b50ed5ed2a0acc83e711c1e) --- source3/lib/smbconf/smbconf_reg.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index f25382769d..6d24aecbff 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -288,25 +288,25 @@ static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx, result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str); break; case REG_MULTI_SZ: { - uint32 j; - for (j = 0; j < value->v.multi_sz.num_strings; j++) { - result = talloc_asprintf(mem_ctx, "%s \"%s\" ", + uint32 j; + for (j = 0; j < value->v.multi_sz.num_strings; j++) { + result = talloc_asprintf(mem_ctx, "%s \"%s\" ", result, value->v.multi_sz.strings[j]); if (result == NULL) { break; } - } - break; - } + } + break; + } case REG_BINARY: - result = talloc_asprintf(mem_ctx, "binary (%d bytes)", + result = talloc_asprintf(mem_ctx, "binary (%d bytes)", (int)value->v.binary.length); - break; - default: - result = talloc_asprintf(mem_ctx, ""); - break; - } + break; + default: + result = talloc_asprintf(mem_ctx, ""); + break; + } return result; } -- cgit From 8e9766289972ecf3f4bcaa1a9ed118bba5fea208 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 01:56:32 +0200 Subject: libsmbconf: add get_includes() and set_includes() to the API. Includes have to get a special treatment, at least for registry. Includes are not like other smbconf parameters: they are some kind of metainformation. "include" has two effects when stated twice so it can not be stored boldly into registry, since there can only be one value named "include" in registry per key. I will provide special handling for includes for the registry backend. This patch provides the necessary methods in the smbconf API. Michael (This used to be commit e86eb375d9f83f73aeea0a16c8b43e2ef21a6e20) --- source3/lib/smbconf/smbconf_reg.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 6d24aecbff..0f499e3146 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -776,6 +776,23 @@ done: return werr; } +static WERROR smbconf_reg_get_includes(struct smbconf_ctx *ctx, + const char *service, + uint32_t *num_includes, + char ***includes) +{ + return WERR_NOT_SUPPORTED; +} + +static WERROR smbconf_reg_set_includes(struct smbconf_ctx *ctx, + const char *service, + uint32_t num_includes, + const char **includes) +{ + return WERR_NOT_SUPPORTED; +} + + struct smbconf_ops smbconf_ops_reg = { .init = smbconf_reg_init, .shutdown = smbconf_reg_shutdown, @@ -790,7 +807,9 @@ struct smbconf_ops smbconf_ops_reg = { .delete_share = smbconf_reg_delete_share, .set_parameter = smbconf_reg_set_parameter, .get_parameter = smbconf_reg_get_parameter, - .delete_parameter = smbconf_reg_delete_parameter + .delete_parameter = smbconf_reg_delete_parameter, + .get_includes = smbconf_reg_get_includes, + .set_includes = smbconf_reg_set_includes, }; -- cgit From f5aac0a8d01885d06594c4bbe0ff815bb9339a0c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 10:16:03 +0200 Subject: libsmbconf: add talloc context to the get_includes methods. Michael (This used to be commit ed535b6b30b5c9412803f6373eadc704de6de2f9) --- source3/lib/smbconf/smbconf_reg.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 0f499e3146..5651357d0b 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -777,6 +777,7 @@ done: } static WERROR smbconf_reg_get_includes(struct smbconf_ctx *ctx, + TALLOC_CTX *mem_ctx, const char *service, uint32_t *num_includes, char ***includes) -- cgit From 56c0f28a505611654d48c3283bf917ab95c2afa7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 17:46:36 +0200 Subject: libsmbconf: implement get_includes() and set_includes() for registry backend. includes are stored per share in a special registry value "includes" of type multi_sz. Michael (This used to be commit 3fee0d79cc618adc7dd82cfeff62c72ef061017b) --- source3/lib/smbconf/smbconf_reg.c | 119 +++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 5651357d0b..e604a608e1 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -20,6 +20,8 @@ #include "includes.h" #include "smbconf_private.h" +#define INCLUDES_VALNAME "includes" + struct reg_private_data { NT_USER_TOKEN *token; bool open; /* did _we_ open the registry? */ @@ -262,6 +264,51 @@ done: return werr; } +static WERROR smbconf_reg_set_multi_sz_value(struct registry_key *key, + const char *valname, + const uint32_t num_strings, + const char **strings) +{ + WERROR werr; + struct registry_value *value; + uint32_t count; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + if (strings == NULL) { + werr = WERR_INVALID_PARAM; + goto done; + } + + value = TALLOC_ZERO_P(tmp_ctx, struct registry_value); + + value->type = REG_MULTI_SZ; + value->v.multi_sz.num_strings = num_strings; + value->v.multi_sz.strings = TALLOC_ARRAY(tmp_ctx, char *, num_strings); + if (value->v.multi_sz.strings == NULL) { + werr = WERR_NOMEM; + goto done; + } + for (count = 0; count < num_strings; count++) { + value->v.multi_sz.strings[count] = + talloc_strdup(value->v.multi_sz.strings, + strings[count]); + if (value->v.multi_sz.strings[count] == NULL) { + werr = WERR_NOMEM; + goto done; + } + } + + werr = reg_setvalue(key, valname, value); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5, ("Error adding value '%s' to key '%s': %s\n", + valname, key->key->name, dos_errstr(werr))); + } + +done: + TALLOC_FREE(tmp_ctx); + return werr; +} + /** * format a registry_value into a string. * @@ -782,7 +829,60 @@ static WERROR smbconf_reg_get_includes(struct smbconf_ctx *ctx, uint32_t *num_includes, char ***includes) { - return WERR_NOT_SUPPORTED; + WERROR werr; + uint32_t count; + struct registry_key *key = NULL; + struct registry_value *value = NULL; + char **tmp_includes = NULL; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + werr = smbconf_reg_open_service_key(tmp_ctx, ctx, service, + REG_KEY_READ, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { + /* no includes */ + goto done; + } + + werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (value->type != REG_MULTI_SZ) { + /* wront type -- ignore */ + goto done; + } + + for (count = 0; count < value->v.multi_sz.num_strings; count++) + { + werr = smbconf_add_string_to_array(tmp_ctx, + &tmp_includes, + count, + value->v.multi_sz.strings[count]); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + } + + if (count > 0) { + *includes = talloc_move(mem_ctx, &tmp_includes); + if (*includes == NULL) { + werr = WERR_NOMEM; + goto done; + } + *num_includes = count; + } else { + *num_includes = 0; + *includes = NULL; + } + +done: + TALLOC_FREE(tmp_ctx); + return werr; } static WERROR smbconf_reg_set_includes(struct smbconf_ctx *ctx, @@ -790,7 +890,22 @@ static WERROR smbconf_reg_set_includes(struct smbconf_ctx *ctx, uint32_t num_includes, const char **includes) { - return WERR_NOT_SUPPORTED; + WERROR werr = WERR_OK; + struct registry_key *key = NULL; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + werr = smbconf_reg_open_service_key(tmp_ctx, ctx, service, + REG_KEY_ALL, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME, + num_includes, includes); + +done: + TALLOC_FREE(tmp_ctx); + return werr; } -- cgit From 7f0127a90347c27a858eac0104e83df858bf5cc1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 22:23:57 +0200 Subject: libsmbconf: more sanely print multi_sz values in registry backend Michael (This used to be commit 382c623948abd1c6a5cf8ab7ee2be784fcef76ee) --- source3/lib/smbconf/smbconf_reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index e604a608e1..dada8eece0 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -337,8 +337,8 @@ static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx, case REG_MULTI_SZ: { uint32 j; for (j = 0; j < value->v.multi_sz.num_strings; j++) { - result = talloc_asprintf(mem_ctx, "%s \"%s\" ", - result, + result = talloc_asprintf(mem_ctx, "%s\"%s\" ", + result ? result : "" , value->v.multi_sz.strings[j]); if (result == NULL) { break; -- cgit From e06e8084c6dd33b2d54bd497d245a806a71c5ccc Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 22:51:02 +0200 Subject: libsmbconf: move registry_smbconf_valname_forbidden() to the registry backend from util_reg.c - no other callers left Michael (This used to be commit 98151fd3e1c24e5c8aaf3f5132071e91ac6ef257) --- source3/lib/smbconf/smbconf_reg.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index dada8eece0..e8ce1f55a5 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -41,6 +41,28 @@ static struct reg_private_data *rpd(struct smbconf_ctx *ctx) return (struct reg_private_data *)(ctx->data); } +/* + * check whether a given value name is forbidden in registry (smbconf) + */ +bool registry_smbconf_valname_forbidden(const char *valname) +{ + /* hard code the list of forbidden names here for now */ + const char *forbidden_valnames[] = { + "lock directory", + "lock dir", + "config backend", + NULL + }; + const char **forbidden = NULL; + + for (forbidden = forbidden_valnames; *forbidden != NULL; forbidden++) { + if (strwicmp(valname, *forbidden) == 0) { + return true; + } + } + return false; +} + /** * Open a registry key specified by "path" */ -- cgit From b91cdf7183460f838e8bf7a5996a5d9b3c41b2ed Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 22:56:06 +0200 Subject: libsmbconf: make registry_smbconf_valname_forbidden() static Michael (This used to be commit 798808174d0d4cae3a746e26a253cad1a3177684) --- source3/lib/smbconf/smbconf_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index e8ce1f55a5..9d526b465e 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -44,7 +44,7 @@ static struct reg_private_data *rpd(struct smbconf_ctx *ctx) /* * check whether a given value name is forbidden in registry (smbconf) */ -bool registry_smbconf_valname_forbidden(const char *valname) +static bool registry_smbconf_valname_forbidden(const char *valname) { /* hard code the list of forbidden names here for now */ const char *forbidden_valnames[] = { -- cgit From a7e06ad6253ba0b30d9b2f1393c2a6f7064f464b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 22:57:48 +0200 Subject: libsmbconf: rename registry_smbconf_valname_forbidden() to smbconf_reg_valname_forbidden() Michael (This used to be commit 23fb33fd33a8287d8691a1a5e95bf160be3ed25c) --- source3/lib/smbconf/smbconf_reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 9d526b465e..e790e65175 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -44,7 +44,7 @@ static struct reg_private_data *rpd(struct smbconf_ctx *ctx) /* * check whether a given value name is forbidden in registry (smbconf) */ -static bool registry_smbconf_valname_forbidden(const char *valname) +static bool smbconf_reg_valname_forbidden(const char *valname) { /* hard code the list of forbidden names here for now */ const char *forbidden_valnames[] = { @@ -244,7 +244,7 @@ static WERROR smbconf_reg_set_value(struct registry_key *key, goto done; } - if (registry_smbconf_valname_forbidden(canon_valname)) { + if (smbconf_reg_valname_forbidden(canon_valname)) { DEBUG(5, ("Parameter '%s' not allowed in registry.\n", canon_valname)); werr = WERR_INVALID_PARAM; -- cgit From 1da629537cdd81eb499666c59b9c6260ff8a89b7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Apr 2008 23:58:56 +0200 Subject: libsmbconf: refactor get_includes on opened key into smbconf_reg_get_includes_internal() Michael (This used to be commit 072a3228a4e08894c67ad2983bcea3417e202773) --- source3/lib/smbconf/smbconf_reg.c | 96 +++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 40 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index e790e65175..23aad44892 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -379,6 +379,60 @@ static char *smbconf_format_registry_value(TALLOC_CTX *mem_ctx, return result; } +static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx, + struct registry_key *key, + uint32_t *num_includes, + char ***includes) +{ + WERROR werr; + uint32_t count; + struct registry_value *value = NULL; + char **tmp_includes = NULL; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { + /* no includes */ + goto done; + } + + werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (value->type != REG_MULTI_SZ) { + /* wront type -- ignore */ + goto done; + } + + for (count = 0; count < value->v.multi_sz.num_strings; count++) + { + werr = smbconf_add_string_to_array(tmp_ctx, + &tmp_includes, + count, + value->v.multi_sz.strings[count]); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + } + + if (count > 0) { + *includes = talloc_move(mem_ctx, &tmp_includes); + if (*includes == NULL) { + werr = WERR_NOMEM; + goto done; + } + *num_includes = count; + } else { + *num_includes = 0; + *includes = NULL; + } + +done: + TALLOC_FREE(tmp_ctx); + return werr; +} + /** * Get the values of a key as a list of value names * and a list of value strings (ordered) @@ -852,10 +906,7 @@ static WERROR smbconf_reg_get_includes(struct smbconf_ctx *ctx, char ***includes) { WERROR werr; - uint32_t count; struct registry_key *key = NULL; - struct registry_value *value = NULL; - char **tmp_includes = NULL; TALLOC_CTX *tmp_ctx = talloc_stackframe(); werr = smbconf_reg_open_service_key(tmp_ctx, ctx, service, @@ -864,43 +915,8 @@ static WERROR smbconf_reg_get_includes(struct smbconf_ctx *ctx, goto done; } - if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { - /* no includes */ - goto done; - } - - werr = reg_queryvalue(tmp_ctx, key, INCLUDES_VALNAME, &value); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - if (value->type != REG_MULTI_SZ) { - /* wront type -- ignore */ - goto done; - } - - for (count = 0; count < value->v.multi_sz.num_strings; count++) - { - werr = smbconf_add_string_to_array(tmp_ctx, - &tmp_includes, - count, - value->v.multi_sz.strings[count]); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - } - - if (count > 0) { - *includes = talloc_move(mem_ctx, &tmp_includes); - if (*includes == NULL) { - werr = WERR_NOMEM; - goto done; - } - *num_includes = count; - } else { - *num_includes = 0; - *includes = NULL; - } + werr = smbconf_reg_get_includes_internal(mem_ctx, key, num_includes, + includes); done: TALLOC_FREE(tmp_ctx); -- cgit From bb39d5c14b86dc704c1d2845a3a22580a3915dbd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Apr 2008 00:05:45 +0200 Subject: libsmbconf: add function smbconf_reg_valname_valid() and use it in get_values() so "includes" doesn't get listed as a parameter Michael (This used to be commit 01c4bd07305b4ce800b99a098652623f118a74aa) --- source3/lib/smbconf/smbconf_reg.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 23aad44892..65f07a0893 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -63,6 +63,12 @@ static bool smbconf_reg_valname_forbidden(const char *valname) return false; } +static bool smbconf_reg_valname_valid(const char *valname) +{ + return (lp_parameter_is_valid(valname) && + !smbconf_reg_valname_forbidden(valname)); +} + /** * Open a registry key specified by "path" */ @@ -448,6 +454,7 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, uint32_t count; struct registry_value *valvalue = NULL; char *valname = NULL; + uint32_t tmp_num_values = 0; char **tmp_valnames = NULL; char **tmp_valstrings = NULL; @@ -471,19 +478,24 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, { char *valstring; + if (!smbconf_reg_valname_valid(valname)) { + continue; + } + werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames, - count, valname); + tmp_num_values, valname); if (!W_ERROR_IS_OK(werr)) { goto done; } valstring = smbconf_format_registry_value(tmp_ctx, valvalue); werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings, - count, valstring); + tmp_num_values, valstring); if (!W_ERROR_IS_OK(werr)) { goto done; } + tmp_num_values++; } if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { goto done; @@ -491,8 +503,8 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, werr = WERR_OK; - *num_values = count; - if (count > 0) { + *num_values = tmp_num_values; + if (tmp_num_values > 0) { *value_names = talloc_move(mem_ctx, &tmp_valnames); *value_strings = talloc_move(mem_ctx, &tmp_valstrings); } else { -- cgit From 7bf407c7116ee0e6d61c0dbc38f48ccf5da850c2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Apr 2008 00:47:27 +0200 Subject: libsmbconf: add includes at the end of parameter list in reg_get_share(). Michael (This used to be commit 9bd06d5737aff2bb27c07575285e079fd561a566) --- source3/lib/smbconf/smbconf_reg.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 65f07a0893..72f901d54d 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -457,6 +457,8 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, uint32_t tmp_num_values = 0; char **tmp_valnames = NULL; char **tmp_valstrings = NULL; + uint32_t num_includes = 0; + char **includes = NULL; if ((num_values == NULL) || (value_names == NULL) || (value_strings == NULL)) @@ -501,7 +503,28 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, goto done; } - werr = WERR_OK; + /* now add the includes at the end */ + werr = smbconf_reg_get_includes_internal(tmp_ctx, key, &num_includes, + &includes); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + for (count = 0; count < num_includes; count++) { + werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valnames, + tmp_num_values, "include"); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = smbconf_add_string_to_array(tmp_ctx, &tmp_valstrings, + tmp_num_values, + includes[count]); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + tmp_num_values++; + } *num_values = tmp_num_values; if (tmp_num_values > 0) { -- cgit From d26daa02346952d2342fb92b89ce2ac96d0591ba Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Apr 2008 01:19:50 +0200 Subject: libsmbconf: consider "include" a forbidden parameter in regisry config again. It is now taken care of by the special includes handling. Michael (This used to be commit 2c8c65d6900086e92c838333b31abf9efdb61343) --- source3/lib/smbconf/smbconf_reg.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 72f901d54d..75b76a8de0 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -51,6 +51,7 @@ static bool smbconf_reg_valname_forbidden(const char *valname) "lock directory", "lock dir", "config backend", + "include", NULL }; const char **forbidden = NULL; -- cgit From bb91ab6116055b3a450de3925737f91c3fdf4dca Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Apr 2008 09:54:17 +0200 Subject: libsmbconf: prevent getting/deleting value "includes". This has to be handled differently (by using get_includes / set_includes) Michael (This used to be commit 5a880c6a2f2415220557a76a9b4ce9a17c766819) --- source3/lib/smbconf/smbconf_reg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 75b76a8de0..fbc8577835 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -884,6 +884,11 @@ static WERROR smbconf_reg_get_parameter(struct smbconf_ctx *ctx, goto done; } + if (!smbconf_reg_valname_valid(param)) { + werr = WERR_INVALID_PARAM; + goto done; + } + if (!smbconf_value_exists(key, param)) { werr = WERR_INVALID_PARAM; goto done; @@ -923,6 +928,11 @@ static WERROR smbconf_reg_delete_parameter(struct smbconf_ctx *ctx, goto done; } + if (!smbconf_reg_valname_valid(param)) { + werr = WERR_INVALID_PARAM; + goto done; + } + if (!smbconf_value_exists(key, param)) { werr = WERR_INVALID_PARAM; goto done; -- cgit From 1321dda51bf3fd208d77cebafc14fec2800cc10d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Apr 2008 18:46:02 +0200 Subject: libsmbconf: let set_includes delete the includes paramter when given an empty list instead of complaining Michael (This used to be commit 0dc1fd68598529891429fb29ab1f561fb434bf38) --- source3/lib/smbconf/smbconf_reg.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index fbc8577835..d43c6a15f1 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -984,8 +984,15 @@ static WERROR smbconf_reg_set_includes(struct smbconf_ctx *ctx, goto done; } - werr = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME, - num_includes, includes); + if (num_includes == 0) { + if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { + goto done; + } + werr = reg_deletevalue(key, INCLUDES_VALNAME); + } else { + werr = smbconf_reg_set_multi_sz_value(key, INCLUDES_VALNAME, + num_includes, includes); + } done: TALLOC_FREE(tmp_ctx); -- cgit From 87ca44723181900799985d7c3c1d02863fb8da71 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Apr 2008 22:21:15 +0200 Subject: libsmbconf: add delete_includes mehtod to the api (and backend implementations) Michael (This used to be commit daef50e54d58a6684b6a890ebf523ca6245f0290) --- source3/lib/smbconf/smbconf_reg.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index d43c6a15f1..b262959afc 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -999,6 +999,30 @@ done: return werr; } +static WERROR smbconf_reg_delete_includes(struct smbconf_ctx *ctx, + const char *service) +{ + WERROR werr = WERR_OK; + struct registry_key *key = NULL; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + werr = smbconf_reg_open_service_key(tmp_ctx, ctx, service, + REG_KEY_ALL, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { + goto done; + } + + werr = reg_deletevalue(key, INCLUDES_VALNAME); + + +done: + TALLOC_FREE(tmp_ctx); + return werr; +} struct smbconf_ops smbconf_ops_reg = { .init = smbconf_reg_init, @@ -1017,6 +1041,7 @@ struct smbconf_ops smbconf_ops_reg = { .delete_parameter = smbconf_reg_delete_parameter, .get_includes = smbconf_reg_get_includes, .set_includes = smbconf_reg_set_includes, + .delete_includes = smbconf_reg_delete_includes, }; -- cgit From 30fedf28557b71367ed16279353f781280e1bf69 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Apr 2008 22:22:20 +0200 Subject: libsmbconf: return success and count 0 from get_includes when no includes present. Michael (This used to be commit 182433be5bae753d264491a3ec97433e2e316d10) --- source3/lib/smbconf/smbconf_reg.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index b262959afc..0ac49a74e5 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -399,6 +399,9 @@ static WERROR smbconf_reg_get_includes_internal(TALLOC_CTX *mem_ctx, if (!smbconf_value_exists(key, INCLUDES_VALNAME)) { /* no includes */ + *num_includes = 0; + *includes = NULL; + werr = WERR_OK; goto done; } -- cgit From bcb19766d6c18b847b0576ea86c0a0e468af78af Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 13 Apr 2008 12:10:07 +0200 Subject: registry: make registry_init_smbconf() hook the registry ops onto given key. This still defaults to HKLM\Software\Samba\smbconf, but is interchangeable now. This allows us to open the libsmbconf registry backend on different registry keys. Michael (This used to be commit 8fe1a2f567afbecbe487f08825cb43b038065e99) --- source3/lib/smbconf/smbconf_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 0ac49a74e5..c53d275938 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -576,7 +576,7 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) } rpd(ctx)->open = false; - if (!registry_init_smbconf()) { + if (!registry_init_smbconf(path)) { werr = WERR_REG_IO_FAILURE; goto done; } -- cgit From 6c66d5d0197e6b598e088e863aaaa29c7ca31db2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 13 Apr 2008 15:25:47 +0200 Subject: registry: change registry_init_smbconf() to return WERROR instead of bool Michael (This used to be commit 7c343c60574cda091f59861fbcb2893aefb564e9) --- source3/lib/smbconf/smbconf_reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index c53d275938..ce38a20f3f 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -576,8 +576,8 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) } rpd(ctx)->open = false; - if (!registry_init_smbconf(path)) { - werr = WERR_REG_IO_FAILURE; + werr = registry_init_smbconf(path); + if (!W_ERROR_IS_OK(werr)) { goto done; } -- cgit From 611b6bfa3b46fec656d68705fb8e88e31409f46a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 13 Apr 2008 16:26:14 +0200 Subject: libsmbconf: rename smbconf_init() to smbconf_init_internal(). smbconf_init should be the name of the dispatcher (to be written) Michael (This used to be commit 3fb95ab757650712716472ebaccb7119feb27596) --- source3/lib/smbconf/smbconf_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index ce38a20f3f..2bdc11fa7f 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -1055,5 +1055,5 @@ struct smbconf_ops smbconf_ops_reg = { WERROR smbconf_init_reg(TALLOC_CTX *mem_ctx, struct smbconf_ctx **conf_ctx, const char *path) { - return smbconf_init(mem_ctx, conf_ctx, path, &smbconf_ops_reg); + return smbconf_init_internal(mem_ctx, conf_ctx, path, &smbconf_ops_reg); } -- cgit From bcaac7fa36329acd8220a4d7dbfc9a2ca9c12b58 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 15 Apr 2008 17:39:01 +0200 Subject: libmsbconf: add handling of NULL share parameters to registry backend. Michael (This used to be commit 6c1181fda2f040d9555917b10a65bc0dfc1f0593) --- source3/lib/smbconf/smbconf_reg.c | 106 +++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 14 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 2bdc11fa7f..39b05f7016 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -131,12 +131,11 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, char *path = NULL; if (servicename == NULL) { - DEBUG(3, ("Error: NULL servicename given.\n")); - werr = WERR_INVALID_PARAM; - goto done; + path = talloc_strdup(mem_ctx, ctx->path); + } else { + path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path, + servicename); } - - path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path, servicename); if (path == NULL) { werr = WERR_NOMEM; goto done; @@ -544,6 +543,65 @@ done: return werr; } +static bool smbconf_reg_key_has_values(struct registry_key *key) +{ + WERROR werr; + uint32_t num_subkeys; + uint32_t max_subkeylen; + uint32_t max_subkeysize; + uint32_t num_values; + uint32_t max_valnamelen; + uint32_t max_valbufsize; + uint32_t secdescsize; + NTTIME last_changed_time; + + werr = reg_queryinfokey(key, &num_subkeys, &max_subkeylen, + &max_subkeysize, &num_values, &max_valnamelen, + &max_valbufsize, &secdescsize, + &last_changed_time); + if (!W_ERROR_IS_OK(werr)) { + return false; + } + + return (num_values != 0); +} + +/** + * delete all values from a key + */ +static WERROR smbconf_reg_delete_values(struct registry_key *key) +{ + WERROR werr; + char *valname; + struct registry_value *valvalue; + uint32_t count; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + for (count = 0; + werr = reg_enumvalue(mem_ctx, key, count, &valname, &valvalue), + W_ERROR_IS_OK(werr); + count++) + { + werr = reg_deletevalue(key, valname); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + } + if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { + DEBUG(1, ("smbconf_reg_delete_values: " + "Error enumerating values of %s: %s\n", + key->key->name, + dos_errstr(werr))); + goto done; + } + + werr = WERR_OK; + +done: + TALLOC_FREE(mem_ctx); + return werr; +} + /********************************************************************** * * smbconf operations: registry implementations @@ -707,20 +765,30 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, goto done; } - /* make sure "global" is always listed first */ - if (smbconf_share_exists(ctx, GLOBAL_NAME)) { + /* if there are values in the base key, return NULL as share name */ + werr = smbconf_reg_open_base_key(tmp_ctx, ctx, + SEC_RIGHTS_ENUM_SUBKEYS, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (smbconf_reg_key_has_values(key)) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, - 0, GLOBAL_NAME); + 0, NULL); if (!W_ERROR_IS_OK(werr)) { goto done; } added_count++; } - werr = smbconf_reg_open_base_key(tmp_ctx, ctx, - SEC_RIGHTS_ENUM_SUBKEYS, &key); - if (!W_ERROR_IS_OK(werr)) { - goto done; + /* make sure "global" is always listed first */ + if (smbconf_share_exists(ctx, GLOBAL_NAME)) { + werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, + 1, GLOBAL_NAME); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + added_count++; } for (count = 0; @@ -789,7 +857,13 @@ static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx = talloc_stackframe(); struct registry_key *key = NULL; - werr = smbconf_reg_create_service_key(mem_ctx, ctx, servicename, &key); + if (servicename == NULL) { + werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, + &key); + } else { + werr = smbconf_reg_create_service_key(mem_ctx, ctx, + servicename, &key); + } TALLOC_FREE(mem_ctx); return werr; @@ -836,7 +910,11 @@ static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx, goto done; } - werr = reg_deletekey_recursive(key, key, servicename); + if (servicename != NULL) { + werr = reg_deletekey_recursive(key, key, servicename); + } else { + werr = smbconf_reg_delete_values(key); + } done: TALLOC_FREE(mem_ctx); -- cgit From 4a9e0e6034a17604c50ed5483f1d4c2067cab5bd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 16 Apr 2008 22:42:49 +0200 Subject: libsmbconf: fix segfault in listing share names / config. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Discovered by Günther while giving a talk. - Sorry Günther! Michael (This used to be commit 518f4d4e6662138a2e71acc2296acedefc7c739a) --- source3/lib/smbconf/smbconf_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 39b05f7016..930999cc3f 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -784,7 +784,7 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, /* make sure "global" is always listed first */ if (smbconf_share_exists(ctx, GLOBAL_NAME)) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, - 1, GLOBAL_NAME); + added_count, GLOBAL_NAME); if (!W_ERROR_IS_OK(werr)) { goto done; } -- cgit From fb9232c0a98d9ce600e379dd03ee6fa3cd73cba5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 22 Apr 2008 16:31:16 +0200 Subject: libsmbconf: rewrite API to use smbconf_service struct instead of lists of strings and counters directly... Michael (This used to be commit 17415e2dc457ce41793a7e28e71f72c538c19c61) --- source3/lib/smbconf/smbconf_reg.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 930999cc3f..5f5724c406 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -875,23 +875,44 @@ static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx, static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx, TALLOC_CTX *mem_ctx, const char *servicename, - uint32_t *num_params, - char ***param_names, char ***param_values) + struct smbconf_service **service) { WERROR werr = WERR_OK; struct registry_key *key = NULL; + struct smbconf_service *tmp_service = NULL; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); - werr = smbconf_reg_open_service_key(mem_ctx, ctx, servicename, + werr = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename, REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { goto done; } - werr = smbconf_reg_get_values(mem_ctx, key, num_params, - param_names, param_values); + tmp_service = TALLOC_ZERO_P(tmp_ctx, struct smbconf_service); + if (tmp_service == NULL) { + werr = WERR_NOMEM; + goto done; + } + + if (servicename != NULL) { + tmp_service->name = talloc_strdup(tmp_service, servicename); + if (tmp_service->name == NULL) { + werr = WERR_NOMEM; + goto done; + } + } + + werr = smbconf_reg_get_values(tmp_service, key, + &(tmp_service->num_params), + &(tmp_service->param_names), + &(tmp_service->param_values)); + + if (W_ERROR_IS_OK(werr)) { + *service = talloc_move(mem_ctx, &tmp_service); + } done: - TALLOC_FREE(key); + TALLOC_FREE(tmp_ctx); return werr; } -- cgit From 21e82d7afcae995e1c38c020945f59a3561099fd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 23 Apr 2008 01:48:26 +0200 Subject: libsmbconf: remove unnecessary talloc success checks from smbconf_reg.c talloc_stackframe panics on NOMEM. Michael (This used to be commit 03fd30eef803ff2718e7af618d38944d56ccd329) --- source3/lib/smbconf/smbconf_reg.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 5f5724c406..b6d6d70621 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -195,10 +195,7 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, /* create a new talloc ctx for creation. it will hold * the intermediate parent key (SMBCONF) for creation * and will be destroyed when leaving this function... */ - if (!(create_ctx = talloc_stackframe())) { - werr = WERR_NOMEM; - goto done; - } + create_ctx = talloc_stackframe(); werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE, &create_parent); @@ -471,10 +468,6 @@ static WERROR smbconf_reg_get_values(TALLOC_CTX *mem_ctx, } tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - werr = WERR_NOMEM; - goto done; - } for (count = 0; werr = reg_enumvalue(tmp_ctx, key, count, &valname, &valvalue), @@ -760,10 +753,6 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, } tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - werr = WERR_NOMEM; - goto done; - } /* if there are values in the base key, return NULL as share name */ werr = smbconf_reg_open_base_key(tmp_ctx, ctx, -- cgit From 82e36e083dd17a894e37645d03ba81fa1706ead3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Apr 2008 11:12:25 +0200 Subject: Increase level of debug msg when a regkey is not found This is a pretty normal situation if you have "include=registry" set but no configuration options have been set there yet. (This used to be commit 727127f1dcd49b31b5a48cc3f9314aa2380d60e1) --- source3/lib/smbconf/smbconf_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index b6d6d70621..dfce7502c5 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -110,7 +110,7 @@ static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, key); if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, ("Error opening registry path '%s': %s\n", + DEBUG(5, ("Error opening registry path '%s': %s\n", path, dos_errstr(werr))); } -- cgit From cb5f5eac3820895fe5dbabb27265a06ae3e1075d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 23 Jun 2008 11:09:38 +0200 Subject: libsmbconf: fastpaths first in smbconf_reg_valname_valid(). Before dropping into lp_parameter_is_valid(). Michael (This used to be commit 59beb7acd777a4c224dce90fbbff7a137d2b89c1) --- source3/lib/smbconf/smbconf_reg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index dfce7502c5..395e44a31e 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -66,8 +66,8 @@ static bool smbconf_reg_valname_forbidden(const char *valname) static bool smbconf_reg_valname_valid(const char *valname) { - return (lp_parameter_is_valid(valname) && - !smbconf_reg_valname_forbidden(valname)); + return (!smbconf_reg_valname_forbidden(valname) && + lp_parameter_is_valid(valname)); } /** -- cgit From 1ef07a6686d3f21052e4105b4d996aa931b6ddc4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 23 Jun 2008 11:11:08 +0200 Subject: libsmbconf: add "includes" to the forbidden_valnames[]. This removes the warning messages 'Unknown parameter encountered: "includes"'. Michael (This used to be commit b20019ceaaf4a8964792f6ba37f50f91b6847e7f) --- source3/lib/smbconf/smbconf_reg.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib/smbconf/smbconf_reg.c') diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index 395e44a31e..033f800e2a 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -52,6 +52,7 @@ static bool smbconf_reg_valname_forbidden(const char *valname) "lock dir", "config backend", "include", + "includes", /* this has a special meaning internally */ NULL }; const char **forbidden = NULL; -- cgit