root/source4/torture/raw/open.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_rdwr
  2. rdwr_string
  3. test_open
  4. test_openx
  5. test_t2open
  6. test_ntcreatex
  7. test_nttrans_create
  8. test_ntcreatex_brlocked
  9. test_mknew
  10. test_create
  11. test_ctemp
  12. test_chained
  13. test_no_leading_slash
  14. test_openx_over_dir
  15. test_raw_open_multi
  16. test_open_for_delete
  17. torture_raw_open

   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 "torture/torture.h"
  22 #include "libcli/raw/libcliraw.h"
  23 #include "libcli/raw/raw_proto.h"
  24 #include "system/time.h"
  25 #include "system/filesys.h"
  26 #include "librpc/gen_ndr/security.h"
  27 #include "lib/events/events.h"
  28 #include "libcli/libcli.h"
  29 #include "torture/util.h"
  30 #include "auth/credentials/credentials.h"
  31 #include "lib/cmdline/popt_common.h"
  32 
  33 /* enum for whether reads/writes are possible on a file */
  34 enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
  35 
  36 #define BASEDIR "\\rawopen"
  37 
  38 /*
  39   check if a open file can be read/written
  40 */
  41 static enum rdwr_mode check_rdwr(struct smbcli_tree *tree, int fnum)
     /* [<][>][^][v][top][bottom][index][help] */
  42 {
  43         uint8_t c = 1;
  44         bool can_read  = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
  45         bool can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
  46         if ( can_read &&  can_write) return RDWR_RDWR;
  47         if ( can_read && !can_write) return RDWR_RDONLY;
  48         if (!can_read &&  can_write) return RDWR_WRONLY;
  49         return RDWR_NONE;
  50 }
  51 
  52 /*
  53   describe a RDWR mode as a string
  54 */
  55 static const char *rdwr_string(enum rdwr_mode m)
     /* [<][>][^][v][top][bottom][index][help] */
  56 {
  57         switch (m) {
  58         case RDWR_NONE: return "NONE";
  59         case RDWR_RDONLY: return "RDONLY";
  60         case RDWR_WRONLY: return "WRONLY";
  61         case RDWR_RDWR: return "RDWR";
  62         }
  63         return "-";
  64 }
  65 
  66 #define CHECK_STATUS(status, correct) do { \
  67         if (!NT_STATUS_EQUAL(status, correct)) { \
  68                 printf("(%s) Incorrect status %s - should be %s\n", \
  69                        __location__, nt_errstr(status), nt_errstr(correct)); \
  70                 ret = false; \
  71                 goto done; \
  72         }} while (0)
  73 
  74 #define CREATE_FILE do { \
  75         fnum = create_complex_file(cli, tctx, fname); \
  76         if (fnum == -1) { \
  77                 printf("(%s) Failed to create %s - %s\n", __location__, fname, smbcli_errstr(cli->tree)); \
  78                 ret = false; \
  79                 goto done; \
  80         }} while (0)
  81 
  82 #define CHECK_RDWR(fnum, correct) do { \
  83         enum rdwr_mode m = check_rdwr(cli->tree, fnum); \
  84         if (m != correct) { \
  85                 printf("(%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 (abs(t1-t2) > 2) { \
  99                 printf("(%s) wrong time for field %s  %s - %s\n", \
 100                        __location__, #field, \
 101                        timestring(tctx, t1), \
 102                        timestring(tctx, t2)); \
 103                 dump_all_info(tctx, &finfo); \
 104                 ret = false; \
 105         }} while (0)
 106 
 107 #define CHECK_NTTIME(t, field) do { \
 108         NTTIME t2; \
 109         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
 110         finfo.all_info.in.file.path = fname; \
 111         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
 112         CHECK_STATUS(status, NT_STATUS_OK); \
 113         t2 = finfo.all_info.out.field; \
 114         if (t != t2) { \
 115                 printf("(%s) wrong time for field %s  %s - %s\n", \
 116                        __location__, #field, \
 117                        nt_time_string(tctx, t), \
 118                        nt_time_string(tctx, t2)); \
 119                 dump_all_info(tctx, &finfo); \
 120                 ret = false; \
 121         }} while (0)
 122 
 123 #define CHECK_ALL_INFO(v, field) do { \
 124         finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
 125         finfo.all_info.in.file.path = fname; \
 126         status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
 127         CHECK_STATUS(status, NT_STATUS_OK); \
 128         if ((v) != (finfo.all_info.out.field)) { \
 129                 printf("(%s) wrong value for field %s  0x%x - 0x%x\n", \
 130                        __location__, #field, (int)v, (int)(finfo.all_info.out.field)); \
 131                 dump_all_info(tctx, &finfo); \
 132                 ret = false; \
 133         }} while (0)
 134 
 135 #define CHECK_VAL(v, correct) do { \
 136         if ((v) != (correct)) { \
 137                 printf("(%s) wrong value for %s  0x%x - should be 0x%x\n", \
 138                        __location__, #v, (int)(v), (int)correct); \
 139                 ret = false; \
 140         }} while (0)
 141 
 142 #define SET_ATTRIB(sattrib) do { \
 143         union smb_setfileinfo sfinfo; \
 144         ZERO_STRUCT(sfinfo.basic_info.in); \
 145         sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
 146         sfinfo.basic_info.in.file.path = fname; \
 147         sfinfo.basic_info.in.attrib = sattrib; \
 148         status = smb_raw_setpathinfo(cli->tree, &sfinfo); \
 149         if (!NT_STATUS_IS_OK(status)) { \
 150                 printf("(%s) Failed to set attrib 0x%x on %s\n", \
 151                        __location__, sattrib, fname); \
 152         }} while (0)
 153 
 154 /*
 155   test RAW_OPEN_OPEN
 156 */
 157 static bool test_open(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 158 {
 159         union smb_open io;
 160         union smb_fileinfo finfo;
 161         const char *fname = BASEDIR "\\torture_open.txt";
 162         NTSTATUS status;
 163         int fnum = -1, fnum2;
 164         bool ret = true;
 165 
 166         printf("Checking RAW_OPEN_OPEN\n");
 167 
 168         io.openold.level = RAW_OPEN_OPEN;
 169         io.openold.in.fname = fname;
 170         io.openold.in.open_mode = OPEN_FLAGS_FCB;
 171         io.openold.in.search_attrs = 0;
 172         status = smb_raw_open(cli->tree, tctx, &io);
 173         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
 174         fnum = io.openold.out.file.fnum;
 175 
 176         smbcli_unlink(cli->tree, fname);
 177         CREATE_FILE;
 178         smbcli_close(cli->tree, fnum);
 179 
 180         status = smb_raw_open(cli->tree, tctx, &io);
 181         CHECK_STATUS(status, NT_STATUS_OK);
 182         fnum = io.openold.out.file.fnum;
 183         CHECK_RDWR(fnum, RDWR_RDWR);
 184 
 185         status = smb_raw_open(cli->tree, tctx, &io);
 186         CHECK_STATUS(status, NT_STATUS_OK);
 187         fnum2 = io.openold.out.file.fnum;
 188         CHECK_RDWR(fnum2, RDWR_RDWR);
 189         smbcli_close(cli->tree, fnum2);
 190         smbcli_close(cli->tree, fnum);
 191 
 192         /* check the read/write modes */
 193         io.openold.level = RAW_OPEN_OPEN;
 194         io.openold.in.fname = fname;
 195         io.openold.in.search_attrs = 0;
 196 
 197         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
 198         status = smb_raw_open(cli->tree, tctx, &io);
 199         CHECK_STATUS(status, NT_STATUS_OK);
 200         fnum = io.openold.out.file.fnum;
 201         CHECK_RDWR(fnum, RDWR_RDONLY);
 202         smbcli_close(cli->tree, fnum);
 203 
 204         io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
 205         status = smb_raw_open(cli->tree, tctx, &io);
 206         CHECK_STATUS(status, NT_STATUS_OK);
 207         fnum = io.openold.out.file.fnum;
 208         CHECK_RDWR(fnum, RDWR_WRONLY);
 209         smbcli_close(cli->tree, fnum);
 210 
 211         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
 212         status = smb_raw_open(cli->tree, tctx, &io);
 213         CHECK_STATUS(status, NT_STATUS_OK);
 214         fnum = io.openold.out.file.fnum;
 215         CHECK_RDWR(fnum, RDWR_RDWR);
 216         smbcli_close(cli->tree, fnum);
 217 
 218         /* check the share modes roughly - not a complete matrix */
 219         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
 220         status = smb_raw_open(cli->tree, tctx, &io);
 221         CHECK_STATUS(status, NT_STATUS_OK);
 222         fnum = io.openold.out.file.fnum;
 223         CHECK_RDWR(fnum, RDWR_RDWR);
 224         
 225         if (io.openold.in.open_mode != io.openold.out.rmode) {
 226                 printf("(%s) rmode should equal open_mode - 0x%x 0x%x\n",
 227                        __location__, io.openold.out.rmode, io.openold.in.open_mode);
 228         }
 229 
 230         io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
 231         status = smb_raw_open(cli->tree, tctx, &io);
 232         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
 233 
 234         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
 235         status = smb_raw_open(cli->tree, tctx, &io);
 236         CHECK_STATUS(status, NT_STATUS_OK);
 237         fnum2 = io.openold.out.file.fnum;
 238         CHECK_RDWR(fnum2, RDWR_RDONLY);
 239         smbcli_close(cli->tree, fnum);
 240         smbcli_close(cli->tree, fnum2);
 241 
 242 
 243         /* check the returned write time */
 244         io.openold.level = RAW_OPEN_OPEN;
 245         io.openold.in.fname = fname;
 246         io.openold.in.search_attrs = 0;
 247         io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
 248         status = smb_raw_open(cli->tree, tctx, &io);
 249         CHECK_STATUS(status, NT_STATUS_OK);
 250         fnum = io.openold.out.file.fnum;
 251 
 252         /* check other reply fields */
 253         CHECK_TIME(io.openold.out.write_time, write_time);
 254         CHECK_ALL_INFO(io.openold.out.size, size);
 255         CHECK_ALL_INFO(io.openold.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
 256 
 257 done:
 258         smbcli_close(cli->tree, fnum);
 259         smbcli_unlink(cli->tree, fname);
 260 
 261         return ret;
 262 }
 263 
 264 
 265 /*
 266   test RAW_OPEN_OPENX
 267 */
 268 static bool test_openx(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 269 {
 270         union smb_open io;
 271         union smb_fileinfo finfo;
 272         const char *fname = BASEDIR "\\torture_openx.txt";
 273         const char *fname_exe = BASEDIR "\\torture_openx.exe";
 274         NTSTATUS status;
 275         int fnum = -1, fnum2;
 276         bool ret = true;
 277         int i;
 278         struct timeval tv;
 279         struct {
 280                 uint16_t open_func;
 281                 bool with_file;
 282                 NTSTATUS correct_status;
 283         } open_funcs[] = {
 284                 { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
 285                 { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
 286                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
 287                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
 288                 { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
 289                 { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
 290                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
 291                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
 292                 { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
 293                 { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
 294                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
 295                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
 296         };
 297 
 298         printf("Checking RAW_OPEN_OPENX\n");
 299         smbcli_unlink(cli->tree, fname);
 300 
 301         io.openx.level = RAW_OPEN_OPENX;
 302         io.openx.in.fname = fname;
 303         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
 304         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
 305         io.openx.in.search_attrs = 0;
 306         io.openx.in.file_attrs = 0;
 307         io.openx.in.write_time = 0;
 308         io.openx.in.size = 1024*1024;
 309         io.openx.in.timeout = 0;
 310 
 311         /* check all combinations of open_func */
 312         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
 313                 if (open_funcs[i].with_file) {
 314                         fnum = create_complex_file(cli, tctx, fname);
 315                         if (fnum == -1) {
 316                                 d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
 317                                 ret = false;
 318                                 goto done;
 319                         }
 320                         smbcli_close(cli->tree, fnum);
 321                 }
 322                 io.openx.in.open_func = open_funcs[i].open_func;
 323                 status = smb_raw_open(cli->tree, tctx, &io);
 324                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
 325                         printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_func=0x%x)\n", 
 326                                __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
 327                                i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
 328                         ret = false;
 329                 }
 330                 if (NT_STATUS_IS_OK(status)) {
 331                         smbcli_close(cli->tree, io.openx.out.file.fnum);
 332                 }
 333                 if (open_funcs[i].with_file) {
 334                         smbcli_unlink(cli->tree, fname);
 335                 }
 336         }
 337 
 338         smbcli_unlink(cli->tree, fname);
 339 
 340         /* check the basic return fields */
 341         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
 342         status = smb_raw_open(cli->tree, tctx, &io);
 343         CHECK_STATUS(status, NT_STATUS_OK);
 344         fnum = io.openx.out.file.fnum;
 345 
 346         CHECK_ALL_INFO(io.openx.out.size, size);
 347         CHECK_TIME(io.openx.out.write_time, write_time);
 348         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
 349         CHECK_VAL(io.openx.out.access, OPENX_MODE_ACCESS_RDWR);
 350         CHECK_VAL(io.openx.out.ftype, 0);
 351         CHECK_VAL(io.openx.out.devstate, 0);
 352         CHECK_VAL(io.openx.out.action, OPENX_ACTION_CREATED);
 353         CHECK_VAL(io.openx.out.size, 1024*1024);
 354         CHECK_ALL_INFO(io.openx.in.size, size);
 355         smbcli_close(cli->tree, fnum);
 356         smbcli_unlink(cli->tree, fname);
 357 
 358         /* check the fields when the file already existed */
 359         fnum2 = create_complex_file(cli, tctx, fname);
 360         if (fnum2 == -1) {
 361                 ret = false;
 362                 goto done;
 363         }
 364         smbcli_close(cli->tree, fnum2);
 365 
 366         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
 367         status = smb_raw_open(cli->tree, tctx, &io);
 368         CHECK_STATUS(status, NT_STATUS_OK);
 369         fnum = io.openx.out.file.fnum;
 370 
 371         CHECK_ALL_INFO(io.openx.out.size, size);
 372         CHECK_TIME(io.openx.out.write_time, write_time);
 373         CHECK_VAL(io.openx.out.action, OPENX_ACTION_EXISTED);
 374         CHECK_VAL(io.openx.out.unknown, 0);
 375         CHECK_ALL_INFO(io.openx.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
 376         smbcli_close(cli->tree, fnum);
 377 
 378         /* now check the search attrib for hidden files - win2003 ignores this? */
 379         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
 380         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
 381 
 382         io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
 383         status = smb_raw_open(cli->tree, tctx, &io);
 384         CHECK_STATUS(status, NT_STATUS_OK);
 385         smbcli_close(cli->tree, io.openx.out.file.fnum);
 386 
 387         io.openx.in.search_attrs = 0;
 388         status = smb_raw_open(cli->tree, tctx, &io);
 389         CHECK_STATUS(status, NT_STATUS_OK);
 390         smbcli_close(cli->tree, io.openx.out.file.fnum);
 391 
 392         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
 393         smbcli_unlink(cli->tree, fname);
 394 
 395         /* and check attrib on create */
 396         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
 397         io.openx.in.search_attrs = 0;
 398         io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
 399         status = smb_raw_open(cli->tree, tctx, &io);
 400         CHECK_STATUS(status, NT_STATUS_OK);
 401         if (torture_setting_bool(tctx, "samba3", false)) {
 402                 CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
 403                                attrib & ~(FILE_ATTRIBUTE_NONINDEXED|
 404                                           FILE_ATTRIBUTE_SPARSE));
 405         }
 406         else {
 407                 CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
 408                                attrib & ~(FILE_ATTRIBUTE_NONINDEXED));
 409         }
 410         smbcli_close(cli->tree, io.openx.out.file.fnum);
 411         smbcli_unlink(cli->tree, fname);
 412 
 413         /* check timeout on create - win2003 ignores the timeout! */
 414         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
 415         io.openx.in.file_attrs = 0;
 416         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
 417         status = smb_raw_open(cli->tree, tctx, &io);
 418         CHECK_STATUS(status, NT_STATUS_OK);
 419         fnum = io.openx.out.file.fnum;
 420 
 421         io.openx.in.timeout = 20000;
 422         tv = timeval_current();
 423         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
 424         status = smb_raw_open(cli->tree, tctx, &io);
 425         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
 426         if (timeval_elapsed(&tv) > 3.0) {
 427                 printf("(%s) Incorrect timing in openx with timeout - waited %.2f seconds\n",
 428                        __location__, timeval_elapsed(&tv));
 429                 ret = false;
 430         }
 431         smbcli_close(cli->tree, fnum);
 432         smbcli_unlink(cli->tree, fname);
 433 
 434         /* now this is a really weird one - open for execute implies create?! */
 435         io.openx.in.fname = fname;
 436         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
 437         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
 438         io.openx.in.search_attrs = 0;
 439         io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL;
 440         io.openx.in.file_attrs = 0;
 441         io.openx.in.write_time = 0;
 442         io.openx.in.size = 0;
 443         io.openx.in.timeout = 0;
 444         status = smb_raw_open(cli->tree, tctx, &io);
 445         CHECK_STATUS(status, NT_STATUS_OK);
 446         smbcli_close(cli->tree, io.openx.out.file.fnum);
 447 
 448         /* check the extended return flag */
 449         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
 450         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
 451         status = smb_raw_open(cli->tree, tctx, &io);
 452         CHECK_STATUS(status, NT_STATUS_OK);
 453         CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
 454         smbcli_close(cli->tree, io.openx.out.file.fnum);
 455 
 456         io.openx.in.fname = "\\A.+,;=[].B";
 457         status = smb_raw_open(cli->tree, tctx, &io);
 458         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
 459 
 460         /* Check the mapping for open exec. */
 461 
 462         /* First create an .exe file. */
 463         smbcli_unlink(cli->tree, fname_exe);
 464         fnum = create_complex_file(cli, tctx, fname_exe);
 465         smbcli_close(cli->tree, fnum);
 466 
 467         io.openx.level = RAW_OPEN_OPENX;
 468         io.openx.in.fname = fname_exe;
 469         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
 470         io.openx.in.open_mode = OPENX_MODE_ACCESS_EXEC | OPENX_MODE_DENY_NONE;
 471         io.openx.in.search_attrs = 0;
 472         io.openx.in.file_attrs = 0;
 473         io.openx.in.write_time = 0;
 474         io.openx.in.size = 0;
 475         io.openx.in.timeout = 0;
 476         status = smb_raw_open(cli->tree, tctx, &io);
 477         CHECK_STATUS(status, NT_STATUS_OK);
 478 
 479         /* Can we read and write ? */
 480         CHECK_RDWR(io.openx.out.file.fnum, RDWR_RDONLY);
 481         smbcli_close(cli->tree, io.openx.out.file.fnum);
 482         smbcli_unlink(cli->tree, fname);
 483 
 484 done:
 485         smbcli_close(cli->tree, fnum);
 486         smbcli_unlink(cli->tree, fname_exe);
 487         smbcli_unlink(cli->tree, fname);
 488 
 489         return ret;
 490 }
 491 
 492 
 493 /*
 494   test RAW_OPEN_T2OPEN
 495 
 496   many thanks to kukks for a sniff showing how this works with os2->w2k
 497 */
 498 static bool test_t2open(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 499 {
 500         union smb_open io;
 501         union smb_fileinfo finfo;
 502         const char *fname1 = BASEDIR "\\torture_t2open_yes.txt";
 503         const char *fname2 = BASEDIR "\\torture_t2open_no.txt";
 504         const char *fname = BASEDIR "\\torture_t2open_3.txt";
 505         NTSTATUS status;
 506         int fnum;
 507         bool ret = true;
 508         int i;
 509         struct {
 510                 uint16_t open_func;
 511                 bool with_file;
 512                 NTSTATUS correct_status;
 513         } open_funcs[] = {
 514                 { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
 515                 { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
 516                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
 517                 { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
 518                 { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_OBJECT_NAME_COLLISION },
 519                 { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_OBJECT_NAME_COLLISION },
 520                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
 521                 { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OBJECT_NAME_COLLISION },
 522                 { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
 523                 { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OK },
 524                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
 525                 { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
 526         };
 527 
 528         fnum = create_complex_file(cli, tctx, fname1);
 529         if (fnum == -1) {
 530                 d_printf("Failed to create file %s - %s\n", fname1, smbcli_errstr(cli->tree));
 531                 ret = false;
 532                 goto done;
 533         }
 534         smbcli_close(cli->tree, fnum);
 535 
 536         printf("Checking RAW_OPEN_T2OPEN\n");
 537 
 538         io.t2open.level = RAW_OPEN_T2OPEN;
 539         io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
 540         io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
 541         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
 542         io.t2open.in.search_attrs = 0;
 543         io.t2open.in.file_attrs = 0;
 544         io.t2open.in.write_time = 0;
 545         io.t2open.in.size = 0;
 546         io.t2open.in.timeout = 0;
 547 
 548         io.t2open.in.num_eas = 3;
 549         io.t2open.in.eas = talloc_array(tctx, struct ea_struct, io.t2open.in.num_eas);
 550         io.t2open.in.eas[0].flags = 0;
 551         io.t2open.in.eas[0].name.s = ".CLASSINFO";
 552         io.t2open.in.eas[0].value = data_blob_talloc(tctx, "first value", 11);
 553         io.t2open.in.eas[1].flags = 0;
 554         io.t2open.in.eas[1].name.s = "EA TWO";
 555         io.t2open.in.eas[1].value = data_blob_talloc(tctx, "foo", 3);
 556         io.t2open.in.eas[2].flags = 0;
 557         io.t2open.in.eas[2].name.s = "X THIRD";
 558         io.t2open.in.eas[2].value = data_blob_talloc(tctx, "xy", 2);
 559 
 560         /* check all combinations of open_func */
 561         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
 562         again:
 563                 if (open_funcs[i].with_file) {
 564                         io.t2open.in.fname = fname1;
 565                 } else {
 566                         io.t2open.in.fname = fname2;
 567                 }
 568                 io.t2open.in.open_func = open_funcs[i].open_func;
 569                 status = smb_raw_open(cli->tree, tctx, &io);
 570                 if ((io.t2open.in.num_eas != 0)
 571                     && NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
 572                     && torture_setting_bool(tctx, "samba3", false)) {
 573                         printf("(%s) EAs not supported, not treating as fatal "
 574                                "in Samba3 test\n", __location__);
 575                         io.t2open.in.num_eas = 0;
 576                         goto again;
 577                 }
 578 
 579                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
 580                         printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_func=0x%x)\n", 
 581                                __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
 582                                i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
 583                         ret = false;
 584                 }
 585                 if (NT_STATUS_IS_OK(status)) {
 586                         smbcli_close(cli->tree, io.t2open.out.file.fnum);
 587                 }
 588         }
 589 
 590         smbcli_unlink(cli->tree, fname1);
 591         smbcli_unlink(cli->tree, fname2);
 592 
 593         /* check the basic return fields */
 594         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
 595         io.t2open.in.write_time = 0;
 596         io.t2open.in.fname = fname;
 597         status = smb_raw_open(cli->tree, tctx, &io);
 598         CHECK_STATUS(status, NT_STATUS_OK);
 599         fnum = io.t2open.out.file.fnum;
 600 
 601         CHECK_ALL_INFO(io.t2open.out.size, size);
 602 #if 0
 603         /* windows appears to leak uninitialised memory here */
 604         CHECK_VAL(io.t2open.out.write_time, 0);
 605 #endif
 606         CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
 607         CHECK_VAL(io.t2open.out.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
 608         CHECK_VAL(io.t2open.out.ftype, 0);
 609         CHECK_VAL(io.t2open.out.devstate, 0);
 610         CHECK_VAL(io.t2open.out.action, OPENX_ACTION_CREATED);
 611         smbcli_close(cli->tree, fnum);
 612 
 613         status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
 614         CHECK_STATUS(status, io.t2open.in.num_eas
 615                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
 616         status = torture_check_ea(cli, fname, "EA TWO", "foo");
 617         CHECK_STATUS(status, io.t2open.in.num_eas
 618                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
 619         status = torture_check_ea(cli, fname, "X THIRD", "xy");
 620         CHECK_STATUS(status, io.t2open.in.num_eas
 621                      ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
 622 
 623         /* now check the search attrib for hidden files - win2003 ignores this? */
 624         SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
 625         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
 626 
 627         status = smb_raw_open(cli->tree, tctx, &io);
 628         CHECK_STATUS(status, NT_STATUS_OK);
 629         smbcli_close(cli->tree, io.t2open.out.file.fnum);
 630 
 631         status = smb_raw_open(cli->tree, tctx, &io);
 632         CHECK_STATUS(status, NT_STATUS_OK);
 633         smbcli_close(cli->tree, io.t2open.out.file.fnum);
 634 
 635         SET_ATTRIB(FILE_ATTRIBUTE_NORMAL);
 636         smbcli_unlink(cli->tree, fname);
 637 
 638         /* and check attrib on create */
 639         io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
 640         io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
 641         status = smb_raw_open(cli->tree, tctx, &io);
 642         CHECK_STATUS(status, NT_STATUS_OK);
 643 
 644         /* check timeout on create - win2003 ignores the timeout! */
 645         io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
 646         io.t2open.in.file_attrs = 0;
 647         io.t2open.in.timeout = 20000;
 648         io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
 649         status = smb_raw_open(cli->tree, tctx, &io);
 650         CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
 651 
 652 done:
 653         smbcli_close(cli->tree, fnum);
 654         smbcli_unlink(cli->tree, fname);
 655 
 656         return ret;
 657 }
 658         
 659 
 660 /*
 661   test RAW_OPEN_NTCREATEX
 662 */
 663 static bool test_ntcreatex(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 664 {
 665         union smb_open io;
 666         union smb_fileinfo finfo;
 667         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
 668         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
 669         NTSTATUS status;
 670         int fnum = -1;
 671         bool ret = true;
 672         int i;
 673         struct {
 674                 uint32_t open_disp;
 675                 bool with_file;
 676                 NTSTATUS correct_status;
 677         } open_funcs[] = {
 678                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
 679                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
 680                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
 681                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
 682                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
 683                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
 684                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
 685                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
 686                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
 687                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
 688                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
 689                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
 690                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
 691                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
 692         };
 693 
 694         printf("Checking RAW_OPEN_NTCREATEX\n");
 695 
 696         /* reasonable default parameters */
 697         io.generic.level = RAW_OPEN_NTCREATEX;
 698         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
 699         io.ntcreatex.in.root_fid = 0;
 700         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 701         io.ntcreatex.in.alloc_size = 1024*1024;
 702         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 703         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 704         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 705         io.ntcreatex.in.create_options = 0;
 706         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 707         io.ntcreatex.in.security_flags = 0;
 708         io.ntcreatex.in.fname = fname;
 709 
 710         /* test the open disposition */
 711         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
 712                 if (open_funcs[i].with_file) {
 713                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
 714                         if (fnum == -1) {
 715                                 d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
 716                                 ret = false;
 717                                 goto done;
 718                         }
 719                         smbcli_close(cli->tree, fnum);
 720                 }
 721                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
 722                 status = smb_raw_open(cli->tree, tctx, &io);
 723                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
 724                         printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n", 
 725                                __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
 726                                i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_disp);
 727                         ret = false;
 728                 }
 729                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
 730                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
 731                         smbcli_unlink(cli->tree, fname);
 732                 }
 733         }
 734 
 735         /* basic field testing */
 736         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 737 
 738         status = smb_raw_open(cli->tree, tctx, &io);
 739         CHECK_STATUS(status, NT_STATUS_OK);
 740         fnum = io.ntcreatex.out.file.fnum;
 741 
 742         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
 743         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
 744         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
 745         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
 746         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
 747         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
 748         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
 749         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
 750         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
 751         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
 752         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
 753 
 754         /* check fields when the file already existed */
 755         smbcli_close(cli->tree, fnum);
 756         smbcli_unlink(cli->tree, fname);
 757         fnum = create_complex_file(cli, tctx, fname);
 758         if (fnum == -1) {
 759                 ret = false;
 760                 goto done;
 761         }
 762         smbcli_close(cli->tree, fnum);
 763 
 764         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
 765         status = smb_raw_open(cli->tree, tctx, &io);
 766         CHECK_STATUS(status, NT_STATUS_OK);
 767         fnum = io.ntcreatex.out.file.fnum;
 768 
 769         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
 770         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
 771         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
 772         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
 773         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
 774         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
 775         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
 776         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
 777         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
 778         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
 779         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
 780         smbcli_close(cli->tree, fnum);
 781         smbcli_unlink(cli->tree, fname);
 782 
 783 
 784         /* create a directory */
 785         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 786         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 787         io.ntcreatex.in.alloc_size = 0;
 788         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
 789         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 790         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 791         io.ntcreatex.in.create_options = 0;
 792         io.ntcreatex.in.fname = dname;
 793         fname = dname;
 794 
 795         smbcli_rmdir(cli->tree, fname);
 796         smbcli_unlink(cli->tree, fname);
 797 
 798         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 799         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
 800         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 801         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 802         status = smb_raw_open(cli->tree, tctx, &io);
 803         CHECK_STATUS(status, NT_STATUS_OK);
 804         fnum = io.ntcreatex.out.file.fnum;
 805 
 806         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
 807         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
 808         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
 809         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
 810         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
 811         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
 812         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
 813         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
 814                   FILE_ATTRIBUTE_DIRECTORY);
 815         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
 816         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
 817         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
 818         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
 819         CHECK_VAL(io.ntcreatex.out.size, 0);
 820         CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
 821         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
 822         smbcli_unlink(cli->tree, fname);
 823         
 824 
 825 done:
 826         smbcli_close(cli->tree, fnum);
 827         smbcli_unlink(cli->tree, fname);
 828 
 829         return ret;
 830 }
 831 
 832 
 833 /*
 834   test RAW_OPEN_NTTRANS_CREATE
 835 */
 836 static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 837 {
 838         union smb_open io;
 839         union smb_fileinfo finfo;
 840         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
 841         const char *dname = BASEDIR "\\torture_ntcreatex.dir";
 842         NTSTATUS status;
 843         int fnum = -1;
 844         bool ret = true;
 845         int i;
 846         uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
 847         uint32_t not_a_directory_mask, unexpected_mask;
 848         struct {
 849                 uint32_t open_disp;
 850                 bool with_file;
 851                 NTSTATUS correct_status;
 852         } open_funcs[] = {
 853                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
 854                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
 855                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
 856                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
 857                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
 858                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
 859                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
 860                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
 861                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
 862                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
 863                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
 864                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
 865                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
 866                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
 867         };
 868 
 869         printf("Checking RAW_OPEN_NTTRANS_CREATE\n");
 870 
 871         /* reasonable default parameters */
 872         io.generic.level = RAW_OPEN_NTTRANS_CREATE;
 873         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
 874         io.ntcreatex.in.root_fid = 0;
 875         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 876         io.ntcreatex.in.alloc_size = 1024*1024;
 877         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 878         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 879         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 880         io.ntcreatex.in.create_options = 0;
 881         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 882         io.ntcreatex.in.security_flags = 0;
 883         io.ntcreatex.in.fname = fname;
 884         io.ntcreatex.in.sec_desc = NULL;
 885         io.ntcreatex.in.ea_list = NULL;
 886 
 887         /* test the open disposition */
 888         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
 889                 if (open_funcs[i].with_file) {
 890                         fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
 891                         if (fnum == -1) {
 892                                 d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
 893                                 ret = false;
 894                                 goto done;
 895                         }
 896                         smbcli_close(cli->tree, fnum);
 897                 }
 898                 io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
 899                 status = smb_raw_open(cli->tree, tctx, &io);
 900                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
 901                         printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n", 
 902                                __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
 903                                i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_disp);
 904                         ret = false;
 905                 }
 906                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
 907                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
 908                         smbcli_unlink(cli->tree, fname);
 909                 }
 910         }
 911 
 912         /* basic field testing */
 913         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 914 
 915         status = smb_raw_open(cli->tree, tctx, &io);
 916         CHECK_STATUS(status, NT_STATUS_OK);
 917         fnum = io.ntcreatex.out.file.fnum;
 918 
 919         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
 920         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
 921         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
 922         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
 923         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
 924         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
 925         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
 926         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
 927         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
 928         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
 929         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
 930 
 931         /* check fields when the file already existed */
 932         smbcli_close(cli->tree, fnum);
 933         smbcli_unlink(cli->tree, fname);
 934         fnum = create_complex_file(cli, tctx, fname);
 935         if (fnum == -1) {
 936                 ret = false;
 937                 goto done;
 938         }
 939         smbcli_close(cli->tree, fnum);
 940 
 941         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
 942         status = smb_raw_open(cli->tree, tctx, &io);
 943         CHECK_STATUS(status, NT_STATUS_OK);
 944         fnum = io.ntcreatex.out.file.fnum;
 945 
 946         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
 947         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
 948         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
 949         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
 950         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
 951         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
 952         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
 953         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
 954         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
 955         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
 956         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
 957         smbcli_close(cli->tree, fnum);
 958 
 959         /* check no-recall - don't pull a file from tape on a HSM */
 960         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
 961         status = smb_raw_open(cli->tree, tctx, &io);
 962         CHECK_STATUS(status, NT_STATUS_OK);
 963         fnum = io.ntcreatex.out.file.fnum;
 964 
 965         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
 966         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
 967         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
 968         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
 969         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
 970         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
 971         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
 972         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
 973         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
 974         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
 975         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
 976         smbcli_close(cli->tree, fnum);
 977 
 978         /* Check some create options (these all should be ignored) */
 979         for (i=0; i < 32; i++) {
 980                 uint32_t create_option = (1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
 981                 if (create_option == 0) {
 982                         continue;
 983                 }
 984                 io.ntcreatex.in.create_options = create_option;
 985                 status = smb_raw_open(cli->tree, tctx, &io);
 986                 if (!NT_STATUS_IS_OK(status)) {
 987                         printf("ntcreatex create option 0x%08x gave %s - should give NT_STATUS_OK\n",
 988                                create_option, nt_errstr(status));
 989                 }
 990                 CHECK_STATUS(status, NT_STATUS_OK);
 991                 fnum = io.ntcreatex.out.file.fnum;
 992 
 993                 CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
 994                 CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
 995                 CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
 996                 CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
 997                 CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
 998                 CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
 999                 CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1000                 CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1001                 CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1002                 CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1003                 CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1004                 smbcli_close(cli->tree, fnum);
1005         }
1006 
1007         io.ntcreatex.in.file_attr = 0;
1008         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1009         io.ntcreatex.in.access_mask     = SEC_FLAG_MAXIMUM_ALLOWED;
1010 
1011         /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
1012         ok_mask = 0;
1013         not_supported_mask = 0;
1014         invalid_parameter_mask = 0;
1015         not_a_directory_mask = 0;
1016         unexpected_mask = 0;
1017         for (i=0; i < 32; i++) {
1018                 uint32_t create_option = 1<<i;
1019                 if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
1020                         continue;
1021                 }
1022                 io.ntcreatex.in.create_options = create_option;
1023                 status = smb_raw_open(cli->tree, tctx, &io);
1024                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1025                         not_supported_mask |= create_option;
1026                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
1027                         ok_mask |= create_option;
1028                         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1029                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
1030                         invalid_parameter_mask |= create_option;
1031                 } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1032                         not_a_directory_mask |= 1<<i;
1033                 } else {
1034                         unexpected_mask |= 1<<i;
1035                         printf("create option 0x%08x returned %s\n", create_option, nt_errstr(status));
1036                 }
1037         }
1038 
1039         CHECK_VAL(ok_mask,                0x00efcfce);
1040         CHECK_VAL(not_a_directory_mask,   0x00000001);
1041         CHECK_VAL(not_supported_mask,     0x00002000);
1042         CHECK_VAL(invalid_parameter_mask, 0xff100030);
1043         CHECK_VAL(unexpected_mask,        0x00000000);
1044 
1045         smbcli_unlink(cli->tree, fname);
1046 
1047 
1048         /* create a directory */
1049         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1050         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1051         io.ntcreatex.in.alloc_size = 0;
1052         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1053         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1054         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1055         io.ntcreatex.in.create_options = 0;
1056         io.ntcreatex.in.fname = dname;
1057         fname = dname;
1058 
1059         smbcli_rmdir(cli->tree, fname);
1060         smbcli_unlink(cli->tree, fname);
1061 
1062         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1063         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1064         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1065         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
1066         status = smb_raw_open(cli->tree, tctx, &io);
1067         CHECK_STATUS(status, NT_STATUS_OK);
1068         fnum = io.ntcreatex.out.file.fnum;
1069 
1070         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1071         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1072         CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
1073         CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
1074         CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
1075         CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
1076         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1077         CHECK_VAL(io.ntcreatex.out.attrib & ~FILE_ATTRIBUTE_NONINDEXED, 
1078                   FILE_ATTRIBUTE_DIRECTORY);
1079         CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
1080         CHECK_ALL_INFO(io.ntcreatex.out.size, size);
1081         CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
1082         CHECK_VAL(io.ntcreatex.out.is_directory, 1);
1083         CHECK_VAL(io.ntcreatex.out.size, 0);
1084         CHECK_VAL(io.ntcreatex.out.alloc_size, 0);
1085         CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
1086         smbcli_unlink(cli->tree, fname);
1087         
1088 
1089 done:
1090         smbcli_close(cli->tree, fnum);
1091         smbcli_unlink(cli->tree, fname);
1092 
1093         return ret;
1094 }
1095 
1096 /*
1097   test RAW_OPEN_NTCREATEX with an already opened and byte range locked file
1098 
1099   I've got an application that does a similar sequence of ntcreate&x,
1100   locking&x and another ntcreate&x with
1101   open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
1102   second open.
1103 */
1104 static bool test_ntcreatex_brlocked(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1105 {
1106         union smb_open io, io1;
1107         union smb_lock io2;
1108         struct smb_lock_entry lock[1];
1109         const char *fname = BASEDIR "\\torture_ntcreatex.txt";
1110         NTSTATUS status;
1111         bool ret = true;
1112 
1113         printf("Testing ntcreatex with a byte range locked file\n");
1114 
1115         io.generic.level = RAW_OPEN_NTCREATEX;
1116         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1117         io.ntcreatex.in.root_fid = 0;
1118         io.ntcreatex.in.access_mask = 0x2019f;
1119         io.ntcreatex.in.alloc_size = 0;
1120         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1121         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1122                 NTCREATEX_SHARE_ACCESS_WRITE;
1123         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1124         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
1125         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1126         io.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1127                 NTCREATEX_SECURITY_ALL;
1128         io.ntcreatex.in.fname = fname;
1129 
1130         status = smb_raw_open(cli->tree, tctx, &io);
1131         CHECK_STATUS(status, NT_STATUS_OK);
1132 
1133         io2.lockx.level = RAW_LOCK_LOCKX;
1134         io2.lockx.in.file.fnum = io.ntcreatex.out.file.fnum;
1135         io2.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
1136         io2.lockx.in.timeout = 0;
1137         io2.lockx.in.ulock_cnt = 0;
1138         io2.lockx.in.lock_cnt = 1;
1139         lock[0].pid = cli->session->pid;
1140         lock[0].offset = 0;
1141         lock[0].count = 0x1;
1142         io2.lockx.in.locks = &lock[0];
1143         status = smb_raw_lock(cli->tree, &io2);
1144         CHECK_STATUS(status, NT_STATUS_OK);
1145 
1146         io1.generic.level = RAW_OPEN_NTCREATEX;
1147         io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1148         io1.ntcreatex.in.root_fid = 0;
1149         io1.ntcreatex.in.access_mask = 0x20196;
1150         io1.ntcreatex.in.alloc_size = 0;
1151         io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1152         io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
1153                 NTCREATEX_SHARE_ACCESS_WRITE;
1154         io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1155         io1.ntcreatex.in.create_options = 0;
1156         io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
1157         io1.ntcreatex.in.security_flags = NTCREATEX_SECURITY_DYNAMIC |
1158                 NTCREATEX_SECURITY_ALL;
1159         io1.ntcreatex.in.fname = fname;
1160 
1161         status = smb_raw_open(cli->tree, tctx, &io1);
1162         CHECK_STATUS(status, NT_STATUS_OK);
1163 
1164  done:
1165         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1166         smbcli_close(cli->tree, io1.ntcreatex.out.file.fnum);
1167         smbcli_unlink(cli->tree, fname);
1168         return ret;
1169 }
1170 
1171 /*
1172   test RAW_OPEN_MKNEW
1173 */
1174 static bool test_mknew(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1175 {
1176         union smb_open io;
1177         const char *fname = BASEDIR "\\torture_mknew.txt";
1178         NTSTATUS status;
1179         int fnum = -1;
1180         bool ret = true;
1181         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1182         union smb_fileinfo finfo;
1183 
1184         printf("Checking RAW_OPEN_MKNEW\n");
1185 
1186         io.mknew.level = RAW_OPEN_MKNEW;
1187         io.mknew.in.attrib = 0;
1188         io.mknew.in.write_time = 0;
1189         io.mknew.in.fname = fname;
1190         status = smb_raw_open(cli->tree, tctx, &io);
1191         CHECK_STATUS(status, NT_STATUS_OK);
1192         fnum = io.mknew.out.file.fnum;
1193 
1194         status = smb_raw_open(cli->tree, tctx, &io);
1195         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
1196 
1197         smbcli_close(cli->tree, fnum);
1198         smbcli_unlink(cli->tree, fname);
1199 
1200         /* make sure write_time works */
1201         io.mknew.in.write_time = basetime;
1202         status = smb_raw_open(cli->tree, tctx, &io);
1203         CHECK_STATUS(status, NT_STATUS_OK);
1204         fnum = io.mknew.out.file.fnum;
1205         CHECK_TIME(basetime, write_time);
1206 
1207         smbcli_close(cli->tree, fnum);
1208         smbcli_unlink(cli->tree, fname);
1209 
1210         /* make sure file_attrs works */
1211         io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1212         status = smb_raw_open(cli->tree, tctx, &io);
1213         CHECK_STATUS(status, NT_STATUS_OK);
1214         fnum = io.mknew.out.file.fnum;
1215         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
1216                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1217         
1218 done:
1219         smbcli_close(cli->tree, fnum);
1220         smbcli_unlink(cli->tree, fname);
1221 
1222         return ret;
1223 }
1224 
1225 
1226 /*
1227   test RAW_OPEN_CREATE
1228 */
1229 static bool test_create(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1230 {
1231         union smb_open io;
1232         const char *fname = BASEDIR "\\torture_create.txt";
1233         NTSTATUS status;
1234         int fnum = -1;
1235         bool ret = true;
1236         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1237         union smb_fileinfo finfo;
1238 
1239         printf("Checking RAW_OPEN_CREATE\n");
1240 
1241         io.create.level = RAW_OPEN_CREATE;
1242         io.create.in.attrib = 0;
1243         io.create.in.write_time = 0;
1244         io.create.in.fname = fname;
1245         status = smb_raw_open(cli->tree, tctx, &io);
1246         CHECK_STATUS(status, NT_STATUS_OK);
1247         fnum = io.create.out.file.fnum;
1248 
1249         status = smb_raw_open(cli->tree, tctx, &io);
1250         CHECK_STATUS(status, NT_STATUS_OK);
1251 
1252         smbcli_close(cli->tree, io.create.out.file.fnum);
1253         smbcli_close(cli->tree, fnum);
1254         smbcli_unlink(cli->tree, fname);
1255 
1256         /* make sure write_time works */
1257         io.create.in.write_time = basetime;
1258         status = smb_raw_open(cli->tree, tctx, &io);
1259         CHECK_STATUS(status, NT_STATUS_OK);
1260         fnum = io.create.out.file.fnum;
1261         CHECK_TIME(basetime, write_time);
1262 
1263         smbcli_close(cli->tree, fnum);
1264         smbcli_unlink(cli->tree, fname);
1265 
1266         /* make sure file_attrs works */
1267         io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1268         status = smb_raw_open(cli->tree, tctx, &io);
1269         CHECK_STATUS(status, NT_STATUS_OK);
1270         fnum = io.create.out.file.fnum;
1271         CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
1272                        attrib & ~FILE_ATTRIBUTE_NONINDEXED);
1273         
1274 done:
1275         smbcli_close(cli->tree, fnum);
1276         smbcli_unlink(cli->tree, fname);
1277 
1278         return ret;
1279 }
1280 
1281 
1282 /*
1283   test RAW_OPEN_CTEMP
1284 */
1285 static bool test_ctemp(struct smbcli_state *cli, TALLOC_CTX *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1286 {
1287         union smb_open io;
1288         NTSTATUS status;
1289         int fnum = -1;
1290         bool ret = true;
1291         time_t basetime = (time(NULL) + 3600*24*3) & ~1;
1292         union smb_fileinfo finfo;
1293         const char *name, *fname = NULL;
1294 
1295         printf("Checking RAW_OPEN_CTEMP\n");
1296 
1297         io.ctemp.level = RAW_OPEN_CTEMP;
1298         io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
1299         io.ctemp.in.write_time = basetime;
1300         io.ctemp.in.directory = BASEDIR;
1301         status = smb_raw_open(cli->tree, tctx, &io);
1302         CHECK_STATUS(status, NT_STATUS_OK);
1303         fnum = io.ctemp.out.file.fnum;
1304 
1305         name = io.ctemp.out.name;
1306 
1307         finfo.generic.level = RAW_FILEINFO_NAME_INFO;
1308         finfo.generic.in.file.fnum = fnum;
1309         status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
1310         CHECK_STATUS(status, NT_STATUS_OK);
1311 
1312         fname = finfo.name_info.out.fname.s;
1313         d_printf("ctemp name=%s  real name=%s\n", name, fname);
1314 
1315 done:
1316         smbcli_close(cli->tree, fnum);
1317         if (fname) {
1318                 smbcli_unlink(cli->tree, fname);
1319         }
1320 
1321         return ret;
1322 }
1323 
1324 
1325 /*
1326   test chained RAW_OPEN_OPENX_READX
1327 */
1328 static bool test_chained(struct smbcli_state *cli, TALLOC_CTX *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1329 {
1330         union smb_open io;
1331         const char *fname = BASEDIR "\\torture_chained.txt";
1332         NTSTATUS status;
1333         int fnum = -1;
1334         bool ret = true;
1335         const char *buf = "test";
1336         char buf2[4];
1337 
1338         printf("Checking RAW_OPEN_OPENX chained with READX\n");
1339         smbcli_unlink(cli->tree, fname);
1340 
1341         fnum = create_complex_file(cli, tctx, fname);
1342 
1343         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1344 
1345         smbcli_close(cli->tree, fnum);  
1346 
1347         io.openxreadx.level = RAW_OPEN_OPENX_READX;
1348         io.openxreadx.in.fname = fname;
1349         io.openxreadx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1350         io.openxreadx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1351         io.openxreadx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1352         io.openxreadx.in.search_attrs = 0;
1353         io.openxreadx.in.file_attrs = 0;
1354         io.openxreadx.in.write_time = 0;
1355         io.openxreadx.in.size = 1024*1024;
1356         io.openxreadx.in.timeout = 0;
1357         
1358         io.openxreadx.in.offset = 0;
1359         io.openxreadx.in.mincnt = sizeof(buf);
1360         io.openxreadx.in.maxcnt = sizeof(buf);
1361         io.openxreadx.in.remaining = 0;
1362         io.openxreadx.out.data = (uint8_t *)buf2;
1363 
1364         status = smb_raw_open(cli->tree, tctx, &io);
1365         CHECK_STATUS(status, NT_STATUS_OK);
1366         fnum = io.openxreadx.out.file.fnum;
1367 
1368         if (memcmp(buf, buf2, sizeof(buf)) != 0) {
1369                 d_printf("wrong data in reply buffer\n");
1370                 ret = false;
1371         }
1372 
1373 done:
1374         smbcli_close(cli->tree, fnum);
1375         smbcli_unlink(cli->tree, fname);
1376 
1377         return ret;
1378 }
1379 
1380 /*
1381   test RAW_OPEN_OPENX without a leading slash on the path.
1382   NetApp filers are known to fail on this.
1383   
1384 */
1385 static bool test_no_leading_slash(struct smbcli_state *cli, TALLOC_CTX *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1386 {
1387         union smb_open io;
1388         const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
1389         NTSTATUS status;
1390         int fnum = -1;
1391         bool ret = true;
1392         const char *buf = "test";
1393 
1394         printf("Checking RAW_OPEN_OPENX without leading slash on path\n");
1395         smbcli_unlink(cli->tree, fname);
1396 
1397         /* Create the file */
1398         fnum = create_complex_file(cli, tctx, fname);
1399         smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
1400         smbcli_close(cli->tree, fnum);  
1401 
1402         /* Prepare to open the file using path without leading slash */
1403         io.openx.level = RAW_OPEN_OPENX;
1404         io.openx.in.fname = fname + 1;
1405         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1406         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1407         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1408         io.openx.in.search_attrs = 0;
1409         io.openx.in.file_attrs = 0;
1410         io.openx.in.write_time = 0;
1411         io.openx.in.size = 1024*1024;
1412         io.openx.in.timeout = 0;
1413 
1414         status = smb_raw_open(cli->tree, tctx, &io);
1415         CHECK_STATUS(status, NT_STATUS_OK);
1416         fnum = io.openx.out.file.fnum;
1417 
1418 done:
1419         smbcli_close(cli->tree, fnum);
1420         smbcli_unlink(cli->tree, fname);
1421 
1422         return ret;
1423 }
1424 
1425 /*
1426   test RAW_OPEN_OPENX against an existing directory to
1427   ensure it returns NT_STATUS_FILE_IS_A_DIRECTORY.
1428   Samba 3.2.0 - 3.2.6 are known to fail this.
1429   
1430 */
1431 static bool test_openx_over_dir(struct smbcli_state *cli, TALLOC_CTX *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1432 {
1433         union smb_open io;
1434         const char *fname = BASEDIR "\\openx_over_dir";
1435         NTSTATUS status;
1436         int d_fnum = -1;
1437         int fnum = -1;
1438         bool ret = true;
1439 
1440         printf("Checking RAW_OPEN_OPENX over an existing directory\n");
1441         smbcli_unlink(cli->tree, fname);
1442 
1443         /* Create the Directory */
1444         status = create_directory_handle(cli->tree, fname, &d_fnum);
1445         smbcli_close(cli->tree, d_fnum);        
1446 
1447         /* Prepare to open the file over the directory. */
1448         io.openx.level = RAW_OPEN_OPENX;
1449         io.openx.in.fname = fname;
1450         io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
1451         io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
1452         io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
1453         io.openx.in.search_attrs = 0;
1454         io.openx.in.file_attrs = 0;
1455         io.openx.in.write_time = 0;
1456         io.openx.in.size = 1024*1024;
1457         io.openx.in.timeout = 0;
1458 
1459         status = smb_raw_open(cli->tree, tctx, &io);
1460         CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
1461         fnum = io.openx.out.file.fnum;
1462 
1463 done:
1464         smbcli_close(cli->tree, fnum);
1465         smbcli_unlink(cli->tree, fname);
1466 
1467         return ret;
1468 }
1469 
1470 
1471 /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
1472 
1473 static bool test_raw_open_multi(struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1474 {
1475         struct smbcli_state *cli;
1476         TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
1477         const char *fname = "\\test_oplock.dat";
1478         NTSTATUS status;
1479         bool ret = true;
1480         union smb_open io;
1481         struct smbcli_state **clients;
1482         struct smbcli_request **requests;
1483         union smb_open *ios;
1484         const char *host = torture_setting_string(tctx, "host", NULL);
1485         const char *share = torture_setting_string(tctx, "share", NULL);
1486         int i, num_files = 3;
1487         int num_ok = 0;
1488         int num_collision = 0;
1489         
1490         clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
1491         requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
1492         ios = talloc_array(mem_ctx, union smb_open, num_files);
1493         if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
1494             (ios == NULL)) {
1495                 DEBUG(0, ("talloc failed\n"));
1496                 return false;
1497         }
1498 
1499         if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
1500                 return false;
1501         }
1502 
1503         cli->tree->session->transport->options.request_timeout = 60;
1504 
1505         for (i=0; i<num_files; i++) {
1506                 if (!torture_open_connection_share(mem_ctx, &(clients[i]),
1507                                                    tctx, host, share, tctx->ev)) {
1508                         DEBUG(0, ("Could not open %d'th connection\n", i));
1509                         return false;
1510                 }
1511                 clients[i]->tree->session->transport->options.request_timeout = 60;
1512         }
1513 
1514         /* cleanup */
1515         smbcli_unlink(cli->tree, fname);
1516 
1517         /*
1518           base ntcreatex parms
1519         */
1520         io.generic.level = RAW_OPEN_NTCREATEX;
1521         io.ntcreatex.in.root_fid = 0;
1522         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1523         io.ntcreatex.in.alloc_size = 0;
1524         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1525         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1526                 NTCREATEX_SHARE_ACCESS_WRITE|
1527                 NTCREATEX_SHARE_ACCESS_DELETE;
1528         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1529         io.ntcreatex.in.create_options = 0;
1530         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1531         io.ntcreatex.in.security_flags = 0;
1532         io.ntcreatex.in.fname = fname;
1533         io.ntcreatex.in.flags = 0;
1534 
1535         for (i=0; i<num_files; i++) {
1536                 ios[i] = io;
1537                 requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
1538                 if (requests[i] == NULL) {
1539                         DEBUG(0, ("could not send %d'th request\n", i));
1540                         return false;
1541                 }
1542         }
1543 
1544         DEBUG(10, ("waiting for replies\n"));
1545         while (1) {
1546                 bool unreplied = false;
1547                 for (i=0; i<num_files; i++) {
1548                         if (requests[i] == NULL) {
1549                                 continue;
1550                         }
1551                         if (requests[i]->state < SMBCLI_REQUEST_DONE) {
1552                                 unreplied = true;
1553                                 break;
1554                         }
1555                         status = smb_raw_open_recv(requests[i], mem_ctx,
1556                                                    &ios[i]);
1557 
1558                         DEBUG(0, ("File %d returned status %s\n", i,
1559                                   nt_errstr(status)));
1560 
1561                         if (NT_STATUS_IS_OK(status)) {
1562                                 num_ok += 1;
1563                         } 
1564 
1565                         if (NT_STATUS_EQUAL(status,
1566                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
1567                                 num_collision += 1;
1568                         }
1569 
1570                         requests[i] = NULL;
1571                 }
1572                 if (!unreplied) {
1573                         break;
1574                 }
1575 
1576                 if (event_loop_once(tctx->ev) != 0) {
1577                         DEBUG(0, ("event_loop_once failed\n"));
1578                         return false;
1579                 }
1580         }
1581 
1582         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
1583                 ret = false;
1584         }
1585 
1586         for (i=0; i<num_files; i++) {
1587                 torture_close_connection(clients[i]);
1588         }
1589         talloc_free(mem_ctx);
1590         return ret;
1591 }
1592 
1593 /*
1594   test opening for delete on a read-only attribute file.
1595 */
1596 static bool test_open_for_delete(struct smbcli_state *cli, struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
1597 {
1598         union smb_open io;
1599         union smb_fileinfo finfo;
1600         const char *fname = BASEDIR "\\torture_open_for_delete.txt";
1601         NTSTATUS status;
1602         int fnum = -1;
1603         bool ret = true;
1604 
1605         printf("Checking RAW_NTCREATEX for delete on a readonly file.\n");
1606 
1607         /* reasonable default parameters */
1608         io.generic.level = RAW_OPEN_NTCREATEX;
1609         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1610         io.ntcreatex.in.root_fid = 0;
1611         io.ntcreatex.in.alloc_size = 0;
1612         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1613         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
1614         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1615         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1616         io.ntcreatex.in.create_options = 0;
1617         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1618         io.ntcreatex.in.security_flags = 0;
1619         io.ntcreatex.in.fname = fname;
1620 
1621         /* Create the readonly file. */
1622 
1623         status = smb_raw_open(cli->tree, tctx, &io);
1624         CHECK_STATUS(status, NT_STATUS_OK);
1625         fnum = io.ntcreatex.out.file.fnum;
1626 
1627         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1628         io.ntcreatex.in.create_options = 0;
1629         CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
1630         CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
1631         smbcli_close(cli->tree, fnum);
1632 
1633         /* Now try and open for delete only - should succeed. */
1634         io.ntcreatex.in.access_mask = SEC_STD_DELETE;
1635         io.ntcreatex.in.file_attr = 0;
1636         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
1637         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1638         status = smb_raw_open(cli->tree, tctx, &io);
1639         CHECK_STATUS(status, NT_STATUS_OK);
1640 
1641         smbcli_unlink(cli->tree, fname);
1642 
1643 done:
1644         smbcli_close(cli->tree, fnum);
1645         smbcli_unlink(cli->tree, fname);
1646 
1647         return ret;
1648 }
1649 
1650 
1651 /* basic testing of all RAW_OPEN_* calls 
1652 */
1653 bool torture_raw_open(struct torture_context *torture, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
1654 {
1655         bool ret = true;
1656 
1657         if (!torture_setup_dir(cli, BASEDIR)) {
1658                 return false;
1659         }
1660 
1661         ret &= test_ntcreatex_brlocked(cli, torture);
1662         ret &= test_open(cli, torture);
1663         ret &= test_raw_open_multi(torture);
1664         ret &= test_openx(cli, torture);
1665         ret &= test_ntcreatex(cli, torture);
1666         ret &= test_nttrans_create(cli, torture);
1667         ret &= test_t2open(cli, torture);
1668         ret &= test_mknew(cli, torture);
1669         ret &= test_create(cli, torture);
1670         ret &= test_ctemp(cli, torture);
1671         ret &= test_chained(cli, torture);
1672         ret &= test_no_leading_slash(cli, torture);
1673         ret &= test_openx_over_dir(cli, torture);
1674         ret &= test_open_for_delete(cli, torture);
1675 
1676         smb_raw_exit(cli->session);
1677         smbcli_deltree(cli->tree, BASEDIR);
1678 
1679         return ret;
1680 }

/* [<][>][^][v][top][bottom][index][help] */