vfs3: Pass "lease" through SMB_VFS_CREATE_FILE
[metze/samba/wip.git] / source3 / smbd / reply.c
index 5371537b05f193129544fec6acb6d7398925fc5e..4cb446fb23e6aa24418018ccdaadd530ffff9d12 100644 (file)
@@ -693,8 +693,8 @@ void reply_tcon(struct smb_request *req)
        const uint8_t *p;
        const char *p2;
        TALLOC_CTX *ctx = talloc_tos();
-       struct smbd_server_connection *sconn = req->sconn;
-       struct smbXsrv_connection *xconn = sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
+       struct smbd_server_connection *sconn = xconn->sconn;
        NTTIME now = timeval_to_nttime(&req->request_time);
 
        START_PROFILE(SMBtcon);
@@ -771,8 +771,8 @@ void reply_tcon_and_X(struct smb_request *req)
        NTTIME now = timeval_to_nttime(&req->request_time);
        bool session_key_updated = false;
        uint16_t optional_support = 0;
-       struct smbd_server_connection *sconn = req->sconn;
-       struct smbXsrv_connection *xconn = sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
+       struct smbd_server_connection *sconn = xconn->sconn;
 
        START_PROFILE(SMBtconX);
 
@@ -862,7 +862,7 @@ void reply_tcon_and_X(struct smb_request *req)
 
        DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
 
