diff options
author | Jeremy Allison <jra@samba.org> | 2008-11-11 10:20:24 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-11-11 10:20:24 -0800 |
commit | 4f2635b729e636e123afacb0970c3d49343b3e90 (patch) | |
tree | 76d632982f23f08b23593af78614e9414dbbac2c /source3/smbd/ipc.c | |
parent | 8cb23a6b2950d7419767845b6097470f76f348a7 (diff) | |
parent | 2e6bf03e519e180a1ee672dc9c9171d9e0cd114f (diff) | |
download | samba-4f2635b729e636e123afacb0970c3d49343b3e90.tar.gz samba-4f2635b729e636e123afacb0970c3d49343b3e90.tar.bz2 samba-4f2635b729e636e123afacb0970c3d49343b3e90.zip |
Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
Diffstat (limited to 'source3/smbd/ipc.c')
-rw-r--r-- | source3/smbd/ipc.c | 152 |
1 files changed, 78 insertions, 74 deletions
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 0ce226809e..26a4212ec9 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -81,7 +81,8 @@ static void copy_trans_params_and_data(char *outbuf, int align, Send a trans reply. ****************************************************************************/ -void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, +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) @@ -90,7 +91,6 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, int tot_data_sent = 0; int tot_param_sent = 0; int align; - char *outbuf; int ldata = rdata ? rdata_len : 0; int lparam = rparam ? rparam_len : 0; @@ -103,38 +103,43 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, align = ((this_lparam)%4); - if (!create_outbuf(talloc_tos(), (char *)inbuf, &outbuf, - 10, 1+align+this_ldata+this_lparam)) { - smb_panic("could not allocate outbuf"); - } + 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(outbuf, align, + copy_trans_params_and_data((char *)req->outbuf, align, rparam, tot_param_sent, this_lparam, rdata, tot_data_sent, this_ldata); - SSVAL(outbuf,smb_vwv0,lparam); - SSVAL(outbuf,smb_vwv1,ldata); - SSVAL(outbuf,smb_vwv3,this_lparam); - SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf)); - SSVAL(outbuf,smb_vwv5,0); - SSVAL(outbuf,smb_vwv6,this_ldata); - SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align, - outbuf)); - SSVAL(outbuf,smb_vwv8,0); - SSVAL(outbuf,smb_vwv9,0); + 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 *)outbuf, ERRDOS, ERRmoredata, + error_packet_set((char *)req->outbuf, ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW, __LINE__, __FILE__); } - show_msg(outbuf); - if (!srv_send_smb(smbd_server_fd(), (char *)outbuf, + show_msg((char *)req->outbuf); + if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, IS_CONN_ENCRYPTED(conn))) { exit_server_cleanly("send_trans_reply: srv_send_smb failed."); } - TALLOC_FREE(outbuf); + TALLOC_FREE(req->outbuf); tot_data_sent = this_ldata; tot_param_sent = this_lparam; @@ -154,39 +159,45 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, align = (this_lparam%4); - if (!create_outbuf(talloc_tos(), (char *)inbuf, &outbuf, - 10, 1+align+this_ldata+this_lparam)) { - smb_panic("could not allocate outbuf"); - } + 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(outbuf, align, + copy_trans_params_and_data((char *)req->outbuf, align, rparam, tot_param_sent, this_lparam, rdata, tot_data_sent, this_ldata); - SSVAL(outbuf,smb_vwv3,this_lparam); - SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf)); - SSVAL(outbuf,smb_vwv5,tot_param_sent); - SSVAL(outbuf,smb_vwv6,this_ldata); - SSVAL(outbuf,smb_vwv7, - smb_offset(smb_buf(outbuf)+1+this_lparam+align, outbuf)); - SSVAL(outbuf,smb_vwv8,tot_data_sent); - SSVAL(outbuf,smb_vwv9,0); + 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(outbuf, ERRDOS, ERRmoredata, + error_packet_set((char *)req->outbuf, + ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW, __LINE__, __FILE__); } - show_msg(outbuf); - if (!srv_send_smb(smbd_server_fd(), outbuf, + show_msg((char *)req->outbuf); + if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, IS_CONN_ENCRYPTED(conn))) exit_server_cleanly("send_trans_reply: srv_send_smb " "failed."); tot_data_sent += this_ldata; tot_param_sent += this_lparam; - TALLOC_FREE(outbuf); + TALLOC_FREE(req->outbuf); } } @@ -218,7 +229,7 @@ static void api_rpc_trans_reply(connection_struct *conn, return; } - send_trans_reply(conn, req->inbuf, NULL, 0, (char *)rdata, data_len, + send_trans_reply(conn, req, NULL, 0, (char *)rdata, data_len, is_data_outstanding); SAFE_FREE(rdata); return; @@ -239,7 +250,7 @@ static void api_WNPHS(connection_struct *conn, struct smb_request *req, DEBUG(4,("WaitNamedPipeHandleState priority %x\n", (int)SVAL(param,0))); - send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); + send_trans_reply(conn, req, NULL, 0, NULL, 0, False); } @@ -257,7 +268,7 @@ static void api_SNPHS(connection_struct *conn, struct smb_request *req, DEBUG(4,("SetNamedPipeHandleState to code %x\n", (int)SVAL(param,0))); - send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); + send_trans_reply(conn, req, NULL, 0, NULL, 0, False); } @@ -276,7 +287,7 @@ static void api_no_reply(connection_struct *conn, struct smb_request *req) DEBUG(3,("Unsupported API fd command\n")); /* now send the reply */ - send_trans_reply(conn, req->inbuf, rparam, 4, NULL, 0, False); + send_trans_reply(conn, req, rparam, 4, NULL, 0, False); return; } @@ -320,8 +331,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid, /* 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(conn, req->inbuf, NULL, 0, NULL, 0, - False); + send_trans_reply(conn, req, NULL, 0, NULL, 0, False); return; } @@ -506,10 +516,10 @@ void reply_trans(struct smb_request *req) size = smb_len(req->inbuf) + 4; av_size = smb_len(req->inbuf); - dsoff = SVAL(req->inbuf, smb_dsoff); - dscnt = SVAL(req->inbuf, smb_dscnt); - psoff = SVAL(req->inbuf, smb_psoff); - pscnt = SVAL(req->inbuf, smb_pscnt); + dsoff = SVAL(req->vwv+12, 0); + dscnt = SVAL(req->vwv+11, 0); + psoff = SVAL(req->vwv+10, 0); + pscnt = SVAL(req->vwv+9, 0); result = allow_new_trans(conn->pending_trans, req->mid); if (!NT_STATUS_IS_OK(result)) { @@ -531,20 +541,20 @@ void reply_trans(struct smb_request *req) state->mid = req->mid; state->vuid = req->vuid; - state->setup_count = CVAL(req->inbuf, smb_suwcnt); + state->setup_count = CVAL(req->vwv+13, 0); state->setup = NULL; - state->total_param = SVAL(req->inbuf, smb_tpscnt); + state->total_param = SVAL(req->vwv+0, 0); state->param = NULL; - state->total_data = SVAL(req->inbuf, smb_tdscnt); + state->total_data = SVAL(req->vwv+1, 0); state->data = NULL; - state->max_param_return = SVAL(req->inbuf, smb_mprcnt); - state->max_data_return = SVAL(req->inbuf, smb_mdrcnt); - state->max_setup_return = CVAL(req->inbuf, smb_msrcnt); - state->close_on_completion = BITSETW(req->inbuf+smb_vwv5,0); - state->one_way = BITSETW(req->inbuf+smb_vwv5,1); + state->max_param_return = SVAL(req->vwv+2, 0); + state->max_data_return = SVAL(req->vwv+3, 0); + state->max_setup_return = CVAL(req->vwv+4, 0); + state->close_on_completion = BITSETW(req->vwv+5, 0); + state->one_way = BITSETW(req->vwv+5, 1); - srvstr_pull_buf_talloc(state, req->inbuf, req->flags2, &state->name, - smb_buf(req->inbuf), STR_TERMINATE); + srvstr_pull_req_talloc(state, req, &state->name, req->buf, + STR_TERMINATE); if ((dscnt > state->total_data) || (pscnt > state->total_param) || !state->name) @@ -710,20 +720,20 @@ void reply_transs(struct smb_request *req) /* Revise total_params and total_data in case they have changed * downwards */ - if (SVAL(req->inbuf, smb_vwv0) < state->total_param) - state->total_param = SVAL(req->inbuf,smb_vwv0); - if (SVAL(req->inbuf, smb_vwv1) < state->total_data) - state->total_data = SVAL(req->inbuf,smb_vwv1); + if (SVAL(req->vwv+0, 0) < state->total_param) + state->total_param = SVAL(req->vwv+0, 0); + if (SVAL(req->vwv+1, 0) < state->total_data) + state->total_data = SVAL(req->vwv+1, 0); av_size = smb_len(req->inbuf); - pcnt = SVAL(req->inbuf, smb_spscnt); - poff = SVAL(req->inbuf, smb_spsoff); - pdisp = SVAL(req->inbuf, smb_spsdisp); + pcnt = SVAL(req->vwv+2, 0); + poff = SVAL(req->vwv+3, 0); + pdisp = SVAL(req->vwv+4, 0); - dcnt = SVAL(req->inbuf, smb_sdscnt); - doff = SVAL(req->inbuf, smb_sdsoff); - ddisp = SVAL(req->inbuf, smb_sdsdisp); + dcnt = SVAL(req->vwv+5, 0); + doff = SVAL(req->vwv+6, 0); + ddisp = SVAL(req->vwv+7, 0); state->received_param += pcnt; state->received_data += dcnt; @@ -776,12 +786,6 @@ void reply_transs(struct smb_request *req) return; } - /* - * construct_reply_common will copy smb_com from inbuf to - * outbuf. SMBtranss is wrong here. - */ - SCVAL(req->inbuf,smb_com,SMBtrans); - handle_trans(conn, req, state); DLIST_REMOVE(conn->pending_trans, state); |