LCOV - code coverage report
Current view: top level - source4/torture/smb2 - create.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 1269 1337 94.9 %
Date: 2021-08-25 13:27:56 Functions: 23 23 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    SMB2 create test suite
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2008
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/smb2/smb2.h"
      24             : #include "libcli/smb2/smb2_calls.h"
      25             : #include "torture/torture.h"
      26             : #include "torture/util.h"
      27             : #include "torture/smb2/proto.h"
      28             : #include "librpc/gen_ndr/ndr_security.h"
      29             : #include "libcli/security/security.h"
      30             : 
      31             : #include "system/filesys.h"
      32             : #include "auth/credentials/credentials.h"
      33             : #include "lib/cmdline/cmdline.h"
      34             : #include "librpc/gen_ndr/security.h"
      35             : #include "lib/events/events.h"
      36             : 
      37             : #define FNAME "test_create.dat"
      38             : #define DNAME "smb2_open"
      39             : 
      40             : #define CHECK_STATUS(status, correct) do { \
      41             :         if (!NT_STATUS_EQUAL(status, correct)) { \
      42             :                 torture_result(tctx, TORTURE_FAIL, \
      43             :                         "(%s) Incorrect status %s - should be %s\n", \
      44             :                          __location__, nt_errstr(status), nt_errstr(correct)); \
      45             :                 return false; \
      46             :         }} while (0)
      47             : 
      48             : #define CHECK_EQUAL(v, correct) do { \
      49             :         if (v != correct) { \
      50             :                 torture_result(tctx, TORTURE_FAIL, \
      51             :                         "(%s) Incorrect value for %s 0x%08llx - " \
      52             :                         "should be 0x%08llx\n", \
      53             :                          __location__, #v, \
      54             :                         (unsigned long long)v, \
      55             :                         (unsigned long long)correct); \
      56             :                 return false;                                   \
      57             :         }} while (0)
      58             : 
      59             : #define CHECK_TIME(t, field) do { \
      60             :         time_t t1, t2; \
      61             :         finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
      62             :         finfo.all_info.in.file.handle = h1; \
      63             :         status = smb2_getinfo_file(tree, tctx, &finfo); \
      64             :         CHECK_STATUS(status, NT_STATUS_OK); \
      65             :         t1 = t & ~1; \
      66             :         t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
      67             :         if (abs(t1-t2) > 2) { \
      68             :                 torture_result(tctx, TORTURE_FAIL, \
      69             :                         "(%s) wrong time for field %s  %s - %s\n", \
      70             :                         __location__, #field, \
      71             :                         timestring(tctx, t1), \
      72             :                         timestring(tctx, t2)); \
      73             :                 dump_all_info(tctx, &finfo); \
      74             :                 ret = false; \
      75             :         }} while (0)
      76             : 
      77             : #define CHECK_NTTIME(t, field) do { \
      78             :         NTTIME t2; \
      79             :         finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
      80             :         finfo.all_info.in.file.handle = h1; \
      81             :         status = smb2_getinfo_file(tree, tctx, &finfo); \
      82             :         CHECK_STATUS(status, NT_STATUS_OK); \
      83             :         t2 = finfo.all_info.out.field; \
      84             :         if (llabs((int64_t)(t-t2)) > 20000) { \
      85             :                 torture_result(tctx, TORTURE_FAIL, \
      86             :                         "(%s) wrong time for field %s  %s - %s\n", \
      87             :                        __location__, #field, \
      88             :                        nt_time_string(tctx, t), \
      89             :                        nt_time_string(tctx, t2)); \
      90             :                 dump_all_info(tctx, &finfo); \
      91             :                 ret = false; \
      92             :         }} while (0)
      93             : 
      94             : #define CHECK_ALL_INFO(v, field) do { \
      95             :         finfo.all_info.level = RAW_FILEINFO_ALL_INFORMATION; \
      96             :         finfo.all_info.in.file.handle = h1; \
      97             :         status = smb2_getinfo_file(tree, tctx, &finfo); \
      98             :         CHECK_STATUS(status, NT_STATUS_OK); \
      99             :         if ((v) != (finfo.all_info.out.field)) { \
     100             :                torture_result(tctx, TORTURE_FAIL, \
     101             :                         "(%s) wrong value for field %s  0x%x - 0x%x\n", \
     102             :                         __location__, #field, (int)v,\
     103             :                         (int)(finfo.all_info.out.field)); \
     104             :                 dump_all_info(tctx, &finfo); \
     105             :                 ret = false; \
     106             :         }} while (0)
     107             : 
     108             : #define CHECK_VAL(v, correct) do { \
     109             :         if ((v) != (correct)) { \
     110             :                 torture_result(tctx, TORTURE_FAIL, \
     111             :                         "(%s) wrong value for %s  0x%x - should be 0x%x\n", \
     112             :                        __location__, #v, (int)(v), (int)correct); \
     113             :                 ret = false; \
     114             :         }} while (0)
     115             : 
     116             : #define SET_ATTRIB(sattrib) do { \
     117             :         union smb_setfileinfo sfinfo; \
     118             :         ZERO_STRUCT(sfinfo.basic_info.in); \
     119             :         sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION; \
     120             :         sfinfo.basic_info.in.file.handle = h1; \
     121             :         sfinfo.basic_info.in.attrib = sattrib; \
     122             :         status = smb2_setinfo_file(tree, &sfinfo); \
     123             :         if (!NT_STATUS_IS_OK(status)) { \
     124             :                 torture_comment(tctx, \
     125             :                     "(%s) Failed to set attrib 0x%x on %s\n", \
     126             :                        __location__, (unsigned int)(sattrib), fname); \
     127             :         }} while (0)
     128             : 
     129             : /*
     130             :   test some interesting combinations found by gentest
     131             :  */
     132           6 : static bool test_create_gentest(struct torture_context *tctx, struct smb2_tree *tree)
     133             : {
     134             :         struct smb2_create io;
     135             :         NTSTATUS status;
     136             :         uint32_t access_mask, file_attributes_set;
     137             :         uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
     138             :         uint32_t not_a_directory_mask, unexpected_mask;
     139             :         union smb_fileinfo q;
     140             : 
     141           6 :         ZERO_STRUCT(io);
     142           6 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
     143           6 :         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
     144           6 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     145           6 :         io.in.share_access = 
     146             :                 NTCREATEX_SHARE_ACCESS_DELETE|
     147             :                 NTCREATEX_SHARE_ACCESS_READ|
     148             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     149           6 :         io.in.create_options = 0;
     150           6 :         io.in.fname = FNAME;
     151             : 
     152           6 :         status = smb2_create(tree, tctx, &io);
     153           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     154             : 
     155           6 :         status = smb2_util_close(tree, io.out.file.handle);
     156           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     157             : 
     158           6 :         io.in.create_options = 0xF0000000;
     159           6 :         status = smb2_create(tree, tctx, &io);
     160           6 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     161             : 
     162           6 :         io.in.create_options = 0;
     163             : 
     164           6 :         io.in.file_attributes = FILE_ATTRIBUTE_DEVICE;
     165           6 :         status = smb2_create(tree, tctx, &io);
     166           6 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     167             : 
     168           1 :         io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
     169           1 :         status = smb2_create(tree, tctx, &io);
     170           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     171             : 
     172           1 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
     173           1 :         io.in.file_attributes = FILE_ATTRIBUTE_VOLUME;
     174           1 :         status = smb2_create(tree, tctx, &io);
     175           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     176             :         
     177           1 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
     178           1 :         io.in.desired_access = 0x08000000;
     179           1 :         status = smb2_create(tree, tctx, &io);
     180           1 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     181             : 
     182           1 :         io.in.desired_access = 0x04000000;
     183           1 :         status = smb2_create(tree, tctx, &io);
     184           1 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     185             : 
     186           1 :         io.in.file_attributes = 0;
     187           1 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     188           1 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
     189           1 :         ok_mask = 0;
     190           1 :         not_supported_mask = 0;
     191           1 :         invalid_parameter_mask = 0;
     192           1 :         not_a_directory_mask = 0;
     193           1 :         unexpected_mask = 0;
     194             :         {
     195             :                 int i;
     196          33 :                 for (i=0;i<32;i++) {
     197          32 :                         io.in.create_options = (uint32_t)1<<i;
     198          32 :                         if (io.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
     199           1 :                                 continue;
     200             :                         }
     201          31 :                         status = smb2_create(tree, tctx, &io);
     202          31 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
     203           3 :                                 not_supported_mask |= 1<<i;
     204          28 :                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
     205           8 :                                 invalid_parameter_mask |= 1<<i;
     206          20 :                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
     207           1 :                                 not_a_directory_mask |= 1<<i;
     208          19 :                         } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
     209          19 :                                 ok_mask |= 1<<i;
     210          19 :                                 status = smb2_util_close(tree, io.out.file.handle);
     211          19 :                                 CHECK_STATUS(status, NT_STATUS_OK);
     212             :                         } else {
     213           0 :                                 unexpected_mask |= 1<<i;
     214           0 :                                 torture_comment(tctx,
     215             :                                     "create option 0x%08x returned %s\n",
     216             :                                     1<<i, nt_errstr(status));
     217             :                         }
     218             :                 }
     219             :         }
     220           1 :         io.in.create_options = 0;
     221             : 
     222           1 :         CHECK_EQUAL(ok_mask,                0x00efcf7e);
     223           1 :         CHECK_EQUAL(not_a_directory_mask,   0x00000001);
     224           1 :         CHECK_EQUAL(not_supported_mask,     0x00102080);
     225           1 :         CHECK_EQUAL(invalid_parameter_mask, 0xff000000);
     226           1 :         CHECK_EQUAL(unexpected_mask,        0x00000000);
     227             : 
     228           1 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     229           1 :         io.in.file_attributes = 0;
     230           1 :         access_mask = 0;
     231             :         {
     232             :                 int i;
     233          33 :                 for (i=0;i<32;i++) {
     234          32 :                         io.in.desired_access = (uint32_t)1<<i;
     235          32 :                         status = smb2_create(tree, tctx, &io);
     236          51 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
     237          19 :                             NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
     238          13 :                                 access_mask |= io.in.desired_access;
     239             :                         } else {
     240          19 :                                 CHECK_STATUS(status, NT_STATUS_OK);
     241          19 :                                 status = smb2_util_close(tree, io.out.file.handle);
     242          19 :                                 CHECK_STATUS(status, NT_STATUS_OK);
     243             :                         }
     244             :                 }
     245             :         }
     246             : 
     247           1 :         if (TARGET_IS_WIN7(tctx)) {
     248           0 :                 CHECK_EQUAL(access_mask, 0x0de0fe00);
     249           1 :         } else if (torture_setting_bool(tctx, "samba4", false)) {
     250           1 :                 CHECK_EQUAL(access_mask, 0x0cf0fe00);
     251             :         } else {
     252           0 :                 CHECK_EQUAL(access_mask, 0x0df0fe00);
     253             :         }
     254             : 
     255           1 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     256           1 :         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     257           1 :         io.in.file_attributes = 0;
     258           1 :         ok_mask = 0;
     259           1 :         invalid_parameter_mask = 0;
     260           1 :         unexpected_mask = 0;
     261           1 :         file_attributes_set = 0;
     262             :         {
     263             :                 int i;
     264          33 :                 for (i=0;i<32;i++) {
     265          32 :                         io.in.file_attributes = (uint32_t)1<<i;
     266          32 :                         if (io.in.file_attributes & FILE_ATTRIBUTE_ENCRYPTED) {
     267           1 :                                 continue;
     268             :                         }
     269          31 :                         smb2_deltree(tree, FNAME);
     270          31 :                         status = smb2_create(tree, tctx, &io);
     271          31 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
     272          19 :                                 invalid_parameter_mask |= 1<<i;
     273          12 :                         } else if (NT_STATUS_IS_OK(status)) {
     274             :                                 uint32_t expected;
     275          12 :                                 ok_mask |= 1<<i;
     276             : 
     277          12 :                                 expected = (io.in.file_attributes | FILE_ATTRIBUTE_ARCHIVE) & 0x00005127;
     278          12 :                                 io.out.file_attr &= ~FILE_ATTRIBUTE_NONINDEXED;
     279          12 :                                 CHECK_EQUAL(io.out.file_attr, expected);
     280          12 :                                 file_attributes_set |= io.out.file_attr;
     281             : 
     282          12 :                                 status = smb2_util_close(tree, io.out.file.handle);
     283          12 :                                 CHECK_STATUS(status, NT_STATUS_OK);
     284             :                         } else {
     285           0 :                                 unexpected_mask |= 1<<i;
     286           0 :                                 torture_comment(tctx,
     287             :                                     "file attribute 0x%08x returned %s\n",
     288             :                                     1<<i, nt_errstr(status));
     289             :                         }
     290             :                 }
     291             :         }
     292             : 
     293           1 :         CHECK_EQUAL(ok_mask,                0x00003fb7);
     294           1 :         CHECK_EQUAL(invalid_parameter_mask, 0xffff8048);
     295           1 :         CHECK_EQUAL(unexpected_mask,        0x00000000);
     296           1 :         CHECK_EQUAL(file_attributes_set,    0x00001127);
     297             : 
     298           1 :         smb2_deltree(tree, FNAME);
     299             : 
     300             :         /*
     301             :          * Standalone servers doesn't support encryption
     302             :          */
     303           1 :         io.in.file_attributes = FILE_ATTRIBUTE_ENCRYPTED;
     304           1 :         status = smb2_create(tree, tctx, &io);
     305           1 :         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
     306           1 :                 torture_comment(tctx,
     307             :                     "FILE_ATTRIBUTE_ENCRYPTED returned %s\n",
     308             :                     nt_errstr(status));
     309             :         } else {
     310           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     311           0 :                 CHECK_EQUAL(io.out.file_attr, (FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_ARCHIVE));
     312           0 :                 status = smb2_util_close(tree, io.out.file.handle);
     313           0 :                 CHECK_STATUS(status, NT_STATUS_OK);
     314             :         }
     315             : 
     316           1 :         smb2_deltree(tree, FNAME);
     317             : 
     318           1 :         ZERO_STRUCT(io);
     319           1 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
     320           1 :         io.in.file_attributes    = 0;
     321           1 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     322           1 :         io.in.share_access = 
     323             :                 NTCREATEX_SHARE_ACCESS_READ|
     324             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     325           1 :         io.in.create_options = 0;
     326           1 :         io.in.fname = FNAME ":stream1";
     327           1 :         status = smb2_create(tree, tctx, &io);
     328           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     329             : 
     330           1 :         status = smb2_util_close(tree, io.out.file.handle);
     331           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     332             : 
     333           1 :         io.in.fname = FNAME;
     334           1 :         io.in.file_attributes = 0x8040;
     335           1 :         io.in.share_access = 
     336             :                 NTCREATEX_SHARE_ACCESS_READ;
     337           1 :         status = smb2_create(tree, tctx, &io);
     338           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     339             : 
     340           1 :         io.in.fname = FNAME;
     341           1 :         io.in.file_attributes = 0;
     342           1 :         io.in.desired_access  = SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA;
     343           1 :         io.in.query_maximal_access = true;
     344           1 :         status = smb2_create(tree, tctx, &io);
     345           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     346           1 :         CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
     347             : 
     348           1 :         q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
     349           1 :         q.access_information.in.file.handle = io.out.file.handle;
     350           1 :         status = smb2_getinfo_file(tree, tctx, &q);
     351           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     352           1 :         CHECK_EQUAL(q.access_information.out.access_flags, io.in.desired_access);
     353             : 
     354           1 :         io.in.file_attributes = 0;
     355           1 :         io.in.desired_access  = 0;
     356           1 :         io.in.query_maximal_access = false;
     357           1 :         io.in.share_access = 0;
     358           1 :         status = smb2_create(tree, tctx, &io);
     359           1 :         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
     360             :         
     361           1 :         smb2_deltree(tree, FNAME);
     362             : 
     363           1 :         return true;
     364             : }
     365             : 
     366             : 
     367             : /*
     368             :   try the various request blobs
     369             :  */
     370           6 : static bool test_create_blob(struct torture_context *tctx, struct smb2_tree *tree)
     371             : {
     372             :         struct smb2_create io;
     373             :         NTSTATUS status;
     374             : 
     375           6 :         smb2_deltree(tree, FNAME);
     376             : 
     377           6 :         ZERO_STRUCT(io);
     378           6 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
     379           6 :         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
     380           6 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     381           6 :         io.in.share_access = 
     382             :                 NTCREATEX_SHARE_ACCESS_DELETE|
     383             :                 NTCREATEX_SHARE_ACCESS_READ|
     384             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     385           6 :         io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
     386             :                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
     387             :                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
     388             :                                           0x00200000;
     389           6 :         io.in.fname = FNAME;
     390             : 
     391           6 :         status = smb2_create(tree, tctx, &io);
     392           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     393             : 
     394           6 :         status = smb2_util_close(tree, io.out.file.handle);
     395           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     396             : 
     397           6 :         torture_comment(tctx, "Testing alloc size\n");
     398             :         /* FIXME We use 1M cause that's the rounded size of Samba.
     399             :          * We should ask the server for the cluser size and calulate it
     400             :          * correctly. */
     401           6 :         io.in.alloc_size = 0x00100000;
     402           6 :         status = smb2_create(tree, tctx, &io);
     403           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     404           6 :         CHECK_EQUAL(io.out.alloc_size, io.in.alloc_size);
     405             : 
     406           6 :         status = smb2_util_close(tree, io.out.file.handle);
     407           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     408             : 
     409           6 :         torture_comment(tctx, "Testing durable open\n");
     410           6 :         io.in.durable_open = true;
     411           6 :         status = smb2_create(tree, tctx, &io);
     412           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     413             : 
     414           6 :         status = smb2_util_close(tree, io.out.file.handle);
     415           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     416             : 
     417           6 :         torture_comment(tctx, "Testing query maximal access\n");
     418           6 :         io.in.query_maximal_access = true;
     419           6 :         status = smb2_create(tree, tctx, &io);
     420           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     421           6 :         CHECK_EQUAL(io.out.maximal_access, 0x001f01ff);
     422             : 
     423           6 :         status = smb2_util_close(tree, io.out.file.handle);
     424           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     425             : 
     426           6 :         torture_comment(tctx, "Testing timewarp\n");
     427           6 :         io.in.timewarp = 10000;
     428           6 :         status = smb2_create(tree, tctx, &io);
     429           6 :         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     430           1 :         io.in.timewarp = 0;
     431             : 
     432           1 :         torture_comment(tctx, "Testing query_on_disk\n");
     433           1 :         io.in.query_on_disk_id = true;
     434           1 :         status = smb2_create(tree, tctx, &io);
     435           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     436             : 
     437           1 :         status = smb2_util_close(tree, io.out.file.handle);
     438           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     439             : 
     440           1 :         torture_comment(tctx, "Testing unknown tag\n");
     441           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     442             :                                       "FooO", data_blob(NULL, 0));
     443           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     444             : 
     445           1 :         status = smb2_create(tree, tctx, &io);
     446           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     447             : 
     448           1 :         status = smb2_util_close(tree, io.out.file.handle);
     449           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     450             : 
     451           1 :         torture_comment(tctx, "Testing bad tag length 0\n");
     452           1 :         ZERO_STRUCT(io.in.blobs);
     453           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     454             :                                       "x", data_blob(NULL, 0));
     455           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     456           1 :         status = smb2_create(tree, tctx, &io);
     457           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     458             : 
     459           1 :         torture_comment(tctx, "Testing bad tag length 1\n");
     460           1 :         ZERO_STRUCT(io.in.blobs);
     461           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     462             :                                       "x", data_blob(NULL, 0));
     463           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     464           1 :         status = smb2_create(tree, tctx, &io);
     465           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     466             : 
     467           1 :         torture_comment(tctx, "Testing bad tag length 2\n");
     468           1 :         ZERO_STRUCT(io.in.blobs);
     469           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     470             :                                       "xx", data_blob(NULL, 0));
     471           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     472           1 :         status = smb2_create(tree, tctx, &io);
     473           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     474             : 
     475           1 :         torture_comment(tctx, "Testing bad tag length 3\n");
     476           1 :         ZERO_STRUCT(io.in.blobs);
     477           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     478             :                                       "xxx", data_blob(NULL, 0));
     479           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     480           1 :         status = smb2_create(tree, tctx, &io);
     481           1 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
     482             : 
     483           1 :         torture_comment(tctx, "Testing tag length 4\n");
     484           1 :         ZERO_STRUCT(io.in.blobs);
     485           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     486             :                                       "xxxx", data_blob(NULL, 0));
     487           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     488           1 :         status = smb2_create(tree, tctx, &io);
     489           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     490             : 
     491           1 :         torture_comment(tctx, "Testing tag length 5\n");
     492           1 :         ZERO_STRUCT(io.in.blobs);
     493           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     494             :                                       "xxxxx", data_blob(NULL, 0));
     495           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     496           1 :         status = smb2_create(tree, tctx, &io);
     497           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     498             : 
     499           1 :         torture_comment(tctx, "Testing tag length 6\n");
     500           1 :         ZERO_STRUCT(io.in.blobs);
     501           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     502             :                                       "xxxxxx", data_blob(NULL, 0));
     503           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     504           1 :         status = smb2_create(tree, tctx, &io);
     505           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     506             : 
     507           1 :         torture_comment(tctx, "Testing tag length 7\n");
     508           1 :         ZERO_STRUCT(io.in.blobs);
     509           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     510             :                                       "xxxxxxx", data_blob(NULL, 0));
     511           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     512           1 :         status = smb2_create(tree, tctx, &io);
     513           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     514             : 
     515           1 :         torture_comment(tctx, "Testing tag length 8\n");
     516           1 :         ZERO_STRUCT(io.in.blobs);
     517           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     518             :                                       "xxxxxxxx", data_blob(NULL, 0));
     519           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     520           1 :         status = smb2_create(tree, tctx, &io);
     521           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     522             : 
     523           1 :         torture_comment(tctx, "Testing tag length 16\n");
     524           1 :         ZERO_STRUCT(io.in.blobs);
     525           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     526             :                                       "xxxxxxxxxxxxxxxx", data_blob(NULL, 0));
     527           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     528           1 :         status = smb2_create(tree, tctx, &io);
     529           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     530             : 
     531           1 :         torture_comment(tctx, "Testing tag length 17\n");
     532           1 :         ZERO_STRUCT(io.in.blobs);
     533           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     534             :                                       "xxxxxxxxxxxxxxxxx", data_blob(NULL, 0));
     535           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     536           1 :         status = smb2_create(tree, tctx, &io);
     537           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     538             : 
     539           1 :         torture_comment(tctx, "Testing tag length 34\n");
     540           1 :         ZERO_STRUCT(io.in.blobs);
     541           1 :         status = smb2_create_blob_add(tctx, &io.in.blobs,
     542             :                                       "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
     543             :                                       data_blob(NULL, 0));
     544           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     545           1 :         status = smb2_create(tree, tctx, &io);
     546           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     547             : 
     548           1 :         smb2_deltree(tree, FNAME);
     549             :         
     550           1 :         return true;
     551             : }
     552             : 
     553             : #define FAIL_UNLESS(__cond)                                     \
     554             :         do {                                                    \
     555             :                 if (__cond) {} else {                           \
     556             :                         torture_result(tctx, TORTURE_FAIL, "%s) condition violated: %s\n",    \
     557             :                                __location__, #__cond);          \
     558             :                         ret = false; goto done;                 \
     559             :                 }                                               \
     560             :         } while(0)
     561             : 
     562             : /*
     563             :   try creating with acls
     564             :  */
     565          12 : static bool test_create_acl_ext(struct torture_context *tctx, struct smb2_tree *tree, bool test_dir)
     566             : {
     567          12 :         bool ret = true;
     568             :         struct smb2_create io;
     569             :         NTSTATUS status;
     570             :         struct security_ace ace;
     571             :         struct security_descriptor *sd;
     572             :         struct dom_sid *test_sid;
     573          12 :         union smb_fileinfo q = {};
     574          12 :         uint32_t attrib =
     575             :             FILE_ATTRIBUTE_HIDDEN |
     576             :             FILE_ATTRIBUTE_SYSTEM |
     577             :             (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
     578          12 :         NTSTATUS (*delete_func)(struct smb2_tree *, const char *) =
     579          12 :             test_dir ? smb2_util_rmdir : smb2_util_unlink;
     580             : 
     581          12 :         ZERO_STRUCT(ace);
     582             : 
     583          12 :         smb2_deltree(tree, FNAME);
     584             : 
     585          12 :         ZERO_STRUCT(io);
     586          12 :         io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
     587          12 :         io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
     588          12 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
     589          12 :         io.in.share_access = 
     590             :                 NTCREATEX_SHARE_ACCESS_DELETE |
     591             :                 NTCREATEX_SHARE_ACCESS_READ |
     592             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     593          12 :         io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT | 0x00200000 |
     594             :             (test_dir ?  NTCREATEX_OPTIONS_DIRECTORY :
     595             :                 (NTCREATEX_OPTIONS_NON_DIRECTORY_FILE));
     596             : 
     597          12 :         io.in.fname = FNAME;
     598             : 
     599          12 :         torture_comment(tctx, "basic create\n");
     600             : 
     601          12 :         status = smb2_create(tree, tctx, &io);
     602          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     603             : 
     604          12 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     605          12 :         q.query_secdesc.in.file.handle = io.out.file.handle;
     606          12 :         q.query_secdesc.in.secinfo_flags = 
     607             :                 SECINFO_OWNER |
     608             :                 SECINFO_GROUP |
     609             :                 SECINFO_DACL;
     610          12 :         status = smb2_getinfo_file(tree, tctx, &q);
     611          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     612          12 :         sd = q.query_secdesc.out.sd;
     613             : 
     614          12 :         status = smb2_util_close(tree, io.out.file.handle);
     615          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     616          12 :         status = delete_func(tree, FNAME);
     617          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     618             : 
     619          12 :         torture_comment(tctx, "adding a new ACE\n");
     620          12 :         test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
     621             : 
     622          12 :         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
     623          12 :         ace.flags = 0;
     624          12 :         ace.access_mask = SEC_STD_ALL;
     625          12 :         ace.trustee = *test_sid;
     626             : 
     627          12 :         status = security_descriptor_dacl_add(sd, &ace);
     628          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     629             : 
     630          12 :         torture_comment(tctx, "creating a file with an initial ACL\n");
     631             : 
     632          12 :         io.in.sec_desc = sd;
     633          12 :         status = smb2_create(tree, tctx, &io);
     634          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     635             : 
     636          12 :         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
     637             : 
     638          12 :         status = smb2_util_close(tree, io.out.file.handle);
     639          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     640          12 :         status = delete_func(tree, FNAME);
     641          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     642             : 
     643          12 :         torture_comment(tctx, "creating with attributes\n");
     644             : 
     645          12 :         io.in.sec_desc = NULL;
     646          12 :         io.in.file_attributes = attrib;
     647          12 :         status = smb2_create(tree, tctx, &io);
     648          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     649             : 
     650          12 :         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
     651             : 
     652          11 :         status = smb2_util_close(tree, io.out.file.handle);
     653          11 :         CHECK_STATUS(status, NT_STATUS_OK);
     654          11 :         status = delete_func(tree, FNAME);
     655          11 :         CHECK_STATUS(status, NT_STATUS_OK);
     656             : 
     657          11 :         torture_comment(tctx, "creating with attributes and ACL\n");
     658             : 
     659          11 :         io.in.sec_desc = sd;
     660          11 :         io.in.file_attributes = attrib;
     661          11 :         status = smb2_create(tree, tctx, &io);
     662          11 :         CHECK_STATUS(status, NT_STATUS_OK);
     663             : 
     664          11 :         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
     665          11 :         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
     666             :         
     667          11 :         status = smb2_util_close(tree, io.out.file.handle);
     668          11 :         CHECK_STATUS(status, NT_STATUS_OK);
     669          11 :         status = delete_func(tree, FNAME);
     670          11 :         CHECK_STATUS(status, NT_STATUS_OK);
     671             : 
     672          11 :         torture_comment(tctx, "creating with attributes, ACL and owner\n");
     673          11 :         sd = security_descriptor_dacl_create(tctx,
     674             :                                         0, SID_WORLD, SID_BUILTIN_USERS,
     675             :                                         SID_WORLD,
     676             :                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
     677             :                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
     678             :                                         0,
     679             :                                         NULL);
     680             : 
     681          11 :         io.in.sec_desc = sd;
     682          11 :         io.in.file_attributes = attrib;
     683          11 :         status = smb2_create(tree, tctx, &io);
     684          11 :         CHECK_STATUS(status, NT_STATUS_OK);
     685             : 
     686          11 :         FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
     687          11 :         FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));
     688             : 
     689          12 :  done:
     690          12 :         status = smb2_util_close(tree, io.out.file.handle);
     691          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     692          12 :         status = delete_func(tree, FNAME);
     693          12 :         CHECK_STATUS(status, NT_STATUS_OK);
     694             : 
     695          12 :         return ret;
     696             : }
     697             : 
     698             : /*
     699             :   test SMB2 open
     700             : */
     701           6 : static bool test_smb2_open(struct torture_context *tctx,
     702             :                            struct smb2_tree *tree)
     703             : {
     704             :         union smb_open io;
     705             :         union smb_fileinfo finfo;
     706           6 :         const char *fname = DNAME "\\torture_ntcreatex.txt";
     707           6 :         const char *dname = DNAME "\\torture_ntcreatex.dir";
     708             :         NTSTATUS status;
     709           6 :         struct smb2_handle h = {{0}};
     710           6 :         struct smb2_handle h1 = {{0}};
     711           6 :         bool ret = true;
     712             :         int i;
     713             :         struct {
     714             :                 uint32_t create_disp;
     715             :                 bool with_file;
     716             :                 NTSTATUS correct_status;
     717           6 :         } open_funcs[] = {
     718             :                 { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
     719             :                 { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
     720             :                 { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
     721             :                 { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     722             :                 { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
     723             :                 { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
     724             :                 { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
     725             :                 { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
     726             :                 { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
     727             :                 { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
     728             :                 { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
     729             :                 { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
     730             :                 { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
     731             :                 { 6,                            false, NT_STATUS_INVALID_PARAMETER },
     732             :         };
     733             : 
     734           6 :         torture_comment(tctx, "Checking SMB2 Open\n");
     735             : 
     736           6 :         smb2_util_unlink(tree, fname);
     737           6 :         smb2_util_rmdir(tree, dname);
     738             : 
     739           6 :         status = torture_smb2_testdir(tree, DNAME, &h);
     740           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     741             : 
     742           6 :         ZERO_STRUCT(io.smb2);
     743             :         /* reasonable default parameters */
     744           6 :         io.generic.level = RAW_OPEN_SMB2;
     745           6 :         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     746           6 :         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     747           6 :         io.smb2.in.alloc_size = 1024*1024;
     748           6 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     749           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     750           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     751           6 :         io.smb2.in.create_options = 0;
     752           6 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
     753           6 :         io.smb2.in.security_flags = 0;
     754           6 :         io.smb2.in.fname = fname;
     755             : 
     756             :         /* test the create disposition */
     757          90 :         for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
     758          84 :                 if (open_funcs[i].with_file) {
     759          42 :                         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     760          42 :                         status= smb2_create(tree, tctx, &(io.smb2));
     761          42 :                         if (!NT_STATUS_IS_OK(status)) {
     762           0 :                                 torture_comment(tctx,
     763             :                                     "Failed to create file %s status %s %d\n",
     764             :                                     fname, nt_errstr(status), i);
     765             : 
     766           0 :                                 ret = false;
     767           0 :                                 goto done;
     768             :                         }
     769          42 :                         smb2_util_close(tree, io.smb2.out.file.handle);
     770             :                 }
     771          84 :                 io.smb2.in.create_disposition = open_funcs[i].create_disp;
     772          84 :                 status = smb2_create(tree, tctx, &(io.smb2));
     773          84 :                 if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
     774           0 :                         torture_comment(tctx,
     775             :                             "(%s) incorrect status %s should be %s (i=%d "
     776             :                             "with_file=%d open_disp=%d)\n",
     777             :                          __location__, nt_errstr(status),
     778             :                         nt_errstr(open_funcs[i].correct_status),
     779           0 :                         i, (int)open_funcs[i].with_file,
     780           0 :                         (int)open_funcs[i].create_disp);
     781             : 
     782           0 :                         ret = false;
     783           0 :                         goto done;
     784             :                 }
     785          84 :                 if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
     786          66 :                         smb2_util_close(tree, io.smb2.out.file.handle);
     787          66 :                         smb2_util_unlink(tree, fname);
     788             :                 }
     789             :         }
     790             : 
     791             :         /* basic field testing */
     792           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     793             : 
     794           6 :         status = smb2_create(tree, tctx, &(io.smb2));
     795           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     796           6 :         h1 = io.smb2.out.file.handle;
     797             : 
     798           6 :         CHECK_VAL(io.smb2.out.oplock_level, 0);
     799           6 :         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
     800           6 :         CHECK_NTTIME(io.smb2.out.create_time, create_time);
     801           6 :         CHECK_NTTIME(io.smb2.out.access_time, access_time);
     802           6 :         CHECK_NTTIME(io.smb2.out.write_time, write_time);
     803           6 :         CHECK_NTTIME(io.smb2.out.change_time, change_time);
     804           6 :         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
     805           6 :         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
     806           6 :         CHECK_ALL_INFO(io.smb2.out.size, size);
     807             : 
     808             :         /* check fields when the file already existed */
     809           6 :         smb2_util_close(tree, h1);
     810           6 :         smb2_util_unlink(tree, fname);
     811             : 
     812           6 :         status = smb2_create_complex_file(tctx, tree, fname, &h1);
     813           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     814             : 
     815           1 :         smb2_util_close(tree, h1);
     816             : 
     817           1 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
     818           1 :         status = smb2_create(tree, tctx, &(io.smb2));
     819           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     820           1 :         h1 = io.smb2.out.file.handle;
     821             : 
     822           1 :         CHECK_VAL(io.smb2.out.oplock_level, 0);
     823           1 :         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_EXISTED);
     824           1 :         CHECK_NTTIME(io.smb2.out.create_time, create_time);
     825           1 :         CHECK_NTTIME(io.smb2.out.access_time, access_time);
     826           1 :         CHECK_NTTIME(io.smb2.out.write_time, write_time);
     827           1 :         CHECK_NTTIME(io.smb2.out.change_time, change_time);
     828           1 :         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
     829           1 :         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
     830           1 :         CHECK_ALL_INFO(io.smb2.out.size, size);
     831           1 :         smb2_util_close(tree, h1);
     832           1 :         smb2_util_unlink(tree, fname);
     833             : 
     834             :         /* create a directory */
     835           1 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     836           1 :         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
     837           1 :         io.smb2.in.alloc_size = 0;
     838           1 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     839           1 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     840           1 :         io.smb2.in.create_options = 0;
     841           1 :         io.smb2.in.fname = dname;
     842           1 :         fname = dname;
     843             : 
     844           1 :         smb2_util_rmdir(tree, fname);
     845           1 :         smb2_util_unlink(tree, fname);
     846             : 
     847           1 :         io.smb2.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
     848           1 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     849           1 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     850           1 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     851             :                                 NTCREATEX_SHARE_ACCESS_WRITE;
     852           1 :         status = smb2_create(tree, tctx, &(io.smb2));
     853           1 :         CHECK_STATUS(status, NT_STATUS_OK);
     854           1 :         h1 = io.smb2.out.file.handle;
     855             : 
     856           1 :         CHECK_VAL(io.smb2.out.oplock_level, 0);
     857           1 :         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
     858           1 :         CHECK_NTTIME(io.smb2.out.create_time, create_time);
     859           1 :         CHECK_NTTIME(io.smb2.out.access_time, access_time);
     860           1 :         CHECK_NTTIME(io.smb2.out.write_time, write_time);
     861           1 :         CHECK_NTTIME(io.smb2.out.change_time, change_time);
     862           1 :         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
     863           1 :         CHECK_VAL(io.smb2.out.file_attr & ~FILE_ATTRIBUTE_NONINDEXED,
     864             :                   FILE_ATTRIBUTE_DIRECTORY);
     865           1 :         CHECK_ALL_INFO(io.smb2.out.alloc_size, alloc_size);
     866           1 :         CHECK_ALL_INFO(io.smb2.out.size, size);
     867           1 :         CHECK_VAL(io.smb2.out.size, 0);
     868           1 :         CHECK_VAL(io.smb2.out.alloc_size, 0);
     869           1 :         smb2_util_unlink(tree, fname);
     870             : 
     871           1 : done:
     872           1 :         smb2_util_close(tree, h1);
     873           1 :         smb2_util_unlink(tree, fname);
     874           1 :         smb2_deltree(tree, DNAME);
     875           1 :         return ret;
     876             : }
     877             : 
     878             : /*
     879             :   test with an already opened and byte range locked file
     880             : */
     881             : 
     882           6 : static bool test_smb2_open_brlocked(struct torture_context *tctx,
     883             :                                     struct smb2_tree *tree)
     884             : {
     885             :         union smb_open io, io1;
     886             :         union smb_lock io2;
     887             :         struct smb2_lock_element lock[1];
     888           6 :         const char *fname = DNAME "\\torture_ntcreatex.txt";
     889             :         NTSTATUS status;
     890           6 :         bool ret = true;
     891             :         struct smb2_handle h;
     892           6 :         char b = 42;
     893             : 
     894           6 :         torture_comment(tctx,
     895             :                 "Testing SMB2 open with a byte range locked file\n");
     896             : 
     897           6 :         smb2_util_unlink(tree, fname);
     898             : 
     899           6 :         status = torture_smb2_testdir(tree, DNAME, &h);
     900           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     901             : 
     902           6 :         ZERO_STRUCT(io.smb2);
     903           6 :         io.generic.level = RAW_OPEN_SMB2;
     904           6 :         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     905           6 :         io.smb2.in.desired_access = 0x2019f;
     906           6 :         io.smb2.in.alloc_size = 0;
     907           6 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     908           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     909             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     910           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
     911           6 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE;
     912           6 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
     913           6 :         io.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
     914           6 :         io.smb2.in.fname = fname;
     915             : 
     916           6 :         status = smb2_create(tree, tctx, &(io.smb2));
     917           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     918             : 
     919           6 :         status = smb2_util_write(tree, io.smb2.out.file.handle, &b, 0, 1);
     920           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     921             : 
     922           6 :         ZERO_STRUCT(io2.smb2);
     923           6 :         io2.smb2.level = RAW_LOCK_SMB2;
     924           6 :         io2.smb2.in.file.handle = io.smb2.out.file.handle;
     925           6 :         io2.smb2.in.lock_count = 1;
     926             : 
     927           6 :         ZERO_STRUCT(lock);
     928           6 :         lock[0].offset = 0;
     929           6 :         lock[0].length = 1;
     930           6 :         lock[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE |
     931             :                         SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
     932           6 :         io2.smb2.in.locks = &lock[0];
     933           6 :         status = smb2_lock(tree, &(io2.smb2));
     934           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     935             : 
     936           6 :         ZERO_STRUCT(io1.smb2);
     937           6 :         io1.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
     938           6 :         io1.smb2.in.desired_access = 0x20196;
     939           6 :         io1.smb2.in.alloc_size = 0;
     940           6 :         io1.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     941           6 :         io1.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     942             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     943           6 :         io1.smb2.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     944           6 :         io1.smb2.in.create_options = 0;
     945           6 :         io1.smb2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
     946           6 :         io1.smb2.in.security_flags = SMB2_SECURITY_DYNAMIC_TRACKING;
     947           6 :         io1.smb2.in.fname = fname;
     948             : 
     949           6 :         status = smb2_create(tree, tctx, &(io1.smb2));
     950           6 :         CHECK_STATUS(status, NT_STATUS_OK);
     951             : 
     952           6 :         smb2_util_close(tree, io.smb2.out.file.handle);
     953           6 :         smb2_util_close(tree, io1.smb2.out.file.handle);
     954           6 :         smb2_util_unlink(tree, fname);
     955           6 :         smb2_deltree(tree, DNAME);
     956             : 
     957           6 :         return ret;
     958             : }
     959             : 
     960             : /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
     961             : 
     962           6 : static bool test_smb2_open_multi(struct torture_context *tctx,
     963             :                                 struct smb2_tree *tree)
     964             : {
     965           6 :         const char *fname = "test_oplock.dat";
     966             :         NTSTATUS status;
     967           6 :         bool ret = true;
     968             :         union smb_open io;
     969             :         struct smb2_tree **trees;
     970             :         struct smb2_request **requests;
     971             :         union smb_open *ios;
     972           6 :         int i, num_files = 3;
     973           6 :         int num_ok = 0;
     974           6 :         int num_collision = 0;
     975             : 
     976           6 :         torture_comment(tctx,
     977             :                 "Testing SMB2 Open with multiple connections\n");
     978           6 :         trees = talloc_array(tctx, struct smb2_tree *, num_files);
     979           6 :         requests = talloc_array(tctx, struct smb2_request *, num_files);
     980           6 :         ios = talloc_array(tctx, union smb_open, num_files);
     981           6 :         if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
     982             :             (ios == NULL)) {
     983           0 :                 torture_comment(tctx, ("talloc failed\n"));
     984           0 :                 ret = false;
     985           0 :                 goto done;
     986             :         }
     987             : 
     988           6 :         tree->session->transport->options.request_timeout = 60;
     989             : 
     990          24 :         for (i=0; i<num_files; i++) {
     991          18 :                 if (!torture_smb2_connection(tctx, &(trees[i]))) {
     992           0 :                         torture_comment(tctx,
     993             :                                 "Could not open %d'th connection\n", i);
     994           0 :                         ret = false;
     995           0 :                         goto done;
     996             :                 }
     997          18 :                 trees[i]->session->transport->options.request_timeout = 60;
     998             :         }
     999             : 
    1000             :         /* cleanup */
    1001           6 :         smb2_util_unlink(tree, fname);
    1002             : 
    1003             :         /*
    1004             :           base ntcreatex parms
    1005             :         */
    1006           6 :         ZERO_STRUCT(io.smb2);
    1007           6 :         io.generic.level = RAW_OPEN_SMB2;
    1008           6 :         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1009           6 :         io.smb2.in.alloc_size = 0;
    1010           6 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1011           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1012             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    1013             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    1014           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    1015           6 :         io.smb2.in.create_options = 0;
    1016           6 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    1017           6 :         io.smb2.in.security_flags = 0;
    1018           6 :         io.smb2.in.fname = fname;
    1019           6 :         io.smb2.in.create_flags = 0;
    1020             : 
    1021          24 :         for (i=0; i<num_files; i++) {
    1022          18 :                 ios[i] = io;
    1023          18 :                 requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
    1024          18 :                 if (requests[i] == NULL) {
    1025           0 :                         torture_comment(tctx,
    1026             :                                 "could not send %d'th request\n", i);
    1027           0 :                         ret = false;
    1028           0 :                         goto done;
    1029             :                 }
    1030             :         }
    1031             : 
    1032           6 :         torture_comment(tctx, "waiting for replies\n");
    1033          72 :         while (1) {
    1034          78 :                 bool unreplied = false;
    1035         113 :                 for (i=0; i<num_files; i++) {
    1036         107 :                         if (requests[i] == NULL) {
    1037          17 :                                 continue;
    1038             :                         }
    1039          90 :                         if (requests[i]->state < SMB2_REQUEST_DONE) {
    1040          72 :                                 unreplied = true;
    1041          72 :                                 break;
    1042             :                         }
    1043          18 :                         status = smb2_create_recv(requests[i], tctx,
    1044          18 :                                                   &(ios[i].smb2));
    1045             : 
    1046          18 :                         torture_comment(tctx,
    1047             :                                 "File %d returned status %s\n", i,
    1048             :                                 nt_errstr(status));
    1049             : 
    1050          18 :                         if (NT_STATUS_IS_OK(status)) {
    1051           6 :                                 num_ok += 1;
    1052             :                         }
    1053             : 
    1054          18 :                         if (NT_STATUS_EQUAL(status,
    1055             :                                             NT_STATUS_OBJECT_NAME_COLLISION)) {
    1056          12 :                                 num_collision += 1;
    1057             :                         }
    1058             : 
    1059          18 :                         requests[i] = NULL;
    1060             :                 }
    1061          78 :                 if (!unreplied) {
    1062           6 :                         break;
    1063             :                 }
    1064             : 
    1065          72 :                 if (tevent_loop_once(tctx->ev) != 0) {
    1066           0 :                         torture_comment(tctx, "tevent_loop_once failed\n");
    1067           0 :                         ret = false;
    1068           0 :                         goto done;
    1069             :                 }
    1070             :         }
    1071             : 
    1072           6 :         if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
    1073           0 :                 ret = false;
    1074             :         }
    1075          12 : done:
    1076           6 :         smb2_deltree(tree, fname);
    1077             : 
    1078           6 :         return ret;
    1079             : }
    1080             : 
    1081             : /*
    1082             :   test opening for delete on a read-only attribute file.
    1083             : */
    1084             : 
    1085           6 : static bool test_smb2_open_for_delete(struct torture_context *tctx,
    1086             :                                       struct smb2_tree *tree)
    1087             : {
    1088             :         union smb_open io;
    1089             :         union smb_fileinfo finfo;
    1090           6 :         const char *fname = DNAME "\\torture_open_for_delete.txt";
    1091             :         NTSTATUS status;
    1092             :         struct smb2_handle h, h1;
    1093           6 :         bool ret = true;
    1094             : 
    1095           6 :         torture_comment(tctx,
    1096             :                 "Checking SMB2_OPEN for delete on a readonly file.\n");
    1097           6 :         smb2_util_unlink(tree, fname);
    1098           6 :         smb2_deltree(tree, fname);
    1099             : 
    1100           6 :         status = torture_smb2_testdir(tree, DNAME, &h);
    1101           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1102             : 
    1103             :         /* reasonable default parameters */
    1104           6 :         ZERO_STRUCT(io.smb2);
    1105           6 :         io.generic.level = RAW_OPEN_SMB2;
    1106           6 :         io.smb2.in.create_flags = NTCREATEX_FLAGS_EXTENDED;
    1107           6 :         io.smb2.in.alloc_size = 0;
    1108           6 :         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1109           6 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_READONLY;
    1110           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1111           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    1112           6 :         io.smb2.in.create_options = 0;
    1113           6 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    1114           6 :         io.smb2.in.security_flags = 0;
    1115           6 :         io.smb2.in.fname = fname;
    1116             : 
    1117             :         /* Create the readonly file. */
    1118             : 
    1119           6 :         status = smb2_create(tree, tctx, &(io.smb2));
    1120           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1121           6 :         h1 = io.smb2.out.file.handle;
    1122             : 
    1123           6 :         CHECK_VAL(io.smb2.out.oplock_level, 0);
    1124           6 :         io.smb2.in.create_options = 0;
    1125           6 :         CHECK_VAL(io.smb2.out.create_action, NTCREATEX_ACTION_CREATED);
    1126           6 :         CHECK_ALL_INFO(io.smb2.out.file_attr, attrib);
    1127           6 :         smb2_util_close(tree, h1);
    1128             : 
    1129             :         /* Now try and open for delete only - should succeed. */
    1130           6 :         io.smb2.in.desired_access = SEC_STD_DELETE;
    1131           6 :         io.smb2.in.file_attributes = 0;
    1132           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1133             :                                 NTCREATEX_SHARE_ACCESS_WRITE |
    1134             :                                 NTCREATEX_SHARE_ACCESS_DELETE;
    1135           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN;
    1136           6 :         status = smb2_create(tree, tctx, &(io.smb2));
    1137           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1138           6 :         smb2_util_close(tree, io.smb2.out.file.handle);
    1139             : 
    1140             :         /* Clear readonly flag to allow file deletion */
    1141           6 :         io.smb2.in.desired_access = SEC_FILE_READ_ATTRIBUTE |
    1142             :                                 SEC_FILE_WRITE_ATTRIBUTE;
    1143           6 :         status = smb2_create(tree, tctx, &(io.smb2));
    1144           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1145           6 :         h1 = io.smb2.out.file.handle;
    1146           6 :         SET_ATTRIB(FILE_ATTRIBUTE_ARCHIVE);
    1147           6 :         smb2_util_close(tree, h1);
    1148             : 
    1149           6 :         smb2_util_close(tree, h);
    1150           6 :         smb2_util_unlink(tree, fname);
    1151           6 :         smb2_deltree(tree, DNAME);
    1152             : 
    1153           6 :         return ret;
    1154             : }
    1155             : 
    1156             : /*
    1157             :   test SMB2 open with a leading slash on the path.
    1158             :   Trying to create a directory with a leading slash
    1159             :   should give NT_STATUS_INVALID_PARAMETER error
    1160             : */
    1161           6 : static bool test_smb2_leading_slash(struct torture_context *tctx,
    1162             :                                     struct smb2_tree *tree)
    1163             : {
    1164             :         union smb_open io;
    1165           6 :         const char *dnameslash = "\\"DNAME;
    1166             :         NTSTATUS status;
    1167           6 :         bool ret = true;
    1168             : 
    1169           6 :         torture_comment(tctx,
    1170             :                 "Trying to create a directory with leading slash on path\n");
    1171           6 :         smb2_deltree(tree, dnameslash);
    1172             : 
    1173           6 :         ZERO_STRUCT(io.smb2);
    1174           6 :         io.generic.level = RAW_OPEN_SMB2;
    1175           6 :         io.smb2.in.oplock_level = 0;
    1176           6 :         io.smb2.in.desired_access = SEC_RIGHTS_DIR_ALL;
    1177           6 :         io.smb2.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
    1178           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    1179           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
    1180             :                                 NTCREATEX_SHARE_ACCESS_WRITE |
    1181             :                                 NTCREATEX_SHARE_ACCESS_DELETE;
    1182           6 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1183           6 :         io.smb2.in.fname = dnameslash;
    1184             : 
    1185           6 :         status = smb2_create(tree, tree, &(io.smb2));
    1186           6 :         CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
    1187             : 
    1188           6 :         smb2_deltree(tree, dnameslash);
    1189           6 :         return ret;
    1190             : }
    1191             : 
    1192             : /*
    1193             :   test SMB2 open with an invalid impersonation level.
    1194             :   Should give NT_STATUS_BAD_IMPERSONATION_LEVEL error
    1195             : */
    1196           6 : static bool test_smb2_impersonation_level(struct torture_context *tctx,
    1197             :                                     struct smb2_tree *tree)
    1198             : {
    1199             :         union smb_open io;
    1200           6 :         const char *fname = DNAME "\\torture_invalid_impersonation_level.txt";
    1201             :         NTSTATUS status;
    1202             :         struct smb2_handle h;
    1203           6 :         bool ret = true;
    1204             : 
    1205           6 :         torture_comment(tctx,
    1206             :                 "Testing SMB2 open with an invalid impersonation level.\n");
    1207             : 
    1208           6 :         smb2_util_unlink(tree, fname);
    1209           6 :         smb2_util_rmdir(tree, DNAME);
    1210             : 
    1211           6 :         status = torture_smb2_testdir(tree, DNAME, &h);
    1212           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1213             : 
    1214           6 :         ZERO_STRUCT(io.smb2);
    1215           6 :         io.generic.level = RAW_OPEN_SMB2;
    1216           6 :         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1217           6 :         io.smb2.in.alloc_size = 0;
    1218           6 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1219           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1220             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    1221             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    1222           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_CREATE;
    1223           6 :         io.smb2.in.create_options = 0;
    1224           6 :         io.smb2.in.impersonation_level = 0x12345678;
    1225           6 :         io.smb2.in.security_flags = 0;
    1226           6 :         io.smb2.in.fname = fname;
    1227           6 :         io.smb2.in.create_flags = 0;
    1228             : 
    1229           6 :         status = smb2_create(tree, tree, &(io.smb2));
    1230           6 :         CHECK_STATUS(status, NT_STATUS_BAD_IMPERSONATION_LEVEL);
    1231             : 
    1232           5 :         smb2_util_close(tree, h);
    1233           5 :         smb2_util_unlink(tree, fname);
    1234           5 :         smb2_deltree(tree, DNAME);
    1235           5 :         return ret;
    1236             : }
    1237             : 
    1238           6 : static bool test_create_acl_file(struct torture_context *tctx,
    1239             :     struct smb2_tree *tree)
    1240             : {
    1241           6 :         torture_comment(tctx, "Testing nttrans create with sec_desc on files\n");
    1242             : 
    1243           6 :         return test_create_acl_ext(tctx, tree, false);
    1244             : }
    1245             : 
    1246           6 : static bool test_create_acl_dir(struct torture_context *tctx,
    1247             :     struct smb2_tree *tree)
    1248             : {
    1249           6 :         torture_comment(tctx, "Testing nttrans create with sec_desc on directories\n");
    1250             : 
    1251           6 :         return test_create_acl_ext(tctx, tree, true);
    1252             : }
    1253             : 
    1254             : #define CHECK_ACCESS_FLAGS(_fh, flags) do { \
    1255             :         union smb_fileinfo _q; \
    1256             :         _q.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; \
    1257             :         _q.access_information.in.file.handle = (_fh); \
    1258             :         status = smb2_getinfo_file(tree, tctx, &_q); \
    1259             :         CHECK_STATUS(status, NT_STATUS_OK); \
    1260             :         if (_q.access_information.out.access_flags != (flags)) { \
    1261             :                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect access_flags 0x%08x - should be 0x%08x\n", \
    1262             :                        __location__, _q.access_information.out.access_flags, (flags)); \
    1263             :                 ret = false; \
    1264             :                 goto done; \
    1265             :         } \
    1266             : } while (0)
    1267             : 
    1268             : /*
    1269             :  * Test creating a file with a NULL DACL.
    1270             :  */
    1271           6 : static bool test_create_null_dacl(struct torture_context *tctx,
    1272             :     struct smb2_tree *tree)
    1273             : {
    1274             :         NTSTATUS status;
    1275             :         struct smb2_create io;
    1276           6 :         const char *fname = "nulldacl.txt";
    1277           6 :         bool ret = true;
    1278             :         struct smb2_handle handle;
    1279             :         union smb_fileinfo q;
    1280             :         union smb_setfileinfo s;
    1281           6 :         struct security_descriptor *sd = security_descriptor_initialise(tctx);
    1282             :         struct security_acl dacl;
    1283             : 
    1284           6 :         torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");
    1285             : 
    1286           6 :         smb2_util_unlink(tree, fname);
    1287             : 
    1288           6 :         ZERO_STRUCT(io);
    1289           6 :         io.level = RAW_OPEN_SMB2;
    1290           6 :         io.in.create_flags = 0;
    1291           6 :         io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
    1292             :                 | SEC_STD_WRITE_OWNER;
    1293           6 :         io.in.create_options = 0;
    1294           6 :         io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1295           6 :         io.in.share_access =
    1296             :                 NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    1297           6 :         io.in.alloc_size = 0;
    1298           6 :         io.in.create_disposition = NTCREATEX_DISP_CREATE;
    1299           6 :         io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1300           6 :         io.in.security_flags = 0;
    1301           6 :         io.in.fname = fname;
    1302           6 :         io.in.sec_desc = sd;
    1303             :         /* XXX create_options ? */
    1304           6 :         io.in.create_options            = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
    1305             :                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
    1306             :                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
    1307             :                                           0x00200000;
    1308             : 
    1309           6 :         torture_comment(tctx, "creating a file with a empty sd\n");
    1310           6 :         status = smb2_create(tree, tctx, &io);
    1311           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1312           6 :         handle = io.out.file.handle;
    1313             : 
    1314           6 :         torture_comment(tctx, "get the original sd\n");
    1315           6 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1316           6 :         q.query_secdesc.in.file.handle = handle;
    1317           6 :         q.query_secdesc.in.secinfo_flags =
    1318             :                 SECINFO_OWNER |
    1319             :                 SECINFO_GROUP |
    1320             :                 SECINFO_DACL;
    1321           6 :         status = smb2_getinfo_file(tree, tctx, &q);
    1322           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1323             : 
    1324             :         /*
    1325             :          * Testing the created DACL,
    1326             :          * the server should add the inherited DACL
    1327             :          * when SEC_DESC_DACL_PRESENT isn't specified
    1328             :          */
    1329           6 :         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
    1330           0 :                 ret = false;
    1331           0 :                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    1332             :         }
    1333           6 :         if (q.query_secdesc.out.sd->dacl == NULL) {
    1334           0 :                 ret = false;
    1335           0 :                 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
    1336             :         }
    1337             : 
    1338           6 :         torture_comment(tctx, "set NULL DACL\n");
    1339           6 :         sd->type |= SEC_DESC_DACL_PRESENT;
    1340             : 
    1341           6 :         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1342           6 :         s.set_secdesc.in.file.handle = handle;
    1343           6 :         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1344           6 :         s.set_secdesc.in.sd = sd;
    1345           6 :         status = smb2_setinfo_file(tree, &s);
    1346           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1347             : 
    1348           6 :         torture_comment(tctx, "get the sd\n");
    1349           6 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1350           6 :         q.query_secdesc.in.file.handle = handle;
    1351           6 :         q.query_secdesc.in.secinfo_flags =
    1352             :                 SECINFO_OWNER |
    1353             :                 SECINFO_GROUP |
    1354             :                 SECINFO_DACL;
    1355           6 :         status = smb2_getinfo_file(tree, tctx, &q);
    1356           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1357             : 
    1358             :         /* Testing the modified DACL */
    1359           6 :         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
    1360           0 :                 ret = false;
    1361           0 :                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    1362             :         }
    1363           6 :         if (q.query_secdesc.out.sd->dacl != NULL) {
    1364           0 :                 ret = false;
    1365           0 :                 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
    1366             :         }
    1367             : 
    1368           6 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
    1369             : 
    1370           6 :         torture_comment(tctx, "try open for read control\n");
    1371           6 :         io.in.desired_access = SEC_STD_READ_CONTROL;
    1372           6 :         status = smb2_create(tree, tctx, &io);
    1373           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1374           6 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
    1375             :                 SEC_STD_READ_CONTROL);
    1376           6 :         smb2_util_close(tree, io.out.file.handle);
    1377             : 
    1378           6 :         torture_comment(tctx, "try open for write\n");
    1379           6 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1380           6 :         status = smb2_create(tree, tctx, &io);
    1381           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1382           6 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
    1383             :                 SEC_FILE_WRITE_DATA);
    1384           6 :         smb2_util_close(tree, io.out.file.handle);
    1385             : 
    1386           6 :         torture_comment(tctx, "try open for read\n");
    1387           6 :         io.in.desired_access = SEC_FILE_READ_DATA;
    1388           6 :         status = smb2_create(tree, tctx, &io);
    1389           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1390           6 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
    1391             :                 SEC_FILE_READ_DATA);
    1392           6 :         smb2_util_close(tree, io.out.file.handle);
    1393             : 
    1394           6 :         torture_comment(tctx, "try open for generic write\n");
    1395           6 :         io.in.desired_access = SEC_GENERIC_WRITE;
    1396           6 :         status = smb2_create(tree, tctx, &io);
    1397           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1398           6 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
    1399             :                 SEC_RIGHTS_FILE_WRITE);
    1400           6 :         smb2_util_close(tree, io.out.file.handle);
    1401             : 
    1402           6 :         torture_comment(tctx, "try open for generic read\n");
    1403           6 :         io.in.desired_access = SEC_GENERIC_READ;
    1404           6 :         status = smb2_create(tree, tctx, &io);
    1405           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1406           6 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
    1407             :                 SEC_RIGHTS_FILE_READ);
    1408           6 :         smb2_util_close(tree, io.out.file.handle);
    1409             : 
    1410           6 :         torture_comment(tctx, "set DACL with 0 aces\n");
    1411           6 :         ZERO_STRUCT(dacl);
    1412           6 :         dacl.revision = SECURITY_ACL_REVISION_NT4;
    1413           6 :         dacl.num_aces = 0;
    1414           6 :         sd->dacl = &dacl;
    1415             : 
    1416           6 :         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1417           6 :         s.set_secdesc.in.file.handle = handle;
    1418           6 :         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1419           6 :         s.set_secdesc.in.sd = sd;
    1420           6 :         status = smb2_setinfo_file(tree, &s);
    1421           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1422             : 
    1423           6 :         torture_comment(tctx, "get the sd\n");
    1424           6 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1425           6 :         q.query_secdesc.in.file.handle = handle;
    1426           6 :         q.query_secdesc.in.secinfo_flags =
    1427             :                 SECINFO_OWNER |
    1428             :                 SECINFO_GROUP |
    1429             :                 SECINFO_DACL;
    1430           6 :         status = smb2_getinfo_file(tree, tctx, &q);
    1431           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1432             : 
    1433             :         /* Testing the modified DACL */
    1434           6 :         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
    1435           0 :                 ret = false;
    1436           0 :                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    1437             :         }
    1438           6 :         if (q.query_secdesc.out.sd->dacl == NULL) {
    1439           0 :                 ret = false;
    1440           0 :                 torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
    1441             :         }
    1442           6 :         if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
    1443           0 :                 torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
    1444           0 :                        q.query_secdesc.out.sd->dacl->num_aces);
    1445           0 :                 ret = false;
    1446           0 :                 goto done;
    1447             :         }
    1448             : 
    1449           6 :         torture_comment(tctx, "try open for read control\n");
    1450           6 :         io.in.desired_access = SEC_STD_READ_CONTROL;
    1451           6 :         status = smb2_create(tree, tctx, &io);
    1452           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1453           6 :         CHECK_ACCESS_FLAGS(io.out.file.handle,
    1454             :                 SEC_STD_READ_CONTROL);
    1455           6 :         smb2_util_close(tree, io.out.file.handle);
    1456             : 
    1457           6 :         torture_comment(tctx, "try open for write => access_denied\n");
    1458           6 :         io.in.desired_access = SEC_FILE_WRITE_DATA;
    1459           6 :         status = smb2_create(tree, tctx, &io);
    1460           6 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1461           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1462             :         } else {
    1463           6 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1464             :         }
    1465             : 
    1466           6 :         torture_comment(tctx, "try open for read => access_denied\n");
    1467           6 :         io.in.desired_access = SEC_FILE_READ_DATA;
    1468           6 :         status = smb2_create(tree, tctx, &io);
    1469           6 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1470           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1471             :         } else {
    1472           6 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1473             :         }
    1474             : 
    1475           6 :         torture_comment(tctx, "try open for generic write => access_denied\n");
    1476           6 :         io.in.desired_access = SEC_GENERIC_WRITE;
    1477           6 :         status = smb2_create(tree, tctx, &io);
    1478           6 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1479           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1480             :         } else {
    1481           6 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1482             :         }
    1483             : 
    1484           6 :         torture_comment(tctx, "try open for generic read => access_denied\n");
    1485           6 :         io.in.desired_access = SEC_GENERIC_READ;
    1486           6 :         status = smb2_create(tree, tctx, &io);
    1487           6 :         if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
    1488           0 :                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1489             :         } else {
    1490           6 :                 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    1491             :         }
    1492             : 
    1493           6 :         torture_comment(tctx, "set empty sd\n");
    1494           6 :         sd->type &= ~SEC_DESC_DACL_PRESENT;
    1495           6 :         sd->dacl = NULL;
    1496             : 
    1497           6 :         s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    1498           6 :         s.set_secdesc.in.file.handle = handle;
    1499           6 :         s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    1500           6 :         s.set_secdesc.in.sd = sd;
    1501           6 :         status = smb2_setinfo_file(tree, &s);
    1502           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1503             : 
    1504           6 :         torture_comment(tctx, "get the sd\n");
    1505           6 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    1506           6 :         q.query_secdesc.in.file.handle = handle;
    1507           6 :         q.query_secdesc.in.secinfo_flags =
    1508             :                 SECINFO_OWNER |
    1509             :                 SECINFO_GROUP |
    1510             :                 SECINFO_DACL;
    1511           6 :         status = smb2_getinfo_file(tree, tctx, &q);
    1512           6 :         CHECK_STATUS(status, NT_STATUS_OK);
    1513             : 
    1514             :         /* Testing the modified DACL */
    1515           6 :         if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
    1516           0 :                 ret = false;
    1517           0 :                 torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    1518             :         }
    1519           6 :         if (q.query_secdesc.out.sd->dacl != NULL) {
    1520           0 :                 ret = false;
    1521           0 :                 torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
    1522             :         }
    1523          12 : done:
    1524           6 :         smb2_util_close(tree, handle);
    1525           6 :         smb2_util_unlink(tree, fname);
    1526           6 :         smb2_tdis(tree);
    1527           6 :         smb2_logoff(tree->session);
    1528           6 :         return ret;
    1529             : }
    1530             : 
    1531             : /*
    1532             :   test SMB2 mkdir with OPEN_IF on the same name twice.
    1533             :   Must use 2 connections to hit the race.
    1534             : */
    1535             : 
    1536           6 : static bool test_mkdir_dup(struct torture_context *tctx,
    1537             :                                 struct smb2_tree *tree)
    1538             : {
    1539           6 :         const char *fname = "mkdir_dup";
    1540             :         NTSTATUS status;
    1541           6 :         bool ret = true;
    1542             :         union smb_open io;
    1543             :         struct smb2_tree **trees;
    1544             :         struct smb2_request **requests;
    1545             :         union smb_open *ios;
    1546           6 :         int i, num_files = 2;
    1547           6 :         int num_ok = 0;
    1548           6 :         int num_created = 0;
    1549           6 :         int num_existed = 0;
    1550             : 
    1551           6 :         torture_comment(tctx,
    1552             :                 "Testing SMB2 Create Directory with multiple connections\n");
    1553           6 :         trees = talloc_array(tctx, struct smb2_tree *, num_files);
    1554           6 :         requests = talloc_array(tctx, struct smb2_request *, num_files);
    1555           6 :         ios = talloc_array(tctx, union smb_open, num_files);
    1556           6 :         if ((tctx->ev == NULL) || (trees == NULL) || (requests == NULL) ||
    1557             :             (ios == NULL)) {
    1558           0 :                 torture_fail(tctx, ("talloc failed\n"));
    1559             :                 ret = false;
    1560             :                 goto done;
    1561             :         }
    1562             : 
    1563           6 :         tree->session->transport->options.request_timeout = 60;
    1564             : 
    1565          18 :         for (i=0; i<num_files; i++) {
    1566          12 :                 if (!torture_smb2_connection(tctx, &(trees[i]))) {
    1567           0 :                         torture_fail(tctx,
    1568             :                                 talloc_asprintf(tctx,
    1569             :                                         "Could not open %d'th connection\n", i));
    1570             :                         ret = false;
    1571             :                         goto done;
    1572             :                 }
    1573          12 :                 trees[i]->session->transport->options.request_timeout = 60;
    1574             :         }
    1575             : 
    1576             :         /* cleanup */
    1577           6 :         smb2_util_unlink(tree, fname);
    1578           6 :         smb2_util_rmdir(tree, fname);
    1579             : 
    1580             :         /*
    1581             :           base ntcreatex parms
    1582             :         */
    1583           6 :         ZERO_STRUCT(io.smb2);
    1584           6 :         io.generic.level = RAW_OPEN_SMB2;
    1585           6 :         io.smb2.in.desired_access = SEC_RIGHTS_FILE_ALL;
    1586           6 :         io.smb2.in.alloc_size = 0;
    1587           6 :         io.smb2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    1588           6 :         io.smb2.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1589             :                 NTCREATEX_SHARE_ACCESS_WRITE|
    1590             :                 NTCREATEX_SHARE_ACCESS_DELETE;
    1591           6 :         io.smb2.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
    1592           6 :         io.smb2.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1593           6 :         io.smb2.in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS;
    1594           6 :         io.smb2.in.security_flags = 0;
    1595           6 :         io.smb2.in.fname = fname;
    1596           6 :         io.smb2.in.create_flags = 0;
    1597             : 
    1598          18 :         for (i=0; i<num_files; i++) {
    1599          12 :                 ios[i] = io;
    1600          12 :                 requests[i] = smb2_create_send(trees[i], &(ios[i].smb2));
    1601          12 :                 if (requests[i] == NULL) {
    1602           0 :                         torture_fail(tctx,
    1603             :                                 talloc_asprintf(tctx,
    1604             :                                 "could not send %d'th request\n", i));
    1605             :                         ret = false;
    1606             :                         goto done;
    1607             :                 }
    1608             :         }
    1609             : 
    1610           6 :         torture_comment(tctx, "waiting for replies\n");
    1611          48 :         while (1) {
    1612          54 :                 bool unreplied = false;
    1613          81 :                 for (i=0; i<num_files; i++) {
    1614          75 :                         if (requests[i] == NULL) {
    1615          15 :                                 continue;
    1616             :                         }
    1617          60 :                         if (requests[i]->state < SMB2_REQUEST_DONE) {
    1618          48 :                                 unreplied = true;
    1619          48 :                                 break;
    1620             :                         }
    1621          12 :                         status = smb2_create_recv(requests[i], tctx,
    1622          12 :                                                   &(ios[i].smb2));
    1623             : 
    1624          12 :                         if (NT_STATUS_IS_OK(status)) {
    1625          12 :                                 num_ok += 1;
    1626             : 
    1627          12 :                                 if (ios[i].smb2.out.create_action ==
    1628             :                                                 NTCREATEX_ACTION_CREATED) {
    1629           6 :                                         num_created++;
    1630             :                                 }
    1631          12 :                                 if (ios[i].smb2.out.create_action ==
    1632             :                                                 NTCREATEX_ACTION_EXISTED) {
    1633           6 :                                         num_existed++;
    1634             :                                 }
    1635             :                         } else {
    1636           0 :                                 torture_fail(tctx,
    1637             :                                         talloc_asprintf(tctx,
    1638             :                                         "File %d returned status %s\n", i,
    1639             :                                         nt_errstr(status)));
    1640             :                         }
    1641             : 
    1642             : 
    1643          12 :                         requests[i] = NULL;
    1644             :                 }
    1645          54 :                 if (!unreplied) {
    1646           6 :                         break;
    1647             :                 }
    1648             : 
    1649          48 :                 if (tevent_loop_once(tctx->ev) != 0) {
    1650           0 :                         torture_fail(tctx, "tevent_loop_once failed\n");
    1651             :                         ret = false;
    1652             :                         goto done;
    1653             :                 }
    1654             :         }
    1655             : 
    1656           6 :         if (num_ok != 2) {
    1657           0 :                 torture_fail(tctx,
    1658             :                         talloc_asprintf(tctx,
    1659             :                         "num_ok == %d\n", num_ok));
    1660             :                 ret = false;
    1661             :         }
    1662           6 :         if (num_created != 1) {
    1663           0 :                 torture_fail(tctx,
    1664             :                         talloc_asprintf(tctx,
    1665             :                         "num_created == %d\n", num_created));
    1666             :                 ret = false;
    1667             :         }
    1668           6 :         if (num_existed != 1) {
    1669           0 :                 torture_fail(tctx,
    1670             :                         talloc_asprintf(tctx,
    1671             :                         "num_existed == %d\n", num_existed));
    1672             :                 ret = false;
    1673             :         }
    1674           6 : done:
    1675           6 :         smb2_deltree(tree, fname);
    1676             : 
    1677           6 :         return ret;
    1678             : }
    1679             : 
    1680             : /*
    1681             :   test directory creation with an initial allocation size > 0
    1682             : */
    1683           6 : static bool test_dir_alloc_size(struct torture_context *tctx,
    1684             :                                 struct smb2_tree *tree)
    1685             : {
    1686           6 :         bool ret = true;
    1687           6 :         const char *dname = DNAME "\\torture_alloc_size.dir";
    1688             :         NTSTATUS status;
    1689             :         struct smb2_create c;
    1690           6 :         struct smb2_handle h1 = {{0}}, h2;
    1691             : 
    1692           6 :         torture_comment(tctx, "Checking initial allocation size on directories\n");
    1693             : 
    1694           6 :         smb2_deltree(tree, dname);
    1695             : 
    1696           6 :         status = torture_smb2_testdir(tree, DNAME, &h1);
    1697           6 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
    1698             : 
    1699           6 :         ZERO_STRUCT(c);
    1700           6 :         c.in.create_disposition = NTCREATEX_DISP_CREATE;
    1701           6 :         c.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
    1702           6 :         c.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
    1703           6 :         c.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1704           6 :         c.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1705           6 :         c.in.fname = dname;
    1706             :         /*
    1707             :          * An insanely large value so we can check the value is
    1708             :          * ignored: Samba either returns 0 (current behaviour), or,
    1709             :          * once vfswrap_get_alloc_size() is fixed to allow retrieving
    1710             :          * the allocated size for directories, returns
    1711             :          * smb_roundup(..., stat.st_size) which would be 1 MB by
    1712             :          * default.
    1713             :          *
    1714             :          * Windows returns 0 for empty directories, once directories
    1715             :          * have a few entries it starts replying with values > 0.
    1716             :          */
    1717           6 :         c.in.alloc_size = 1024*1024*1024;
    1718             : 
    1719           6 :         status = smb2_create(tree, tctx, &c);
    1720           6 :         h2 = c.out.file.handle;
    1721           6 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    1722             :                                         "dir create with initial alloc size failed");
    1723             : 
    1724           6 :         smb2_util_close(tree, h2);
    1725             : 
    1726           6 :         torture_comment(tctx, "Got directory alloc size: %ju\n", (uintmax_t)c.out.alloc_size);
    1727             : 
    1728             :         /*
    1729             :          * See above for the rational for this test
    1730             :          */
    1731           6 :         if (c.out.alloc_size > 1024*1024) {
    1732           0 :                 torture_fail_goto(tctx, done, talloc_asprintf(tctx, "bad alloc size: %ju",
    1733             :                                                               (uintmax_t)c.out.alloc_size));
    1734             :         }
    1735             : 
    1736          12 : done:
    1737           6 :         if (!smb2_util_handle_empty(h1)) {
    1738           6 :                 smb2_util_close(tree, h1);
    1739             :         }
    1740           6 :         smb2_deltree(tree, DNAME);
    1741           6 :         return ret;
    1742             : }
    1743             : 
    1744           7 : static bool test_twrp_write(struct torture_context *tctx, struct smb2_tree *tree)
    1745             : {
    1746             :         struct smb2_create io;
    1747           7 :         struct smb2_handle h1 = {{0}};
    1748             :         NTSTATUS status;
    1749           7 :         bool ret = true;
    1750           7 :         char *p = NULL;
    1751             :         struct tm tm;
    1752             :         time_t t;
    1753             :         uint64_t nttime;
    1754           7 :         const char *file = NULL;
    1755           7 :         const char *snapshot = NULL;
    1756             : 
    1757           7 :         file = torture_setting_string(tctx, "twrp_file", NULL);
    1758           7 :         if (file == NULL) {
    1759           5 :                 torture_skip(tctx, "missing 'twrp_file' option\n");
    1760             :         }
    1761             : 
    1762           2 :         snapshot = torture_setting_string(tctx, "twrp_snapshot", NULL);
    1763           2 :         if (snapshot == NULL) {
    1764           0 :                 torture_skip(tctx, "missing 'twrp_snapshot' option\n");
    1765             :         }
    1766             : 
    1767           2 :         torture_comment(tctx, "Testing timewarp (%s) (%s)\n", file, snapshot);
    1768             : 
    1769           2 :         setenv("TZ", "GMT", 1);
    1770             : 
    1771             :         /* strptime does not set tm.tm_isdst but mktime assumes DST is in
    1772             :          * effect if it is greather than 1. */
    1773           2 :         ZERO_STRUCT(tm);
    1774             : 
    1775           2 :         p = strptime(snapshot, "@GMT-%Y.%m.%d-%H.%M.%S", &tm);
    1776           2 :         torture_assert_goto(tctx, p != NULL, ret, done, "strptime\n");
    1777           2 :         torture_assert_goto(tctx, *p == '\0', ret, done, "strptime\n");
    1778             : 
    1779           2 :         t = mktime(&tm);
    1780           2 :         unix_to_nt_time(&nttime, t);
    1781             : 
    1782           2 :         io = (struct smb2_create) {
    1783             :                 .in.desired_access = SEC_FILE_READ_DATA,
    1784             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    1785             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    1786             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    1787             :                 .in.fname = file,
    1788             :                 .in.query_maximal_access = true,
    1789             :                 .in.timewarp = nttime,
    1790             :         };
    1791             : 
    1792           2 :         status = smb2_create(tree, tctx, &io);
    1793           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    1794             :                                         "smb2_create\n");
    1795           2 :         smb2_util_close(tree, io.out.file.handle);
    1796             : 
    1797           2 :         ret = io.out.maximal_access & (SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA);
    1798           2 :         torture_assert_goto(tctx, ret, ret, done, "Bad access\n");
    1799             : 
    1800           2 :         io = (struct smb2_create) {
    1801             :                 .in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA,
    1802             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    1803             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    1804             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    1805             :                 .in.fname = file,
    1806             :                 .in.timewarp = nttime,
    1807             :         };
    1808             : 
    1809           2 :         status = smb2_create(tree, tctx, &io);
    1810           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    1811             :                                         "smb2_create\n");
    1812           2 :         h1 = io.out.file.handle;
    1813             : 
    1814           2 :         status = smb2_util_write(tree, h1, "123", 0, 3);
    1815           2 :         torture_assert_ntstatus_equal_goto(tctx, status,
    1816             :                                            NT_STATUS_MEDIA_WRITE_PROTECTED,
    1817             :                                            ret, done, "smb2_create\n");
    1818             : 
    1819           2 :         smb2_util_close(tree, h1);
    1820             : 
    1821           2 : done:
    1822           2 :         return ret;
    1823             : }
    1824             : 
    1825           7 : static bool test_twrp_stream(struct torture_context *tctx,
    1826             :                              struct smb2_tree *tree)
    1827             : {
    1828             :         struct smb2_create io;
    1829             :         NTSTATUS status;
    1830           7 :         bool ret = true;
    1831           7 :         char *p = NULL;
    1832             :         struct tm tm;
    1833             :         time_t t;
    1834             :         uint64_t nttime;
    1835           7 :         const char *file = NULL;
    1836           7 :         const char *stream = NULL;
    1837           7 :         const char *snapshot = NULL;
    1838             :         int stream_size;
    1839           7 :         char *path = NULL;
    1840           7 :         uint8_t *buf = NULL;
    1841           7 :         struct smb2_handle h1 = {{0}};
    1842             :         struct smb2_read r;
    1843             : 
    1844           7 :         file = torture_setting_string(tctx, "twrp_file", NULL);
    1845           7 :         if (file == NULL) {
    1846           5 :                 torture_skip(tctx, "missing 'twrp_file' option\n");
    1847             :         }
    1848             : 
    1849           2 :         stream = torture_setting_string(tctx, "twrp_stream", NULL);
    1850           2 :         if (stream == NULL) {
    1851           0 :                 torture_skip(tctx, "missing 'twrp_stream' option\n");
    1852             :         }
    1853             : 
    1854           2 :         snapshot = torture_setting_string(tctx, "twrp_snapshot", NULL);
    1855           2 :         if (snapshot == NULL) {
    1856           0 :                 torture_skip(tctx, "missing 'twrp_snapshot' option\n");
    1857             :         }
    1858             : 
    1859           2 :         stream_size = torture_setting_int(tctx, "twrp_stream_size", 0);
    1860           2 :         if (stream_size == 0) {
    1861           0 :                 torture_skip(tctx, "missing 'twrp_stream_size' option\n");
    1862             :         }
    1863             : 
    1864           2 :         torture_comment(tctx, "Testing timewarp on stream (%s) (%s)\n",
    1865             :                         file, snapshot);
    1866             : 
    1867           2 :         path = talloc_asprintf(tree, "%s:%s", file, stream);
    1868           2 :         torture_assert_not_null_goto(tctx, path, ret, done, "path\n");
    1869             : 
    1870           2 :         buf = talloc_zero_array(tree, uint8_t, stream_size);
    1871           2 :         torture_assert_not_null_goto(tctx, buf, ret, done, "buf\n");
    1872             : 
    1873           2 :         setenv("TZ", "GMT", 1);
    1874             : 
    1875             :         /* strptime does not set tm.tm_isdst but mktime assumes DST is in
    1876             :          * effect if it is greather than 1. */
    1877           2 :         ZERO_STRUCT(tm);
    1878             : 
    1879           2 :         p = strptime(snapshot, "@GMT-%Y.%m.%d-%H.%M.%S", &tm);
    1880           2 :         torture_assert_goto(tctx, p != NULL, ret, done, "strptime\n");
    1881           2 :         torture_assert_goto(tctx, *p == '\0', ret, done, "strptime\n");
    1882             : 
    1883           2 :         t = mktime(&tm);
    1884           2 :         unix_to_nt_time(&nttime, t);
    1885             : 
    1886           2 :         io = (struct smb2_create) {
    1887             :                 .in.desired_access = SEC_FILE_READ_DATA,
    1888             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    1889             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    1890             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    1891             :                 .in.fname = path,
    1892             :                 .in.timewarp = nttime,
    1893             :         };
    1894             : 
    1895           2 :         status = smb2_create(tree, tctx, &io);
    1896           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    1897             :                                         "smb2_create\n");
    1898           2 :         h1 = io.out.file.handle;
    1899             : 
    1900           2 :         r = (struct smb2_read) {
    1901             :                 .in.file.handle = h1,
    1902             :                 .in.length = stream_size,
    1903             :                 .in.offset = 0,
    1904             :         };
    1905             : 
    1906           2 :         status = smb2_read(tree, tree, &r);
    1907           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    1908             :                                         "smb2_create\n");
    1909             : 
    1910           2 :         smb2_util_close(tree, h1);
    1911             : 
    1912           2 : done:
    1913           2 :         return ret;
    1914             : }
    1915             : 
    1916           7 : static bool test_twrp_openroot(struct torture_context *tctx, struct smb2_tree *tree)
    1917             : {
    1918             :         struct smb2_create io;
    1919             :         NTSTATUS status;
    1920           7 :         bool ret = true;
    1921           7 :         char *p = NULL;
    1922             :         struct tm tm;
    1923             :         time_t t;
    1924             :         uint64_t nttime;
    1925           7 :         const char *snapshot = NULL;
    1926             : 
    1927           7 :         snapshot = torture_setting_string(tctx, "twrp_snapshot", NULL);
    1928           7 :         if (snapshot == NULL) {
    1929           5 :                 torture_skip(tctx, "missing 'twrp_snapshot' option\n");
    1930             :         }
    1931             : 
    1932           2 :         torture_comment(tctx, "Testing open of root of "
    1933             :                 "share with timewarp (%s)\n",
    1934             :                 snapshot);
    1935             : 
    1936           2 :         setenv("TZ", "GMT", 1);
    1937             : 
    1938             :         /* strptime does not set tm.tm_isdst but mktime assumes DST is in
    1939             :          * effect if it is greather than 1. */
    1940           2 :         ZERO_STRUCT(tm);
    1941             : 
    1942           2 :         p = strptime(snapshot, "@GMT-%Y.%m.%d-%H.%M.%S", &tm);
    1943           2 :         torture_assert_goto(tctx, p != NULL, ret, done, "strptime\n");
    1944           2 :         torture_assert_goto(tctx, *p == '\0', ret, done, "strptime\n");
    1945             : 
    1946           2 :         t = mktime(&tm);
    1947           2 :         unix_to_nt_time(&nttime, t);
    1948             : 
    1949           2 :         io = (struct smb2_create) {
    1950             :                 .in.desired_access = SEC_FILE_READ_DATA,
    1951             :                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
    1952             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    1953             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    1954             :                 .in.fname = "",
    1955             :                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
    1956             :                 .in.timewarp = nttime,
    1957             :         };
    1958             : 
    1959           2 :         status = smb2_create(tree, tctx, &io);
    1960           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    1961             :                                         "smb2_create\n");
    1962           2 :         smb2_util_close(tree, io.out.file.handle);
    1963             : 
    1964           2 : done:
    1965           2 :         return ret;
    1966             : }
    1967             : 
    1968           2 : static bool test_fileid(struct torture_context *tctx,
    1969             :                         struct smb2_tree *tree)
    1970             : {
    1971           2 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    1972           2 :         const char *fname = DNAME "\\foo";
    1973           2 :         const char *sname = DNAME "\\foo:bar";
    1974             :         struct smb2_handle testdirh;
    1975             :         struct smb2_handle h1;
    1976             :         struct smb2_create create;
    1977             :         union smb_fileinfo finfo;
    1978             :         union smb_setfileinfo sinfo;
    1979             :         struct smb2_find f;
    1980             :         unsigned int count;
    1981             :         union smb_search_data *d;
    1982             :         uint64_t expected_fileid;
    1983             :         uint64_t returned_fileid;
    1984             :         NTSTATUS status;
    1985           2 :         bool ret = true;
    1986             : 
    1987           2 :         smb2_deltree(tree, DNAME);
    1988             : 
    1989           2 :         status = torture_smb2_testdir(tree, DNAME, &testdirh);
    1990           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    1991             :                                         "torture_smb2_testdir failed\n");
    1992             : 
    1993             :         /*
    1994             :          * Initial create with QFID
    1995             :          */
    1996           2 :         create = (struct smb2_create) {
    1997             :                 .in.desired_access = SEC_FILE_ALL,
    1998             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    1999             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2000             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2001             :                 .in.fname = fname,
    2002             :                 .in.query_on_disk_id = true,
    2003             :         };
    2004             : 
    2005           2 :         status = smb2_create(tree, tctx, &create);
    2006           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2007             :                                         "test file could not be created\n");
    2008           2 :         h1 = create.out.file.handle;
    2009           2 :         expected_fileid = BVAL(&create.out.on_disk_id, 0);
    2010             : 
    2011             :         /*
    2012             :          * Getinfo the File-ID on the just opened handle
    2013             :          */
    2014           2 :         finfo = (union smb_fileinfo) {
    2015             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2016             :                 .generic.in.file.handle = h1,
    2017             :         };
    2018             : 
    2019           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2020           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2021             :                                         "torture_smb2_testdir\n");
    2022           2 :         smb2_util_close(tree, h1);
    2023           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2024             :                                       expected_fileid,
    2025             :                                       ret, done, "bad fileid\n");
    2026             : 
    2027             :         /*
    2028             :          * Open existing with QFID
    2029             :          */
    2030           2 :         create = (struct smb2_create) {
    2031             :                 .in.desired_access = SEC_FILE_ALL,
    2032             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2033             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2034             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2035             :                 .in.fname = fname,
    2036             :                 .in.query_on_disk_id = true,
    2037             :         };
    2038             : 
    2039           2 :         status = smb2_create(tree, tctx, &create);
    2040           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2041             :                                         "test file could not be created\n");
    2042           2 :         h1 = create.out.file.handle;
    2043           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2044           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2045             :                                       ret, done, "bad fileid\n");
    2046             : 
    2047             :         /*
    2048             :          * Getinfo the File-ID on the just opened handle
    2049             :          */
    2050           2 :         finfo = (union smb_fileinfo) {
    2051             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2052             :                 .generic.in.file.handle = h1,
    2053             :         };
    2054             : 
    2055           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2056           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2057             :                                         "torture_smb2_testdir\n");
    2058           2 :         smb2_util_close(tree, h1);
    2059           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2060             :                                       expected_fileid,
    2061             :                                       ret, done, "bad fileid\n");
    2062             : 
    2063             :         /*
    2064             :          * Overwrite with QFID
    2065             :          */
    2066           2 :         create = (struct smb2_create) {
    2067             :                 .in.desired_access = SEC_FILE_ALL,
    2068             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2069             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2070             :                 .in.create_disposition = NTCREATEX_DISP_OVERWRITE,
    2071             :                 .in.fname = fname,
    2072             :                 .in.query_on_disk_id = true,
    2073             :         };
    2074             : 
    2075           2 :         status = smb2_create(tree, tctx, &create);
    2076           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2077             :                                         "test file could not be created\n");
    2078           2 :         h1 = create.out.file.handle;
    2079           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2080           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2081             :                                       ret, done, "bad fileid\n");
    2082             : 
    2083             :         /*
    2084             :          * Getinfo the File-ID on the open with overwrite handle
    2085             :          */
    2086           2 :         finfo = (union smb_fileinfo) {
    2087             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2088             :                 .generic.in.file.handle = h1,
    2089             :         };
    2090             : 
    2091           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2092           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2093             :                                         "torture_smb2_testdir\n");
    2094           2 :         smb2_util_close(tree, h1);
    2095           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2096             :                                       expected_fileid,
    2097             :                                       ret, done, "bad fileid\n");
    2098             : 
    2099             :         /*
    2100             :          * Do some modifications on the basefile (IO, setinfo), verifying
    2101             :          * File-ID after each step.
    2102             :          */
    2103           2 :         create = (struct smb2_create) {
    2104             :                 .in.desired_access = SEC_FILE_ALL,
    2105             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2106             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2107             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2108             :                 .in.fname = fname,
    2109             :                 .in.query_on_disk_id = true,
    2110             :         };
    2111             : 
    2112           2 :         status = smb2_create(tree, tctx, &create);
    2113           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2114             :                                         "test file could not be created\n");
    2115           2 :         h1 = create.out.file.handle;
    2116             : 
    2117           2 :         status = smb2_util_write(tree, h1, "foo", 0, strlen("foo"));
    2118           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2119             :                                         "smb2_util_write failed\n");
    2120             : 
    2121           2 :         finfo = (union smb_fileinfo) {
    2122             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2123             :                 .generic.in.file.handle = h1,
    2124             :         };
    2125           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2126           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2127             :                                         "smb2_getinfo_file failed\n");
    2128           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2129             :                                       expected_fileid,
    2130             :                                       ret, done, "bad fileid\n");
    2131             : 
    2132           2 :         sinfo = (union smb_setfileinfo) {
    2133             :                 .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION,
    2134             :                 .basic_info.in.file.handle = h1,
    2135             :         };
    2136           2 :         unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL));
    2137             : 
    2138           2 :         status = smb2_setinfo_file(tree, &sinfo);
    2139           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2140             :                                         "smb2_setinfo_file failed\n");
    2141             : 
    2142           2 :         finfo = (union smb_fileinfo) {
    2143             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2144             :                 .generic.in.file.handle = h1,
    2145             :         };
    2146           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2147           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2148             :                                         "smb2_getinfo_file failed\n");
    2149           2 :         smb2_util_close(tree, h1);
    2150           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2151             :                                       expected_fileid,
    2152             :                                       ret, done, "bad fileid\n");
    2153             : 
    2154             :         /*
    2155             :          * Create stream, check the stream's File-ID, should be the same as the
    2156             :          * base file (sic!, tested against Windows).
    2157             :          */
    2158           2 :         create = (struct smb2_create) {
    2159             :                 .in.desired_access = SEC_FILE_ALL,
    2160             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2161             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2162             :                 .in.create_disposition = NTCREATEX_DISP_CREATE,
    2163             :                 .in.fname = sname,
    2164             :                 .in.query_on_disk_id = true,
    2165             :         };
    2166             : 
    2167           2 :         status = smb2_create(tree, tctx, &create);
    2168           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2169             :                                         "test file could not be created\n");
    2170           2 :         h1 = create.out.file.handle;
    2171           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2172           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2173             :                                       ret, done, "bad fileid\n");
    2174             : 
    2175             :         /*
    2176             :          * Getinfo the File-ID on the created stream
    2177             :          */
    2178           2 :         finfo = (union smb_fileinfo) {
    2179             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2180             :                 .generic.in.file.handle = h1,
    2181             :         };
    2182             : 
    2183           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2184           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2185             :                                         "smb2_getinfo_file failed\n");
    2186           2 :         smb2_util_close(tree, h1);
    2187           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2188             :                                       expected_fileid,
    2189             :                                       ret, done, "bad fileid\n");
    2190             : 
    2191             :         /*
    2192             :          * Open stream, check the stream's File-ID, should be the same as the
    2193             :          * base file (sic!, tested against Windows).
    2194             :          */
    2195           2 :         create = (struct smb2_create) {
    2196             :                 .in.desired_access = SEC_FILE_ALL,
    2197             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2198             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2199             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2200             :                 .in.fname = sname,
    2201             :                 .in.query_on_disk_id = true,
    2202             :         };
    2203             : 
    2204           2 :         status = smb2_create(tree, tctx, &create);
    2205           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2206             :                                         "test file could not be created\n");
    2207           2 :         h1 = create.out.file.handle;
    2208           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2209           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2210             :                                       ret, done, "bad fileid\n");
    2211             : 
    2212             :         /*
    2213             :          * Getinfo the File-ID on the opened stream
    2214             :          */
    2215           2 :         finfo = (union smb_fileinfo) {
    2216             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2217             :                 .generic.in.file.handle = h1,
    2218             :         };
    2219             : 
    2220           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2221           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2222             :                                         "smb2_getinfo_file failed\n");
    2223           2 :         smb2_util_close(tree, h1);
    2224           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2225             :                                       expected_fileid,
    2226             :                                       ret, done, "bad fileid\n");
    2227             : 
    2228             :         /*
    2229             :          * Overwrite stream, check the stream's File-ID, should be the same as
    2230             :          * the base file (sic!, tested against Windows).
    2231             :          */
    2232           2 :         create = (struct smb2_create) {
    2233             :                 .in.desired_access = SEC_FILE_ALL,
    2234             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2235             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2236             :                 .in.create_disposition = NTCREATEX_DISP_OVERWRITE,
    2237             :                 .in.fname = sname,
    2238             :                 .in.query_on_disk_id = true,
    2239             :         };
    2240             : 
    2241           2 :         status = smb2_create(tree, tctx, &create);
    2242           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2243             :                                         "test file could not be created\n");
    2244           2 :         h1 = create.out.file.handle;
    2245           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2246           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2247             :                                       ret, done, "bad fileid\n");
    2248             : 
    2249             :         /*
    2250             :          * Getinfo the File-ID on the overwritten stream
    2251             :          */
    2252           2 :         finfo = (union smb_fileinfo) {
    2253             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2254             :                 .generic.in.file.handle = h1,
    2255             :         };
    2256             : 
    2257           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2258           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2259             :                                         "smb2_getinfo_file failed\n");
    2260           2 :         smb2_util_close(tree, h1);
    2261           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2262             :                                       expected_fileid,
    2263             :                                       ret, done, "bad fileid\n");
    2264             : 
    2265             :         /*
    2266             :          * Do some modifications on the stream (IO, setinfo), verifying File-ID
    2267             :          * after earch step.
    2268             :          */
    2269           2 :         create = (struct smb2_create) {
    2270             :                 .in.desired_access = SEC_FILE_ALL,
    2271             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2272             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2273             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2274             :                 .in.fname = sname,
    2275             :                 .in.query_on_disk_id = true,
    2276             :         };
    2277             : 
    2278           2 :         status = smb2_create(tree, tctx, &create);
    2279           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2280             :                                         "test file could not be created\n");
    2281           2 :         h1 = create.out.file.handle;
    2282             : 
    2283           2 :         status = smb2_util_write(tree, h1, "foo", 0, strlen("foo"));
    2284           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2285             :                                         "smb2_util_write failed\n");
    2286             : 
    2287           2 :         finfo = (union smb_fileinfo) {
    2288             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2289             :                 .generic.in.file.handle = h1,
    2290             :         };
    2291           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2292           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2293             :                                         "smb2_getinfo_file failed\n");
    2294           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2295             :                                       expected_fileid,
    2296             :                                       ret, done, "bad fileid\n");
    2297             : 
    2298           2 :         sinfo = (union smb_setfileinfo) {
    2299             :                 .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION,
    2300             :                 .basic_info.in.file.handle = h1,
    2301             :         };
    2302           2 :         unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL));
    2303             : 
    2304           2 :         status = smb2_setinfo_file(tree, &sinfo);
    2305           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2306             :                                         "smb2_setinfo_file failed\n");
    2307             : 
    2308           2 :         finfo = (union smb_fileinfo) {
    2309             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2310             :                 .generic.in.file.handle = h1,
    2311             :         };
    2312           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2313           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2314             :                                         "smb2_getinfo_file failed\n");
    2315           2 :         smb2_util_close(tree, h1);
    2316           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2317             :                                       expected_fileid,
    2318             :                                       ret, done, "bad fileid\n");
    2319             : 
    2320             :         /*
    2321             :          * Final open of the basefile with QFID
    2322             :          */
    2323           2 :         create = (struct smb2_create) {
    2324             :                 .in.desired_access = SEC_FILE_ALL,
    2325             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2326             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2327             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2328             :                 .in.fname = fname,
    2329             :                 .in.query_on_disk_id = true,
    2330             :         };
    2331             : 
    2332           2 :         status = smb2_create(tree, tctx, &create);
    2333           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2334             :                                         "test file could not be created\n");
    2335           2 :         h1 = create.out.file.handle;
    2336           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2337           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2338             :                                       ret, done, "bad fileid\n");
    2339             : 
    2340             :         /*
    2341             :          * Final Getinfo checking File-ID
    2342             :          */
    2343           2 :         finfo = (union smb_fileinfo) {
    2344             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2345             :                 .generic.in.file.handle = h1,
    2346             :         };
    2347             : 
    2348           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2349           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2350             :                                         "torture_smb2_testdir\n");
    2351           2 :         smb2_util_close(tree, h1);
    2352           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2353             :                                       expected_fileid,
    2354             :                                       ret, done, "bad fileid\n");
    2355             : 
    2356             :         /*
    2357             :          * Final list directory, verifying the operations on basefile and stream
    2358             :          * didn't modify the base file metadata.
    2359             :          */
    2360           2 :         f = (struct smb2_find) {
    2361             :                 .in.file.handle = testdirh,
    2362             :                 .in.pattern = "foo",
    2363             :                 .in.max_response_size = 0x1000,
    2364             :                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
    2365             :                 .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART,
    2366             :         };
    2367             : 
    2368           2 :         status = smb2_find_level(tree, tree, &f, &count, &d);
    2369           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2370             :                                         "smb2_find_level failed\n");
    2371           2 :         torture_assert_u64_equal_goto(tctx,
    2372             :                                       d->id_both_directory_info.file_id,
    2373             :                                       expected_fileid,
    2374             :                                       ret, done, "bad fileid\n");
    2375             : 
    2376           4 : done:
    2377           2 :         smb2_util_close(tree, testdirh);
    2378           2 :         smb2_deltree(tree, DNAME);
    2379           2 :         talloc_free(mem_ctx);
    2380           2 :         return ret;
    2381             : }
    2382             : 
    2383           2 : static bool test_fileid_dir(struct torture_context *tctx,
    2384             :                             struct smb2_tree *tree)
    2385             : {
    2386           2 :         TALLOC_CTX *mem_ctx = talloc_new(tctx);
    2387           2 :         const char *dname = DNAME "\\foo";
    2388           2 :         const char *sname = DNAME "\\foo:bar";
    2389             :         struct smb2_handle testdirh;
    2390             :         struct smb2_handle h1;
    2391             :         struct smb2_create create;
    2392             :         union smb_fileinfo finfo;
    2393             :         union smb_setfileinfo sinfo;
    2394             :         struct smb2_find f;
    2395             :         unsigned int count;
    2396             :         union smb_search_data *d;
    2397             :         uint64_t expected_fileid;
    2398             :         uint64_t returned_fileid;
    2399             :         NTSTATUS status;
    2400           2 :         bool ret = true;
    2401             : 
    2402           2 :         smb2_deltree(tree, DNAME);
    2403             : 
    2404           2 :         status = torture_smb2_testdir(tree, DNAME, &testdirh);
    2405           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2406             :                                         "torture_smb2_testdir failed\n");
    2407             : 
    2408             :         /*
    2409             :          * Initial directory create with QFID
    2410             :          */
    2411           2 :         create = (struct smb2_create) {
    2412             :                 .in.desired_access = SEC_FILE_ALL,
    2413             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2414             :                 .in.create_disposition = NTCREATEX_DISP_OPEN_IF,
    2415             :                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
    2416             :                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
    2417             :                 .in.fname = dname,
    2418             :                 .in.query_on_disk_id = true,
    2419             :         };
    2420             : 
    2421           2 :         status = smb2_create(tree, tctx, &create);
    2422           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2423             :                                         "test file could not be created\n");
    2424           2 :         h1 = create.out.file.handle;
    2425           2 :         expected_fileid = BVAL(&create.out.on_disk_id, 0);
    2426             : 
    2427             :         /*
    2428             :          * Getinfo the File-ID on the just opened handle
    2429             :          */
    2430           2 :         finfo = (union smb_fileinfo) {
    2431             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2432             :                 .generic.in.file.handle = h1,
    2433             :         };
    2434             : 
    2435           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2436           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2437             :                                         "torture_smb2_testdir\n");
    2438           2 :         smb2_util_close(tree, h1);
    2439           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2440             :                                       expected_fileid,
    2441             :                                       ret, done, "bad fileid\n");
    2442             : 
    2443             :         /*
    2444             :          * Open existing directory with QFID
    2445             :          */
    2446           2 :         create = (struct smb2_create) {
    2447             :                 .in.desired_access = SEC_FILE_ALL,
    2448             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2449             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2450             :                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
    2451             :                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
    2452             :                 .in.fname = dname,
    2453             :                 .in.query_on_disk_id = true,
    2454             :         };
    2455             : 
    2456           2 :         status = smb2_create(tree, tctx, &create);
    2457           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2458             :                                         "test file could not be created\n");
    2459           2 :         h1 = create.out.file.handle;
    2460           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2461           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2462             :                                       ret, done, "bad fileid\n");
    2463             : 
    2464             :         /*
    2465             :          * Getinfo the File-ID on the just opened handle
    2466             :          */
    2467           2 :         finfo = (union smb_fileinfo) {
    2468             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2469             :                 .generic.in.file.handle = h1,
    2470             :         };
    2471             : 
    2472           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2473           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2474             :                                         "torture_smb2_testdir\n");
    2475           2 :         smb2_util_close(tree, h1);
    2476           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2477             :                                       expected_fileid,
    2478             :                                       ret, done, "bad fileid\n");
    2479             : 
    2480             :         /*
    2481             :          * Create stream, check the stream's File-ID, should be the same as the
    2482             :          * base file (sic!, tested against Windows).
    2483             :          */
    2484           2 :         create = (struct smb2_create) {
    2485             :                 .in.desired_access = SEC_FILE_ALL,
    2486             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2487             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2488             :                 .in.create_disposition = NTCREATEX_DISP_CREATE,
    2489             :                 .in.fname = sname,
    2490             :                 .in.query_on_disk_id = true,
    2491             :         };
    2492             : 
    2493           2 :         status = smb2_create(tree, tctx, &create);
    2494           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2495             :                                         "test file could not be created\n");
    2496           2 :         h1 = create.out.file.handle;
    2497           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2498           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2499             :                                       ret, done, "bad fileid\n");
    2500             : 
    2501             :         /*
    2502             :          * Getinfo the File-ID on the created stream
    2503             :          */
    2504           2 :         finfo = (union smb_fileinfo) {
    2505             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2506             :                 .generic.in.file.handle = h1,
    2507             :         };
    2508             : 
    2509           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2510           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2511             :                                         "smb2_getinfo_file failed\n");
    2512           2 :         smb2_util_close(tree, h1);
    2513           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2514             :                                       expected_fileid,
    2515             :                                       ret, done, "bad fileid\n");
    2516             : 
    2517             :         /*
    2518             :          * Open stream, check the stream's File-ID, should be the same as the
    2519             :          * base file (sic!, tested against Windows).
    2520             :          */
    2521           2 :         create = (struct smb2_create) {
    2522             :                 .in.desired_access = SEC_FILE_ALL,
    2523             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2524             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2525             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2526             :                 .in.fname = sname,
    2527             :                 .in.query_on_disk_id = true,
    2528             :         };
    2529             : 
    2530           2 :         status = smb2_create(tree, tctx, &create);
    2531           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2532             :                                         "test file could not be created\n");
    2533           2 :         h1 = create.out.file.handle;
    2534           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2535           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2536             :                                       ret, done, "bad fileid\n");
    2537             : 
    2538             :         /*
    2539             :          * Getinfo the File-ID on the opened stream
    2540             :          */
    2541           2 :         finfo = (union smb_fileinfo) {
    2542             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2543             :                 .generic.in.file.handle = h1,
    2544             :         };
    2545             : 
    2546           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2547           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2548             :                                         "smb2_getinfo_file failed\n");
    2549           2 :         smb2_util_close(tree, h1);
    2550           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2551             :                                       expected_fileid,
    2552             :                                       ret, done, "bad fileid\n");
    2553             : 
    2554             :         /*
    2555             :          * Overwrite stream, check the stream's File-ID, should be the same as
    2556             :          * the base file (sic!, tested against Windows).
    2557             :          */
    2558           2 :         create = (struct smb2_create) {
    2559             :                 .in.desired_access = SEC_FILE_ALL,
    2560             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2561             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2562             :                 .in.create_disposition = NTCREATEX_DISP_OVERWRITE,
    2563             :                 .in.fname = sname,
    2564             :                 .in.query_on_disk_id = true,
    2565             :         };
    2566             : 
    2567           2 :         status = smb2_create(tree, tctx, &create);
    2568           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2569             :                                         "test file could not be created\n");
    2570           2 :         h1 = create.out.file.handle;
    2571           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2572           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2573             :                                       ret, done, "bad fileid\n");
    2574             : 
    2575             :         /*
    2576             :          * Getinfo the File-ID on the overwritten stream
    2577             :          */
    2578           2 :         finfo = (union smb_fileinfo) {
    2579             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2580             :                 .generic.in.file.handle = h1,
    2581             :         };
    2582             : 
    2583           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2584           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2585             :                                         "smb2_getinfo_file failed\n");
    2586           2 :         smb2_util_close(tree, h1);
    2587           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2588             :                                       expected_fileid,
    2589             :                                       ret, done, "bad fileid\n");
    2590             : 
    2591             :         /*
    2592             :          * Do some modifications on the stream (IO, setinfo), verifying File-ID
    2593             :          * after earch step.
    2594             :          */
    2595           2 :         create = (struct smb2_create) {
    2596             :                 .in.desired_access = SEC_FILE_ALL,
    2597             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2598             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2599             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2600             :                 .in.fname = sname,
    2601             :                 .in.query_on_disk_id = true,
    2602             :         };
    2603             : 
    2604           2 :         status = smb2_create(tree, tctx, &create);
    2605           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2606             :                                         "test file could not be created\n");
    2607           2 :         h1 = create.out.file.handle;
    2608             : 
    2609           2 :         status = smb2_util_write(tree, h1, "foo", 0, strlen("foo"));
    2610           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2611             :                                         "smb2_util_write failed\n");
    2612             : 
    2613           2 :         finfo = (union smb_fileinfo) {
    2614             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2615             :                 .generic.in.file.handle = h1,
    2616             :         };
    2617           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2618           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2619             :                                         "smb2_getinfo_file failed\n");
    2620           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2621             :                                       expected_fileid,
    2622             :                                       ret, done, "bad fileid\n");
    2623             : 
    2624           2 :         sinfo = (union smb_setfileinfo) {
    2625             :                 .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION,
    2626             :                 .basic_info.in.file.handle = h1,
    2627             :         };
    2628           2 :         unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL));
    2629             : 
    2630           2 :         status = smb2_setinfo_file(tree, &sinfo);
    2631           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2632             :                                         "smb2_setinfo_file failed\n");
    2633             : 
    2634           2 :         finfo = (union smb_fileinfo) {
    2635             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2636             :                 .generic.in.file.handle = h1,
    2637             :         };
    2638           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2639           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2640             :                                         "smb2_getinfo_file failed\n");
    2641           2 :         smb2_util_close(tree, h1);
    2642           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2643             :                                       expected_fileid,
    2644             :                                       ret, done, "bad fileid\n");
    2645             : 
    2646             :         /*
    2647             :          * Final open of the directory with QFID
    2648             :          */
    2649           2 :         create = (struct smb2_create) {
    2650             :                 .in.desired_access = SEC_FILE_ALL,
    2651             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2652             :                 .in.file_attributes = FILE_ATTRIBUTE_DIRECTORY,
    2653             :                 .in.create_options = NTCREATEX_OPTIONS_DIRECTORY,
    2654             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2655             :                 .in.fname = dname,
    2656             :                 .in.query_on_disk_id = true,
    2657             :         };
    2658             : 
    2659           2 :         status = smb2_create(tree, tctx, &create);
    2660           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2661             :                                         "test file could not be created\n");
    2662           2 :         h1 = create.out.file.handle;
    2663           2 :         returned_fileid = BVAL(&create.out.on_disk_id, 0);
    2664           2 :         torture_assert_u64_equal_goto(tctx, returned_fileid, expected_fileid,
    2665             :                                       ret, done, "bad fileid\n");
    2666             : 
    2667             :         /*
    2668             :          * Final Getinfo checking File-ID
    2669             :          */
    2670           2 :         finfo = (union smb_fileinfo) {
    2671             :                 .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
    2672             :                 .generic.in.file.handle = h1,
    2673             :         };
    2674             : 
    2675           2 :         status = smb2_getinfo_file(tree, tctx, &finfo);
    2676           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2677             :                                         "torture_smb2_testdir\n");
    2678           2 :         smb2_util_close(tree, h1);
    2679           2 :         torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id,
    2680             :                                       expected_fileid,
    2681             :                                       ret, done, "bad fileid\n");
    2682             : 
    2683             :         /*
    2684             :          * Final list directory, verifying the operations on basefile and stream
    2685             :          * didn't modify the base file metadata.
    2686             :          */
    2687           2 :         f = (struct smb2_find) {
    2688             :                 .in.file.handle = testdirh,
    2689             :                 .in.pattern = "foo",
    2690             :                 .in.max_response_size = 0x1000,
    2691             :                 .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO,
    2692             :                 .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART,
    2693             :         };
    2694             : 
    2695           2 :         status = smb2_find_level(tree, tree, &f, &count, &d);
    2696           2 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2697             :                                         "smb2_find_level failed\n");
    2698           2 :         torture_assert_u64_equal_goto(tctx,
    2699             :                                       d->id_both_directory_info.file_id,
    2700             :                                       expected_fileid,
    2701             :                                       ret, done, "bad fileid\n");
    2702             : 
    2703           4 : done:
    2704           2 :         smb2_util_close(tree, testdirh);
    2705           2 :         smb2_deltree(tree, DNAME);
    2706           2 :         talloc_free(mem_ctx);
    2707           2 :         return ret;
    2708             : }
    2709             : 
    2710             : /*
    2711             :   test opening quota fakefile handle and returned attributes
    2712             : */
    2713           6 : static bool test_smb2_open_quota_fake_file(struct torture_context *tctx,
    2714             :                                            struct smb2_tree *tree)
    2715             : {
    2716           6 :         const char *fname = "$Extend\\$Quota:$Q:$INDEX_ALLOCATION";
    2717             :         struct smb2_create create;
    2718           6 :         struct smb2_handle h = {{0}};
    2719             :         NTSTATUS status;
    2720           6 :         bool ret = true;
    2721             : 
    2722           6 :         create = (struct smb2_create) {
    2723             :                 .in.desired_access = SEC_RIGHTS_FILE_READ,
    2724             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
    2725             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
    2726             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
    2727             :                 .in.impersonation_level = SMB2_IMPERSONATION_ANONYMOUS,
    2728             :                 .in.fname = fname,
    2729             :         };
    2730             : 
    2731           6 :         status = smb2_create(tree, tree, &create);
    2732           6 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2733             :                                         "smb2_create failed\n");
    2734           5 :         h = create.out.file.handle;
    2735             : 
    2736           5 :         torture_assert_u64_equal_goto(tctx,
    2737             :                                       create.out.file_attr,
    2738             :                                       FILE_ATTRIBUTE_HIDDEN
    2739             :                                       | FILE_ATTRIBUTE_SYSTEM
    2740             :                                       | FILE_ATTRIBUTE_DIRECTORY
    2741             :                                       | FILE_ATTRIBUTE_ARCHIVE,
    2742             :                                       ret,
    2743             :                                       done,
    2744             :                                       "Wrong attributes\n");
    2745             : 
    2746           5 :         torture_assert_u64_equal_goto(tctx,
    2747             :                                       create.out.create_time, 0,
    2748             :                                       ret,
    2749             :                                       done,
    2750             :                                       "create_time is not 0\n");
    2751           5 :         torture_assert_u64_equal_goto(tctx,
    2752             :                                       create.out.access_time, 0,
    2753             :                                       ret,
    2754             :                                       done,
    2755             :                                       "access_time is not 0\n");
    2756           5 :         torture_assert_u64_equal_goto(tctx,
    2757             :                                       create.out.write_time, 0,
    2758             :                                       ret,
    2759             :                                       done,
    2760             :                                       "write_time is not 0\n");
    2761           5 :         torture_assert_u64_equal_goto(tctx,
    2762             :                                       create.out.change_time, 0,
    2763             :                                       ret,
    2764             :                                       done,
    2765             :                                       "change_time is not 0\n");
    2766             : 
    2767          11 : done:
    2768           6 :         smb2_util_close(tree, h);
    2769           6 :         return ret;
    2770             : }
    2771             : 
    2772             : /*
    2773             :    basic testing of SMB2 read
    2774             : */
    2775        2353 : struct torture_suite *torture_smb2_create_init(TALLOC_CTX *ctx)
    2776             : {
    2777        2353 :         struct torture_suite *suite = torture_suite_create(ctx, "create");
    2778             : 
    2779        2353 :         torture_suite_add_1smb2_test(suite, "gentest", test_create_gentest);
    2780        2353 :         torture_suite_add_1smb2_test(suite, "blob", test_create_blob);
    2781        2353 :         torture_suite_add_1smb2_test(suite, "open", test_smb2_open);
    2782        2353 :         torture_suite_add_1smb2_test(suite, "brlocked", test_smb2_open_brlocked);
    2783        2353 :         torture_suite_add_1smb2_test(suite, "multi", test_smb2_open_multi);
    2784        2353 :         torture_suite_add_1smb2_test(suite, "delete", test_smb2_open_for_delete);
    2785        2353 :         torture_suite_add_1smb2_test(suite, "leading-slash", test_smb2_leading_slash);
    2786        2353 :         torture_suite_add_1smb2_test(suite, "impersonation", test_smb2_impersonation_level);
    2787        2353 :         torture_suite_add_1smb2_test(suite, "aclfile", test_create_acl_file);
    2788        2353 :         torture_suite_add_1smb2_test(suite, "acldir", test_create_acl_dir);
    2789        2353 :         torture_suite_add_1smb2_test(suite, "nulldacl", test_create_null_dacl);
    2790        2353 :         torture_suite_add_1smb2_test(suite, "mkdir-dup", test_mkdir_dup);
    2791        2353 :         torture_suite_add_1smb2_test(suite, "dir-alloc-size", test_dir_alloc_size);
    2792        2353 :         torture_suite_add_1smb2_test(suite, "quota-fake-file", test_smb2_open_quota_fake_file);
    2793             : 
    2794        2353 :         suite->description = talloc_strdup(suite, "SMB2-CREATE tests");
    2795             : 
    2796        2353 :         return suite;
    2797             : }
    2798             : 
    2799        2353 : struct torture_suite *torture_smb2_twrp_init(TALLOC_CTX *ctx)
    2800             : {
    2801        2353 :         struct torture_suite *suite = torture_suite_create(ctx, "twrp");
    2802             : 
    2803        2353 :         torture_suite_add_1smb2_test(suite, "write", test_twrp_write);
    2804        2353 :         torture_suite_add_1smb2_test(suite, "stream", test_twrp_stream);
    2805        2353 :         torture_suite_add_1smb2_test(suite, "openroot", test_twrp_openroot);
    2806             : 
    2807        2353 :         suite->description = talloc_strdup(suite, "SMB2-TWRP tests");
    2808             : 
    2809        2353 :         return suite;
    2810             : }
    2811             : 
    2812             : /*
    2813             :    basic testing of SMB2 File-IDs
    2814             : */
    2815        2353 : struct torture_suite *torture_smb2_fileid_init(TALLOC_CTX *ctx)
    2816             : {
    2817        2353 :         struct torture_suite *suite = torture_suite_create(ctx, "fileid");
    2818             : 
    2819        2353 :         torture_suite_add_1smb2_test(suite, "fileid", test_fileid);
    2820        2353 :         torture_suite_add_1smb2_test(suite, "fileid-dir", test_fileid_dir);
    2821             : 
    2822        2353 :         suite->description = talloc_strdup(suite, "SMB2-CREATE tests");
    2823             : 
    2824        2353 :         return suite;
    2825             : }

Generated by: LCOV version 1.13