static NTSTATUS init_registry_data_action(struct db_context *db, void *private_data) { NTSTATUS status; TALLOC_CTX *frame = talloc_stackframe(); struct regval_ctr *values; int i; /* loop over all of the predefined paths and add each component */ for (i=0; builtin_registry_paths[i] != NULL; i++) { if (regdb_key_exists(db, builtin_registry_paths[i])) { continue; } status = werror_to_ntstatus(init_registry_key_internal(db, builtin_registry_paths[i])); if (!NT_STATUS_IS_OK(status)) { goto done; } } /* loop over all of the predefined values and add each component */ for (i=0; builtin_registry_values[i].path != NULL; i++) { WERROR werr; werr = regval_ctr_init(frame, &values); if (!W_ERROR_IS_OK(werr)) { status = werror_to_ntstatus(werr); goto done; } regdb_fetch_values_internal(db, builtin_registry_values[i].path, values); /* preserve existing values across restarts. Only add new ones */ if (!regval_ctr_key_exists(values, builtin_registry_values[i].valuename)) { regdb_ctr_add_value(values, &builtin_registry_values[i]); status = regdb_store_values_internal(db, builtin_registry_values[i].path, values); if (!NT_STATUS_IS_OK(status)) { goto done; } } TALLOC_FREE(values); } status = NT_STATUS_OK; done: TALLOC_FREE(frame); return status; }
WERROR init_registry_data(void) { WERROR werr; TALLOC_CTX *frame = talloc_stackframe(); struct regval_ctr *values; int i; /* * 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(regdb, builtin_registry_paths[i])) { goto do_init; } } for (i=0; builtin_registry_values[i].path != NULL; i++) { werr = regval_ctr_init(frame, &values); W_ERROR_NOT_OK_GOTO_DONE(werr); regdb_fetch_values_internal(regdb, 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 * its fsync()s. See tdb/common/transaction.c for info about nested * transaction behaviour. */ werr = regdb_trans_do(regdb, init_registry_data_action, NULL); done: TALLOC_FREE(frame); return werr; }
static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, REGF_NK_REC *parent, REGF_FILE *outfile, const char *parentpath ) { REGF_NK_REC *key, *subkey; struct security_descriptor *new_sd; struct regval_ctr *values; struct regsubkey_ctr *subkeys; int i; char *path; WERROR werr; /* swap out the SIDs in the security descriptor */ if ( !(new_sd = dup_sec_desc( outfile->mem_ctx, nk->sec_desc->sec_desc )) ) { fprintf( stderr, "Failed to copy security descriptor!\n" ); return False; } verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname); swap_sid_in_acl( new_sd, &old_sid, &new_sid ); werr = regsubkey_ctr_init(NULL, &subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("copy_registry_tree: talloc() failure!\n")); return False; } werr = regval_ctr_init(subkeys, &values); if (!W_ERROR_IS_OK(werr)) { TALLOC_FREE( subkeys ); DEBUG(0,("copy_registry_tree: talloc() failure!\n")); return False; } /* copy values into the struct regval_ctr */ for ( i=0; i<nk->num_values; i++ ) { regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type, nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) ); } /* copy subkeys into the struct regsubkey_ctr */ while ( (subkey = regfio_fetch_subkey( infile, nk )) ) { regsubkey_ctr_addkey( subkeys, subkey->keyname ); } key = regfio_write_key( outfile, nk->keyname, values, subkeys, new_sd, parent ); /* write each one of the subkeys out */ path = talloc_asprintf(subkeys, "%s%s%s", parentpath, parent ? "\\" : "",nk->keyname); if (!path) { TALLOC_FREE( subkeys ); return false; } nk->subkey_index = 0; while ((subkey = regfio_fetch_subkey(infile, nk))) { if (!copy_registry_tree( infile, subkey, key, outfile, path)) { TALLOC_FREE(subkeys); return false; } } verbose_output("[%s]\n", path); /* values is a talloc()'d child of subkeys here so just throw it all away */ TALLOC_FREE(subkeys); return True; }
static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, REGF_NK_REC *key) { REGF_NK_REC *subkey; struct registry_key_handle registry_key; struct regval_ctr *values; struct regsubkey_ctr *subkeys; int i; char *path = NULL; WERROR result = WERR_OK; /* initialize the struct registry_key_handle structure */ registry_key.ops = reghook_cache_find(topkeypath); if (!registry_key.ops) { DEBUG(0, ("reg_load_tree: Failed to assign registry_ops " "to [%s]\n", topkeypath)); return WERR_BADFILE; } registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath); if (!registry_key.name) { DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n")); return WERR_NOMEM; } /* now start parsing the values and subkeys */ result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); W_ERROR_NOT_OK_RETURN(result); result = regval_ctr_init(subkeys, &values); W_ERROR_NOT_OK_RETURN(result); /* copy values into the struct regval_ctr */ for (i=0; i<key->num_values; i++) { regval_ctr_addvalue(values, key->values[i].valuename, key->values[i].type, key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET)); } /* copy subkeys into the struct regsubkey_ctr */ key->subkey_index = 0; while ((subkey = regfio_fetch_subkey( regfile, key ))) { result = regsubkey_ctr_addkey(subkeys, subkey->keyname); if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(subkeys); return result; } } /* write this key and values out */ if (!store_reg_values(®istry_key, values) || !store_reg_keys(®istry_key, subkeys)) { DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); result = WERR_REG_IO_FAILURE; } TALLOC_FREE(subkeys); if (!W_ERROR_IS_OK(result)) { return result; } /* now continue to load each subkey registry tree */ key->subkey_index = 0; while ((subkey = regfio_fetch_subkey(regfile, key))) { path = talloc_asprintf(regfile->mem_ctx, "%s\\%s", topkeypath, subkey->keyname); if (path == NULL) { return WERR_NOMEM; } result = reg_load_tree(regfile, path, subkey); if (!W_ERROR_IS_OK(result)) { break; } } return result; }
static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, REGF_NK_REC *parent) { REGF_NK_REC *key; struct regval_ctr *values; struct regsubkey_ctr *subkeys; int i, num_subkeys; char *key_tmp = NULL; char *keyname, *parentpath; char *subkeypath = NULL; char *subkeyname; struct registry_key_handle registry_key; WERROR result = WERR_OK; struct security_descriptor *sec_desc = NULL; if (!regfile) { return WERR_GENERAL_FAILURE; } if (!keypath) { return WERR_OBJECT_PATH_INVALID; } /* split up the registry key path */ key_tmp = talloc_strdup(regfile->mem_ctx, keypath); if (!key_tmp) { return WERR_NOMEM; } if (!reg_split_key(key_tmp, &parentpath, &keyname)) { return WERR_OBJECT_PATH_INVALID; } if (!keyname) { keyname = parentpath; } /* we need a registry_key_handle object here to enumerate subkeys and values */ ZERO_STRUCT(registry_key); registry_key.name = talloc_strdup(regfile->mem_ctx, keypath); if (registry_key.name == NULL) { return WERR_NOMEM; } registry_key.ops = reghook_cache_find(registry_key.name); if (registry_key.ops == NULL) { return WERR_BADFILE; } /* lookup the values and subkeys */ result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); W_ERROR_NOT_OK_RETURN(result); result = regval_ctr_init(subkeys, &values); W_ERROR_NOT_OK_RETURN(result); fetch_reg_keys(®istry_key, subkeys); fetch_reg_values(®istry_key, values); result = regkey_get_secdesc(regfile->mem_ctx, ®istry_key, &sec_desc); if (!W_ERROR_IS_OK(result)) { goto done; } /* write out this key */ key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc, parent); if (key == NULL) { result = WERR_CAN_NOT_COMPLETE; goto done; } /* write each one of the subkeys out */ num_subkeys = regsubkey_ctr_numkeys(subkeys); for (i=0; i<num_subkeys; i++) { subkeyname = regsubkey_ctr_specific_key(subkeys, i); subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s", keypath, subkeyname); if (subkeypath == NULL) { result = WERR_NOMEM; goto done; } result = reg_write_tree(regfile, subkeypath, key); if (!W_ERROR_IS_OK(result)) goto done; } DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath)); done: TALLOC_FREE(subkeys); TALLOC_FREE(registry_key.name); return result; }