LCOV - code coverage report
Current view: top level - source4/torture/raw - open.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 1201 1278 94.0 %
Date: 2021-09-23 10: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             :         union smb_open io;
     164             :         union smb_fileinfo finfo;
     165           6 :         const char *fname = BASEDIR "\\torture_open.txt";
     166             :         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          11 : 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             :         union smb_open io;
     275             :         union smb_fileinfo finfo;
     276           6 :         const char *fname = BASEDIR "\\torture_openx.txt";
     277           6 :         const char *fname_exe = BASEDIR "\\torture_openx.exe";
     278             :         NTSTATUS status;
     279           6 :         int fnum = -1, fnum2;
     280           6 :         bool ret = true;
     281             :         int i;
     282             :         struct timeval tv;
     283             :         struct {
     284             :                 uint16_t open_func;
     285             :                 bool with_file;
     286             :                 NTSTATUS correct_status;
     287           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             :         union smb_open io;
     511             :         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             :         NTSTATUS status;
     516             :         int fnum;
     517           6 :         bool ret = true;
     518             :         int i;
     519             :         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          78 :         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          11 : 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             :         union smb_open io;
     683             :         union smb_fileinfo finfo;
     684           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
     685           6 :         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
     686             :         NTSTATUS status;
     687           6 :         int fnum = -1;
     688           6 :         bool ret = true;
     689             :         int i;
     690             :         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           5 :         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.alloc_size, 0);
     844           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     845           6 :         smbcli_unlink(cli->tree, fname);
     846             :         
     847             : 
     848           6 : done:
     849           6 :         smbcli_close(cli->tree, fnum);
     850           6 :         smbcli_deltree(cli->tree, BASEDIR);
     851             : 
     852           6 :         return ret;
     853             : }
     854             : 
     855             : 
     856             : /*
     857             :   test RAW_OPEN_NTTRANS_CREATE
     858             : */
     859           6 : static bool test_nttrans_create(struct torture_context *tctx, struct smbcli_state *cli)
     860             : {
     861             :         union smb_open io;
     862             :         union smb_fileinfo finfo;
     863           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
     864           6 :         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
     865             :         NTSTATUS status;
     866           6 :         int fnum = -1;
     867           6 :         bool ret = true;
     868             :         int i;
     869             :         uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
     870             :         uint32_t not_a_directory_mask, unexpected_mask;
     871             :         struct {
     872             :                 uint32_t open_disp;
     873             :                 bool with_file;
     874             :                 NTSTATUS correct_status;
     875           6 :         } open_funcs[] = {
     876             :                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
     877             :                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
     878             :                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
     879             :                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     880             :                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
     881             :                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
     882             :                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
     883             :                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
     884             :                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
     885             :                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     886             :                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
     887             :                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
     888             :                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
     889             :                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
     890             :         };
     891             : 
     892           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     893             : 
     894             :         /* reasonable default parameters */
     895           6 :         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
     896           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     897           6 :         io.ntcreatex.in.root_fid.fnum = 0;
     898           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     899           6 :         io.ntcreatex.in.alloc_size = 1024*1024;
     900           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     901           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     902           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     903           6 :         io.ntcreatex.in.create_options = 0;
     904           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     905           6 :         io.ntcreatex.in.security_flags = 0;
     906           6 :         io.ntcreatex.in.fname = fname;
     907           6 :         io.ntcreatex.in.sec_desc = NULL;
     908           6 :         io.ntcreatex.in.ea_list = NULL;
     909             : 
     910             :         /* test the open disposition */
     911          90 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     912          84 :                 if (open_funcs[i].with_file) {
     913          42 :                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
     914          42 :                         if (fnum == -1) {
     915           0 :                                 torture_result(tctx, TORTURE_FAIL,
     916             :                                         "Failed to create file %s - %s\n",
     917             :                                         fname, smbcli_errstr(cli->tree));
     918           0 :                                 ret = false;
     919           0 :                                 goto done;
     920             :                         }
     921          42 :                         smbcli_close(cli->tree, fnum);
     922             :                 }
     923          84 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
     924          84 :                 status = smb_raw_open(cli->tree, tctx, &io);
     925          84 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
     926           0 :                         torture_result(tctx, TORTURE_FAIL,
     927             :                                 "(%s) incorrect status %s should be %s "
     928             :                                 "(i=%d with_file=%d open_disp=%d)\n",
     929             :                                 __location__, nt_errstr(status),
     930             :                                 nt_errstr(open_funcs[i].correct_status),
     931           0 :                                 i, (int)open_funcs[i].with_file,
     932           0 :                                 (int)open_funcs[i].open_disp);
     933           0 :                         ret = false;
     934             :                 }
     935          84 :                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
     936          66 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
     937          66 :                         smbcli_unlink(cli->tree, fname);
     938             :                 }
     939             :         }
     940             : 
     941             :         /* basic field testing */
     942           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     943             : 
     944           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     945           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     946           6 :         fnum = io.ntcreatex.out.file.fnum;
     947             : 
     948           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     949           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
     950           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     951           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     952           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     953           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     954           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     955           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     956           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     957           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     958           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     959             : 
     960             :         /* check fields when the file already existed */
     961           6 :         smbcli_close(cli->tree, fnum);
     962           6 :         smbcli_unlink(cli->tree, fname);
     963           6 :         fnum = create_complex_file(cli, tctx, fname);
     964           6 :         if (fnum == -1) {
     965           0 :                 ret = false;
     966           0 :                 goto done;
     967             :         }
     968           6 :         smbcli_close(cli->tree, fnum);
     969             : 
     970           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
     971           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     972           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     973           6 :         fnum = io.ntcreatex.out.file.fnum;
     974             : 
     975           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     976           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     977           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     978           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     979           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     980           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
     981           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
     982           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
     983           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
     984           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
     985           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
     986           6 :         smbcli_close(cli->tree, fnum);
     987             : 
     988             :         /* check no-recall - don't pull a file from tape on a HSM */
     989           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
     990           6 :         status = smb_raw_open(cli->tree, tctx, &io);
     991           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     992           6 :         fnum = io.ntcreatex.out.file.fnum;
     993             : 
     994           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
     995           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
     996           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
     997           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
     998           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
     999           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    1000           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1001           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1002           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1003           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1004           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1005           6 :         smbcli_close(cli->tree, fnum);
    1006             : 
    1007             :         /* Check some create options (these all should be ignored) */
    1008         198 :         for (i=0; i < 32; i++) {
    1009         192 :                 uint32_t create_option =
    1010         192 :                         ((uint32_t)1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
    1011         192 :                 if (create_option == 0) {
    1012         150 :                         continue;
    1013             :                 }
    1014          42 :                 io.ntcreatex.in.create_options = create_option;
    1015          42 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1016          42 :                 if (!NT_STATUS_IS_OK(status)) {
    1017           0 :                         torture_warning(tctx, "ntcreatex create option 0x%08x "
    1018             :                                 "gave %s - should give NT_STATUS_OK\n",
    1019             :                                 create_option, nt_errstr(status));
    1020             :                 }
    1021          42 :                 CHECK_STATUS(status, NT_STATUS_OK);
    1022          42 :                 fnum = io.ntcreatex.out.file.fnum;
    1023             : 
    1024          42 :                 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1025          42 :                 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
    1026          42 :                 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    1027          42 :                 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    1028          42 :                 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    1029          42 :                 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    1030          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1031          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1032          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1033          42 :                 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1034          42 :                 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1035          42 :                 smbcli_close(cli->tree, fnum);
    1036             :         }
    1037             : 
    1038           6 :         io.ntcreatex.in.file_attr = 0;
    1039           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1040           6 :         io.ntcreatex.in.access_mask     = SEC_FLAG_MAXIMUM_ALLOWED;
    1041             : 
    1042             :         /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
    1043           6 :         ok_mask = 0;
    1044           6 :         not_supported_mask = 0;
    1045           6 :         invalid_parameter_mask = 0;
    1046           6 :         not_a_directory_mask = 0;
    1047           6 :         unexpected_mask = 0;
    1048         198 :         for (i=0; i < 32; i++) {
    1049         192 :                 uint32_t create_option = (uint32_t)1<<i;
    1050         192 :                 if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
    1051           6 :                         continue;
    1052             :                 }
    1053         186 :                 io.ntcreatex.in.create_options = create_option;
    1054         186 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1055         186 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
    1056           6 :                         not_supported_mask |= create_option;
    1057         180 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
    1058         108 :                         ok_mask |= create_option;
    1059         108 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1060          72 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
    1061          66 :                         invalid_parameter_mask |= create_option;
    1062           6 :                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
    1063           6 :                         not_a_directory_mask |= 1<<i;
    1064             :                 } else {
    1065           0 :                         unexpected_mask |= 1<<i;
    1066           0 :                         torture_comment(tctx, "create option 0x%08x returned %s\n",
    1067             :                                         create_option, nt_errstr(status));
    1068             :                 }
    1069             :         }
    1070             : 
    1071           6 :         CHECK_VAL(ok_mask,                0x00efcfce);
    1072           6 :         CHECK_VAL(not_a_directory_mask,   0x00000001);
    1073           6 :         CHECK_VAL(not_supported_mask,     0x00002000);
    1074           6 :         CHECK_VAL(invalid_parameter_mask, 0xff100030);
    1075           6 :         CHECK_VAL(unexpected_mask,        0x00000000);
    1076             : 
    1077           6 :         smbcli_unlink(cli->tree, fname);
    1078             : 
    1079             : 
    1080             :         /* create a directory */
    1081           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1082           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1083           6 :         io.ntcreatex.in.alloc_size = 0;
    1084           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1085           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1086           5 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1087           6 :         io.ntcreatex.in.create_options = 0;
    1088           6 :         io.ntcreatex.in.fname = dname;
    1089           6 :         fname = dname;
    1090             : 
    1091           6 :         smbcli_rmdir(cli->tree, fname);
    1092           6 :         smbcli_unlink(cli->tree, fname);
    1093             : 
    1094           6 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1095           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1096           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1097           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1098           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1099           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1100           6 :         fnum = io.ntcreatex.out.file.fnum;
    1101             : 
    1102           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1103           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    1104           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    1105           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    1106           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    1107           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    1108           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1109           6 :         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
    1110             :                   FILE_ATTRIBUTE_DIRECTORY);
    1111           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    1112           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    1113           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    1114           6 :         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
    1115           6 :         CHECK_VAL(io.ntcreatex.out.size, 0);
    1116           6 :         CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
    1117           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    1118           6 :         smbcli_unlink(cli->tree, fname);
    1119             :         
    1120             : 
    1121           6 : done:
    1122           6 :         smbcli_close(cli->tree, fnum);
    1123           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1124             : 
    1125           6 :         return ret;
    1126             : }
    1127             : 
    1128             : /*
    1129             :   test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
    1130             : 
    1131             :   I've got an application that does a similar sequence of ntcreate&x,
    1132             :   locking&x and another ntcreate&x with
    1133             :   open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
    1134             :   second open.
    1135             : */
    1136           6 : static bool test_ntcreatex_brlocked(struct torture_context *tctx, struct smbcli_state *cli)
    1137             : {
    1138             :         union smb_open io, io1;
    1139             :         union smb_lock io2;
    1140             :         struct smb_lock_entry lock[1];
    1141           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
    1142             :         NTSTATUS status;
    1143           6 :         bool ret = true;
    1144             : 
    1145           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1146             : 
    1147           6 :         torture_comment(tctx, "Testing ntcreatex with a byte range locked file\n");
    1148             : 
    1149           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1150           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1151           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1152           6 :         io.ntcreatex.in.access_mask = 0x2019f;
    1153           6 :         io.ntcreatex.in.alloc_size = 0;
    1154           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1155           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1156             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1157           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1158           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    1159           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1160           6 :         io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
    1161             :                 NTCREATEX_SECURITY_ALL;
    1162           6 :         io.ntcreatex.in.fname = fname;
    1163             : 
    1164           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1165           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1166             : 
    1167           6 :         io2.lockx.level = RAW_LOCK_LOCKX;
    1168           6 :         io2.lockx.in.file.fnum = io.ntcreatex.out.file.fnum;
    1169           6 :         io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
    1170           6 :         io2.lockx.in.timeout = 0;
    1171           6 :         io2.lockx.in.ulock_cnt = 0;
    1172           6 :         io2.lockx.in.lock_cnt = 1;
    1173           6 :         lock[0].pid = cli->session->pid;
    1174           6 :         lock[0].offset = 0;
    1175           6 :         lock[0].count = 0x1;
    1176           6 :         io2.lockx.in.locks = &lock[0];
    1177           6 :         status = smb_raw_lock(cli->tree, &io2);
    1178           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1179             : 
    1180           6 :         io1.generic.level = RAW_OPEN_NTCREATEX;
    1181           6 :         io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1182           6 :         io1.ntcreatex.in.root_fid.fnum = 0;
    1183           6 :         io1.ntcreatex.in.access_mask = 0x20196;
    1184           6 :         io1.ntcreatex.in.alloc_size = 0;
    1185           6 :         io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1186           6 :         io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1187             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1188           6 :         io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
    1189           6 :         io1.ntcreatex.in.create_options = 0;
    1190           6 :         io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1191           6 :         io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
    1192             :                 NTCREATEX_SECURITY_ALL;
    1193           6 :         io1.ntcreatex.in.fname = fname;
    1194             : 
    1195           6 :         status = smb_raw_open(cli->tree, tctx, &io1);
    1196           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1197             : 
    1198          11 :  done:
    1199           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1200           6 :         smbcli_close(cli->tree, io1.ntcreatex.out.file.fnum);
    1201           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1202           6 :         return ret;
    1203             : }
    1204             : 
    1205             : /*
    1206             :   test RAW_OPEN_MKNEW
    1207             : */
    1208           6 : static bool test_mknew(struct torture_context *tctx, struct smbcli_state *cli)
    1209             : {
    1210             :         union smb_open io;
    1211           6 :         const char *fname = BASEDIR "\\torture_mknew.txt";
    1212             :         NTSTATUS status;
    1213           6 :         int fnum = -1;
    1214           6 :         bool ret = true;
    1215           6 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1216             :         union smb_fileinfo finfo;
    1217             : 
    1218           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1219             : 
    1220           6 :         io.mknew.level = RAW_OPEN_MKNEW;
    1221           6 :         io.mknew.in.attrib = 0;
    1222           6 :         io.mknew.in.write_time = 0;
    1223           6 :         io.mknew.in.fname = fname;
    1224           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1225           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1226           6 :         fnum = io.mknew.out.file.fnum;
    1227             : 
    1228           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1229           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
    1230             : 
    1231           6 :         smbcli_close(cli->tree, fnum);
    1232           6 :         smbcli_unlink(cli->tree, fname);
    1233             : 
    1234             :         /* make sure write_time works */
    1235           6 :         io.mknew.in.write_time = basetime;
    1236           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1237           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1238           6 :         fnum = io.mknew.out.file.fnum;
    1239           6 :         CHECK_TIME(basetime, write_time);
    1240             : 
    1241           6 :         smbcli_close(cli->tree, fnum);
    1242           6 :         smbcli_unlink(cli->tree, fname);
    1243             : 
    1244             :         /* make sure file_attrs works */
    1245           6 :         io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1246           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1247           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1248           6 :         fnum = io.mknew.out.file.fnum;
    1249           6 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
    1250             :                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
    1251             :         
    1252          11 : done:
    1253           6 :         smbcli_close(cli->tree, fnum);
    1254           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1255             : 
    1256           6 :         return ret;
    1257             : }
    1258             : 
    1259             : 
    1260             : /*
    1261             :   test RAW_OPEN_CREATE
    1262             : */
    1263           6 : static bool test_create(struct torture_context *tctx, struct smbcli_state *cli)
    1264             : {
    1265             :         union smb_open io;
    1266           6 :         const char *fname = BASEDIR "\\torture_create.txt";
    1267             :         NTSTATUS status;
    1268           6 :         int fnum = -1;
    1269           6 :         bool ret = true;
    1270           6 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1271             :         union smb_fileinfo finfo;
    1272             : 
    1273           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1274             : 
    1275           6 :         io.create.level = RAW_OPEN_CREATE;
    1276           6 :         io.create.in.attrib = 0;
    1277           6 :         io.create.in.write_time = 0;
    1278           6 :         io.create.in.fname = fname;
    1279           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1280           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1281           6 :         fnum = io.create.out.file.fnum;
    1282             : 
    1283           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1284           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1285             : 
    1286           6 :         smbcli_close(cli->tree, io.create.out.file.fnum);
    1287           6 :         smbcli_close(cli->tree, fnum);
    1288           6 :         smbcli_unlink(cli->tree, fname);
    1289             : 
    1290             :         /* make sure write_time works */
    1291           6 :         io.create.in.write_time = basetime;
    1292           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1293           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1294           6 :         fnum = io.create.out.file.fnum;
    1295           6 :         CHECK_TIME(basetime, write_time);
    1296             : 
    1297           6 :         smbcli_close(cli->tree, fnum);
    1298           6 :         smbcli_unlink(cli->tree, fname);
    1299             : 
    1300             :         /* make sure file_attrs works */
    1301           6 :         io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1302           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1303           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1304           6 :         fnum = io.create.out.file.fnum;
    1305           6 :         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
    1306             :                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
    1307             :         
    1308          11 : done:
    1309           6 :         smbcli_close(cli->tree, fnum);
    1310           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1311             : 
    1312           6 :         return ret;
    1313             : }
    1314             : 
    1315             : 
    1316             : /*
    1317             :   test RAW_OPEN_CTEMP
    1318             : */
    1319           6 : static bool test_ctemp(struct torture_context *tctx, struct smbcli_state *cli)
    1320             : {
    1321             :         union smb_open io;
    1322             :         NTSTATUS status;
    1323           6 :         int fnum = -1;
    1324           6 :         bool ret = true;
    1325           6 :         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
    1326             :         union smb_fileinfo finfo;
    1327           6 :         const char *name, *fname = NULL;
    1328             : 
    1329           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1330             : 
    1331           6 :         io.ctemp.level = RAW_OPEN_CTEMP;
    1332           6 :         io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
    1333           6 :         io.ctemp.in.write_time = basetime;
    1334           6 :         io.ctemp.in.directory = BASEDIR;
    1335           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1336           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1337           6 :         fnum = io.ctemp.out.file.fnum;
    1338             : 
    1339           6 :         name = io.ctemp.out.name;
    1340             : 
    1341           6 :         finfo.generic.level = RAW_FILEINFO_NAME_INFO;
    1342           6 :         finfo.generic.in.file.fnum = fnum;
    1343           6 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    1344           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1345             : 
    1346           6 :         fname = finfo.name_info.out.fname.s;
    1347           6 :         torture_comment(tctx, "ctemp name=%s  real name=%s\n", name, fname);
    1348             : 
    1349           6 : done:
    1350           6 :         smbcli_close(cli->tree, fnum);
    1351           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1352             : 
    1353           6 :         return ret;
    1354             : }
    1355             : 
    1356             : 
    1357             : /*
    1358             :   test chained RAW_OPEN_OPENX_READX
    1359             : */
    1360           6 : static bool test_chained(struct torture_context *tctx, struct smbcli_state *cli)
    1361             : {
    1362             :         union smb_open io;
    1363           6 :         const char *fname = BASEDIR "\\torture_chained.txt";
    1364             :         NTSTATUS status;
    1365           6 :         int fnum = -1;
    1366           6 :         bool ret = true;
    1367           6 :         const char buf[] = "test";
    1368             :         char buf2[4];
    1369             : 
    1370           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1371             : 
    1372           6 :         fnum = create_complex_file(cli, tctx, fname);
    1373             : 
    1374           6 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1375             : 
    1376           6 :         smbcli_close(cli->tree, fnum);       
    1377             : 
    1378           6 :         io.openxreadx.level = RAW_OPEN_OPENX_READX;
    1379           6 :         io.openxreadx.in.fname = fname;
    1380           6 :         io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1381           6 :         io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1382           6 :         io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1383           6 :         io.openxreadx.in.search_attrs = 0;
    1384           6 :         io.openxreadx.in.file_attrs = 0;
    1385           6 :         io.openxreadx.in.write_time = 0;
    1386           6 :         io.openxreadx.in.size = 1024*1024;
    1387           6 :         io.openxreadx.in.timeout = 0;
    1388             :         
    1389           6 :         io.openxreadx.in.offset = 0;
    1390           6 :         io.openxreadx.in.mincnt = sizeof(buf2);
    1391           6 :         io.openxreadx.in.maxcnt = sizeof(buf2);
    1392           6 :         io.openxreadx.in.remaining = 0;
    1393           6 :         io.openxreadx.out.data = (uint8_t *)buf2;
    1394             : 
    1395           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1396           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1397           6 :         fnum = io.openxreadx.out.file.fnum;
    1398             : 
    1399           6 :         if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
    1400           0 :                 torture_result(tctx, TORTURE_FAIL,
    1401             :                         "wrong data in reply buffer\n");
    1402           0 :                 ret = false;
    1403             :         }
    1404             : 
    1405          11 : done:
    1406           6 :         smbcli_close(cli->tree, fnum);
    1407           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1408             : 
    1409           6 :         return ret;
    1410             : }
    1411             : 
    1412             : /*
    1413             :   test RAW_OPEN_OPENX without a leading slash on the path.
    1414             :   NetApp filers are known to fail on this.
    1415             :   
    1416             : */
    1417           6 : static bool test_no_leading_slash(struct torture_context *tctx, struct smbcli_state *cli)
    1418             : {
    1419             :         union smb_open io;
    1420           6 :         const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
    1421             :         NTSTATUS status;
    1422           6 :         int fnum = -1;
    1423           6 :         bool ret = true;
    1424           6 :         const char buf[] = "test";
    1425             : 
    1426           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1427             : 
    1428           6 :         smbcli_unlink(cli->tree, fname);
    1429             : 
    1430             :         /* Create the file */
    1431           6 :         fnum = create_complex_file(cli, tctx, fname);
    1432           6 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1433           6 :         smbcli_close(cli->tree, fnum);       
    1434             : 
    1435             :         /* Prepare to open the file using path without leading slash */
    1436           6 :         io.openx.level = RAW_OPEN_OPENX;
    1437           6 :         io.openx.in.fname = fname + 1;
    1438           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1439           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1440           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1441           6 :         io.openx.in.search_attrs = 0;
    1442           6 :         io.openx.in.file_attrs = 0;
    1443           6 :         io.openx.in.write_time = 0;
    1444           6 :         io.openx.in.size = 1024*1024;
    1445           6 :         io.openx.in.timeout = 0;
    1446             : 
    1447           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1448           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1449           6 :         fnum = io.openx.out.file.fnum;
    1450             : 
    1451           6 : done:
    1452           6 :         smbcli_close(cli->tree, fnum);
    1453           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1454             : 
    1455           6 :         return ret;
    1456             : }
    1457             : 
    1458             : /*
    1459             :   test RAW_OPEN_OPENX against an existing directory to
    1460             :   ensure it returns NT_STATUS_FILE_IS_A_DIRECTORY.
    1461             :   Samba 3.2.0 - 3.2.6 are known to fail this.
    1462             :   
    1463             : */
    1464           6 : static bool test_openx_over_dir(struct torture_context *tctx, struct smbcli_state *cli)
    1465             : {
    1466             :         union smb_open io;
    1467           6 :         const char *fname = BASEDIR "\\openx_over_dir";
    1468             :         NTSTATUS status;
    1469           6 :         int d_fnum = -1;
    1470           6 :         int fnum = -1;
    1471           6 :         bool ret = true;
    1472             : 
    1473           6 :         ZERO_STRUCT(io);
    1474             : 
    1475           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1476             : 
    1477             :         /* Create the Directory */
    1478           6 :         status = create_directory_handle(cli->tree, fname, &d_fnum);
    1479           6 :         smbcli_close(cli->tree, d_fnum);     
    1480             : 
    1481             :         /* Prepare to open the file over the directory. */
    1482           6 :         io.openx.level = RAW_OPEN_OPENX;
    1483           6 :         io.openx.in.fname = fname;
    1484           6 :         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
    1485           6 :         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
    1486           6 :         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
    1487           6 :         io.openx.in.search_attrs = 0;
    1488           6 :         io.openx.in.file_attrs = 0;
    1489           6 :         io.openx.in.write_time = 0;
    1490           6 :         io.openx.in.size = 1024*1024;
    1491           6 :         io.openx.in.timeout = 0;
    1492             : 
    1493           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1494           6 :         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
    1495           6 :         fnum = io.openx.out.file.fnum;
    1496             : 
    1497           6 : done:
    1498           6 :         smbcli_close(cli->tree, fnum);
    1499           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1500             : 
    1501           6 :         return ret;
    1502             : }
    1503             : 
    1504             : 
    1505             : /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
    1506             : 
    1507           6 : static bool test_raw_open_multi(struct torture_context *tctx, struct smbcli_state *cli_ignored)
    1508             : {
    1509             :         struct smbcli_state *cli;
    1510           6 :         TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
    1511           6 :         const char *fname = "\\test_oplock.dat";
    1512             :         NTSTATUS status;
    1513           6 :         bool ret = true;
    1514             :         union smb_open io;
    1515             :         struct smbcli_state **clients;
    1516             :         struct smbcli_request **requests;
    1517             :         union smb_open *ios;
    1518           6 :         const char *host = torture_setting_string(tctx, "host", NULL);
    1519           6 :         const char *share = torture_setting_string(tctx, "share", NULL);
    1520           6 :         int i, num_files = 3;
    1521           6 :         int num_ok = 0;
    1522           6 :         int num_collision = 0;
    1523             :         
    1524           6 :         clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
    1525           6 :         requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
    1526           6 :         ios = talloc_array(mem_ctx, union smb_open, num_files);
    1527           6 :         if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
    1528             :             (ios == NULL)) {
    1529           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s): talloc failed\n",
    1530             :                                 __location__);
    1531           0 :                 return false;
    1532             :         }
    1533             : 
    1534           6 :         if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
    1535           0 :                 return false;
    1536             :         }
    1537             : 
    1538           6 :         cli->tree->session->transport->options.request_timeout = 60;
    1539             : 
    1540          24 :         for (i=0; i<num_files; i++) {
    1541          18 :                 if (!torture_open_connection_share(mem_ctx, &(clients[i]),
    1542             :                                                    tctx, host, share, tctx->ev)) {
    1543           0 :                         torture_result(tctx, TORTURE_FAIL,
    1544             :                                        "(%s): Could not open %d'th connection\n",
    1545             :                                        __location__, i);
    1546           0 :                         return false;
    1547             :                 }
    1548          18 :                 clients[i]->tree->session->transport->options.request_timeout = 60;
    1549             :         }
    1550             : 
    1551             :         /* cleanup */
    1552           6 :         smbcli_unlink(cli->tree, fname);
    1553             : 
    1554             :         /*
    1555             :           base ntcreatex parms
    1556             :         */
    1557           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1558           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1559           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1560           6 :         io.ntcreatex.in.alloc_size = 0;
    1561           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1562           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1563             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    1564             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    1565           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1566           6 :         io.ntcreatex.in.create_options = 0;
    1567           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1568           6 :         io.ntcreatex.in.security_flags = 0;
    1569           6 :         io.ntcreatex.in.fname = fname;
    1570           6 :         io.ntcreatex.in.flags = 0;
    1571             : 
    1572          24 :         for (i=0; i<num_files; i++) {
    1573          18 :                 ios[i] = io;
    1574          18 :                 requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
    1575          18 :                 if (requests[i] == NULL) {
    1576           0 :                         torture_result(tctx, TORTURE_FAIL,
    1577             :                                 "(%s): could not send %d'th request\n",
    1578             :                                 __location__, i);
    1579           0 :                         return false;
    1580             :                 }
    1581             :         }
    1582             : 
    1583           6 :         torture_comment(tctx, "waiting for replies\n");
    1584          45 :         while (1) {
    1585          60 :                 bool unreplied = false;
    1586          94 :                 for (i=0; i<num_files; i++) {
    1587          88 :                         if (requests[i] == NULL) {
    1588          16 :                                 continue;
    1589             :                         }
    1590          72 :                         if (requests[i]->state < SMBCLI_REQUEST_DONE) {
    1591          45 :                                 unreplied = true;
    1592          45 :                                 break;
    1593             :                         }
    1594          18 :                         status = smb_raw_open_recv(requests[i], mem_ctx,
    1595          18 :                                                    &ios[i]);
    1596             : 
    1597          18 :                         torture_comment(tctx, "File %d returned status %s\n", i,
    1598             :                                   nt_errstr(status));
    1599             : 
    1600          18 :                         if (NT_STATUS_IS_OK(status)) {
    1601           6 :                                 num_ok += 1;
    1602             :                         } 
    1603             : 
    1604          18 :                         if (NT_STATUS_EQUAL(status,
    1605             :                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
    1606          12 :                                 num_collision += 1;
    1607             :                         }
    1608             : 
    1609          18 :                         requests[i] = NULL;
    1610             :                 }
    1611          60 :                 if (!unreplied) {
    1612           5 :                         break;
    1613             :                 }
    1614             : 
    1615          54 :                 if (tevent_loop_once(tctx->ev) != 0) {
    1616           0 :                         torture_result(tctx, TORTURE_FAIL,
    1617             :                                 "(%s): tevent_loop_once failed\n", __location__);
    1618           0 :                         return false;
    1619             :                 }
    1620             :         }
    1621             : 
    1622           6 :         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
    1623           0 :                 ret = false;
    1624             :         }
    1625             : 
    1626          24 :         for (i=0; i<num_files; i++) {
    1627          18 :                 torture_close_connection(clients[i]);
    1628             :         }
    1629           6 :         talloc_free(mem_ctx);
    1630           6 :         return ret;
    1631             : }
    1632             : 
    1633             : /*
    1634             :   test opening for delete on a read-only attribute file.
    1635             : */
    1636           6 : static bool test_open_for_delete(struct torture_context *tctx, struct smbcli_state *cli)
    1637             : {
    1638             :         union smb_open io;
    1639             :         union smb_fileinfo finfo;
    1640           6 :         const char *fname = BASEDIR "\\torture_open_for_delete.txt";
    1641             :         NTSTATUS status;
    1642           6 :         int fnum = -1;
    1643           6 :         bool ret = true;
    1644             : 
    1645           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1646             : 
    1647             :         /* reasonable default parameters */
    1648           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1649           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1650           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1651           6 :         io.ntcreatex.in.alloc_size = 0;
    1652           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1653           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
    1654           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1655           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1656           6 :         io.ntcreatex.in.create_options = 0;
    1657           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1658           6 :         io.ntcreatex.in.security_flags = 0;
    1659           6 :         io.ntcreatex.in.fname = fname;
    1660             : 
    1661             :         /* Create the readonly file. */
    1662             : 
    1663           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1664           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1665           6 :         fnum = io.ntcreatex.out.file.fnum;
    1666             : 
    1667           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    1668           6 :         io.ntcreatex.in.create_options = 0;
    1669           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    1670           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    1671           6 :         smbcli_close(cli->tree, fnum);
    1672             : 
    1673             :         /* Now try and open for delete only - should succeed. */
    1674           6 :         io.ntcreatex.in.access_mask = SEC_STD_DELETE;
    1675           6 :         io.ntcreatex.in.file_attr = 0;
    1676           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    1677           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1678           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1679           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1680             : 
    1681           6 :         smbcli_unlink(cli->tree, fname);
    1682             : 
    1683           6 : done:
    1684           6 :         smbcli_close(cli->tree, fnum);
    1685           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1686             : 
    1687           6 :         return ret;
    1688             : }
    1689             : 
    1690             : /*
    1691             :   test chained RAW_OPEN_NTCREATEX_READX
    1692             :   Send chained NTCREATEX_READX on a file that doesn't exist, then create
    1693             :   the file and try again.
    1694             : */
    1695           6 : static bool test_chained_ntcreatex_readx(struct torture_context *tctx, struct smbcli_state *cli)
    1696             : {
    1697           6 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    1698             :         union smb_open io;
    1699           6 :         const char *fname = BASEDIR "\\torture_chained.txt";
    1700             :         NTSTATUS status;
    1701           6 :         int fnum = -1;
    1702           6 :         bool ret = true;
    1703           6 :         const char buf[] = "test";
    1704             :         char buf2[4];
    1705             : 
    1706           6 :         ZERO_STRUCT(io);
    1707             : 
    1708           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1709             : 
    1710           6 :         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
    1711             :                               "non-existent file \n");
    1712             : 
    1713             :         /* ntcreatex parameters */
    1714           6 :         io.generic.level = RAW_OPEN_NTCREATEX_READX;
    1715           6 :         io.ntcreatexreadx.in.flags = 0;
    1716           6 :         io.ntcreatexreadx.in.root_fid.fnum = 0;
    1717           6 :         io.ntcreatexreadx.in.access_mask = SEC_FILE_READ_DATA;
    1718           6 :         io.ntcreatexreadx.in.alloc_size = 0;
    1719           6 :         io.ntcreatexreadx.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1720           6 :         io.ntcreatexreadx.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1721             :                 NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
    1722           6 :         io.ntcreatexreadx.in.open_disposition = NTCREATEX_DISP_OPEN;
    1723           6 :         io.ntcreatexreadx.in.create_options = 0;
    1724           6 :         io.ntcreatexreadx.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
    1725           6 :         io.ntcreatexreadx.in.security_flags = 0;
    1726           6 :         io.ntcreatexreadx.in.fname = fname;
    1727             : 
    1728             :         /* readx parameters */
    1729           6 :         io.ntcreatexreadx.in.offset = 0;
    1730           6 :         io.ntcreatexreadx.in.mincnt = sizeof(buf2);
    1731           6 :         io.ntcreatexreadx.in.maxcnt = sizeof(buf2);
    1732           6 :         io.ntcreatexreadx.in.remaining = 0;
    1733           6 :         io.ntcreatexreadx.out.data = (uint8_t *)buf2;
    1734             : 
    1735             :         /* try to open the non-existent file */
    1736           6 :         status = smb_raw_open(cli->tree, mem_ctx, &io);
    1737           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1738           6 :         fnum = io.ntcreatexreadx.out.file.fnum;
    1739             : 
    1740           6 :         smbcli_close(cli->tree, fnum);
    1741           6 :         smbcli_unlink(cli->tree, fname);
    1742             : 
    1743           6 :         torture_comment(tctx, "Checking RAW_NTCREATEX_READX chained on "
    1744             :                               "existing file \n");
    1745             : 
    1746           6 :         fnum = create_complex_file(cli, mem_ctx, fname);
    1747           6 :         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
    1748           6 :         smbcli_close(cli->tree, fnum);
    1749             : 
    1750           6 :         status = smb_raw_open(cli->tree, mem_ctx, &io);
    1751           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1752           6 :         fnum = io.ntcreatexreadx.out.file.fnum;
    1753             : 
    1754           6 :         if (memcmp(buf, buf2, MIN(sizeof(buf), sizeof(buf2))) != 0) {
    1755           0 :                 torture_result(tctx, TORTURE_FAIL,
    1756             :                         "(%s): wrong data in reply buffer\n", __location__);
    1757           0 :                 ret = false;
    1758             :         }
    1759             : 
    1760          11 : done:
    1761           6 :         smbcli_close(cli->tree, fnum);
    1762           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1763           6 :         talloc_free(mem_ctx);
    1764             : 
    1765           6 :         return ret;
    1766             : }
    1767             : 
    1768           6 : static bool test_ntcreatex_opendisp_dir(struct torture_context *tctx,
    1769             :                                         struct smbcli_state *cli)
    1770             : {
    1771           6 :         const char *dname = BASEDIR "\\torture_ntcreatex_opendisp_dir";
    1772             :         NTSTATUS status;
    1773           6 :         bool ret = true;
    1774             :         int i;
    1775             :         struct {
    1776             :                 uint32_t open_disp;
    1777             :                 bool dir_exists;
    1778             :                 NTSTATUS correct_status;
    1779           6 :         } open_funcs_dir[] = {
    1780             :                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_INVALID_PARAMETER },
    1781             :                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_INVALID_PARAMETER },
    1782             :                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
    1783             :                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1784             :                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
    1785             :                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
    1786             :                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
    1787             :                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
    1788             :                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_INVALID_PARAMETER },
    1789             :                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_INVALID_PARAMETER },
    1790             :                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_INVALID_PARAMETER },
    1791             :                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_INVALID_PARAMETER },
    1792             :                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
    1793             :                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
    1794             :         };
    1795             :         union smb_open io;
    1796             : 
    1797           6 :         ZERO_STRUCT(io);
    1798           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1799           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1800           6 :         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1801           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1802           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1803           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1804           6 :         io.ntcreatex.in.fname = dname;
    1805             : 
    1806           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1807             : 
    1808           6 :         smbcli_rmdir(cli->tree, dname);
    1809           6 :         smbcli_unlink(cli->tree, dname);
    1810             : 
    1811             :         /* test the open disposition for directories */
    1812           6 :         torture_comment(tctx, "Testing open dispositions for directories...\n");
    1813             : 
    1814          90 :         for (i=0; i<ARRAY_SIZE(open_funcs_dir); i++) {
    1815          84 :                 if (open_funcs_dir[i].dir_exists) {
    1816          42 :                         status = smbcli_mkdir(cli->tree, dname);
    1817          42 :                         if (!NT_STATUS_IS_OK(status)) {
    1818           0 :                                 torture_result(tctx, TORTURE_FAIL,
    1819             :                                         "(%s): Failed to make directory "
    1820             :                                         "%s - %s\n", __location__, dname,
    1821             :                                         smbcli_errstr(cli->tree));
    1822           0 :                                 ret = false;
    1823           0 :                                 goto done;
    1824             :                         }
    1825             :                 }
    1826             : 
    1827          84 :                 io.ntcreatex.in.open_disposition = open_funcs_dir[i].open_disp;
    1828          84 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1829          84 :                 if (!NT_STATUS_EQUAL(status, open_funcs_dir[i].correct_status)) {
    1830           0 :                         torture_result(tctx, TORTURE_FAIL,
    1831             :                                 "(%s) incorrect status %s should be %s "
    1832             :                                 "(i=%d dir_exists=%d open_disp=%d)\n",
    1833             :                                 __location__, nt_errstr(status),
    1834             :                                 nt_errstr(open_funcs_dir[i].correct_status),
    1835           0 :                                 i, (int)open_funcs_dir[i].dir_exists,
    1836           0 :                                 (int)open_funcs_dir[i].open_disp);
    1837           0 :                         ret = false;
    1838             :                 }
    1839          84 :                 if (NT_STATUS_IS_OK(status) || open_funcs_dir[i].dir_exists) {
    1840          54 :                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1841          54 :                         smbcli_rmdir(cli->tree, dname);
    1842             :                 }
    1843             :         }
    1844             : 
    1845           6 : done:
    1846           6 :         smbcli_deltree(cli->tree, BASEDIR);
    1847             : 
    1848           6 :         return ret;
    1849             : }
    1850             : 
    1851             : /**
    1852             :  * Test what happens when trying to open a file with directory parameters and
    1853             :  * vice-versa.  Also test that NTCREATEX_OPTIONS_DIRECTORY is treated as
    1854             :  * mandatory and FILE_ATTRIBUTE_DIRECTORY is advisory for directory
    1855             :  * creation/opening.
    1856             :  */
    1857           6 : static bool test_ntcreatexdir(struct torture_context *tctx,
    1858             :     struct smbcli_state *cli)
    1859             : {
    1860             :         union smb_open io;
    1861           6 :         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
    1862           6 :         const char *dname = BASEDIR "\\torture_ntcreatex_dir";
    1863             :         NTSTATUS status;
    1864             :         int i;
    1865             : 
    1866             :         struct {
    1867             :                 uint32_t open_disp;
    1868             :                 uint32_t file_attr;
    1869             :                 uint32_t create_options;
    1870             :                 NTSTATUS correct_status;
    1871           6 :         } open_funcs[] = {
    1872             :                 { NTCREATEX_DISP_SUPERSEDE,     0, NTCREATEX_OPTIONS_DIRECTORY,
    1873             :                   NT_STATUS_INVALID_PARAMETER },
    1874             :                 { NTCREATEX_DISP_OPEN,          0, NTCREATEX_OPTIONS_DIRECTORY,
    1875             :                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1876             :                 { NTCREATEX_DISP_CREATE,        0, NTCREATEX_OPTIONS_DIRECTORY,
    1877             :                   NT_STATUS_OK },
    1878             :                 { NTCREATEX_DISP_OPEN_IF,       0, NTCREATEX_OPTIONS_DIRECTORY,
    1879             :                   NT_STATUS_OK },
    1880             :                 { NTCREATEX_DISP_OVERWRITE,     0, NTCREATEX_OPTIONS_DIRECTORY,
    1881             :                   NT_STATUS_INVALID_PARAMETER },
    1882             :                 { NTCREATEX_DISP_OVERWRITE_IF,  0, NTCREATEX_OPTIONS_DIRECTORY,
    1883             :                   NT_STATUS_INVALID_PARAMETER },
    1884             :                 { NTCREATEX_DISP_SUPERSEDE,     FILE_ATTRIBUTE_DIRECTORY, 0,
    1885             :                   NT_STATUS_OK },
    1886             :                 { NTCREATEX_DISP_OPEN,          FILE_ATTRIBUTE_DIRECTORY, 0,
    1887             :                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1888             :                 { NTCREATEX_DISP_CREATE,        FILE_ATTRIBUTE_DIRECTORY, 0,
    1889             :                   NT_STATUS_OK },
    1890             :                 { NTCREATEX_DISP_OPEN_IF,       FILE_ATTRIBUTE_DIRECTORY, 0,
    1891             :                   NT_STATUS_OK },
    1892             :                 { NTCREATEX_DISP_OVERWRITE,     FILE_ATTRIBUTE_DIRECTORY, 0,
    1893             :                   NT_STATUS_OBJECT_NAME_NOT_FOUND },
    1894             :                 { NTCREATEX_DISP_OVERWRITE_IF,  FILE_ATTRIBUTE_DIRECTORY, 0,
    1895             :                   NT_STATUS_OK },
    1896             : 
    1897             :         };
    1898             : 
    1899           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    1900             : 
    1901             :         /* setup some base params. */
    1902           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1903           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1904           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    1905           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1906           6 :         io.ntcreatex.in.alloc_size = 0;
    1907           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1908           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1909           6 :         io.ntcreatex.in.security_flags = 0;
    1910           6 :         io.ntcreatex.in.fname = fname;
    1911             : 
    1912             :         /*
    1913             :          * Test the validity checking for create dispositions, which is done
    1914             :          * against the requested parameters rather than what's actually on
    1915             :          * disk.
    1916             :          */
    1917          78 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
    1918          72 :                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
    1919          72 :                 io.ntcreatex.in.file_attr = open_funcs[i].file_attr;
    1920          72 :                 io.ntcreatex.in.create_options = open_funcs[i].create_options;
    1921          72 :                 status = smb_raw_open(cli->tree, tctx, &io);
    1922          72 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
    1923           0 :                         torture_result(tctx, TORTURE_FAIL,
    1924             :                                 "(%s) incorrect status %s should be %s "
    1925             :                                 "(i=%d open_disp=%d)\n",
    1926             :                                 __location__, nt_errstr(status),
    1927             :                                 nt_errstr(open_funcs[i].correct_status),
    1928           0 :                                 i, (int)open_funcs[i].open_disp);
    1929           0 :                         return false;
    1930             :                 }
    1931             :                 /* Close and delete the file. */
    1932          72 :                 if (NT_STATUS_IS_OK(status)) {
    1933          36 :                         if (open_funcs[i].create_options != 0) {
    1934             :                                 /* out attrib should be a directory. */
    1935          12 :                                 torture_assert_int_equal(tctx,
    1936             :                                     io.ntcreatex.out.attrib,
    1937             :                                     FILE_ATTRIBUTE_DIRECTORY, "should have "
    1938             :                                     "created a directory");
    1939             : 
    1940          12 :                                 smbcli_close(cli->tree,
    1941          12 :                                     io.ntcreatex.out.file.fnum);
    1942             : 
    1943             :                                 /* Make sure unlink fails. */
    1944          12 :                                 status = smbcli_unlink(cli->tree, fname);
    1945          12 :                                 torture_assert_ntstatus_equal(tctx, status,
    1946             :                                     NT_STATUS_FILE_IS_A_DIRECTORY,
    1947             :                                     "unlink should fail for a directory");
    1948             : 
    1949          12 :                                 status = smbcli_rmdir(cli->tree, fname);
    1950          12 :                                 torture_assert_ntstatus_ok(tctx, status,
    1951             :                                     "rmdir failed");
    1952             :                         } else {
    1953          24 :                                 torture_assert_int_equal(tctx,
    1954             :                                     io.ntcreatex.out.attrib,
    1955             :                                     FILE_ATTRIBUTE_ARCHIVE, "should not have "
    1956             :                                     "created a directory");
    1957             : 
    1958          24 :                                 smbcli_close(cli->tree,
    1959          24 :                                     io.ntcreatex.out.file.fnum);
    1960             : 
    1961             :                                 /* Make sure rmdir fails. */
    1962          24 :                                 status = smbcli_rmdir(cli->tree, fname);
    1963          24 :                                 torture_assert_ntstatus_equal(tctx, status,
    1964             :                                     NT_STATUS_NOT_A_DIRECTORY,
    1965             :                                     "rmdir should fail for a file");
    1966             : 
    1967          24 :                                 status = smbcli_unlink(cli->tree, fname);
    1968          24 :                                 torture_assert_ntstatus_ok(tctx, status,
    1969             :                                     "unlink failed");
    1970             :                         }
    1971             :                 }
    1972             :         }
    1973             : 
    1974             :         /* Create a file. */
    1975           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1976           6 :         io.ntcreatex.in.create_options = 0;
    1977           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1978           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1979           6 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create file.");
    1980           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1981             : 
    1982             :         /* Try and open the file with file_attr_dir and check the error. */
    1983           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1984           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1985             : 
    1986           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1987           6 :         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_DIRECTORY "
    1988             :             "doesn't produce a hard failure.");
    1989           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1990             : 
    1991             :         /* Try and open file with createx_option_dir and check the error. */
    1992           6 :         io.ntcreatex.in.file_attr = 0;
    1993           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1994             : 
    1995           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    1996           6 :         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_A_DIRECTORY,
    1997             :             "NTCREATEX_OPTIONS_DIRECTORY will a file from being opened.");
    1998           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1999             : 
    2000             :         /* Delete the file and move onto directory testing. */
    2001           6 :         smbcli_unlink(cli->tree, fname);
    2002             : 
    2003             :         /* Now try some tests on a directory. */
    2004           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2005           6 :         io.ntcreatex.in.file_attr = 0;
    2006           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    2007           6 :         io.ntcreatex.in.fname = dname;
    2008             : 
    2009           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2010           6 :         torture_assert_ntstatus_ok(tctx, status, "Failed to create dir.");
    2011             : 
    2012             :         /* out attrib should be a directory. */
    2013           6 :         torture_assert_int_equal(tctx, io.ntcreatex.out.attrib,
    2014             :             FILE_ATTRIBUTE_DIRECTORY, "should have created a directory");
    2015             : 
    2016           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2017             : 
    2018             :         /* Try and open it with normal attr and check the error. */
    2019           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2020           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    2021             : 
    2022           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2023           6 :         torture_assert_ntstatus_ok(tctx, status, "FILE_ATTRIBUTE_NORMAL "
    2024             :             "doesn't produce a hard failure.");
    2025           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2026             : 
    2027             :         /* Try and open it with file create_options and check the error. */
    2028           6 :         io.ntcreatex.in.file_attr = 0;
    2029           6 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
    2030             : 
    2031           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2032           6 :         torture_assert_ntstatus_equal(tctx, status,
    2033             :             NT_STATUS_FILE_IS_A_DIRECTORY,
    2034             :             "NTCREATEX_OPTIONS_NON_DIRECTORY_FILE should be returned ");
    2035           6 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    2036             : 
    2037           6 :         smbcli_deltree(cli->tree, BASEDIR);
    2038             : 
    2039           6 :         return true;
    2040             : }
    2041             : 
    2042             : /*
    2043             :   test opening with truncate on an already open file
    2044             :   returns share violation and doesn't truncate the file.
    2045             :   Regression test for bug #10671.
    2046             : */
    2047           6 : static bool test_open_for_truncate(struct torture_context *tctx, struct smbcli_state *cli)
    2048             : {
    2049             :         union smb_open io;
    2050             :         union smb_fileinfo finfo;
    2051           6 :         const char *fname = BASEDIR "\\torture_open_for_truncate.txt";
    2052             :         NTSTATUS status;
    2053           6 :         int fnum = -1;
    2054           6 :         ssize_t val = 0;
    2055           6 :         char c = '\0';
    2056           6 :         bool ret = true;
    2057             : 
    2058           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
    2059             :                 "Failed to setup up test directory: " BASEDIR);
    2060             : 
    2061           6 :         torture_comment(tctx, "Testing open truncate disposition.\n");
    2062             : 
    2063             :         /* reasonable default parameters */
    2064           6 :         ZERO_STRUCT(io);
    2065           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2066           6 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    2067           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    2068           6 :         io.ntcreatex.in.alloc_size = 0;
    2069           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2070           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2071           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2072           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2073           6 :         io.ntcreatex.in.create_options = 0;
    2074           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2075           6 :         io.ntcreatex.in.security_flags = 0;
    2076           6 :         io.ntcreatex.in.fname = fname;
    2077             : 
    2078           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2079           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2080           6 :         fnum = io.ntcreatex.out.file.fnum;
    2081             : 
    2082             :         /* Write a byte at offset 1k-1. */
    2083           6 :         val =smbcli_write(cli->tree, fnum, 0, &c, 1023, 1);
    2084           6 :         torture_assert_int_equal(tctx, val, 1, "write failed\n");
    2085             : 
    2086             :         /* Now try and open for read/write with truncate - should fail. */
    2087           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_WRITE|SEC_RIGHTS_FILE_READ;
    2088           6 :         io.ntcreatex.in.file_attr = 0;
    2089           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    2090             :                         NTCREATEX_SHARE_ACCESS_WRITE |
    2091             :                         NTCREATEX_SHARE_ACCESS_DELETE;
    2092           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
    2093           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2094           6 :         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
    2095             : 
    2096             :         /* Ensure file size is still 1k */
    2097           6 :         finfo.generic.level = RAW_FILEINFO_GETATTRE;
    2098           6 :         finfo.generic.in.file.fnum = fnum;
    2099           6 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    2100           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2101           6 :         CHECK_VAL(finfo.getattre.out.size, 1024);
    2102             : 
    2103           6 :         smbcli_close(cli->tree, fnum);
    2104             : 
    2105           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2106           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2107           6 :         fnum = io.ntcreatex.out.file.fnum;
    2108             : 
    2109             :         /* Ensure truncate actually works */
    2110           6 :         finfo.generic.level = RAW_FILEINFO_GETATTRE;
    2111           6 :         finfo.generic.in.file.fnum = fnum;
    2112           6 :         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
    2113           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2114           6 :         CHECK_VAL(finfo.getattre.out.size, 0);
    2115             : 
    2116           6 :         smbcli_close(cli->tree, fnum);
    2117           6 :         smbcli_unlink(cli->tree, fname);
    2118             : 
    2119           6 : done:
    2120           6 :         smbcli_close(cli->tree, fnum);
    2121           6 :         smbcli_deltree(cli->tree, BASEDIR);
    2122             : 
    2123           6 :         return ret;
    2124             : }
    2125             : 
    2126             : /**
    2127             :  * Test for file size to be 0 after create with FILE_SUPERSEDE
    2128             :  */
    2129           6 : static bool test_ntcreatex_supersede(struct torture_context *tctx, struct smbcli_state *cli)
    2130             : {
    2131             :         union smb_open io;
    2132             :         union smb_setfileinfo sfi;
    2133             :         union smb_fileinfo finfo;
    2134           6 :         const char *fname = BASEDIR "\\torture_ntcreatex_supersede.txt";
    2135             :         NTSTATUS status;
    2136           6 :         int fnum = -1;
    2137           6 :         bool ret = true;
    2138             : 
    2139           6 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
    2140             : 
    2141             :         /* reasonable default parameters */
    2142           6 :         io.generic.level = RAW_OPEN_NTCREATEX;
    2143           6 :         io.ntcreatex.in.flags = 0;
    2144           6 :         io.ntcreatex.in.root_fid.fnum = 0;
    2145           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    2146           6 :         io.ntcreatex.in.alloc_size = 0;
    2147           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2148           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2149           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    2150           6 :         io.ntcreatex.in.create_options = 0;
    2151           6 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    2152           6 :         io.ntcreatex.in.security_flags = 0;
    2153           6 :         io.ntcreatex.in.fname = fname;
    2154             : 
    2155           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2156           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2157           6 :         fnum = io.ntcreatex.out.file.fnum;
    2158             : 
    2159           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2160           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
    2161           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2162           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2163           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    2164           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    2165           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2166           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2167           6 :         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
    2168           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2169           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2170             : 
    2171             :         /* extend the file size */
    2172           6 :         ZERO_STRUCT(sfi);
    2173           6 :         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFO;
    2174           6 :         sfi.generic.in.file.fnum = fnum;
    2175           6 :         sfi.end_of_file_info.in.size = 512;
    2176           6 :         status = smb_raw_setfileinfo(cli->tree, &sfi);
    2177           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2178             : 
    2179             :         /* close the file and re-open with to verify new size */
    2180           6 :         smbcli_close(cli->tree, fnum);
    2181           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    2182           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
    2183           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2184           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2185           6 :         fnum = io.ntcreatex.out.file.fnum;
    2186             : 
    2187           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2188           6 :         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
    2189           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2190           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2191           6 :         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
    2192           6 :         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
    2193           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2194           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2195           6 :         CHECK_VAL(io.ntcreatex.out.size, 512);
    2196           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2197           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2198             : 
    2199             :         /* close and re-open the file with SUPERSEDE flag */
    2200           6 :         smbcli_close(cli->tree, fnum);
    2201           6 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
    2202           6 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ;
    2203           6 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    2204           6 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    2205           6 :         io.ntcreatex.in.create_options = 0;
    2206             : 
    2207           6 :         status = smb_raw_open(cli->tree, tctx, &io);
    2208           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    2209           6 :         fnum = io.ntcreatex.out.file.fnum;
    2210             : 
    2211             :         /* The file size in the superseded create response should be 0 */
    2212           6 :         CHECK_VAL(io.ntcreatex.out.size, 0);
    2213           6 :         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
    2214           6 :         CHECK_VAL(io.ntcreatex.out.create_action, FILE_WAS_SUPERSEDED);
    2215           6 :         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
    2216           6 :         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
    2217           6 :         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
    2218           6 :         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
    2219           6 :         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
    2220           6 :         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
    2221          11 : done:
    2222           6 :         smbcli_close(cli->tree, fnum);
    2223           6 :         smbcli_deltree(cli->tree, BASEDIR);
    2224             : 
    2225           6 :         return ret;
    2226             : }
    2227             : 
    2228             : /* basic testing of all RAW_OPEN_* calls
    2229             : */
    2230        2355 : struct torture_suite *torture_raw_open(TALLOC_CTX *mem_ctx)
    2231             : {
    2232        2355 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "open");
    2233             : 
    2234        2355 :         torture_suite_add_1smb_test(suite, "brlocked", test_ntcreatex_brlocked);
    2235        2355 :         torture_suite_add_1smb_test(suite, "open", test_open);
    2236        2355 :         torture_suite_add_1smb_test(suite, "open-multi", test_raw_open_multi);
    2237        2355 :         torture_suite_add_1smb_test(suite, "openx", test_openx);
    2238        2355 :         torture_suite_add_1smb_test(suite, "ntcreatex", test_ntcreatex);
    2239        2355 :         torture_suite_add_1smb_test(suite, "nttrans-create", test_nttrans_create);
    2240        2355 :         torture_suite_add_1smb_test(suite, "t2open", test_t2open);
    2241        2355 :         torture_suite_add_1smb_test(suite, "mknew", test_mknew);
    2242        2355 :         torture_suite_add_1smb_test(suite, "create", test_create);
    2243        2355 :         torture_suite_add_1smb_test(suite, "ctemp", test_ctemp);
    2244        2355 :         torture_suite_add_1smb_test(suite, "chained-openx", test_chained);
    2245        2355 :         torture_suite_add_1smb_test(suite, "chained-ntcreatex", test_chained_ntcreatex_readx);
    2246        2355 :         torture_suite_add_1smb_test(suite, "no-leading-slash", test_no_leading_slash);
    2247        2355 :         torture_suite_add_1smb_test(suite, "openx-over-dir", test_openx_over_dir);
    2248        2355 :         torture_suite_add_1smb_test(suite, "open-for-delete", test_open_for_delete);
    2249        2355 :         torture_suite_add_1smb_test(suite, "opendisp-dir", test_ntcreatex_opendisp_dir);
    2250        2355 :         torture_suite_add_1smb_test(suite, "ntcreatedir", test_ntcreatexdir);
    2251        2355 :         torture_suite_add_1smb_test(suite, "open-for-truncate", test_open_for_truncate);
    2252        2355 :         torture_suite_add_1smb_test(suite, "ntcreatex_supersede", test_ntcreatex_supersede);
    2253             : 
    2254        2355 :         return suite;
    2255             : }

Generated by: LCOV version 1.13