EINVAL is also a valid error return, meaning "this filesystem
[kai/samba.git] / source3 / smbd / reply.c
index f36c5c4d312b697d84938d1b5aa0ad95416da0b5..06aa835cb0e975356619dab725177c055af76a67 100644 (file)
@@ -32,7 +32,6 @@ extern int max_recv;
 unsigned int smb_echo_count = 0;
 extern uint32 global_client_caps;
 
-extern struct current_user current_user;
 extern bool global_encrypted_passwords_negotiated;
 
 /****************************************************************************
@@ -363,6 +362,37 @@ bool check_fsp(connection_struct *conn, struct smb_request *req,
        return True;
 }
 
+/****************************************************************************
+ Check if we have a correct fsp pointing to a quota fake file. Replacement for
+ the CHECK_NTQUOTA_HANDLE_OK macro.
+****************************************************************************/
+
+bool check_fsp_ntquota_handle(connection_struct *conn, struct smb_request *req,
+                             files_struct *fsp)
+{
+       if (!check_fsp_open(conn, req, fsp)) {
+               return false;
+       }
+
+       if (fsp->is_directory) {
+               return false;
+       }
+
+       if (fsp->fake_file_handle == NULL) {
+               return false;
+       }
+
+       if (fsp->fake_file_handle->type != FAKE_FILE_TYPE_QUOTA) {
+               return false;
+       }
+
+       if (fsp->fake_file_handle->private_data == NULL) {
+               return false;
+       }
+
+       return true;
+}
+
 /****************************************************************************
  Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
 ****************************************************************************/
@@ -2000,7 +2030,7 @@ void reply_mknew(struct smb_request *req)
        }
 
        ts[0] = get_atimespec(&sbuf); /* atime. */
-       status = smb_set_file_time(conn, fsp, fname, &sbuf, ts, true);
+       status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true);
        if (!NT_STATUS_IS_OK(status)) {
                END_PROFILE(SMBcreate);
                reply_openerror(req, status);
@@ -2101,7 +2131,7 @@ void reply_ctemp(struct smb_request *req)
                return;
        }
 
-       status = check_name(conn, CONST_DISCARD(char *,fname));
+       status = check_name(conn, fname);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
                END_PROFILE(SMBctemp);
@@ -2328,13 +2358,13 @@ static NTSTATUS do_unlink(connection_struct *conn,
                 &sbuf);                /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("open_file_ntcreate failed: %s\n",
+               DEBUG(10, ("create_file_unixpath failed: %s\n",
                           nt_errstr(status)));
                return status;
        }
 
        /* The set is across all open files on this dev/inode pair. */
-       if (!set_delete_on_close(fsp, True, &current_user.ut)) {
+       if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
                close_file(fsp, NORMAL_CLOSE);
                return NT_STATUS_ACCESS_DENIED;
        }
@@ -2497,7 +2527,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
                TALLOC_FREE(dir_hnd);
        }
 
-       if (count == 0 && NT_STATUS_IS_OK(status)) {
+       if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
                status = map_nt_error_from_unix(errno);
        }
 
@@ -2789,7 +2819,7 @@ void reply_readbraw(struct smb_request *req)
         */
 
        if (!fsp || !conn || conn != fsp->conn ||
-                       current_user.vuid != fsp->vuid ||
+                       req->vuid != fsp->vuid ||
                        fsp->is_directory || fsp->fh->fd == -1) {
                /*
                 * fsp could be NULL here so use the value from the packet. JRA.
@@ -3168,8 +3198,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                setup_readX_header((char *)headerbuf, smb_maxcnt);
 
                if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
-                       /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
-                       if (errno == ENOSYS) {
+                       /* Returning ENOSYS or EINVAL means no data at all was sent. 
+                          Do this as a normal read. */
+                       if (errno == ENOSYS || errno == EINVAL) {
                                goto normal_read;
                        }
 
@@ -4246,7 +4277,7 @@ void reply_close(struct smb_request *req)
         * We can only use CHECK_FSP if we know it's not a directory.
         */
 
-       if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
+       if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) {
                reply_doserror(req, ERRDOS, ERRbadfid);
                END_PROFILE(SMBclose);
                return;
@@ -4612,7 +4643,7 @@ void reply_printopen(struct smb_request *req)
        }
 
        /* Open for exclusive use, write only. */
-       status = print_fsp_open(conn, NULL, &fsp);
+       status = print_fsp_open(conn, NULL, req->vuid, &fsp);
 
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -4672,6 +4703,8 @@ void reply_printclose(struct smb_request *req)
                return;
        }
 
+       reply_outbuf(req, 0, 0);
+
        END_PROFILE(SMBsplclose);
        return;
 }
@@ -5880,7 +5913,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
        }
        TALLOC_FREE(dir_hnd);
 
-       if (count == 0 && NT_STATUS_IS_OK(status)) {
+       if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
                status = map_nt_error_from_unix(errno);
        }