Ok - this is the 'expose 64 bit to the clients' checkin.
authorJeremy Allison <jra@samba.org>
Fri, 11 Sep 1998 19:14:27 +0000 (19:14 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 11 Sep 1998 19:14:27 +0000 (19:14 +0000)
I have tested it by creating a 'holey' 20GB file - checking that
it shows up correctl in the NT file view (it does) and am busily
copying it to NULL: on the NT box. All good so far.... :-).

Also implemented NT 'delete on close' semantics.

Jeremy.
(This used to be commit 1654faee80648583e6a47ab7eda990fefdf85124)

source3/include/smb.h
source3/smbd/blocking.c
source3/smbd/close.c
source3/smbd/negprot.c
source3/smbd/open.c
source3/smbd/reply.c
source3/smbd/trans2.c

index 3e68f1c4ca41df23df66298e2b295970df406575..5a90f08258f840de97b9405976e9c5f57891c60b 100644 (file)
@@ -576,6 +576,7 @@ typedef struct files_struct
        BOOL granted_oplock;
        BOOL sent_oplock_break;
        BOOL is_directory;
+       BOOL delete_on_close;
        char *fsp_name;
 } files_struct;
 
index 051e276ca769554923761df2579173cc5135a28f..27a51839529a37139de7025c165d94e923411120 100644 (file)
@@ -222,7 +222,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec
       offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
                ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
     }
-#endif
+#endif /* LARGE_SMB_OFF_T */
     do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
   }
 
@@ -412,7 +412,7 @@ static BOOL process_lockingX(blocking_lock_record *blr)
       offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) |
                ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num)));
     }
-#endif
+#endif /* LARGE_SMB_OFF_T */
     errno = 0;
     if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
                 &eclass, &ecode))
index e9606cdfbeda8bde6a9a322c44fabdf2b0de34d7..981c0d77bb2a02d55c56642bea45ae81dd6329d2 100644 (file)
@@ -102,6 +102,7 @@ void close_file(files_struct *fsp, BOOL normal_close)
        SMB_DEV_T dev = fsp->fd_ptr->dev;
        SMB_INO_T inode = fsp->fd_ptr->inode;
        int token;
+    BOOL last_reference = False;
        connection_struct *conn = fsp->conn;
 
        remove_pending_lock_requests_by_fid(fsp);
@@ -118,7 +119,9 @@ void close_file(files_struct *fsp, BOOL normal_close)
        }
 
        if(fd_attempt_close(fsp->fd_ptr) == 0)
-               fsp->fd_ptr = NULL;
+               last_reference = True;
+
+    fsp->fd_ptr = NULL;
 
        if (lp_share_modes(SNUM(conn)))
                unlock_share_entry(conn, dev, inode, token);
@@ -132,6 +135,17 @@ void close_file(files_struct *fsp, BOOL normal_close)
                check_magic(fsp,conn);
        }
 
+       /*
+        * NT can set delete_on_close of the last open
+        * reference to a file.
+        */
+
+    if (normal_close && last_reference && fsp->delete_on_close) {
+               if(dos_unlink(fsp->fsp_name) != 0)
+          DEBUG(0,("close_file: file %s. Delete on close was set and unlink failed \
+with error %s\n", fsp->fsp_name, strerror(errno) ));
+    }
+
        if(fsp->granted_oplock == True)
                global_oplocks_open--;
 
index 6a9cc9fb9bd6e6faf355f6528ba5e8600b3bd061..e9dd4614c42c6a332a9072143aa8716ab48263c8 100644 (file)
@@ -157,11 +157,15 @@ static int reply_nt1(char *outbuf)
 {
   /* dual names + lock_and_read + nt SMBs + remote API calls */
   int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
-                     (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0);
+                     (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) |
+#ifdef LARGE_SMB_OFF_T
+                     (sizeof(SMB_OFF_T) == 8 ? CAP_LARGE_FILES : 0);
+#else
+                     0;
+#endif
 
 /*
   other valid capabilities which we may support at some time...
-                     CAP_LARGE_FILES|
                      CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
  */
 
index bdd4816aa71a4e30e53a49d0b1e596642dc9a1b4..42b0fba425bc43653e406ac71c6581f136714525 100644 (file)
@@ -507,6 +507,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
     fsp->granted_oplock = False;
     fsp->sent_oplock_break = False;
     fsp->is_directory = False;
+    fsp->delete_on_close = False;
     fsp->conn = conn;
     /*
      * Note that the file name here is the *untranslated* name
index 8ec2715d0dad9e54b586595506c89cd779a33f6a..e956ab6cd9393586cef55824c80f0a149ed43a22 100644 (file)
@@ -2006,14 +2006,14 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
   set_message(outbuf,12,0,True);
   data = smb_buf(outbuf);
 
-#ifdef LARGE_SMB_INO_T
+#ifdef LARGE_SMB_OFF_T
   if(SVAL(inbuf,smb_wct) == 12) {
     /*
      * This is a large offset (64 bit) read.
      */
     startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
   }
