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

📄 nttrans.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    parse NTTRANS_IOCTL request */static NTSTATUS nttrans_ioctl(struct smbsrv_request *req, 			      struct nttrans_op *op){	struct smb_nttrans *trans = op->trans;	union smb_ioctl *nt;	/* should have at least 4 setup words */	if (trans->in.setup_count != 4) {		return NT_STATUS_INVALID_PARAMETER;	}	nt = talloc(op, union smb_ioctl);	NT_STATUS_HAVE_NO_MEMORY(nt);		nt->ntioctl.level		= RAW_IOCTL_NTIOCTL;	nt->ntioctl.in.function		= IVAL(trans->in.setup, 0);	nt->ntioctl.in.file.ntvfs	= smbsrv_pull_fnum(req, (uint8_t *)trans->in.setup, 4);	nt->ntioctl.in.fsctl		= CVAL(trans->in.setup, 6);	nt->ntioctl.in.filter		= CVAL(trans->in.setup, 7);	nt->ntioctl.in.max_data		= trans->in.max_data;	nt->ntioctl.in.blob		= trans->in.data;	op->op_info = nt;	op->send_fn = nttrans_ioctl_send;	SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(nt->ntioctl.in.file.ntvfs);	return ntvfs_ioctl(req->ntvfs, nt);}/*    send NTTRANS_NOTIFY_CHANGE reply */static NTSTATUS nttrans_notify_change_send(struct nttrans_op *op){	union smb_notify *info = talloc_get_type(op->op_info, union smb_notify);	size_t size = 0;	int i;	NTSTATUS status;	uint8_t *p;#define MAX_BYTES_PER_CHAR 3		/* work out how big the reply buffer could be */	for (i=0;i<info->nttrans.out.num_changes;i++) {		size += 12 + 3 + (1+strlen(info->nttrans.out.changes[i].name.s)) * MAX_BYTES_PER_CHAR;	}	status = nttrans_setup_reply(op, op->trans, size, 0, 0);	NT_STATUS_NOT_OK_RETURN(status);	p = op->trans->out.params.data;	/* construct the changes buffer */	for (i=0;i<info->nttrans.out.num_changes;i++) {		uint32_t ofs;		ssize_t len;		SIVAL(p, 4, info->nttrans.out.changes[i].action);		len = push_string(lp_iconv_convenience(global_loadparm), p + 12, info->nttrans.out.changes[i].name.s, 				  op->trans->out.params.length - 				  (p+12 - op->trans->out.params.data), STR_UNICODE);		SIVAL(p, 8, len);		ofs = len + 12;		if (ofs & 3) {			int pad = 4 - (ofs & 3);			memset(p+ofs, 0, pad);			ofs += pad;		}		if (i == info->nttrans.out.num_changes-1) {			SIVAL(p, 0, 0);		} else {			SIVAL(p, 0, ofs);		}		p += ofs;	}	op->trans->out.params.length = p - op->trans->out.params.data;	return NT_STATUS_OK;}/*    parse NTTRANS_NOTIFY_CHANGE request */static NTSTATUS nttrans_notify_change(struct smbsrv_request *req, 				      struct nttrans_op *op){	struct smb_nttrans *trans = op->trans;	union smb_notify *info;	/* should have at least 4 setup words */	if (trans->in.setup_count != 4) {		return NT_STATUS_INVALID_PARAMETER;	}	info = talloc(op, union smb_notify);	NT_STATUS_HAVE_NO_MEMORY(info);	info->nttrans.level			= RAW_NOTIFY_NTTRANS;	info->nttrans.in.completion_filter	= IVAL(trans->in.setup, 0);	info->nttrans.in.file.ntvfs		= smbsrv_pull_fnum(req, (uint8_t *)trans->in.setup, 4);	info->nttrans.in.recursive		= SVAL(trans->in.setup, 6);	info->nttrans.in.buffer_size		= trans->in.max_param;	op->op_info = info;	op->send_fn = nttrans_notify_change_send;	SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(info->nttrans.in.file.ntvfs);	return ntvfs_notify(req->ntvfs, info);}/*  backend for nttrans requests*/static NTSTATUS nttrans_backend(struct smbsrv_request *req, 				struct nttrans_op *op){	/* the nttrans command is in function */	switch (op->trans->in.function) {	case NT_TRANSACT_CREATE:		return nttrans_create(req, op);	case NT_TRANSACT_IOCTL:		return nttrans_ioctl(req, op);	case NT_TRANSACT_RENAME:		return nttrans_rename(req, op);	case NT_TRANSACT_QUERY_SECURITY_DESC:		return nttrans_query_sec_desc(req, op);	case NT_TRANSACT_SET_SECURITY_DESC:		return nttrans_set_sec_desc(req, op);	case NT_TRANSACT_NOTIFY_CHANGE:		return nttrans_notify_change(req, op);	}	/* an unknown nttrans command */	return NT_STATUS_DOS(ERRSRV, ERRerror);}static void reply_nttrans_send(struct ntvfs_request *ntvfs){	struct smbsrv_request *req;	uint32_t params_left, data_left;	uint8_t *params, *data;	struct smb_nttrans *trans;	struct nttrans_op *op;	SMBSRV_CHECK_ASYNC_STATUS(op, struct nttrans_op);	trans = op->trans;	/* if this function needs work to form the nttrans reply buffer, then	   call that now */	if (op->send_fn != NULL) {		NTSTATUS status;		status = op->send_fn(op);		if (!NT_STATUS_IS_OK(status)) {			smbsrv_send_error(req, status);			return;		}	}	smbsrv_setup_reply(req, 18 + trans->out.setup_count, 0);	/* note that we don't check the max_setup count (matching w2k3	   behaviour) */	if (trans->out.params.length > trans->in.max_param) {		smbsrv_setup_error(req, NT_STATUS_BUFFER_TOO_SMALL);		trans->out.params.length = trans->in.max_param;	}	if (trans->out.data.length > trans->in.max_data) {		smbsrv_setup_error(req, NT_STATUS_BUFFER_TOO_SMALL);		trans->out.data.length = trans->in.max_data;	}	params_left = trans->out.params.length;	data_left   = trans->out.data.length;	params      = trans->out.params.data;	data        = trans->out.data.data;	/* we need to divide up the reply into chunks that fit into	   the negotiated buffer size */	do {		uint32_t this_data, this_param, max_bytes;		uint_t align1 = 1, align2 = (params_left ? 2 : 0);		struct smbsrv_request *this_req;		max_bytes = req_max_data(req) - (align1 + align2);		this_param = params_left;		if (this_param > max_bytes) {			this_param = max_bytes;		}		max_bytes -= this_param;		this_data = data_left;		if (this_data > max_bytes) {			this_data = max_bytes;		}		/* don't destroy unless this is the last chunk */		if (params_left - this_param != 0 || 		    data_left - this_data != 0) {			this_req = smbsrv_setup_secondary_request(req);		} else {			this_req = req;		}		req_grow_data(this_req, this_param + this_data + (align1 + align2));		SSVAL(this_req->out.vwv, 0, 0); /* reserved */		SCVAL(this_req->out.vwv, 2, 0); /* reserved */		SIVAL(this_req->out.vwv, 3, trans->out.params.length);		SIVAL(this_req->out.vwv, 7, trans->out.data.length);		SIVAL(this_req->out.vwv, 11, this_param);		SIVAL(this_req->out.vwv, 15, align1 + PTR_DIFF(this_req->out.data, this_req->out.hdr));		SIVAL(this_req->out.vwv, 19, PTR_DIFF(params, trans->out.params.data));		SIVAL(this_req->out.vwv, 23, this_data);		SIVAL(this_req->out.vwv, 27, align1 + align2 + 		      PTR_DIFF(this_req->out.data + this_param, this_req->out.hdr));		SIVAL(this_req->out.vwv, 31, PTR_DIFF(data, trans->out.data.data));		SCVAL(this_req->out.vwv, 35, trans->out.setup_count);		memcpy((char *)(this_req->out.vwv) + VWV(18), trans->out.setup,		       sizeof(uint16_t) * trans->out.setup_count);		memset(this_req->out.data, 0, align1);		if (this_param != 0) {			memcpy(this_req->out.data + align1, params, this_param);		}		memset(this_req->out.data+this_param+align1, 0, align2);		if (this_data != 0) {			memcpy(this_req->out.data+this_param+align1+align2, 			       data, this_data);		}		params_left -= this_param;		data_left -= this_data;		params += this_param;		data += this_data;		smbsrv_send_reply(this_req);	} while (params_left != 0 || data_left != 0);}/**************************************************************************** Reply to an SMBnttrans request****************************************************************************/void smbsrv_reply_nttrans(struct smbsrv_request *req){	struct nttrans_op *op;	struct smb_nttrans *trans;	uint32_t param_ofs, data_ofs;	uint32_t param_count, data_count;	uint32_t param_total, data_total;	/* parse request */	if (req->in.wct < 19) {		smbsrv_send_error(req, NT_STATUS_FOOBAR);		return;	}	SMBSRV_TALLOC_IO_PTR(op, struct nttrans_op);	SMBSRV_SETUP_NTVFS_REQUEST(reply_nttrans_send, NTVFS_ASYNC_STATE_MAY_ASYNC);	trans = talloc(op, struct smb_nttrans);	if (trans == NULL) {		smbsrv_send_error(req, NT_STATUS_NO_MEMORY);		return;	}	op->trans = trans;	op->op_info = NULL;	op->send_fn = NULL;	trans->in.max_setup  = CVAL(req->in.vwv, 0);	param_total          = IVAL(req->in.vwv, 3);	data_total           = IVAL(req->in.vwv, 7);	trans->in.max_param  = IVAL(req->in.vwv, 11);	trans->in.max_data   = IVAL(req->in.vwv, 15);	param_count          = IVAL(req->in.vwv, 19);	param_ofs            = IVAL(req->in.vwv, 23);	data_count           = IVAL(req->in.vwv, 27);	data_ofs             = IVAL(req->in.vwv, 31);	trans->in.setup_count= CVAL(req->in.vwv, 35);	trans->in.function   = SVAL(req->in.vwv, 36);	if (req->in.wct != 19 + trans->in.setup_count) {		smbsrv_send_error(req, NT_STATUS_DOS(ERRSRV, ERRerror));		return;	}	/* parse out the setup words */	trans->in.setup = talloc_array(req, uint8_t, trans->in.setup_count*2);	if (!trans->in.setup) {		smbsrv_send_error(req, NT_STATUS_NO_MEMORY);		return;	}	memcpy(trans->in.setup, (char *)(req->in.vwv) + VWV(19),	       sizeof(uint16_t) * trans->in.setup_count);	if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||	    !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {		smbsrv_send_error(req, NT_STATUS_FOOBAR);		return;	}	/* is it a partial request? if so, then send a 'send more' message */	if (param_total > param_count ||	    data_total > data_count) {		DEBUG(0,("REWRITE: not handling partial nttrans requests!\n"));		smbsrv_send_error(req, NT_STATUS_FOOBAR);		return;	}	ZERO_STRUCT(trans->out);	SMBSRV_CALL_NTVFS_BACKEND(nttrans_backend(req, op));}/**************************************************************************** Reply to an SMBnttranss request****************************************************************************/void smbsrv_reply_nttranss(struct smbsrv_request *req){	smbsrv_send_error(req, NT_STATUS_FOOBAR);}

⌨️ 快捷键说明

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