s3:smbd: pass smbXsrv_connection explicitly to sendfile_short_send()
authorStefan Metzmacher <metze@samba.org>
Thu, 12 Jun 2014 06:42:16 +0000 (08:42 +0200)
committerMichael Adam <obnox@samba.org>
Wed, 6 Aug 2014 07:51:14 +0000 (09:51 +0200)
We now let the caller terminate the connection.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
source3/smbd/proto.h
source3/smbd/reply.c
source3/smbd/smb2_read.c

index 3e15be02fa5db56994bb577fe6fd020a9a28405a..453d82916974a4967c9c8794601316f1f9428048 100644 (file)
@@ -858,10 +858,11 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
 void reply_unlink(struct smb_request *req);
 ssize_t fake_sendfile(struct smbXsrv_connection *xconn, files_struct *fsp,
                      off_t startpos, size_t nread);
-void sendfile_short_send(files_struct *fsp,
-                               ssize_t nread,
-                               size_t headersize,
-                               size_t smb_maxcnt);
+ssize_t sendfile_short_send(struct smbXsrv_connection *xconn,
+                           files_struct *fsp,
+                           ssize_t nread,
+                           size_t headersize,
+                           size_t smb_maxcnt);
 void reply_readbraw(struct smb_request *req);
 void reply_lockread(struct smb_request *req);
 void reply_read(struct smb_request *req);
index 83df1044788c8cf71b024aa2de947799b4ef8f44..a92e3a7ad2372a60fb36dfc3279c8a33236f5734 100644 (file)
@@ -3088,22 +3088,21 @@ ssize_t fake_sendfile(struct smbXsrv_connection *xconn, files_struct *fsp,
 
 /****************************************************************************
  Deal with the case of sendfile reading less bytes from the file than
- requested. Fill with zeros (all we can do).
+ requested. Fill with zeros (all we can do). Returns 0 on success
 ****************************************************************************/
 
-void sendfile_short_send(files_struct *fsp,
-                               ssize_t nread,
-                               size_t headersize,
-                               size_t smb_maxcnt)
+ssize_t sendfile_short_send(struct smbXsrv_connection *xconn,
+                           files_struct *fsp,
+                           ssize_t nread,
+                           size_t headersize,
+                           size_t smb_maxcnt)
 {
-       struct smbXsrv_connection *xconn = fsp->conn->sconn->conn;
-
 #define SHORT_SEND_BUFSIZE 1024
        if (nread < headersize) {
                DEBUG(0,("sendfile_short_send: sendfile failed to send "
                        "header for file %s (%s). Terminating\n",
                        fsp_str_dbg(fsp), strerror(errno)));
-               exit_server_cleanly("sendfile_short_send failed");
+               return -1;
        }
 
        nread -= headersize;
@@ -3111,8 +3110,10 @@ void sendfile_short_send(files_struct *fsp,
        if (nread < smb_maxcnt) {
                char *buf = SMB_CALLOC_ARRAY(char, SHORT_SEND_BUFSIZE);
                if (!buf) {
-                       exit_server_cleanly("sendfile_short_send: "
-                               "malloc failed");
+                       DEBUG(0,("sendfile_short_send: malloc failed "
+                               "for file %s (%s). Terminating\n",
+                               fsp_str_dbg(fsp), strerror(errno)));
+                       return -1;
                }
 
                DEBUG(0,("sendfile_short_send: filling truncated file %s "
@@ -3149,13 +3150,14 @@ void sendfile_short_send(files_struct *fsp,
                                          smbXsrv_connection_dbg(xconn),
                                          strerror(saved_errno)));
                                errno = saved_errno;
-                               exit_server_cleanly("sendfile_short_send: "
-                                                   "write_data failed");
+                               return -1;
                        }
                        nread += to_write;
                }
                SAFE_FREE(buf);
        }
+
+       return 0;
 }
 
 /****************************************************************************
@@ -3270,7 +3272,11 @@ static void send_file_readbraw(connection_struct *conn,
 
                /* Deal with possible short send. */
                if (sendfile_read != 4+nread) {
-                       sendfile_short_send(fsp, sendfile_read, 4, nread);
+                       ret = sendfile_short_send(xconn, fsp,
+                                                 sendfile_read, 4, nread);
+                       if (ret == -1) {
+                               fail_readraw();
+                       }
                }
                return;
        }
@@ -3817,7 +3823,17 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
 
                /* Deal with possible short send. */
                if (nread != smb_maxcnt + sizeof(headerbuf)) {
-                       sendfile_short_send(fsp, nread, sizeof(headerbuf), smb_maxcnt);
+                       ssize_t ret;
+
+                       ret = sendfile_short_send(xconn, fsp, nread,
+                                                 sizeof(headerbuf), smb_maxcnt);
+                       if (ret == -1) {
+                               const char *r;
+                               r = "send_file_readX: sendfile_short_send failed";
+                               DEBUG(0,("%s for file %s (%s).\n",
+                                        r, fsp_str_dbg(fsp), strerror(errno)));
+                               exit_server_cleanly(r);
+                       }
                }
                /* No outbuf here means successful sendfile. */
                SMB_PERFCOUNT_SET_MSGLEN_OUT(&req->pcd, nread);
index 636f068c47617748bf08dada434d1e047fe40d5d..f485fe9f0b668998e20c2559b9f3be3c8847f868 100644 (file)
@@ -282,7 +282,18 @@ normal_read:
   out:
 
        if (nread < in_length) {
-               sendfile_short_send(fsp, nread, hdr->length, in_length);
+               ret = sendfile_short_send(xconn, fsp, nread,
+                                         hdr->length, in_length);
+               if (ret == -1) {
+                       saved_errno = errno;
+                       DEBUG(0,("smb2_sendfile_send_data: sendfile_short_send "
+                                "failed for file %s (%s) for client %s. "
+                                "Terminating\n",
+                                fsp_str_dbg(fsp), strerror(saved_errno),
+                                smbXsrv_connection_dbg(xconn)));
+                       exit_server_cleanly("smb2_sendfile_send_data: "
+                               "sendfile_short_send failed");
+               }
        }
 
        init_strict_lock_struct(fsp,