-       nt_status = smb1srv_session_lookup(req->sconn->conn,
+       nt_status = smb1srv_session_lookup(xconn,
                                           req->vuid, now, &session);
        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_USER_SESSION_DELETED)) {
                reply_force_doserror(req, ERRSRV, ERRbaduid);
@@ -1555,8 +1555,8 @@ void reply_search(struct smb_request *req)
        TALLOC_CTX *ctx = talloc_tos();
        bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
        struct dptr_struct *dirptr = NULL;
-       struct smbd_server_connection *sconn = req->sconn;
-       struct smbXsrv_connection *xconn = sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
+       struct smbd_server_connection *sconn = xconn->sconn;
 
        START_PROFILE(SMBsearch);
 
@@ -1948,6 +1948,7 @@ void reply_open(struct smb_request *req)
                create_options,                         /* create_options */
                dos_attr,                               /* file_attributes */
                oplock_request,                         /* oplock_request */
+               NULL,                                   /* lease */
                0,                                      /* allocation_size */
                private_flags,
                NULL,                                   /* sd */
@@ -2116,6 +2117,7 @@ void reply_open_and_X(struct smb_request *req)
                create_options,                         /* create_options */
                smb_attr,                               /* file_attributes */
                oplock_request,                         /* oplock_request */
+               NULL,                                   /* lease */
                0,                                      /* allocation_size */
                private_flags,
                NULL,                                   /* sd */
@@ -2363,6 +2365,7 @@ void reply_mknew(struct smb_request *req)
                create_options,                         /* create_options */
                fattr,                                  /* file_attributes */
                oplock_request,                         /* oplock_request */
+               NULL,                                   /* lease */
                0,                                      /* allocation_size */
                0,                                      /* private_flags */
                NULL,                                   /* sd */
@@ -2490,6 +2493,7 @@ void reply_ctemp(struct smb_request *req)
                        0,                                      /* create_options */
                        fattr,                                  /* file_attributes */
                        oplock_request,                         /* oplock_request */
+                       NULL,                                   /* lease */
                        0,                                      /* allocation_size */
                        0,                                      /* private_flags */
                        NULL,                                   /* sd */
@@ -2707,6 +2711,7 @@ static NTSTATUS do_unlink(connection_struct *conn,
                 posix_paths ? FILE_FLAG_POSIX_SEMANTICS|0777 :
                                FILE_ATTRIBUTE_NORMAL,
                 0,                     /* oplock_request */
+                NULL,                  /* lease */
                 0,                     /* allocation_size */
                 0,                     /* private_flags */
                 NULL,                  /* sd */
@@ -3026,9 +3031,9 @@ static void fail_readraw(void)
  Fake (read/write) sendfile. Returns -1 on read or write fail.
 ****************************************************************************/
 
-ssize_t fake_sendfile(files_struct *fsp, off_t startpos, size_t nread)
+ssize_t fake_sendfile(struct smbXsrv_connection *xconn, files_struct *fsp,
+                     off_t startpos, size_t nread)
 {
-       struct smbXsrv_connection *xconn = fsp->conn->sconn->conn;
        size_t bufsize;
        size_t tosend = nread;
        char *buf;
@@ -3088,22 +3093,21 @@ ssize_t fake_sendfile(files_struct *fsp, off_t startpos, size_t nread)
 
 /****************************************************************************
  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 +3115,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,27 +3155,27 @@ 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;
 }
 
 /****************************************************************************
  Return a readbraw error (4 bytes of zero).
 ****************************************************************************/
 
-static void reply_readbraw_error(struct smbd_server_connection *sconn)
+static void reply_readbraw_error(struct smbXsrv_connection *xconn)
 {
-       struct smbXsrv_connection *xconn = sconn->conn;
        char header[4];
 
        SIVAL(header,0,0);
 
-       smbd_lock_socket(sconn);
+       smbd_lock_socket(xconn);
        if (write_data(xconn->transport.sock,header,4) != 4) {
                int saved_errno = errno;
                /*
@@ -3184,7 +3190,7 @@ static void reply_readbraw_error(struct smbd_server_connection *sconn)
 
                fail_readraw();
        }
-       smbd_unlock_socket(sconn);
+       smbd_unlock_socket(xconn);
 }
 
 /****************************************************************************
@@ -3198,8 +3204,7 @@ static void send_file_readbraw(connection_struct *conn,
                               size_t nread,
                               ssize_t mincount)
 {
-       struct smbd_server_connection *sconn = req->sconn;
-       struct smbXsrv_connection *xconn = sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
        char *outbuf = NULL;
        ssize_t ret=0;
 
@@ -3240,7 +3245,7 @@ static void send_file_readbraw(connection_struct *conn,
                                set_use_sendfile(SNUM(conn), False);
                                DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
 
-                               if (fake_sendfile(fsp, startpos, nread) == -1) {
+                               if (fake_sendfile(xconn, fsp, startpos, nread) == -1) {
                                        DEBUG(0,("send_file_readbraw: "
                                                 "fake_sendfile failed for "
                                                 "file %s (%s).\n",
@@ -3271,7 +3276,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;
        }
@@ -3282,7 +3291,7 @@ normal_readbraw:
        if (!outbuf) {
                DEBUG(0,("send_file_readbraw: talloc_array failed for size %u.\n",
                        (unsigned)(nread+4)));
-               reply_readbraw_error(sconn);
+               reply_readbraw_error(xconn);
                return;
        }
 
@@ -3322,8 +3331,7 @@ normal_readbraw:
 void reply_readbraw(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
-       struct smbd_server_connection *sconn = req->sconn;
-       struct smbXsrv_connection *xconn = sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
        ssize_t maxcount,mincount;
        size_t nread = 0;
        off_t startpos;
@@ -3339,7 +3347,7 @@ void reply_readbraw(struct smb_request *req)
        }
 
        if (req->wct < 8) {
-               reply_readbraw_error(sconn);
+               reply_readbraw_error(xconn);
                END_PROFILE(SMBreadbraw);
                return;
        }
@@ -3347,7 +3355,7 @@ void reply_readbraw(struct smb_request *req)
        if (xconn->smb1.echo_handler.trusted_fde) {
                DEBUG(2,("SMBreadbraw rejected with NOT_SUPPORTED because of "
                         "'async smb echo handler = yes'\n"));
-               reply_readbraw_error(sconn);
+               reply_readbraw_error(xconn);
                END_PROFILE(SMBreadbraw);
                return;
        }
@@ -3375,7 +3383,7 @@ void reply_readbraw(struct smb_request *req)
                DEBUG(3,("reply_readbraw: fnum %d not valid "
                        "- cache prime?\n",
                        (int)SVAL(req->vwv+0, 0)));
-               reply_readbraw_error(sconn);
+               reply_readbraw_error(xconn);
                END_PROFILE(SMBreadbraw);
                return;
        }
@@ -3386,7 +3394,7 @@ void reply_readbraw(struct smb_request *req)
                                (fsp->access_mask & FILE_EXECUTE)))) {
                DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
                                (int)SVAL(req->vwv+0, 0)));
-               reply_readbraw_error(sconn);
+               reply_readbraw_error(xconn);
                END_PROFILE(SMBreadbraw);
                return;
        }
@@ -3405,7 +3413,7 @@ void reply_readbraw(struct smb_request *req)
                        DEBUG(0,("reply_readbraw: negative 64 bit "
                                "readraw offset (%.0f) !\n",
                                (double)startpos ));
-                       reply_readbraw_error(sconn);
+                       reply_readbraw_error(xconn);
                        END_PROFILE(SMBreadbraw);
                        return;
                }
@@ -3422,7 +3430,7 @@ void reply_readbraw(struct smb_request *req)
            &lock);
 
        if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
-               reply_readbraw_error(sconn);
+               reply_readbraw_error(xconn);
                END_PROFILE(SMBreadbraw);
                return;
        }
@@ -3478,8 +3486,7 @@ void reply_lockread(struct smb_request *req)
        files_struct *fsp;
        struct byte_range_lock *br_lck = NULL;
        char *p = NULL;
-       struct smbd_server_connection *sconn = req->sconn;
-       struct smbXsrv_connection *xconn = sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
 
        START_PROFILE(SMBlockread);
 
@@ -3588,8 +3595,7 @@ void reply_read(struct smb_request *req)
        off_t startpos;
        files_struct *fsp;
        struct lock_struct lock;
-       struct smbd_server_connection *sconn = req->sconn;
-       struct smbXsrv_connection *xconn = sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
 
        START_PROFILE(SMBread);
 
@@ -3703,7 +3709,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                            files_struct *fsp, off_t startpos,
                            size_t smb_maxcnt)
 {
-       struct smbXsrv_connection *xconn = req->sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
        ssize_t nread = -1;
        struct lock_struct lock;
        int saved_errno = 0;
@@ -3778,7 +3784,7 @@ 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"));
-                               nread = fake_sendfile(fsp, startpos,
+                               nread = fake_sendfile(xconn, fsp, startpos,
                                                      smb_maxcnt);
                                if (nread == -1) {
                                        saved_errno = errno;
@@ -3821,7 +3827,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);
@@ -3855,7 +3871,7 @@ normal_read:
                        errno = saved_errno;
                        exit_server_cleanly("send_file_readX sendfile failed");
                }
-               nread = fake_sendfile(fsp, startpos, smb_maxcnt);
+               nread = fake_sendfile(xconn, fsp, startpos, smb_maxcnt);
                if (nread == -1) {
                        saved_errno = errno;
                        DEBUG(0,("send_file_readX: fake_sendfile failed for file "
@@ -3903,9 +3919,9 @@ nosendfile_read:
 
 static size_t calc_max_read_pdu(const struct smb_request *req)
 {
-       struct smbXsrv_connection *xconn = req->sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
 
-       if (req->sconn->conn->protocol < PROTOCOL_NT1) {
+       if (xconn->protocol < PROTOCOL_NT1) {
                return xconn->smb1.sessions.max_send;
        }
 
@@ -3949,6 +3965,7 @@ static size_t calc_read_size(const struct smb_request *req,
                             size_t upper_size,
                             size_t lower_size)
 {
+       struct smbXsrv_connection *xconn = req->xconn;
        size_t max_pdu = calc_max_read_pdu(req);
        size_t total_size = 0;
        size_t hdr_len = MIN_SMB_SIZE + VWV(12);
@@ -3964,7 +3981,7 @@ static size_t calc_read_size(const struct smb_request *req,
                upper_size = 0;
        }
 
-       if (req->sconn->conn->protocol < PROTOCOL_NT1) {
+       if (xconn->protocol < PROTOCOL_NT1) {
                upper_size = 0;
        }
 
@@ -4060,9 +4077,9 @@ void reply_read_and_X(struct smb_request *req)
                /* NT_STATUS_RETRY - fall back to sync read. */
        }
 
-       smbd_lock_socket(req->sconn);
+       smbd_lock_socket(req->xconn);
        send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
-       smbd_unlock_socket(req->sconn);
+       smbd_unlock_socket(req->xconn);
 
  out:
        END_PROFILE(SMBreadX);
@@ -4127,7 +4144,7 @@ static NTSTATUS read_smb_length(int fd, char *inbuf, unsigned int timeout,
 void reply_writebraw(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
-       struct smbXsrv_connection *xconn = req->sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
        char *buf = NULL;
        ssize_t nwritten=0;
        ssize_t total_written=0;
@@ -4719,7 +4736,7 @@ bool is_valid_writeX_buffer(struct smbXsrv_connection *xconn,
 void reply_write_and_X(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
-       struct smbXsrv_connection *xconn = req->sconn->conn;
+       struct smbXsrv_connection *xconn = req->xconn;
        files_struct *fsp;
        struct lock_struct lock;
        off_t startpos;
@@ -5956,6 +5973,7 @@ void reply_rmdir(struct smb_request *req)
                FILE_DIRECTORY_FILE,                    /* create_options */
                FILE_ATTRIBUTE_DIRECTORY,               /* file_attributes */
                0,                                      /* oplock_request */
+               NULL,                                   /* lease */
                0,                                      /* allocation_size */
                0,                                      /* private_flags */
                NULL,                                   /* sd */
@@ -6723,6 +6741,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        create_options,                 /* create_options */
                        posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
                        0,                              /* oplock_request */
+                       NULL,                           /* lease */
                        0,                              /* allocation_size */
                        0,                              /* private_flags */
                        NULL,                           /* sd */
@@ -6869,6 +6888,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        create_options,                 /* create_options */
                        posix_pathnames ? FILE_FLAG_POSIX_SEMANTICS|0777 : 0, /* file_attributes */
                        0,                              /* oplock_request */
+                       NULL,                           /* lease */
                        0,                              /* allocation_size */
                        0,                              /* private_flags */
                        NULL,                           /* sd */
@@ -7138,6 +7158,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                0,                                      /* create_options */
                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               NULL,                                   /* lease */
                0,                                      /* allocation_size */
                0,                                      /* private_flags */
                NULL,                                   /* sd */
@@ -7167,6 +7188,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                0,                                      /* create_options */
                dosattrs,                               /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               NULL,                                   /* lease */
                0,                                      /* allocation_size */
                0,                                      /* private_flags */
                NULL,                                   /* sd */