-#endif /* LARGE_SMB_INO_T */
+#endif /* LARGE_SMB_OFF_T */
 
   if (is_locked(fsp,conn,smb_maxcnt,startpos, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));
@@ -2264,14 +2264,14 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
 
   data = smb_base(inbuf) + smb_doff;
 
-#ifdef LLARGE_SMB_INO_T
+#ifdef LLARGE_SMB_OFF_T
   if(SVAL(inbuf,smb_wct) == 14) {
     /*
      * This is a large offset (64 bit) write.
      */
     startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
   }
-#endif /* LARGE_SMB_INO_T */
+#endif /* LARGE_SMB_OFF_T */
 
   if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
@@ -2408,8 +2408,8 @@ int reply_close(connection_struct *conn,
         * We can only use CHECK_FSP if we know it's not a directory.
         */
 
-       if(!(fsp && fsp->open && fsp->is_directory))
-               CHECK_FSP(fsp,conn);
+    if(!fsp || !fsp->open || (fsp->conn != conn))
+      return(ERROR(ERRDOS,ERRbadfid));
 
        if(HAS_CACHED_ERROR(fsp)) {
                eclass = fsp->wbmpx_ptr->wr_errclass;
@@ -3631,7 +3631,7 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
       offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
                ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
     }
-#endif
+#endif /* LARGE_SMB_OFF_T */
 
     DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
           (double)offset, (double)count, fsp->fsp_name ));
@@ -3661,8 +3661,8 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
       offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
                ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
     }
-#endif
-
+#endif /* LARGE_SMB_OFF_T */
     DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
           (double)offset, (double)count, fsp->fsp_name ));
 
@@ -3696,7 +3696,7 @@ dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
         offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
                  ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
       }
-#endif
+#endif /* LARGE_SMB_OFF_T */
 
       do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
     }
