Looking into printer driver issues, I ran across some peculiarities in
authorDavid Disseldorp <ddiss@suse.de>
Wed, 26 Jan 2011 22:32:01 +0000 (14:32 -0800)
committerJeremy Allison <jra@samba.org>
Wed, 26 Jan 2011 23:15:18 +0000 (15:15 -0800)
copy_file():
- Firstly, if the source file is zero bytes, NT_STATUS_DISK_FULL is
  returned.
- Secondly, the conditional lseek is confusing. It fires when
  OPENX_FILE_EXISTS_OPEN is set and I can't see why the lseek is
  necessary in this case.
- Finally, the lseek error path also results in NT_STATUS_DISK_FULL.

Proposed fix for first and third point below.
(cherry picked from commit aa3bba8d778862c82e48a7c6f7bd51f5c78c7d90)

source3/smbd/reply.c

index 4d3be85a85f56699fe6f1fe1a4ae6cbf2e278922..f7265e010d40813cfdd6852b9f48e485f585f1dd 100644 (file)
@@ -6789,20 +6789,23 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                goto out;
        }
 
-       if ((ofun&3) == 1) {
-               if(SMB_VFS_LSEEK(fsp2,0,SEEK_END) == -1) {
-                       DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
-                       /*
-                        * Stop the copy from occurring.
-                        */
-                       ret = -1;
-                       smb_fname_src->st.st_ex_size = 0;
+       if (ofun & OPENX_FILE_EXISTS_OPEN) {
+               ret = SMB_VFS_LSEEK(fsp2, 0, SEEK_END);
+               if (ret == -1) {
+                       DEBUG(0, ("error - vfs lseek returned error %s\n",
+                               strerror(errno)));
+                       status = map_nt_error_from_unix(errno);
+                       close_file(NULL, fsp1, ERROR_CLOSE);
+                       close_file(NULL, fsp2, ERROR_CLOSE);
+                       goto out;
                }
        }
 
        /* Do the actual copy. */
        if (smb_fname_src->st.st_ex_size) {
                ret = vfs_transfer_file(fsp1, fsp2, smb_fname_src->st.st_ex_size);
+       } else {
+               ret = 0;
        }
 
        close_file(NULL, fsp1, NORMAL_CLOSE);