Exemple #1
0
/****************************************************************************
  reply to a read and X

  This code is basically stolen from reply_read_and_X with some
  wrinkles to handle pipes.
****************************************************************************/
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
	pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2);
	int smb_maxcnt = SVAL(inbuf,smb_vwv5);
	int smb_mincnt = SVAL(inbuf,smb_vwv6);
	int nread = -1;
	char *data;
	/* we don't use the offset given to use for pipe reads. This
           is deliberate, instead we always return the next lump of
           data on the pipe */
#if 0
	uint32 smb_offs = IVAL(inbuf,smb_vwv3);
#endif

	if (!p)
		return(ERROR(ERRDOS,ERRbadfid));

	set_message(outbuf,12,0,True);
	data = smb_buf(outbuf);

	nread = (int)read_from_pipe(p, data, (size_t)smb_maxcnt);

	if (nread < 0)
		return(UNIXERROR(ERRDOS,ERRnoaccess));
  
	SSVAL(outbuf,smb_vwv5,nread);
	SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
	SSVAL(smb_buf(outbuf),-2,nread);
  
	DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
		 p->pnum, smb_mincnt, smb_maxcnt, nread));

	return chain_reply(inbuf,outbuf,length,bufsize);
}
Exemple #2
0
void reply_pipe_read_and_X(struct smb_request *req)
{
	smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv2));
	int smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
	int smb_mincnt = SVAL(req->inbuf,smb_vwv6);
	int nread = -1;
	char *data;
	bool unused;

	/* we don't use the offset given to use for pipe reads. This
           is deliberate, instead we always return the next lump of
           data on the pipe */
#if 0
	uint32 smb_offs = IVAL(req->inbuf,smb_vwv3);
