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

📄 clitrans.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   client transaction calls   Copyright (C) Andrew Tridgell 1994-1998      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"/**************************************************************************** Send a SMB trans or trans2 request.****************************************************************************/BOOL cli_send_trans(struct cli_state *cli, int trans, 		    const char *pipe_name, 		    int fid, int flags,		    uint16 *setup, unsigned int lsetup, unsigned int msetup,		    const char *param, unsigned int lparam, unsigned int mparam,		    const char *data, unsigned int ldata, unsigned int mdata){	unsigned int i;	unsigned int this_ldata,this_lparam;	unsigned int tot_data=0,tot_param=0;	char *outdata,*outparam;	char *p;	int pipe_name_len=0;	uint16 mid;	this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */	this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));	memset(cli->outbuf,'\0',smb_size);	set_message(cli->outbuf,14+lsetup,0,True);	SCVAL(cli->outbuf,smb_com,trans);	SSVAL(cli->outbuf,smb_tid, cli->cnum);	cli_setup_packet(cli);	/*	 * Save the mid we're using. We need this for finding	 * signing replies.	 */	mid = cli->mid;	if (pipe_name) {		pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE);	}	outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3);	outdata = outparam+this_lparam;	/* primary request */	SSVAL(cli->outbuf,smb_tpscnt,lparam);	/* tpscnt */	SSVAL(cli->outbuf,smb_tdscnt,ldata);	/* tdscnt */	SSVAL(cli->outbuf,smb_mprcnt,mparam);	/* mprcnt */	SSVAL(cli->outbuf,smb_mdrcnt,mdata);	/* mdrcnt */	SCVAL(cli->outbuf,smb_msrcnt,msetup);	/* msrcnt */	SSVAL(cli->outbuf,smb_flags,flags);	/* flags */	SIVAL(cli->outbuf,smb_timeout,0);		/* timeout */	SSVAL(cli->outbuf,smb_pscnt,this_lparam);	/* pscnt */	SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */	SSVAL(cli->outbuf,smb_dscnt,this_ldata);	/* dscnt */	SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */	SCVAL(cli->outbuf,smb_suwcnt,lsetup);	/* suwcnt */	for (i=0;i<lsetup;i++)		/* setup[] */		SSVAL(cli->outbuf,smb_setup+i*2,setup[i]);	p = smb_buf(cli->outbuf);	if (trans != SMBtrans) {		*p++ = 0;  /* put in a null smb_name */		*p++ = 'D'; *p++ = ' ';	/* observed in OS/2 */	}	if (this_lparam)			/* param[] */		memcpy(outparam,param,this_lparam);	if (this_ldata)			/* data[] */		memcpy(outdata,data,this_ldata);	cli_setup_bcc(cli, outdata+this_ldata);	show_msg(cli->outbuf);	if (!cli_send_smb(cli)) {		return False;	}	if (this_ldata < ldata || this_lparam < lparam) {		/* receive interim response */		if (!cli_receive_smb(cli) || cli_is_error(cli)) {			return(False);		}		tot_data = this_ldata;		tot_param = this_lparam;				while (tot_data < ldata || tot_param < lparam)  {			this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */			this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));			set_message(cli->outbuf,trans==SMBtrans?8:9,0,True);			SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2));						outparam = smb_buf(cli->outbuf);			outdata = outparam+this_lparam;						/* secondary request */			SSVAL(cli->outbuf,smb_tpscnt,lparam);	/* tpscnt */			SSVAL(cli->outbuf,smb_tdscnt,ldata);	/* tdscnt */			SSVAL(cli->outbuf,smb_spscnt,this_lparam);	/* pscnt */			SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */			SSVAL(cli->outbuf,smb_spsdisp,tot_param);	/* psdisp */			SSVAL(cli->outbuf,smb_sdscnt,this_ldata);	/* dscnt */			SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */			SSVAL(cli->outbuf,smb_sdsdisp,tot_data);	/* dsdisp */			if (trans==SMBtrans2)				SSVALS(cli->outbuf,smb_sfid,fid);		/* fid */			if (this_lparam)			/* param[] */				memcpy(outparam,param+tot_param,this_lparam);			if (this_ldata)			/* data[] */				memcpy(outdata,data+tot_data,this_ldata);			cli_setup_bcc(cli, outdata+this_ldata);						/*			 * Save the mid we're using. We need this for finding			 * signing replies.			 */			mid = cli->mid;			show_msg(cli->outbuf);			if (!cli_send_smb(cli)) {				return False;			}			/* Ensure we use the same mid for the secondaries. */			cli->mid = mid;						tot_data += this_ldata;			tot_param += this_lparam;		}	}	/* Note we're in a trans state. Save the sequence	 * numbers for replies. */	cli_signing_trans_start(cli, mid);	return(True);}/**************************************************************************** Receive a SMB trans or trans2 response allocating the necessary memory.****************************************************************************/BOOL cli_receive_trans(struct cli_state *cli,int trans,                              char **param, unsigned int *param_len,                              char **data, unsigned int *data_len){	unsigned int total_data=0;	unsigned int total_param=0;	unsigned int this_data,this_param;	NTSTATUS status;	char *tdata;	char *tparam;	*data_len = *param_len = 0;	if (!cli_receive_smb(cli)) {		cli_signing_trans_stop(cli);		return False;	}	show_msg(cli->inbuf);		/* sanity check */	if (CVAL(cli->inbuf,smb_com) != trans) {		DEBUG(0,("Expected %s response, got command 0x%02x\n",			 trans==SMBtrans?"SMBtrans":"SMBtrans2", 			 CVAL(cli->inbuf,smb_com)));		cli_signing_trans_stop(cli);		return(False);	}	/*	 * An NT RPC pipe call can return ERRDOS, ERRmoredata	 * to a trans call. This is not an error and should not	 * be treated as such. Note that STATUS_NO_MORE_FILES is	 * returned when a trans2 findfirst/next finishes.	 */	status = cli_nt_error(cli);		if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) {		cli_signing_trans_stop(cli);		return False;	}	/* parse out the lengths */	total_data = SVAL(cli->inbuf,smb_tdrcnt);	total_param = SVAL(cli->inbuf,smb_tprcnt);	/* allocate it */	if (total_data!=0) {		tdata = SMB_REALLOC(*data,total_data);		if (!tdata) {			DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n"));			cli_signing_trans_stop(cli);			return False;		}		else			*data = tdata;	}	if (total_param!=0) {		tparam = SMB_REALLOC(*param,total_param);		if (!tparam) {			DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n"));			cli_signing_trans_stop(cli);			return False;		}		else			*param = tparam;	}	for (;;)  {		this_data = SVAL(cli->inbuf,smb_drcnt);		this_param = SVAL(cli->inbuf,smb_prcnt);		if (this_data + *data_len > total_data ||		    this_param + *param_len > total_param) {			DEBUG(1,("Data overflow in cli_receive_trans\n"));			cli_signing_trans_stop(cli);			return False;		}		if (this_data + *data_len < this_data ||				this_data + *data_len < *data_len ||				this_param + *param_len < this_param ||				this_param + *param_len < *param_len) {			DEBUG(1,("Data overflow in cli_receive_trans\n"));			cli_signing_trans_stop(cli);			return False;		}		if (this_data) {			unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp);			unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff);			if (data_offset_out > total_data ||					data_offset_out + this_data > total_data ||					data_offset_out + this_data < data_offset_out ||					data_offset_out + this_data < this_data) {				DEBUG(1,("Data overflow in cli_receive_trans\n"));				cli_signing_trans_stop(cli);				return False;			}			if (data_offset_in > cli->bufsize ||					data_offset_in + this_data >  cli->bufsize ||					data_offset_in + this_data < data_offset_in ||					data_offset_in + this_data < this_data) {				DEBUG(1,("Data overflow in cli_receive_trans\n"));				cli_signing_trans_stop(cli);				return False;			}			memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data);		}		if (this_param) {			unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp);			unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff);			if (param_offset_out > total_param ||					param_offset_out + this_param > total_param ||					param_offset_out + this_param < param_offset_out ||					param_offset_out + this_param < this_param) {				DEBUG(1,("Param overflow in cli_receive_trans\n"));				cli_signing_trans_stop(cli);				return False;			}			if (param_offset_in > cli->bufsize ||					param_offset_in + this_param >  cli->bufsize ||					param_offset_in + this_param < param_offset_in ||					param_offset_in + this_param < this_param) {				DEBUG(1,("Param overflow in cli_receive_trans\n"));				cli_signing_trans_stop(cli);				return False;			}			memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param);		}		*data_len += this_data;		*param_len += this_param;		if (total_data <= *data_len && total_param <= *param_len)			break;				if (!cli_receive_smb(cli)) {			cli_signing_trans_stop(cli);			return False;			}		show_msg(cli->inbuf);				/* sanity check */		if (CVAL(cli->inbuf,smb_com) != trans) {			DEBUG(0,("Expected %s response, got command 0x%02x\n",				 trans==SMBtrans?"SMBtrans":"SMBtrans2", 				 CVAL(cli->inbuf,smb_com)));			cli_signing_trans_stop(cli);			return(False);		}		if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {			cli_signing_trans_stop(cli);			return(False);		}		/* parse out the total lengths again - they can shrink! */		if (SVAL(cli->inbuf,smb_tdrcnt) < total_data)			total_data = SVAL(cli->inbuf,smb_tdrcnt);		if (SVAL(cli->inbuf,smb_tprcnt) < total_param)			total_param = SVAL(cli->inbuf,smb_tprcnt);				if (total_data <= *data_len && total_param <= *param_len)			break;			}	

⌨️ 快捷键说明

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