index 709b8daecd683bd568ebb04e629852f3d3633d3e..87d1ea27d0b199d65a2f08b7a6ee3305b0385b7b 100644 (file)
@@ -415,8 +415,8 @@ static int get_lanman2_dir_entry(connection_struct *conn,
   {
     case 1:
       if(requires_resume_key) {
-       SIVAL(p,0,reskey);
-       p += 4;
+        SIVAL(p,0,reskey);
+        p += 4;
       }
       put_dos_date2(p,l1_fdateCreation,cdate);
       put_dos_date2(p,l1_fdateLastAccess,adate);
@@ -433,8 +433,8 @@ static int get_lanman2_dir_entry(connection_struct *conn,
     case 2:
       /* info_level 2 */
       if(requires_resume_key) {
-       SIVAL(p,0,reskey);
-       p += 4;
+        SIVAL(p,0,reskey);
+        p += 4;
       }
       put_dos_date2(p,l2_fdateCreation,cdate);
       put_dos_date2(p,l2_fdateLastAccess,adate);
@@ -466,8 +466,8 @@ static int get_lanman2_dir_entry(connection_struct *conn,
 
     case 4:
       if(requires_resume_key) {
-       SIVAL(p,0,reskey);
-       p += 4;
+        SIVAL(p,0,reskey);
+        p += 4;
       }
       SIVAL(p,0,33+strlen(fname)+1);
       put_dos_date2(p,4,cdate);
@@ -492,17 +492,22 @@ static int get_lanman2_dir_entry(connection_struct *conn,
       put_long_date(p,adate); p += 8;
       put_long_date(p,mdate); p += 8;
       put_long_date(p,mdate); p += 8;
-      SIVAL(p,0,size); p += 8;
-      SIVAL(p,0,size); p += 8;
+      SIVAL(p,0,size);
+      SIVAL(p,8,size);
+#ifdef LARGE_SMB_OFF_T
+      SIVAL(p,4,size >> 32);
+      SIVAL(p,12,size >> 32);
+#endif /* LARGE_SMB_OFF_T */
+      p += 16;
       SIVAL(p,0,nt_extmode); p += 4;
       SIVAL(p,0,strlen(fname)); p += 4;
       SIVAL(p,0,0); p += 4;
       if (!was_8_3) {
-       pstrcpy(p+2,fname);
-       if (!name_map_mangle(p+2,True,SNUM(conn)))
-         (p+2)[12] = 0;
+        pstrcpy(p+2,fname);
+        if (!name_map_mangle(p+2,True,SNUM(conn)))
+          (p+2)[12] = 0;
       } else
-       *(p+2) = 0;
+        *(p+2) = 0;
       strupper(p+2);
       SSVAL(p,0,strlen(p+2));
       p += 2 + 24;
@@ -520,8 +525,13 @@ static int get_lanman2_dir_entry(connection_struct *conn,
       put_long_date(p,adate); p += 8;
       put_long_date(p,mdate); p += 8;
       put_long_date(p,mdate); p += 8;
-      SIVAL(p,0,size); p += 8;
-      SIVAL(p,0,size); p += 8;
+      SIVAL(p,0,size);
+      SIVAL(p,8,size);
+#ifdef LARGE_SMB_OFF_T
+      SIVAL(p,4,size >> 32);
+      SIVAL(p,12,size >> 32);
+#endif /* LARGE_SMB_OFF_T */
+      p += 16;
       SIVAL(p,0,nt_extmode); p += 4;
       SIVAL(p,0,strlen(fname)); p += 4;
       pstrcpy(p,fname);
@@ -538,8 +548,13 @@ static int get_lanman2_dir_entry(connection_struct *conn,
       put_long_date(p,adate); p += 8;
       put_long_date(p,mdate); p += 8;
       put_long_date(p,mdate); p += 8;
-      SIVAL(p,0,size); p += 8;
-      SIVAL(p,0,size); p += 8;
+      SIVAL(p,0,size); 
+      SIVAL(p,8,size);
+#ifdef LARGE_SMB_OFF_T
+      SIVAL(p,4,size >> 32);
+      SIVAL(p,12,size >> 32);
+#endif /* LARGE_SMB_OFF_T */
+      p += 16;
       SIVAL(p,0,nt_extmode); p += 4;
       SIVAL(p,0,strlen(fname)); p += 4;
       SIVAL(p,0,0); p += 4;
@@ -1055,6 +1070,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
 /****************************************************************************
   reply to a TRANS2_QFSINFO (query filesystem info)
 ****************************************************************************/
+
 static int call_trans2qfsinfo(connection_struct *conn, 
                              char *inbuf, char *outbuf, 
                              int length, int bufsize,
@@ -1329,6 +1345,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
       data_size = 22;
       SIVAL(pdata,0,size);
       SIVAL(pdata,8,size);
+#ifdef LARGE_SMB_OFF_T
+      SIVAL(pdata,4,size>>32);
+      SIVAL(pdata,12,size>>32);
+#endif /* LARGE_SMB_OFF_T */
       SIVAL(pdata,16,sbuf.st_nlink);
       CVAL(pdata,20) = 0;
       CVAL(pdata,21) = (mode&aDIR)?1:0;
@@ -1367,6 +1387,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
     case SMB_QUERY_FILE_END_OF_FILEINFO:
       data_size = 8;
       SIVAL(pdata,0,size);
+#ifdef LARGE_SMB_OFF_T
+      SIVAL(pdata,4,size >> 32);
+#endif /* LARGE_SMB_OFF_T */
       break;
 
     case SMB_QUERY_FILE_ALL_INFO:
@@ -1378,6 +1401,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
       pdata += 40;
       SIVAL(pdata,0,size);
       SIVAL(pdata,8,size);
+#ifdef LARGE_SMB_OFF_T
+      SIVAL(pdata,4,size >> 32);
+      SIVAL(pdata,12,size >> 32);
+#endif /* LARGE_SMB_OFF_T */
       SIVAL(pdata,16,sbuf.st_nlink);
       CVAL(pdata,20) = 0;
       CVAL(pdata,21) = (mode&aDIR)?1:0;
@@ -1385,9 +1412,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
       pdata += 8; /* index number */
       pdata += 4; /* EA info */
       if (mode & aRONLY)
-       SIVAL(pdata,0,0xA9);
+        SIVAL(pdata,0,0xA9);
       else
-       SIVAL(pdata,0,0xd01BF);
+        SIVAL(pdata,0,0xd01BF);
       pdata += 4;
       SIVAL(pdata,0,pos); /* current offset */
       pdata += 8;
@@ -1566,16 +1593,39 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
 
     case SMB_SET_FILE_END_OF_FILE_INFO:
     {
+      size = IVAL(pdata,0);
+#ifdef LARGE_SMB_OFF_T
+      size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+#else /* LARGE_SMB_OFF_T */
       if (IVAL(pdata,4) != 0)  /* more than 32 bits? */
          return(ERROR(ERRDOS,ERRunknownlevel));
-      size = IVAL(pdata,0);
+#endif /* LARGE_SMB_OFF_T */
       break;
     }
 
     case SMB_SET_FILE_ALLOCATION_INFO:
       break; /* We don't need to do anything for this call. */
 
-    case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
+    case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
+    {
+      if (tran_call == TRANSACT2_SETFILEINFO) {
+        files_struct *fsp = file_fsp(params,0);
+        if(fsp->is_directory)
+          return(ERROR(ERRDOS,ERRnoaccess));
+        /*
+         * TODO - check here is this means set
+         * this flag bit on all open files that
+         * reference this particular dev/inode pair.
+         * If so we'll need to search the open
+         * file entries here and set this flag on 
+         * all of them that match. JRA.
+         */
+        fsp->delete_on_close = CVAL(pdata,0);
+      } else
+        return(ERROR(ERRDOS,ERRunknownlevel));
+      break;
+    }
+
     default:
     {
       return(ERROR(ERRDOS,ERRunknownlevel));