summaryrefslogtreecommitdiff
path: root/source/registry/reg_backend_db.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/registry/reg_backend_db.c')
-rw-r--r--source/registry/reg_backend_db.c362
1 files changed, 76 insertions, 286 deletions
diff --git a/source/registry/reg_backend_db.c b/source/registry/reg_backend_db.c
index 6f4c614b9a..52a01507c0 100644
--- a/source/registry/reg_backend_db.c
+++ b/source/registry/reg_backend_db.c
@@ -27,9 +27,6 @@
static struct db_context *regdb = NULL;
static int regdb_refcount;
-static bool regdb_key_exists(const char *key);
-static bool regdb_key_is_base_key(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
@@ -49,14 +46,6 @@ static const char *builtin_registry_paths[] = {
KEY_SMBCONF,
KEY_PERFLIB,
KEY_PERFLIB_009,
- KEY_GROUP_POLICY,
- KEY_SAMBA_GROUP_POLICY,
- KEY_GP_MACHINE_POLICY,
- KEY_GP_MACHINE_WIN_POLICY,
- KEY_HKCU,
- KEY_GP_USER_POLICY,
- KEY_GP_USER_WIN_POLICY,
- KEY_WINLOGON_GPEXT_PATH,
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
KEY_PROD_OPTIONS,
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration",
@@ -202,10 +191,6 @@ WERROR init_registry_key(const char *add_path)
{
WERROR werr;
- if (regdb_key_exists(add_path)) {
- return WERR_OK;
- }
-
if (regdb->transaction_start(regdb) != 0) {
DEBUG(0, ("init_registry_key: transaction_start failed\n"));
return WERR_REG_IO_FAILURE;
@@ -238,45 +223,12 @@ fail:
WERROR init_registry_data(void)
{
WERROR werr;
- TALLOC_CTX *frame = talloc_stackframe();
+ TALLOC_CTX *frame = NULL;
REGVAL_CTR *values;
int i;
UNISTR2 data;
/*
- * First, check for the existence of the needed keys and values.
- * If all do already exist, we can save the writes.
- */
- for (i=0; builtin_registry_paths[i] != NULL; i++) {
- if (!regdb_key_exists(builtin_registry_paths[i])) {
- goto do_init;
- }
- }
-
- for (i=0; builtin_registry_values[i].path != NULL; i++) {
- values = TALLOC_ZERO_P(frame, REGVAL_CTR);
- if (values == NULL) {
- werr = WERR_NOMEM;
- goto done;
- }
-
- regdb_fetch_values(builtin_registry_values[i].path, values);
- if (!regval_ctr_key_exists(values,
- builtin_registry_values[i].valuename))
- {
- TALLOC_FREE(values);
- goto do_init;
- }
-
- TALLOC_FREE(values);
- }
-
- werr = WERR_OK;
- goto done;
-
-do_init:
-
- /*
* There are potentially quite a few store operations which are all
* indiviually wrapped in tdb transactions. Wrapping them in a single
* transaction gives just a single transaction_commit() to actually do
@@ -287,16 +239,12 @@ do_init:
if (regdb->transaction_start(regdb) != 0) {
DEBUG(0, ("init_registry_data: tdb_transaction_start "
"failed\n"));
- werr = WERR_REG_IO_FAILURE;
- goto done;
+ return WERR_REG_IO_FAILURE;
}
/* loop over all of the predefined paths and add each component */
for (i=0; builtin_registry_paths[i] != NULL; i++) {
- if (regdb_key_exists(builtin_registry_paths[i])) {
- continue;
- }
werr = init_registry_key_internal(builtin_registry_paths[i]);
if (!W_ERROR_IS_OK(werr)) {
goto fail;
@@ -305,6 +253,8 @@ do_init:
/* loop over all of the predefined values and add each component */
+ frame = talloc_stackframe();
+
for (i=0; builtin_registry_values[i].path != NULL; i++) {
values = TALLOC_ZERO_P(frame, REGVAL_CTR);
@@ -352,24 +302,25 @@ do_init:
TALLOC_FREE(values);
}
+ TALLOC_FREE(frame);
+
if (regdb->transaction_commit(regdb) != 0) {
DEBUG(0, ("init_registry_data: Could not commit "
"transaction\n"));
- werr = WERR_REG_IO_FAILURE;
- } else {
- werr = WERR_OK;
+ return WERR_REG_IO_FAILURE;
}
- goto done;
+ return WERR_OK;
+
+ fail:
+
+ TALLOC_FREE(frame);
-fail:
if (regdb->transaction_cancel(regdb) != 0) {
smb_panic("init_registry_data: tdb_transaction_cancel "
"failed\n");
}
-done:
- TALLOC_FREE(frame);
return werr;
}
@@ -390,14 +341,14 @@ WERROR regdb_init(void)
return WERR_OK;
}
- regdb = db_open(NULL, state_path("registry.tdb"), 0,
+ regdb = db_open_trans(NULL, state_path("registry.tdb"), 0,
REG_TDB_FLAGS, O_RDWR, 0600);
if (!regdb) {
- regdb = db_open(NULL, state_path("registry.tdb"), 0,
+ regdb = db_open_trans(NULL, state_path("registry.tdb"), 0,
REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600);
if (!regdb) {
werr = ntstatus_to_werror(map_nt_error_from_unix(errno));
- DEBUG(1,("regdb_init: Failed to open registry %s (%s)\n",
+ DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n",
state_path("registry.tdb"), strerror(errno) ));
return werr;
}
@@ -416,7 +367,7 @@ WERROR regdb_init(void)
vers_id, REGVER_V1));
status = dbwrap_trans_store_int32(regdb, vstring, REGVER_V1);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("regdb_init: error storing %s = %d: %s\n",
+ DEBUG(0, ("regdb_init: error storing %s = %d: %s\n",
vstring, REGVER_V1, nt_errstr(status)));
return ntstatus_to_werror(status);
} else {
@@ -444,7 +395,7 @@ WERROR regdb_open( void )
become_root();
- regdb = db_open(NULL, state_path("registry.tdb"), 0,
+ regdb = db_open_trans(NULL, state_path("registry.tdb"), 0,
REG_TDB_FLAGS, O_RDWR, 0600);
if ( !regdb ) {
result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
@@ -583,10 +534,6 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
TALLOC_CTX *ctx = talloc_stackframe();
NTSTATUS status;
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
- goto fail;
- }
-
/*
* fetch a list of the old subkeys so we can determine if anything has
* changed
@@ -636,28 +583,15 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
regdb_fetch_keys(key, old_subkeys);
- /*
- * Make the store operation as safe as possible without transactions:
- *
- * (1) For each subkey removed from ctr compared with old_subkeys:
- *
- * (a) First delete the value db entry.
- *
- * (b) Next delete the secdesc db record.
- *
- * (c) Then delete the subkey list entry.
- *
- * (2) Now write the list of subkeys of the parent key,
- * deleting removed entries and adding new ones.
- *
- * (3) Finally create the subkey list entries for the added keys.
- *
- * This way if we crash half-way in between deleting the subkeys
- * and storing the parent's list of subkeys, no old data can pop up
- * out of the blue when re-adding keys later on.
- */
+ /* store the subkey list for the parent */
- /* (1) delete removed keys' lists (values/secdesc/subkeys) */
+ if (!regdb_store_keys_internal(key, ctr) ) {
+ DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
+ "for parent [%s]\n", key));
+ goto cancel;
+ }
+
+ /* now delete removed keys */
num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
for (i=0; i<num_subkeys; i++) {
@@ -671,12 +605,7 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
continue;
}
- /* (a) Delete the value list for this key */
-
- path = talloc_asprintf(ctx, "%s/%s/%s",
- REG_VALUE_PREFIX,
- key,
- oldkeyname );
+ path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
if (!path) {
goto cancel;
}
@@ -684,14 +613,15 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
if (!path) {
goto cancel;
}
- /* Ignore errors here, we might have no values around */
- dbwrap_delete_bystring(regdb, path);
- TALLOC_FREE(path);
-
- /* (b) Delete the secdesc for this key */
+ status = dbwrap_delete_bystring(regdb, path);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Deleting %s failed\n", path));
+ goto cancel;
+ }
+ TALLOC_FREE(path);
path = talloc_asprintf(ctx, "%s/%s/%s",
- REG_SECDESC_PREFIX,
+ REG_VALUE_PREFIX,
key,
oldkeyname );
if (!path) {
@@ -701,50 +631,17 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr)
if (!path) {
goto cancel;
}
- status = dbwrap_delete_bystring(regdb, path);
- /* Don't fail if there are no values around. */
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))
- {
- DEBUG(1, ("Deleting %s failed: %s\n", path,
- nt_errstr(status)));
- goto cancel;
- }
- TALLOC_FREE(path);
-
- /* (c) Delete the list of subkeys of this key */
- path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
- if (!path) {
- goto cancel;
- }
- path = normalize_reg_path(ctx, path);
- if (!path) {
- goto cancel;
- }
- status = dbwrap_delete_bystring(regdb, path);
- /* Don't fail if the subkey record was not found. */
- if (!NT_STATUS_IS_OK(status) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND))
- {
- DEBUG(1, ("Deleting %s failed: %s\n", path,
- nt_errstr(status)));
- goto cancel;
- }
+ /*
+ * Ignore errors here, we might have no values around
+ */
+ dbwrap_delete_bystring(regdb, path);
TALLOC_FREE(path);
}
TALLOC_FREE(old_subkeys);
- /* (2) store the subkey list for the parent */
-
- if (!regdb_store_keys_internal(key, ctr) ) {
- DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
- "for parent [%s]\n", key));
- goto cancel;
- }
-
- /* (3) now create records for any subkeys that don't already exist */
+ /* now create records for any subkeys that don't already exist */
num_subkeys = regsubkey_ctr_numkeys(ctr);
@@ -808,118 +705,6 @@ fail:
}
-static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
-{
- char *path = NULL;
- TDB_DATA data;
-
- path = normalize_reg_path(mem_ctx, key);
- if (!path) {
- return make_tdb_data(NULL, 0);
- }
-
- data = dbwrap_fetch_bystring(regdb, mem_ctx, path);
-
- TALLOC_FREE(path);
- return data;
-}
-
-
-/**
- * check whether a given key name represents a base key,
- * i.e one without a subkey separator ('/' or '\').
- */
-static bool regdb_key_is_base_key(const char *key)
-{
- TALLOC_CTX *mem_ctx = talloc_stackframe();
- bool ret = false;
- char *path;
-
- 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;
- }
-
- ret = (strrchr(path, '/') == NULL);
-
-done:
- TALLOC_FREE(mem_ctx);
- return ret;
-}
-
-
-/**
- * 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 = 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;
- }
-
- 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;
-}
-
-
/***********************************************************************
Retrieve an array of strings containing subkeys. Memory should be
released by the caller.
@@ -928,34 +713,46 @@ done:
int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
{
WERROR werr;
+ char *path = NULL;
uint32 num_items;
uint8 *buf;
uint32 buflen, len;
int i;
fstring subkeyname;
int ret = -1;
+ int dbret = -1;
TALLOC_CTX *frame = talloc_stackframe();
TDB_DATA value;
DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
- if (!regdb_key_exists(key)) {
- goto done;
+ path = talloc_strdup(frame, key);
+ if (!path) {
+ goto fail;
}
- ctr->seqnum = regdb_get_seqnum();
+ /* convert to key format */
+ path = talloc_string_sub(frame, path, "\\", "/");
+ if (!path) {
+ goto fail;
+ }
+ strupper_m(path);
- value = regdb_fetch_key_internal(frame, key);
+ ctr->seqnum = regdb_get_seqnum();
- if (value.dptr == NULL) {
- DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n",
- key));
- ret = 0;
- goto done;
+ dbret = regdb->fetch(regdb, frame, string_term_tdb_data(path), &value);
+ if (dbret != 0) {
+ goto fail;
}
buf = value.dptr;
buflen = value.dsize;
+
+ if ( !buf ) {
+ DEBUG(5,("regdb_fetch_keys: tdb lookup failed to locate key [%s]\n", key));
+ goto fail;
+ }
+
len = tdb_unpack( buf, buflen, "d", &num_items);
for (i=0; i<num_items; i++) {
@@ -964,14 +761,14 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
if (!W_ERROR_IS_OK(werr)) {
DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey "
"failed: %s\n", dos_errstr(werr)));
- goto done;
+ goto fail;
}
}
DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
ret = num_items;
-done:
+ fail:
TALLOC_FREE(frame);
return ret;
}
@@ -1065,22 +862,26 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
char *keystr = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
int ret = 0;
+ int dbret = -1;
TDB_DATA value;
DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
- if (!regdb_key_exists(key)) {
- goto done;
- }
-
keystr = talloc_asprintf(ctx, "%s/%s", REG_VALUE_PREFIX, key);
if (!keystr) {
+ return 0;
+ }
+ keystr = normalize_reg_path(ctx, keystr);
+ if (!keystr) {
goto done;
}
values->seqnum = regdb_get_seqnum();
- value = regdb_fetch_key_internal(ctx, keystr);
+ dbret = regdb->fetch(regdb, ctx, string_term_tdb_data(keystr), &value);
+ if (dbret != 0) {
+ goto done;
+ }
if (!value.dptr) {
/* all keys have zero values by default */
@@ -1106,10 +907,6 @@ bool regdb_store_values( const char *key, REGVAL_CTR *values )
DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
- if (!regdb_key_exists(key)) {
- goto done;
- }
-
ZERO_STRUCT(data);
len = regdb_pack_values(values, data.dptr, data.dsize);
@@ -1144,7 +941,8 @@ bool regdb_store_values( const char *key, REGVAL_CTR *values )
goto done;
}
- status = dbwrap_trans_store_bystring(regdb, keystr, data, TDB_REPLACE);
+ status = dbwrap_trans_store(regdb, string_term_tdb_data(keystr), data,
+ TDB_REPLACE);
result = NT_STATUS_IS_OK(status);
@@ -1164,11 +962,6 @@ static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key));
- if (!regdb_key_exists(key)) {
- err = WERR_BADFILE;
- goto done;
- }
-
tdbkey = talloc_asprintf(tmp_ctx, "%s/%s", REG_SECDESC_PREFIX, key);
if (tdbkey == NULL) {
err = WERR_NOMEM;
@@ -1205,11 +998,6 @@ static WERROR regdb_set_secdesc(const char *key,
WERROR err = WERR_NOMEM;
TDB_DATA tdbdata;
- if (!regdb_key_exists(key)) {
- err = WERR_BADFILE;
- goto done;
- }
-
tdbkey = talloc_asprintf(mem_ctx, "%s/%s", REG_SECDESC_PREFIX, key);
if (tdbkey == NULL) {
goto done;
@@ -1218,7 +1006,8 @@ static WERROR regdb_set_secdesc(const char *key,
if (secdesc == NULL) {
/* assuming a delete */
- status = dbwrap_trans_delete_bystring(regdb, tdbkey);
+ status = dbwrap_trans_delete(regdb,
+ string_term_tdb_data(tdbkey));
if (NT_STATUS_IS_OK(status)) {
err = WERR_OK;
} else {
@@ -1234,7 +1023,8 @@ static WERROR regdb_set_secdesc(const char *key,
goto done;
}
- status = dbwrap_trans_store_bystring(regdb, tdbkey, tdbdata, 0);
+ status = dbwrap_trans_store(regdb, string_term_tdb_data(tdbkey),
+ tdbdata, 0);
if (!NT_STATUS_IS_OK(status)) {
err = ntstatus_to_werror(status);
goto done;