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; }