Make us bug-for-bug compatible with W2K3 - to get delete on close semantics
authorJeremy Allison <jra@samba.org>
Fri, 20 Feb 2004 22:45:53 +0000 (22:45 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 20 Feb 2004 22:45:53 +0000 (22:45 +0000)
on an initial open the desired_access field *must* contain DELETE_ACCESS,
simply having it map from a GENERIC_ALL won't do. Fixes delete on close test.
Jeremy.
(This used to be commit 5c6f8b1053fd1f170fbb76640649653f8aa80f18)

source3/libsmb/clirap.c
source3/smbd/nttrans.c
source3/torture/torture.c

index 36bc403e0b4a44cb89335a098cff87baf2f9cb28..c4b08d21d817b5fd0a6ce07cc483799a89f13661 100644 (file)
@@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
 /****************************************************************************
 send a qfileinfo call
 ****************************************************************************/
-BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata)
+BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen)
 {
        unsigned int data_len = 0;
        unsigned int param_len = 0;
@@ -639,9 +639,13 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat
        pstring param;
        char *rparam=NULL, *rdata=NULL;
 
+       *poutdata = NULL;
+       *poutlen = 0;
+
        /* if its a win95 server then fail this - win95 totally screws it
           up */
-       if (cli->win95) return False;
+       if (cli->win95)
+               return False;
 
        param_len = 4;
 
@@ -665,7 +669,8 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat
                return False;
        }
 
-       memcpy(outdata, rdata, data_len);
+       memdup(poutdata, data_len);
+       *poutlen = data_len;
 
        SAFE_FREE(rdata);
        SAFE_FREE(rparam);
index 92629faa9e2d13ebfef9522a5b98dba26bc6abd9..3127134458fc0370ccb6cc22171b2cc1632476d1 100644 (file)
@@ -353,6 +353,7 @@ static int map_share_mode( char *fname, uint32 create_options,
                        uint32 *desired_access, uint32 share_access, uint32 file_attributes)
 {
        int smb_open_mode = -1;
+       uint32 original_desired_access = *desired_access;
 
        /*
         * Convert GENERIC bits to specific bits.
@@ -424,6 +425,10 @@ static int map_share_mode( char *fname, uint32 create_options,
                DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode));
        }
 
+       if(*desired_access & DELETE_ACCESS) {
+               DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
+       }
+
        /*
         * We need to store the intent to open for Delete. This
         * is what determines if a delete on close flag can be set.
@@ -431,11 +436,19 @@ static int map_share_mode( char *fname, uint32 create_options,
         * is the only practical way. JRA.
         */
 
-       if(*desired_access & DELETE_ACCESS) {
-               DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
-       }
-
        if (create_options & FILE_DELETE_ON_CLOSE) {
+               /*
+                * W2K3 bug compatibility mode... To set delete on close
+                * the redirector must have *specifically* set DELETE_ACCESS
+                * in the desired_access field. Just asking for GENERIC_ALL won't do. JRA.
+                */
+
+               if (!(original_desired_access & DELETE_ACCESS)) {
+                       DEBUG(5,("map_share_mode: FILE_DELETE_ON_CLOSE requested without \
+DELETE_ACCESS for file %s. (desired_access = 0x%lx)\n",
+                               fname, (unsigned long)*desired_access));
+                       return -1;
+               }
                /* Implicit delete access is *NOT* requested... */
                smb_open_mode |= DELETE_ON_CLOSE_FLAG;
                DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode));
@@ -738,7 +751,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                                           share_access, 
                                           file_attributes)) == -1) {
                END_PROFILE(SMBntcreateX);
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
        }
 
        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
@@ -1267,7 +1280,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
 
        if((smb_open_mode = map_share_mode( fname, create_options, &desired_access,
                                                share_access, file_attributes)) == -1)
-               return ERROR_DOS(ERRDOS,ERRnoaccess);
+               return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
 
        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
        oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
index 2e6bc49d55ac04e7f107cdfd03a93988e142baa1..d8bfe53dc3f88d676fd9c52a8d1c8d0163b42461 100644 (file)
@@ -2493,19 +2493,19 @@ static BOOL run_trans2test(int dummy)
 
 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
 {
-       char buf[4096];
+       char *buf = NULL;
+       uint32 len;
        BOOL correct = True;
 
-       memset(buf, 0xff, sizeof(buf));
-
-       if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
+       if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
                printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
                correct = False;
        } else {
-               printf("qfileinfo: level %d\n", level);
-               dump_data(0, buf, 256);
+               printf("qfileinfo: level %d, len = %u\n", level, len);
+               dump_data(0, buf, len);
                printf("\n");
        }
+       SAFE_FREE(buf);
        return correct;
 }
 
@@ -2812,8 +2812,8 @@ static BOOL run_deletetest(int dummy)
        cli_setatr(cli1, fname, 0, 0);
        cli_unlink(cli1, fname);
        
-       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  0, FILE_OVERWRITE_IF, 
                                   FILE_DELETE_ON_CLOSE, 0);
        
        if (fnum1 == -1) {
@@ -2821,7 +2821,15 @@ static BOOL run_deletetest(int dummy)
                correct = False;
                goto fail;
        }
-       
+
+#if 0
+       {
+               uint32 accinfo = 0;
+               cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char *)&accinfo);
+               printf("access mode = 0x%lx\n", accinfo);
+       }
+#endif
+
        if (!cli_close(cli1, fnum1)) {
                printf("[1] close failed (%s)\n", cli_errstr(cli1));
                correct = False;