summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2012-03-30 00:10:14 +0200
committerAndreas Schneider <asn@samba.org>2012-04-25 14:23:05 +0200
commit6c016734aa98836f818a9549a0ac4917381abca2 (patch)
tree9135726e40bf649f8068fc1415756656522480d5
parent877af95ed714452bc1ea58c0aad113f599fcc787 (diff)
downloadsamba-6c016734aa98836f818a9549a0ac4917381abca2.tar.gz
samba-6c016734aa98836f818a9549a0ac4917381abca2.tar.bz2
samba-6c016734aa98836f818a9549a0ac4917381abca2.zip
s3:registry:reg_api: fix reg_queryvalue to not fail when values are modified while it runs
Signed-off-by: Andreas Schneider <asn@samba.org>
-rw-r--r--source3/registry/reg_api.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index 372f2d396e..d1b43ba3e8 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -376,6 +376,43 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
return WERR_OK;
}
+static WERROR reg_enumvalue_nocachefill(TALLOC_CTX *mem_ctx,
+ struct registry_key *key,
+ uint32 idx, char **pname,
+ struct registry_value **pval)
+{
+ struct registry_value *val;
+ struct regval_blob *blob;
+
+ if (!(key->key->access_granted & KEY_QUERY_VALUE)) {
+ return WERR_ACCESS_DENIED;
+ }
+
+ if (idx >= regval_ctr_numvals(key->values)) {
+ return WERR_NO_MORE_ITEMS;
+ }
+
+ blob = regval_ctr_specific_value(key->values, idx);
+
+ val = talloc_zero(mem_ctx, struct registry_value);
+ if (val == NULL) {
+ return WERR_NOMEM;
+ }
+
+ val->type = regval_type(blob);
+ val->data = data_blob_talloc(mem_ctx, regval_data_p(blob), regval_size(blob));
+
+ if (pname
+ && !(*pname = talloc_strdup(
+ mem_ctx, regval_name(blob)))) {
+ TALLOC_FREE(val);
+ return WERR_NOMEM;
+ }
+
+ *pval = val;
+ return WERR_OK;
+}
+
WERROR reg_queryvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
const char *name, struct registry_value **pval)
{
@@ -394,7 +431,14 @@ WERROR reg_queryvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
struct regval_blob *blob;
blob = regval_ctr_specific_value(key->values, i);
if (strequal(regval_name(blob), name)) {
- return reg_enumvalue(mem_ctx, key, i, NULL, pval);
+ /*
+ * don't use reg_enumvalue here:
+ * re-reading the values from the disk
+ * would change the indexing and break
+ * this function.
+ */
+ return reg_enumvalue_nocachefill(mem_ctx, key, i,
+ NULL, pval);
}
}