Ensure the RECVFILE path in vfs_write_data() operates on a blocking socket.
authorJeremy Allison <jra@samba.org>
Mon, 8 Apr 2013 17:32:10 +0000 (10:32 -0700)
committerKarolin Seeger <kseeger@samba.org>
Thu, 25 Apr 2013 10:50:59 +0000 (12:50 +0200)
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Stefan (metze) Metzmacher <metze@samba.org>
(cherry picked from commit 1ed710c2ffc91d8b33b87e572a6075e0126b5826)

source3/smbd/vfs.c

index 581a02567ec09342b7c0056b197ebe39afe1b57e..30899ef5f50b811f75ca4481b10c19db1f5a90ca 100644 (file)
@@ -428,14 +428,25 @@ ssize_t vfs_write_data(struct smb_request *req,
        ssize_t ret;
 
        if (req && req->unread_bytes) {
+               int sockfd = req->sconn->sock;
+               int old_flags;
                SMB_ASSERT(req->unread_bytes == N);
                /* VFS_RECVFILE must drain the socket
                 * before returning. */
                req->unread_bytes = 0;
-               return SMB_VFS_RECVFILE(req->sconn->sock,
+               /* Ensure the socket is blocking. */
+               old_flags = fcntl(sockfd, F_GETFL, 0);
+               if (set_blocking(sockfd, true) == -1) {
+                       return (ssize_t)-1;
+               }
+               ret = SMB_VFS_RECVFILE(sockfd,
                                        fsp,
                                        (off_t)-1,
                                        N);
+               if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
+                       return (ssize_t)-1;
+               }
+               return ret;
        }
 
        while (total < N) {