#include "nt_printing.h"
#include "util_tdb.h"
#include "dbwrap.h"
+#include "../libcli/security/secdesc.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
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);
-
- /*
- * recreate the sorted subkey cache for regdb_key_exists()
- */
- werr = ntstatus_to_werror(create_sorted_subkeys(keyname));
done:
TALLOC_FREE(ctx);
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 = regsubkey_ctr_init(frame, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ 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(frame);
+ return werr;
+}
+
/***********************************************************************
Store the new subkey record and create any child key records that
do not currently exist
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 {
goto fail;
}
+ 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);
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);