diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/reply.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 93e2aaf0be..9119ec1e0b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2333,9 +2333,22 @@ static void fail_readraw(void) Fake (read/write) sendfile. Returns -1 on read or write fail. ****************************************************************************/ -static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, size_t bufsize) +static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, + size_t nread) { + size_t bufsize; size_t tosend = nread; + char *buf; + + if (nread == 0) { + return 0; + } + + bufsize = MIN(nread, 65536); + + if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) { + return -1; + } while (tosend > 0) { ssize_t ret; @@ -2348,6 +2361,7 @@ static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread } ret = read_file(fsp,buf,startpos,cur_read); if (ret == -1) { + SAFE_FREE(buf); return -1; } @@ -2357,12 +2371,14 @@ static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread } if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) { + SAFE_FREE(buf); return -1; } tosend -= cur_read; startpos += cur_read; } + SAFE_FREE(buf); return (ssize_t)nread; } @@ -2408,7 +2424,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st set_use_sendfile(SNUM(conn), False); DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n")); - if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) { + if (fake_sendfile(fsp, startpos, nread) == -1) { DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n", fsp->fsp_name, strerror(errno) )); exit_server_cleanly("send_file_readbraw fake_sendfile failed"); @@ -2806,9 +2822,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, /* Ensure we don't do this again. */ set_use_sendfile(SNUM(conn), False); DEBUG(0,("send_file_readX: sendfile not available. Faking..\n")); - - if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data, - len_outbuf - (data-outbuf))) == -1) { + nread = fake_sendfile(fsp, startpos, + smb_maxcnt); + if (nread == -1) { DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n", fsp->fsp_name, strerror(errno) )); exit_server_cleanly("send_file_readX: fake_sendfile failed"); @@ -2844,8 +2860,8 @@ normal_read: fsp->fsp_name, strerror(errno) )); exit_server_cleanly("send_file_readX sendfile failed"); } - if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data, - len_outbuf - (data-outbuf))) == -1) { + nread = fake_sendfile(fsp, startpos, smb_maxcnt); + if (nread == -1) { DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n", fsp->fsp_name, strerror(errno) )); exit_server_cleanly("send_file_readX: fake_sendfile failed"); |