diff options
Diffstat (limited to 'source3/registry')
-rw-r--r-- | source3/registry/reg_api.c | 33 | ||||
-rw-r--r-- | source3/registry/reg_db.c | 29 | ||||
-rw-r--r-- | source3/registry/reg_frontend_hilvl.c | 29 | ||||
-rw-r--r-- | source3/registry/reg_printing.c | 2 | ||||
-rw-r--r-- | source3/registry/reg_shares.c | 2 | ||||
-rw-r--r-- | source3/registry/reg_smbconf.c | 4 |
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 }; |