summaryrefslogtreecommitdiff
path: root/source3/registry
diff options
context:
space:
mode:
Diffstat (limited to 'source3/registry')
-rw-r--r--source3/registry/reg_backend_db.c55
1 files changed, 52 insertions, 3 deletions
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;
}