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