1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-03 04:23:50 +03:00

r10025: Add some utility functions for storing/loading tdr encoded data

This commit is contained in:
Jelmer Vernooij
2005-09-04 13:13:47 +00:00
committed by Gerald (Jerry) Carter
parent 6835e42790
commit bcd433bfc1
2 changed files with 82 additions and 92 deletions

View File

@@ -31,6 +31,7 @@
struct regf_data { struct regf_data {
DATA_BLOB data; DATA_BLOB data;
struct hbin_block **hbins; struct hbin_block **hbins;
struct regf_hdr *header;
}; };
static struct hbin_block *hbin_by_offset (const struct regf_data *data, uint32_t offset, uint32_t *rel_offset) static struct hbin_block *hbin_by_offset (const struct regf_data *data, uint32_t offset, uint32_t *rel_offset)
@@ -67,7 +68,7 @@ static uint32_t regf_hdr_checksum(const uint8_t *buffer)
return checksum; return checksum;
} }
static DATA_BLOB hbin_get_data(const struct regf_data *data, uint32_t offset) static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset)
{ {
DATA_BLOB ret; DATA_BLOB ret;
struct hbin_block *hbin; struct hbin_block *hbin;
@@ -94,6 +95,31 @@ static DATA_BLOB hbin_get_data(const struct regf_data *data, uint32_t offset)
return ret; return ret;
} }
static BOOL hbin_get_tdr (struct regf_data *regf, uint32_t offset, tdr_pull_fn_t pull_fn, void *p)
{
DATA_BLOB data;
struct tdr_pull *pull;
data = hbin_get(regf, offset);
if (!data.data) {
DEBUG(1, ("Unable to get data at 0x%04x\n", offset));
return False;
}
pull = talloc_zero(regf, struct tdr_pull);
pull->data = data;
if (NT_STATUS_IS_ERR(pull_fn(pull, p))) {
DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset));
talloc_free(pull);
return False;
}
/* FIXME: Free pull ! */
return True;
}
/* Allocate some new data */ /* Allocate some new data */
static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *offset) static DATA_BLOB hbin_alloc (struct regf_data *data, uint32_t size, uint32_t *offset)
{ {
@@ -197,6 +223,23 @@ static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob)
return ret; return ret;
} }
static uint32_t hbin_store_tdr (struct regf_data *data, tdr_push_fn_t push_fn, void *p)
{
struct tdr_push *push = talloc_zero(data, struct tdr_push);
uint32_t ret;
if (NT_STATUS_IS_ERR(push_fn(push, p))) {
DEBUG(0, ("Error during push\n"));
return -1;
}
ret = hbin_store(data, push->data);
talloc_free(push);
return ret;
}
/* Free existing data */ /* Free existing data */
static void hbin_free (struct regf_data *data, uint32_t offset) static void hbin_free (struct regf_data *data, uint32_t offset)
@@ -278,6 +321,23 @@ static uint32_t hbin_store_resize (struct regf_data *data, uint32_t orig_offset,
return hbin_store(data, blob); return hbin_store(data, blob);
} }
static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn, uint32_t orig_offset, void *p)
{
struct tdr_push *push = talloc_zero(regf, struct tdr_push);
uint32_t ret;
if (NT_STATUS_IS_ERR(push_fn(push, p))) {
DEBUG(0, ("Error during push\n"));
return -1;
}
ret = hbin_store_resize(regf, orig_offset, push->data);
talloc_free(push);
return ret;
}
static WERROR regf_num_subkeys (struct registry_key *key, uint32_t *count) static WERROR regf_num_subkeys (struct registry_key *key, uint32_t *count)
{ {
struct nk_block *nk = key->backend_data; struct nk_block *nk = key->backend_data;
@@ -298,24 +358,13 @@ static WERROR regf_num_values (struct registry_key *key, uint32_t *count)
static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *regf, uint32_t offset) static struct registry_key *regf_get_key (TALLOC_CTX *ctx, struct regf_data *regf, uint32_t offset)
{ {
DATA_BLOB data = hbin_get_data(regf, offset);
struct tdr_pull *pull;
struct registry_key *ret; struct registry_key *ret;
struct nk_block *nk; struct nk_block *nk;
if (data.data == NULL) {
DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));
return NULL;
}
ret = talloc_zero(ctx, struct registry_key); ret = talloc_zero(ctx, struct registry_key);
pull = talloc_zero(ret, struct tdr_pull);
pull->data = data;
nk = talloc(ret, struct nk_block); nk = talloc(ret, struct nk_block);
if (!hbin_get_tdr(regf, offset, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) {
if (NT_STATUS_IS_ERR(tdr_pull_nk_block(pull, nk))) { DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));
DEBUG(1, ("Error parsing 'nk' record\n"));
talloc_free(ret);
return NULL; return NULL;
} }
@@ -337,14 +386,14 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx
{ {
struct nk_block *nk = key->backend_data; struct nk_block *nk = key->backend_data;
struct vk_block *vk; struct vk_block *vk;
struct tdr_pull *pull; struct regf_data *regf = key->hive->backend_data;
uint32_t vk_offset; uint32_t vk_offset;
DATA_BLOB data; DATA_BLOB data;
if (idx >= nk->num_values) if (idx >= nk->num_values)
return WERR_NO_MORE_ITEMS; return WERR_NO_MORE_ITEMS;
data = hbin_get_data(key->hive->backend_data, nk->values_offset); data = hbin_get(regf, nk->values_offset);
if (!data.data) { if (!data.data) {
DEBUG(0, ("Unable to find value list\n")); DEBUG(0, ("Unable to find value list\n"));
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
@@ -356,12 +405,6 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx
vk_offset = IVAL(data.data, idx * 4); vk_offset = IVAL(data.data, idx * 4);
data = hbin_get_data(key->hive->backend_data, vk_offset);
if (!data.data) {
DEBUG(0, ("Unable to find value\n"));
return WERR_GENERAL_FAILURE;
}
*ret = talloc_zero(ctx, struct registry_value); *ret = talloc_zero(ctx, struct registry_value);
if (!(*ret)) if (!(*ret))
return WERR_NOMEM; return WERR_NOMEM;
@@ -370,11 +413,8 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx
if (!vk) if (!vk)
return WERR_NOMEM; return WERR_NOMEM;
pull = talloc_zero(*ret, struct tdr_pull); if (!hbin_get_tdr(regf, vk_offset, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) {
pull->data = data; DEBUG(0, ("Unable to get VK block at %d\n", vk_offset));
if (NT_STATUS_IS_ERR(tdr_pull_vk_block(pull, vk))) {
DEBUG(0, ("Error parsing vk block\n"));
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
} }
@@ -385,7 +425,7 @@ static WERROR regf_get_value (TALLOC_CTX *ctx, struct registry_key *key, int idx
(*ret)->data.data = (uint8_t *)&vk->data_offset; (*ret)->data.data = (uint8_t *)&vk->data_offset;
(*ret)->data.length = vk->data_length; (*ret)->data.length = vk->data_length;
} else { } else {
(*ret)->data = hbin_get_data(key->hive->backend_data, vk->data_offset); (*ret)->data = hbin_get(regf, vk->data_offset);
} }
if ((*ret)->data.length < vk->data_length) { if ((*ret)->data.length < vk->data_length) {
@@ -404,7 +444,7 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id
if (idx >= nk->num_subkeys) if (idx >= nk->num_subkeys)
return WERR_NO_MORE_ITEMS; return WERR_NO_MORE_ITEMS;
data = hbin_get_data(key->hive->backend_data, nk->subkeys_offset); data = hbin_get(key->hive->backend_data, nk->subkeys_offset);
if (!data.data) { if (!data.data) {
DEBUG(0, ("Unable to find subkey list\n")); DEBUG(0, ("Unable to find subkey list\n"));
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
@@ -452,27 +492,15 @@ static WERROR regf_get_subkey (TALLOC_CTX *ctx, struct registry_key *key, int id
static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **sd) static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struct security_descriptor **sd)
{ {
struct nk_block *nk = key->backend_data; struct nk_block *nk = key->backend_data;
struct tdr_pull *tdr;
struct sk_block sk; struct sk_block sk;
struct regf_data *regf = key->hive->backend_data;
DATA_BLOB data; DATA_BLOB data;
data = hbin_get_data(key->hive->backend_data, nk->sk_offset); if (!hbin_get_tdr(regf, nk->sk_offset, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) {
if (!data.data) {
DEBUG(0, ("Unable to find security descriptor\n")); DEBUG(0, ("Unable to find security descriptor\n"));
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
} }
tdr = talloc_zero(ctx, struct tdr_pull);
if (!tdr)
return WERR_NOMEM;
tdr->data = data;
if (NT_STATUS_IS_ERR(tdr_pull_sk_block(tdr, &sk))) {
DEBUG(0, ("Error parsing SK block\n"));
return WERR_GENERAL_FAILURE;
}
if (strcmp(sk.header, "sk") != 0) { if (strcmp(sk.header, "sk") != 0) {
DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header));
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
@@ -489,8 +517,6 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, struct registry_key *key, struc
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
} }
talloc_free(tdr);
return WERR_OK; return WERR_OK;
} }
@@ -498,8 +524,6 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons
{ {
uint32_t ret; uint32_t ret;
struct lf_block lf; struct lf_block lf;
struct tdr_pull *pull = NULL;
struct tdr_push *push;
/* Add to subkeys list */ /* Add to subkeys list */
if (list_offset == -1) { /* Need to create subkeys list */ if (list_offset == -1) { /* Need to create subkeys list */
@@ -507,38 +531,17 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons
lf.key_count = 0; lf.key_count = 0;
lf.hr = NULL; lf.hr = NULL;
} else { } else {
DATA_BLOB data; if (!hbin_get_tdr(regf, list_offset, (tdr_pull_fn_t)tdr_pull_lf_block, &lf)) {
pull = talloc(regf, struct tdr_pull);
data = hbin_get_data(regf, list_offset);
if (!data.data) {
DEBUG(0, ("Can't get subkeys list\n")); DEBUG(0, ("Can't get subkeys list\n"));
talloc_free(pull);
return -1;
}
if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, &lf))) {
DEBUG(0, ("Unable to parse lf list\n"));
talloc_free(pull);
return -1; return -1;
} }
} }
lf.hr = talloc_realloc(pull, lf.hr, struct hash_record, lf.key_count+1); lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1);
lf.hr[lf.key_count].nk_off = key_offset; lf.hr[lf.key_count].nk_off = key_offset;
lf.hr[lf.key_count].hash = name; lf.hr[lf.key_count].hash = name;
push = talloc_zero(regf, struct tdr_push); ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf);
if (NT_STATUS_IS_ERR(tdr_push_lf_block(push, &lf))) {
DEBUG(0, ("Error storing lf block\n"));
return -1;
}
ret = hbin_store_resize (regf, list_offset, push->data);
talloc_free(push);
talloc_free(pull);
return ret; return ret;
} }
@@ -546,8 +549,6 @@ static uint32_t lf_add_entry (struct regf_data *regf, uint32_t list_offset, cons
static WERROR regf_add_key (TALLOC_CTX *ctx, 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, 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 nk_block *parent_nk = parent->backend_data, nk;
DATA_BLOB data;
struct tdr_push *push;
uint32_t offset; uint32_t offset;
nk.header = "nk"; nk.header = "nk";
@@ -566,29 +567,13 @@ static WERROR regf_add_key (TALLOC_CTX *ctx, struct registry_key *parent, const
nk.clsname_length = 0; nk.clsname_length = 0;
nk.key_name = name; nk.key_name = name;
push = talloc_zero(ctx, struct tdr_push); offset = hbin_store_tdr(parent->hive->backend_data, (tdr_push_fn_t) tdr_push_nk_block, &nk);
if (NT_STATUS_IS_ERR(tdr_push_nk_block(push, &nk))) {
DEBUG(0, ("Error storing 'nk' block\n"));
return WERR_GENERAL_FAILURE;
}
offset = hbin_store(parent->hive->backend_data, push->data);
parent_nk->subkeys_offset = lf_add_entry(parent->hive->backend_data, parent_nk->subkeys_offset, name, nk.parent_offset); parent_nk->subkeys_offset = lf_add_entry(parent->hive->backend_data, parent_nk->subkeys_offset, name, nk.parent_offset);
parent_nk->num_subkeys++; parent_nk->num_subkeys++;
ZERO_STRUCTP(push); hbin_store_tdr_resize(parent->hive->backend_data, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk);
if (NT_STATUS_IS_ERR(tdr_push_nk_block(push, parent_nk))) {
DEBUG(0, ("Error storing parent 'nk' block\n"));
return WERR_GENERAL_FAILURE;
}
data = hbin_get_data(parent->hive->backend_data, nk.parent_offset);
memcpy(data.data, push->data.data, push->data.length);
talloc_free(push);
/* FIXME: Set sec desc ! */ /* FIXME: Set sec desc ! */
@@ -628,6 +613,8 @@ static WERROR nt_open_hive (struct registry_hive *h, struct registry_key **key)
return WERR_GENERAL_FAILURE; return WERR_GENERAL_FAILURE;
} }
regf->header = regf_hdr;
if (strcmp(regf_hdr->REGF_ID, "regf") != 0) { if (strcmp(regf_hdr->REGF_ID, "regf") != 0) {
DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n", DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n",
regf_hdr->REGF_ID, h->location)); regf_hdr->REGF_ID, h->location));

View File

@@ -52,3 +52,6 @@ struct tdr_print {
(s) = talloc_array_size(tdr, sizeof(*(s)), n); \ (s) = talloc_array_size(tdr, sizeof(*(s)), n); \
if ((n) && !(s)) return NT_STATUS_NO_MEMORY; \ if ((n) && !(s)) return NT_STATUS_NO_MEMORY; \
} while (0) } while (0)
typedef NTSTATUS (*tdr_push_fn_t) (struct tdr_push *, void *);
typedef NTSTATUS (*tdr_pull_fn_t) (struct tdr_pull *, void *);