summaryrefslogtreecommitdiff
path: root/source3/registry
diff options
context:
space:
mode:
Diffstat (limited to 'source3/registry')
-rw-r--r--source3/registry/reg_api.c33
-rw-r--r--source3/registry/reg_db.c29
-rw-r--r--source3/registry/reg_frontend_hilvl.c29
-rw-r--r--source3/registry/reg_printing.c2
-rw-r--r--source3/registry/reg_shares.c2
-rw-r--r--source3/registry/reg_smbconf.c4
6 files changed, 80 insertions, 19 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index bb410e646b..d1657c8cf6 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -1,4 +1,4 @@
-/*
+/*
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
* Copyright (C) Volker Lendecke 2006
@@ -7,12 +7,12 @@
* 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 <http://www.gnu.org/licenses/>.
*/
@@ -27,7 +27,9 @@
static WERROR fill_value_cache(struct registry_key *key)
{
if (key->values != NULL) {
- return WERR_OK;
+ if (!reg_values_need_update(key->key, key->values)) {
+ return WERR_OK;
+ }
}
if (!(key->values = TALLOC_ZERO_P(key, REGVAL_CTR))) {
@@ -44,7 +46,9 @@ static WERROR fill_value_cache(struct registry_key *key)
static WERROR fill_subkey_cache(struct registry_key *key)
{
if (key->subkeys != NULL) {
- return WERR_OK;
+ if (!reg_subkeys_need_update(key->key, key->subkeys)) {
+ return WERR_OK;
+ }
}
if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) {
@@ -136,7 +140,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
result = WERR_BADFILE;
goto done;
}
-
+
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
@@ -149,7 +153,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
result = WERR_BADFILE;
goto done;
}
-
+
TALLOC_FREE( subkeys );
if ( !regkey_access_check( key, access_desired, &key->access_granted,
@@ -298,7 +302,7 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
SAFE_FREE(val);
return WERR_NOMEM;
}
-
+
*pval = val;
return WERR_OK;
}
@@ -490,7 +494,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
TALLOC_FREE(mem_ctx);
return err;
}
-
WERROR reg_deletekey(struct registry_key *parent, const char *path)
{
@@ -708,8 +711,8 @@ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
}
/*
- * Utility function to delete a registry key with all its subkeys.
- * Note that reg_deletekey returns ACCESS_DENIED when called on a
+ * Utility function to delete a registry key with all its subkeys.
+ * Note that reg_deletekey returns ACCESS_DENIED when called on a
* key that has subkeys.
*/
WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
@@ -735,11 +738,11 @@ WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
}
while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0,
- &subkey_name, NULL)))
+ &subkey_name, NULL)))
{
werr = reg_deletekey_recursive_internal(mem_ctx, key,
subkey_name,
- True);
+ true);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -767,12 +770,12 @@ WERROR reg_deletekey_recursive(TALLOC_CTX *ctx,
struct registry_key *parent,
const char *path)
{
- return reg_deletekey_recursive_internal(ctx, parent, path, True);
+ return reg_deletekey_recursive_internal(ctx, parent, path, true);
}
WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx,
struct registry_key *parent,
const char *path)
{
- return reg_deletekey_recursive_internal(ctx, parent, path, False);
+ return reg_deletekey_recursive_internal(ctx, parent, path, false);
}
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c
index f50a41816c..c4bfc2b6c9 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_db.c
@@ -622,7 +622,15 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
}
strupper_m(path);
+ if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, path, 10) == -1) {
+ return 0;
+ }
+
dbuf = tdb_fetch_bystring(tdb_reg->tdb, path);
+ ctr->seqnum = regdb_get_seqnum();
+
+ tdb_read_unlock_bystring(tdb_reg->tdb, path);
+
buf = dbuf.dptr;
buflen = dbuf.dsize;
@@ -750,7 +758,14 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
return 0;
}
+ if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, keystr, 10) == -1) {
+ return 0;
+ }
+
data = tdb_fetch_bystring(tdb_reg->tdb, keystr);
+ values->seqnum = regdb_get_seqnum();
+
+ tdb_read_unlock_bystring(tdb_reg->tdb, keystr);
if (!data.dptr) {
/* all keys have zero values by default */
@@ -907,6 +922,16 @@ static WERROR regdb_set_secdesc(const char *key,
return err;
}
+bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys)
+{
+ return (regdb_get_seqnum() != subkeys->seqnum);
+}
+
+bool regdb_values_need_update(REGVAL_CTR *values)
+{
+ return (regdb_get_seqnum() != values->seqnum);
+}
+
/*
* Table of function pointers for default access
*/
@@ -918,5 +943,7 @@ REGISTRY_OPS regdb_ops = {
regdb_store_values,
NULL,
regdb_get_secdesc,
- regdb_set_secdesc
+ regdb_set_secdesc,
+ regdb_subkeys_need_update,
+ regdb_values_need_update
};
diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c
index a4b78b24c0..73fcf87e17 100644
--- a/source3/registry/reg_frontend_hilvl.c
+++ b/source3/registry/reg_frontend_hilvl.c
@@ -214,3 +214,32 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key,
return WERR_ACCESS_DENIED;
}
+
+/**
+ * Check whether the in-memory version of the subkyes of a
+ * registry key needs update from disk.
+ */
+bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys)
+{
+ if (key->hook && key->hook->ops && key->hook->ops->subkeys_need_update)
+ {
+ return key->hook->ops->subkeys_need_update(subkeys);
+ }
+
+ return false;
+}
+
+/**
+ * Check whether the in-memory version of the values of a
+ * registry key needs update from disk.
+ */
+bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values)
+{
+ if (key->hook && key->hook->ops && key->hook->ops->values_need_update)
+ {
+ return key->hook->ops->values_need_update(values);
+ }
+
+ return false;
+}
+
diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c
index 2ca74f7c16..5be0796002 100644
--- a/source3/registry/reg_printing.c
+++ b/source3/registry/reg_printing.c
@@ -1266,5 +1266,5 @@ REGISTRY_OPS printing_ops = {
regprint_fetch_reg_values,
regprint_store_reg_keys,
regprint_store_reg_values,
- NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL
};
diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_shares.c
index 178f23e21c..4ac6e1d151 100644
--- a/source3/registry/reg_shares.c
+++ b/source3/registry/reg_shares.c
@@ -159,7 +159,7 @@ REGISTRY_OPS shares_reg_ops = {
shares_value_info,
shares_store_subkey,
shares_store_value,
- NULL, NULL, NULL
+ NULL, NULL, NULL, NULL, NULL
};
diff --git a/source3/registry/reg_smbconf.c b/source3/registry/reg_smbconf.c
index 116cde936e..8dfb745a7e 100644
--- a/source3/registry/reg_smbconf.c
+++ b/source3/registry/reg_smbconf.c
@@ -271,5 +271,7 @@ REGISTRY_OPS smbconf_reg_ops = {
smbconf_store_values,
smbconf_reg_access_check,
smbconf_get_secdesc,
- smbconf_set_secdesc
+ smbconf_set_secdesc,
+ NULL,
+ NULL
};