diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/process.c | 2 | ||||
-rw-r--r-- | source3/smbd/reply.c | 59 |
2 files changed, 41 insertions, 20 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c index c84f4b2dee..e05a941542 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -700,7 +700,7 @@ static const struct smb_message_struct { /* 0x07 */ { "SMBmv",NULL,reply_mv,AS_USER | NEED_WRITE }, /* 0x08 */ { "SMBgetatr",NULL,reply_getatr,AS_USER}, /* 0x09 */ { "SMBsetatr",NULL,reply_setatr,AS_USER | NEED_WRITE}, -/* 0x0a */ { "SMBread",reply_read,NULL,AS_USER}, +/* 0x0a */ { "SMBread",NULL,reply_read,AS_USER}, /* 0x0b */ { "SMBwrite",NULL,reply_write,AS_USER | CAN_IPC }, /* 0x0c */ { "SMBlock",reply_lock,NULL,AS_USER}, /* 0x0d */ { "SMBunlock",reply_unlock,NULL,AS_USER}, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 3805994fb5..37d13bfa96 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2828,26 +2828,41 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", Reply to a read. ****************************************************************************/ -int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize) +void reply_read(connection_struct *conn, struct smb_request *req) { size_t numtoread; ssize_t nread = 0; char *data; SMB_OFF_T startpos; int outsize = 0; - files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0)); + files_struct *fsp; + START_PROFILE(SMBread); - CHECK_FSP(fsp,conn); - if (!CHECK_READ(fsp,inbuf)) { - return(ERROR_DOS(ERRDOS,ERRbadaccess)); + if (req->wct < 3) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + END_PROFILE(SMBread); + return; } - numtoread = SVAL(inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); + fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + + if (!check_fsp(conn, req, fsp, ¤t_user)) { + END_PROFILE(SMBread); + return; + } + + if (!CHECK_READ(fsp,req->inbuf)) { + reply_doserror(req, ERRDOS, ERRbadaccess); + END_PROFILE(SMBread); + return; + } + + numtoread = SVAL(req->inbuf,smb_vwv1); + startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); - outsize = set_message(inbuf,outbuf,5,3,True); numtoread = MIN(BUFFER_SIZE-outsize,numtoread); + /* * The requested read size cannot be greater than max_recv. JRA. */ @@ -2858,32 +2873,38 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n", numtoread = MIN(numtoread,max_recv); } - data = smb_buf(outbuf) + 3; + reply_outbuf(req, 5, numtoread+3); + + data = smb_buf(req->outbuf) + 3; - if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) { + if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtoread, + (SMB_BIG_UINT)startpos, READ_LOCK)) { + reply_doserror(req, ERRDOS,ERRlock); END_PROFILE(SMBread); - return ERROR_DOS(ERRDOS,ERRlock); + return; } if (numtoread > 0) nread = read_file(fsp,data,startpos,numtoread); if (nread < 0) { + reply_unixerror(req, ERRDOS,ERRnoaccess); END_PROFILE(SMBread); - return(UNIXERROR(ERRDOS,ERRnoaccess)); + return; } - - outsize += nread; - SSVAL(outbuf,smb_vwv0,nread); - SSVAL(outbuf,smb_vwv5,nread+3); - SCVAL(smb_buf(outbuf),0,1); - SSVAL(smb_buf(outbuf),1,nread); + + set_message(NULL, (char *)req->outbuf, 5, nread+3, False); + + SSVAL(req->outbuf,smb_vwv0,nread); + SSVAL(req->outbuf,smb_vwv5,nread+3); + SCVAL(smb_buf(req->outbuf),0,1); + SSVAL(smb_buf(req->outbuf),1,nread); DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n", fsp->fnum, (int)numtoread, (int)nread ) ); END_PROFILE(SMBread); - return(outsize); + return; } /**************************************************************************** |