diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/process.c | 2 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 108 |
2 files changed, 53 insertions, 57 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 54a1ef17b1..0076cfcad7 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -738,7 +738,7 @@ static const struct smb_message_struct { /* 0x2f */ { "SMBwriteX",reply_write_and_X,NULL,AS_USER | CAN_IPC }, /* 0x30 */ { NULL, NULL, NULL, 0 }, /* 0x31 */ { NULL, NULL, NULL, 0 }, -/* 0x32 */ { "SMBtrans2", reply_trans2,NULL, AS_USER | CAN_IPC }, +/* 0x32 */ { "SMBtrans2", NULL,reply_trans2, AS_USER | CAN_IPC }, /* 0x33 */ { "SMBtranss2", reply_transs2,NULL, AS_USER}, /* 0x34 */ { "SMBfindclose", reply_findclose,NULL,AS_USER}, /* 0x35 */ { "SMBfindnclose", reply_findnclose,NULL, AS_USER}, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 33aa3d0036..240d45e94b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7014,67 +7014,71 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req, Reply to a SMBtrans2. ****************************************************************************/ -int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, - int size, int bufsize) +void reply_trans2(connection_struct *conn, struct smb_request *req) { - int outsize = 0; unsigned int dsoff; unsigned int dscnt; unsigned int psoff; unsigned int pscnt; unsigned int tran_call; + int size; struct trans_state *state; NTSTATUS result; START_PROFILE(SMBtrans2); - if (SVAL(inbuf, smb_wct) < 8) { + if (req->wct < 8) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBtrans2); - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return; } - dsoff = SVAL(inbuf, smb_dsoff); - dscnt = SVAL(inbuf, smb_dscnt); - psoff = SVAL(inbuf, smb_psoff); - pscnt = SVAL(inbuf, smb_pscnt); - tran_call = SVAL(inbuf, smb_setup0); + dsoff = SVAL(req->inbuf, smb_dsoff); + dscnt = SVAL(req->inbuf, smb_dscnt); + psoff = SVAL(req->inbuf, smb_psoff); + pscnt = SVAL(req->inbuf, smb_pscnt); + tran_call = SVAL(req->inbuf, smb_setup0); + size = smb_len(req->inbuf) + 4; - result = allow_new_trans(conn->pending_trans, SVAL(inbuf, smb_mid)); + result = allow_new_trans(conn->pending_trans, req->mid); if (!NT_STATUS_IS_OK(result)) { DEBUG(2, ("Got invalid trans2 request: %s\n", nt_errstr(result))); + reply_nterror(req, result); END_PROFILE(SMBtrans2); - return ERROR_NT(result); + return; } if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN) && (tran_call != TRANSACT2_GET_DFS_REFERRAL) && (tran_call != TRANSACT2_QFILEINFO)) { + reply_doserror(req, ERRSRV, ERRaccess); END_PROFILE(SMBtrans2); - return ERROR_DOS(ERRSRV,ERRaccess); + return; } if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) { DEBUG(0, ("talloc failed\n")); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBtrans2); - return ERROR_NT(NT_STATUS_NO_MEMORY); + return; } state->cmd = SMBtrans2; - state->mid = SVAL(inbuf, smb_mid); - state->vuid = SVAL(inbuf, smb_uid); - state->setup_count = SVAL(inbuf, smb_suwcnt); + state->mid = req->mid; + state->vuid = req->vuid; + state->setup_count = SVAL(req->inbuf, smb_suwcnt); state->setup = NULL; - state->total_param = SVAL(inbuf, smb_tpscnt); + state->total_param = SVAL(req->inbuf, smb_tpscnt); state->param = NULL; - state->total_data = SVAL(inbuf, smb_tdscnt); + state->total_data = SVAL(req->inbuf, smb_tdscnt); state->data = NULL; - state->max_param_return = SVAL(inbuf, smb_mprcnt); - state->max_data_return = SVAL(inbuf, smb_mdrcnt); - state->max_setup_return = SVAL(inbuf, smb_msrcnt); - state->close_on_completion = BITSETW(inbuf+smb_vwv5,0); - state->one_way = BITSETW(inbuf+smb_vwv5,1); + state->max_param_return = SVAL(req->inbuf, smb_mprcnt); + state->max_data_return = SVAL(req->inbuf, smb_mdrcnt); + state->max_setup_return = SVAL(req->inbuf, smb_msrcnt); + state->close_on_completion = BITSETW(req->inbuf+smb_vwv5,0); + state->one_way = BITSETW(req->inbuf+smb_vwv5,1); state->call = tran_call; @@ -7089,16 +7093,18 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, * Until DosPrintSetJobInfo with PRJINFO3 is supported, * outbuf doesn't have to be set(only job id is used). */ - if ( (state->setup_count == 4) && (tran_call == TRANSACT2_IOCTL) && - (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) && - (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { + if ( (state->setup_count == 4) + && (tran_call == TRANSACT2_IOCTL) + && (SVAL(req->inbuf,(smb_setup+4)) == LMCAT_SPL) + && (SVAL(req->inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { DEBUG(2,("Got Trans2 DevIOctl jobid\n")); } else { DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count)); DEBUG(2,("Transaction is %d\n",tran_call)); TALLOC_FREE(state); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBtrans2); - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return; } } @@ -7113,16 +7119,18 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, DEBUG(0,("reply_trans2: data malloc fail for %u " "bytes !\n", (unsigned int)state->total_data)); TALLOC_FREE(state); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBtrans2); - return(ERROR_DOS(ERRDOS,ERRnomem)); + return; } if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt)) goto bad_param; - if ((smb_base(inbuf)+dsoff+dscnt > inbuf + size) || - (smb_base(inbuf)+dsoff+dscnt < smb_base(inbuf))) + if ((smb_base(req->inbuf)+dsoff+dscnt + > (char *)req->inbuf + size) || + (smb_base(req->inbuf)+dsoff+dscnt < smb_base(req->inbuf))) goto bad_param; - memcpy(state->data,smb_base(inbuf)+dsoff,dscnt); + memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt); } if (state->total_param) { @@ -7134,16 +7142,18 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, "bytes !\n", (unsigned int)state->total_param)); SAFE_FREE(state->data); TALLOC_FREE(state); + reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBtrans2); - return(ERROR_DOS(ERRDOS,ERRnomem)); + return; } if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt)) goto bad_param; - if ((smb_base(inbuf)+psoff+pscnt > inbuf + size) || - (smb_base(inbuf)+psoff+pscnt < smb_base(inbuf))) + if ((smb_base(req->inbuf)+psoff+pscnt + > (char *)req->inbuf + size) || + (smb_base(req->inbuf)+psoff+pscnt < smb_base(req->inbuf))) goto bad_param; - memcpy(state->param,smb_base(inbuf)+psoff,pscnt); + memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt); } state->received_data = dscnt; @@ -7152,37 +7162,23 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, if ((state->received_param == state->total_param) && (state->received_data == state->total_data)) { - struct smb_request *req; - - if (!(req = talloc(tmp_talloc_ctx(), struct smb_request))) { - END_PROFILE(SMBtrans2); - return ERROR_NT(NT_STATUS_NO_MEMORY); - } - - init_smb_request(req, (uint8 *)inbuf); - - outsize = -1; handle_trans2(conn, req, state); - if (req->outbuf != NULL) { - outsize = smb_len(req->outbuf) + 4; - memcpy(outbuf, req->outbuf, outsize); - } - TALLOC_FREE(req); + SAFE_FREE(state->data); SAFE_FREE(state->param); TALLOC_FREE(state); END_PROFILE(SMBtrans2); - return outsize; + return; } DLIST_ADD(conn->pending_trans, state); /* We need to send an interim response then receive the rest of the parameter/data bytes */ - outsize = set_message(inbuf, outbuf,0,0,False); - show_msg(outbuf); + reply_outbuf(req, 0, 0); + show_msg((char *)req->outbuf); END_PROFILE(SMBtrans2); - return outsize; + return; bad_param: @@ -7191,7 +7187,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf, SAFE_FREE(state->param); TALLOC_FREE(state); END_PROFILE(SMBtrans2); - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); } |