summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/pipes.c29
-rw-r--r--source3/smbd/process.c2
-rw-r--r--source3/smbd/reply.c61
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, &current_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;
}
/****************************************************************************