LCOV - code coverage report
Current view: top level - source4/torture/raw - open.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 1273 1350 94.3 %
Date: 2024-02-28 12:06:22 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          48 : static enum rdwr_mode check_rdwr(struct smbcli_tree *tree, int fnum)
      38             : {
      39          48 :         uint8_t c = 1;
      40          48 :         bool can_read  = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
      41          48 :         bool can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
      42          48 :         if ( can_read &&  can_write) return RDWR_RDWR;
      43          24 :         if ( can_read && !can_write) return RDWR_RDONLY;
      44           6 :         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           6 : static bool test_open(struct torture_context *tctx, struct smbcli_state *cli)
     162             : {
     163           1 :         union smb_open io;
     164           1 :         union smb_fileinfo finfo;
     165           6 :         const char *fname = BASEDIR "\\torture_open.txt";
     166           1 :         NTSTATUS status;
     167           6 :         int fnum = -1, fnum2;
     168           6 :         bool ret = true;
     169             : 
     170           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     171             : 
     172           6 :         io.openold.level = RAW_OPEN_OPEN;
     173           6 :         io.openold.in.fname = fname;
     174           6 :         io.openold.in.open_mode = OPEN_FLAGS_FCB;
     175           6 :         io.openold.in.search_attrs = 0;
     176           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     177           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     178           6 :         fnum = io.openold.out.file.fnum;
     179             : 
     180           6 :         smbcli_unlink(cli->tree, fname);
     181           6 :         CREATE_FILE;
     182           6 :         smbcli_close(cli->tree, fnum);
     183             : 
     184           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     185           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     186           6 :         fnum = io.openold.out.file.fnum;
     187           6 :         CHECK_RDWR(fnum, RDWR_RDWR);
     188             : 
     189           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     190           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     191           6 :         fnum2 = io.openold.out.file.fnum;
     192           6 :         CHECK_RDWR(fnum2, RDWR_RDWR);
     193           6 :         smbcli_close(cli->tree, fnum2);
     194           6 :         smbcli_close(cli->tree, fnum);
     195             : 
     196             :         /* check the read/write modes */
     197           6 :         io.openold.level = RAW_OPEN_OPEN;
     198           6 :         io.openold.in.fname = fname;
     199           6 :         io.openold.in.search_attrs = 0;
     200             : 
     201           6 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
     202           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     203           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     204           6 :         fnum = io.openold.out.file.fnum;
     205           6 :         CHECK_RDWR(fnum, RDWR_RDONLY);
     206           6 :         smbcli_close(cli->tree, fnum);
     207             : 
     208           6 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
     209           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     210           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     211           6 :         fnum = io.openold.out.file.fnum;
     212           6 :         CHECK_RDWR(fnum, RDWR_WRONLY);
     213           6 :         smbcli_close(cli->tree, fnum);
     214             : 
     215           6 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
     216           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     217           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     218           6 :         fnum = io.openold.out.file.fnum;
     219           6 :         CHECK_RDWR(fnum, RDWR_RDWR);
     220           6 :         smbcli_close(cli->tree, fnum);
     221             : 
     222             :         /* check the share modes roughly - not a complete matrix */
     223           6 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
     224           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     225           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     226           6 :         fnum = io.openold.out.file.fnum;
     227           6 :         CHECK_RDWR(fnum, RDWR_RDWR);
     228             :         
     229           6 :         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           6 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
     235           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     236           6 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     237             : 
     238           6 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
     239           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     240           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     241           6 :         fnum2 = io.openold.out.file.fnum;
     242           6 :         CHECK_RDWR(fnum2, RDWR_RDONLY);
     243           6 :         smbcli_close(cli->tree, fnum);
     244           6 :         smbcli_close(cli->tree, fnum2);
     245             : 
     246             : 
     247             :         /* check the returned write time */
     248           6 :         io.openold.level = RAW_OPEN_OPEN;
     249           6 :         io.openold.in.fname = fname;
     250           6 :         io.openold.in.search_attrs = 0;
     251           6 :         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
     252           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     253           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     254           6 :         fnum = io.openold.out.file.fnum;
     255             : 
     256             :         /* check other reply fields */
     257           6 :         CHECK_TIME(io.openold.out.write_time, write_time);
     258           6 :         CHECK_ALL_INFO(io.openold.out.size, size);
     259           6 :         CHECK_ALL_INFO(io.openold.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     260             : 
     261           6 : done:
     262           6 :         smbcli_close(cli->tree, fnum);
     263           6 :         smbcli_deltree(cli->tree, BASEDIR);
     264             : 
     265           6 :         return ret;
     266             : }
     267             : 
     268             : 
     269             : /*
     270             :   test RAW_OPEN_OPENX
     271             : */
     272           6 : static bool test_openx(struct torture_context *tctx, struct smbcli_state *cli)
     273             : {
     274           1 :         union smb_open io;
     275           1 :         union smb_fileinfo finfo;
     276           6 :         const char *fname = BASEDIR "\\torture_openx.txt";
     277           6 :         const char *fname_exe = BASEDIR "\\torture_openx.exe";
     278           1 :         NTSTATUS status;
     279           6 :         int fnum = -1, fnum2;
     280           6 :         bool ret = true;
     281           1 :         int i;
     282           1 :         struct timeval tv;
     283           1 :         struct {
     284             :                 uint16_t open_func;
     285             :                 bool with_file;
     286             :                 NTSTATUS correct_status;
     287           6 :         } 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           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     303             : 
     304           6 :         io.openx.level = RAW_OPEN_OPENX;
     305           6 :         io.openx.in.fname = fname;
     306           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     307           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
     308           6 :         io.openx.in.search_attrs = 0;
     309           6 :         io.openx.in.file_attrs = 0;
     310           6 :         io.openx.in.write_time = 0;
     311           6 :         io.openx.in.size = 1024*1024;
     312           6 :         io.openx.in.timeout = 0;
     313             : 
     314             :         /* check all combinations of open_func */
     315          78 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     316          72 :                 if (open_funcs[i].with_file) {
     317          36 :                         fnum = create_complex_file(cli, tctx, fname);
     318          36 :                         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          36 :                         smbcli_close(cli->tree, fnum);
     326             :                 }
     327          72 :                 io.openx.in.open_func = open_funcs[i].open_func;
     328          72 :                 status = smb_raw_open(cli->tree, tctx, &io);
     329          72 :                 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          72 :                 if (NT_STATUS_IS_OK(status)) {
     340          42 :                         smbcli_close(cli->tree, io.openx.out.file.fnum);
     341             :                 }
     342          72 :                 if (open_funcs[i].with_file) {
     343          36 :                         smbcli_unlink(cli->tree, fname);
     344             :                 }
     345             :         }
     346             : 
     347           6 :         smbcli_unlink(cli->tree, fname);
     348             : 
     349             :         /* check the basic return fields */
     350           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     351           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     352           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     353           6 :         fnum = io.openx.out.file.fnum;
     354             : 
     355           6 :         CHECK_ALL_INFO(io.openx.out.size, size);
     356           6 :         CHECK_TIME(io.openx.out.write_time, write_time);
     357           6 :         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     358           6 :         CHECK_VAL(io.openx.out.access, OPENX_MODE_ACCESS_RDWR);
     359           6 :         CHECK_VAL(io.openx.out.ftype, 0);
     360           6 :         CHECK_VAL(io.openx.out.devstate, 0);
     361           6 :         CHECK_VAL(io.openx.out.action, OPENX_ACTION_CREATED);
     362           6 :         CHECK_VAL(io.openx.out.size, 1024*1024);
     363           6 :         CHECK_ALL_INFO(io.openx.in.size, size);
     364           6 :         smbcli_close(cli->tree, fnum);
     365           6 :         smbcli_unlink(cli->tree, fname);
     366             : 
     367             :         /* check the fields when the file already existed */
     368           6 :         fnum2 = create_complex_file(cli, tctx, fname);
     369           6 :         if (fnum2 == -1) {
     370           0 :                 ret = false;
     371           0 :                 goto done;
     372             :         }
     373           6 :         smbcli_close(cli->tree, fnum2);
     374             : 
     375           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
     376           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     377           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     378           6 :         fnum = io.openx.out.file.fnum;
     379             : 
     380           6 :         CHECK_ALL_INFO(io.openx.out.size, size);
     381           6 :         CHECK_TIME(io.openx.out.write_time, write_time);
     382           6 :         CHECK_VAL(io.openx.out.action, OPENX_ACTION_EXISTED);
     383           6 :         CHECK_VAL(io.openx.out.unknown, 0);
     384           6 :         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     385           6 :         smbcli_close(cli->tree, fnum);
     386             : 
     387             :         /* now check the search attrib for hidden files - win2003 ignores this? */
     388           6 :         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
     389           6 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
     390             : 
     391           6 :         io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
     392           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     393           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     394           6 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     395             : 
     396           6 :         io.openx.in.search_attrs = 0;
     397           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     398           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     399           6 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     400             : 
     401           6 :         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
     402           6 :         smbcli_unlink(cli->tree, fname);
     403             : 
     404             :         /* and check attrib on create */
     405           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
     406           6 :         io.openx.in.search_attrs = 0;
     407           6 :         io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
     408           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     409           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     410           6 :         if (torture_setting_bool(tctx, "samba3", false)) {
     411           5 :                 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           6 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     420           6 :         smbcli_unlink(cli->tree, fname);
     421             : 
     422             :         /* check timeout on create - win2003 ignores the timeout! */
     423           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     424           6 :         io.openx.in.file_attrs = 0;
     425           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
     426           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     427           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     428           6 :         fnum = io.openx.out.file.fnum;
     429             : 
     430           6 :         io.openx.in.timeout = 20000;
     431           6 :         tv = timeval_current();
     432           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
     433           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     434           6 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     435           6 :         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           6 :         smbcli_close(cli->tree, fnum);
     443           6 :         smbcli_unlink(cli->tree, fname);
     444             : 
     445             :         /* now this is a really weird one - open for execute implies create?! */
     446           6 :         io.openx.in.fname = fname;
     447           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     448           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
     449           6 :         io.openx.in.search_attrs = 0;
     450           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL;
     451           6 :         io.openx.in.file_attrs = 0;
     452           6 :         io.openx.in.write_time = 0;
     453           6 :         io.openx.in.size = 0;
     454           6 :         io.openx.in.timeout = 0;
     455           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     456           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     457           6 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     458             : 
     459             :         /* check the extended return flag */
     460           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
     461           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
     462           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     463           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     464           6 :         CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
     465           6 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     466             : 
     467           6 :         io.openx.in.fname = "\\A.+,;=[].B";
     468           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     469           6 :         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           6 :         smbcli_unlink(cli->tree, fname_exe);
     475           6 :         fnum = create_complex_file(cli, tctx, fname_exe);
     476           6 :         smbcli_close(cli->tree, fnum);
     477             : 
     478           6 :         io.openx.level = RAW_OPEN_OPENX;
     479           6 :         io.openx.in.fname = fname_exe;
     480           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     481           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
     482           6 :         io.openx.in.search_attrs = 0;
     483           6 :         io.openx.in.file_attrs = 0;
     484           6 :         io.openx.in.write_time = 0;
     485           6 :         io.openx.in.size = 0;
     486           6 :         io.openx.in.timeout = 0;
     487           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     488           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     489             : 
     490             :         /* Can we read and write ? */
     491           6 :         CHECK_RDWR(io.openx.out.file.fnum, RDWR_RDONLY);
     492           6 :         smbcli_close(cli->tree, io.openx.out.file.fnum);
     493           6 :         smbcli_unlink(cli->tree, fname);
     494             : 
     495           6 : done:
     496           6 :         smbcli_close(cli->tree, fnum);
     497           6 :         smbcli_deltree(cli->tree, BASEDIR);
     498             : 
     499           6 :         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           6 : static bool test_t2open(struct torture_context *tctx, struct smbcli_state *cli)
     509             : {
     510           1 :         union smb_open io;
     511           1 :         union smb_fileinfo finfo;
     512           6 :         const char *fname1 = BASEDIR "\\torture_t2open_yes.txt";
     513           6 :         const char *fname2 = BASEDIR "\\torture_t2open_no.txt";
     514           6 :         const char *fname = BASEDIR "\\torture_t2open_3.txt";
     515           1 :         NTSTATUS status;
     516           1 :         int fnum;
     517           6 :         bool ret = true;
     518           1 :         int i;
     519           1 :         struct {
     520             :                 uint16_t open_func;
     521             :                 bool with_file;
     522             :                 NTSTATUS correct_status;
     523           6 :         } 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           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     539             : 
     540           6 :         fnum = create_complex_file(cli, tctx, fname1);
     541           6 :         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           6 :         smbcli_close(cli->tree, fnum);
     549             : 
     550           6 :         io.t2open.level = RAW_OPEN_T2OPEN;
     551           6 :         io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
     552           6 :         io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
     553           6 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     554           6 :         io.t2open.in.search_attrs = 0;
     555           6 :         io.t2open.in.file_attrs = 0;
     556           6 :         io.t2open.in.write_time = 0;
     557           6 :         io.t2open.in.size = 0;
     558           6 :         io.t2open.in.timeout = 0;
     559             : 
     560           6 :         io.t2open.in.num_eas = 3;
     561           6 :         io.t2open.in.eas = talloc_array(tctx, struct ea_struct, io.t2open.in.num_eas);
     562           6 :         io.t2open.in.eas[0].flags = 0;
     563           6 :         io.t2open.in.eas[0].name.s = ".CLASSINFO";
     564           6 :         io.t2open.in.eas[0].value = data_blob_talloc(tctx, "first value", 11);
     565           6 :         io.t2open.in.eas[1].flags = 0;
     566           6 :         io.t2open.in.eas[1].name.s = "EA TWO";
     567           6 :         io.t2open.in.eas[1].value = data_blob_talloc(tctx, "foo", 3);
     568           6 :         io.t2open.in.eas[2].flags = 0;
     569           6 :         io.t2open.in.eas[2].name.s = "X THIRD";
     570           6 :         io.t2open.in.eas[2].value = data_blob_talloc(tctx, "xy", 2);
     571             : 
     572             :         /* check all combinations of open_func */
     573          79 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     574          72 :         again:
     575          72 :                 if (open_funcs[i].with_file) {
     576          36 :                         io.t2open.in.fname = fname1;
     577             :                 } else {
     578          36 :                         io.t2open.in.fname = fname2;
     579             :                 }
     580          72 :                 io.t2open.in.open_func = open_funcs[i].open_func;
     581          72 :                 status = smb_raw_open(cli->tree, tctx, &io);
     582          72 :                 if ((io.t2open.in.num_eas != 0)
     583          72 :                     && 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          72 :                 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          72 :                 if (NT_STATUS_IS_OK(status)) {
     603          42 :                         smbcli_close(cli->tree, io.t2open.out.file.fnum);
     604             :                 }
     605             :         }
     606             : 
     607           6 :         smbcli_unlink(cli->tree, fname1);
     608           6 :         smbcli_unlink(cli->tree, fname2);
     609             : 
     610             :         /* check the basic return fields */
     611           6 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     612           6 :         io.t2open.in.write_time = 0;
     613           6 :         io.t2open.in.fname = fname;
     614           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     615           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     616           6 :         fnum = io.t2open.out.file.fnum;
     617             : 
     618           6 :         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           6 :         CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
     624           6 :         CHECK_VAL(io.t2open.out.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
     625           6 :         CHECK_VAL(io.t2open.out.ftype, 0);
     626           6 :         CHECK_VAL(io.t2open.out.devstate, 0);
     627           6 :         CHECK_VAL(io.t2open.out.action, OPENX_ACTION_CREATED);
     628           6 :         smbcli_close(cli->tree, fnum);
     629             : 
     630           6 :         status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
     631           6 :         CHECK_STATUS(status, io.t2open.in.num_eas
     632             :                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
     633           6 :         status = torture_check_ea(cli, fname, "EA TWO", "foo");
     634           6 :         CHECK_STATUS(status, io.t2open.in.num_eas
     635             :                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
     636           6 :         status = torture_check_ea(cli, fname, "X THIRD", "xy");
     637           6 :         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           6 :         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
     642           6 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
     643             : 
     644           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     645           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     646           6 :         smbcli_close(cli->tree, io.t2open.out.file.fnum);
     647             : 
     648           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     649           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     650           6 :         smbcli_close(cli->tree, io.t2open.out.file.fnum);
     651             : 
     652           6 :         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
     653           6 :         smbcli_unlink(cli->tree, fname);
     654             : 
     655             :         /* and check attrib on create */
     656           6 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
     657           6 :         io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
     658           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     659           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     660             : 
     661             :         /* check timeout on create - win2003 ignores the timeout! */
     662           6 :         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
     663           6 :         io.t2open.in.file_attrs = 0;
     664           6 :         io.t2open.in.timeout = 20000;
     665           6 :         io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
     666           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     667           6 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
     668             : 
     669           6 : done:
     670           6 :         smbcli_close(cli->tree, fnum);
     671           6 :         smbcli_deltree(cli->tree, BASEDIR);
     672             : 
     673           6 :         return ret;
     674             : }
     675             :         
     676             : 
     677             : /*
     678             :   test RAW_OPEN_NTCREATEX
     679             : */
     680           6 : static bool test_ntcreatex(struct torture_context *tctx, struct smbcli_state *cli)
     681             : {
     682           1 :         union smb_open io;
     683           1 :         union smb_fileinfo finfo;
     684           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
     685           6 :         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
     686           1 :         NTSTATUS status;
     687           6 :         int fnum = -1;
     688           6 :         bool ret = true;
     689           1 :         int i;
     690           1 :         struct {
     691             :                 uint32_t open_disp;
     692             :                 bool with_file;
     693             :                 NTSTATUS correct_status;
     694           6 :         } 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           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     712             : 
     713             :         /* reasonable default parameters */
     714           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
     715           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     716           6 :         io.ntcreatex.in.root_fid.fnum = 0;
     717           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     718           6 :         io.ntcreatex.in.alloc_size = 1024*1024;
     719           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     720           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     721           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     722           6 :         io.ntcreatex.in.create_options = 0;
     723           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     724           6 :         io.ntcreatex.in.security_flags = 0;
     725           6 :         io.ntcreatex.in.fname = fname;
     726             : 
     727             :         /* test the open disposition */
     728          90 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     729          84 :                 if (open_funcs[i].with_file) {
     730          42 :                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
     731          42 :                         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          42 :                         smbcli_close(cli->tree, fnum);
     739             :                 }
     740          84 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
     741          84 :                 status = smb_raw_open(cli->tree, tctx, &io);
     742          84 :                 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          84 :                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
     753          66 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
     754          66 :                         smbcli_unlink(cli->tree, fname);
     755             :                 }
     756             :         }
     757             : 
     758             :         /* basic field testing */
     759           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     760             : 
     761           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     762           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     763           6 :         fnum = io.ntcreatex.out.file.fnum;
     764             : 
     765           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     766           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
     767           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     768           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     769           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     770           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     771           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     772           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     773           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     774           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     775           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     776             : 
     777             :         /* check fields when the file already existed */
     778           6 :         smbcli_close(cli->tree, fnum);
     779           6 :         smbcli_unlink(cli->tree, fname);
     780           6 :         fnum = create_complex_file(cli, tctx, fname);
     781           6 :         if (fnum == -1) {
     782           0 :                 ret = false;
     783           0 :                 goto done;
     784             :         }
     785           6 :         smbcli_close(cli->tree, fnum);
     786             : 
     787           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
     788           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     789           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     790           6 :         fnum = io.ntcreatex.out.file.fnum;
     791             : 
     792           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     793           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     794           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     795           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     796           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     797           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     798           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     799           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     800           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     801           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     802           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     803           6 :         smbcli_close(cli->tree, fnum);
     804           6 :         smbcli_unlink(cli->tree, fname);
     805             : 
     806             : 
     807             :         /* create a directory */
     808           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     809           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     810           6 :         io.ntcreatex.in.alloc_size = 0;
     811           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
     812           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     813           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     814           6 :         io.ntcreatex.in.create_options = 0;
     815           6 :         io.ntcreatex.in.fname = dname;
     816           6 :         fname = dname;
     817             : 
     818           6 :         smbcli_rmdir(cli->tree, fname);
     819           6 :         smbcli_unlink(cli->tree, fname);
     820             : 
     821           6 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     822           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     823           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     824           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
     825           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     826           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     827           6 :         fnum = io.ntcreatex.out.file.fnum;
     828             : 
     829           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     830           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
     831           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     832           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     833           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     834           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     835           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     836           6 :         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
     837             :                   FILE_ATTRIBUTE_DIRECTORY);
     838           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     839           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     840           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     841           6 :         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
     842           6 :         CHECK_VAL(io.ntcreatex.out.size, 0);
     843           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     844           6 :         smbcli_unlink(cli->tree, fname);
     845             :         
     846             : 
     847           6 : done:
     848           6 :         smbcli_close(cli->tree, fnum);
     849           6 :         smbcli_deltree(cli->tree, BASEDIR);
     850             : 
     851           6 :         return ret;
     852             : }
     853             : 
     854             : 
     855             : /*
     856             :   test RAW_OPEN_NTTRANS_CREATE
     857             : */
     858           6 : static bool test_nttrans_create(struct torture_context *tctx, struct smbcli_state *cli)
     859             : {
     860           1 :         union smb_open io;
     861           1 :         union smb_fileinfo finfo;
     862           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
     863           6 :         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
     864           1 :         NTSTATUS status;
     865           6 :         int fnum = -1;
     866           6 :         bool ret = true;
     867           1 :         int i;
     868           1 :         uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
     869           1 :         uint32_t not_a_directory_mask, unexpected_mask;
     870           1 :         struct {
     871             :                 uint32_t open_disp;
     872             :                 bool with_file;
     873             :                 NTSTATUS correct_status;
     874           6 :         } 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           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     892             : 
     893             :         /* reasonable default parameters */
     894           6 :         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
     895           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     896           6 :         io.ntcreatex.in.root_fid.fnum = 0;
     897           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     898           6 :         io.ntcreatex.in.alloc_size = 1024*1024;
     899           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     900           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     901           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     902           6 :         io.ntcreatex.in.create_options = 0;
     903           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     904           6 :         io.ntcreatex.in.security_flags = 0;
     905           6 :         io.ntcreatex.in.fname = fname;
     906           6 :         io.ntcreatex.in.sec_desc = NULL;
     907           6 :         io.ntcreatex.in.ea_list = NULL;
     908             : 
     909             :         /* test the open disposition */
     910          90 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     911          84 :                 if (open_funcs[i].with_file) {
     912          42 :                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
     913          42 :                         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          42 :                         smbcli_close(cli->tree, fnum);
     921             :                 }
     922          84 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
     923          84 :                 status = smb_raw_open(cli->tree, tctx, &io);
     924          84 :                 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          84 :                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
     935          66 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
     936          66 :                         smbcli_unlink(cli->tree, fname);
     937             :                 }
     938             :         }
     939             : 
     940             :         /* basic field testing */
     941           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     942             : 
     943           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     944           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     945           6 :         fnum = io.ntcreatex.out.file.fnum;
     946             : 
     947           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     948           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
     949           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     950           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     951           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     952           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     953           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     954           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     955           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     956           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     957           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     958             : 
     959             :         /* check fields when the file already existed */
     960           6 :         smbcli_close(cli->tree, fnum);
     961           6 :         smbcli_unlink(cli->tree, fname);
     962           6 :         fnum = create_complex_file(cli, tctx, fname);
     963           6 :         if (fnum == -1) {
     964           0 :                 ret = false;
     965           0 :                 goto done;
     966             :         }
     967           6 :         smbcli_close(cli->tree, fnum);
     968             : 
     969           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
     970           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     971           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     972           6 :         fnum = io.ntcreatex.out.file.fnum;
     973             : 
     974           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     975           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     976           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     977           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     978           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     979           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     980           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     981           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     982           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     983           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     984           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     985           6 :         smbcli_close(cli->tree, fnum);
     986             : 
     987             :         /* check no-recall - don't pull a file from tape on a HSM */
     988           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
     989           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     990           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     991           6 :         fnum = io.ntcreatex.out.file.fnum;
     992             : 
     993           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     994           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     995           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     996           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     997           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     998           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     999           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1000           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1001           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1002           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1003           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1004           6 :         smbcli_close(cli->tree, fnum);
    1005             : 
    1006             :         /* Check some create options (these all should be ignored) */
    1007         199 :         for (i=0; i < 32; i++) {
    1008         192 :                 uint32_t create_option =
    1009         192 :                         ((uint32_t)1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
    1010         192 :                 if (create_option == 0) {
    1011         150 :                         continue;
    1012             :                 }
    1013          42 :                 io.ntcreatex.in.create_options = create_option;
    1014          42 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1015          42 :                 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          42 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1021          42 :                 fnum = io.ntcreatex.out.file.fnum;
    1022             : 
    1023          42 :                 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1024          42 :                 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
    1025          42 :                 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    1026          42 :                 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    1027          42 :                 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    1028          42 :                 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    1029          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1030          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1031          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1032          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1033          42 :                 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1034          42 :                 smbcli_close(cli->tree, fnum);
    1035             :         }
    1036             : 
    1037           6 :         io.ntcreatex.in.file_attr = 0;
    1038           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1039           6 :         io.ntcreatex.in.access_mask     = SEC_FLAG_MAXIMUM_ALLOWED;
    1040             : 
    1041             :         /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
    1042           6 :         ok_mask = 0;
    1043           6 :         not_supported_mask = 0;
    1044           6 :         invalid_parameter_mask = 0;
    1045           6 :         not_a_directory_mask = 0;
    1046           6 :         unexpected_mask = 0;
    1047         198 :         for (i=0; i < 32; i++) {
    1048         192 :                 uint32_t create_option = (uint32_t)1<<i;
    1049         192 :                 if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
    1050           6 :                         continue;
    1051             :                 }
    1052         186 :                 io.ntcreatex.in.create_options = create_option;
    1053         186 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1054         186 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
    1055           6 :                         not_supported_mask |= create_option;
    1056         180 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
    1057         108 :                         ok_mask |= create_option;
    1058         108 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1059          72 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    1060          66 :                         invalid_parameter_mask |= create_option;
    1061           6 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
    1062           6 :                         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           6 :         CHECK_VAL(ok_mask,                0x00efcfce);
    1071           6 :         CHECK_VAL(not_a_directory_mask,   0x00000001);
    1072           6 :         CHECK_VAL(not_supported_mask,     0x00002000);
    1073           6 :         CHECK_VAL(invalid_parameter_mask, 0xff100030);
    1074           6 :         CHECK_VAL(unexpected_mask,        0x00000000);
    1075             : 
    1076           6 :         smbcli_unlink(cli->tree, fname);
    1077             : 
    1078             : 
    1079             :         /* create a directory */
    1080           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1081           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1082           6 :         io.ntcreatex.in.alloc_size = 0;
    1083           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1084           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1085           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1086           6 :         io.ntcreatex.in.create_options = 0;
    1087           6 :         io.ntcreatex.in.fname = dname;
    1088           6 :         fname = dname;
    1089             : 
    1090           6 :         smbcli_rmdir(cli->tree, fname);
    1091           6 :         smbcli_unlink(cli->tree, fname);
    1092             : 
    1093           6 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1094           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1095           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1096           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1097           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1098           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1099           6 :         fnum = io.ntcreatex.out.file.fnum;
    1100             : 
    1101           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1102           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    1103           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    1104           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    1105           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    1106           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    1107           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1108           6 :         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
    1109             :                   FILE_ATTRIBUTE_DIRECTORY);
    1110           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1111           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1112           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1113           6 :         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
    1114           6 :         CHECK_VAL(io.ntcreatex.out.size, 0);
    1115           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1116           6 :         smbcli_unlink(cli->tree, fname);
    1117             :         
    1118             : 
    1119           6 : done:
    1120           6 :         smbcli_close(cli->tree, fnum);
    1121           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1122             : 
    1123           6 :         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           6 : static bool test_ntcreatex_brlocked(struct torture_context *tctx, struct smbcli_state *cli)
    1135             : {
    1136           1 :         union smb_open io, io1;
    1137           1 :         union smb_lock io2;
    1138           1 :         struct smb_lock_entry lock[1];
    1139           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
    1140           1 :         NTSTATUS status;
    1141           6 :         bool ret = true;
    1142             : 
    1143           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1144             : 
    1145           6 :         torture_comment(tctx, "Testing ntcreatex with a byte range locked file\n");
    1146             : 
    1147           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1148           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1149           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1150           6 :         io.ntcreatex.in.access_mask = 0x2019f;
    1151           6 :         io.ntcreatex.in.alloc_size = 0;
    1152           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1153           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1154             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1155           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1156           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    1157           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1158           6 :         io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
    1159             :                 NTCREATEX_SECURITY_ALL;
    1160           6 :         io.ntcreatex.in.fname = fname;
    1161             : 
    1162           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1163           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1164             : 
    1165           6 :         io2.lockx.level = RAW_LOCK_LOCKX;
    1166           6 :         io2.lockx.in.file.fnum = io.ntcreatex.out.file.fnum;
    1167           6 :         io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
    1168           6 :         io2.lockx.in.timeout = 0;
    1169           6 :         io2.lockx.in.ulock_cnt = 0;
    1170           6 :         io2.lockx.in.lock_cnt = 1;
    1171           6 :         lock[0].pid = cli->session->pid;
    1172           6 :         lock[0].offset = 0;
    1173           6 :         lock[0].count = 0x1;
    1174           6 :         io2.lockx.in.locks = &lock[0];
    1175           6 :         status = smb_raw_lock(cli->tree, &io2);
    1176           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1177             : 
    1178           6 :         io1.generic.level = RAW_OPEN_NTCREATEX;
    1179           6 :         io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1180           6 :         io1.ntcreatex.in.root_fid.fnum = 0;
    1181           6 :         io1.ntcreatex.in.access_mask = 0x20196;
    1182           6 :         io1.ntcreatex.in.alloc_size = 0;
    1183           6 :         io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1184           6 :         io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1185             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1186           6 :         io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    1187           6 :         io1.ntcreatex.in.create_options = 0;
    1188           6 :         io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1189           6 :         io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
    1190             :                 NTCREATEX_SECURITY_ALL;
    1191           6 :         io1.ntcreatex.in.fname = fname;
    1192             : 
    1193           6 :         status = smb_raw_open(cli->tree, tctx, &io1);
    1194           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1195             : 
    1196           6 :  done:
    1197           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1198           6 :         smbcli_close(cli->tree, io1.ntcreatex.out.file.fnum);
    1199           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1200           6 :         return ret;
    1201             : }
    1202             : 
    1203             : /*
    1204             :   test RAW_OPEN_MKNEW
    1205             : */
    1206           6 : static bool test_mknew(struct torture_context *tctx, struct smbcli_state *cli)
    1207             : {
    1208           1 :         union smb_open io;
    1209           6 :         const char *fname = BASEDIR "\\torture_mknew.txt";
    1210           1 :         NTSTATUS status;
    1211           6 :         int fnum = -1;
    1212           6 :         bool ret = true;
    1213           6 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1214           1 :         union smb_fileinfo finfo;
    1215             : 
    1216           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1217             : 
    1218           6 :         io.mknew.level = RAW_OPEN_MKNEW;
    1219           6 :         io.mknew.in.attrib = 0;
    1220           6 :         io.mknew.in.write_time = 0;
    1221           6 :         io.mknew.in.fname = fname;
    1222           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1223           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1224           6 :         fnum = io.mknew.out.file.fnum;
    1225             : 
    1226           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1227           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
    1228             : 
    1229           6 :         smbcli_close(cli->tree, fnum);
    1230           6 :         smbcli_unlink(cli->tree, fname);
    1231             : 
    1232             :         /* make sure write_time works */
    1233           6 :         io.mknew.in.write_time = basetime;
    1234           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1235           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1236           6 :         fnum = io.mknew.out.file.fnum;
    1237           6 :         CHECK_TIME(basetime, write_time);
    1238             : 
    1239           6 :         smbcli_close(cli->tree, fnum);
    1240           6 :         smbcli_unlink(cli->tree, fname);
    1241             : 
    1242             :         /* make sure file_attrs works */
    1243           6 :         io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1244           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1245           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1246           6 :         fnum = io.mknew.out.file.fnum;
    1247           6 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
    1248             :                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
    1249             :         
    1250           6 : done:
    1251           6 :         smbcli_close(cli->tree, fnum);
    1252           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1253             : 
    1254           6 :         return ret;
    1255             : }
    1256             : 
    1257             : 
    1258             : /*
    1259             :   test RAW_OPEN_CREATE
    1260             : */
    1261           6 : static bool test_create(struct torture_context *tctx, struct smbcli_state *cli)
    1262             : {
    1263           1 :         union smb_open io;
    1264           6 :         const char *fname = BASEDIR "\\torture_create.txt";
    1265           1 :         NTSTATUS status;
    1266           6 :         int fnum = -1;
    1267           6 :         bool ret = true;
    1268           6 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1269           1 :         union smb_fileinfo finfo;
    1270             : 
    1271           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1272             : 
    1273           6 :         io.create.level = RAW_OPEN_CREATE;
    1274           6 :         io.create.in.attrib = 0;
    1275           6 :         io.create.in.write_time = 0;
    1276           6 :         io.create.in.fname = fname;
    1277           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1278           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1279           6 :         fnum = io.create.out.file.fnum;
    1280             : 
    1281           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1282           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1283             : 
    1284           6 :         smbcli_close(cli->tree, io.create.out.file.fnum);
    1285           6 :         smbcli_close(cli->tree, fnum);
    1286           6 :         smbcli_unlink(cli->tree, fname);
    1287             : 
    1288             :         /* make sure write_time works */
    1289           6 :         io.create.in.write_time = basetime;
    1290           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1291           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1292           6 :         fnum = io.create.out.file.fnum;
    1293           6 :         CHECK_TIME(basetime, write_time);
    1294             : 
    1295           6 :         smbcli_close(cli->tree, fnum);
    1296           6 :         smbcli_unlink(cli->tree, fname);
    1297             : 
    1298             :         /* make sure file_attrs works */
    1299           6 :         io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1300           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1301           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1302           6 :         fnum = io.create.out.file.fnum;
    1303           6 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
    1304             :                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
    1305             :         
    1306           6 : done:
    1307           6 :         smbcli_close(cli->tree, fnum);
    1308           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1309             : 
    1310           6 :         return ret;
    1311             : }
    1312             : 
    1313             : 
    1314             : /*
    1315             :   test RAW_OPEN_CTEMP
    1316             : */
    1317           6 : static bool test_ctemp(struct torture_context *tctx, struct smbcli_state *cli)
    1318             : {
    1319           1 :         union smb_open io;
    1320           1 :         NTSTATUS status;
    1321           6 :         int fnum = -1;
    1322           6 :         bool ret = true;
    1323           6 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1324           1 :         union smb_fileinfo finfo;
    1325           6 :         const char *name, *fname = NULL;
    1326             : 
    1327           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1328             : 
    1329           6 :         io.ctemp.level = RAW_OPEN_CTEMP;
    1330           6 :         io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1331           6 :         io.ctemp.in.write_time = basetime;
    1332           6 :         io.ctemp.in.directory = BASEDIR;
    1333           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1334           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1335           6 :         fnum = io.ctemp.out.file.fnum;
    1336             : 
    1337           6 :         name = io.ctemp.out.name;
    1338             : 
    1339           6 :         finfo.generic.level = RAW_FILEINFO_NAME_INFO;
    1340           6 :         finfo.generic.in.file.fnum = fnum;
    1341           6 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    1342           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1343             : 
    1344           6 :         fname = finfo.name_info.out.fname.s;
    1345           6 :         torture_comment(tctx, "ctemp name=%s  real name=%s\n", name, fname);
    1346             : 
    1347           6 : done:
    1348           6 :         smbcli_close(cli->tree, fnum);
    1349           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1350             : 
    1351           6 :         return ret;
    1352             : }
    1353             : 
    1354             : 
    1355             : /*
    1356             :   test chained RAW_OPEN_OPENX_READX
    1357             : */
    1358           6 : static bool test_chained(struct torture_context *tctx, struct smbcli_state *cli)
    1359             : {
    1360           1 :         union smb_open io;
    1361           6 :         const char *fname = BASEDIR "\\torture_chained.txt";
    1362           1 :         NTSTATUS status;
    1363           6 :         int fnum = -1;
    1364           6 :         bool ret = true;
    1365           6 :         const char buf[] = "test";
    1366           1 :         char buf2[4];
    1367             : 
    1368           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1369             : 
    1370           6 :         fnum = create_complex_file(cli, tctx, fname);
    1371             : 
    1372           6 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1373             : 
    1374           6 :         smbcli_close(cli->tree, fnum);       
    1375             : 
    1376           6 :         io.openxreadx.level = RAW_OPEN_OPENX_READX;
    1377           6 :         io.openxreadx.in.fname = fname;
    1378           6 :         io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1379           6 :         io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1380           6 :         io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1381           6 :         io.openxreadx.in.search_attrs = 0;
    1382           6 :         io.openxreadx.in.file_attrs = 0;
    1383           6 :         io.openxreadx.in.write_time = 0;
    1384           6 :         io.openxreadx.in.size = 1024*1024;
    1385           6 :         io.openxreadx.in.timeout = 0;
    1386             :         
    1387           6 :         io.openxreadx.in.offset = 0;
    1388           6 :         io.openxreadx.in.mincnt = sizeof(buf2);
    1389           6 :         io.openxreadx.in.maxcnt = sizeof(buf2);
    1390           6 :         io.openxreadx.in.remaining = 0;
    1391           6 :         io.openxreadx.out.data = (uint8_t *)buf2;
    1392             : 
    1393           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1394           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1395           6 :         fnum = io.openxreadx.out.file.fnum;
    1396             : 
    1397           6 :         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           6 : done:
    1404           6 :         smbcli_close(cli->tree, fnum);
    1405           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1406             : 
    1407           6 :         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           6 : static bool test_no_leading_slash(struct torture_context *tctx, struct smbcli_state *cli)
    1416             : {
    1417           1 :         union smb_open io;
    1418           6 :         const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
    1419           1 :         NTSTATUS status;
    1420           6 :         int fnum = -1;
    1421           6 :         bool ret = true;
    1422           6 :         const char buf[] = "test";
    1423             : 
    1424           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1425             : 
    1426           6 :         smbcli_unlink(cli->tree, fname);
    1427             : 
    1428             :         /* Create the file */
    1429           6 :         fnum = create_complex_file(cli, tctx, fname);
    1430           6 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1431           6 :         smbcli_close(cli->tree, fnum);       
    1432             : 
    1433             :         /* Prepare to open the file using path without leading slash */
    1434           6 :         io.openx.level = RAW_OPEN_OPENX;
    1435           6 :         io.openx.in.fname = fname + 1;
    1436           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1437           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1438           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1439           6 :         io.openx.in.search_attrs = 0;
    1440           6 :         io.openx.in.file_attrs = 0;
    1441           6 :         io.openx.in.write_time = 0;
    1442           6 :         io.openx.in.size = 1024*1024;
    1443           6 :         io.openx.in.timeout = 0;
    1444             : 
    1445           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1446           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1447           6 :         fnum = io.openx.out.file.fnum;
    1448             : 
    1449           6 : done:
    1450           6 :         smbcli_close(cli->tree, fnum);
    1451           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1452             : 
    1453           6 :         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           6 : static bool test_openx_over_dir(struct torture_context *tctx, struct smbcli_state *cli)
    1463             : {
    1464           1 :         union smb_open io;
    1465           6 :         const char *fname = BASEDIR "\\openx_over_dir";
    1466           1 :         NTSTATUS status;
    1467           6 :         int d_fnum = -1;
    1468           6 :         int fnum = -1;
    1469           6 :         bool ret = true;
    1470             : 
    1471           6 :         ZERO_STRUCT(io);
    1472             : 
    1473           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1474             : 
    1475             :         /* Create the Directory */
    1476           6 :         status = create_directory_handle(cli->tree, fname, &d_fnum);
    1477           6 :         smbcli_close(cli->tree, d_fnum);     
    1478             : 
    1479             :         /* Prepare to open the file over the directory. */
    1480           6 :         io.openx.level = RAW_OPEN_OPENX;
    1481           6 :         io.openx.in.fname = fname;
    1482           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1483           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1484           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1485           6 :         io.openx.in.search_attrs = 0;
    1486           6 :         io.openx.in.file_attrs = 0;
    1487           6 :         io.openx.in.write_time = 0;
    1488           6 :         io.openx.in.size = 1024*1024;
    1489           6 :         io.openx.in.timeout = 0;
    1490             : 
    1491           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1492           6 :         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
    1493           6 :         fnum = io.openx.out.file.fnum;
    1494             : 
    1495           6 : done:
    1496           6 :         smbcli_close(cli->tree, fnum);
    1497           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1498             : 
    1499           6 :         return ret;
    1500             : }
    1501             : 
    1502             : 
    1503             : /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
    1504             : 
    1505           6 : static bool test_raw_open_multi(struct torture_context *tctx, struct smbcli_state *cli_ignored)
    1506             : {
    1507           1 :         struct smbcli_state *cli;
    1508           6 :         TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
    1509           6 :         const char *fname = "\\test_oplock.dat";
    1510           1 :         NTSTATUS status;
    1511           6 :         bool ret = true;
    1512           1 :         union smb_open io;
    1513           1 :         struct smbcli_state **clients;
    1514           1 :         struct smbcli_request **requests;
    1515           1 :         union smb_open *ios;
    1516           6 :         const char *host = torture_setting_string(tctx, "host", NULL);
    1517           6 :         const char *share = torture_setting_string(tctx, "share", NULL);
    1518           6 :         int i, num_files = 3;
    1519           6 :         int num_ok = 0;
    1520           6 :         int num_collision = 0;
    1521             :         
    1522           6 :         clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
    1523           6 :         requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
    1524           6 :         ios = talloc_array(mem_ctx, union smb_open, num_files);
    1525           6 :         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           6 :         if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
    1533           0 :                 return false;
    1534             :         }
    1535             : 
    1536           6 :         cli->tree->session->transport->options.request_timeout = 60;
    1537             : 
    1538          24 :         for (i=0; i<num_files; i++) {
    1539          18 :                 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          18 :                 clients[i]->tree->session->transport->options.request_timeout = 60;
    1547             :         }
    1548             : 
    1549             :         /* cleanup */
    1550           6 :         smbcli_unlink(cli->tree, fname);
    1551             : 
    1552             :         /*
    1553             :           base ntcreatex parms
    1554             :         */
    1555           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1556           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1557           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1558           6 :         io.ntcreatex.in.alloc_size = 0;
    1559           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1560           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1561             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    1562             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    1563           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1564           6 :         io.ntcreatex.in.create_options = 0;
    1565           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1566           6 :         io.ntcreatex.in.security_flags = 0;
    1567           6 :         io.ntcreatex.in.fname = fname;
    1568           6 :         io.ntcreatex.in.flags = 0;
    1569             : 
    1570          25 :         for (i=0; i<num_files; i++) {
    1571          18 :                 ios[i] = io;
    1572          18 :                 requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
    1573          18 :                 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           6 :         torture_comment(tctx, "waiting for replies\n");
    1582          55 :         while (1) {
    1583          60 :                 bool unreplied = false;
    1584          90 :                 for (i=0; i<num_files; i++) {
    1585          84 :                         if (requests[i] == NULL) {
    1586          12 :                                 continue;
    1587             :                         }
    1588          72 :                         if (requests[i]->state < SMBCLI_REQUEST_DONE) {
    1589          45 :                                 unreplied = true;
    1590          45 :                                 break;
    1591             :                         }
    1592          21 :                         status = smb_raw_open_recv(requests[i], mem_ctx,
    1593          18 :                                                    &ios[i]);
    1594             : 
    1595          18 :                         torture_comment(tctx, "File %d returned status %s\n", i,
    1596             :                                   nt_errstr(status));
    1597             : 
    1598          18 :                         if (NT_STATUS_IS_OK(status)) {
    1599           6 :                                 num_ok += 1;
    1600             :                         } 
    1601             : 
    1602          18 :                         if (NT_STATUS_EQUAL(status,
    1603             :                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
    1604          12 :                                 num_collision += 1;
    1605             :                         }
    1606             : 
    1607          18 :                         requests[i] = NULL;
    1608             :                 }
    1609          60 :                 if (!unreplied) {
    1610           5 :                         break;
    1611             :                 }
    1612             : 
    1613          54 :                 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           6 :         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
    1621           0 :                 ret = false;
    1622             :         }
    1623             : 
    1624          24 :         for (i=0; i<num_files; i++) {
    1625          18 :                 torture_close_connection(clients[i]);
    1626             :         }
    1627           6 :         talloc_free(mem_ctx);
    1628           6 :         return ret;
    1629             : }
    1630             : 
    1631             : /*
    1632             :   test opening for delete on a read-only attribute file.
    1633             : */
    1634           6 : static bool test_open_for_delete(struct torture_context *tctx, struct smbcli_state *cli)
    1635             : {
    1636           1 :         union smb_open io;
    1637           1 :         union smb_fileinfo finfo;
    1638           6 :         const char *fname = BASEDIR "\\torture_open_for_delete.txt";
    1639           1 :         NTSTATUS status;
    1640           6 :         int fnum = -1;
    1641           6 :         bool ret = true;
    1642             : 
    1643           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1644             : 
    1645             :         /* reasonable default parameters */
    1646           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1647           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1648           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1649           6 :         io.ntcreatex.in.alloc_size = 0;
    1650           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1651           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
    1652           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1653           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1654           6 :         io.ntcreatex.in.create_options = 0;
    1655           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1656           6 :         io.ntcreatex.in.security_flags = 0;
    1657           6 :         io.ntcreatex.in.fname = fname;
    1658             : 
    1659             :         /* Create the readonly file. */
    1660             : 
    1661           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1662           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1663           6 :         fnum = io.ntcreatex.out.file.fnum;
    1664             : 
    1665           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1666           6 :         io.ntcreatex.in.create_options = 0;
    1667           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    1668           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1669           6 :         smbcli_close(cli->tree, fnum);
    1670             : 
    1671             :         /* Now try and open for delete only - should succeed. */
    1672           6 :         io.ntcreatex.in.access_mask = SEC_STD_DELETE;
    1673           6 :         io.ntcreatex.in.file_attr = 0;
    1674           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    1675           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1676           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1677           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1678             : 
    1679           6 :         smbcli_unlink(cli->tree, fname);
    1680             : 
    1681           6 : done:
    1682           6 :         smbcli_close(cli->tree, fnum);
    1683           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1684             : 
    1685           6 :         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           6 : static bool test_chained_ntcreatex_readx(struct torture_context *tctx, struct smbcli_state *cli)
    1694             : {
    1695           6 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    1696           1 :         union smb_open io;
    1697           6 :         const char *fname = BASEDIR "\\torture_chained.txt";
    1698           1 :         NTSTATUS status;
    1699           6 :         int fnum = -1;
    1700           6 :         bool ret = true;
    1701           6 :         const char buf[] = "test";
    1702           1 :         char buf2[4];
    1703             : 
    1704           6 :         ZERO_STRUCT(io);
    1705             : 
    1706           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1707             : 
    1708           6 :         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
    1709             :                               "non-existent file \n");
    1710             : 
    1711             :         /* ntcreatex parameters */
    1712           6 :         io.generic.level = RAW_OPEN_NTCREATEX_READX;
    1713           6 :         io.ntcreatexreadx.in.flags = 0;
    1714           6 :         io.ntcreatexreadx.in.root_fid.fnum = 0;
    1715           6 :         io.ntcreatexreadx.in.access_mask = SEC_FILE_READ_DATA;
    1716           6 :         io.ntcreatexreadx.in.alloc_size = 0;
    1717           6 :         io.ntcreatexreadx.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1718           6 :         io.ntcreatexreadx.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1719             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    1720           6 :         io.ntcreatexreadx.in.open_disposition = NTCREATEX_DISP_OPEN;
    1721           6 :         io.ntcreatexreadx.in.create_options = 0;
    1722           6 :         io.ntcreatexreadx.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1723           6 :         io.ntcreatexreadx.in.security_flags = 0;
    1724           6 :         io.ntcreatexreadx.in.fname = fname;
    1725             : 
    1726             :         /* readx parameters */
    1727           6 :         io.ntcreatexreadx.in.offset = 0;
    1728           6 :         io.ntcreatexreadx.in.mincnt = sizeof(buf2);
    1729           6 :         io.ntcreatexreadx.in.maxcnt = sizeof(buf2);
    1730           6 :         io.ntcreatexreadx.in.remaining = 0;
    1731           6 :         io.ntcreatexreadx.out.data = (uint8_t *)buf2;
    1732             : 
    1733             :         /* try to open the non-existent file */
    1734           6 :         status = smb_raw_open(cli->tree, mem_ctx, &io);
    1735           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1736           6 :         fnum = io.ntcreatexreadx.out.file.fnum;
    1737             : 
    1738           6 :         smbcli_close(cli->tree, fnum);
    1739           6 :         smbcli_unlink(cli->tree, fname);
    1740             : 
    1741           6 :         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
    1742             :                               "existing file \n");
    1743             : 
    1744           6 :         fnum = create_complex_file(cli, mem_ctx, fname);
    1745           6 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1746           6 :         smbcli_close(cli->tree, fnum);
    1747             : 
    1748           6 :         status = smb_raw_open(cli->tree, mem_ctx, &io);
    1749           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1750           6 :         fnum = io.ntcreatexreadx.out.file.fnum;
    1751             : 
    1752           6 :         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           6 : done:
    1759           6 :         smbcli_close(cli->tree, fnum);
    1760           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1761           6 :         talloc_free(mem_ctx);
    1762             : 
    1763           6 :         return ret;
    1764             : }
    1765             : 
    1766           6 : static bool test_ntcreatex_opendisp_dir(struct torture_context *tctx,
    1767             :                                         struct smbcli_state *cli)
    1768             : {
    1769           6 :         const char *dname = BASEDIR "\\torture_ntcreatex_opendisp_dir";
    1770           1 :         NTSTATUS status;
    1771           6 :         bool ret = true;
    1772           1 :         int i;
    1773           1 :         struct {
    1774             :                 uint32_t open_disp;
    1775             :                 bool dir_exists;
    1776             :                 NTSTATUS correct_status;
    1777           6 :         } 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           1 :         union smb_open io;
    1794             : 
    1795           6 :         ZERO_STRUCT(io);
    1796           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1797           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1798           6 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1799           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1800           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1801           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1802           6 :         io.ntcreatex.in.fname = dname;
    1803             : 
    1804           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1805             : 
    1806           6 :         smbcli_rmdir(cli->tree, dname);
    1807           6 :         smbcli_unlink(cli->tree, dname);
    1808             : 
    1809             :         /* test the open disposition for directories */
    1810           6 :         torture_comment(tctx, "Testing open dispositions for directories...\n");
    1811             : 
    1812          91 :         for (i=0; i<ARRAY_SIZE(open_funcs_dir); i++) {
    1813          84 :                 if (open_funcs_dir[i].dir_exists) {
    1814          42 :                         status = smbcli_mkdir(cli->tree, dname);
    1815          42 :                         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          84 :                 io.ntcreatex.in.open_disposition = open_funcs_dir[i].open_disp;
    1826          84 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1827          84 :                 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          84 :                 if (NT_STATUS_IS_OK(status) || open_funcs_dir[i].dir_exists) {
    1838          54 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1839          54 :                         smbcli_rmdir(cli->tree, dname);
    1840             :                 }
    1841             :         }
    1842             : 
    1843           6 : done:
    1844           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1845             : 
    1846           6 :         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           6 : static bool test_ntcreatexdir(struct torture_context *tctx,
    1856             :     struct smbcli_state *cli)
    1857             : {
    1858           1 :         union smb_open io;
    1859           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
    1860           6 :         const char *dname = BASEDIR "\\torture_ntcreatex_dir";
    1861           1 :         NTSTATUS status;
    1862           1 :         int i;
    1863             : 
    1864           1 :         struct {
    1865             :                 uint32_t open_disp;
    1866             :                 uint32_t file_attr;
    1867             :                 uint32_t create_options;
    1868             :                 NTSTATUS correct_status;
    1869           6 :         } 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           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1898             : 
    1899             :         /* setup some base params. */
    1900           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1901           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1902           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1903           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1904           6 :         io.ntcreatex.in.alloc_size = 0;
    1905           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1906           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1907           6 :         io.ntcreatex.in.security_flags = 0;
    1908           6 :         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          78 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
    1916          72 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
    1917          72 :                 io.ntcreatex.in.file_attr = open_funcs[i].file_attr;
    1918          72 :                 io.ntcreatex.in.create_options = open_funcs[i].create_options;
    1919          72 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1920          72 :                 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          72 :                 if (NT_STATUS_IS_OK(status)) {
    1931          36 :                         if (open_funcs[i].create_options != 0) {
    1932             :                                 /* out attrib should be a directory. */
    1933          12 :                                 torture_assert_int_equal(tctx,
    1934             :                                     io.ntcreatex.out.attrib,
    1935             :                                     FILE_ATTRIBUTE_DIRECTORY, "should have "
    1936             :                                     "created a directory");
    1937             : 
    1938          12 :                                 smbcli_close(cli->tree,
    1939          12 :                                     io.ntcreatex.out.file.fnum);
    1940             : 
    1941             :                                 /* Make sure unlink fails. */
    1942          12 :                                 status = smbcli_unlink(cli->tree, fname);
    1943          12 :                                 torture_assert_ntstatus_equal(tctx, status,
    1944             :                                     NT_STATUS_FILE_IS_A_DIRECTORY,
    1945             :                                     "unlink should fail for a directory");
    1946             : 
    1947          12 :                                 status = smbcli_rmdir(cli->tree, fname);
    1948          12 :                                 torture_assert_ntstatus_ok(tctx, status,
    1949             :                                     "rmdir failed");
    1950             :                         } else {
    1951          24 :                                 torture_assert_int_equal(tctx,
    1952             :                                     io.ntcreatex.out.attrib,
    1953             :                                     FILE_ATTRIBUTE_ARCHIVE, "should not have "
    1954             :                                     "created a directory");
    1955             : 
    1956          24 :                                 smbcli_close(cli->tree,
    1957          24 :                                     io.ntcreatex.out.file.fnum);
    1958             : 
    1959             :                                 /* Make sure rmdir fails. */
    1960          24 :                                 status = smbcli_rmdir(cli->tree, fname);
    1961          24 :                                 torture_assert_ntstatus_equal(tctx, status,
    1962             :                                     NT_STATUS_NOT_A_DIRECTORY,
    1963             :                                     "rmdir should fail for a file");
    1964             : 
    1965          24 :                                 status = smbcli_unlink(cli->tree, fname);
    1966          32 :                                 torture_assert_ntstatus_ok(tctx, status,
    1967             :                                     "unlink failed");
    1968             :                         }
    1969             :                 }
    1970             :         }
    1971             : 
    1972             :         /* Create a file. */
    1973           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1974           6 :         io.ntcreatex.in.create_options = 0;
    1975           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1976           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1977           6 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create file.");
    1978           6 :         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           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1982           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1983             : 
    1984           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1985           6 :         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_DIRECTORY "
    1986             :             "doesn't produce a hard failure.");
    1987           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1988             : 
    1989             :         /* Try and open file with createx_option_dir and check the error. */
    1990           6 :         io.ntcreatex.in.file_attr = 0;
    1991           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1992             : 
    1993           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1994           6 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_A_DIRECTORY,
    1995             :             "NTCREATEX_OPTIONS_DIRECTORY will a file from being opened.");
    1996           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1997             : 
    1998             :         /* Delete the file and move onto directory testing. */
    1999           6 :         smbcli_unlink(cli->tree, fname);
    2000             : 
    2001             :         /* Now try some tests on a directory. */
    2002           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2003           6 :         io.ntcreatex.in.file_attr = 0;
    2004           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    2005           6 :         io.ntcreatex.in.fname = dname;
    2006             : 
    2007           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2008           6 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create dir.");
    2009             : 
    2010             :         /* out attrib should be a directory. */
    2011           6 :         torture_assert_int_equal(tctx, io.ntcreatex.out.attrib,
    2012             :             FILE_ATTRIBUTE_DIRECTORY, "should have created a directory");
    2013             : 
    2014           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2015             : 
    2016             :         /* Try and open it with normal attr and check the error. */
    2017           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2018           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    2019             : 
    2020           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2021           6 :         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_NORMAL "
    2022             :             "doesn't produce a hard failure.");
    2023           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2024             : 
    2025             :         /* Try and open it with file create_options and check the error. */
    2026           6 :         io.ntcreatex.in.file_attr = 0;
    2027           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    2028             : 
    2029           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2030           6 :         torture_assert_ntstatus_equal(tctx, status,
    2031             :             NT_STATUS_FILE_IS_A_DIRECTORY,
    2032             :             "NTCREATEX_OPTIONS_NON_DIRECTORY_FILE should be returned ");
    2033           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2034             : 
    2035           6 :         smbcli_deltree(cli->tree, BASEDIR);
    2036             : 
    2037           6 :         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           6 : static bool test_open_for_truncate(struct torture_context *tctx, struct smbcli_state *cli)
    2046             : {
    2047           1 :         union smb_open io;
    2048           1 :         union smb_fileinfo finfo;
    2049           6 :         const char *fname = BASEDIR "\\torture_open_for_truncate.txt";
    2050           1 :         NTSTATUS status;
    2051           6 :         int fnum = -1;
    2052           6 :         ssize_t val = 0;
    2053           6 :         char c = '\0';
    2054           6 :         bool ret = true;
    2055             : 
    2056           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
    2057             :                 "Failed to setup up test directory: " BASEDIR);
    2058             : 
    2059           6 :         torture_comment(tctx, "Testing open truncate disposition.\n");
    2060             : 
    2061             :         /* reasonable default parameters */
    2062           6 :         ZERO_STRUCT(io);
    2063           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2064           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    2065           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    2066           6 :         io.ntcreatex.in.alloc_size = 0;
    2067           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2068           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2069           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2070           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2071           6 :         io.ntcreatex.in.create_options = 0;
    2072           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2073           6 :         io.ntcreatex.in.security_flags = 0;
    2074           6 :         io.ntcreatex.in.fname = fname;
    2075             : 
    2076           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2077           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2078           6 :         fnum = io.ntcreatex.out.file.fnum;
    2079             : 
    2080             :         /* Write a byte at offset 1k-1. */
    2081           6 :         val =smbcli_write(cli->tree, fnum, 0, &c, 1023, 1);
    2082           6 :         torture_assert_int_equal(tctx, val, 1, "write failed\n");
    2083             : 
    2084             :         /* Now try and open for read/write with truncate - should fail. */
    2085           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE|SEC_RIGHTS_FILE_READ;
    2086           6 :         io.ntcreatex.in.file_attr = 0;
    2087           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    2088             :                         NTCREATEX_SHARE_ACCESS_WRITE |
    2089             :                         NTCREATEX_SHARE_ACCESS_DELETE;
    2090           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
    2091           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2092           6 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
    2093             : 
    2094             :         /* Ensure file size is still 1k */
    2095           6 :         finfo.generic.level = RAW_FILEINFO_GETATTRE;
    2096           6 :         finfo.generic.in.file.fnum = fnum;
    2097           6 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    2098           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2099           6 :         CHECK_VAL(finfo.getattre.out.size, 1024);
    2100             : 
    2101           6 :         smbcli_close(cli->tree, fnum);
    2102             : 
    2103           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2104           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2105           6 :         fnum = io.ntcreatex.out.file.fnum;
    2106             : 
    2107             :         /* Ensure truncate actually works */
    2108           6 :         finfo.generic.level = RAW_FILEINFO_GETATTRE;
    2109           6 :         finfo.generic.in.file.fnum = fnum;
    2110           6 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    2111           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2112           6 :         CHECK_VAL(finfo.getattre.out.size, 0);
    2113             : 
    2114           6 :         smbcli_close(cli->tree, fnum);
    2115           6 :         smbcli_unlink(cli->tree, fname);
    2116             : 
    2117           6 : done:
    2118           6 :         smbcli_close(cli->tree, fnum);
    2119           6 :         smbcli_deltree(cli->tree, BASEDIR);
    2120             : 
    2121           6 :         return ret;
    2122             : }
    2123             : 
    2124             : /**
    2125             :  * Test for file size to be 0 after create with FILE_SUPERSEDE
    2126             :  */
    2127           6 : static bool test_ntcreatex_supersede(struct torture_context *tctx, struct smbcli_state *cli)
    2128             : {
    2129           1 :         union smb_open io;
    2130           1 :         union smb_setfileinfo sfi;
    2131           1 :         union smb_fileinfo finfo;
    2132           6 :         const char *fname = BASEDIR "\\torture_ntcreatex_supersede.txt";
    2133           1 :         NTSTATUS status;
    2134           6 :         int fnum = -1;
    2135           6 :         bool ret = true;
    2136             : 
    2137           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    2138             : 
    2139             :         /* reasonable default parameters */
    2140           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2141           6 :         io.ntcreatex.in.flags = 0;
    2142           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    2143           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2144           6 :         io.ntcreatex.in.alloc_size = 0;
    2145           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2146           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2147           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2148           6 :         io.ntcreatex.in.create_options = 0;
    2149           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2150           6 :         io.ntcreatex.in.security_flags = 0;
    2151           6 :         io.ntcreatex.in.fname = fname;
    2152             : 
    2153           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2154           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2155           6 :         fnum = io.ntcreatex.out.file.fnum;
    2156             : 
    2157           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2158           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    2159           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2160           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2161           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    2162           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    2163           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2164           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2165           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    2166           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2167           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2168             : 
    2169             :         /* extend the file size */
    2170           6 :         ZERO_STRUCT(sfi);
    2171           6 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
    2172           6 :         sfi.generic.in.file.fnum = fnum;
    2173           6 :         sfi.end_of_file_info.in.size = 512;
    2174           6 :         status = smb_raw_setfileinfo(cli->tree, &sfi);
    2175           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2176             : 
    2177             :         /* close the file and re-open with to verify new size */
    2178           6 :         smbcli_close(cli->tree, fnum);
    2179           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    2180           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
    2181           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2182           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2183           6 :         fnum = io.ntcreatex.out.file.fnum;
    2184             : 
    2185           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2186           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
    2187           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2188           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2189           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    2190           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    2191           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2192           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2193           6 :         CHECK_VAL(io.ntcreatex.out.size, 512);
    2194           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2195           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2196             : 
    2197             :         /* close and re-open the file with SUPERSEDE flag */
    2198           6 :         smbcli_close(cli->tree, fnum);
    2199           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
    2200           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
    2201           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2202           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2203           6 :         io.ntcreatex.in.create_options = 0;
    2204             : 
    2205           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2206           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2207           6 :         fnum = io.ntcreatex.out.file.fnum;
    2208             : 
    2209             :         /* The file size in the superseded create response should be 0 */
    2210           6 :         CHECK_VAL(io.ntcreatex.out.size, 0);
    2211           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2212           6 :         CHECK_VAL(io.ntcreatex.out.create_action, FILE_WAS_SUPERSEDED);
    2213           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2214           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2215           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2216           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2217           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2218           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2219           6 : done:
    2220           6 :         smbcli_close(cli->tree, fnum);
    2221           6 :         smbcli_deltree(cli->tree, BASEDIR);
    2222             : 
    2223           6 :         return ret;
    2224             : }
    2225             : 
    2226             : /* basic testing of all RAW_OPEN_* calls
    2227             : */
    2228        2379 : struct torture_suite *torture_raw_open(TALLOC_CTX *mem_ctx)
    2229             : {
    2230        2379 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "open");
    2231             : 
    2232        2379 :         torture_suite_add_1smb_test(suite, "brlocked", test_ntcreatex_brlocked);
    2233        2379 :         torture_suite_add_1smb_test(suite, "open", test_open);
    2234        2379 :         torture_suite_add_1smb_test(suite, "open-multi", test_raw_open_multi);
    2235        2379 :         torture_suite_add_1smb_test(suite, "openx", test_openx);
    2236        2379 :         torture_suite_add_1smb_test(suite, "ntcreatex", test_ntcreatex);
    2237        2379 :         torture_suite_add_1smb_test(suite, "nttrans-create", test_nttrans_create);
    2238        2379 :         torture_suite_add_1smb_test(suite, "t2open", test_t2open);
    2239        2379 :         torture_suite_add_1smb_test(suite, "mknew", test_mknew);
    2240        2379 :         torture_suite_add_1smb_test(suite, "create", test_create);
    2241        2379 :         torture_suite_add_1smb_test(suite, "ctemp", test_ctemp);
    2242        2379 :         torture_suite_add_1smb_test(suite, "chained-openx", test_chained);
    2243        2379 :         torture_suite_add_1smb_test(suite, "chained-ntcreatex", test_chained_ntcreatex_readx);
    2244        2379 :         torture_suite_add_1smb_test(suite, "no-leading-slash", test_no_leading_slash);
    2245        2379 :         torture_suite_add_1smb_test(suite, "openx-over-dir", test_openx_over_dir);
    2246        2379 :         torture_suite_add_1smb_test(suite, "open-for-delete", test_open_for_delete);
    2247        2379 :         torture_suite_add_1smb_test(suite, "opendisp-dir", test_ntcreatex_opendisp_dir);
    2248        2379 :         torture_suite_add_1smb_test(suite, "ntcreatedir", test_ntcreatexdir);
    2249        2379 :         torture_suite_add_1smb_test(suite, "open-for-truncate", test_open_for_truncate);
    2250        2379 :         torture_suite_add_1smb_test(suite, "ntcreatex_supersede", test_ntcreatex_supersede);
    2251             : 
    2252        2379 :         return suite;
    2253             : }

Generated by: LCOV version 1.14