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

📄 trans2.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	/* work out the backend level - we make it 1-1 in the header */	st->generic.level = (enum smb_fileinfo_level)level;	if (st->generic.level >= RAW_FILEINFO_GENERIC) {		return NT_STATUS_INVALID_LEVEL;	}	if (st->generic.level == RAW_FILEINFO_EA_LIST) {		TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req, 					       &st->ea_list.in.num_names,					       &st->ea_list.in.ea_names));	}	op->op_info = st;	op->send_fn = trans2_fileinfo_send;	return ntvfs_qpathinfo(req->ntvfs, st);}/*  trans2 qpathinfo implementation*/static NTSTATUS trans2_qfileinfo(struct smbsrv_request *req, struct trans_op *op){	struct smb_trans2 *trans = op->trans;	union smb_fileinfo *st;	uint16_t level;	struct ntvfs_handle *h;	/* make sure we got enough parameters */	if (trans->in.params.length < 4) {		return NT_STATUS_FOOBAR;	}	st = talloc(op, union smb_fileinfo);	NT_STATUS_HAVE_NO_MEMORY(st);	h     = smbsrv_pull_fnum(req, trans->in.params.data, 0);	level = SVAL(trans->in.params.data, 2);	st->generic.in.file.ntvfs = h;	/* work out the backend level - we make it 1-1 in the header */	st->generic.level = (enum smb_fileinfo_level)level;	if (st->generic.level >= RAW_FILEINFO_GENERIC) {		return NT_STATUS_INVALID_LEVEL;	}	if (st->generic.level == RAW_FILEINFO_EA_LIST) {		TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req, 					       &st->ea_list.in.num_names,					       &st->ea_list.in.ea_names));	}	op->op_info = st;	op->send_fn = trans2_fileinfo_send;	SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(st->generic.in.file.ntvfs);	return ntvfs_qfileinfo(req->ntvfs, st);}/*  parse a trans2 setfileinfo/setpathinfo data blob*/static NTSTATUS trans2_parse_sfileinfo(struct smbsrv_request *req,				       union smb_setfileinfo *st,				       const DATA_BLOB *blob){	enum smb_setfileinfo_level passthru_level;	switch (st->generic.level) {	case RAW_SFILEINFO_GENERIC:	case RAW_SFILEINFO_SETATTR:	case RAW_SFILEINFO_SETATTRE:	case RAW_SFILEINFO_SEC_DESC:		/* handled elsewhere */		return NT_STATUS_INVALID_LEVEL;	case RAW_SFILEINFO_STANDARD:		CHECK_MIN_BLOB_SIZE(blob, 12);		st->standard.in.create_time = srv_pull_dos_date2(req->smb_conn, blob->data + 0);		st->standard.in.access_time = srv_pull_dos_date2(req->smb_conn, blob->data + 4);		st->standard.in.write_time  = srv_pull_dos_date2(req->smb_conn, blob->data + 8);		return NT_STATUS_OK;	case RAW_SFILEINFO_EA_SET:		return ea_pull_list(blob, req, 				    &st->ea_set.in.num_eas, 				    &st->ea_set.in.eas);	case SMB_SFILEINFO_BASIC_INFO:	case SMB_SFILEINFO_BASIC_INFORMATION:		passthru_level = SMB_SFILEINFO_BASIC_INFORMATION;		break;	case SMB_SFILEINFO_DISPOSITION_INFO:	case SMB_SFILEINFO_DISPOSITION_INFORMATION:		passthru_level = SMB_SFILEINFO_DISPOSITION_INFORMATION;		break;	case SMB_SFILEINFO_ALLOCATION_INFO:	case SMB_SFILEINFO_ALLOCATION_INFORMATION:		passthru_level = SMB_SFILEINFO_ALLOCATION_INFORMATION;		break;	case RAW_SFILEINFO_END_OF_FILE_INFO:	case RAW_SFILEINFO_END_OF_FILE_INFORMATION:		passthru_level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;		break;	case RAW_SFILEINFO_RENAME_INFORMATION:	case RAW_SFILEINFO_POSITION_INFORMATION:	case RAW_SFILEINFO_MODE_INFORMATION:		passthru_level = st->generic.level;		break;	case RAW_SFILEINFO_UNIX_BASIC:	case RAW_SFILEINFO_UNIX_LINK:	case RAW_SFILEINFO_UNIX_HLINK:	case RAW_SFILEINFO_1023:	case RAW_SFILEINFO_1025:	case RAW_SFILEINFO_1029:	case RAW_SFILEINFO_1032:	case RAW_SFILEINFO_1039:	case RAW_SFILEINFO_1040:		return NT_STATUS_INVALID_LEVEL;	default:		/* we need a default here to cope with invalid values on the wire */		return NT_STATUS_INVALID_LEVEL;	}	return smbsrv_pull_passthru_sfileinfo(st, passthru_level, st,					      blob, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),					      &req->in.bufinfo);}/*  trans2 setfileinfo implementation*/static NTSTATUS trans2_setfileinfo(struct smbsrv_request *req, struct trans_op *op){	struct smb_trans2 *trans = op->trans;	union smb_setfileinfo *st;	uint16_t level;	struct ntvfs_handle *h;	/* make sure we got enough parameters */	if (trans->in.params.length < 4) {		return NT_STATUS_FOOBAR;	}	st = talloc(op, union smb_setfileinfo);	NT_STATUS_HAVE_NO_MEMORY(st);	h     = smbsrv_pull_fnum(req, trans->in.params.data, 0);	level = SVAL(trans->in.params.data, 2);	st->generic.in.file.ntvfs = h;	/* work out the backend level - we make it 1-1 in the header */	st->generic.level = (enum smb_setfileinfo_level)level;	if (st->generic.level >= RAW_SFILEINFO_GENERIC) {		return NT_STATUS_INVALID_LEVEL;	}	TRANS2_CHECK(trans2_parse_sfileinfo(req, st, &trans->in.data));	op->op_info = st;	op->send_fn = trans2_simple_send;	SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(st->generic.in.file.ntvfs);	return ntvfs_setfileinfo(req->ntvfs, st);}/*  trans2 setpathinfo implementation*/static NTSTATUS trans2_setpathinfo(struct smbsrv_request *req, struct trans_op *op){	struct smb_trans2 *trans = op->trans;	union smb_setfileinfo *st;	uint16_t level;	/* make sure we got enough parameters */	if (trans->in.params.length < 4) {		return NT_STATUS_FOOBAR;	}	st = talloc(op, union smb_setfileinfo);	NT_STATUS_HAVE_NO_MEMORY(st);	level = SVAL(trans->in.params.data, 0);	smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 6, &st->generic.in.file.path, 0);	if (st->generic.in.file.path == NULL) {		return NT_STATUS_FOOBAR;	}	/* work out the backend level - we make it 1-1 in the header */	st->generic.level = (enum smb_setfileinfo_level)level;	if (st->generic.level >= RAW_SFILEINFO_GENERIC) {		return NT_STATUS_INVALID_LEVEL;	}	TRANS2_CHECK(trans2_parse_sfileinfo(req, st, &trans->in.data));	op->op_info = st;	op->send_fn = trans2_simple_send;	return ntvfs_setpathinfo(req->ntvfs, st);}/* a structure to encapsulate the state information about an in-progress ffirst/fnext operation */struct find_state {	struct trans_op *op;	void *search;	enum smb_search_data_level data_level;	uint16_t last_entry_offset;	uint16_t flags;};/*  fill a single entry in a trans2 find reply */static NTSTATUS find_fill_info(struct find_state *state,			       const union smb_search_data *file){	struct smbsrv_request *req = state->op->req;	struct smb_trans2 *trans = state->op->trans;	uint8_t *data;	uint_t ofs = trans->out.data.length;	uint32_t ea_size;	switch (state->data_level) {	case RAW_SEARCH_DATA_GENERIC:	case RAW_SEARCH_DATA_SEARCH:		/* handled elsewhere */		return NT_STATUS_INVALID_LEVEL;	case RAW_SEARCH_DATA_STANDARD:		if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27));			SIVAL(trans->out.data.data, ofs, file->standard.resume_key);			ofs += 4;		} else {			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 23));		}		data = trans->out.data.data + ofs;		srv_push_dos_date2(req->smb_conn, data, 0, file->standard.create_time);		srv_push_dos_date2(req->smb_conn, data, 4, file->standard.access_time);		srv_push_dos_date2(req->smb_conn, data, 8, file->standard.write_time);		SIVAL(data, 12, file->standard.size);		SIVAL(data, 16, file->standard.alloc_size);		SSVAL(data, 20, file->standard.attrib);		TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->standard.name.s, 						       ofs + 22, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),						       STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM));		break;	case RAW_SEARCH_DATA_EA_SIZE:		if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 31));			SIVAL(trans->out.data.data, ofs, file->ea_size.resume_key);			ofs += 4;		} else {			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27));		}		data = trans->out.data.data + ofs;		srv_push_dos_date2(req->smb_conn, data, 0, file->ea_size.create_time);		srv_push_dos_date2(req->smb_conn, data, 4, file->ea_size.access_time);		srv_push_dos_date2(req->smb_conn, data, 8, file->ea_size.write_time);		SIVAL(data, 12, file->ea_size.size);		SIVAL(data, 16, file->ea_size.alloc_size);		SSVAL(data, 20, file->ea_size.attrib);		SIVAL(data, 22, file->ea_size.ea_size);		TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_size.name.s, 						       ofs + 26, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),						       STR_LEN8BIT | STR_NOALIGN));		TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, trans->out.data.length + 1));		break;	case RAW_SEARCH_DATA_EA_LIST:		ea_size = ea_list_size(file->ea_list.eas.num_eas, file->ea_list.eas.eas);		if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27 + ea_size));			SIVAL(trans->out.data.data, ofs, file->ea_list.resume_key);			ofs += 4;		} else {			TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 23 + ea_size));		}		data = trans->out.data.data + ofs;		srv_push_dos_date2(req->smb_conn, data, 0, file->ea_list.create_time);		srv_push_dos_date2(req->smb_conn, data, 4, file->ea_list.access_time);		srv_push_dos_date2(req->smb_conn, data, 8, file->ea_list.write_time);		SIVAL(data, 12, file->ea_list.size);		SIVAL(data, 16, file->ea_list.alloc_size);		SSVAL(data, 20, file->ea_list.attrib);		ea_put_list(data+22, file->ea_list.eas.num_eas, file->ea_list.eas.eas);		TRANS2_CHECK(smbsrv_blob_append_string(trans, &trans->out.data, file->ea_list.name.s, 						       ofs + 22 + ea_size, SMBSRV_REQ_DEFAULT_STR_FLAGS(req),						       STR_LEN8BIT | STR_NOALIGN));		TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, trans->out.data.length + 1));		break;	case RAW_SEARCH_DATA_DIRECTORY_INFO:	case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:	case RAW_SEARCH_DATA_NAME_INFO:	case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:	case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:	case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:		return smbsrv_push_passthru_search(trans, &trans->out.data, state->data_level, file,						   SMBSRV_REQ_DEFAULT_STR_FLAGS(req));	case RAW_SEARCH_DATA_UNIX_INFO:		return NT_STATUS_INVALID_LEVEL;	}	return NT_STATUS_OK;}/* callback function for trans2 findfirst/findnext */static bool find_callback(void *private, const union smb_search_data *file){	struct find_state *state = talloc_get_type(private, struct find_state);	struct smb_trans2 *trans = state->op->trans;	uint_t old_length;	old_length = trans->out.data.length;	if (!NT_STATUS_IS_OK(find_fill_info(state, file)) ||	    trans->out.data.length > trans->in.max_data) {		/* restore the old length and tell the backend to stop */		smbsrv_blob_grow_data(trans, &trans->out.data, old_length);		return false;	}	state->last_entry_offset = old_length;		return true;}/*  trans2 findfirst send */static NTSTATUS trans2_findfirst_send(struct trans_op *op){	struct smbsrv_request *req = op->req;	struct smb_trans2 *trans = op->trans;	union smb_search_first *search;	struct find_state *state;	uint8_t *param;	TRANS2_CHECK_ASYNC_STATUS(state, struct find_state);	search = talloc_get_type(state->search, union smb_search_first);	/* fill in the findfirst reply header */	param = trans->out.params.data;	SSVAL(param, VWV(0), search->t2ffirst.out.handle);	SSVAL(param, VWV(1), search->t2ffirst.out.count);	SSVAL(param, VWV(2), search->t2ffirst.out.end_of_search);	SSVAL(param, VWV(3), 0);	SSVAL(param, VWV(4), state->last_entry_offset);	return NT_STATUS_OK;}/*  trans2 findfirst implementation*/static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct trans_op *op){	struct smb_trans2 *trans = op->trans;	union smb_search_first *search;	uint16_t level;	struct find_state *state;	/* make sure we got all the parameters */	if (trans->in.params.length < 14) {		return NT_STATUS_FOOBAR;	}	search = talloc(op, union smb_search_first);	NT_STATUS_HAVE_NO_MEMORY(search);	search->t2ffirst.in.search_attrib = SVAL(trans->in.params.data, 0);	search->t2ffirst.in.max_count     = SVAL(trans->in.params.data, 2);	search->t2ffirst.in.flags         = SVAL(trans->in.params.data, 4);	level                             = SVAL(trans->in.params.data, 6);	search->t2ffirst.in.storage_type  = IVAL(trans->in.params.data, 8);	smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 12, &search->t2ffirst.in.pattern, 0);	if (search->t2ffirst.in.pattern == NULL) {		return NT_STATUS_FOOBAR;	}	search->t2ffirst.level = RAW_SEARCH_TRANS2;	search->t2ffirst.data_level = (enum smb_search_data_level)level;	if (search->t2ffirst.data_level >= RAW_SEARCH_DATA_GENERIC) {		return NT_STATUS_INVALID_LEVEL;	}	if (search->t2ffirst.data_level == RAW_SEARCH_DATA_EA_LIST) {		TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,					       &search->t2ffirst.in.num_names, 					       &search->t2ffirst.in.ea_names));	}	/* setup the private state structure that the backend will	   give us in the callback */	state = talloc(op, struct find_state);	NT_STATUS_HAVE_NO_MEMORY(state);	state->op		= op;	state->search		= search;	state->data_level	= search->t2ffirst.data_level;	state->last_entry_offset= 0;	state->flags		= search->t2ffirst.in.flags;	/* setup for just a header in the reply */	TRANS2_CHECK(trans2_setup_reply(trans, 10, 0, 0));	op->op_info = state;	op->send_fn = trans2_findfirst_send;	return ntvfs_search_first(req->ntvfs, search, state, find_callback);}/*  trans2 findnext send*/static NTSTATUS trans2_findnext_send(struct trans_op *op){	struct smbsrv_request *req = op->req;	struct smb_trans2 *trans = op->trans;	union smb_search_next *search;	struct find_state *state;	uint8_t *param;	TRANS2_CHECK_ASYNC_STATUS(state, struct find_state);	search = talloc_get_type(state->search, union smb_search_next);	/* fill in the findfirst reply header */	param = trans->out.params.data;	SSVAL(param, VWV(0), search->t2fnext.out.count);	SSVAL(param, VWV(1), search->t2fnext.out.end_of_search);	SSVAL(param, VWV(2), 0);	SSVAL(param, VWV(3), state->last_entry_offset);		return NT_STATUS_OK;}/*  trans2 findnext implementation*/static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct trans_op *op){	struct smb_trans2 *trans = op->trans;	union smb_search_next *search;	uint16_t level;	struct find_state *state;

⌨️ 快捷键说明

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