static int dbwrap_cache_exists(struct db_context *db, TDB_DATA key) { struct db_cache_ctx *ctx = talloc_get_type_abort( db->private_data, struct db_cache_ctx); if (ctx->positive && dbwrap_exists(ctx->positive, key)) { return true; } if (ctx->negative && dbwrap_exists(ctx->negative, key)) { return false; } return dbwrap_exists(ctx->backing, key); }
/* * Deletes the key if it exists. */ bool secrets_delete(const char *key) { bool exists; if (!secrets_init()) { return false; } exists = dbwrap_exists(db_ctx, string_tdb_data(key)); if (!exists) { return true; } return secrets_delete_entry(key); }
static int dbwrap_tool_exists(struct db_context *db, const char *keyname, const char *data) { bool result; result = dbwrap_exists(db, string_term_tdb_data(keyname)); if (result) { d_fprintf(stdout, "Key %s exists\n", keyname); } else { d_fprintf(stdout, "Key %s does not exist\n", keyname); } return (result)?0:1; }
static NTSTATUS dbwrap_cache_parse_record( struct db_context *db, TDB_DATA key, void (*parser)(TDB_DATA key, TDB_DATA data, void *private_data), void *private_data) { struct db_cache_ctx *ctx = talloc_get_type_abort( db->private_data, struct db_cache_ctx); TDB_DATA value; NTSTATUS status; if (!dbwrap_cache_validate(ctx)) { return NT_STATUS_NO_MEMORY; } if (dbwrap_exists(ctx->negative, key)) { return NT_STATUS_NOT_FOUND; } status = dbwrap_parse_record(ctx->positive, key, parser, private_data); if (NT_STATUS_IS_OK(status)) { return status; } status = dbwrap_fetch(ctx->backing, talloc_tos(), key, &value); if (NT_STATUS_IS_OK(status)) { dbwrap_store(ctx->positive, key, value, 0); parser(key, value, private_data); TALLOC_FREE(value.dptr); return NT_STATUS_OK; } if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { char c = '\0'; value.dptr = (uint8_t *)&c; value.dsize = sizeof(c); dbwrap_store(ctx->negative, key, value, 0); return NT_STATUS_NOT_FOUND; } return status; }
static bool upgrade_v2_to_v3_check_subkeylist(struct db_context *db, const char *key, const char *subkey) { static uint32_t zero = 0; static TDB_DATA empty_subkey_list = { .dptr = (unsigned char*)&zero, .dsize = sizeof(uint32_t), }; bool success = false; char *path = talloc_asprintf(talloc_tos(), "%s\\%s", key, subkey); strupper_m(path); if (!dbwrap_exists(db, string_term_tdb_data(path))) { NTSTATUS status; DEBUG(10, ("regdb_upgrade_v2_to_v3: writing subkey list [%s]\n", path)); status = dbwrap_store_bystring(db, path, empty_subkey_list, TDB_INSERT); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("regdb_upgrade_v2_to_v3: writing subkey list " "[%s] failed\n", path)); goto done; } } success = true; done: talloc_free(path); return success; } static bool upgrade_v2_to_v3_check_parent(struct db_context *db, const char *key) { const char *sep = strrchr_m(key, '\\'); if (sep != NULL) { char *pkey = talloc_strndup(talloc_tos(), key, sep-key); if (!dbwrap_exists(db, string_term_tdb_data(pkey))) { DEBUG(0, ("regdb_upgrade_v2_to_v3: missing subkey list " "[%s]\nrun \"net registry check\"\n", pkey)); } talloc_free(pkey); } return true; } #define IS_EQUAL(d,s) (((d).dsize == strlen(s)+1) && \ (strcmp((char*)(d).dptr, (s)) == 0)) #define STARTS_WITH(d,s) (((d).dsize > strlen(s)) && \ (strncmp((char*)(d).dptr, (s), strlen(s)) == 0)) #define SSTR(d) (int)(d).dsize , (char*)(d).dptr static int regdb_upgrade_v2_to_v3_fn(struct db_record *rec, void *private_data) { struct db_context *db = (struct db_context *)private_data; TDB_DATA key = dbwrap_record_get_key(rec); TDB_DATA val = dbwrap_record_get_value(rec); if (tdb_data_is_empty(key)) { return 0; } if (db == NULL) { DEBUG(0, ("regdb_upgrade_v2_to_v3_fn: ERROR: " "NULL db context handed in via private_data\n")); return 1; } if (IS_EQUAL(key, REGDB_VERSION_KEYNAME) || STARTS_WITH(key, REG_VALUE_PREFIX) || STARTS_WITH(key, REG_SECDESC_PREFIX)) { DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping [%.*s]\n", SSTR(key))); return 0; } if (STARTS_WITH(key, REG_SORTED_SUBKEYS_PREFIX)) { NTSTATUS status; /* Delete the deprecated sorted subkeys cache. */ DEBUG(10, ("regdb_upgrade_v2_to_v3: deleting [%.*s]\n", SSTR(key))); status = dbwrap_record_delete(rec); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("regdb_upgrade_v2_to_v3: deleting [%.*s] " "failed!\n", SSTR(key))); return 1; } return 0; } if ( tdb_data_is_cstr(key) && hive_info((char*)key.dptr) != NULL ) { /* * Found a regular subkey list record. * Walk the list and create the list record for those * subkeys that don't already have one. */ TDB_DATA pos = val; char *subkey, *path = (char*)key.dptr; uint32_t num_items, found_items = 0; DEBUG(10, ("regdb_upgrade_v2_to_v3: scanning subkeylist of " "[%s]\n", path)); if (!tdb_data_read_uint32(&pos, &num_items)) { /* invalid or empty - skip */ return 0; } while (tdb_data_read_cstr(&pos, &subkey)) { found_items++; if (!upgrade_v2_to_v3_check_subkeylist(db, path, subkey)) { return 1; } if (!upgrade_v2_to_v3_check_parent(db, path)) { return 1; } } if (found_items != num_items) { DEBUG(0, ("regdb_upgrade_v2_to_v3: inconsistent subkey " "list [%s]\nrun \"net registry check\"\n", path)); } } else { DEBUG(10, ("regdb_upgrade_v2_to_v3: skipping invalid [%.*s]\n" "run \"net registry check\"\n", SSTR(key))); } return 0; } static WERROR regdb_upgrade_v2_to_v3(struct db_context *db) { NTSTATUS status; WERROR werr; status = dbwrap_traverse(db, regdb_upgrade_v2_to_v3_fn, db, NULL); if (!NT_STATUS_IS_OK(status)) { werr = WERR_REG_IO_FAILURE; goto done; } werr = regdb_store_regdb_version(db, REGDB_VERSION_V3); done: return werr; }