summaryrefslogtreecommitdiff
path: root/source3/lib/smbconf
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib/smbconf')
-rw-r--r--source3/lib/smbconf/smbconf.c5
-rw-r--r--source3/lib/smbconf/smbconf_reg.c106
-rw-r--r--source3/lib/smbconf/smbconf_txt_simple.c29
-rw-r--r--source3/lib/smbconf/smbconf_util.c20
4 files changed, 130 insertions, 30 deletions
diff --git a/source3/lib/smbconf/smbconf.c b/source3/lib/smbconf/smbconf.c
index 541b163bfb..9565540df4 100644
--- a/source3/lib/smbconf/smbconf.c
+++ b/source3/lib/smbconf/smbconf.c
@@ -183,9 +183,6 @@ WERROR smbconf_get_share_names(struct smbconf_ctx *ctx,
bool smbconf_share_exists(struct smbconf_ctx *ctx,
const char *servicename)
{
- if (servicename == NULL) {
- return false;
- }
return ctx->ops->share_exists(ctx, servicename);
}
@@ -195,7 +192,7 @@ bool smbconf_share_exists(struct smbconf_ctx *ctx,
WERROR smbconf_create_share(struct smbconf_ctx *ctx,
const char *servicename)
{
- if (smbconf_share_exists(ctx, servicename)) {
+ if ((servicename != NULL) && smbconf_share_exists(ctx, servicename)) {
return WERR_ALREADY_EXISTS;
}
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);
diff --git a/source3/lib/smbconf/smbconf_txt_simple.c b/source3/lib/smbconf/smbconf_txt_simple.c
index 1ce9069020..d2dc24a117 100644
--- a/source3/lib/smbconf/smbconf_txt_simple.c
+++ b/source3/lib/smbconf/smbconf_txt_simple.c
@@ -121,8 +121,14 @@ static bool smbconf_txt_do_parameter(const char *param_name,
struct txt_cache *cache = tpd->cache;
if (cache->num_shares == 0) {
- /* not in any share ... */
- return false;
+ /*
+ * not in any share yet,
+ * initialize the "empty" section (NULL):
+ * parameters without a previous [section] are stored here.
+ */
+ if (!smbconf_txt_do_section(NULL, private_data)) {
+ return false;
+ }
}
param_names = cache->param_names[cache->current_share];
@@ -301,10 +307,21 @@ static WERROR smbconf_txt_get_share_names(struct smbconf_ctx *ctx,
goto done;
}
- /* make sure "global" is always listed first */
+ /* make sure "global" is always listed first,
+ * possibly after NULL section */
+
+ if (smbconf_share_exists(ctx, NULL)) {
+ werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
+ 0, NULL);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+ added_count++;
+ }
+
if (smbconf_share_exists(ctx, GLOBAL_NAME)) {
werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
- 0, GLOBAL_NAME);
+ added_count, GLOBAL_NAME);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -312,7 +329,9 @@ static WERROR smbconf_txt_get_share_names(struct smbconf_ctx *ctx,
}
for (count = 0; count < pd(ctx)->cache->num_shares; count++) {
- if (strequal(pd(ctx)->cache->share_names[count], GLOBAL_NAME)) {
+ if (strequal(pd(ctx)->cache->share_names[count], GLOBAL_NAME) ||
+ (pd(ctx)->cache->share_names[count] == NULL))
+ {
continue;
}
diff --git a/source3/lib/smbconf/smbconf_util.c b/source3/lib/smbconf/smbconf_util.c
index 1a3a0ded44..b2e253dd26 100644
--- a/source3/lib/smbconf/smbconf_util.c
+++ b/source3/lib/smbconf/smbconf_util.c
@@ -82,7 +82,7 @@ WERROR smbconf_add_string_to_array(TALLOC_CTX *mem_ctx,
{
char **new_array = NULL;
- if ((array == NULL) || (string == NULL)) {
+ if (array == NULL) {
return WERR_INVALID_PARAM;
}
@@ -91,10 +91,14 @@ WERROR smbconf_add_string_to_array(TALLOC_CTX *mem_ctx,
return WERR_NOMEM;
}
- new_array[count] = talloc_strdup(new_array, string);
- if (new_array[count] == NULL) {
- TALLOC_FREE(new_array);
- return WERR_NOMEM;
+ if (string == NULL) {
+ new_array[count] = NULL;
+ } else {
+ new_array[count] = talloc_strdup(new_array, string);
+ if (new_array[count] == NULL) {
+ TALLOC_FREE(new_array);
+ return WERR_NOMEM;
+ }
}
*array = new_array;
@@ -107,12 +111,14 @@ bool smbconf_find_in_array(const char *string, char **list,
{
uint32_t i;
- if ((string == NULL) || (list == NULL)) {
+ if (list == NULL) {
return false;
}
for (i = 0; i < num_entries; i++) {
- if (strequal(string, list[i])) {
+ if (((string == NULL) && (list[i] == NULL)) ||
+ strequal(string, list[i]))
+ {
if (entry != NULL) {
*entry = i;
}