Author: jelmer Date: 2007-08-04 13:13:40 +0000 (Sat, 04 Aug 2007) New Revision: 24179
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24179 Log: Improvements towards write support for regf by Jelmer Vernooij and me. Modified: branches/4.0-regwrite/ branches/4.0-regwrite/source/lib/policy/parse_adm.y branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c branches/4.0-regwrite/source/lib/registry/regf.idl Changeset: Property changes on: branches/4.0-regwrite ___________________________________________________________________ Name: bzr:revision-info - timestamp: Sun 2007-01-14 14:43:18.105000019 +0100 committer: Wilco Baan Hofman <[EMAIL PROTECTED]> properties: branch-nick: 4.0-regwrite rebase-of: [EMAIL PROTECTED] + timestamp: Sun 2007-01-14 16:15:41.398000002 +0100 committer: Wilco Baan Hofman <[EMAIL PROTECTED]> properties: branch-nick: 4.0-regwrite rebase-of: [EMAIL PROTECTED] Name: bzr:file-ids - source/script/tests/test_blackbox.sh [EMAIL PROTECTED]:branches%2FSAMBA_4_0:source%2Fscript%2Ftests%2Ftest_blackbox.sh testprogs/blackbox [EMAIL PROTECTED]:branches%2FSAMBA_4_0:testprogs%2Fblackbox testprogs/blackbox/test_smbclient.sh [EMAIL PROTECTED]:branches%2FSAMBA_4_0:testprogs%2Fblackbox%2Ftest_smbclient.sh testprogs/blackbox/test_cifsdd.sh [EMAIL PROTECTED]:branches%2FSAMBA_4_0:testprogs%2Fblackbox%2Ftest_cifsdd.sh + Name: bzr:revision-id:v3-trunk0 - 11140 [EMAIL PROTECTED] 11142 [EMAIL PROTECTED] 11143 [EMAIL PROTECTED] 11144 [EMAIL PROTECTED] 11145 [EMAIL PROTECTED] 11146 [EMAIL PROTECTED] 11147 [EMAIL PROTECTED] 11148 [EMAIL PROTECTED] 11149 [EMAIL PROTECTED] 11150 [EMAIL PROTECTED] 11151 [EMAIL PROTECTED] + 11140 [EMAIL PROTECTED] 11142 [EMAIL PROTECTED] 11143 [EMAIL PROTECTED] 11144 [EMAIL PROTECTED] 11145 [EMAIL PROTECTED] 11146 [EMAIL PROTECTED] 11147 [EMAIL PROTECTED] 11148 [EMAIL PROTECTED] 11149 [EMAIL PROTECTED] 11150 [EMAIL PROTECTED] 11151 [EMAIL PROTECTED] 11152 [EMAIL PROTECTED] Modified: branches/4.0-regwrite/source/lib/policy/parse_adm.y =================================================================== --- branches/4.0-regwrite/source/lib/policy/parse_adm.y 2007-08-04 13:13:30 UTC (rev 24178) +++ branches/4.0-regwrite/source/lib/policy/parse_adm.y 2007-08-04 13:13:40 UTC (rev 24179) @@ -23,8 +23,10 @@ %{ #include "config.h" - +void error_message (const char *format, ...); +int yyparse (void); void yyerror (const char *s); +extern int yylex (void); %} Modified: branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c =================================================================== --- branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c 2007-08-04 13:13:30 UTC (rev 24178) +++ branches/4.0-regwrite/source/lib/registry/reg_backend_regf.c 2007-08-04 13:13:40 UTC (rev 24179) @@ -30,6 +30,7 @@ * - Locking */ +static WERROR regf_save_hbin(struct registry_hive *hive); /* * Read HBIN blocks into memory */ @@ -40,6 +41,11 @@ struct regf_hdr *header; }; +struct regf_key_data { + uint32_t offset; + struct nk_block *nk; +}; + static struct hbin_block *hbin_by_offset (const struct regf_data *data, uint32_t offset, uint32_t *rel_offset) { int i; @@ -48,7 +54,7 @@ if (offset >= data->hbins[i]->offset_from_first && offset < data->hbins[i]->offset_from_first+ data->hbins[i]->offset_to_next) { - if (rel_offset) + if (rel_offset != NULL) *rel_offset = offset - data->hbins[i]->offset_from_first - 0x20; return data->hbins[i]; } @@ -148,10 +154,10 @@ for (i = 0; (hbin = data->hbins[i]); i++) { int j; - uint32_t my_size; + int32_t my_size; for (j = 0; j < hbin->offset_to_next-0x20; j+= my_size) { uint32_t header = IVAL(hbin->data, j + 4); - my_size = IVAL(hbin->data, j); + my_size = IVALS(hbin->data, j); if (my_size == 0x0) { DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); @@ -162,9 +168,9 @@ DEBUG(0, ("Encountered non-aligned block!\n")); } - if (my_size & 0x80000000) { /* Used... */ - my_size = (my_size ^ 0xffffffff) + 1; - } else if (my_size == size) { /* exact match */ + if (my_size < 0) { /* Used... */ + my_size = -my_size; + } else if (-my_size == size) { /* exact match */ rel_offset = j; DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", size)); break; @@ -219,7 +225,7 @@ } /* Set size and mark as used */ - SIVAL(hbin->data, rel_offset, size | 0x80000000); + SIVAL(hbin->data, rel_offset, -size); ret.data = hbin->data + rel_offset + 0x4; /* Skip past length */ ret.length = size - 0x4; @@ -265,7 +271,7 @@ /* Free existing data */ static void hbin_free (struct regf_data *data, uint32_t offset) { - uint32_t size; + int32_t size; uint32_t rel_offset; struct hbin_block *hbin; @@ -277,28 +283,28 @@ return; /* Get original size */ - size = IVAL(hbin->data, rel_offset); + size = IVALS(hbin->data, rel_offset); - if (!(size & 0x80000000)) { + if (size > 0) { DEBUG(1, ("Trying to free already freed block at 0x%04x\n", offset)); return; } /* Mark block as free */ - SIVAL(hbin->data, rel_offset, size &~ 0x80000000); + SIVALS(hbin->data, rel_offset, -size); } -/* Store a data blob data was already stored, but hsa changed in size +/* Store a data blob data was already stored, but has changed in size * Will try to save it at the current location if possible, otherwise * does a free + store */ static uint32_t hbin_store_resize (struct regf_data *data, uint32_t orig_offset, DATA_BLOB blob) { uint32_t rel_offset; struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset); - uint32_t my_size; - uint32_t orig_size; - uint32_t needed_size; - uint32_t possible_size; + int32_t my_size; + int32_t orig_size; + int32_t needed_size; + int32_t possible_size; int i; SMB_ASSERT(orig_offset > 0); @@ -307,7 +313,7 @@ return hbin_store(data, blob); /* Get original size */ - orig_size = IVAL(hbin->data, rel_offset); + orig_size = IVALS(hbin->data, rel_offset); needed_size = blob.length + 4; /* Add uint32 containing length */ needed_size = (needed_size + 7) & ~7; /* Align */ @@ -321,14 +327,12 @@ possible_size = orig_size; /* Check if it can be combined with the next few free records */ - for (i = rel_offset; - i < hbin->offset_to_next - 0x20; - i += my_size) { + for (i = rel_offset; i < hbin->offset_to_next - 0x20; i += my_size) { uint32_t header; - if (IVAL(hbin->data, i) & 0x80000000) /* Used */ + if (IVALS(hbin->data, i) < 0) /* Used */ break; - my_size = IVAL(hbin->data, i); + my_size = IVALS(hbin->data, i); header = IVAL(hbin->data, i + 4); if (header == 0xffffffff) { possible_size = hbin->offset_to_next - 0x20 - rel_offset; @@ -340,7 +344,7 @@ } if (possible_size >= blob.length) { - SIVAL(hbin->data, rel_offset, possible_size); + SIVAL(hbin->data, rel_offset, -possible_size); memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); return orig_offset; } @@ -372,18 +376,18 @@ static WERROR regf_num_subkeys (const struct registry_key *key, uint32_t *count) { - struct nk_block *nk = key->backend_data; + struct regf_key_data *private_data = key->backend_data; - *count = nk->num_subkeys; + *count = private_data->nk->num_subkeys; return WERR_OK; } static WERROR regf_num_values (const struct registry_key *key, uint32_t *count) { - struct nk_block *nk = key->backend_data; + struct regf_key_data *private_data = key->backend_data; - *count = nk->num_values; + *count = private_data->nk->num_values; return WERR_OK; } @@ -392,9 +396,13 @@ { struct registry_key *ret; struct nk_block *nk; + struct regf_key_data *private_data; ret = talloc_zero(ctx, struct registry_key); + private_data = talloc_zero(ret, struct regf_key_data); + private_data->offset = offset; nk = talloc(ret, struct nk_block); + private_data->nk = nk; if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return NULL; @@ -413,29 +421,29 @@ DATA_BLOB data = hbin_get(regf, nk->clsname_offset); ret->class_name = talloc_strndup(ret, (char*)data.data, nk->clsname_length); } - ret->backend_data = nk; + ret->backend_data = private_data; return ret; } static WERROR regf_get_value (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_value **ret) { - struct nk_block *nk = key->backend_data; + struct regf_key_data *private_data = key->backend_data; struct vk_block *vk; struct regf_data *regf = key->hive->backend_data; uint32_t vk_offset; DATA_BLOB data; - if (idx >= nk->num_values) + if (idx >= private_data->nk->num_values) return WERR_NO_MORE_ITEMS; - data = hbin_get(regf, nk->values_offset); + data = hbin_get(regf, private_data->nk->values_offset); if (!data.data) { DEBUG(0, ("Unable to find value list\n")); return WERR_GENERAL_FAILURE; } - if (data.length < nk->num_values * 4) { + if (data.length < private_data->nk->num_values * 4) { DEBUG(1, ("Value counts mismatch\n")); } @@ -474,7 +482,8 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, const struct registry_key *key, int idx, struct registry_key **ret) { DATA_BLOB data; - struct nk_block *nk = key->backend_data; + struct regf_key_data *private_data = key->backend_data; + struct nk_block *nk = private_data->nk; uint32_t key_off=0; if (idx >= nk->num_subkeys) @@ -663,7 +672,8 @@ static WERROR regf_get_subkey_by_name (TALLOC_CTX *ctx, const struct registry_key *key, const char *name, struct registry_key **ret) { DATA_BLOB data; - struct nk_block *nk = key->backend_data; + struct regf_key_data *private_data = key->backend_data; + struct nk_block *nk = private_data->nk; uint32_t key_off = 0; data = hbin_get(key->hive->backend_data, nk->subkeys_offset); @@ -871,12 +881,12 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **sd) { - struct nk_block *nk = key->backend_data; + struct regf_key_data *private_data = key->backend_data; struct sk_block sk; struct regf_data *regf = key->hive->backend_data; DATA_BLOB data; - if (!hbin_get_tdr(regf, nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_GENERAL_FAILURE; } @@ -938,11 +948,11 @@ static WERROR regf_del_key (const struct registry_key *parent, const char *name) { - struct nk_block *nk = parent->backend_data; + struct regf_key_data *private_data = parent->backend_data; - SMB_ASSERT(nk); + SMB_ASSERT(private_data); - if (nk->subkeys_offset == -1) + if (private_data->nk->subkeys_offset == -1) return WERR_BADFILE; /* FIXME */ @@ -950,9 +960,11 @@ return WERR_NOT_SUPPORTED; } -static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key *parent, const char *name, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) +static WERROR regf_add_key (TALLOC_CTX *ctx, const struct registry_key *parent, const char *name, + uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **ret) { - struct nk_block *parent_nk = parent->backend_data, nk; + struct regf_key_data *private_data = parent->backend_data; + struct nk_block *parent_nk = private_data->nk, nk; struct regf_data *regf = parent->hive->backend_data; uint32_t offset; @@ -960,13 +972,13 @@ nk.type = REG_SUB_KEY; unix_to_nt_time(&nk.last_change, time(NULL)); nk.uk1 = 0; - nk.parent_offset = 0; /* FIXME */ + nk.parent_offset = private_data->offset; nk.num_subkeys = 0; nk.uk2 = 0; nk.subkeys_offset = -1; nk.unknown_offset = -1; nk.num_values = 0; - nk.sk_offset = 0; + nk.sk_offset = -1; memset(nk.unk3, 0, 5); nk.clsname_offset = -1; nk.clsname_length = 0; @@ -974,16 +986,17 @@ offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk); - parent_nk->subkeys_offset = lf_add_entry(regf, parent_nk->subkeys_offset, name, nk.parent_offset); - + /* FIXME: Support other formats than just 'lf' */ + parent_nk->subkeys_offset = lf_add_entry(regf, parent_nk->subkeys_offset, name, offset); parent_nk->num_subkeys++; + /* Since the subkey offset of the parent can change, store it again */ hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk); *ret = regf_get_key(ctx, regf, offset); /* FIXME: Set sec desc ! */ - return WERR_OK; + return regf_save_hbin(parent->hive); } static WERROR regf_set_value (const struct registry_key *key, const char *name, uint32_t type, const DATA_BLOB data) @@ -993,28 +1006,35 @@ return WERR_NOT_SUPPORTED; } -#if 0 /* Unused */ - -static WERROR regf_save_hbin(struct registry_hive *hive, struct hbin_block *hbin) +static WERROR regf_save_hbin(struct registry_hive *hive) { struct regf_data *regf = hive->backend_data; + int i; - /* go to right offset */ - if (lseek(regf->fd, SEEK_SET, regf->header->data_offset + hbin->offset_from_first) == -1) { + if (lseek(regf->fd, SEEK_SET, 0) == -1) { DEBUG(0, ("Error lseeking in regf file\n")); return WERR_GENERAL_FAILURE; } - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_hbin_block, hbin))) { - DEBUG(0, ("Error writing HBIN block\n")); + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_regf_hdr, regf->header))) { + DEBUG(0, ("Error writing registry file header\n")); return WERR_GENERAL_FAILURE; } + if (lseek(regf->fd, SEEK_SET, 0x1000) == -1) { + DEBUG(0, ("Error lseeking to 0x1000 in regf file\n")); + return WERR_GENERAL_FAILURE; + } + for (i = 0; regf->hbins[i]; i++) { + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, (tdr_push_fn_t)tdr_push_hbin_block, regf->hbins[i]))) { + DEBUG(0, ("Error writing HBIN block\n")); + return WERR_GENERAL_FAILURE; + } + } + return WERR_OK; } -#endif - static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key) { struct regf_data *regf; Modified: branches/4.0-regwrite/source/lib/registry/regf.idl =================================================================== --- branches/4.0-regwrite/source/lib/registry/regf.idl 2007-08-04 13:13:30 UTC (rev 24178) +++ branches/4.0-regwrite/source/lib/registry/regf.idl 2007-08-04 13:13:40 UTC (rev 24179) @@ -66,7 +66,7 @@ uint8 data[offset_to_next-0x20]; /* data is filled with: uint32 length; - Negative if in used, positive otherwise + Negative if in use, positive otherwise Always a multiple of 8 uint8_t data[length]; Free space marker if 0xffffffff
