LCOV - code coverage report
Current view: top level - source4/torture/raw - open.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 1198 1276 93.9 %
Date: 2024-02-14 10:14:15 Functions: 21 22 95.5 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    RAW_OPEN_* individual test suite
       4             :    Copyright (C) Andrew Tridgell 2003
       5             :    
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             :    
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             :    
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "libcli/raw/libcliraw.h"
      22             : #include "system/time.h"
      23             : #include "system/filesys.h"
      24             : #include "lib/events/events.h"
      25             : #include "libcli/libcli.h"
      26             : #include "torture/util.h"
      27             : #include "torture/raw/proto.h"
      28             : 
      29             : /* enum for whether reads/writes are possible on a file */
      30             : enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
      31             : 
      32             : #define BASEDIR "\\rawopen"
      33             : 
      34             : /*
      35             :   check if a open file can be read/written
      36             : */
      37           8 : static enum rdwr_mode check_rdwr(struct smbcli_tree *tree, int fnum)
      38             : {
      39           8 :         uint8_t c = 1;
      40           8 :         bool can_read  = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
      41           8 :         bool can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
      42           8 :         if ( can_read &&  can_write) return RDWR_RDWR;
      43           4 :         if ( can_read && !can_write) return RDWR_RDONLY;
      44           1 :         if (!can_read &&  can_write) return RDWR_WRONLY;
      45           0 :         return RDWR_NONE;
      46             : }
      47             : 
      48             : /*
      49             :   describe a RDWR mode as a string
      50             : */
      51           0 : static const char *rdwr_string(enum rdwr_mode m)
      52             : {
      53           0 :         switch (m) {
      54           0 :         case RDWR_NONE: return "NONE";
      55           0 :         case RDWR_RDONLY: return "RDONLY";
      56           0 :         case RDWR_WRONLY: return "WRONLY";
      57           0 :         case RDWR_RDWR: return "RDWR";
      58             :         }
      59           0 :         return "-";
      60             : }
      61             : 
      62             : #define CHECK_STATUS(status, correct) do { \
      63             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      64             :                 torture_result(tctx, TORTURE_FAIL, \
      65             :                         "(%s) Incorrect status %s - should be %s\n", \
      66             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
      67             :                 ret = false; \
      68             :                 goto done; \
      69             :         }} while (0)
      70             : 
      71             : #define CREATE_FILE do { \
      72             :         fnum = create_complex_file(cli, tctx, fname); \
      73             :         if (fnum == -1) { \
      74             :                 torture_result(tctx, TORTURE_FAIL, \
      75             :                         "(%s) Failed to create %s - %s\n", \
      76             :                          __location__, fname, smbcli_errstr(cli->tree)); \
      77             :                 ret = false; \
      78             :                 goto done; \
      79             :         }} while (0)
      80             : 
      81             : #define CHECK_RDWR(fnum, correct) do { \
      82             :         enum rdwr_mode m = check_rdwr(cli->tree, fnum); \
      83             :         if (m != correct) { \
      84             :                 torture_result(tctx, TORTURE_FAIL, \
      85             :                        "(%s) Incorrect readwrite mode %s - expected %s\n", \
      86             :                        __location__, rdwr_string(m), rdwr_string(correct)); \
      87             :                 ret = false; \
      88             :         }} while (0)
      89             : 
      90             : #define CHECK_TIME(t, field) do { \
      91             :         time_t t1, t2; \
      92             :         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
      93             :         finfo.all_info.in.file.path = fname; \
      94             :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
      95             :         CHECK_STATUS(status, NT_STATUS_OK); \
      96             :         t1 = t & ~1; \
      97             :         t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
      98             :         if (labs(t1-t2) > 2) { \
      99             :                 torture_result(tctx, TORTURE_FAIL, \
     100             :                        "(%s) wrong time for field %s  %s - %s\n", \
     101             :                        __location__, #field, \
     102             :                        timestring(tctx, t1), \
     103             :                        timestring(tctx, t2)); \
     104             :                 dump_all_info(tctx, &finfo); \
     105             :                 ret = false; \
     106             :         }} while (0)
     107             : 
     108             : #define CHECK_NTTIME(t, field) do { \
     109             :         NTTIME t2; \
     110             :         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
     111             :         finfo.all_info.in.file.path = fname; \
     112             :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
     113             :         CHECK_STATUS(status, NT_STATUS_OK); \
     114             :         t2 = finfo.all_info.out.field; \
     115             :         if (llabs((int64_t)(t-t2)) > 20000) { \
     116             :                 torture_result(tctx, TORTURE_FAIL, \
     117             :                        "(%s) wrong time for field %s  %s - %s\n", \
     118             :                        __location__, #field, \
     119             :                        nt_time_string(tctx, t), \
     120             :                        nt_time_string(tctx, t2)); \
     121             :                 dump_all_info(tctx, &finfo); \
     122             :                 ret = false; \
     123             :         }} while (0)
     124             : 
     125             : #define CHECK_ALL_INFO(v, field) do { \
     126             :         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
     127             :         finfo.all_info.in.file.path = fname; \
     128             :         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
     129             :         CHECK_STATUS(status, NT_STATUS_OK); \
     130             :         if ((v) != (finfo.all_info.out.field)) { \
     131             :                 torture_result(tctx, TORTURE_FAIL, \
     132             :                        "(%s) wrong value for field %s  0x%x - 0x%x\n", \
     133             :                        __location__, #field, (unsigned int)(v), (unsigned int)(finfo.all_info.out.field)); \
     134             :                 dump_all_info(tctx, &finfo); \
     135             :                 ret = false; \
     136             :         }} while (0)
     137             : 
     138             : #define CHECK_VAL(v, correct) do { \
     139             :         if ((v) != (correct)) { \
     140             :                 torture_result(tctx, TORTURE_FAIL, \
     141             :                        "(%s) wrong value for %s  0x%x - should be 0x%x\n", \
     142             :                        __location__, #v, (unsigned int)(v), (unsigned int)(correct)); \
     143             :                 ret = false; \
     144             :         }} while (0)
     145             : 
     146             : #define SET_ATTRIB(sattrib) do { \
     147             :         union smb_setfileinfo sfinfo; \
     148             :         ZERO_STRUCT(sfinfo.basic_info.in); \
     149             :         sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
     150             :         sfinfo.basic_info.in.file.path = fname; \
     151             :         sfinfo.basic_info.in.attrib = sattrib; \
     152             :         status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
     153             :         if (!NT_STATUS_IS_OK(status)) { \
     154             :                 torture_warning(tctx, "(%s) Failed to set attrib 0x%x on %s\n", \
     155             :                        __location__, (unsigned int)(sattrib), fname); \
     156             :         }} while (0)
     157             : 
     158             : /*
     159             :   test RAW_OPEN_OPEN
     160             : */
     161           1 : static bool test_open(struct torture_context *tctx, struct smbcli_state *cli)
     162             : {
     163             :         union smb_open io;
     164             :         union smb_fileinfo finfo;
     165           1 :         const char *fname = BASEDIR "\\torture_open.txt";
     166             :         NTSTATUS status;
     167           1 :         int fnum = -1, fnum2;
     168           1 :         bool ret = true;
     169             : 
     170           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     171             : 
     172           1 :         io.openold.level = RAW_OPEN_OPEN;
     173           1 :         io.openold.in.fname = fname;
     174           1 :         io.openold.in.open_mode = OPEN_FLAGS_FCB;
     175           1 :         io.openold.in.search_attrs = 0;
     176           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     177           1 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     178           1 :         fnum = io.openold.out.file.fnum;
     179             : 
     180           1 :         smbcli_unlink(cli->tree, fname);
     181           1 :         CREATE_FILE;
     182           1 :         smbcli_close(cli->tree, fnum);
     183             : 
     184           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     185           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     186           1 :         fnum = io.openold.out.file.fnum;
     187           1 :         CHECK_RDWR(fnum, RDWR_RDWR);
     188             : 
     189           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     190           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     191           1 :         fnum2 = io.openold.out.file.fnum;
     192           1 :         CHECK_RDWR(fnum2, RDWR_RDWR);
     193           1 :         smbcli_close(cli->tree, fnum2);
     194           1 :         smbcli_close(cli->tree, fnum);
     195             : 
     196             :         /* check the read/write modes */
     197           1 :         io.openold.level = RAW_OPEN_OPEN;
     198           1 :         io.openold.in.fname = fname;
     199           1 :         io.openold.in.search_attrs = 0;
     200             : 
     201           1 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
     202           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     203           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     204           1 :         fnum = io.openold.out.file.fnum;
     205           1 :         CHECK_RDWR(fnum, RDWR_RDONLY);
     206           1 :         smbcli_close(cli->tree, fnum);
     207             : 
     208           1 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
     209           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     210           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     211           1 :         fnum = io.openold.out.file.fnum;
     212           1 :         CHECK_RDWR(fnum, RDWR_WRONLY);
     213           1 :         smbcli_close(cli->tree, fnum);
     214             : 
     215           1 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
     216           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     217           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     218           1 :         fnum = io.openold.out.file.fnum;
     219           1 :         CHECK_RDWR(fnum, RDWR_RDWR);
     220           1 :         smbcli_close(cli->tree, fnum);
     221             : 
     222             :         /* check the share modes roughly - not a complete matrix */
     223           1 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
     224           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     225           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     226           1 :         fnum = io.openold.out.file.fnum;
     227           1 :         CHECK_RDWR(fnum, RDWR_RDWR);
     228             :         
     229           1 :         if (io.openold.in.open_mode != io.openold.out.rmode) {
     230           0 :                 torture_warning(tctx, "(%s) rmode should equal open_mode - 0x%x 0x%x\n",
     231           0 :                        __location__, io.openold.out.rmode, io.openold.in.open_mode);
     232             :         }
     233             : 
     234           1 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
     235           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     236           1 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     237             : 
     238           1 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
     239           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     240           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     241           1 :         fnum2 = io.openold.out.file.fnum;
     242           1 :         CHECK_RDWR(fnum2, RDWR_RDONLY);
     243           1 :         smbcli_close(cli->tree, fnum);
     244           1 :         smbcli_close(cli->tree, fnum2);
     245             : 
     246             : 
     247             :         /* check the returned write time */
     248           1 :         io.openold.level = RAW_OPEN_OPEN;
     249           1 :         io.openold.in.fname = fname;
     250           1 :         io.openold.in.search_attrs = 0;
     251           1 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
     252           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     253           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     254           1 :         fnum = io.openold.out.file.fnum;
     255             : 
     256             :         /* check other reply fields */
     257           1 :         CHECK_TIME(io.openold.out.write_time, write_time);
     258           1 :         CHECK_ALL_INFO(io.openold.out.size, size);
     259           1 :         CHECK_ALL_INFO(io.openold.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     260             : 
     261           1 : done:
     262           1 :         smbcli_close(cli->tree, fnum);
     263           1 :         smbcli_deltree(cli->tree, BASEDIR);
     264             : 
     265           1 :         return ret;
     266             : }
     267             : 
     268             : 
     269             : /*
     270             :   test RAW_OPEN_OPENX
     271             : */
     272           1 : static bool test_openx(struct torture_context *tctx, struct smbcli_state *cli)
     273             : {
     274             :         union smb_open io;
     275             :         union smb_fileinfo finfo;
     276           1 :         const char *fname = BASEDIR "\\torture_openx.txt";
     277           1 :         const char *fname_exe = BASEDIR "\\torture_openx.exe";
     278             :         NTSTATUS status;
     279           1 :         int fnum = -1, fnum2;
     280           1 :         bool ret = true;
     281             :         int i;
     282             :         struct timeval tv;
     283             :         struct {
     284             :                 uint16_t open_func;
     285             :                 bool with_file;
     286             :                 NTSTATUS correct_status;
     287           1 :         } open_funcs[] = {
     288             :                 { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
     289             :                 { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     290             :                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
     291             :                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
     292             :                 { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
     293             :                 { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
     294             :                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
     295             :                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
     296             :                 { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
     297             :                 { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     298             :                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
     299             :                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
     300             :         };
     301             : 
     302           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     303             : 
     304           1 :         io.openx.level = RAW_OPEN_OPENX;
     305           1 :         io.openx.in.fname = fname;
     306           1 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     307           1 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
     308           1 :         io.openx.in.search_attrs = 0;
     309           1 :         io.openx.in.file_attrs = 0;
     310           1 :         io.openx.in.write_time = 0;
     311           1 :         io.openx.in.size = 1024*1024;
     312           1 :         io.openx.in.timeout = 0;
     313             : 
     314             :         /* check all combinations of open_func */
     315          13 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     316          12 :                 if (open_funcs[i].with_file) {
     317           6 :                         fnum = create_complex_file(cli, tctx, fname);
     318           6 :                         if (fnum == -1) {
     319           0 :                                 torture_result(tctx, TORTURE_FAIL,
     320             :                                         "Failed to create file %s - %s\n",
     321             :                                         fname, smbcli_errstr(cli->tree));
     322           0 :                                 ret = false;
     323           0 :                                 goto done;
     324             :                         }
     325           6 :                         smbcli_close(cli->tree, fnum);
     326             :                 }
     327          12 :                 io.openx.in.open_func = open_funcs[i].open_func;
     328          12 :                 status = smb_raw_open(cli->tree, tctx, &io);
     329          12 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
     330           0 :                         torture_result(tctx, TORTURE_FAIL,
     331             :                                 "(%s) incorrect status %s should be %s "
     332             :                                 "(i=%d with_file=%d open_func=0x%x)\n",
     333             :                                 __location__, nt_errstr(status),
     334             :                                 nt_errstr(open_funcs[i].correct_status),
     335           0 :                                 i, (int)open_funcs[i].with_file,
     336           0 :                                 open_funcs[i].open_func);
     337           0 :                         ret = false;
     338             :                 }
     339          12 :                 if (NT_STATUS_IS_OK(status)) {
     340           7 :                         smbcli_close(cli->tree, io.openx.out.file.fnum);
     341             :                 }
     342          12 :                 if (open_funcs[i].with_file) {
     343           6 :                         smbcli_unlink(cli->tree, fname);
     344             :                 }
     345             :         }
     346             : 
     347           1 :         smbcli_unlink(cli->tree, fname);
     348             : 
     349             :         /* check the basic return fields */
     350           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     351           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     352           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     353           1 :         fnum = io.openx.out.file.fnum;
     354             : 
     355           1 :         CHECK_ALL_INFO(io.openx.out.size, size);
     356           1 :         CHECK_TIME(io.openx.out.write_time, write_time);
     357           1 :         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     358           1 :         CHECK_VAL(io.openx.out.access, OPENX_MODE_ACCESS_RDWR);
     359           1 :         CHECK_VAL(io.openx.out.ftype, 0);
     360           1 :         CHECK_VAL(io.openx.out.devstate, 0);
     361           1 :         CHECK_VAL(io.openx.out.action, OPENX_ACTION_CREATED);
     362           1 :         CHECK_VAL(io.openx.out.size, 1024*1024);
     363           1 :         CHECK_ALL_INFO(io.openx.in.size, size);
     364           1 :         smbcli_close(cli->tree, fnum);
     365           1 :         smbcli_unlink(cli->tree, fname);
     366             : 
     367             :         /* check the fields when the file already existed */
     368           1 :         fnum2 = create_complex_file(cli, tctx, fname);
     369           1 :         if (fnum2 == -1) {
     370           0 :                 ret = false;
     371           0 :                 goto done;
     372             :         }
     373           1 :         smbcli_close(cli->tree, fnum2);
     374             : 
     375           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
     376           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     377           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     378           1 :         fnum = io.openx.out.file.fnum;
     379             : 
     380           1 :         CHECK_ALL_INFO(io.openx.out.size, size);
     381           1 :         CHECK_TIME(io.openx.out.write_time, write_time);
     382           1 :         CHECK_VAL(io.openx.out.action, OPENX_ACTION_EXISTED);
     383           1 :         CHECK_VAL(io.openx.out.unknown, 0);
     384           1 :         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     385           1 :         smbcli_close(cli->tree, fnum);
     386             : 
     387             :         /* now check the search attrib for hidden files - win2003 ignores this? */
     388           1 :         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
     389           1 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
     390             : 
     391           1 :         io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
     392           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     393           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     394           1 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     395             : 
     396           1 :         io.openx.in.search_attrs = 0;
     397           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     398           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     399           1 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     400             : 
     401           1 :         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
     402           1 :         smbcli_unlink(cli->tree, fname);
     403             : 
     404             :         /* and check attrib on create */
     405           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
     406           1 :         io.openx.in.search_attrs = 0;
     407           1 :         io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
     408           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     409           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     410           1 :         if (torture_setting_bool(tctx, "samba3", false)) {
     411           0 :                 CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
     412             :                                attrib & ~(FILE_ATTRIBUTE_NONINDEXED|
     413             :                                           FILE_ATTRIBUTE_SPARSE));
     414             :         }
     415             :         else {
     416           1 :                 CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
     417             :                                attrib & ~(FILE_ATTRIBUTE_NONINDEXED));
     418             :         }
     419           1 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     420           1 :         smbcli_unlink(cli->tree, fname);
     421             : 
     422             :         /* check timeout on create - win2003 ignores the timeout! */
     423           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     424           1 :         io.openx.in.file_attrs = 0;
     425           1 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
     426           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     427           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     428           1 :         fnum = io.openx.out.file.fnum;
     429             : 
     430           1 :         io.openx.in.timeout = 20000;
     431           1 :         tv = timeval_current();
     432           1 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
     433           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     434           1 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     435           1 :         if (timeval_elapsed(&tv) > 3.0) {
     436           0 :                 torture_result(tctx, TORTURE_FAIL,
     437             :                         "(%s) Incorrect timing in openx with timeout "
     438             :                         "- waited %.2f seconds\n",
     439             :                         __location__, timeval_elapsed(&tv));
     440           0 :                 ret = false;
     441             :         }
     442           1 :         smbcli_close(cli->tree, fnum);
     443           1 :         smbcli_unlink(cli->tree, fname);
     444             : 
     445             :         /* now this is a really weird one - open for execute implies create?! */
     446           1 :         io.openx.in.fname = fname;
     447           1 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     448           1 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
     449           1 :         io.openx.in.search_attrs = 0;
     450           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL;
     451           1 :         io.openx.in.file_attrs = 0;
     452           1 :         io.openx.in.write_time = 0;
     453           1 :         io.openx.in.size = 0;
     454           1 :         io.openx.in.timeout = 0;
     455           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     456           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     457           1 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     458             : 
     459             :         /* check the extended return flag */
     460           1 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
     461           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
     462           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     463           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     464           1 :         CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
     465           1 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     466             : 
     467           1 :         io.openx.in.fname = "\\A.+,;=[].B";
     468           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     469           1 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     470             : 
     471             :         /* Check the mapping for open exec. */
     472             : 
     473             :         /* First create an .exe file. */
     474           1 :         smbcli_unlink(cli->tree, fname_exe);
     475           1 :         fnum = create_complex_file(cli, tctx, fname_exe);
     476           1 :         smbcli_close(cli->tree, fnum);
     477             : 
     478           1 :         io.openx.level = RAW_OPEN_OPENX;
     479           1 :         io.openx.in.fname = fname_exe;
     480           1 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     481           1 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
     482           1 :         io.openx.in.search_attrs = 0;
     483           1 :         io.openx.in.file_attrs = 0;
     484           1 :         io.openx.in.write_time = 0;
     485           1 :         io.openx.in.size = 0;
     486           1 :         io.openx.in.timeout = 0;
     487           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     488           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     489             : 
     490             :         /* Can we read and write ? */
     491           1 :         CHECK_RDWR(io.openx.out.file.fnum, RDWR_RDONLY);
     492           1 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     493           1 :         smbcli_unlink(cli->tree, fname);
     494             : 
     495           1 : done:
     496           1 :         smbcli_close(cli->tree, fnum);
     497           1 :         smbcli_deltree(cli->tree, BASEDIR);
     498             : 
     499           1 :         return ret;
     500             : }
     501             : 
     502             : 
     503             : /*
     504             :   test RAW_OPEN_T2OPEN
     505             : 
     506             :   many thanks to kukks for a sniff showing how this works with os2->w2k
     507             : */
     508           1 : static bool test_t2open(struct torture_context *tctx, struct smbcli_state *cli)
     509             : {
     510             :         union smb_open io;
     511             :         union smb_fileinfo finfo;
     512           1 :         const char *fname1 = BASEDIR "\\torture_t2open_yes.txt";
     513           1 :         const char *fname2 = BASEDIR "\\torture_t2open_no.txt";
     514           1 :         const char *fname = BASEDIR "\\torture_t2open_3.txt";
     515             :         NTSTATUS status;
     516             :         int fnum;
     517           1 :         bool ret = true;
     518             :         int i;
     519             :         struct {
     520             :                 uint16_t open_func;
     521             :                 bool with_file;
     522             :                 NTSTATUS correct_status;
     523           1 :         } open_funcs[] = {
     524             :                 { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
     525             :                 { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     526             :                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
     527             :                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
     528             :                 { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_OBJECT_NAME_COLLISION },
     529             :                 { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_OBJECT_NAME_COLLISION },
     530             :                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
     531             :                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OBJECT_NAME_COLLISION },
     532             :                 { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
     533             :                 { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OK },
     534             :                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
     535             :                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
     536             :         };
     537             : 
     538           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     539             : 
     540           1 :         fnum = create_complex_file(cli, tctx, fname1);
     541           1 :         if (fnum == -1) {
     542           0 :                 torture_result(tctx, TORTURE_FAIL,
     543             :                         "(%s): Failed to create file %s - %s\n",
     544             :                         __location__, fname1, smbcli_errstr(cli->tree));
     545           0 :                 ret = false;
     546           0 :                 goto done;
     547             :         }
     548           1 :         smbcli_close(cli->tree, fnum);
     549             : 
     550           1 :         io.t2open.level = RAW_OPEN_T2OPEN;
     551           1 :         io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     552           1 :         io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
     553           1 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     554           1 :         io.t2open.in.search_attrs = 0;
     555           1 :         io.t2open.in.file_attrs = 0;
     556           1 :         io.t2open.in.write_time = 0;
     557           1 :         io.t2open.in.size = 0;
     558           1 :         io.t2open.in.timeout = 0;
     559             : 
     560           1 :         io.t2open.in.num_eas = 3;
     561           1 :         io.t2open.in.eas = talloc_array(tctx, struct ea_struct, io.t2open.in.num_eas);
     562           1 :         io.t2open.in.eas[0].flags = 0;
     563           1 :         io.t2open.in.eas[0].name.s = ".CLASSINFO";
     564           1 :         io.t2open.in.eas[0].value = data_blob_talloc(tctx, "first value", 11);
     565           1 :         io.t2open.in.eas[1].flags = 0;
     566           1 :         io.t2open.in.eas[1].name.s = "EA TWO";
     567           1 :         io.t2open.in.eas[1].value = data_blob_talloc(tctx, "foo", 3);
     568           1 :         io.t2open.in.eas[2].flags = 0;
     569           1 :         io.t2open.in.eas[2].name.s = "X THIRD";
     570           1 :         io.t2open.in.eas[2].value = data_blob_talloc(tctx, "xy", 2);
     571             : 
     572             :         /* check all combinations of open_func */
     573          13 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     574          12 :         again:
     575          12 :                 if (open_funcs[i].with_file) {
     576           6 :                         io.t2open.in.fname = fname1;
     577             :                 } else {
     578           6 :                         io.t2open.in.fname = fname2;
     579             :                 }
     580          12 :                 io.t2open.in.open_func = open_funcs[i].open_func;
     581          12 :                 status = smb_raw_open(cli->tree, tctx, &io);
     582          12 :                 if ((io.t2open.in.num_eas != 0)
     583          12 :                     && NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
     584           0 :                     && torture_setting_bool(tctx, "samba3", false)) {
     585           0 :                         torture_warning(tctx, "(%s) EAs not supported, not "
     586             :                                 "treating as fatal in Samba3 test\n",
     587             :                                 __location__);
     588           0 :                         io.t2open.in.num_eas = 0;
     589           0 :                         goto again;
     590             :                 }
     591             : 
     592          12 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
     593           0 :                         torture_result(tctx, TORTURE_FAIL,
     594             :                                 "(%s) incorrect status %s should be %s "
     595             :                                 "(i=%d with_file=%d open_func=0x%x)\n",
     596             :                                  __location__, nt_errstr(status),
     597             :                                 nt_errstr(open_funcs[i].correct_status),
     598           0 :                                 i, (int)open_funcs[i].with_file,
     599           0 :                                 open_funcs[i].open_func);
     600           0 :                         ret = false;
     601             :                 }
     602          12 :                 if (NT_STATUS_IS_OK(status)) {
     603           7 :                         smbcli_close(cli->tree, io.t2open.out.file.fnum);
     604             :                 }
     605             :         }
     606             : 
     607           1 :         smbcli_unlink(cli->tree, fname1);
     608           1 :         smbcli_unlink(cli->tree, fname2);
     609             : 
     610             :         /* check the basic return fields */
     611           1 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     612           1 :         io.t2open.in.write_time = 0;
     613           1 :         io.t2open.in.fname = fname;
     614           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     615           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     616           1 :         fnum = io.t2open.out.file.fnum;
     617             : 
     618           1 :         CHECK_ALL_INFO(io.t2open.out.size, size);
     619             : #if 0
     620             :         /* windows appears to leak uninitialised memory here */
     621             :         CHECK_VAL(io.t2open.out.write_time, 0);
     622             : #endif
     623           1 :         CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     624           1 :         CHECK_VAL(io.t2open.out.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
     625           1 :         CHECK_VAL(io.t2open.out.ftype, 0);
     626           1 :         CHECK_VAL(io.t2open.out.devstate, 0);
     627           1 :         CHECK_VAL(io.t2open.out.action, OPENX_ACTION_CREATED);
     628           1 :         smbcli_close(cli->tree, fnum);
     629             : 
     630           1 :         status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
     631           1 :         CHECK_STATUS(status, io.t2open.in.num_eas
     632             :                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
     633           1 :         status = torture_check_ea(cli, fname, "EA TWO", "foo");
     634           1 :         CHECK_STATUS(status, io.t2open.in.num_eas
     635             :                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
     636           1 :         status = torture_check_ea(cli, fname, "X THIRD", "xy");
     637           1 :         CHECK_STATUS(status, io.t2open.in.num_eas
     638             :                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
     639             : 
     640             :         /* now check the search attrib for hidden files - win2003 ignores this? */
     641           1 :         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
     642           1 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
     643             : 
     644           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     645           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     646           1 :         smbcli_close(cli->tree, io.t2open.out.file.fnum);
     647             : 
     648           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     649           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     650           1 :         smbcli_close(cli->tree, io.t2open.out.file.fnum);
     651             : 
     652           1 :         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
     653           1 :         smbcli_unlink(cli->tree, fname);
     654             : 
     655             :         /* and check attrib on create */
     656           1 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
     657           1 :         io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
     658           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     659           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     660             : 
     661             :         /* check timeout on create - win2003 ignores the timeout! */
     662           1 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     663           1 :         io.t2open.in.file_attrs = 0;
     664           1 :         io.t2open.in.timeout = 20000;
     665           1 :         io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
     666           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     667           1 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     668             : 
     669           1 : done:
     670           1 :         smbcli_close(cli->tree, fnum);
     671           1 :         smbcli_deltree(cli->tree, BASEDIR);
     672             : 
     673           1 :         return ret;
     674             : }
     675             :         
     676             : 
     677             : /*
     678             :   test RAW_OPEN_NTCREATEX
     679             : */
     680           1 : static bool test_ntcreatex(struct torture_context *tctx, struct smbcli_state *cli)
     681             : {
     682             :         union smb_open io;
     683             :         union smb_fileinfo finfo;
     684           1 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
     685           1 :         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
     686             :         NTSTATUS status;
     687           1 :         int fnum = -1;
     688           1 :         bool ret = true;
     689             :         int i;
     690             :         struct {
     691             :                 uint32_t open_disp;
     692             :                 bool with_file;
     693             :                 NTSTATUS correct_status;
     694           1 :         } open_funcs[] = {
     695             :                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
     696             :                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
     697             :                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
     698             :                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     699             :                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
     700             :                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
     701             :                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
     702             :                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
     703             :                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
     704             :                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     705             :                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
     706             :                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
     707             :                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
     708             :                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
     709             :         };
     710             : 
     711           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     712             : 
     713             :         /* reasonable default parameters */
     714           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
     715           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     716           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     717           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     718           1 :         io.ntcreatex.in.alloc_size = 1024*1024;
     719           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     720           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     721           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     722           1 :         io.ntcreatex.in.create_options = 0;
     723           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     724           1 :         io.ntcreatex.in.security_flags = 0;
     725           1 :         io.ntcreatex.in.fname = fname;
     726             : 
     727             :         /* test the open disposition */
     728          15 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     729          14 :                 if (open_funcs[i].with_file) {
     730           7 :                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
     731           7 :                         if (fnum == -1) {
     732           0 :                                 torture_result(tctx, TORTURE_FAIL,
     733             :                                         "Failed to create file %s - %s\n",
     734             :                                         fname, smbcli_errstr(cli->tree));
     735           0 :                                 ret = false;
     736           0 :                                 goto done;
     737             :                         }
     738           7 :                         smbcli_close(cli->tree, fnum);
     739             :                 }
     740          14 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
     741          14 :                 status = smb_raw_open(cli->tree, tctx, &io);
     742          14 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
     743           0 :                         torture_result(tctx, TORTURE_FAIL,
     744             :                                 "(%s) incorrect status %s should be %s "
     745             :                                 "(i=%d with_file=%d open_disp=%d)\n",
     746             :                                 __location__, nt_errstr(status),
     747             :                                 nt_errstr(open_funcs[i].correct_status),
     748           0 :                                 i, (int)open_funcs[i].with_file,
     749           0 :                                 (int)open_funcs[i].open_disp);
     750           0 :                         ret = false;
     751             :                 }
     752          14 :                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
     753          11 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
     754          11 :                         smbcli_unlink(cli->tree, fname);
     755             :                 }
     756             :         }
     757             : 
     758             :         /* basic field testing */
     759           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     760             : 
     761           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     762           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     763           1 :         fnum = io.ntcreatex.out.file.fnum;
     764             : 
     765           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     766           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
     767           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     768           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     769           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     770           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     771           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     772           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     773           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     774           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     775           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     776             : 
     777             :         /* check fields when the file already existed */
     778           1 :         smbcli_close(cli->tree, fnum);
     779           1 :         smbcli_unlink(cli->tree, fname);
     780           1 :         fnum = create_complex_file(cli, tctx, fname);
     781           1 :         if (fnum == -1) {
     782           0 :                 ret = false;
     783           0 :                 goto done;
     784             :         }
     785           1 :         smbcli_close(cli->tree, fnum);
     786             : 
     787           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
     788           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     789           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     790           1 :         fnum = io.ntcreatex.out.file.fnum;
     791             : 
     792           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     793           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     794           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     795           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     796           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     797           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     798           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     799           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     800           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     801           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     802           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     803           1 :         smbcli_close(cli->tree, fnum);
     804           1 :         smbcli_unlink(cli->tree, fname);
     805             : 
     806             : 
     807             :         /* create a directory */
     808           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     809           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     810           1 :         io.ntcreatex.in.alloc_size = 0;
     811           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
     812           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     813           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     814           1 :         io.ntcreatex.in.create_options = 0;
     815           1 :         io.ntcreatex.in.fname = dname;
     816           1 :         fname = dname;
     817             : 
     818           1 :         smbcli_rmdir(cli->tree, fname);
     819           1 :         smbcli_unlink(cli->tree, fname);
     820             : 
     821           1 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     822           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     823           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     824           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
     825           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     826           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     827           1 :         fnum = io.ntcreatex.out.file.fnum;
     828             : 
     829           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     830           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
     831           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     832           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     833           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     834           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     835           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     836           1 :         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
     837             :                   FILE_ATTRIBUTE_DIRECTORY);
     838           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     839           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     840           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     841           1 :         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
     842           1 :         CHECK_VAL(io.ntcreatex.out.size, 0);
     843           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     844           1 :         smbcli_unlink(cli->tree, fname);
     845             :         
     846             : 
     847           1 : done:
     848           1 :         smbcli_close(cli->tree, fnum);
     849           1 :         smbcli_deltree(cli->tree, BASEDIR);
     850             : 
     851           1 :         return ret;
     852             : }
     853             : 
     854             : 
     855             : /*
     856             :   test RAW_OPEN_NTTRANS_CREATE
     857             : */
     858           1 : static bool test_nttrans_create(struct torture_context *tctx, struct smbcli_state *cli)
     859             : {
     860             :         union smb_open io;
     861             :         union smb_fileinfo finfo;
     862           1 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
     863           1 :         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
     864             :         NTSTATUS status;
     865           1 :         int fnum = -1;
     866           1 :         bool ret = true;
     867             :         int i;
     868             :         uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
     869             :         uint32_t not_a_directory_mask, unexpected_mask;
     870             :         struct {
     871             :                 uint32_t open_disp;
     872             :                 bool with_file;
     873             :                 NTSTATUS correct_status;
     874           1 :         } open_funcs[] = {
     875             :                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
     876             :                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
     877             :                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
     878             :                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     879             :                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
     880             :                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
     881             :                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
     882             :                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
     883             :                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
     884             :                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     885             :                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
     886             :                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
     887             :                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
     888             :                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
     889             :         };
     890             : 
     891           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     892             : 
     893             :         /* reasonable default parameters */
     894           1 :         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
     895           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     896           1 :         io.ntcreatex.in.root_fid.fnum = 0;
     897           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     898           1 :         io.ntcreatex.in.alloc_size = 1024*1024;
     899           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     900           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     901           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     902           1 :         io.ntcreatex.in.create_options = 0;
     903           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     904           1 :         io.ntcreatex.in.security_flags = 0;
     905           1 :         io.ntcreatex.in.fname = fname;
     906           1 :         io.ntcreatex.in.sec_desc = NULL;
     907           1 :         io.ntcreatex.in.ea_list = NULL;
     908             : 
     909             :         /* test the open disposition */
     910          15 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     911          14 :                 if (open_funcs[i].with_file) {
     912           7 :                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
     913           7 :                         if (fnum == -1) {
     914           0 :                                 torture_result(tctx, TORTURE_FAIL,
     915             :                                         "Failed to create file %s - %s\n",
     916             :                                         fname, smbcli_errstr(cli->tree));
     917           0 :                                 ret = false;
     918           0 :                                 goto done;
     919             :                         }
     920           7 :                         smbcli_close(cli->tree, fnum);
     921             :                 }
     922          14 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
     923          14 :                 status = smb_raw_open(cli->tree, tctx, &io);
     924          14 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
     925           0 :                         torture_result(tctx, TORTURE_FAIL,
     926             :                                 "(%s) incorrect status %s should be %s "
     927             :                                 "(i=%d with_file=%d open_disp=%d)\n",
     928             :                                 __location__, nt_errstr(status),
     929             :                                 nt_errstr(open_funcs[i].correct_status),
     930           0 :                                 i, (int)open_funcs[i].with_file,
     931           0 :                                 (int)open_funcs[i].open_disp);
     932           0 :                         ret = false;
     933             :                 }
     934          14 :                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
     935          11 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
     936          11 :                         smbcli_unlink(cli->tree, fname);
     937             :                 }
     938             :         }
     939             : 
     940             :         /* basic field testing */
     941           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     942             : 
     943           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     944           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     945           1 :         fnum = io.ntcreatex.out.file.fnum;
     946             : 
     947           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     948           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
     949           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     950           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     951           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     952           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     953           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     954           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     955           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     956           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     957           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     958             : 
     959             :         /* check fields when the file already existed */
     960           1 :         smbcli_close(cli->tree, fnum);
     961           1 :         smbcli_unlink(cli->tree, fname);
     962           1 :         fnum = create_complex_file(cli, tctx, fname);
     963           1 :         if (fnum == -1) {
     964           0 :                 ret = false;
     965           0 :                 goto done;
     966             :         }
     967           1 :         smbcli_close(cli->tree, fnum);
     968             : 
     969           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
     970           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     971           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     972           1 :         fnum = io.ntcreatex.out.file.fnum;
     973             : 
     974           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     975           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     976           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     977           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     978           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     979           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     980           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     981           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     982           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     983           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     984           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     985           1 :         smbcli_close(cli->tree, fnum);
     986             : 
     987             :         /* check no-recall - don't pull a file from tape on a HSM */
     988           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
     989           1 :         status = smb_raw_open(cli->tree, tctx, &io);
     990           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     991           1 :         fnum = io.ntcreatex.out.file.fnum;
     992             : 
     993           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     994           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     995           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     996           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     997           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     998           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     999           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1000           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1001           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1002           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1003           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1004           1 :         smbcli_close(cli->tree, fnum);
    1005             : 
    1006             :         /* Check some create options (these all should be ignored) */
    1007          33 :         for (i=0; i < 32; i++) {
    1008          32 :                 uint32_t create_option =
    1009          32 :                         ((uint32_t)1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
    1010          32 :                 if (create_option == 0) {
    1011          25 :                         continue;
    1012             :                 }
    1013           7 :                 io.ntcreatex.in.create_options = create_option;
    1014           7 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1015           7 :                 if (!NT_STATUS_IS_OK(status)) {
    1016           0 :                         torture_warning(tctx, "ntcreatex create option 0x%08x "
    1017             :                                 "gave %s - should give NT_STATUS_OK\n",
    1018             :                                 create_option, nt_errstr(status));
    1019             :                 }
    1020           7 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1021           7 :                 fnum = io.ntcreatex.out.file.fnum;
    1022             : 
    1023           7 :                 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1024           7 :                 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
    1025           7 :                 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    1026           7 :                 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    1027           7 :                 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    1028           7 :                 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    1029           7 :                 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1030           7 :                 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1031           7 :                 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1032           7 :                 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1033           7 :                 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1034           7 :                 smbcli_close(cli->tree, fnum);
    1035             :         }
    1036             : 
    1037           1 :         io.ntcreatex.in.file_attr = 0;
    1038           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1039           1 :         io.ntcreatex.in.access_mask     = SEC_FLAG_MAXIMUM_ALLOWED;
    1040             : 
    1041             :         /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
    1042           1 :         ok_mask = 0;
    1043           1 :         not_supported_mask = 0;
    1044           1 :         invalid_parameter_mask = 0;
    1045           1 :         not_a_directory_mask = 0;
    1046           1 :         unexpected_mask = 0;
    1047          33 :         for (i=0; i < 32; i++) {
    1048          32 :                 uint32_t create_option = (uint32_t)1<<i;
    1049          32 :                 if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
    1050           1 :                         continue;
    1051             :                 }
    1052          31 :                 io.ntcreatex.in.create_options = create_option;
    1053          31 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1054          31 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
    1055           1 :                         not_supported_mask |= create_option;
    1056          30 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
    1057          18 :                         ok_mask |= create_option;
    1058          18 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1059          12 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    1060          11 :                         invalid_parameter_mask |= create_option;
    1061           1 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
    1062           1 :                         not_a_directory_mask |= 1<<i;
    1063             :                 } else {
    1064           0 :                         unexpected_mask |= 1<<i;
    1065           0 :                         torture_comment(tctx, "create option 0x%08x returned %s\n",
    1066             :                                         create_option, nt_errstr(status));
    1067             :                 }
    1068             :         }
    1069             : 
    1070           1 :         CHECK_VAL(ok_mask,                0x00efcfce);
    1071           1 :         CHECK_VAL(not_a_directory_mask,   0x00000001);
    1072           1 :         CHECK_VAL(not_supported_mask,     0x00002000);
    1073           1 :         CHECK_VAL(invalid_parameter_mask, 0xff100030);
    1074           1 :         CHECK_VAL(unexpected_mask,        0x00000000);
    1075             : 
    1076           1 :         smbcli_unlink(cli->tree, fname);
    1077             : 
    1078             : 
    1079             :         /* create a directory */
    1080           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1081           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1082           1 :         io.ntcreatex.in.alloc_size = 0;
    1083           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1084           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1085           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1086           1 :         io.ntcreatex.in.create_options = 0;
    1087           1 :         io.ntcreatex.in.fname = dname;
    1088           1 :         fname = dname;
    1089             : 
    1090           1 :         smbcli_rmdir(cli->tree, fname);
    1091           1 :         smbcli_unlink(cli->tree, fname);
    1092             : 
    1093           1 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1094           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1095           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1096           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1097           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1098           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1099           1 :         fnum = io.ntcreatex.out.file.fnum;
    1100             : 
    1101           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1102           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    1103           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    1104           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    1105           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    1106           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    1107           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1108           1 :         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
    1109             :                   FILE_ATTRIBUTE_DIRECTORY);
    1110           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1111           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1112           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1113           1 :         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
    1114           1 :         CHECK_VAL(io.ntcreatex.out.size, 0);
    1115           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1116           1 :         smbcli_unlink(cli->tree, fname);
    1117             :         
    1118             : 
    1119           1 : done:
    1120           1 :         smbcli_close(cli->tree, fnum);
    1121           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1122             : 
    1123           1 :         return ret;
    1124             : }
    1125             : 
    1126             : /*
    1127             :   test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
    1128             : 
    1129             :   I've got an application that does a similar sequence of ntcreate&x,
    1130             :   locking&x and another ntcreate&x with
    1131             :   open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
    1132             :   second open.
    1133             : */
    1134           1 : static bool test_ntcreatex_brlocked(struct torture_context *tctx, struct smbcli_state *cli)
    1135             : {
    1136             :         union smb_open io, io1;
    1137             :         union smb_lock io2;
    1138             :         struct smb_lock_entry lock[1];
    1139           1 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
    1140             :         NTSTATUS status;
    1141           1 :         bool ret = true;
    1142             : 
    1143           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1144             : 
    1145           1 :         torture_comment(tctx, "Testing ntcreatex with a byte range locked file\n");
    1146             : 
    1147           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1148           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1149           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1150           1 :         io.ntcreatex.in.access_mask = 0x2019f;
    1151           1 :         io.ntcreatex.in.alloc_size = 0;
    1152           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1153           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1154             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1155           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1156           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    1157           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1158           1 :         io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
    1159             :                 NTCREATEX_SECURITY_ALL;
    1160           1 :         io.ntcreatex.in.fname = fname;
    1161             : 
    1162           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1163           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1164             : 
    1165           1 :         io2.lockx.level = RAW_LOCK_LOCKX;
    1166           1 :         io2.lockx.in.file.fnum = io.ntcreatex.out.file.fnum;
    1167           1 :         io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
    1168           1 :         io2.lockx.in.timeout = 0;
    1169           1 :         io2.lockx.in.ulock_cnt = 0;
    1170           1 :         io2.lockx.in.lock_cnt = 1;
    1171           1 :         lock[0].pid = cli->session->pid;
    1172           1 :         lock[0].offset = 0;
    1173           1 :         lock[0].count = 0x1;
    1174           1 :         io2.lockx.in.locks = &lock[0];
    1175           1 :         status = smb_raw_lock(cli->tree, &io2);
    1176           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1177             : 
    1178           1 :         io1.generic.level = RAW_OPEN_NTCREATEX;
    1179           1 :         io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1180           1 :         io1.ntcreatex.in.root_fid.fnum = 0;
    1181           1 :         io1.ntcreatex.in.access_mask = 0x20196;
    1182           1 :         io1.ntcreatex.in.alloc_size = 0;
    1183           1 :         io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1184           1 :         io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1185             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1186           1 :         io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    1187           1 :         io1.ntcreatex.in.create_options = 0;
    1188           1 :         io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1189           1 :         io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
    1190             :                 NTCREATEX_SECURITY_ALL;
    1191           1 :         io1.ntcreatex.in.fname = fname;
    1192             : 
    1193           1 :         status = smb_raw_open(cli->tree, tctx, &io1);
    1194           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1195             : 
    1196           1 :  done:
    1197           1 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1198           1 :         smbcli_close(cli->tree, io1.ntcreatex.out.file.fnum);
    1199           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1200           1 :         return ret;
    1201             : }
    1202             : 
    1203             : /*
    1204             :   test RAW_OPEN_MKNEW
    1205             : */
    1206           1 : static bool test_mknew(struct torture_context *tctx, struct smbcli_state *cli)
    1207             : {
    1208             :         union smb_open io;
    1209           1 :         const char *fname = BASEDIR "\\torture_mknew.txt";
    1210             :         NTSTATUS status;
    1211           1 :         int fnum = -1;
    1212           1 :         bool ret = true;
    1213           1 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1214             :         union smb_fileinfo finfo;
    1215             : 
    1216           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1217             : 
    1218           1 :         io.mknew.level = RAW_OPEN_MKNEW;
    1219           1 :         io.mknew.in.attrib = 0;
    1220           1 :         io.mknew.in.write_time = 0;
    1221           1 :         io.mknew.in.fname = fname;
    1222           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1223           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1224           1 :         fnum = io.mknew.out.file.fnum;
    1225             : 
    1226           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1227           1 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
    1228             : 
    1229           1 :         smbcli_close(cli->tree, fnum);
    1230           1 :         smbcli_unlink(cli->tree, fname);
    1231             : 
    1232             :         /* make sure write_time works */
    1233           1 :         io.mknew.in.write_time = basetime;
    1234           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1235           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1236           1 :         fnum = io.mknew.out.file.fnum;
    1237           1 :         CHECK_TIME(basetime, write_time);
    1238             : 
    1239           1 :         smbcli_close(cli->tree, fnum);
    1240           1 :         smbcli_unlink(cli->tree, fname);
    1241             : 
    1242             :         /* make sure file_attrs works */
    1243           1 :         io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1244           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1245           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1246           1 :         fnum = io.mknew.out.file.fnum;
    1247           1 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
    1248             :                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
    1249             :         
    1250           1 : done:
    1251           1 :         smbcli_close(cli->tree, fnum);
    1252           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1253             : 
    1254           1 :         return ret;
    1255             : }
    1256             : 
    1257             : 
    1258             : /*
    1259             :   test RAW_OPEN_CREATE
    1260             : */
    1261           1 : static bool test_create(struct torture_context *tctx, struct smbcli_state *cli)
    1262             : {
    1263             :         union smb_open io;
    1264           1 :         const char *fname = BASEDIR "\\torture_create.txt";
    1265             :         NTSTATUS status;
    1266           1 :         int fnum = -1;
    1267           1 :         bool ret = true;
    1268           1 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1269             :         union smb_fileinfo finfo;
    1270             : 
    1271           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1272             : 
    1273           1 :         io.create.level = RAW_OPEN_CREATE;
    1274           1 :         io.create.in.attrib = 0;
    1275           1 :         io.create.in.write_time = 0;
    1276           1 :         io.create.in.fname = fname;
    1277           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1278           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1279           1 :         fnum = io.create.out.file.fnum;
    1280             : 
    1281           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1282           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1283             : 
    1284           1 :         smbcli_close(cli->tree, io.create.out.file.fnum);
    1285           1 :         smbcli_close(cli->tree, fnum);
    1286           1 :         smbcli_unlink(cli->tree, fname);
    1287             : 
    1288             :         /* make sure write_time works */
    1289           1 :         io.create.in.write_time = basetime;
    1290           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1291           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1292           1 :         fnum = io.create.out.file.fnum;
    1293           1 :         CHECK_TIME(basetime, write_time);
    1294             : 
    1295           1 :         smbcli_close(cli->tree, fnum);
    1296           1 :         smbcli_unlink(cli->tree, fname);
    1297             : 
    1298             :         /* make sure file_attrs works */
    1299           1 :         io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1300           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1301           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1302           1 :         fnum = io.create.out.file.fnum;
    1303           1 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
    1304             :                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
    1305             :         
    1306           1 : done:
    1307           1 :         smbcli_close(cli->tree, fnum);
    1308           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1309             : 
    1310           1 :         return ret;
    1311             : }
    1312             : 
    1313             : 
    1314             : /*
    1315             :   test RAW_OPEN_CTEMP
    1316             : */
    1317           1 : static bool test_ctemp(struct torture_context *tctx, struct smbcli_state *cli)
    1318             : {
    1319             :         union smb_open io;
    1320             :         NTSTATUS status;
    1321           1 :         int fnum = -1;
    1322           1 :         bool ret = true;
    1323           1 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1324             :         union smb_fileinfo finfo;
    1325           1 :         const char *name, *fname = NULL;
    1326             : 
    1327           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1328             : 
    1329           1 :         io.ctemp.level = RAW_OPEN_CTEMP;
    1330           1 :         io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1331           1 :         io.ctemp.in.write_time = basetime;
    1332           1 :         io.ctemp.in.directory = BASEDIR;
    1333           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1334           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1335           1 :         fnum = io.ctemp.out.file.fnum;
    1336             : 
    1337           1 :         name = io.ctemp.out.name;
    1338             : 
    1339           1 :         finfo.generic.level = RAW_FILEINFO_NAME_INFO;
    1340           1 :         finfo.generic.in.file.fnum = fnum;
    1341           1 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    1342           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1343             : 
    1344           1 :         fname = finfo.name_info.out.fname.s;
    1345           1 :         torture_comment(tctx, "ctemp name=%s  real name=%s\n", name, fname);
    1346             : 
    1347           1 : done:
    1348           1 :         smbcli_close(cli->tree, fnum);
    1349           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1350             : 
    1351           1 :         return ret;
    1352             : }
    1353             : 
    1354             : 
    1355             : /*
    1356             :   test chained RAW_OPEN_OPENX_READX
    1357             : */
    1358           1 : static bool test_chained(struct torture_context *tctx, struct smbcli_state *cli)
    1359             : {
    1360             :         union smb_open io;
    1361           1 :         const char *fname = BASEDIR "\\torture_chained.txt";
    1362             :         NTSTATUS status;
    1363           1 :         int fnum = -1;
    1364           1 :         bool ret = true;
    1365           1 :         const char buf[] = "test";
    1366             :         char buf2[4];
    1367             : 
    1368           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1369             : 
    1370           1 :         fnum = create_complex_file(cli, tctx, fname);
    1371             : 
    1372           1 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1373             : 
    1374           1 :         smbcli_close(cli->tree, fnum);       
    1375             : 
    1376           1 :         io.openxreadx.level = RAW_OPEN_OPENX_READX;
    1377           1 :         io.openxreadx.in.fname = fname;
    1378           1 :         io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1379           1 :         io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1380           1 :         io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1381           1 :         io.openxreadx.in.search_attrs = 0;
    1382           1 :         io.openxreadx.in.file_attrs = 0;
    1383           1 :         io.openxreadx.in.write_time = 0;
    1384           1 :         io.openxreadx.in.size = 1024*1024;
    1385           1 :         io.openxreadx.in.timeout = 0;
    1386             :         
    1387           1 :         io.openxreadx.in.offset = 0;
    1388           1 :         io.openxreadx.in.mincnt = sizeof(buf2);
    1389           1 :         io.openxreadx.in.maxcnt = sizeof(buf2);
    1390           1 :         io.openxreadx.in.remaining = 0;
    1391           1 :         io.openxreadx.out.data = (uint8_t *)buf2;
    1392             : 
    1393           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1394           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1395           1 :         fnum = io.openxreadx.out.file.fnum;
    1396             : 
    1397           1 :         if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
    1398           0 :                 torture_result(tctx, TORTURE_FAIL,
    1399             :                         "wrong data in reply buffer\n");
    1400           0 :                 ret = false;
    1401             :         }
    1402             : 
    1403           1 : done:
    1404           1 :         smbcli_close(cli->tree, fnum);
    1405           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1406             : 
    1407           1 :         return ret;
    1408             : }
    1409             : 
    1410             : /*
    1411             :   test RAW_OPEN_OPENX without a leading slash on the path.
    1412             :   NetApp filers are known to fail on this.
    1413             :   
    1414             : */
    1415           1 : static bool test_no_leading_slash(struct torture_context *tctx, struct smbcli_state *cli)
    1416             : {
    1417             :         union smb_open io;
    1418           1 :         const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
    1419             :         NTSTATUS status;
    1420           1 :         int fnum = -1;
    1421           1 :         bool ret = true;
    1422           1 :         const char buf[] = "test";
    1423             : 
    1424           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1425             : 
    1426           1 :         smbcli_unlink(cli->tree, fname);
    1427             : 
    1428             :         /* Create the file */
    1429           1 :         fnum = create_complex_file(cli, tctx, fname);
    1430           1 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1431           1 :         smbcli_close(cli->tree, fnum);       
    1432             : 
    1433             :         /* Prepare to open the file using path without leading slash */
    1434           1 :         io.openx.level = RAW_OPEN_OPENX;
    1435           1 :         io.openx.in.fname = fname + 1;
    1436           1 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1437           1 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1438           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1439           1 :         io.openx.in.search_attrs = 0;
    1440           1 :         io.openx.in.file_attrs = 0;
    1441           1 :         io.openx.in.write_time = 0;
    1442           1 :         io.openx.in.size = 1024*1024;
    1443           1 :         io.openx.in.timeout = 0;
    1444             : 
    1445           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1446           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1447           1 :         fnum = io.openx.out.file.fnum;
    1448             : 
    1449           1 : done:
    1450           1 :         smbcli_close(cli->tree, fnum);
    1451           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1452             : 
    1453           1 :         return ret;
    1454             : }
    1455             : 
    1456             : /*
    1457             :   test RAW_OPEN_OPENX against an existing directory to
    1458             :   ensure it returns NT_STATUS_FILE_IS_A_DIRECTORY.
    1459             :   Samba 3.2.0 - 3.2.6 are known to fail this.
    1460             :   
    1461             : */
    1462           1 : static bool test_openx_over_dir(struct torture_context *tctx, struct smbcli_state *cli)
    1463             : {
    1464             :         union smb_open io;
    1465           1 :         const char *fname = BASEDIR "\\openx_over_dir";
    1466             :         NTSTATUS status;
    1467           1 :         int d_fnum = -1;
    1468           1 :         int fnum = -1;
    1469           1 :         bool ret = true;
    1470             : 
    1471           1 :         ZERO_STRUCT(io);
    1472             : 
    1473           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1474             : 
    1475             :         /* Create the Directory */
    1476           1 :         status = create_directory_handle(cli->tree, fname, &d_fnum);
    1477           1 :         smbcli_close(cli->tree, d_fnum);     
    1478             : 
    1479             :         /* Prepare to open the file over the directory. */
    1480           1 :         io.openx.level = RAW_OPEN_OPENX;
    1481           1 :         io.openx.in.fname = fname;
    1482           1 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1483           1 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1484           1 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1485           1 :         io.openx.in.search_attrs = 0;
    1486           1 :         io.openx.in.file_attrs = 0;
    1487           1 :         io.openx.in.write_time = 0;
    1488           1 :         io.openx.in.size = 1024*1024;
    1489           1 :         io.openx.in.timeout = 0;
    1490             : 
    1491           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1492           1 :         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
    1493           1 :         fnum = io.openx.out.file.fnum;
    1494             : 
    1495           1 : done:
    1496           1 :         smbcli_close(cli->tree, fnum);
    1497           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1498             : 
    1499           1 :         return ret;
    1500             : }
    1501             : 
    1502             : 
    1503             : /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
    1504             : 
    1505           1 : static bool test_raw_open_multi(struct torture_context *tctx, struct smbcli_state *cli_ignored)
    1506             : {
    1507             :         struct smbcli_state *cli;
    1508           1 :         TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
    1509           1 :         const char *fname = "\\test_oplock.dat";
    1510             :         NTSTATUS status;
    1511           1 :         bool ret = true;
    1512             :         union smb_open io;
    1513             :         struct smbcli_state **clients;
    1514             :         struct smbcli_request **requests;
    1515             :         union smb_open *ios;
    1516           1 :         const char *host = torture_setting_string(tctx, "host", NULL);
    1517           1 :         const char *share = torture_setting_string(tctx, "share", NULL);
    1518           1 :         int i, num_files = 3;
    1519           1 :         int num_ok = 0;
    1520           1 :         int num_collision = 0;
    1521             :         
    1522           1 :         clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
    1523           1 :         requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
    1524           1 :         ios = talloc_array(mem_ctx, union smb_open, num_files);
    1525           1 :         if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
    1526             :             (ios == NULL)) {
    1527           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s): talloc failed\n",
    1528             :                                 __location__);
    1529           0 :                 return false;
    1530             :         }
    1531             : 
    1532           1 :         if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
    1533           0 :                 return false;
    1534             :         }
    1535             : 
    1536           1 :         cli->tree->session->transport->options.request_timeout = 60;
    1537             : 
    1538           4 :         for (i=0; i<num_files; i++) {
    1539           3 :                 if (!torture_open_connection_share(mem_ctx, &(clients[i]),
    1540             :                                                    tctx, host, share, tctx->ev)) {
    1541           0 :                         torture_result(tctx, TORTURE_FAIL,
    1542             :                                        "(%s): Could not open %d'th connection\n",
    1543             :                                        __location__, i);
    1544           0 :                         return false;
    1545             :                 }
    1546           3 :                 clients[i]->tree->session->transport->options.request_timeout = 60;
    1547             :         }
    1548             : 
    1549             :         /* cleanup */
    1550           1 :         smbcli_unlink(cli->tree, fname);
    1551             : 
    1552             :         /*
    1553             :           base ntcreatex parms
    1554             :         */
    1555           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1556           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1557           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1558           1 :         io.ntcreatex.in.alloc_size = 0;
    1559           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1560           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1561             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    1562             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    1563           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1564           1 :         io.ntcreatex.in.create_options = 0;
    1565           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1566           1 :         io.ntcreatex.in.security_flags = 0;
    1567           1 :         io.ntcreatex.in.fname = fname;
    1568           1 :         io.ntcreatex.in.flags = 0;
    1569             : 
    1570           4 :         for (i=0; i<num_files; i++) {
    1571           3 :                 ios[i] = io;
    1572           3 :                 requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
    1573           3 :                 if (requests[i] == NULL) {
    1574           0 :                         torture_result(tctx, TORTURE_FAIL,
    1575             :                                 "(%s): could not send %d'th request\n",
    1576             :                                 __location__, i);
    1577           0 :                         return false;
    1578             :                 }
    1579             :         }
    1580             : 
    1581           1 :         torture_comment(tctx, "waiting for replies\n");
    1582           9 :         while (1) {
    1583          10 :                 bool unreplied = false;
    1584          18 :                 for (i=0; i<num_files; i++) {
    1585          17 :                         if (requests[i] == NULL) {
    1586           5 :                                 continue;
    1587             :                         }
    1588          12 :                         if (requests[i]->state < SMBCLI_REQUEST_DONE) {
    1589           9 :                                 unreplied = true;
    1590           9 :                                 break;
    1591             :                         }
    1592           3 :                         status = smb_raw_open_recv(requests[i], mem_ctx,
    1593           3 :                                                    &ios[i]);
    1594             : 
    1595           3 :                         torture_comment(tctx, "File %d returned status %s\n", i,
    1596             :                                   nt_errstr(status));
    1597             : 
    1598           3 :                         if (NT_STATUS_IS_OK(status)) {
    1599           1 :                                 num_ok += 1;
    1600             :                         } 
    1601             : 
    1602           3 :                         if (NT_STATUS_EQUAL(status,
    1603             :                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
    1604           2 :                                 num_collision += 1;
    1605             :                         }
    1606             : 
    1607           3 :                         requests[i] = NULL;
    1608             :                 }
    1609          10 :                 if (!unreplied) {
    1610           1 :                         break;
    1611             :                 }
    1612             : 
    1613           9 :                 if (tevent_loop_once(tctx->ev) != 0) {
    1614           0 :                         torture_result(tctx, TORTURE_FAIL,
    1615             :                                 "(%s): tevent_loop_once failed\n", __location__);
    1616           0 :                         return false;
    1617             :                 }
    1618             :         }
    1619             : 
    1620           1 :         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
    1621           0 :                 ret = false;
    1622             :         }
    1623             : 
    1624           4 :         for (i=0; i<num_files; i++) {
    1625           3 :                 torture_close_connection(clients[i]);
    1626             :         }
    1627           1 :         talloc_free(mem_ctx);
    1628           1 :         return ret;
    1629             : }
    1630             : 
    1631             : /*
    1632             :   test opening for delete on a read-only attribute file.
    1633             : */
    1634           1 : static bool test_open_for_delete(struct torture_context *tctx, struct smbcli_state *cli)
    1635             : {
    1636             :         union smb_open io;
    1637             :         union smb_fileinfo finfo;
    1638           1 :         const char *fname = BASEDIR "\\torture_open_for_delete.txt";
    1639             :         NTSTATUS status;
    1640           1 :         int fnum = -1;
    1641           1 :         bool ret = true;
    1642             : 
    1643           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1644             : 
    1645             :         /* reasonable default parameters */
    1646           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1647           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1648           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1649           1 :         io.ntcreatex.in.alloc_size = 0;
    1650           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1651           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
    1652           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1653           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1654           1 :         io.ntcreatex.in.create_options = 0;
    1655           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1656           1 :         io.ntcreatex.in.security_flags = 0;
    1657           1 :         io.ntcreatex.in.fname = fname;
    1658             : 
    1659             :         /* Create the readonly file. */
    1660             : 
    1661           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1662           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1663           1 :         fnum = io.ntcreatex.out.file.fnum;
    1664             : 
    1665           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1666           1 :         io.ntcreatex.in.create_options = 0;
    1667           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    1668           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1669           1 :         smbcli_close(cli->tree, fnum);
    1670             : 
    1671             :         /* Now try and open for delete only - should succeed. */
    1672           1 :         io.ntcreatex.in.access_mask = SEC_STD_DELETE;
    1673           1 :         io.ntcreatex.in.file_attr = 0;
    1674           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    1675           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1676           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1677           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1678             : 
    1679           1 :         smbcli_unlink(cli->tree, fname);
    1680             : 
    1681           1 : done:
    1682           1 :         smbcli_close(cli->tree, fnum);
    1683           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1684             : 
    1685           1 :         return ret;
    1686             : }
    1687             : 
    1688             : /*
    1689             :   test chained RAW_OPEN_NTCREATEX_READX
    1690             :   Send chained NTCREATEX_READX on a file that doesn't exist, then create
    1691             :   the file and try again.
    1692             : */
    1693           1 : static bool test_chained_ntcreatex_readx(struct torture_context *tctx, struct smbcli_state *cli)
    1694             : {
    1695           1 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    1696             :         union smb_open io;
    1697           1 :         const char *fname = BASEDIR "\\torture_chained.txt";
    1698             :         NTSTATUS status;
    1699           1 :         int fnum = -1;
    1700           1 :         bool ret = true;
    1701           1 :         const char buf[] = "test";
    1702             :         char buf2[4];
    1703             : 
    1704           1 :         ZERO_STRUCT(io);
    1705             : 
    1706           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1707             : 
    1708           1 :         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
    1709             :                               "non-existent file \n");
    1710             : 
    1711             :         /* ntcreatex parameters */
    1712           1 :         io.generic.level = RAW_OPEN_NTCREATEX_READX;
    1713           1 :         io.ntcreatexreadx.in.flags = 0;
    1714           1 :         io.ntcreatexreadx.in.root_fid.fnum = 0;
    1715           1 :         io.ntcreatexreadx.in.access_mask = SEC_FILE_READ_DATA;
    1716           1 :         io.ntcreatexreadx.in.alloc_size = 0;
    1717           1 :         io.ntcreatexreadx.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1718           1 :         io.ntcreatexreadx.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1719             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    1720           1 :         io.ntcreatexreadx.in.open_disposition = NTCREATEX_DISP_OPEN;
    1721           1 :         io.ntcreatexreadx.in.create_options = 0;
    1722           1 :         io.ntcreatexreadx.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1723           1 :         io.ntcreatexreadx.in.security_flags = 0;
    1724           1 :         io.ntcreatexreadx.in.fname = fname;
    1725             : 
    1726             :         /* readx parameters */
    1727           1 :         io.ntcreatexreadx.in.offset = 0;
    1728           1 :         io.ntcreatexreadx.in.mincnt = sizeof(buf2);
    1729           1 :         io.ntcreatexreadx.in.maxcnt = sizeof(buf2);
    1730           1 :         io.ntcreatexreadx.in.remaining = 0;
    1731           1 :         io.ntcreatexreadx.out.data = (uint8_t *)buf2;
    1732             : 
    1733             :         /* try to open the non-existent file */
    1734           1 :         status = smb_raw_open(cli->tree, mem_ctx, &io);
    1735           1 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1736           1 :         fnum = io.ntcreatexreadx.out.file.fnum;
    1737             : 
    1738           1 :         smbcli_close(cli->tree, fnum);
    1739           1 :         smbcli_unlink(cli->tree, fname);
    1740             : 
    1741           1 :         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
    1742             :                               "existing file \n");
    1743             : 
    1744           1 :         fnum = create_complex_file(cli, mem_ctx, fname);
    1745           1 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1746           1 :         smbcli_close(cli->tree, fnum);
    1747             : 
    1748           1 :         status = smb_raw_open(cli->tree, mem_ctx, &io);
    1749           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    1750           1 :         fnum = io.ntcreatexreadx.out.file.fnum;
    1751             : 
    1752           1 :         if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
    1753           0 :                 torture_result(tctx, TORTURE_FAIL,
    1754             :                         "(%s): wrong data in reply buffer\n", __location__);
    1755           0 :                 ret = false;
    1756             :         }
    1757             : 
    1758           1 : done:
    1759           1 :         smbcli_close(cli->tree, fnum);
    1760           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1761           1 :         talloc_free(mem_ctx);
    1762             : 
    1763           1 :         return ret;
    1764             : }
    1765             : 
    1766           1 : static bool test_ntcreatex_opendisp_dir(struct torture_context *tctx,
    1767             :                                         struct smbcli_state *cli)
    1768             : {
    1769           1 :         const char *dname = BASEDIR "\\torture_ntcreatex_opendisp_dir";
    1770             :         NTSTATUS status;
    1771           1 :         bool ret = true;
    1772             :         int i;
    1773             :         struct {
    1774             :                 uint32_t open_disp;
    1775             :                 bool dir_exists;
    1776             :                 NTSTATUS correct_status;
    1777           1 :         } open_funcs_dir[] = {
    1778             :                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_INVALID_PARAMETER },
    1779             :                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_INVALID_PARAMETER },
    1780             :                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
    1781             :                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1782             :                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
    1783             :                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
    1784             :                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
    1785             :                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
    1786             :                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_INVALID_PARAMETER },
    1787             :                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_INVALID_PARAMETER },
    1788             :                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_INVALID_PARAMETER },
    1789             :                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_INVALID_PARAMETER },
    1790             :                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
    1791             :                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
    1792             :         };
    1793             :         union smb_open io;
    1794             : 
    1795           1 :         ZERO_STRUCT(io);
    1796           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1797           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1798           1 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1799           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1800           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1801           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1802           1 :         io.ntcreatex.in.fname = dname;
    1803             : 
    1804           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1805             : 
    1806           1 :         smbcli_rmdir(cli->tree, dname);
    1807           1 :         smbcli_unlink(cli->tree, dname);
    1808             : 
    1809             :         /* test the open disposition for directories */
    1810           1 :         torture_comment(tctx, "Testing open dispositions for directories...\n");
    1811             : 
    1812          15 :         for (i=0; i<ARRAY_SIZE(open_funcs_dir); i++) {
    1813          14 :                 if (open_funcs_dir[i].dir_exists) {
    1814           7 :                         status = smbcli_mkdir(cli->tree, dname);
    1815           7 :                         if (!NT_STATUS_IS_OK(status)) {
    1816           0 :                                 torture_result(tctx, TORTURE_FAIL,
    1817             :                                         "(%s): Failed to make directory "
    1818             :                                         "%s - %s\n", __location__, dname,
    1819             :                                         smbcli_errstr(cli->tree));
    1820           0 :                                 ret = false;
    1821           0 :                                 goto done;
    1822             :                         }
    1823             :                 }
    1824             : 
    1825          14 :                 io.ntcreatex.in.open_disposition = open_funcs_dir[i].open_disp;
    1826          14 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1827          14 :                 if (!NT_STATUS_EQUAL(status, open_funcs_dir[i].correct_status)) {
    1828           0 :                         torture_result(tctx, TORTURE_FAIL,
    1829             :                                 "(%s) incorrect status %s should be %s "
    1830             :                                 "(i=%d dir_exists=%d open_disp=%d)\n",
    1831             :                                 __location__, nt_errstr(status),
    1832             :                                 nt_errstr(open_funcs_dir[i].correct_status),
    1833           0 :                                 i, (int)open_funcs_dir[i].dir_exists,
    1834           0 :                                 (int)open_funcs_dir[i].open_disp);
    1835           0 :                         ret = false;
    1836             :                 }
    1837          14 :                 if (NT_STATUS_IS_OK(status) || open_funcs_dir[i].dir_exists) {
    1838           9 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1839           9 :                         smbcli_rmdir(cli->tree, dname);
    1840             :                 }
    1841             :         }
    1842             : 
    1843           1 : done:
    1844           1 :         smbcli_deltree(cli->tree, BASEDIR);
    1845             : 
    1846           1 :         return ret;
    1847             : }
    1848             : 
    1849             : /**
    1850             :  * Test what happens when trying to open a file with directory parameters and
    1851             :  * vice-versa.  Also test that NTCREATEX_OPTIONS_DIRECTORY is treated as
    1852             :  * mandatory and FILE_ATTRIBUTE_DIRECTORY is advisory for directory
    1853             :  * creation/opening.
    1854             :  */
    1855           1 : static bool test_ntcreatexdir(struct torture_context *tctx,
    1856             :     struct smbcli_state *cli)
    1857             : {
    1858             :         union smb_open io;
    1859           1 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
    1860           1 :         const char *dname = BASEDIR "\\torture_ntcreatex_dir";
    1861             :         NTSTATUS status;
    1862             :         int i;
    1863             : 
    1864             :         struct {
    1865             :                 uint32_t open_disp;
    1866             :                 uint32_t file_attr;
    1867             :                 uint32_t create_options;
    1868             :                 NTSTATUS correct_status;
    1869           1 :         } open_funcs[] = {
    1870             :                 { NTCREATEX_DISP_SUPERSEDE,     0, NTCREATEX_OPTIONS_DIRECTORY,
    1871             :                   NT_STATUS_INVALID_PARAMETER },
    1872             :                 { NTCREATEX_DISP_OPEN,          0, NTCREATEX_OPTIONS_DIRECTORY,
    1873             :                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1874             :                 { NTCREATEX_DISP_CREATE,        0, NTCREATEX_OPTIONS_DIRECTORY,
    1875             :                   NT_STATUS_OK },
    1876             :                 { NTCREATEX_DISP_OPEN_IF,       0, NTCREATEX_OPTIONS_DIRECTORY,
    1877             :                   NT_STATUS_OK },
    1878             :                 { NTCREATEX_DISP_OVERWRITE,     0, NTCREATEX_OPTIONS_DIRECTORY,
    1879             :                   NT_STATUS_INVALID_PARAMETER },
    1880             :                 { NTCREATEX_DISP_OVERWRITE_IF,  0, NTCREATEX_OPTIONS_DIRECTORY,
    1881             :                   NT_STATUS_INVALID_PARAMETER },
    1882             :                 { NTCREATEX_DISP_SUPERSEDE,     FILE_ATTRIBUTE_DIRECTORY, 0,
    1883             :                   NT_STATUS_OK },
    1884             :                 { NTCREATEX_DISP_OPEN,          FILE_ATTRIBUTE_DIRECTORY, 0,
    1885             :                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1886             :                 { NTCREATEX_DISP_CREATE,        FILE_ATTRIBUTE_DIRECTORY, 0,
    1887             :                   NT_STATUS_OK },
    1888             :                 { NTCREATEX_DISP_OPEN_IF,       FILE_ATTRIBUTE_DIRECTORY, 0,
    1889             :                   NT_STATUS_OK },
    1890             :                 { NTCREATEX_DISP_OVERWRITE,     FILE_ATTRIBUTE_DIRECTORY, 0,
    1891             :                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1892             :                 { NTCREATEX_DISP_OVERWRITE_IF,  FILE_ATTRIBUTE_DIRECTORY, 0,
    1893             :                   NT_STATUS_OK },
    1894             : 
    1895             :         };
    1896             : 
    1897           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1898             : 
    1899             :         /* setup some base params. */
    1900           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1901           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1902           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    1903           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1904           1 :         io.ntcreatex.in.alloc_size = 0;
    1905           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1906           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1907           1 :         io.ntcreatex.in.security_flags = 0;
    1908           1 :         io.ntcreatex.in.fname = fname;
    1909             : 
    1910             :         /*
    1911             :          * Test the validity checking for create dispositions, which is done
    1912             :          * against the requested parameters rather than what's actually on
    1913             :          * disk.
    1914             :          */
    1915          13 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
    1916          12 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
    1917          12 :                 io.ntcreatex.in.file_attr = open_funcs[i].file_attr;
    1918          12 :                 io.ntcreatex.in.create_options = open_funcs[i].create_options;
    1919          12 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1920          12 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
    1921           0 :                         torture_result(tctx, TORTURE_FAIL,
    1922             :                                 "(%s) incorrect status %s should be %s "
    1923             :                                 "(i=%d open_disp=%d)\n",
    1924             :                                 __location__, nt_errstr(status),
    1925             :                                 nt_errstr(open_funcs[i].correct_status),
    1926           0 :                                 i, (int)open_funcs[i].open_disp);
    1927           0 :                         return false;
    1928             :                 }
    1929             :                 /* Close and delete the file. */
    1930          12 :                 if (NT_STATUS_IS_OK(status)) {
    1931           6 :                         if (open_funcs[i].create_options != 0) {
    1932             :                                 /* out attrib should be a directory. */
    1933           2 :                                 torture_assert_int_equal(tctx,
    1934             :                                     io.ntcreatex.out.attrib,
    1935             :                                     FILE_ATTRIBUTE_DIRECTORY, "should have "
    1936             :                                     "created a directory");
    1937             : 
    1938           2 :                                 smbcli_close(cli->tree,
    1939           2 :                                     io.ntcreatex.out.file.fnum);
    1940             : 
    1941             :                                 /* Make sure unlink fails. */
    1942           2 :                                 status = smbcli_unlink(cli->tree, fname);
    1943           2 :                                 torture_assert_ntstatus_equal(tctx, status,
    1944             :                                     NT_STATUS_FILE_IS_A_DIRECTORY,
    1945             :                                     "unlink should fail for a directory");
    1946             : 
    1947           2 :                                 status = smbcli_rmdir(cli->tree, fname);
    1948           2 :                                 torture_assert_ntstatus_ok(tctx, status,
    1949             :                                     "rmdir failed");
    1950             :                         } else {
    1951           4 :                                 torture_assert_int_equal(tctx,
    1952             :                                     io.ntcreatex.out.attrib,
    1953             :                                     FILE_ATTRIBUTE_ARCHIVE, "should not have "
    1954             :                                     "created a directory");
    1955             : 
    1956           4 :                                 smbcli_close(cli->tree,
    1957           4 :                                     io.ntcreatex.out.file.fnum);
    1958             : 
    1959             :                                 /* Make sure rmdir fails. */
    1960           4 :                                 status = smbcli_rmdir(cli->tree, fname);
    1961           4 :                                 torture_assert_ntstatus_equal(tctx, status,
    1962             :                                     NT_STATUS_NOT_A_DIRECTORY,
    1963             :                                     "rmdir should fail for a file");
    1964             : 
    1965           4 :                                 status = smbcli_unlink(cli->tree, fname);
    1966           4 :                                 torture_assert_ntstatus_ok(tctx, status,
    1967             :                                     "unlink failed");
    1968             :                         }
    1969             :                 }
    1970             :         }
    1971             : 
    1972             :         /* Create a file. */
    1973           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1974           1 :         io.ntcreatex.in.create_options = 0;
    1975           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1976           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1977           1 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create file.");
    1978           1 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1979             : 
    1980             :         /* Try and open the file with file_attr_dir and check the error. */
    1981           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1982           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1983             : 
    1984           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1985           1 :         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_DIRECTORY "
    1986             :             "doesn't produce a hard failure.");
    1987           1 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1988             : 
    1989             :         /* Try and open file with createx_option_dir and check the error. */
    1990           1 :         io.ntcreatex.in.file_attr = 0;
    1991           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1992             : 
    1993           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    1994           1 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_A_DIRECTORY,
    1995             :             "NTCREATEX_OPTIONS_DIRECTORY will a file from being opened.");
    1996           1 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1997             : 
    1998             :         /* Delete the file and move onto directory testing. */
    1999           1 :         smbcli_unlink(cli->tree, fname);
    2000             : 
    2001             :         /* Now try some tests on a directory. */
    2002           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2003           1 :         io.ntcreatex.in.file_attr = 0;
    2004           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    2005           1 :         io.ntcreatex.in.fname = dname;
    2006             : 
    2007           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2008           1 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create dir.");
    2009             : 
    2010             :         /* out attrib should be a directory. */
    2011           1 :         torture_assert_int_equal(tctx, io.ntcreatex.out.attrib,
    2012             :             FILE_ATTRIBUTE_DIRECTORY, "should have created a directory");
    2013             : 
    2014           1 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2015             : 
    2016             :         /* Try and open it with normal attr and check the error. */
    2017           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2018           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    2019             : 
    2020           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2021           1 :         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_NORMAL "
    2022             :             "doesn't produce a hard failure.");
    2023           1 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2024             : 
    2025             :         /* Try and open it with file create_options and check the error. */
    2026           1 :         io.ntcreatex.in.file_attr = 0;
    2027           1 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    2028             : 
    2029           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2030           1 :         torture_assert_ntstatus_equal(tctx, status,
    2031             :             NT_STATUS_FILE_IS_A_DIRECTORY,
    2032             :             "NTCREATEX_OPTIONS_NON_DIRECTORY_FILE should be returned ");
    2033           1 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2034             : 
    2035           1 :         smbcli_deltree(cli->tree, BASEDIR);
    2036             : 
    2037           1 :         return true;
    2038             : }
    2039             : 
    2040             : /*
    2041             :   test opening with truncate on an already open file
    2042             :   returns share violation and doesn't truncate the file.
    2043             :   Regression test for bug #10671.
    2044             : */
    2045           1 : static bool test_open_for_truncate(struct torture_context *tctx, struct smbcli_state *cli)
    2046             : {
    2047             :         union smb_open io;
    2048             :         union smb_fileinfo finfo;
    2049           1 :         const char *fname = BASEDIR "\\torture_open_for_truncate.txt";
    2050             :         NTSTATUS status;
    2051           1 :         int fnum = -1;
    2052           1 :         ssize_t val = 0;
    2053           1 :         char c = '\0';
    2054           1 :         bool ret = true;
    2055             : 
    2056           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
    2057             :                 "Failed to setup up test directory: " BASEDIR);
    2058             : 
    2059           1 :         torture_comment(tctx, "Testing open truncate disposition.\n");
    2060             : 
    2061             :         /* reasonable default parameters */
    2062           1 :         ZERO_STRUCT(io);
    2063           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2064           1 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    2065           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2066           1 :         io.ntcreatex.in.alloc_size = 0;
    2067           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2068           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2069           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2070           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2071           1 :         io.ntcreatex.in.create_options = 0;
    2072           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2073           1 :         io.ntcreatex.in.security_flags = 0;
    2074           1 :         io.ntcreatex.in.fname = fname;
    2075             : 
    2076           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2077           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2078           1 :         fnum = io.ntcreatex.out.file.fnum;
    2079             : 
    2080             :         /* Write a byte at offset 1k-1. */
    2081           1 :         val =smbcli_write(cli->tree, fnum, 0, &c, 1023, 1);
    2082           1 :         torture_assert_int_equal(tctx, val, 1, "write failed\n");
    2083             : 
    2084             :         /* Now try and open for read/write with truncate - should fail. */
    2085           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE|SEC_RIGHTS_FILE_READ;
    2086           1 :         io.ntcreatex.in.file_attr = 0;
    2087           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    2088             :                         NTCREATEX_SHARE_ACCESS_WRITE |
    2089             :                         NTCREATEX_SHARE_ACCESS_DELETE;
    2090           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
    2091           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2092           1 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
    2093             : 
    2094             :         /* Ensure file size is still 1k */
    2095           1 :         finfo.generic.level = RAW_FILEINFO_GETATTRE;
    2096           1 :         finfo.generic.in.file.fnum = fnum;
    2097           1 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    2098           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2099           1 :         CHECK_VAL(finfo.getattre.out.size, 1024);
    2100             : 
    2101           1 :         smbcli_close(cli->tree, fnum);
    2102             : 
    2103           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2104           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2105           1 :         fnum = io.ntcreatex.out.file.fnum;
    2106             : 
    2107             :         /* Ensure truncate actually works */
    2108           1 :         finfo.generic.level = RAW_FILEINFO_GETATTRE;
    2109           1 :         finfo.generic.in.file.fnum = fnum;
    2110           1 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    2111           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2112           1 :         CHECK_VAL(finfo.getattre.out.size, 0);
    2113             : 
    2114           1 :         smbcli_close(cli->tree, fnum);
    2115           1 :         smbcli_unlink(cli->tree, fname);
    2116             : 
    2117           1 : done:
    2118           1 :         smbcli_close(cli->tree, fnum);
    2119           1 :         smbcli_deltree(cli->tree, BASEDIR);
    2120             : 
    2121           1 :         return ret;
    2122             : }
    2123             : 
    2124             : /**
    2125             :  * Test for file size to be 0 after create with FILE_SUPERSEDE
    2126             :  */
    2127           1 : static bool test_ntcreatex_supersede(struct torture_context *tctx, struct smbcli_state *cli)
    2128             : {
    2129             :         union smb_open io;
    2130             :         union smb_setfileinfo sfi;
    2131             :         union smb_fileinfo finfo;
    2132           1 :         const char *fname = BASEDIR "\\torture_ntcreatex_supersede.txt";
    2133             :         NTSTATUS status;
    2134           1 :         int fnum = -1;
    2135           1 :         bool ret = true;
    2136             : 
    2137           1 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    2138             : 
    2139             :         /* reasonable default parameters */
    2140           1 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2141           1 :         io.ntcreatex.in.flags = 0;
    2142           1 :         io.ntcreatex.in.root_fid.fnum = 0;
    2143           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2144           1 :         io.ntcreatex.in.alloc_size = 0;
    2145           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2146           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2147           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2148           1 :         io.ntcreatex.in.create_options = 0;
    2149           1 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2150           1 :         io.ntcreatex.in.security_flags = 0;
    2151           1 :         io.ntcreatex.in.fname = fname;
    2152             : 
    2153           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2154           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2155           1 :         fnum = io.ntcreatex.out.file.fnum;
    2156             : 
    2157           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2158           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    2159           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2160           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2161           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    2162           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    2163           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2164           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2165           1 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    2166           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2167           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2168             : 
    2169             :         /* extend the file size */
    2170           1 :         ZERO_STRUCT(sfi);
    2171           1 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
    2172           1 :         sfi.generic.in.file.fnum = fnum;
    2173           1 :         sfi.end_of_file_info.in.size = 512;
    2174           1 :         status = smb_raw_setfileinfo(cli->tree, &sfi);
    2175           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2176             : 
    2177             :         /* close the file and re-open with to verify new size */
    2178           1 :         smbcli_close(cli->tree, fnum);
    2179           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    2180           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
    2181           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2182           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2183           1 :         fnum = io.ntcreatex.out.file.fnum;
    2184             : 
    2185           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2186           1 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
    2187           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2188           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2189           1 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    2190           1 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    2191           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2192           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2193           1 :         CHECK_VAL(io.ntcreatex.out.size, 512);
    2194           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2195           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2196             : 
    2197             :         /* close and re-open the file with SUPERSEDE flag */
    2198           1 :         smbcli_close(cli->tree, fnum);
    2199           1 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
    2200           1 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
    2201           1 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2202           1 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2203           1 :         io.ntcreatex.in.create_options = 0;
    2204             : 
    2205           1 :         status = smb_raw_open(cli->tree, tctx, &io);
    2206           1 :         CHECK_STATUS(status, NT_STATUS_OK);
    2207           1 :         fnum = io.ntcreatex.out.file.fnum;
    2208             : 
    2209             :         /* The file size in the superseded create response should be 0 */
    2210           1 :         CHECK_VAL(io.ntcreatex.out.size, 0);
    2211           1 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2212           1 :         CHECK_VAL(io.ntcreatex.out.create_action, FILE_WAS_SUPERSEDED);
    2213           1 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2214           1 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2215           1 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2216           1 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2217           1 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2218           1 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2219           1 : done:
    2220           1 :         smbcli_close(cli->tree, fnum);
    2221           1 :         smbcli_deltree(cli->tree, BASEDIR);
    2222             : 
    2223           1 :         return ret;
    2224             : }
    2225             : 
    2226             : /* basic testing of all RAW_OPEN_* calls
    2227             : */
    2228         966 : struct torture_suite *torture_raw_open(TALLOC_CTX *mem_ctx)
    2229             : {
    2230         966 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "open");
    2231             : 
    2232         966 :         torture_suite_add_1smb_test(suite, "brlocked", test_ntcreatex_brlocked);
    2233         966 :         torture_suite_add_1smb_test(suite, "open", test_open);
    2234         966 :         torture_suite_add_1smb_test(suite, "open-multi", test_raw_open_multi);
    2235         966 :         torture_suite_add_1smb_test(suite, "openx", test_openx);
    2236         966 :         torture_suite_add_1smb_test(suite, "ntcreatex", test_ntcreatex);
    2237         966 :         torture_suite_add_1smb_test(suite, "nttrans-create", test_nttrans_create);
    2238         966 :         torture_suite_add_1smb_test(suite, "t2open", test_t2open);
    2239         966 :         torture_suite_add_1smb_test(suite, "mknew", test_mknew);
    2240         966 :         torture_suite_add_1smb_test(suite, "create", test_create);
    2241         966 :         torture_suite_add_1smb_test(suite, "ctemp", test_ctemp);
    2242         966 :         torture_suite_add_1smb_test(suite, "chained-openx", test_chained);
    2243         966 :         torture_suite_add_1smb_test(suite, "chained-ntcreatex", test_chained_ntcreatex_readx);
    2244         966 :         torture_suite_add_1smb_test(suite, "no-leading-slash", test_no_leading_slash);
    2245         966 :         torture_suite_add_1smb_test(suite, "openx-over-dir", test_openx_over_dir);
    2246         966 :         torture_suite_add_1smb_test(suite, "open-for-delete", test_open_for_delete);
    2247         966 :         torture_suite_add_1smb_test(suite, "opendisp-dir", test_ntcreatex_opendisp_dir);
    2248         966 :         torture_suite_add_1smb_test(suite, "ntcreatedir", test_ntcreatexdir);
    2249         966 :         torture_suite_add_1smb_test(suite, "open-for-truncate", test_open_for_truncate);
    2250         966 :         torture_suite_add_1smb_test(suite, "ntcreatex_supersede", test_ntcreatex_supersede);
    2251             : 
    2252         966 :         return suite;
    2253             : }

Generated by: LCOV version 1.14