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

📄 regf.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
		while (i--) {			/* Get subkey information. */			error = regf_get_subkey_by_index(parent_nk, sk, 0,							 (const char **)&sk_name,							 NULL, NULL);			if (!W_ERROR_IS_OK(error)) {				DEBUG(0, ("Can't retrieve subkey by index.\n"));				return error;			}			/* Delete subkey. */			error = regf_del_key(sk, sk_name);			if (!W_ERROR_IS_OK(error)) {				DEBUG(0, ("Can't delete key '%s'.\n", sk_name));				return error;			}			talloc_free(sk_name);		}	}	if (key->nk->values_offset != -1) {		char *val_name;		struct hive_key *sk = (struct hive_key *)key;		DATA_BLOB data;		int i = key->nk->num_values;		while (i--) {			/* Get value information. */			error = regf_get_value(parent_nk, sk, 0,					       (const char **)&val_name,					       NULL, &data);			if (!W_ERROR_IS_OK(error)) {				DEBUG(0, ("Can't retrieve value by index.\n"));				return error;			}			/* Delete value. */			error = regf_del_value(sk, val_name);			if (!W_ERROR_IS_OK(error)) {				DEBUG(0, ("Can't delete value '%s'.\n", val_name));				return error;			}			talloc_free(val_name);		}	}	/* Delete it from the subkey list. */	error = regf_sl_del_entry(private_data->hive, parent_nk->subkeys_offset,				  key->offset, &parent_nk->subkeys_offset);	if (!W_ERROR_IS_OK(error)) {		DEBUG(0, ("Can't store new subkey list for parent key. Won't delete.\n"));		return error;	}	/* Re-store parent key */	parent_nk->num_subkeys--;	hbin_store_tdr_resize(private_data->hive,			      (tdr_push_fn_t) tdr_push_nk_block,			      private_data->offset, parent_nk);	if (key->nk->clsname_offset != -1) {		hbin_free(private_data->hive, key->nk->clsname_offset);	}	hbin_free(private_data->hive, key->offset);	return regf_save_hbin(private_data->hive);}static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent,			   const char *name, const char *classname,			   struct security_descriptor *sec_desc,			   struct hive_key **ret){	const struct regf_key_data *private_data =		(const struct regf_key_data *)parent;	struct nk_block *parent_nk = private_data->nk, nk;	struct nk_block *root;	struct regf_data *regf = private_data->hive;	uint32_t offset;	WERROR error;	nk.header = "nk";	nk.type = REG_SUB_KEY;	unix_to_nt_time(&nk.last_change, time(NULL));	nk.uk1 = 0;	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.values_offset = -1;	memset(nk.unk3, 0, 5);	nk.clsname_offset = -1; /* FIXME: fill in */	nk.clsname_length = 0;	nk.key_name = name;	/* Get the security descriptor of the root key */ 	root = talloc_zero(ctx, struct nk_block);	W_ERROR_HAVE_NO_MEMORY(root);	if (!hbin_get_tdr(regf, regf->header->data_offset, root,			  (tdr_pull_fn_t)tdr_pull_nk_block, root)) {		DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset));		return WERR_GENERAL_FAILURE;	}	nk.sk_offset = root->sk_offset;	talloc_free(root);	/* Store the new nk key */	offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk);	error = regf_sl_add_entry(regf, parent_nk->subkeys_offset, name, offset,				  &parent_nk->subkeys_offset);	if (!W_ERROR_IS_OK(error)) {		hbin_free(regf, offset);		return error;	}	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 = (struct hive_key *)regf_get_key(ctx, regf, offset);	return regf_save_hbin(private_data->hive);}static WERROR regf_set_value(struct hive_key *key, const char *name,			     uint32_t type, const DATA_BLOB data){	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 i;	uint32_t tmp_vk_offset, vk_offset, old_vk_offset = -1;	DATA_BLOB values;	ZERO_STRUCT(vk);	/* find the value offset, if it exists */	if (nk->values_offset != -1) {		values = hbin_get(regf, nk->values_offset);		for (i = 0; i < nk->num_values; i++) {			tmp_vk_offset = IVAL(values.data, i * 4);			if (!hbin_get_tdr(regf, tmp_vk_offset, private_data,					  (tdr_pull_fn_t)tdr_pull_vk_block,					  &vk)) {				DEBUG(0, ("Unable to get VK block at %d\n",					tmp_vk_offset));				return WERR_GENERAL_FAILURE;			}			if (strcmp(vk.data_name, name) == 0) {				old_vk_offset = tmp_vk_offset;				break;			}		}		/* Free data, if any */		if (!(vk.data_length & 0x80000000)) {			hbin_free(regf, vk.data_offset);		}	}	if (old_vk_offset == -1) {		vk.header = "vk";		vk.name_length = strlen(name);		if (name != NULL && name[0] != 0) {			vk.flag = 1;			vk.data_name = name;		} else {			vk.data_name = NULL;			vk.flag = 0;		}	}	/* Set the type and data */	vk.data_length = data.length;	vk.data_type = type;	if (type == REG_DWORD) {		vk.data_length |= 0x80000000;		vk.data_offset = *(uint32_t *)data.data;	} else {		/* Store data somewhere */		vk.data_offset = hbin_store(regf, data);	}	if (old_vk_offset == -1) {		/* Store new vk */		vk_offset = hbin_store_tdr(regf,					   (tdr_push_fn_t) tdr_push_vk_block,					   &vk);	} else {		/* Store vk at offset */		vk_offset = hbin_store_tdr_resize(regf,						  (tdr_push_fn_t) tdr_push_vk_block,						  old_vk_offset ,&vk);	}	/* Re-allocate the value list */	if (nk->values_offset == -1) {		nk->values_offset = hbin_store_tdr(regf,						   (tdr_push_fn_t) tdr_push_uint32,						   &vk_offset);		nk->num_values = 1;	} else {		/* Change if we're changing, otherwise we're adding the value */		if (old_vk_offset != -1) {			/* Find and overwrite the offset. */			for (i = 0; i < nk->num_values; i++) {				if (IVAL(values.data, i * 4) == old_vk_offset) {					SIVAL(values.data, i * 4, vk_offset);					break;				}			}		} else {			/* Create a new value list */			DATA_BLOB value_list;			value_list.length = (nk->num_values+1)*4;			value_list.data = (uint8_t *)talloc_array(private_data,								  uint32_t,								  nk->num_values+1);			W_ERROR_HAVE_NO_MEMORY(value_list.data);			memcpy(value_list.data, values.data, nk->num_values * 4);			SIVAL(value_list.data, nk->num_values * 4, vk_offset);			nk->num_values++;			nk->values_offset = hbin_store_resize(regf,							      nk->values_offset,							      value_list);		}	}	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_save_hbin(struct regf_data *regf){	struct tdr_push *push = tdr_push_init(regf, regf->iconv_convenience);	int i;	W_ERROR_HAVE_NO_MEMORY(push);	if (lseek(regf->fd, 0, SEEK_SET) == -1) {		DEBUG(0, ("Error lseeking in regf file\n"));		return WERR_GENERAL_FAILURE;	}	/* Recompute checksum */	if (NT_STATUS_IS_ERR(tdr_push_regf_hdr(push, regf->header))) {		DEBUG(0, ("Failed to push regf header\n"));		return WERR_GENERAL_FAILURE;	}	regf->header->chksum = regf_hdr_checksum(push->data.data);	talloc_free(push);	if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, regf->iconv_convenience,					    (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, 0x1000, SEEK_SET) == -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, regf->iconv_convenience,						    (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;}WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, 			    struct smb_iconv_convenience *iconv_convenience,			    const char *location,			    int minor_version, struct hive_key **key){	struct regf_data *regf;	struct regf_hdr *regf_hdr;	struct nk_block nk;	struct sk_block sk;	WERROR error;	DATA_BLOB data;	struct security_descriptor *sd;	uint32_t sk_offset;	regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);	regf->iconv_convenience = iconv_convenience;	W_ERROR_HAVE_NO_MEMORY(regf);	DEBUG(5, ("Attempting to create registry file\n"));	/* Get the header */	regf->fd = creat(location, 0644);	if (regf->fd == -1) {		DEBUG(0,("Could not create file: %s, %s\n", location,				 strerror(errno)));		talloc_free(regf);		return WERR_GENERAL_FAILURE;	}	regf_hdr = talloc_zero(regf, struct regf_hdr);	W_ERROR_HAVE_NO_MEMORY(regf_hdr);	regf_hdr->REGF_ID = "regf";	unix_to_nt_time(&regf_hdr->modtime, time(NULL));	regf_hdr->version.major = 1;	regf_hdr->version.minor = minor_version;	regf_hdr->last_block = 0x1000; /* Block size */	regf_hdr->description = talloc_strdup(regf_hdr,					      "Registry created by Samba 4");	W_ERROR_HAVE_NO_MEMORY(regf_hdr->description);	regf_hdr->chksum = 0;	regf->header = regf_hdr;	/* Create all hbin blocks */	regf->hbins = talloc_array(regf, struct hbin_block *, 1);	W_ERROR_HAVE_NO_MEMORY(regf->hbins);	regf->hbins[0] = NULL;	nk.header = "nk";	nk.type = REG_SUB_KEY;	unix_to_nt_time(&nk.last_change, time(NULL));	nk.uk1 = 0;	nk.parent_offset = -1;	nk.num_subkeys = 0;	nk.uk2 = 0;	nk.subkeys_offset = -1;	nk.unknown_offset = -1;	nk.num_values = 0;	nk.values_offset = -1;	memset(nk.unk3, 0, 5);	nk.clsname_offset = -1;	nk.clsname_length = 0;	nk.sk_offset = 0x80;	nk.key_name = "SambaRootKey";	/*	 * It should be noted that changing the key_name to something shorter	 * creates a shorter nk block, which makes the position of the sk block	 * change. All Windows registries I've seen have the sk at 0x80. 	 * I therefore recommend that our regf files share that offset -- Wilco	 */	/* Create a security descriptor. */	sd = security_descriptor_dacl_create(regf,					 0,					 NULL, NULL,					 SID_NT_AUTHENTICATED_USERS,					 SEC_ACE_TYPE_ACCESS_ALLOWED,					 SEC_GENERIC_ALL,					 SEC_ACE_FLAG_OBJECT_INHERIT,					 NULL);		/* Push the security descriptor to a blob */	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL, 				     sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) {		DEBUG(0, ("Unable to push security descriptor\n"));		return WERR_GENERAL_FAILURE;	}	ZERO_STRUCT(sk);	sk.header = "sk";	sk.prev_offset = 0x80;	sk.next_offset = 0x80;	sk.ref_cnt = 1;	sk.rec_size = data.length;	sk.sec_desc = data.data;	/* Store the new nk key */	regf->header->data_offset = hbin_store_tdr(regf,						   (tdr_push_fn_t)tdr_push_nk_block,						   &nk);	/* Store the sk block */	sk_offset = hbin_store_tdr(regf,				   (tdr_push_fn_t) tdr_push_sk_block,				   &sk);	if (sk_offset != 0x80) {		DEBUG(0, ("Error storing sk block, should be at 0x80, stored at 0x%x\n", nk.sk_offset));		return WERR_GENERAL_FAILURE;	}	*key = (struct hive_key *)regf_get_key(parent_ctx, regf,					       regf->header->data_offset);	error = regf_save_hbin(regf);	if (!W_ERROR_IS_OK(error)) {		return error;	}		/* We can drop our own reference now that *key will have created one */	talloc_free(regf);	return WERR_OK;}WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, const char *location, 			  struct smb_iconv_convenience *iconv_convenience, struct hive_key **key){	struct regf_data *regf;	struct regf_hdr *regf_hdr;	struct tdr_pull *pull;	int i;	regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);	regf->iconv_convenience = iconv_convenience;	W_ERROR_HAVE_NO_MEMORY(regf);	DEBUG(5, ("Attempting to load registry file\n"));	/* Get the header */	regf->fd = open(location, O_RDWR);	if (regf->fd == -1) {		DEBUG(0,("Could not load file: %s, %s\n", location,				 strerror(errno)));		talloc_free(regf);		return WERR_GENERAL_FAILURE;	}	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) {		DEBUG(0, ("Error reading data\n"));		talloc_free(regf);		return WERR_GENERAL_FAILURE;	}	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))) {		talloc_free(regf);		return WERR_GENERAL_FAILURE;	}	regf->header = regf_hdr;	if (strcmp(regf_hdr->REGF_ID, "regf") != 0) {		DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n",			regf_hdr->REGF_ID, location));		talloc_free(regf);		return WERR_GENERAL_FAILURE;	}	/* Validate the header ... */	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)));		talloc_free(regf);		return WERR_GENERAL_FAILURE;	}	pull->offset = 0x1000;	i = 0;	/* Read in all hbin blocks */	regf->hbins = talloc_array(regf, struct hbin_block *, 1);	W_ERROR_HAVE_NO_MEMORY(regf->hbins);	regf->hbins[0] = NULL;	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))) {			DEBUG(0, ("[%d] Error parsing HBIN block\n", i));			talloc_free(regf);			return WERR_FOOBAR;		}		if (strcmp(hbin->HBIN_ID, "hbin") != 0) {			DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n",				i, hbin->HBIN_ID));			talloc_free(regf);			return WERR_FOOBAR;		}		regf->hbins[i] = hbin;		i++;		regf->hbins = talloc_realloc(regf, regf->hbins,					     struct hbin_block *, i+2);		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,					       regf->header->data_offset);	/* We can drop our own reference now that *key will have created one */	talloc_free(regf);	return WERR_OK;}static struct hive_operations reg_backend_regf = {	.name = "regf",	.get_key_info = regf_get_info,	.enum_key = regf_get_subkey_by_index,	.get_key_by_name = regf_get_subkey_by_name,	.get_value_by_name = regf_get_value_by_name,	.enum_value = regf_get_value,	.get_sec_desc = regf_get_sec_desc,	.set_sec_desc = regf_set_sec_desc,	.add_key = regf_add_key,	.set_value = regf_set_value,	.del_key = regf_del_key,	.delete_value = regf_del_value,};

⌨️ 快捷键说明

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