X-Git-Url: http://git.samba.org/samba.git/?p=tprouty%2Fsamba.git;a=blobdiff_plain;f=source%2Fsmbd%2Fipc.c;h=9fcd39b5002caa932a0ebbcd3163ec055fa6d42f;hp=39072f9b91285fd30a8c88cc942940351d5da694;hb=620f2e608f70ba92f032720c031283d295c5c06a;hpb=3a789cb7f01115c37404e5a696de363287cb0e5f diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 39072f9b91..9fcd39b500 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -96,7 +96,7 @@ void send_trans_reply(char *outbuf, align = ((this_lparam)%4); if (buffer_too_large) { - ERROR_NT(STATUS_BUFFER_OVERFLOW); + ERROR_BOTH(STATUS_BUFFER_OVERFLOW,ERRDOS,ERRmoredata); } set_message(outbuf,10,1+align+this_ldata+this_lparam,True); @@ -165,7 +165,7 @@ void send_trans_reply(char *outbuf, static BOOL api_rpc_trans_reply(char *outbuf, smb_np_struct *p) { BOOL is_data_outstanding; - char *rdata = malloc(p->max_trans_reply); + char *rdata = SMB_MALLOC(p->max_trans_reply); int data_len; if(rdata == NULL) { @@ -281,11 +281,19 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf, subcommand = ((int)setup[0]) & 0xFFFF; if(!(p = get_rpc_pipe(pnum))) { + if (subcommand == TRANSACT_WAITNAMEDPIPEHANDLESTATE) { + /* Win9x does this call with a unicode pipe name, not a pnum. */ + /* Just return success for now... */ + DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n")); + send_trans_reply(outbuf, NULL, 0, NULL, 0, False); + return -1; + } + DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum)); return api_no_reply(outbuf, mdrcnt); } - DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", subcommand, p->name, pnum)); + DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", subcommand, p->name, pnum)); /* record maximum data length that can be transmitted in an SMBtrans */ p->max_trans_reply = mdrcnt; @@ -381,29 +389,31 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int goto bad_param; if (tdscnt) { - if((data = (char *)malloc(tdscnt)) == NULL) { + if((data = (char *)SMB_MALLOC(tdscnt)) == NULL) { DEBUG(0,("reply_trans: data malloc fail for %u bytes !\n", tdscnt)); END_PROFILE(SMBtrans); return(ERROR_DOS(ERRDOS,ERRnomem)); } if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt)) goto bad_param; - if (smb_base(inbuf)+dsoff+dscnt > inbuf + size) + if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) || + (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf))) goto bad_param; memcpy(data,smb_base(inbuf)+dsoff,dscnt); } if (tpscnt) { - if((params = (char *)malloc(tpscnt)) == NULL) { + if((params = (char *)SMB_MALLOC(tpscnt)) == NULL) { DEBUG(0,("reply_trans: param malloc fail for %u bytes !\n", tpscnt)); SAFE_FREE(data); END_PROFILE(SMBtrans); return(ERROR_DOS(ERRDOS,ERRnomem)); } if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt)) - goto bad_param; - if (smb_base(inbuf)+psoff+pscnt > inbuf + size) + goto bad_param; + if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) || + (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf))) goto bad_param; memcpy(params,smb_base(inbuf)+psoff,pscnt); @@ -411,7 +421,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int if (suwcnt) { unsigned int i; - if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) { + if((setup = SMB_MALLOC_ARRAY(uint16,suwcnt)) == NULL) { DEBUG(0,("reply_trans: setup malloc fail for %u bytes !\n", (unsigned int)(suwcnt * sizeof(uint16)))); SAFE_FREE(data); SAFE_FREE(params); @@ -435,6 +445,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int of the parameter/data bytes */ outsize = set_message(outbuf,0,0,True); show_msg(outbuf); + srv_signing_trans_stop(); if (!send_smb(smbd_server_fd(),outbuf)) exit_server("reply_trans: send_smb failed."); } @@ -446,6 +457,13 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT); + /* + * The sequence number for the trans reply is always + * based on the last secondary received. + */ + + srv_signing_trans_start(SVAL(inbuf,smb_mid)); + if ((ret && (CVAL(inbuf, smb_com) != SMBtranss)) || !ret) { if(ret) { DEBUG(0,("reply_trans: Invalid secondary trans packet\n")); @@ -484,11 +502,14 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int goto bad_param; if (pcnt) { - if (pdisp+pcnt >= tpscnt) + if (pdisp+pcnt > tpscnt) goto bad_param; if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt)) - goto bad_param; - if (smb_base(inbuf) + poff + pcnt >= inbuf + bufsize) + goto bad_param; + if (pdisp > tpscnt) + goto bad_param; + if ((smb_base(inbuf) + poff + pcnt >= inbuf + bufsize) || + (smb_base(inbuf) + poff + pcnt < smb_base(inbuf))) goto bad_param; if (params + pdisp < params) goto bad_param; @@ -497,11 +518,14 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int } if (dcnt) { - if (ddisp+dcnt >= tdscnt) + if (ddisp+dcnt > tdscnt) goto bad_param; if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt)) goto bad_param; - if (smb_base(inbuf) + doff + dcnt >= inbuf + bufsize) + if (ddisp > tdscnt) + goto bad_param; + if ((smb_base(inbuf) + doff + dcnt >= inbuf + bufsize) || + (smb_base(inbuf) + doff + dcnt < smb_base(inbuf))) goto bad_param; if (data + ddisp < data) goto bad_param;