#endif

	if (!p) {
		reply_doserror(req, ERRDOS, ERRbadfid);
		return;
	}

	reply_outbuf(req, 12, smb_maxcnt);

	data = smb_buf(req->outbuf);

	nread = read_from_pipe(p, data, smb_maxcnt, &unused);

	if (nread < 0) {
		reply_doserror(req, ERRDOS, ERRnoaccess);
		return;
	}

	srv_set_message((char *)req->outbuf, 12, nread, False);
  
	SSVAL(req->outbuf,smb_vwv5,nread);
	SSVAL(req->outbuf,smb_vwv6,smb_offset(data,req->outbuf));
	SSVAL(smb_buf(req->outbuf),-2,nread);
  
	DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
		 p->pnum, smb_mincnt, smb_maxcnt, nread));

	chain_reply(req);
}
Exemple #3
0
void send_trans_reply(connection_struct *conn,
		      struct smb_request *req,
		      char *rparam, int rparam_len,
		      char *rdata, int rdata_len,
		      bool buffer_too_large)
{
	int this_ldata,this_lparam;
	int tot_data_sent = 0;
	int tot_param_sent = 0;
	int align;

	int ldata  = rdata  ? rdata_len : 0;
	int lparam = rparam ? rparam_len : 0;
	struct smbd_server_connection *sconn = req->sconn;
	int max_send = sconn->smb1.sessions.max_send;

	if (buffer_too_large)
		DEBUG(5,("send_trans_reply: buffer %d too large\n", ldata ));

	this_lparam = MIN(lparam,max_send - 500); /* hack */
	this_ldata  = MIN(ldata,max_send - (500+this_lparam));

	align = ((this_lparam)%4);

	reply_outbuf(req, 10, 1+align+this_ldata+this_lparam);

	/*
	 * We might have SMBtranss in req which was transferred to the outbuf,
	 * fix that.
	 */
	SCVAL(req->outbuf, smb_com, SMBtrans);

	copy_trans_params_and_data((char *)req->outbuf, align,
				rparam, tot_param_sent, this_lparam,
				rdata, tot_data_sent, this_ldata);

	SSVAL(req->outbuf,smb_vwv0,lparam);
	SSVAL(req->outbuf,smb_vwv1,ldata);
	SSVAL(req->outbuf,smb_vwv3,this_lparam);
	SSVAL(req->outbuf,smb_vwv4,
	      smb_offset(smb_buf(req->outbuf)+1, req->outbuf));
	SSVAL(req->outbuf,smb_vwv5,0);
	SSVAL(req->outbuf,smb_vwv6,this_ldata);
	SSVAL(req->outbuf,smb_vwv7,
	      smb_offset(smb_buf(req->outbuf)+1+this_lparam+align,
			 req->outbuf));
	SSVAL(req->outbuf,smb_vwv8,0);
	SSVAL(req->outbuf,smb_vwv9,0);

	if (buffer_too_large) {
		error_packet_set((char *)req->outbuf, ERRDOS, ERRmoredata,
				 STATUS_BUFFER_OVERFLOW, __LINE__, __FILE__);
	}

	show_msg((char *)req->outbuf);
	if (!srv_send_smb(sconn, (char *)req->outbuf,
			  true, req->seqnum+1,
			  IS_CONN_ENCRYPTED(conn), &req->pcd)) {
		exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
	}

	TALLOC_FREE(req->outbuf);

	tot_data_sent = this_ldata;
	tot_param_sent = this_lparam;

	while (tot_data_sent < ldata || tot_param_sent < lparam)
	{
		this_lparam = MIN(lparam-tot_param_sent,
				  max_send - 500); /* hack */
		this_ldata  = MIN(ldata -tot_data_sent,
				  max_send - (500+this_lparam));

		if(this_lparam < 0)
			this_lparam = 0;

		if(this_ldata < 0)
			this_ldata = 0;

		align = (this_lparam%4);

		reply_outbuf(req, 10, 1+align+this_ldata+this_lparam);

		/*
		 * We might have SMBtranss in req which was transferred to the
		 * outbuf, fix that.
		 */
		SCVAL(req->outbuf, smb_com, SMBtrans);

		copy_trans_params_and_data((char *)req->outbuf, align,
					   rparam, tot_param_sent, this_lparam,
					   rdata, tot_data_sent, this_ldata);

		SSVAL(req->outbuf,smb_vwv0,lparam);
		SSVAL(req->outbuf,smb_vwv1,ldata);

		SSVAL(req->outbuf,smb_vwv3,this_lparam);
		SSVAL(req->outbuf,smb_vwv4,
		      smb_offset(smb_buf(req->outbuf)+1,req->outbuf));
		SSVAL(req->outbuf,smb_vwv5,tot_param_sent);
		SSVAL(req->outbuf,smb_vwv6,this_ldata);
		SSVAL(req->outbuf,smb_vwv7,
		      smb_offset(smb_buf(req->outbuf)+1+this_lparam+align,
				 req->outbuf));
		SSVAL(req->outbuf,smb_vwv8,tot_data_sent);
		SSVAL(req->outbuf,smb_vwv9,0);

		if (buffer_too_large) {
			error_packet_set((char *)req->outbuf,
					 ERRDOS, ERRmoredata,
					 STATUS_BUFFER_OVERFLOW,
					 __LINE__, __FILE__);
		}

		show_msg((char *)req->outbuf);
		if (!srv_send_smb(sconn, (char *)req->outbuf,
				  true, req->seqnum+1,
				  IS_CONN_ENCRYPTED(conn), &req->pcd))
			exit_server_cleanly("send_trans_reply: srv_send_smb "
					    "failed.");

		tot_data_sent  += this_ldata;
		tot_param_sent += this_lparam;
		TALLOC_FREE(req->outbuf);
	}
}
Exemple #4
0
bool cli_send_nt_trans(struct cli_state *cli,
		       int function,
		       int flags,
		       uint16 *setup, unsigned int lsetup, unsigned int msetup,
		       char *param, unsigned int lparam, unsigned int mparam,
		       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;
	uint16 mid;
	char *outdata,*outparam;

	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);
	cli_set_message(cli->outbuf,19+lsetup,0,True);
	SCVAL(cli->outbuf,smb_com,SMBnttrans);
	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;

	outparam = smb_buf(cli->outbuf)+3;
	outdata = outparam+this_lparam;

	/* primary request */
	SCVAL(cli->outbuf,smb_nt_MaxSetupCount,msetup);
	SCVAL(cli->outbuf,smb_nt_Flags,flags);
	SIVAL(cli->outbuf,smb_nt_TotalParameterCount, lparam);
	SIVAL(cli->outbuf,smb_nt_TotalDataCount, ldata);
	SIVAL(cli->outbuf,smb_nt_MaxParameterCount, mparam);
	SIVAL(cli->outbuf,smb_nt_MaxDataCount, mdata);
	SIVAL(cli->outbuf,smb_nt_ParameterCount, this_lparam);
	SIVAL(cli->outbuf,smb_nt_ParameterOffset, smb_offset(outparam,cli->outbuf));
	SIVAL(cli->outbuf,smb_nt_DataCount, this_ldata);
	SIVAL(cli->outbuf,smb_nt_DataOffset, smb_offset(outdata,cli->outbuf));
	SIVAL(cli->outbuf,smb_nt_SetupCount, lsetup);
	SIVAL(cli->outbuf,smb_nt_Function, function);
	for (i=0;i<lsetup;i++)		/* setup[] */
		SSVAL(cli->outbuf,smb_nt_SetupStart+i*2,setup[i]);

	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;
	}

	cli_state_seqnum_persistent(cli, mid);

	if (this_ldata < ldata || this_lparam < lparam) {
		/* receive interim response */
		if (!cli_receive_smb(cli) || cli_is_error(cli)) {
			cli_state_seqnum_remove(cli, mid);
			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));

			cli_set_message(cli->outbuf,18,0,True);
			SCVAL(cli->outbuf,smb_com,SMBnttranss);

			/* XXX - these should probably be aligned */
			outparam = smb_buf(cli->outbuf);
			outdata = outparam+this_lparam;

			/* secondary request */
			SIVAL(cli->outbuf,smb_nts_TotalParameterCount,lparam);
			SIVAL(cli->outbuf,smb_nts_TotalDataCount,ldata);
			SIVAL(cli->outbuf,smb_nts_ParameterCount,this_lparam);
			SIVAL(cli->outbuf,smb_nts_ParameterOffset,smb_offset(outparam,cli->outbuf));
			SIVAL(cli->outbuf,smb_nts_ParameterDisplacement,tot_param);
			SIVAL(cli->outbuf,smb_nts_DataCount,this_ldata);
			SIVAL(cli->outbuf,smb_nts_DataOffset,smb_offset(outdata,cli->outbuf));
			SIVAL(cli->outbuf,smb_nts_DataDisplacement,tot_data);
			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);

			show_msg(cli->outbuf);

			cli->mid = mid;
			if (!cli_send_smb(cli)) {
				cli_state_seqnum_remove(cli, mid);
				return False;
			}

			tot_data += this_ldata;
			tot_param += this_lparam;
		}
	}

	return(True);
}
Exemple #5
0
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);
	cli_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;
	}

	cli_state_seqnum_persistent(cli, mid);

	if (this_ldata < ldata || this_lparam < lparam) {
		/* receive interim response */
		if (!cli_receive_smb(cli) || cli_is_error(cli)) {
			cli_state_seqnum_remove(cli, mid);
			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));

			cli_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);

			show_msg(cli->outbuf);

			cli->mid = mid;
			if (!cli_send_smb(cli)) {
				cli_state_seqnum_remove(cli, mid);
				return False;
			}

			tot_data += this_ldata;
			tot_param += this_lparam;
		}
	}

	return(True);
}