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; }
bool eventlog_init_keys(void) { /* Find all of the eventlogs, add keys for each of them */ const char **elogs = lp_eventlog_list(); char *evtlogpath = NULL; char *evtfilepath = NULL; struct regsubkey_ctr *subkeys; REGVAL_CTR *values; uint32 uiMaxSize; uint32 uiRetention; uint32 uiCategoryCount; UNISTR2 data; TALLOC_CTX *ctx = talloc_tos(); WERROR werr; while (elogs && *elogs) { werr = regsubkey_ctr_init(ctx, &subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } regdb_fetch_keys(KEY_EVENTLOG, subkeys); regsubkey_ctr_addkey( subkeys, *elogs ); if ( !regdb_store_keys( KEY_EVENTLOG, subkeys ) ) { TALLOC_FREE(subkeys); return False; } TALLOC_FREE(subkeys); /* add in the key of form KEY_EVENTLOG/Application */ DEBUG( 5, ( "Adding key of [%s] to path of [%s]\n", *elogs, KEY_EVENTLOG ) ); evtlogpath = talloc_asprintf(ctx, "%s\\%s", KEY_EVENTLOG, *elogs); if (!evtlogpath) { return false; } /* add in the key of form KEY_EVENTLOG/Application/Application */ DEBUG( 5, ( "Adding key of [%s] to path of [%s]\n", *elogs, evtlogpath ) ); werr = regsubkey_ctr_init(ctx, &subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } regdb_fetch_keys( evtlogpath, subkeys ); regsubkey_ctr_addkey( subkeys, *elogs ); if ( !regdb_store_keys( evtlogpath, subkeys ) ) { TALLOC_FREE(subkeys); return False; } TALLOC_FREE( subkeys ); /* now add the values to the KEY_EVENTLOG/Application form key */ if (!(values = TALLOC_ZERO_P(ctx, REGVAL_CTR))) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } DEBUG( 5, ( "Storing values to eventlog path of [%s]\n", evtlogpath ) ); regdb_fetch_values( evtlogpath, values ); if (!regval_ctr_key_exists(values, "MaxSize")) { /* assume we have none, add them all */ /* hard code some initial values */ /* uiDisplayNameId = 0x00000100; */ uiMaxSize = 0x00080000; uiRetention = 0x93A80; regval_ctr_addvalue(values, "MaxSize", REG_DWORD, (char *)&uiMaxSize, sizeof(uint32)); regval_ctr_addvalue(values, "Retention", REG_DWORD, (char *)&uiRetention, sizeof(uint32)); init_unistr2(&data, *elogs, UNI_STR_TERMINATE); regval_ctr_addvalue(values, "PrimaryModule", REG_SZ, (char *)data.buffer, data.uni_str_len * sizeof(uint16)); init_unistr2(&data, *elogs, UNI_STR_TERMINATE); regval_ctr_addvalue(values, "Sources", REG_MULTI_SZ, (char *)data.buffer, data.uni_str_len * sizeof(uint16)); evtfilepath = talloc_asprintf(ctx, "%%SystemRoot%%\\system32\\config\\%s.tdb", *elogs); if (!evtfilepath) { TALLOC_FREE(values); } init_unistr2(&data, evtfilepath, UNI_STR_TERMINATE); regval_ctr_addvalue(values, "File", REG_EXPAND_SZ, (char *)data.buffer, data.uni_str_len * sizeof(uint16)); regdb_store_values(evtlogpath, values); } TALLOC_FREE(values); /* now do the values under KEY_EVENTLOG/Application/Application */ TALLOC_FREE(evtlogpath); evtlogpath = talloc_asprintf(ctx, "%s\\%s\\%s", KEY_EVENTLOG, *elogs, *elogs); if (!evtlogpath) { return false; } if (!(values = TALLOC_ZERO_P(ctx, REGVAL_CTR))) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } DEBUG( 5, ( "Storing values to eventlog path of [%s]\n", evtlogpath)); regdb_fetch_values(evtlogpath, values); if (!regval_ctr_key_exists( values, "CategoryCount")) { /* hard code some initial values */ uiCategoryCount = 0x00000007; regval_ctr_addvalue( values, "CategoryCount", REG_DWORD, ( char * ) &uiCategoryCount, sizeof( uint32 ) ); init_unistr2( &data, "%SystemRoot%\\system32\\eventlog.dll", UNI_STR_TERMINATE ); regval_ctr_addvalue( values, "CategoryMessageFile", REG_EXPAND_SZ, ( char * ) data.buffer, data.uni_str_len * sizeof( uint16 ) ); regdb_store_values( evtlogpath, values ); } TALLOC_FREE(values); elogs++; } 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; }
/** * Initialize a key in the registry: * create each component key of the specified path. */ static WERROR init_registry_key_internal(struct db_context *db, const char *add_path) { WERROR werr; TALLOC_CTX *frame = talloc_stackframe(); char *path = NULL; char *base = NULL; char *remaining = NULL; char *keyname; char *subkeyname; struct regsubkey_ctr *subkeys; const char *p, *p2; DEBUG(6, ("init_registry_key: Adding [%s]\n", add_path)); path = talloc_strdup(frame, add_path); base = talloc_strdup(frame, ""); if (!path || !base) { werr = WERR_NOMEM; goto fail; } p = path; while (next_token_talloc(frame, &p, &keyname, "\\")) { /* build up the registry path from the components */ if (*base) { base = talloc_asprintf(frame, "%s\\", base); if (!base) { werr = WERR_NOMEM; goto fail; } } base = talloc_asprintf_append(base, "%s", keyname); if (!base) { werr = WERR_NOMEM; goto fail; } /* get the immediate subkeyname (if we have one ) */ subkeyname = talloc_strdup(frame, ""); if (!subkeyname) { werr = WERR_NOMEM; goto fail; } if (*p) { remaining = talloc_strdup(frame, p); if (!remaining) { werr = WERR_NOMEM; goto fail; } p2 = remaining; if (!next_token_talloc(frame, &p2, &subkeyname, "\\")) { subkeyname = talloc_strdup(frame,p2); if (!subkeyname) { werr = WERR_NOMEM; goto fail; } } } DEBUG(10,("init_registry_key: Storing key [%s] with " "subkey [%s]\n", base, *subkeyname ? subkeyname : "NULL")); /* we don't really care if the lookup succeeds or not * since we are about to update the record. * We just want any subkeys already present */ werr = regsubkey_ctr_init(frame, &subkeys); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("talloc() failure!\n")); goto fail; } werr = regdb_fetch_keys_internal(db, base, subkeys); if (!W_ERROR_IS_OK(werr) && !W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { goto fail; } if (*subkeyname) { werr = regsubkey_ctr_addkey(subkeys, subkeyname); if (!W_ERROR_IS_OK(werr)) { goto fail; } } if (!regdb_store_keys_internal(db, base, subkeys)) { werr = WERR_CAN_NOT_COMPLETE; goto fail; } } werr = WERR_OK; fail: TALLOC_FREE(frame); return werr; }
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; }