diff options
-rw-r--r-- | source3/smbd/pipes.c | 29 | ||||
-rw-r--r-- | source3/smbd/process.c | 2 | ||||
-rw-r--r-- | source3/smbd/reply.c | 61 |
3 files changed, 56 insertions, 36 deletions
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index bf4567ddb9..e8a496ffa7 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -138,24 +138,24 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) Reply to a write on a pipe. ****************************************************************************/ -int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) +void reply_pipe_write(struct smb_request *req) { - smb_np_struct *p = get_rpc_pipe_p(SVAL(inbuf,smb_vwv0)); - uint16 vuid = SVAL(inbuf,smb_uid); - size_t numtowrite = SVAL(inbuf,smb_vwv1); + smb_np_struct *p = get_rpc_pipe_p(SVAL(req->inbuf,smb_vwv0)); + size_t numtowrite = SVAL(req->inbuf,smb_vwv1); int nwritten; - int outsize; char *data; if (!p) { - return(ERROR_DOS(ERRDOS,ERRbadfid)); + reply_doserror(req, ERRDOS, ERRbadfid); + return; } - if (p->vuid != vuid) { - return ERROR_NT(NT_STATUS_INVALID_HANDLE); + if (p->vuid != req->vuid) { + reply_nterror(req, NT_STATUS_INVALID_HANDLE); + return; } - data = smb_buf(inbuf) + 3; + data = smb_buf(req->inbuf) + 3; if (numtowrite == 0) { nwritten = 0; @@ -164,16 +164,17 @@ int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize) } if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0)) { - return (UNIXERROR(ERRDOS,ERRnoaccess)); + reply_unixerror(req, ERRDOS, ERRnoaccess); + return; } - - outsize = set_message(inbuf,outbuf,1,0,True); - SSVAL(outbuf,smb_vwv0,nwritten); + reply_outbuf(req, 1, 0); + + SSVAL(req->outbuf,smb_vwv0,nwritten); DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n", p->pnum, nwritten)); - return(outsize); + return; } /**************************************************************************** diff --git a/source3/smbd/process.c b/source3/smbd/process.c index fe6da4b265..c84f4b2dee 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -701,7 +701,7 @@ static const struct smb_message_struct { /* 0x08 */ { "SMBgetatr",NULL,reply_getatr,AS_USER}, /* 0x09 */ { "SMBsetatr",NULL,reply_setatr,AS_USER | NEED_WRITE}, /* 0x0a */ { "SMBread",reply_read,NULL,AS_USER}, -/* 0x0b */ { "SMBwrite",reply_write,NULL,AS_USER | CAN_IPC }, +/* 0x0b */ { "SMBwrite",NULL,reply_write,AS_USER | CAN_IPC }, /* 0x0c */ { "SMBlock",reply_lock,NULL,AS_USER}, /* 0x0d */ { "SMBunlock",reply_unlock,NULL,AS_USER}, /* 0x0e */ { "SMBctemp",NULL,reply_ctemp,AS_USER }, diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 80a2e9ff14..3805994fb5 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3400,36 +3400,51 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, Reply to a write. ****************************************************************************/ -int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize) +void reply_write(connection_struct *conn, struct smb_request *req) { size_t numtowrite; ssize_t nwritten = -1; SMB_OFF_T startpos; char *data; - files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0)); - int outsize = 0; + files_struct *fsp; NTSTATUS status; + START_PROFILE(SMBwrite); + if (req->wct < 5) { + END_PROFILE(SMBwrite); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + /* If it's an IPC, pass off the pipe handler. */ if (IS_IPC(conn)) { + reply_pipe_write(req); END_PROFILE(SMBwrite); - return reply_pipe_write(inbuf,outbuf,size,dum_buffsize); + return; + } + + fsp = file_fsp(SVAL(req->inbuf,smb_vwv0)); + + if (!check_fsp(conn, req, fsp, ¤t_user)) { + return; } - CHECK_FSP(fsp,conn); if (!CHECK_WRITE(fsp)) { + reply_doserror(req, ERRDOS, ERRbadaccess); END_PROFILE(SMBwrite); - return(ERROR_DOS(ERRDOS,ERRbadaccess)); + return; } - numtowrite = SVAL(inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2); - data = smb_buf(inbuf) + 3; + numtowrite = SVAL(req->inbuf,smb_vwv1); + startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); + data = smb_buf(req->inbuf) + 3; - if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) { + if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)numtowrite, + (SMB_BIG_UINT)startpos, WRITE_LOCK)) { + reply_doserror(req, ERRDOS, ERRlock); END_PROFILE(SMBwrite); - return ERROR_DOS(ERRDOS,ERRlock); + return; } /* @@ -3444,43 +3459,47 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d */ nwritten = vfs_allocate_file_space(fsp, (SMB_OFF_T)startpos); if (nwritten < 0) { + reply_nterror(req, NT_STATUS_DISK_FULL); END_PROFILE(SMBwrite); - return ERROR_NT(NT_STATUS_DISK_FULL); + return; } nwritten = vfs_set_filelen(fsp, (SMB_OFF_T)startpos); if (nwritten < 0) { + reply_nterror(req, NT_STATUS_DISK_FULL); END_PROFILE(SMBwrite); - return ERROR_NT(NT_STATUS_DISK_FULL); + return; } } else nwritten = write_file(fsp,data,startpos,numtowrite); status = sync_file(conn, fsp, False); if (!NT_STATUS_IS_OK(status)) { - END_PROFILE(SMBwrite); DEBUG(5,("reply_write: sync_file for %s returned %s\n", fsp->fsp_name, nt_errstr(status) )); - return ERROR_NT(status); + reply_nterror(req, status); + END_PROFILE(SMBwrite); + return; } if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { + reply_unixerror(req, ERRHRD, ERRdiskfull); END_PROFILE(SMBwrite); - return(UNIXERROR(ERRHRD,ERRdiskfull)); + return; } - outsize = set_message(inbuf,outbuf,1,0,True); + reply_outbuf(req, 1, 0); - SSVAL(outbuf,smb_vwv0,nwritten); + SSVAL(req->outbuf,smb_vwv0,nwritten); if (nwritten < (ssize_t)numtowrite) { - SCVAL(outbuf,smb_rcls,ERRHRD); - SSVAL(outbuf,smb_err,ERRdiskfull); + SCVAL(req->outbuf,smb_rcls,ERRHRD); + SSVAL(req->outbuf,smb_err,ERRdiskfull); } DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); END_PROFILE(SMBwrite); - return(outsize); + return; } /**************************************************************************** |