LCOV - code coverage report
Current view: top level - source4/torture/raw - open.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 1200 1278 93.9 %
Date: 2024-06-13 04:01:37 Functions: 21 22 95.5 %

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

Generated by: LCOV version 1.13