static BOOL add_printers_by_registry( REGSUBKEY_CTR *subkeys ) { int i, num_keys, snum; char *printername; NT_PRINTER_INFO_LEVEL_2 info2; NT_PRINTER_INFO_LEVEL printer; ZERO_STRUCT( info2 ); printer.info_2 = &info2; num_keys = regsubkey_ctr_numkeys( subkeys ); become_root(); for ( i=0; i<num_keys; i++ ) { printername = regsubkey_ctr_specific_key( subkeys, i ); snum = find_service( printername ); /* just verify a valied snum for now */ if ( snum == -1 ) { fstrcpy( info2.printername, printername ); fstrcpy( info2.sharename, printername ); if ( !add_printer_hook( NULL, &printer ) ) { DEBUG(0,("add_printers_by_registry: Failed to add printer [%s]\n", printername)); } } } unbecome_root(); return True; }
static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) { int key_len = strlen(key); /* no keys below 'Print' handled here */ if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) ) return -1; regsubkey_ctr_addkey( subkeys, "Environments" ); regsubkey_ctr_addkey( subkeys, "Monitors" ); regsubkey_ctr_addkey( subkeys, "Forms" ); regsubkey_ctr_addkey( subkeys, "Printers" ); return regsubkey_ctr_numkeys( subkeys ); }
static int key_driver_fetch_keys( const char *key, 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; pstring key2; int num_subkeys = -1; int version; DEBUG(10,("key_driver_fetch_keys key=>[%s]\n", key ? key : "NULL" )); keystr = reg_remaining_path( 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 */ pstrcpy( key2, keystr ); 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 ) regsubkey_ctr_addkey( subkeys, "winprint" ); 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 BOOL key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) { char *printers_key; char *printername, *printerdatakey; NT_PRINTER_INFO_LEVEL *printer = NULL; int i, num_subkeys, num_existing_keys; char *subkeyname; fstring *existing_subkeys = NULL; printers_key = strip_printers_prefix( key ); if ( !printers_key ) { /* have to deal with some new or deleted printer */ return add_printers_by_registry( subkeys ); } if (!reg_split_path( printers_key, &printername, &printerdatakey )) { return False; } /* lookup the printer */ if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername)) ) { DEBUG(0,("key_printers_store_keys: Tried to store subkey for bad printername %s\n", printername)); return False; } /* get the top level printer keys */ num_existing_keys = get_printer_subkeys( printer->info_2->data, "", &existing_subkeys ); for ( i=0; i<num_existing_keys; i++ ) { /* remove the key if it has been deleted */ if ( !regsubkey_ctr_key_exists( subkeys, existing_subkeys[i] ) ) { DEBUG(5,("key_printers_store_keys: deleting key %s\n", existing_subkeys[i])); delete_printer_key( printer->info_2->data, existing_subkeys[i] ); } } num_subkeys = regsubkey_ctr_numkeys( subkeys ); for ( i=0; i<num_subkeys; i++ ) { subkeyname = regsubkey_ctr_specific_key(subkeys, i); /* add any missing printer keys */ if ( lookup_printerkey(printer->info_2->data, subkeyname) == -1 ) { DEBUG(5,("key_printers_store_keys: adding key %s\n", existing_subkeys[i])); if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) { SAFE_FREE( existing_subkeys ); return False; } } } /* write back to disk */ mod_a_printer( printer, 2 ); /* cleanup */ if ( printer ) free_a_printer( &printer, 2 ); SAFE_FREE( existing_subkeys ); return True; }
static int key_printers_fetch_keys( const char *key, 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; }
BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr ) { int num_subkeys, i; pstring path; REGSUBKEY_CTR *subkeys, *old_subkeys; char *oldkeyname; /* fetch a list of the old subkeys so we can determine if any were deleted */ if ( !(old_subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); return False; } regdb_fetch_keys( key, old_subkeys ); /* store the subkey list for the parent */ if ( !regdb_store_keys_internal( key, ctr ) ) { DEBUG(0,("regdb_store_keys: Failed to store new subkey list for parent [%s}\n", key )); return False; } /* now delete removed keys */ num_subkeys = regsubkey_ctr_numkeys( old_subkeys ); for ( i=0; i<num_subkeys; i++ ) { oldkeyname = regsubkey_ctr_specific_key( old_subkeys, i ); if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) { pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname ); normalize_reg_path( path ); tdb_delete_bystring( tdb_reg, path ); } } TALLOC_FREE( old_subkeys ); /* now create records for any subkeys that don't already exist */ num_subkeys = regsubkey_ctr_numkeys( ctr ); for ( i=0; i<num_subkeys; i++ ) { pstr_sprintf( path, "%s%c%s", key, '/', regsubkey_ctr_specific_key( ctr, i ) ); if ( !(subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); return False; } if ( regdb_fetch_keys( path, subkeys ) == -1 ) { /* create a record with 0 subkeys */ if ( !regdb_store_keys_internal( path, subkeys ) ) { DEBUG(0,("regdb_store_keys: Failed to store new record for key [%s}\n", path )); TALLOC_FREE( subkeys ); return False; } } TALLOC_FREE( subkeys ); } return True; }
static BOOL regdb_store_keys_internal( const char *key, REGSUBKEY_CTR *ctr ) { TDB_DATA kbuf, dbuf; char *buffer; int i = 0; uint32 len, buflen; BOOL ret = True; uint32 num_subkeys = regsubkey_ctr_numkeys( ctr ); pstring keyname; if ( !key ) return False; pstrcpy( keyname, key ); normalize_reg_path( keyname ); /* allocate some initial memory */ if (!(buffer = (char *)SMB_MALLOC(sizeof(pstring)))) { return False; } buflen = sizeof(pstring); len = 0; /* store the number of subkeys */ len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys ); /* pack all the strings */ for (i=0; i<num_subkeys; i++) { len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) ); if ( len > buflen ) { /* allocate some extra space */ if ((buffer = (char *)SMB_REALLOC( buffer, len*2 )) == NULL) { DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2)); ret = False; goto done; } buflen = len*2; len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) ); } } /* finally write out the data */ kbuf.dptr = keyname; kbuf.dsize = strlen(keyname)+1; dbuf.dptr = buffer; dbuf.dsize = len; if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) { ret = False; goto done; } done: SAFE_FREE( buffer ); return ret; }
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; }