summaryrefslogtreecommitdiff
path: root/source4/lib/registry
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/registry')
-rw-r--r--source4/lib/registry/regf.c200
1 files changed, 112 insertions, 88 deletions
diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c
index 2485d2899c..8eb5760f56 100644
--- a/source4/lib/registry/regf.c
+++ b/source4/lib/registry/regf.c
@@ -133,21 +133,22 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset)
static bool hbin_get_tdr(struct regf_data *regf, uint32_t offset,
TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p)
{
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
- ZERO_STRUCT(pull);
-
- pull.data = hbin_get(regf, offset);
- if (!pull.data.data) {
+ pull->data = hbin_get(regf, offset);
+ if (!pull->data.data) {
DEBUG(1, ("Unable to get data at 0x%04x\n", offset));
+ talloc_free(pull);
return false;
}
- if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) {
+ if (NT_STATUS_IS_ERR(pull_fn(pull, ctx, p))) {
DEBUG(1, ("Error parsing record at 0x%04x using tdr\n",
offset));
+ talloc_free(pull);
return false;
}
+ talloc_free(pull);
return true;
}
@@ -594,16 +595,17 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
if (!strncmp((char *)data.data, "li", 2)) {
struct li_block li;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
DEBUG(10, ("Subkeys in LI list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, nk, &li))) {
DEBUG(0, ("Error parsing LI list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(li.header, "li", 2));
if (li.key_count != nk->num_subkeys) {
@@ -614,16 +616,17 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
} else if (!strncmp((char *)data.data, "lf", 2)) {
struct lf_block lf;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
DEBUG(10, ("Subkeys in LF list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, nk, &lf))) {
DEBUG(0, ("Error parsing LF list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lf.header, "lf", 2));
if (lf.key_count != nk->num_subkeys) {
@@ -634,16 +637,17 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
key_off = lf.hr[idx].nk_offset;
} else if (!strncmp((char *)data.data, "lh", 2)) {
struct lh_block lh;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);
DEBUG(10, ("Subkeys in LH list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, nk, &lh))) {
DEBUG(0, ("Error parsing LH list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lh.header, "lh", 2));
if (lh.key_count != nk->num_subkeys) {
@@ -653,16 +657,16 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
key_off = lh.hr[idx].nk_offset;
} else if (!strncmp((char *)data.data, "ri", 2)) {
struct ri_block ri;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
uint16_t i;
uint16_t sublist_count = 0;
DEBUG(10, ("Subkeys in RI list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_ri_block(pull, nk, &ri))) {
DEBUG(0, ("Error parsing RI list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
SMB_ASSERT(!strncmp(ri.header, "ri", 2));
@@ -674,21 +678,22 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
list_data = hbin_get(private_data->hive, ri.offset[i]);
if (!list_data.data) {
DEBUG(0, ("Error getting RI list."));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
- ZERO_STRUCT(pull);
- pull.data = list_data;
+ pull->data = list_data;
if (!strncmp((char *)list_data.data, "li", 2)) {
struct li_block li;
DEBUG(10, ("Subkeys in RI->LI list\n"));
- if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull,
+ if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull,
nk,
&li))) {
DEBUG(0, ("Error parsing LI list from RI\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
SMB_ASSERT(!strncmp(li.header, "li", 2));
@@ -706,10 +711,11 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
DEBUG(10, ("Subkeys in RI->LH list\n"));
- if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull,
+ if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull,
nk,
&lh))) {
DEBUG(0, ("Error parsing LH list from RI\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
SMB_ASSERT(!strncmp(lh.header, "lh", 2));
@@ -724,11 +730,14 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,
break;
} else {
DEBUG(0,("Unknown sublist in ri block\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
}
+ talloc_free(pull);
+
if (idx > sublist_count) {
return WERR_NO_MORE_ITEMS;
@@ -771,7 +780,7 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx,
{
DATA_BLOB subkey_data;
struct nk_block subkey;
- struct tdr_pull pull;
+ struct tdr_pull *pull;
const struct regf_key_data *private_data =
(const struct regf_key_data *)key;
@@ -781,13 +790,16 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx,
return WERR_GENERAL_FAILURE;
}
- ZERO_STRUCT(pull);
- pull.data = subkey_data;
+ pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
+
+ pull->data = subkey_data;
- if (NT_STATUS_IS_ERR(tdr_pull_nk_block(&pull, ctx, &subkey))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_nk_block(pull, ctx, &subkey))) {
DEBUG(0, ("Error parsing NK structure.\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
+ talloc_free(pull);
if (strncmp(subkey.header, "nk", 2)) {
DEBUG(0, ("Not an NK structure.\n"));
@@ -821,17 +833,18 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
if (!strncmp((char *)data.data, "li", 2)) {
struct li_block li;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
uint16_t i;
DEBUG(10, ("Subkeys in LI list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, nk, &li))) {
DEBUG(0, ("Error parsing LI list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(li.header, "li", 2));
if (li.key_count != nk->num_subkeys) {
@@ -851,17 +864,18 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
return WERR_NOT_FOUND;
} else if (!strncmp((char *)data.data, "lf", 2)) {
struct lf_block lf;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
uint16_t i;
DEBUG(10, ("Subkeys in LF list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, nk, &lf))) {
DEBUG(0, ("Error parsing LF list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lf.header, "lf", 2));
if (lf.key_count != nk->num_subkeys) {
@@ -885,18 +899,19 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
return WERR_NOT_FOUND;
} else if (!strncmp((char *)data.data, "lh", 2)) {
struct lh_block lh;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
uint16_t i;
uint32_t hash;
DEBUG(10, ("Subkeys in LH list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, nk, &lh))) {
DEBUG(0, ("Error parsing LH list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lh.header, "lh", 2));
if (lh.key_count != nk->num_subkeys) {
@@ -921,15 +936,15 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
return WERR_NOT_FOUND;
} else if (!strncmp((char *)data.data, "ri", 2)) {
struct ri_block ri;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);
uint16_t i, j;
DEBUG(10, ("Subkeys in RI list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_ri_block(pull, nk, &ri))) {
DEBUG(0, ("Error parsing RI list\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
SMB_ASSERT(!strncmp(ri.header, "ri", 2));
@@ -941,19 +956,20 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
list_data = hbin_get(private_data->hive, ri.offset[i]);
if (list_data.data == NULL) {
DEBUG(0, ("Error getting RI list."));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
- ZERO_STRUCT(pull);
- pull.data = list_data;
+ pull->data = list_data;
if (!strncmp((char *)list_data.data, "li", 2)) {
struct li_block li;
- if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull,
+ if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull,
nk,
&li))) {
DEBUG(0, ("Error parsing LI list from RI\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
SMB_ASSERT(!strncmp(li.header, "li", 2));
@@ -970,10 +986,11 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
struct lh_block lh;
uint32_t hash;
- if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull,
+ if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull,
nk,
&lh))) {
DEBUG(0, ("Error parsing LH list from RI\n"));
+ talloc_free(pull);
return WERR_GENERAL_FAILURE;
}
SMB_ASSERT(!strncmp(lh.header, "lh", 2));
@@ -994,6 +1011,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,
if (key_off)
break;
}
+ talloc_free(pull);
if (!key_off)
return WERR_NOT_FOUND;
} else {
@@ -1260,16 +1278,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
}
if (!strncmp((char *)data.data, "li", 2)) {
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
struct li_block li;
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, regf, &li))) {
DEBUG(0, ("Error parsing LI list\n"));
+ talloc_free(pull);
return WERR_BADFILE;
}
+ talloc_free(pull);
if (strncmp(li.header, "li", 2) != 0) {
abort();
@@ -1288,16 +1307,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
talloc_free(li.nk_offset);
} else if (!strncmp((char *)data.data, "lf", 2)) {
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
struct lf_block lf;
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, regf, &lf))) {
DEBUG(0, ("Error parsing LF list\n"));
+ talloc_free(pull);
return WERR_BADFILE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lf.header, "lf", 2));
lf.hr = talloc_realloc(regf, lf.hr, struct hash_record,
@@ -1313,16 +1333,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset,
talloc_free(lf.hr);
} else if (!strncmp((char *)data.data, "lh", 2)) {
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
struct lh_block lh;
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, regf, &lh))) {
DEBUG(0, ("Error parsing LH list\n"));
+ talloc_free(pull);
return WERR_BADFILE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lh.header, "lh", 2));
lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash,
@@ -1361,19 +1382,20 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset,
if (strncmp((char *)data.data, "li", 2) == 0) {
struct li_block li;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
uint16_t i;
bool found_offset = false;
DEBUG(10, ("Subkeys in LI list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_li_block(pull, regf, &li))) {
DEBUG(0, ("Error parsing LI list\n"));
+ talloc_free(pull);
return WERR_BADFILE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(li.header, "li", 2));
@@ -1404,19 +1426,20 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset,
list_offset, &li);
} else if (strncmp((char *)data.data, "lf", 2) == 0) {
struct lf_block lf;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
uint16_t i;
bool found_offset = false;
DEBUG(10, ("Subkeys in LF list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lf_block(pull, regf, &lf))) {
DEBUG(0, ("Error parsing LF list\n"));
+ talloc_free(pull);
return WERR_BADFILE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lf.header, "lf", 2));
@@ -1449,19 +1472,20 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset,
list_offset, &lf);
} else if (strncmp((char *)data.data, "lh", 2) == 0) {
struct lh_block lh;
- struct tdr_pull pull;
+ struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience);
uint16_t i;
bool found_offset = false;
DEBUG(10, ("Subkeys in LH list\n"));
- ZERO_STRUCT(pull);
- pull.data = data;
+ pull->data = data;
- if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_lh_block(pull, regf, &lh))) {
DEBUG(0, ("Error parsing LF list\n"));
+ talloc_free(pull);
return WERR_BADFILE;
}
+ talloc_free(pull);
SMB_ASSERT(!strncmp(lh.header, "lh", 2));
@@ -1837,7 +1861,6 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location,
{
struct regf_data *regf;
struct regf_hdr *regf_hdr;
- struct tdr_pull pull;
int i;
struct nk_block nk;
WERROR error;
@@ -1874,8 +1897,6 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location,
regf->header = regf_hdr;
- pull.offset = 0x1000;
-
i = 0;
/* Create all hbin blocks */
regf->hbins = talloc_array(regf, struct hbin_block *, 1);
@@ -1926,7 +1947,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
{
struct regf_data *regf;
struct regf_hdr *regf_hdr;
- struct tdr_pull pull;
+ struct tdr_pull *pull;
int i;
regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
@@ -1947,10 +1968,11 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
return WERR_GENERAL_FAILURE;
}
- ZERO_STRUCT(pull);
- pull.data.data = (uint8_t*)fd_load(regf->fd, &pull.data.length, regf);
+ pull = tdr_pull_init(regf, regf->iconv_convenience);
+
+ pull->data.data = (uint8_t*)fd_load(regf->fd, &pull->data.length, regf);
- if (pull.data.data == NULL) {
+ if (pull->data.data == NULL) {
DEBUG(0, ("Error reading data\n"));
talloc_free(regf);
return WERR_GENERAL_FAILURE;
@@ -1959,7 +1981,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
regf_hdr = talloc(regf, struct regf_hdr);
W_ERROR_HAVE_NO_MEMORY(regf_hdr);
- if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(&pull, regf_hdr, regf_hdr))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_regf_hdr(pull, regf_hdr, regf_hdr))) {
talloc_free(regf);
return WERR_GENERAL_FAILURE;
}
@@ -1974,15 +1996,15 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
}
/* Validate the header ... */
- if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) {
+ if (regf_hdr_checksum(pull->data.data) != regf_hdr->chksum) {
DEBUG(0, ("Registry file checksum error: %s: %d,%d\n",
location, regf_hdr->chksum,
- regf_hdr_checksum(pull.data.data)));
+ regf_hdr_checksum(pull->data.data)));
talloc_free(regf);
return WERR_GENERAL_FAILURE;
}
- pull.offset = 0x1000;
+ pull->offset = 0x1000;
i = 0;
/* Read in all hbin blocks */
@@ -1991,14 +2013,14 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
regf->hbins[0] = NULL;
- while (pull.offset < pull.data.length &&
- pull.offset <= regf->header->last_block) {
+ while (pull->offset < pull->data.length &&
+ pull->offset <= regf->header->last_block) {
struct hbin_block *hbin = talloc(regf->hbins,
struct hbin_block);
W_ERROR_HAVE_NO_MEMORY(hbin);
- if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(&pull, hbin, hbin))) {
+ if (NT_STATUS_IS_ERR(tdr_pull_hbin_block(pull, hbin, hbin))) {
DEBUG(0, ("[%d] Error parsing HBIN block\n", i));
talloc_free(regf);
return WERR_FOOBAR;
@@ -2018,6 +2040,8 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx,
regf->hbins[i] = NULL;
}
+ talloc_free(pull);
+
DEBUG(1, ("%d HBIN blocks read\n", i));
*key = (struct hive_key *)regf_get_key(parent_ctx, regf,