From a26880c372aeccdb56292c7ce6b594a96e8c61ef Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 6 May 2008 10:05:20 +0200 Subject: registry: Implement new semantics for existence of registry key in tdb. Existence of a key is defined as follows: * If the key is a base key (without separator), the key exists iff the corresponding entry exist in the registry tdb. * If the key is not a base key, the key exists, iff it exists in the list of subkeys of it's parent keyname's tdb entry. Michael (This used to be commit 477008367f0ac90624b4b751955cd3235b2c9cc6) --- source3/registry/reg_backend_db.c | 55 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) (limited to 'source3/registry/reg_backend_db.c') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index d1ec8e4b61..658c979bb2 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -770,15 +770,64 @@ static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) } +/** + * Check for the existence of a key. + * + * Existence of a key is authoritatively defined by its + * existence in the list of subkeys of its parent key. + * The exeption of this are keys without a parent key, + * i.e. the "base" keys (HKLM, HKCU, ...). + */ static bool regdb_key_exists(const char *key) { TALLOC_CTX *mem_ctx = talloc_stackframe(); TDB_DATA value; - bool ret; + bool ret = false; + char *path, *p; + + if (key == NULL) { + goto done; + } + + path = normalize_reg_path(mem_ctx, key); + if (path == NULL) { + DEBUG(0, ("out of memory! (talloc failed)\n")); + goto done; + } + + if (*path == '\0') { + goto done; + } - value = regdb_fetch_key_internal(mem_ctx, key); - ret = (value.dptr != NULL); + p = strrchr(path, '/'); + if (p == NULL) { + /* this is a base key */ + value = regdb_fetch_key_internal(mem_ctx, path); + ret = (value.dptr != NULL); + } else { + /* get the list of subkeys of the parent key */ + uint32 num_items, len, i; + fstring subkeyname; + + *p = '\0'; + p++; + value = regdb_fetch_key_internal(mem_ctx, path); + if (value.dptr == NULL) { + goto done; + } + len = tdb_unpack(value.dptr, value.dsize, "d", &num_items); + for (i = 0; i < num_items; i++) { + len += tdb_unpack(value.dptr +len, value.dsize -len, + "f", &subkeyname); + if (strequal(subkeyname, p)) { + ret = true; + goto done; + } + } + } + +done: TALLOC_FREE(mem_ctx); return ret; } -- cgit