#include "reg_backend_db.h"
#include "reg_objects.h"
#include "nt_printing.h"
+#include "util_tdb.h"
#include "dbwrap.h"
+#include "../libcli/security/secdesc.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
static bool regdb_store_values_internal(struct db_context *db, const char *key,
struct regval_ctr *values);
+static NTSTATUS create_sorted_subkeys(const char *key);
+
/* List the deepest path into the registry. All part components will be created.*/
/* If you want to have a part of the path controlled by the tdb and part by
talloc_destroy(mem_ctx);
- if (rc == -1) {
+ if (rc < 0) {
return WERR_REG_IO_FAILURE;
}
return regdb_delete_key_with_prefix(db, keyname, NULL);
}
+static WERROR regdb_delete_sorted_subkeys(struct db_context *db,
+ const char *keyname)
+{
+ return regdb_delete_key_with_prefix(db, keyname, REG_SORTED_SUBKEYS_PREFIX);
+}
+
+
static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname)
{
WERROR werr;
goto done;
}
+ werr = regdb_delete_sorted_subkeys(db, keyname);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, (__location__ " Deleting %s\\%s failed: %s\n",
+ REG_SORTED_SUBKEYS_PREFIX, keyname,
+ win_errstr(werr)));
+ goto done;
+ }
+
werr = regdb_delete_subkeylist(db, keyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, (__location__ " Deleting %s failed: %s\n",
dbuf.dsize = len;
werr = ntstatus_to_werror(dbwrap_store_bystring(db, keyname, dbuf,
TDB_REPLACE));
- W_ERROR_NOT_OK_GOTO_DONE(werr);
- /*
- * Delete a sorted subkey cache for regdb_key_exists, will be
- * recreated automatically
- */
- keyname = talloc_asprintf(ctx, "%s\\%s", REG_SORTED_SUBKEYS_PREFIX,
- keyname);
- if (keyname == NULL) {
+done:
+ TALLOC_FREE(ctx);
+ SAFE_FREE(buffer);
+ return werr;
+}
+
+/**
+ * Utility function to store a new empty list of
+ * subkeys of given key specified as parent and subkey name
+ * (thereby creating the key).
+ * If the subkey list does already exist, it is not modified.
+ *
+ * Must be called from within a transaction.
+ */
+static WERROR regdb_store_subkey_list(struct db_context *db, const char *parent,
+ const char *key)
+{
+ WERROR werr;
+ char *path = NULL;
+ struct regsubkey_ctr *subkeys = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ path = talloc_asprintf(frame, "%s\\%s", parent, key);
+ if (!path) {
werr = WERR_NOMEM;
goto done;
}
- werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname));
+ werr = regsubkey_ctr_init(frame, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- /* don't treat WERR_NOT_FOUND as an error here */
- if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
- werr = WERR_OK;
+ werr = regdb_fetch_keys_internal(db, path, subkeys);
+ if (W_ERROR_IS_OK(werr)) {
+ /* subkey list exists already - don't modify */
+ goto done;
+ }
+
+ werr = regsubkey_ctr_reinit(subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ /* create a record with 0 subkeys */
+ werr = regdb_store_keys_internal2(db, path, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, ("regdb_store_keys: Failed to store new record for "
+ "key [%s]: %s\n", path, win_errstr(werr)));
+ goto done;
}
done:
- TALLOC_FREE(ctx);
- SAFE_FREE(buffer);
+ talloc_free(frame);
return werr;
}
WERROR werr;
int num_subkeys, i;
char *path = NULL;
- struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
+ struct regsubkey_ctr *old_subkeys = NULL;
char *oldkeyname = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr);
- if (num_subkeys == 0) {
- werr = regsubkey_ctr_init(mem_ctx, &subkeys);
- W_ERROR_NOT_OK_GOTO_DONE(werr);
-
- werr = regdb_store_keys_internal2(db, store_ctx->key, subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: Failed to store "
- "new record for key [%s]: %s\n",
- store_ctx->key, win_errstr(werr)));
- goto done;
- }
- TALLOC_FREE(subkeys);
- }
-
for (i=0; i<num_subkeys; i++) {
- path = talloc_asprintf(mem_ctx, "%s\\%s", store_ctx->key,
- regsubkey_ctr_specific_key(store_ctx->ctr, i));
- if (!path) {
- werr = WERR_NOMEM;
- goto done;
- }
- werr = regsubkey_ctr_init(mem_ctx, &subkeys);
- W_ERROR_NOT_OK_GOTO_DONE(werr);
+ const char *subkey;
- werr = regdb_fetch_keys_internal(db, path, subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- /* create a record with 0 subkeys */
- werr = regdb_store_keys_internal2(db, path, subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: Failed to store "
- "new record for key [%s]: %s\n", path,
- win_errstr(werr)));
- goto done;
- }
- }
+ subkey = regsubkey_ctr_specific_key(store_ctx->ctr, i);
- TALLOC_FREE(subkeys);
- TALLOC_FREE(path);
+ werr = regdb_store_subkey_list(db, store_ctx->key, subkey);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
}
werr = WERR_OK;
bool ret = false;
struct regdb_store_keys_context store_ctx;
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) {
+ if (!regdb_key_exists(db, key)) {
goto done;
}
win_errstr(werr)));
}
+ werr = regdb_store_subkey_list(db, create_ctx->key, create_ctx->subkey);
+
done:
talloc_free(mem_ctx);
return werror_to_ntstatus(werr);
TALLOC_CTX *mem_ctx = talloc_stackframe();
struct regdb_create_subkey_context create_ctx;
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
+ if (!regdb_key_exists(regdb, key)) {
werr = WERR_NOT_FOUND;
goto done;
}
struct regdb_delete_subkey_context delete_ctx;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
+ if (!regdb_key_exists(regdb, key)) {
werr = WERR_NOT_FOUND;
goto done;
}
static int cmp_keynames(char **p1, char **p2)
{
- return StrCaseCmp(*p1, *p2);
+ return strcasecmp_m(*p1, *p2);
}
struct create_sorted_subkeys_context {
return status;
}
-static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+static NTSTATUS create_sorted_subkeys_internal(const char *key,
+ const char *sorted_keyname)
{
NTSTATUS status;
struct create_sorted_subkeys_context sorted_ctx;
create_sorted_subkeys_action,
&sorted_ctx);
- return NT_STATUS_IS_OK(status);
+ return status;
+}
+
+static NTSTATUS create_sorted_subkeys(const char *key)
+{
+ char *sorted_subkeys_keyname;
+ NTSTATUS status;
+
+ sorted_subkeys_keyname = talloc_asprintf(talloc_tos(), "%s\\%s",
+ REG_SORTED_SUBKEYS_PREFIX,
+ key);
+ if (sorted_subkeys_keyname == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ status = create_sorted_subkeys_internal(key, sorted_subkeys_keyname);
+
+done:
+ return status;
}
struct scan_subkey_state {
if (state.scanned) {
result = state.found;
} else {
+ NTSTATUS status;
+
res = db->transaction_start(db);
if (res != 0) {
- DEBUG(0, ("error starting transacion\n"));
+ DEBUG(0, ("error starting transaction\n"));
goto fail;
}
- if (!create_sorted_subkeys(path, key)) {
+ DEBUG(2, (__location__ " WARNING: recreating the sorted "
+ "subkeys cache for key '%s' from scan_parent_subkeys "
+ "this should not happen (too frequently)...\n",
+ path));
+
+ status = create_sorted_subkeys_internal(path, key);
+ if (!NT_STATUS_IS_OK(status)) {
res = db->transaction_cancel(db);
if (res != 0) {
smb_panic("Failed to cancel transaction.");
DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
- frame = talloc_stackframe();
-
if (!regdb_key_exists(db, key)) {
DEBUG(10, ("key [%s] not found\n", key));
werr = WERR_NOT_FOUND;
goto done;
}
- data.dptr = TALLOC_ARRAY(ctx, uint8, len);
+ data.dptr = talloc_array(ctx, uint8, len);
data.dsize = len;
len = regdb_pack_values(values, data.dptr, data.dsize);