diff options
author | Michael Adam <obnox@samba.org> | 2012-03-30 00:10:14 +0200 |
---|---|---|
committer | Andreas Schneider <asn@samba.org> | 2012-04-25 14:23:05 +0200 |
commit | 6c016734aa98836f818a9549a0ac4917381abca2 (patch) | |
tree | 9135726e40bf649f8068fc1415756656522480d5 | |
parent | 877af95ed714452bc1ea58c0aad113f599fcc787 (diff) | |
download | samba-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.c | 46 |
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); } } |