📄 regf.c
字号:
/* Get the next security descriptor for the key */ if (!hbin_get_tdr(regf, cur_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find next security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the next security descriptor */ sk.prev_offset = cur_sk.prev_offset; hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.next_offset, &sk); hbin_free(regf, private_data->nk->sk_offset); } else { /* This key will no longer be referring to this sk */ cur_sk.ref_cnt--; update_cur_sk = true; } sk_offset = root.sk_offset; do { cur_sk_offset = sk_offset; if (!hbin_get_tdr(regf, sk_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_BADFILE; } if (memcmp(data.data, sk.sec_desc, MIN(data.length, sk.rec_size)) == 0) { private_data->nk->sk_offset = sk_offset; sk.ref_cnt++; hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, sk_offset, &sk); hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, private_data->nk); return WERR_OK; } sk_offset = sk.next_offset; } while (sk_offset != root.sk_offset); ZERO_STRUCT(new_sk); new_sk.header = "sk"; new_sk.prev_offset = cur_sk_offset; new_sk.next_offset = root.sk_offset; new_sk.ref_cnt = 1; new_sk.rec_size = data.length; new_sk.sec_desc = data.data; sk_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_sk_block, &new_sk); if (sk_offset == -1) { DEBUG(0, ("Error storing sk block\n")); return WERR_GENERAL_FAILURE; } private_data->nk->sk_offset = sk_offset; if (update_cur_sk) { hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->nk->sk_offset, &cur_sk); } /* Get the previous security descriptor for the key */ if (!hbin_get_tdr(regf, new_sk.prev_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor for previous key\n")); return WERR_BADFILE; } /* Change and store the previous security descriptor */ sk.next_offset = sk_offset; hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.prev_offset, &sk); /* Get the next security descriptor for the key (always root, as we append) */ if (!hbin_get_tdr(regf, new_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the next security descriptor (always root, as we append) */ sk.prev_offset = sk_offset; hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, root.sk_offset, &sk); /* Store the nk. */ hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->offset, private_data->nk); return WERR_OK;}static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, struct security_descriptor **sd){ const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct sk_block sk; struct regf_data *regf = private_data->hive; DATA_BLOB data; 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; } if (strcmp(sk.header, "sk") != 0) { DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); return WERR_GENERAL_FAILURE; } *sd = talloc(ctx, struct security_descriptor); W_ERROR_HAVE_NO_MEMORY(*sd); data.data = sk.sec_desc; data.length = sk.rec_size; if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_struct_blob(&data, ctx, NULL, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { DEBUG(0, ("Error parsing security descriptor\n")); return WERR_GENERAL_FAILURE; } return WERR_OK;}static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, const char *name, uint32_t key_offset, uint32_t *ret){ DATA_BLOB data; /* Create a new key if necessary */ if (list_offset == -1) { if (regf->header->version.major != 1) { DEBUG(0, ("Can't store keys in unknown registry format\n")); return WERR_NOT_SUPPORTED; } if (regf->header->version.minor < 3) { /* Store LI */ struct li_block li; ZERO_STRUCT(li); li.header = "li"; li.key_count = 1; li.nk_offset = talloc_array(regf, uint32_t, 1); W_ERROR_HAVE_NO_MEMORY(li.nk_offset); li.nk_offset[0] = key_offset; *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_li_block, &li); talloc_free(li.nk_offset); } else if (regf->header->version.minor == 3 || regf->header->version.minor == 4) { /* Store LF */ struct lf_block lf; ZERO_STRUCT(lf); lf.header = "lf"; lf.key_count = 1; lf.hr = talloc_array(regf, struct hash_record, 1); W_ERROR_HAVE_NO_MEMORY(lf.hr); lf.hr[0].nk_offset = key_offset; lf.hr[0].hash = talloc_strndup(lf.hr, name, 4); W_ERROR_HAVE_NO_MEMORY(lf.hr[0].hash); *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lf_block, &lf); talloc_free(lf.hr); } else if (regf->header->version.minor == 5) { /* Store LH */ struct lh_block lh; ZERO_STRUCT(lh); lh.header = "lh"; lh.key_count = 1; lh.hr = talloc_array(regf, struct lh_hash, 1); W_ERROR_HAVE_NO_MEMORY(lh.hr); lh.hr[0].nk_offset = key_offset; lh.hr[0].base37 = regf_create_lh_hash(name); *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lh_block, &lh); talloc_free(lh.hr); } return WERR_OK; } data = hbin_get(regf, list_offset); if (!data.data) { DEBUG(0, ("Unable to find subkey list\n")); return WERR_BADFILE; } if (!strncmp((char *)data.data, "li", 2)) { struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); struct li_block li; pull->data = data; 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(); DEBUG(0, ("LI header corrupt\n")); return WERR_BADFILE; } li.nk_offset = talloc_realloc(regf, li.nk_offset, uint32_t, li.key_count+1); W_ERROR_HAVE_NO_MEMORY(li.nk_offset); li.nk_offset[li.key_count] = key_offset; li.key_count++; *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_li_block, list_offset, &li); talloc_free(li.nk_offset); } else if (!strncmp((char *)data.data, "lf", 2)) { struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); struct lf_block lf; pull->data = data; 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, lf.key_count+1); W_ERROR_HAVE_NO_MEMORY(lf.hr); lf.hr[lf.key_count].nk_offset = key_offset; lf.hr[lf.key_count].hash = talloc_strndup(lf.hr, name, 4); W_ERROR_HAVE_NO_MEMORY(lf.hr[lf.key_count].hash); lf.key_count++; *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); talloc_free(lf.hr); } else if (!strncmp((char *)data.data, "lh", 2)) { struct tdr_pull *pull = tdr_pull_init(regf, regf->iconv_convenience); struct lh_block lh; pull->data = data; 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, lh.key_count+1); W_ERROR_HAVE_NO_MEMORY(lh.hr); lh.hr[lh.key_count].nk_offset = key_offset; lh.hr[lh.key_count].base37 = regf_create_lh_hash(name); lh.key_count++; *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lh_block, list_offset, &lh); talloc_free(lh.hr); } else if (!strncmp((char *)data.data, "ri", 2)) { /* FIXME */ DEBUG(0, ("Adding to 'ri' subkey list is not supported yet.\n")); return WERR_NOT_SUPPORTED; } else { DEBUG(0, ("Cannot add to unknown subkey list\n")); return WERR_BADFILE; } return WERR_OK;}static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, uint32_t key_offset, uint32_t *ret){ DATA_BLOB data; data = hbin_get(regf, list_offset); if (!data.data) { DEBUG(0, ("Unable to find subkey list\n")); return WERR_BADFILE; } if (strncmp((char *)data.data, "li", 2) == 0) { struct li_block li; 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")); pull->data = data; 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)); for (i = 0; i < li.key_count; i++) { if (found_offset) { li.nk_offset[i-1] = li.nk_offset[i]; } if (li.nk_offset[i] == key_offset) { found_offset = true; continue; } } if (!found_offset) { DEBUG(2, ("Subkey not found\n")); return WERR_BADFILE; } li.key_count--; /* If the there are no entries left, free the subkey list */ if (li.key_count == 0) { hbin_free(regf, list_offset); *ret = -1; } /* Store li block */ *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_li_block, list_offset, &li); } else if (strncmp((char *)data.data, "lf", 2) == 0) { struct lf_block lf; 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")); pull->data = data; 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)); for (i = 0; i < lf.key_count; i++) { if (found_offset) { lf.hr[i-1] = lf.hr[i]; continue; } if (lf.hr[i].nk_offset == key_offset) { found_offset = 1; continue; } } if (!found_offset) { DEBUG(2, ("Subkey not found\n")); return WERR_BADFILE; } lf.key_count--; /* If the there are no entries left, free the subkey list */ if (lf.key_count == 0) { hbin_free(regf, list_offset); *ret = -1; return WERR_OK; } /* Store lf block */ *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lf_block, list_offset, &lf); } else if (strncmp((char *)data.data, "lh", 2) == 0) { struct lh_block lh; 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")); pull->data = data; 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)); for (i = 0; i < lh.key_count; i++) { if (found_offset) { lh.hr[i-1] = lh.hr[i]; continue; } if (lh.hr[i].nk_offset == key_offset) { found_offset = 1; continue; } } if (!found_offset) { DEBUG(0, ("Subkey not found\n")); return WERR_BADFILE; } lh.key_count--; /* If the there are no entries left, free the subkey list */ if (lh.key_count == 0) { hbin_free(regf, list_offset); *ret = -1; return WERR_OK; } /* Store lh block */ *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lh_block, list_offset, &lh); } else if (strncmp((char *)data.data, "ri", 2) == 0) { /* FIXME */ DEBUG(0, ("Sorry, deletion from ri block is not supported yet.\n")); return WERR_NOT_SUPPORTED; } else { DEBUG (0, ("Unknown header found in subkey list.\n")); return WERR_BADFILE; } return WERR_OK;}static WERROR regf_del_value (struct hive_key *key, const char *name){ struct regf_key_data *private_data = (struct regf_key_data *)key; struct regf_data *regf = private_data->hive; struct nk_block *nk = private_data->nk; struct vk_block vk; uint32_t vk_offset; bool found_offset = false; DATA_BLOB values; uint32_t i; if (nk->values_offset == -1) { return WERR_BADFILE; } values = hbin_get(regf, nk->values_offset); for (i = 0; i < nk->num_values; i++) { if (found_offset) { ((uint32_t *)values.data)[i-1] = ((uint32_t *) values.data)[i]; } else { vk_offset = IVAL(values.data, i * 4); if (!hbin_get_tdr(regf, vk_offset, private_data, (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); return WERR_BADFILE; } if (strcmp(vk.data_name, name) == 0) { hbin_free(regf, vk_offset); found_offset = true; } } } if (!found_offset) { return WERR_BADFILE; } else { nk->num_values--; values.length = (nk->num_values)*4; } /* Store values list and nk */ if (nk->num_values == 0) { hbin_free(regf, nk->values_offset); nk->values_offset = -1; } else { nk->values_offset = hbin_store_resize(regf, nk->values_offset, values); } hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, nk); return regf_save_hbin(private_data->hive);}static WERROR regf_del_key(const struct hive_key *parent, const char *name){ const struct regf_key_data *private_data = (const struct regf_key_data *)parent; struct regf_key_data *key; struct nk_block *parent_nk; WERROR error; SMB_ASSERT(private_data); parent_nk = private_data->nk; if (parent_nk->subkeys_offset == -1) { DEBUG(4, ("Subkey list is empty, this key cannot contain subkeys.\n")); return WERR_BADFILE; } /* Find the key */ if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, (struct hive_key **)&key))) { DEBUG(2, ("Key '%s' not found\n", name)); return WERR_BADFILE; } if (key->nk->subkeys_offset != -1) { char *sk_name; struct hive_key *sk = (struct hive_key *)key; int i = key->nk->num_subkeys;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -