/* Implementation of internal registry database functions. */
#include "includes.h"
-
+#include "system/filesys.h"
#include "registry.h"
#include "reg_db.h"
#include "reg_util_internal.h"
#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
KEY_PRINTING_2K,
KEY_PRINTING_PORTS,
KEY_PRINTING,
+ KEY_PRINTING "\\Forms",
+ KEY_PRINTING "\\Printers",
+ KEY_PRINTING "\\Environments\\Windows NT x86\\Print Processors\\winprint",
KEY_SHARES,
KEY_EVENTLOG,
KEY_SMBCONF,
{ KEY_PRINTING_2K,
"DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } },
{ KEY_EVENTLOG,
- "DisplayName", REG_SZ, { "Event Log" } },
+ "DisplayName", REG_SZ, { "Event Log" } },
{ KEY_EVENTLOG,
"ErrorControl", REG_DWORD, { (char*)0x00000001 } },
{ NULL, NULL, 0, { NULL } }
(const char *) rec->key.dptr,
keyname));
- new_rec.value.dptr = rec->value.dptr;
- new_rec.value.dsize = rec->value.dsize;
- new_rec.key.dptr = (unsigned char *) keyname;
- new_rec.key.dsize = strlen(keyname);
+ new_rec.value = rec->value;
+ new_rec.key = string_term_tdb_data(keyname);
new_rec.private_data = rec->private_data;
/* Delete the original record and store the normalized key */
status = dbwrap_trans_store_int32(regdb, version_keyname, version);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("regdb_init: error storing %s = %d: %s\n",
+ DEBUG(1, ("regdb_store_regdb_version: error storing %s = %d: %s\n",
version_keyname, version, nt_errstr(status)));
return ntstatus_to_werror(status);
} else {
- DEBUG(10, ("regdb_init: stored %s = %d\n",
+ DEBUG(10, ("regdb_store_regdb_version: stored %s = %d\n",
version_keyname, version));
return WERR_OK;
}
WERROR werr;
if (regdb) {
- DEBUG(10, ("regdb_init: incrementing refcount (%d)\n",
- regdb_refcount));
+ DEBUG(10, ("regdb_init: incrementing refcount (%d->%d)\n",
+ regdb_refcount, regdb_refcount+1));
regdb_refcount++;
return WERR_OK;
}
state_path("registry.tdb"), strerror(errno) ));
return werr;
}
-
+
DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
}
regdb_refcount = 1;
+ DEBUG(10, ("regdb_init: registry db openend. refcount reset (%d)\n",
+ regdb_refcount));
expected_version = REGVER_V2;
vers_id = dbwrap_fetch_int32(regdb, vstring);
if (vers_id == -1) {
- NTSTATUS status;
-
DEBUG(10, ("regdb_init: registry version uninitialized "
"(got %d), initializing to version %d\n",
vers_id, expected_version));
- status = dbwrap_trans_store_int32(regdb, vstring, REGVER_V2);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("regdb_init: error storing %s = %d: %s\n",
- vstring, expected_version, nt_errstr(status)));
- return ntstatus_to_werror(status);
- } else {
- DEBUG(10, ("regdb_init: stored %s = %d\n",
- vstring, expected_version));
- }
-
- return WERR_OK;
+ werr = regdb_store_regdb_version(expected_version);
+ return werr;
}
if (vers_id > expected_version || vers_id == 0) {
WERROR result = WERR_OK;
if ( regdb ) {
- DEBUG(10,("regdb_open: incrementing refcount (%d)\n", regdb_refcount));
+ DEBUG(10, ("regdb_open: incrementing refcount (%d->%d)\n",
+ regdb_refcount, regdb_refcount+1));
regdb_refcount++;
return WERR_OK;
}
-
+
become_root();
regdb = db_open(NULL, state_path("registry.tdb"), 0,
REG_TDB_FLAGS, O_RDWR, 0600);
if ( !regdb ) {
result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
- DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
+ DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
state_path("registry.tdb"), strerror(errno) ));
}
unbecome_root();
regdb_refcount = 1;
- DEBUG(10,("regdb_open: refcount reset (%d)\n", regdb_refcount));
+ DEBUG(10, ("regdb_open: registry db opened. refcount reset (%d)\n",
+ regdb_refcount));
return result;
}
regdb_refcount--;
- DEBUG(10,("regdb_close: decrementing refcount (%d)\n", regdb_refcount));
+ DEBUG(10, ("regdb_close: decrementing refcount (%d->%d)\n",
+ regdb_refcount+1, regdb_refcount));
if ( regdb_refcount > 0 )
return 0;
W_ERROR_NOT_OK_GOTO_DONE(werr);
/*
- * Delete a sorted subkey cache for regdb_key_exists, will be
- * recreated automatically
+ * recreate the sorted subkey cache for regdb_key_exists()
*/
- keyname = talloc_asprintf(ctx, "%s\\%s", REG_SORTED_SUBKEYS_PREFIX,
- keyname);
- if (keyname == NULL) {
- werr = WERR_NOMEM;
- goto done;
- }
-
- werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname));
-
- /* don't treat WERR_NOT_FOUND as an error here */
- if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
- werr = WERR_OK;
- }
+ werr = ntstatus_to_werror(create_sorted_subkeys(keyname));
done:
TALLOC_FREE(ctx);
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;
&size,
&data_p);
- /* add the new value. Paranoid protective code -- make sure data_p is valid */
-
- if (size && data_p) {
- regval_ctr_addvalue(values, valuename, type,
- (uint8_t *)data_p, size);
- }
+ regval_ctr_addvalue(values, valuename, type,
+ (uint8_t *)data_p, size);
SAFE_FREE(data_p); /* 'B' option to tdb_unpack does a malloc() */
DEBUG(8,("specific: [%s], len: %d\n", valuename, size));
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);
return (regdb_get_seqnum() != regval_ctr_get_seqnum(values));
}
-/*
+/*
* Table of function pointers for default access
*/
-
+
struct registry_ops regdb_ops = {
.fetch_subkeys = regdb_fetch_keys,
.fetch_values = regdb_fetch_values,