/** * 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; }
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 BOOL init_registry_data( void ) { pstring path, base, remaining; fstring keyname, subkeyname; REGSUBKEY_CTR *subkeys; REGVAL_CTR *values; int i; const char *p, *p2; UNISTR2 data; /* * 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. */ if ( tdb_transaction_start( tdb_reg ) == -1 ) { DEBUG(0, ("init_registry_data: tdb_transaction_start " "failed\n")); return False; } /* loop over all of the predefined paths and add each component */ for ( i=0; builtin_registry_paths[i] != NULL; i++ ) { DEBUG(6,("init_registry_data: Adding [%s]\n", builtin_registry_paths[i])); pstrcpy( path, builtin_registry_paths[i] ); pstrcpy( base, "" ); p = path; while ( next_token(&p, keyname, "\\", sizeof(keyname)) ) { /* build up the registry path from the components */ if ( *base ) pstrcat( base, "\\" ); pstrcat( base, keyname ); /* get the immediate subkeyname (if we have one ) */ *subkeyname = '\0'; if ( *p ) { pstrcpy( remaining, p ); p2 = remaining; if ( !next_token(&p2, subkeyname, "\\", sizeof(subkeyname)) ) fstrcpy( subkeyname, p2 ); } DEBUG(10,("init_registry_data: 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 */ if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) { DEBUG(0,("talloc() failure!\n")); goto fail; } regdb_fetch_keys( base, subkeys ); if ( *subkeyname ) regsubkey_ctr_addkey( subkeys, subkeyname ); if ( !regdb_store_keys( base, subkeys )) goto fail; TALLOC_FREE( subkeys ); } } /* loop over all of the predefined values and add each component */ for ( i=0; builtin_registry_values[i].path != NULL; i++ ) { if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) { DEBUG(0,("talloc() failure!\n")); goto fail; } regdb_fetch_values( 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 ) ) { switch( builtin_registry_values[i].type ) { case REG_DWORD: regval_ctr_addvalue( values, builtin_registry_values[i].valuename, REG_DWORD, (char*)&builtin_registry_values[i].data.dw_value, sizeof(uint32) ); break; case REG_SZ: init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE); regval_ctr_addvalue( values, builtin_registry_values[i].valuename, REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); break; default: DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n", builtin_registry_values[i].type)); } regdb_store_values( builtin_registry_values[i].path, values ); } TALLOC_FREE( values ); } if (tdb_transaction_commit( tdb_reg ) == -1) { DEBUG(0, ("init_registry_data: Could not commit " "transaction\n")); return False; } return True; fail: if (tdb_transaction_cancel( tdb_reg ) == -1) { smb_panic("init_registry_data: tdb_transaction_cancel " "failed\n"); } return False; }
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; } } /* values is a talloc()'d child of subkeys here so just throw it all away */ TALLOC_FREE( subkeys ); verbose_output("[%s]\n", path); return True; }
static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { const char *environments[] = { "Windows 4.0", "Windows NT x86", "Windows NT R4000", "Windows NT Alpha_AXP", "Windows NT PowerPC", "Windows IA64", "Windows x64", NULL }; fstring *drivers = NULL; int i, env_index, num_drivers; char *keystr, *base, *subkeypath; char *key2 = NULL; int num_subkeys = -1; int version; TALLOC_CTX *ctx = talloc_tos(); DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" )); keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS) ); /* list all possible architectures */ if ( !keystr ) { for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ ) regsubkey_ctr_addkey( subkeys, environments[num_subkeys] ); return num_subkeys; } /* we are dealing with a subkey of "Environments */ key2 = talloc_strdup(ctx, keystr); if (!key2) { return -1; } keystr = key2; if (!reg_split_path(keystr, &base, &subkeypath )) { return -1; } /* sanity check */ for ( env_index=0; environments[env_index]; env_index++ ) { if ( strequal( environments[env_index], base ) ) break; } if ( !environments[env_index] ) return -1; /* ...\Print\Environements\...\ */ if ( !subkeypath ) { regsubkey_ctr_addkey( subkeys, "Drivers" ); regsubkey_ctr_addkey( subkeys, "Print Processors" ); return 2; } /* more of the key path to process */ keystr = subkeypath; if (!reg_split_path( keystr, &base, &subkeypath )) { return -1; } /* ...\Print\Environements\...\Drivers\ */ if ( !subkeypath ) { if ( strequal(base, "Drivers") ) { switch ( env_index ) { case 0: /* Win9x */ regsubkey_ctr_addkey( subkeys, "Version-0" ); break; default: /* Windows NT based systems */ regsubkey_ctr_addkey( subkeys, "Version-2" ); regsubkey_ctr_addkey( subkeys, "Version-3" ); break; } return regsubkey_ctr_numkeys( subkeys ); } else if ( strequal(base, "Print Processors") ) { if ( env_index == 1 || env_index == 5 || env_index == 6 ) return regsubkey_ctr_numkeys( subkeys ); } else return -1; /* bad path */ } /* we finally get to enumerate the drivers */ /* only one possible subkey below PrintProc key */ if ( strequal(base, "Print Processors") ) { keystr = subkeypath; if (!reg_split_path( keystr, &base, &subkeypath )) { return -1; } /* no subkeys below this point */ if ( subkeypath ) return -1; /* only allow one keyname here -- 'winprint' */ return strequal( base, "winprint" ) ? 0 : -1; } /* only dealing with drivers from here on out */ keystr = subkeypath; if (!reg_split_path( keystr, &base, &subkeypath )) { return -1; } version = atoi(&base[strlen(base)-1]); switch (env_index) { case 0: if ( version != 0 ) return -1; break; default: if ( version != 2 && version != 3 ) return -1; break; } if ( !subkeypath ) { num_drivers = get_ntdrivers( &drivers, environments[env_index], version ); for ( i=0; i<num_drivers; i++ ) regsubkey_ctr_addkey( subkeys, drivers[i] ); return regsubkey_ctr_numkeys( subkeys ); } /* if anything else left, just say if has no subkeys */ DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s\n", key, subkeypath )); return 0; }
static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { int n_services = lp_numservices(); int snum; fstring sname; int i; int num_subkeys = 0; char *printers_key; char *printername, *printerdatakey; NT_PRINTER_INFO_LEVEL *printer = NULL; fstring *subkey_names = NULL; DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" )); printers_key = strip_printers_prefix( key ); if ( !printers_key ) { /* enumerate all printers */ for (snum=0; snum<n_services; snum++) { if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) ) continue; /* don't report the [printers] share */ if ( strequal( lp_servicename(snum), PRINTERS_NAME ) ) continue; fstrcpy( sname, lp_servicename(snum) ); regsubkey_ctr_addkey( subkeys, sname ); } num_subkeys = regsubkey_ctr_numkeys( subkeys ); goto done; } /* get information for a specific printer */ if (!reg_split_path( printers_key, &printername, &printerdatakey )) { return -1; } /* validate the printer name */ for (snum=0; snum<n_services; snum++) { if ( !lp_snum_ok(snum) || !lp_print_ok(snum) ) continue; if (strequal( lp_servicename(snum), printername ) ) break; } if ( snum>=n_services || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) { return -1; } num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names ); for ( i=0; i<num_subkeys; i++ ) regsubkey_ctr_addkey( subkeys, subkey_names[i] ); free_a_printer( &printer, 2 ); /* no other subkeys below here */ done: SAFE_FREE( subkey_names ); return num_subkeys; }
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; }