⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regf.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
		*data_type = vk->data_type;	if (vk->data_length & 0x80000000) {		vk->data_length &=~0x80000000;		data->data = (uint8_t *)&vk->data_offset;		data->length = vk->data_length;	} else {		*data = hbin_get(regf, vk->data_offset);	}	if (data->length < vk->data_length) {		DEBUG(1, ("Read data less than indicated data length!\n"));	}	talloc_free(vk);	return WERR_OK;}static WERROR regf_get_value_by_name(TALLOC_CTX *mem_ctx,				     struct hive_key *key, const char *name,				     uint32_t *type, DATA_BLOB *data){	int i;	const char *vname;	WERROR error;	/* FIXME: Do binary search? Is this list sorted at all? */	for (i = 0; W_ERROR_IS_OK(error = regf_get_value(mem_ctx, key, i,							 &vname, type, data));							 i++) {		if (!strcmp(vname, name))			return WERR_OK;	}	if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS))		return WERR_BADFILE;	return error;}static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx,				       const struct hive_key *key,				       uint32_t idx, const char **name,				       const char **classname,				       NTTIME *last_mod_time){	DATA_BLOB data;	struct regf_key_data *ret;	const struct regf_key_data *private_data = (const struct regf_key_data *)key;	struct nk_block *nk = private_data->nk;	uint32_t key_off=0;	if (idx >= nk->num_subkeys)		return WERR_NO_MORE_ITEMS;	data = hbin_get(private_data->hive, nk->subkeys_offset);	if (!data.data) {		DEBUG(0, ("Unable to find subkey list\n"));		return WERR_GENERAL_FAILURE;	}	if (!strncmp((char *)data.data, "li", 2)) {		struct li_block li;		struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);		DEBUG(10, ("Subkeys in LI list\n"));		pull->data = data;		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) {			DEBUG(0, ("Subkey counts don't match\n"));			return WERR_GENERAL_FAILURE;		}		key_off = li.nk_offset[idx];	} else if (!strncmp((char *)data.data, "lf", 2)) {		struct lf_block lf;		struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);		DEBUG(10, ("Subkeys in LF list\n"));		pull->data = data;		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) {			DEBUG(0, ("Subkey counts don't match\n"));			return WERR_GENERAL_FAILURE;		}		key_off = lf.hr[idx].nk_offset;	} else if (!strncmp((char *)data.data, "lh", 2)) {		struct lh_block lh;		struct tdr_pull *pull = tdr_pull_init(private_data->hive, private_data->hive->iconv_convenience);		DEBUG(10, ("Subkeys in LH list\n"));		pull->data = data;		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) {			DEBUG(0, ("Subkey counts don't match\n"));			return WERR_GENERAL_FAILURE;		}		key_off = lh.hr[idx].nk_offset;	} else if (!strncmp((char *)data.data, "ri", 2)) {		struct ri_block ri;		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"));		pull->data = data;		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));		for (i = 0; i < ri.key_count; i++) {			DATA_BLOB list_data;			/* Get sublist data blob */			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;			}			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,								       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));				/* Advance to next sublist if necessary */				if (idx >= sublist_count + li.key_count) {					sublist_count += li.key_count;					continue;				}				key_off = li.nk_offset[idx - sublist_count];				sublist_count += li.key_count;				break;			} else if (!strncmp((char *)list_data.data, "lh", 2)) {				struct lh_block lh;				DEBUG(10, ("Subkeys in RI->LH list\n"));				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));				/* Advance to next sublist if necessary */				if (idx >= sublist_count + lh.key_count) {					sublist_count += lh.key_count;					continue;				}				key_off = lh.hr[idx - sublist_count].nk_offset;				sublist_count += lh.key_count;				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;		}	} else {		DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n",				  nk->subkeys_offset, data.data[0], data.data[1]));		return WERR_GENERAL_FAILURE;	}	ret = regf_get_key (ctx, private_data->hive, key_off);	if (classname != NULL) {		if (ret->nk->clsname_offset != -1) {			DATA_BLOB db = hbin_get(ret->hive,						ret->nk->clsname_offset);			*classname = talloc_strndup(ctx,						    (char*)db.data,						    ret->nk->clsname_length);		} else			*classname = NULL;	}	if (last_mod_time != NULL)		*last_mod_time = ret->nk->last_change;	if (name != NULL)		*name = talloc_steal(ctx, ret->nk->key_name);	talloc_free(ret);	return WERR_OK;}static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx,					const struct hive_key *key,					uint32_t offset,					const char *name, uint32_t *ret){	DATA_BLOB subkey_data;	struct nk_block subkey;	struct tdr_pull *pull;	const struct regf_key_data *private_data =		(const struct regf_key_data *)key;	subkey_data = hbin_get(private_data->hive, offset);	if (!subkey_data.data) {		DEBUG(0, ("Unable to retrieve subkey HBIN\n"));		return WERR_GENERAL_FAILURE;	}	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))) {		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"));		return WERR_GENERAL_FAILURE;	}	if (!strcasecmp(subkey.key_name, name)) {		*ret = offset;	} else {		*ret = 0;	}	return WERR_OK;}static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx,				      const struct hive_key *key,				      const char *name,				      struct hive_key **ret){	DATA_BLOB data;	const struct regf_key_data *private_data =		(const struct regf_key_data *)key;	struct nk_block *nk = private_data->nk;	uint32_t key_off = 0;	data = hbin_get(private_data->hive, nk->subkeys_offset);	if (!data.data) {		DEBUG(0, ("Unable to find subkey list\n"));		return WERR_GENERAL_FAILURE;	}	if (!strncmp((char *)data.data, "li", 2)) {		struct li_block li;		struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);		uint16_t i;		DEBUG(10, ("Subkeys in LI list\n"));		pull->data = data;		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) {			DEBUG(0, ("Subkey counts don't match\n"));			return WERR_GENERAL_FAILURE;		}		for (i = 0; i < li.key_count; i++) {			W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key,									li.nk_offset[i],									name,									&key_off));			if (key_off != 0)				break;		}		if (key_off == 0)			return WERR_BADFILE;	} else if (!strncmp((char *)data.data, "lf", 2)) {		struct lf_block lf;		struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);		uint16_t i;		DEBUG(10, ("Subkeys in LF list\n"));		pull->data = data;		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) {			DEBUG(0, ("Subkey counts don't match\n"));			return WERR_GENERAL_FAILURE;		}		for (i = 0; i < lf.key_count; i++) {			if (strncmp(lf.hr[i].hash, name, 4)) {				continue;			}			W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk,									key,									lf.hr[i].nk_offset,									name,									&key_off));			if (key_off != 0)				break;		}		if (key_off == 0)			return WERR_BADFILE;	} else if (!strncmp((char *)data.data, "lh", 2)) {		struct lh_block lh;		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"));		pull->data = data;		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) {			DEBUG(0, ("Subkey counts don't match\n"));			return WERR_GENERAL_FAILURE;		}		hash = regf_create_lh_hash(name);		for (i = 0; i < lh.key_count; i++) {			if (lh.hr[i].base37 != hash) {				continue;			}			W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk,									key,									lh.hr[i].nk_offset,									name,									&key_off));			if (key_off != 0)				break;		}		if (key_off == 0)			return WERR_BADFILE;	} else if (!strncmp((char *)data.data, "ri", 2)) {		struct ri_block ri;		struct tdr_pull *pull = tdr_pull_init(ctx, private_data->hive->iconv_convenience);		uint16_t i, j;		DEBUG(10, ("Subkeys in RI list\n"));		pull->data = data;		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));		for (i = 0; i < ri.key_count; i++) {			DATA_BLOB list_data;			/* Get sublist data blob */			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;			}			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,								       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));				for (j = 0; j < li.key_count; j++) {					W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key,											li.nk_offset[j],											name,											&key_off));					if (key_off)						break;				}			} else if (!strncmp((char *)list_data.data, "lh", 2)) {				struct lh_block lh;				uint32_t hash;				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));				hash = regf_create_lh_hash(name);				for (j = 0; j < lh.key_count; j++) {					if (lh.hr[j].base37 != hash) {						continue;					}					W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key,											lh.hr[j].nk_offset,											name,											&key_off));					if (key_off)						break;				}			}			if (key_off)				break;		}		talloc_free(pull);		if (!key_off)			return WERR_BADFILE;	} else {		DEBUG(0, ("Unknown subkey list type.\n"));		return WERR_GENERAL_FAILURE;	}	*ret = (struct hive_key *)regf_get_key(ctx, private_data->hive,					       key_off);	return WERR_OK;}static WERROR regf_set_sec_desc(struct hive_key *key,				const struct security_descriptor *sec_desc){	const struct regf_key_data *private_data =		(const struct regf_key_data *)key;	struct sk_block cur_sk, sk, new_sk;	struct regf_data *regf = private_data->hive;	struct nk_block root;	DATA_BLOB data;	uint32_t sk_offset, cur_sk_offset;	bool update_cur_sk = false;	/* Get the root nk */ 	hbin_get_tdr(regf, regf->header->data_offset, regf,		     (tdr_pull_fn_t) tdr_pull_nk_block, &root);	/* Push the security descriptor to a blob */	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL, 							  sec_desc, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) {		DEBUG(0, ("Unable to push security descriptor\n"));		return WERR_GENERAL_FAILURE;	}	/* Get the current security descriptor for the key */	if (!hbin_get_tdr(regf, private_data->nk->sk_offset, regf,			  (tdr_pull_fn_t) tdr_pull_sk_block, &cur_sk)) {		DEBUG(0, ("Unable to find security descriptor for current key\n"));		return WERR_BADFILE;	}	/* If there's no change, change nothing. */	if (memcmp(data.data, cur_sk.sec_desc,		   MIN(data.length, cur_sk.rec_size)) == 0) {		return WERR_OK;	}	/* Delete the current sk if only this key is using it */	if (cur_sk.ref_cnt == 1) {		/* Get the previous security descriptor for the key */		if (!hbin_get_tdr(regf, cur_sk.prev_offset, regf,				  (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) {			DEBUG(0, ("Unable to find prev security descriptor for current key\n"));			return WERR_BADFILE;		}		/* Change and store the previous security descriptor */		sk.next_offset = cur_sk.next_offset;		hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block,				      cur_sk.prev_offset, &sk);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -