LCOV - code coverage report
Current view: top level - source4/torture/raw - samba3misc.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 540 677 79.8 %
Date: 2024-04-21 15:09:00 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Test some misc Samba3 code paths
       4             :    Copyright (C) Volker Lendecke 2006
       5             :    
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             :    
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             :    
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "torture/torture.h"
      22             : #include "libcli/raw/libcliraw.h"
      23             : #include "libcli/raw/raw_proto.h"
      24             : #include "system/time.h"
      25             : #include "system/filesys.h"
      26             : #include "libcli/libcli.h"
      27             : #include "torture/util.h"
      28             : #include "lib/events/events.h"
      29             : #include "param/param.h"
      30             : #include "torture/raw/proto.h"
      31             : 
      32             : /*
      33             :  The next 2 functions are stolen from source4/libcli/raw/rawfile.c
      34             :  but allow us to send a raw data blob instead of an OpenX name.
      35             : */
      36             : 
      37             : #define SETUP_REQUEST(cmd, wct, buflen) do { \
      38             :         req = smbcli_request_setup(tree, cmd, wct, buflen); \
      39             :         if (!req) return NULL; \
      40             : } while (0)
      41             : 
      42           4 : static struct smbcli_request *smb_raw_openX_name_blob_send(struct smbcli_tree *tree,
      43             :                                         union smb_open *parms,
      44             :                                         const DATA_BLOB *pname_blob)
      45             : {
      46           4 :         struct smbcli_request *req = NULL;
      47             : 
      48           4 :         if (parms->generic.level != RAW_OPEN_OPENX) {
      49           0 :                 return NULL;
      50             :         }
      51             : 
      52           4 :         SETUP_REQUEST(SMBopenX, 15, 0);
      53           4 :         SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
      54           4 :         SSVAL(req->out.vwv, VWV(1), 0);
      55           4 :         SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
      56           4 :         SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
      57           4 :         SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
      58           4 :         SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
      59           4 :         raw_push_dos_date3(tree->session->transport,
      60             :                         req->out.vwv, VWV(6), parms->openx.in.write_time);
      61           4 :         SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
      62           4 :         SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
      63           4 :         SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
      64           4 :         SIVAL(req->out.vwv, VWV(13),0); /* reserved */
      65           4 :         smbcli_req_append_blob(req, pname_blob);
      66             : 
      67           4 :         if (!smbcli_request_send(req)) {
      68           0 :                 smbcli_request_destroy(req);
      69           0 :                 return NULL;
      70             :         }
      71             : 
      72           4 :         return req;
      73             : }
      74             : 
      75           4 : static NTSTATUS smb_raw_openX_name_blob(struct smbcli_tree *tree,
      76             :                         TALLOC_CTX *mem_ctx,
      77             :                         union smb_open *parms,
      78             :                         const DATA_BLOB *pname_blob)
      79             : {
      80           4 :         struct smbcli_request *req = smb_raw_openX_name_blob_send(tree, parms, pname_blob);
      81           4 :         return smb_raw_open_recv(req, mem_ctx, parms);
      82             : }
      83             : 
      84           4 : static NTSTATUS raw_smbcli_openX_name_blob(struct smbcli_tree *tree,
      85             :                                 const DATA_BLOB *pname_blob,
      86             :                                 int flags,
      87             :                                 int share_mode,
      88             :                                 int *fnum)
      89             : {
      90           0 :         union smb_open open_parms;
      91           4 :         unsigned int openfn=0;
      92           4 :         unsigned int accessmode=0;
      93           0 :         TALLOC_CTX *mem_ctx;
      94           0 :         NTSTATUS status;
      95             : 
      96           4 :         mem_ctx = talloc_init("raw_openX_name_blob");
      97           4 :         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
      98             : 
      99           4 :         if (flags & O_CREAT) {
     100           0 :                 openfn |= OPENX_OPEN_FUNC_CREATE;
     101             :         }
     102           4 :         if (!(flags & O_EXCL)) {
     103           4 :                 if (flags & O_TRUNC) {
     104           0 :                         openfn |= OPENX_OPEN_FUNC_TRUNC;
     105             :                 } else {
     106           4 :                         openfn |= OPENX_OPEN_FUNC_OPEN;
     107             :                 }
     108             :         }
     109             : 
     110           4 :         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
     111             : 
     112           4 :         if ((flags & O_ACCMODE) == O_RDWR) {
     113           4 :                 accessmode |= OPENX_MODE_ACCESS_RDWR;
     114           0 :         } else if ((flags & O_ACCMODE) == O_WRONLY) {
     115           0 :                 accessmode |= OPENX_MODE_ACCESS_WRITE;
     116           0 :         } else if ((flags & O_ACCMODE) == O_RDONLY) {
     117           0 :                 accessmode |= OPENX_MODE_ACCESS_READ;
     118             :         }
     119             : 
     120             : #if defined(O_SYNC)
     121           4 :         if ((flags & O_SYNC) == O_SYNC) {
     122           0 :                 accessmode |= OPENX_MODE_WRITE_THRU;
     123             :         }
     124             : #endif
     125             : 
     126           4 :         if (share_mode == DENY_FCB) {
     127           0 :                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
     128             :         }
     129             : 
     130           4 :         open_parms.openx.level = RAW_OPEN_OPENX;
     131           4 :         open_parms.openx.in.flags = 0;
     132           4 :         open_parms.openx.in.open_mode = accessmode;
     133           4 :         open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
     134           4 :         open_parms.openx.in.file_attrs = 0;
     135           4 :         open_parms.openx.in.write_time = 0;
     136           4 :         open_parms.openx.in.open_func = openfn;
     137           4 :         open_parms.openx.in.size = 0;
     138           4 :         open_parms.openx.in.timeout = 0;
     139           4 :         open_parms.openx.in.fname = NULL;
     140             : 
     141           4 :         status = smb_raw_openX_name_blob(tree, mem_ctx, &open_parms, pname_blob);
     142           4 :         talloc_free(mem_ctx);
     143             : 
     144           4 :         if (fnum && NT_STATUS_IS_OK(status)) {
     145           0 :                 *fnum = open_parms.openx.out.file.fnum;
     146             :         }
     147             : 
     148           4 :         return status;
     149             : }
     150             : 
     151             : 
     152             : #define CHECK_STATUS(torture, status, correct) do {     \
     153             :         if (!NT_STATUS_EQUAL(status, correct)) { \
     154             :                 torture_result(torture, TORTURE_FAIL, "%s: Incorrect status %s - should be %s\n", \
     155             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
     156             :                 ret = false; \
     157             :         } \
     158             : } while (0)
     159             : 
     160           6 : bool torture_samba3_checkfsp(struct torture_context *torture, struct smbcli_state *cli)
     161             : {
     162           6 :         const char *fname = "test.txt";
     163           6 :         const char *dirname = "testdir";
     164           0 :         int fnum;
     165           0 :         NTSTATUS status;
     166           6 :         bool ret = true;
     167           0 :         TALLOC_CTX *mem_ctx;
     168           0 :         ssize_t nread;
     169           0 :         char buf[16];
     170           0 :         struct smbcli_tree *tree2;
     171             : 
     172           6 :         torture_assert(torture, mem_ctx = talloc_init("torture_samba3_checkfsp"), "talloc_init failed\n");
     173             : 
     174           6 :         torture_assert_ntstatus_equal(torture, torture_second_tcon(torture, cli->session,
     175             :                                                                    torture_setting_string(torture, "share", NULL),
     176             :                                                                    &tree2), 
     177             :                                       NT_STATUS_OK,
     178             :                                       "creating second tcon");
     179             : 
     180             :         /* Try a read on an invalid FID */
     181             : 
     182           6 :         nread = smbcli_read(cli->tree, 4711, buf, 0, sizeof(buf));
     183           6 :         CHECK_STATUS(torture, smbcli_nt_error(cli->tree), NT_STATUS_INVALID_HANDLE);
     184             : 
     185             :         /* Try a read on a directory handle */
     186             : 
     187           6 :         torture_assert(torture, torture_setup_dir(cli, dirname), "creating test directory");
     188             : 
     189             :         /* Open the directory */
     190             :         {
     191           0 :                 union smb_open io;
     192           6 :                 io.generic.level = RAW_OPEN_NTCREATEX;
     193           6 :                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     194           6 :                 io.ntcreatex.in.root_fid.fnum = 0;
     195           6 :                 io.ntcreatex.in.security_flags = 0;
     196           6 :                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     197           6 :                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     198           6 :                 io.ntcreatex.in.alloc_size = 0;
     199           6 :                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
     200           6 :                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     201           6 :                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
     202           6 :                 io.ntcreatex.in.create_options = 0;
     203           6 :                 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     204           6 :                 io.ntcreatex.in.fname = dirname;
     205           6 :                 status = smb_raw_open(cli->tree, mem_ctx, &io);
     206           6 :                 if (!NT_STATUS_IS_OK(status)) {
     207           0 :                         torture_result(torture, TORTURE_FAIL, "smb_open on the directory failed: %s\n",
     208             :                                  nt_errstr(status));
     209           0 :                         ret = false;
     210           0 :                         goto done;
     211             :                 }
     212           6 :                 fnum = io.ntcreatex.out.file.fnum;
     213             :         }
     214             : 
     215             :         /* Try a read on the directory */
     216             : 
     217           6 :         nread = smbcli_read(cli->tree, fnum, buf, 0, sizeof(buf));
     218           6 :         if (nread >= 0) {
     219           0 :                 torture_result(torture, TORTURE_FAIL, "smbcli_read on a directory succeeded, expected "
     220             :                          "failure\n");
     221           0 :                 ret = false;
     222             :         }
     223             : 
     224           6 :         CHECK_STATUS(torture, smbcli_nt_error(cli->tree),
     225             :                      NT_STATUS_INVALID_DEVICE_REQUEST);
     226             : 
     227             :         /* Same test on the second tcon */
     228             : 
     229           6 :         nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
     230           6 :         if (nread >= 0) {
     231           0 :                 torture_result(torture, TORTURE_FAIL, "smbcli_read on a directory succeeded, expected "
     232             :                          "failure\n");
     233           0 :                 ret = false;
     234             :         }
     235             : 
     236           6 :         CHECK_STATUS(torture, smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
     237             : 
     238           6 :         smbcli_close(cli->tree, fnum);
     239             : 
     240             :         /* Try a normal file read on a second tcon */
     241             : 
     242           6 :         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
     243           6 :         if (fnum == -1) {
     244           0 :                 torture_result(torture, TORTURE_FAIL, "Failed to create %s - %s\n", fname,
     245             :                          smbcli_errstr(cli->tree));
     246           0 :                 ret = false;
     247           0 :                 goto done;
     248             :         }
     249             : 
     250           6 :         nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
     251           6 :         CHECK_STATUS(torture, smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
     252             : 
     253           6 :         smbcli_close(cli->tree, fnum);
     254             : 
     255           6 :  done:
     256           6 :         smbcli_deltree(cli->tree, dirname);
     257           6 :         talloc_free(mem_ctx);
     258             : 
     259           6 :         return ret;
     260             : }
     261             : 
     262          56 : static NTSTATUS raw_smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
     263             : {
     264           0 :         union smb_open open_parms;
     265          56 :         unsigned int openfn=0;
     266          56 :         unsigned int accessmode=0;
     267           0 :         TALLOC_CTX *mem_ctx;
     268           0 :         NTSTATUS status;
     269             : 
     270          56 :         mem_ctx = talloc_init("raw_open");
     271          56 :         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
     272             : 
     273          56 :         if (flags & O_CREAT) {
     274           8 :                 openfn |= OPENX_OPEN_FUNC_CREATE;
     275             :         }
     276          56 :         if (!(flags & O_EXCL)) {
     277          48 :                 if (flags & O_TRUNC) {
     278           0 :                         openfn |= OPENX_OPEN_FUNC_TRUNC;
     279             :                 } else {
     280          48 :                         openfn |= OPENX_OPEN_FUNC_OPEN;
     281             :                 }
     282             :         }
     283             : 
     284          56 :         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
     285             : 
     286          56 :         if ((flags & O_ACCMODE) == O_RDWR) {
     287           0 :                 accessmode |= OPENX_MODE_ACCESS_RDWR;
     288          56 :         } else if ((flags & O_ACCMODE) == O_WRONLY) {
     289           0 :                 accessmode |= OPENX_MODE_ACCESS_WRITE;
     290          56 :         } else if ((flags & O_ACCMODE) == O_RDONLY) {
     291          56 :                 accessmode |= OPENX_MODE_ACCESS_READ;
     292             :         }
     293             : 
     294             : #if defined(O_SYNC)
     295          56 :         if ((flags & O_SYNC) == O_SYNC) {
     296           0 :                 accessmode |= OPENX_MODE_WRITE_THRU;
     297             :         }
     298             : #endif
     299             : 
     300          56 :         if (share_mode == DENY_FCB) {
     301           0 :                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
     302             :         }
     303             : 
     304          56 :         open_parms.openx.level = RAW_OPEN_OPENX;
     305          56 :         open_parms.openx.in.flags = 0;
     306          56 :         open_parms.openx.in.open_mode = accessmode;
     307          56 :         open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
     308          56 :         open_parms.openx.in.file_attrs = 0;
     309          56 :         open_parms.openx.in.write_time = 0;
     310          56 :         open_parms.openx.in.open_func = openfn;
     311          56 :         open_parms.openx.in.size = 0;
     312          56 :         open_parms.openx.in.timeout = 0;
     313          56 :         open_parms.openx.in.fname = fname;
     314             : 
     315          56 :         status = smb_raw_open(tree, mem_ctx, &open_parms);
     316          56 :         talloc_free(mem_ctx);
     317             : 
     318          56 :         if (fnum && NT_STATUS_IS_OK(status)) {
     319           0 :                 *fnum = open_parms.openx.out.file.fnum;
     320             :         }
     321             : 
     322          56 :         return status;
     323             : }
     324             : 
     325           8 : static NTSTATUS raw_smbcli_t2open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
     326             : {
     327           0 :         union smb_open io;
     328           8 :         unsigned int openfn=0;
     329           8 :         unsigned int accessmode=0;
     330           0 :         TALLOC_CTX *mem_ctx;
     331           0 :         NTSTATUS status;
     332             : 
     333           8 :         mem_ctx = talloc_init("raw_t2open");
     334           8 :         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
     335             : 
     336           8 :         if (flags & O_CREAT) {
     337           8 :                 openfn |= OPENX_OPEN_FUNC_CREATE;
     338             :         }
     339           8 :         if (!(flags & O_EXCL)) {
     340           0 :                 if (flags & O_TRUNC) {
     341           0 :                         openfn |= OPENX_OPEN_FUNC_TRUNC;
     342             :                 } else {
     343           0 :                         openfn |= OPENX_OPEN_FUNC_OPEN;
     344             :                 }
     345             :         }
     346             : 
     347           8 :         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
     348             : 
     349           8 :         if ((flags & O_ACCMODE) == O_RDWR) {
     350           0 :                 accessmode |= OPENX_MODE_ACCESS_RDWR;
     351           8 :         } else if ((flags & O_ACCMODE) == O_WRONLY) {
     352           0 :                 accessmode |= OPENX_MODE_ACCESS_WRITE;
     353           8 :         } else if ((flags & O_ACCMODE) == O_RDONLY) {
     354           8 :                 accessmode |= OPENX_MODE_ACCESS_READ;
     355             :         }
     356             : 
     357             : #if defined(O_SYNC)
     358           8 :         if ((flags & O_SYNC) == O_SYNC) {
     359           0 :                 accessmode |= OPENX_MODE_WRITE_THRU;
     360             :         }
     361             : #endif
     362             : 
     363           8 :         if (share_mode == DENY_FCB) {
     364           0 :                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
     365             :         }
     366             : 
     367           8 :         memset(&io, '\0', sizeof(io));
     368           8 :         io.t2open.level = RAW_OPEN_T2OPEN;
     369           8 :         io.t2open.in.flags = 0;
     370           8 :         io.t2open.in.open_mode = accessmode;
     371           8 :         io.t2open.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
     372           8 :         io.t2open.in.file_attrs = 0;
     373           8 :         io.t2open.in.write_time = 0;
     374           8 :         io.t2open.in.open_func = openfn;
     375           8 :         io.t2open.in.size = 0;
     376           8 :         io.t2open.in.timeout = 0;
     377           8 :         io.t2open.in.fname = fname;
     378             : 
     379           8 :         io.t2open.in.num_eas = 1;
     380           8 :         io.t2open.in.eas = talloc_array(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
     381           8 :         io.t2open.in.eas[0].flags = 0;
     382           8 :         io.t2open.in.eas[0].name.s = ".CLASSINFO";
     383           8 :         io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
     384             : 
     385           8 :         status = smb_raw_open(tree, mem_ctx, &io);
     386           8 :         talloc_free(mem_ctx);
     387             : 
     388           8 :         if (fnum && NT_STATUS_IS_OK(status)) {
     389           0 :                 *fnum = io.openx.out.file.fnum;
     390             :         }
     391             : 
     392           8 :         return status;
     393             : }
     394             : 
     395           8 : static NTSTATUS raw_smbcli_ntcreate(struct smbcli_tree *tree, const char *fname, int *fnum)
     396             : {
     397           0 :         union smb_open io;
     398           0 :         TALLOC_CTX *mem_ctx;
     399           0 :         NTSTATUS status;
     400             : 
     401           8 :         mem_ctx = talloc_init("raw_t2open");
     402           8 :         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
     403             : 
     404           8 :         memset(&io, '\0', sizeof(io));
     405           8 :         io.generic.level = RAW_OPEN_NTCREATEX;
     406           8 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     407           8 :         io.ntcreatex.in.root_fid.fnum = 0;
     408           8 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     409           8 :         io.ntcreatex.in.alloc_size = 0;
     410           8 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     411           8 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
     412           8 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
     413           8 :         io.ntcreatex.in.create_options = 0;
     414           8 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     415           8 :         io.ntcreatex.in.security_flags = 0;
     416           8 :         io.ntcreatex.in.fname = fname;
     417             : 
     418           8 :         status = smb_raw_open(tree, mem_ctx, &io);
     419           8 :         talloc_free(mem_ctx);
     420             : 
     421           8 :         if (fnum && NT_STATUS_IS_OK(status)) {
     422           0 :                 *fnum = io.openx.out.file.fnum;
     423             :         }
     424             : 
     425           8 :         return status;
     426             : }
     427             : 
     428             : 
     429           4 : bool torture_samba3_badpath(struct torture_context *torture)
     430             : {
     431           4 :         struct smbcli_state *cli_nt = NULL;
     432           4 :         struct smbcli_state *cli_dos = NULL;
     433           4 :         const char *fname = "test.txt";
     434           4 :         const char *fname1 = "test1.txt";
     435           4 :         const char *dirname = "testdir";
     436           0 :         char *fpath;
     437           0 :         char *fpath1;
     438           0 :         int fnum;
     439           0 :         NTSTATUS status;
     440           4 :         bool ret = true;
     441           0 :         TALLOC_CTX *mem_ctx;
     442           0 :         bool nt_status_support;
     443           0 :         bool client_ntlmv2_auth;
     444             : 
     445           4 :         torture_assert(torture, mem_ctx = talloc_init("torture_samba3_badpath"), "talloc_init failed");
     446             : 
     447           4 :         nt_status_support = lpcfg_nt_status_support(torture->lp_ctx);
     448           4 :         client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(torture->lp_ctx);
     449             : 
     450           4 :         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes"), ret, fail, "Could not set 'nt status support = yes'\n");
     451           4 :         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "yes"), ret, fail, "Could not set 'client ntlmv2 auth = yes'\n");
     452             : 
     453           4 :         torture_assert_goto(torture, torture_open_connection(&cli_nt, torture, 0), ret, fail, "Could not open NTSTATUS connection\n");
     454             : 
     455           4 :         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no"), ret, fail, "Could not set 'nt status support = no'\n");
     456           4 :         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "no"), ret, fail, "Could not set 'client ntlmv2 auth = no'\n");
     457             : 
     458           4 :         torture_assert_goto(torture, torture_open_connection(&cli_dos, torture, 1), ret, fail, "Could not open DOS connection\n");
     459             : 
     460           4 :         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support",
     461             :                                                        nt_status_support ? "yes":"no"), 
     462             :                             ret, fail, "Could not set 'nt status support' back to where it was\n");
     463           4 :         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth",
     464             :                                                        client_ntlmv2_auth ? "yes":"no"),
     465             :                             ret, fail, "Could not set 'client ntlmv2 auth' back to where it was\n");
     466             : 
     467           4 :         torture_assert(torture, torture_setup_dir(cli_nt, dirname), "creating test directory");
     468             : 
     469           4 :         status = smbcli_chkpath(cli_nt->tree, dirname);
     470           4 :         CHECK_STATUS(torture, status, NT_STATUS_OK);
     471             : 
     472           4 :         status = smbcli_chkpath(cli_nt->tree,
     473           4 :                                 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
     474           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     475             : 
     476           4 :         status = smbcli_chkpath(cli_dos->tree,
     477           4 :                                 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
     478           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     479             : 
     480           4 :         status = smbcli_chkpath(cli_nt->tree,
     481           4 :                                 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
     482             :                                                 dirname));
     483           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
     484           4 :         status = smbcli_chkpath(cli_dos->tree,
     485           4 :                                 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
     486             :                                                 dirname));
     487           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     488             : 
     489           4 :         torture_assert_goto(torture, fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname), 
     490             :                             ret, fail, "Could not allocate fpath\n");
     491             : 
     492           4 :         fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
     493           4 :         if (fnum == -1) {
     494           0 :                 torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s\n", fpath,
     495           0 :                          smbcli_errstr(cli_nt->tree));
     496           0 :                 goto fail;
     497             :         }
     498           4 :         smbcli_close(cli_nt->tree, fnum);
     499             : 
     500           4 :         if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
     501           0 :                 goto fail;
     502             :         }
     503           4 :         fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
     504           4 :         if (fnum == -1) {
     505           0 :                 torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s\n", fpath1,
     506           0 :                          smbcli_errstr(cli_nt->tree));
     507           0 :                 goto fail;
     508             :         }
     509           4 :         smbcli_close(cli_nt->tree, fnum);
     510             : 
     511             :         /*
     512             :          * Do a whole bunch of error code checks on chkpath
     513             :          */
     514             : 
     515           4 :         status = smbcli_chkpath(cli_nt->tree, fpath);
     516           4 :         CHECK_STATUS(torture, status, NT_STATUS_NOT_A_DIRECTORY);
     517           4 :         status = smbcli_chkpath(cli_dos->tree, fpath);
     518           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     519             : 
     520           4 :         status = smbcli_chkpath(cli_nt->tree, "..");
     521           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
     522           4 :         status = smbcli_chkpath(cli_dos->tree, "..");
     523           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
     524             : 
     525           4 :         status = smbcli_chkpath(cli_nt->tree, ".");
     526           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     527           4 :         status = smbcli_chkpath(cli_dos->tree, ".");
     528           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     529             : 
     530           4 :         status = smbcli_chkpath(cli_nt->tree, "\t");
     531           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     532           4 :         status = smbcli_chkpath(cli_dos->tree, "\t");
     533           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     534             : 
     535           4 :         status = smbcli_chkpath(cli_nt->tree, "\t\\bla");
     536           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     537           4 :         status = smbcli_chkpath(cli_dos->tree, "\t\\bla");
     538           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     539             : 
     540           4 :         status = smbcli_chkpath(cli_nt->tree, "<");
     541           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     542           4 :         status = smbcli_chkpath(cli_dos->tree, "<");
     543           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     544             : 
     545           4 :         status = smbcli_chkpath(cli_nt->tree, "<\\bla");
     546           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     547           4 :         status = smbcli_chkpath(cli_dos->tree, "<\\bla");
     548           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
     549             : 
     550             :         /*
     551             :          * .... And the same gang against getatr. Note that the DOS error codes
     552             :          * differ....
     553             :          */
     554             : 
     555           4 :         status = smbcli_getatr(cli_nt->tree, fpath, NULL, NULL, NULL);
     556           4 :         CHECK_STATUS(torture, status, NT_STATUS_OK);
     557           4 :         status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
     558           4 :         CHECK_STATUS(torture, status, NT_STATUS_OK);
     559             : 
     560           4 :         status = smbcli_getatr(cli_nt->tree, "..", NULL, NULL, NULL);
     561           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
     562           4 :         status = smbcli_getatr(cli_dos->tree, "..", NULL, NULL, NULL);
     563           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
     564             : 
     565           4 :         status = smbcli_getatr(cli_nt->tree, ".", NULL, NULL, NULL);
     566           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     567           4 :         status = smbcli_getatr(cli_dos->tree, ".", NULL, NULL, NULL);
     568           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     569             : 
     570           4 :         status = smbcli_getatr(cli_nt->tree, "\t", NULL, NULL, NULL);
     571           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     572           4 :         status = smbcli_getatr(cli_dos->tree, "\t", NULL, NULL, NULL);
     573           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     574             : 
     575           4 :         status = smbcli_getatr(cli_nt->tree, "\t\\bla", NULL, NULL, NULL);
     576           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     577           4 :         status = smbcli_getatr(cli_dos->tree, "\t\\bla", NULL, NULL, NULL);
     578           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     579             : 
     580           4 :         status = smbcli_getatr(cli_nt->tree, "<", NULL, NULL, NULL);
     581           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     582           4 :         status = smbcli_getatr(cli_dos->tree, "<", NULL, NULL, NULL);
     583           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     584             : 
     585           4 :         status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
     586           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     587           4 :         status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
     588           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     589             : 
     590             :         /* Try the same set with openX. */
     591             : 
     592           4 :         status = raw_smbcli_open(cli_nt->tree, "..", O_RDONLY, DENY_NONE, NULL);
     593           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
     594           4 :         status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
     595           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
     596             : 
     597           4 :         status = raw_smbcli_open(cli_nt->tree, ".", O_RDONLY, DENY_NONE, NULL);
     598           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     599           4 :         status = raw_smbcli_open(cli_dos->tree, ".", O_RDONLY, DENY_NONE, NULL);
     600           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     601             : 
     602           4 :         status = raw_smbcli_open(cli_nt->tree, "\t", O_RDONLY, DENY_NONE, NULL);
     603           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     604           4 :         status = raw_smbcli_open(cli_dos->tree, "\t", O_RDONLY, DENY_NONE, NULL);
     605           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     606             : 
     607           4 :         status = raw_smbcli_open(cli_nt->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
     608           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     609           4 :         status = raw_smbcli_open(cli_dos->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
     610           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     611             : 
     612           4 :         status = raw_smbcli_open(cli_nt->tree, "<", O_RDONLY, DENY_NONE, NULL);
     613           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     614           4 :         status = raw_smbcli_open(cli_dos->tree, "<", O_RDONLY, DENY_NONE, NULL);
     615           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     616             : 
     617           4 :         status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
     618           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
     619           4 :         status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
     620           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
     621             : 
     622             :         /* Let's test EEXIST error code mapping. */
     623           4 :         status = raw_smbcli_open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
     624           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
     625           4 :         status = raw_smbcli_open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
     626           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
     627             : 
     628           4 :         status = raw_smbcli_t2open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
     629           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
     630           0 :             || !torture_setting_bool(torture, "samba3", false)) {
     631             :                 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
     632           4 :                 CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
     633             :         }
     634           4 :         status = raw_smbcli_t2open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
     635           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,ERReasnotsupported))
     636           0 :             || !torture_setting_bool(torture, "samba3", false)) {
     637             :                 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
     638           4 :                 CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
     639             :         }
     640             : 
     641           4 :         status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
     642           4 :         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
     643           4 :         status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
     644           4 :         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
     645             : 
     646             :         /* Try the rename test. */
     647             :         {
     648           0 :                 union smb_rename io;
     649           4 :                 memset(&io, '\0', sizeof(io));
     650           4 :                 io.rename.in.pattern1 = fpath1;
     651           4 :                 io.rename.in.pattern2 = fpath;
     652             : 
     653             :                 /* Try with SMBmv rename. */
     654           4 :                 status = smb_raw_rename(cli_nt->tree, &io);
     655           4 :                 CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
     656           4 :                 status = smb_raw_rename(cli_dos->tree, &io);
     657           4 :                 CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRrename));
     658             : 
     659             :                 /* Try with NT rename. */
     660           4 :                 io.generic.level = RAW_RENAME_NTRENAME;
     661           4 :                 io.ntrename.in.old_name = fpath1;
     662           4 :                 io.ntrename.in.new_name = fpath;
     663           4 :                 io.ntrename.in.attrib = 0;
     664           4 :                 io.ntrename.in.cluster_size = 0;
     665           4 :                 io.ntrename.in.flags = RENAME_FLAG_RENAME;
     666             : 
     667           4 :                 status = smb_raw_rename(cli_nt->tree, &io);
     668           4 :                 CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
     669           4 :                 status = smb_raw_rename(cli_dos->tree, &io);
     670           4 :                 CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRrename));
     671             :         }
     672             : 
     673           4 :         goto done;
     674             : 
     675           0 :  fail:
     676           0 :         ret = false;
     677             : 
     678           4 :  done:
     679           4 :         if (cli_nt != NULL) {
     680           4 :                 smbcli_deltree(cli_nt->tree, dirname);
     681           4 :                 torture_close_connection(cli_nt);
     682             :         }
     683           4 :         if (cli_dos != NULL) {
     684           4 :                 torture_close_connection(cli_dos);
     685             :         }
     686           4 :         talloc_free(mem_ctx);
     687             : 
     688           4 :         return ret;
     689             : }
     690             : 
     691          12 : static void count_fn(struct clilist_file_info *info, const char *name,
     692             :                      void *private_data)
     693             : {
     694          12 :         int *counter = (int *)private_data;
     695          12 :         *counter += 1;
     696          12 : }
     697             : 
     698           4 : bool torture_samba3_caseinsensitive(struct torture_context *torture, struct smbcli_state *cli)
     699             : {
     700           0 :         TALLOC_CTX *mem_ctx;
     701           4 :         const char *dirname = "insensitive";
     702           4 :         const char *ucase_dirname = "InSeNsItIvE";
     703           4 :         const char *fname = "foo";
     704           0 :         char *fpath;
     705           0 :         int fnum;
     706           4 :         int counter = 0;
     707           4 :         bool ret = false;
     708             : 
     709           4 :         if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) {
     710           0 :                 torture_result(torture, TORTURE_FAIL, "talloc_init failed\n");
     711           0 :                 return false;
     712             :         }
     713             : 
     714           4 :         torture_assert(torture, torture_setup_dir(cli, dirname), "creating test directory");
     715             : 
     716           4 :         if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
     717           0 :                 goto done;
     718             :         }
     719           4 :         fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
     720           4 :         if (fnum == -1) {
     721           0 :                 torture_result(torture, TORTURE_FAIL,
     722             :                         "Could not create file %s: %s", fpath,
     723             :                          smbcli_errstr(cli->tree));
     724           0 :                 goto done;
     725             :         }
     726           4 :         smbcli_close(cli->tree, fnum);
     727             : 
     728           4 :         smbcli_list(cli->tree, talloc_asprintf(
     729             :                             mem_ctx, "%s\\*", ucase_dirname),
     730             :                     FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN
     731             :                     |FILE_ATTRIBUTE_SYSTEM,
     732             :                     count_fn, (void *)&counter);
     733             : 
     734           4 :         if (counter == 3) {
     735           4 :                 ret = true;
     736             :         }
     737             :         else {
     738           0 :                 torture_result(torture, TORTURE_FAIL,
     739             :                         "expected 3 entries, got %d", counter);
     740           0 :                 ret = false;
     741             :         }
     742             : 
     743           4 :  done:
     744           4 :         talloc_free(mem_ctx);
     745           4 :         return ret;
     746             : }
     747             : 
     748           8 : static void close_locked_file(struct tevent_context *ev,
     749             :                               struct tevent_timer *te,
     750             :                               struct timeval now,
     751             :                               void *private_data)
     752             : {
     753           8 :         int *pfd = (int *)private_data;
     754             : 
     755           8 :         TALLOC_FREE(te);
     756             : 
     757           8 :         if (*pfd != -1) {
     758           8 :                 close(*pfd);
     759           8 :                 *pfd = -1;
     760             :         }
     761           8 : }
     762             : 
     763             : struct lock_result_state {
     764             :         NTSTATUS status;
     765             :         bool done;
     766             : };
     767             : 
     768           8 : static void receive_lock_result(struct smbcli_request *req)
     769             : {
     770           8 :         struct lock_result_state *state =
     771             :                 (struct lock_result_state *)req->async.private_data;
     772             : 
     773           8 :         state->status = smbcli_request_simple_recv(req);
     774           8 :         state->done = true;
     775           8 : }
     776             : 
     777             : /*
     778             :  * Check that Samba3 correctly deals with conflicting local posix byte range
     779             :  * locks on an underlying file via "normal" SMB1 (without unix extensions).
     780             :  *
     781             :  * Note: This test depends on "posix locking = yes".
     782             :  * Note: To run this test, use "--option=torture:localdir=<LOCALDIR>"
     783             :  */
     784             : 
     785           8 : bool torture_samba3_posixtimedlock(struct torture_context *tctx, struct smbcli_state *cli)
     786             : {
     787           0 :         NTSTATUS status;
     788           8 :         bool ret = true;
     789           8 :         const char *dirname = "posixlock";
     790           8 :         const char *fname = "locked";
     791           0 :         const char *fpath;
     792           0 :         const char *localdir;
     793           0 :         const char *localname;
     794           8 :         int fnum = -1;
     795             : 
     796           8 :         int fd = -1;
     797           0 :         struct flock posix_lock;
     798             : 
     799           0 :         union smb_lock io;
     800           0 :         struct smb_lock_entry lock_entry;
     801           0 :         struct smbcli_request *req;
     802           0 :         struct lock_result_state lock_result;
     803             : 
     804           0 :         struct tevent_timer *te;
     805             : 
     806           8 :         torture_assert(tctx, torture_setup_dir(cli, dirname), "creating test directory");
     807             : 
     808           8 :         if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
     809           0 :                 torture_warning(tctx, "talloc failed\n");
     810           0 :                 ret = false;
     811           0 :                 goto done;
     812             :         }
     813           8 :         fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
     814           8 :         if (fnum == -1) {
     815           0 :                 torture_warning(tctx, "Could not create file %s: %s\n", fpath,
     816             :                                 smbcli_errstr(cli->tree));
     817           0 :                 ret = false;
     818           0 :                 goto done;
     819             :         }
     820             : 
     821           8 :         if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
     822           0 :                 torture_warning(tctx, "Need 'localdir' setting\n");
     823           0 :                 ret = false;
     824           0 :                 goto done;
     825             :         }
     826             : 
     827           8 :         if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
     828             :                                           fname))) {
     829           0 :                 torture_warning(tctx, "talloc failed\n");
     830           0 :                 ret = false;
     831           0 :                 goto done;
     832             :         }
     833             : 
     834             :         /*
     835             :          * Lock a byte range from posix
     836             :          */
     837             : 
     838           8 :         fd = open(localname, O_RDWR);
     839           8 :         if (fd == -1) {
     840           0 :                 torture_warning(tctx, "open(%s) failed: %s\n",
     841           0 :                                 localname, strerror(errno));
     842           0 :                 goto done;
     843             :         }
     844             : 
     845           8 :         posix_lock.l_type = F_WRLCK;
     846           8 :         posix_lock.l_whence = SEEK_SET;
     847           8 :         posix_lock.l_start = 0;
     848           8 :         posix_lock.l_len = 1;
     849             : 
     850           8 :         if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
     851           0 :                 torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
     852           0 :                 ret = false;
     853           0 :                 goto done;
     854             :         }
     855             : 
     856             :         /*
     857             :          * Try a cifs brlock without timeout to see if posix locking = yes
     858             :          */
     859             : 
     860           8 :         io.lockx.in.ulock_cnt = 0;
     861           8 :         io.lockx.in.lock_cnt = 1;
     862             : 
     863           8 :         lock_entry.count = 1;
     864           8 :         lock_entry.offset = 0;
     865           8 :         lock_entry.pid = cli->tree->session->pid;
     866             : 
     867           8 :         io.lockx.level = RAW_LOCK_LOCKX;
     868           8 :         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
     869           8 :         io.lockx.in.timeout = 0;
     870           8 :         io.lockx.in.locks = &lock_entry;
     871           8 :         io.lockx.in.file.fnum = fnum;
     872             : 
     873           8 :         status = smb_raw_lock(cli->tree, &io);
     874             : 
     875           8 :         ret = true;
     876           8 :         CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
     877             : 
     878           8 :         if (!ret) {
     879           0 :                 goto done;
     880             :         }
     881             : 
     882             :         /*
     883             :          * Now fire off a timed brlock, unlock the posix lock and see if the
     884             :          * timed lock gets through.
     885             :          */
     886             : 
     887           8 :         io.lockx.in.timeout = 5000;
     888             : 
     889           8 :         req = smb_raw_lock_send(cli->tree, &io);
     890           8 :         if (req == NULL) {
     891           0 :                 torture_warning(tctx, "smb_raw_lock_send failed\n");
     892           0 :                 ret = false;
     893           0 :                 goto done;
     894             :         }
     895             : 
     896           8 :         lock_result.done = false;
     897           8 :         req->async.fn = receive_lock_result;
     898           8 :         req->async.private_data = &lock_result;
     899             : 
     900           8 :         te = tevent_add_timer(tctx->ev,
     901             :                               tctx, timeval_current_ofs(1, 0),
     902             :                               close_locked_file, &fd);
     903           8 :         if (te == NULL) {
     904           0 :                 torture_warning(tctx, "tevent_add_timer failed\n");
     905           0 :                 ret = false;
     906           0 :                 goto done;
     907             :         }
     908             : 
     909          40 :         while ((fd != -1) || (!lock_result.done)) {
     910          32 :                 if (tevent_loop_once(tctx->ev) == -1) {
     911           0 :                         torture_warning(tctx, "tevent_loop_once failed: %s\n",
     912           0 :                                         strerror(errno));
     913           0 :                         ret = false;
     914           0 :                         goto done;
     915             :                 }
     916             :         }
     917             : 
     918           8 :         CHECK_STATUS(tctx, lock_result.status, NT_STATUS_OK);
     919             : 
     920           8 :  done:
     921           8 :         if (fnum != -1) {
     922           8 :                 smbcli_close(cli->tree, fnum);
     923             :         }
     924           8 :         if (fd != -1) {
     925           0 :                 close(fd);
     926             :         }
     927           8 :         smbcli_deltree(cli->tree, dirname);
     928           8 :         return ret;
     929             : }
     930             : 
     931           4 : bool torture_samba3_rootdirfid(struct torture_context *tctx, struct smbcli_state *cli)
     932             : {
     933           0 :         uint16_t dnum;
     934           0 :         union smb_open io;
     935           4 :         const char *fname = "testfile";
     936           4 :         bool ret = false;
     937             : 
     938           4 :         smbcli_unlink(cli->tree, fname);
     939             : 
     940           4 :         ZERO_STRUCT(io);
     941           4 :         io.generic.level = RAW_OPEN_NTCREATEX;
     942           4 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
     943           4 :         io.ntcreatex.in.root_fid.fnum = 0;
     944           4 :         io.ntcreatex.in.security_flags = 0;
     945           4 :         io.ntcreatex.in.access_mask =
     946             :                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
     947           4 :         io.ntcreatex.in.alloc_size = 0;
     948           4 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
     949           4 :         io.ntcreatex.in.share_access =
     950             :                 NTCREATEX_SHARE_ACCESS_READ
     951             :                 | NTCREATEX_SHARE_ACCESS_READ;
     952           4 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
     953           4 :         io.ntcreatex.in.create_options = 0;
     954           4 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     955           4 :         io.ntcreatex.in.fname = "\\";
     956           4 :         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io), 
     957             :                                            NT_STATUS_OK,
     958             :                                            ret, done, "smb_open on the directory failed: %s\n");
     959             : 
     960           4 :         dnum = io.ntcreatex.out.file.fnum;
     961             : 
     962           4 :         io.ntcreatex.in.flags =
     963             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK
     964             :                 | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
     965           4 :         io.ntcreatex.in.root_fid.fnum = dnum;
     966           4 :         io.ntcreatex.in.security_flags = 0;
     967           4 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
     968           4 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
     969           4 :         io.ntcreatex.in.alloc_size = 0;
     970           4 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
     971           4 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
     972           4 :         io.ntcreatex.in.create_options = 0;
     973           4 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
     974           4 :         io.ntcreatex.in.fname = fname;
     975             : 
     976           4 :         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
     977             :                                            NT_STATUS_OK,
     978             :                                            ret, done, "smb_open on the file failed");
     979             : 
     980           4 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
     981           4 :         smbcli_close(cli->tree, dnum);
     982           4 :         smbcli_unlink(cli->tree, fname);
     983             : 
     984           4 :         ret = true;
     985           4 :  done:
     986           4 :         return ret;
     987             : }
     988             : 
     989           4 : bool torture_samba3_rootdirfid2(struct torture_context *tctx, struct smbcli_state *cli)
     990             : {
     991           0 :         int fnum;
     992           0 :         uint16_t dnum;
     993           0 :         union smb_open io;
     994           4 :         const char *dirname1 = "dir1";
     995           4 :         const char *dirname2 = "dir1/dir2";
     996           4 :         const char *path = "dir1/dir2/testfile";
     997           4 :         const char *relname = "dir2/testfile";
     998           4 :         bool ret = false;
     999             : 
    1000           4 :         smbcli_deltree(cli->tree, dirname1);
    1001             : 
    1002           4 :         torture_assert(tctx, torture_setup_dir(cli, dirname1), "creating test directory");
    1003           4 :         torture_assert(tctx, torture_setup_dir(cli, dirname2), "creating test directory");
    1004             : 
    1005           4 :         fnum = smbcli_open(cli->tree, path, O_RDWR | O_CREAT, DENY_NONE);
    1006           4 :         if (fnum == -1) {
    1007           0 :                 torture_result(tctx, TORTURE_FAIL,
    1008             :                         "Could not create file: %s",
    1009             :                          smbcli_errstr(cli->tree));
    1010           0 :                 goto done;
    1011             :         }
    1012           4 :         smbcli_close(cli->tree, fnum);
    1013             : 
    1014           4 :         ZERO_STRUCT(io);
    1015           4 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1016           4 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1017           4 :         io.ntcreatex.in.root_fid.fnum = 0;
    1018           4 :         io.ntcreatex.in.security_flags = 0;
    1019           4 :         io.ntcreatex.in.access_mask =
    1020             :                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
    1021           4 :         io.ntcreatex.in.alloc_size = 0;
    1022           4 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1023           4 :         io.ntcreatex.in.share_access =
    1024             :                 NTCREATEX_SHARE_ACCESS_READ
    1025             :                 | NTCREATEX_SHARE_ACCESS_READ;
    1026           4 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1027           4 :         io.ntcreatex.in.create_options = 0;
    1028           4 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1029           4 :         io.ntcreatex.in.fname = dirname1;
    1030           4 :         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
    1031             :                                            NT_STATUS_OK,
    1032             :                                            ret, done, "smb_open on the directory failed: %s\n");
    1033             : 
    1034           4 :         dnum = io.ntcreatex.out.file.fnum;
    1035             : 
    1036           4 :         io.ntcreatex.in.flags =
    1037             :                 NTCREATEX_FLAGS_REQUEST_OPLOCK
    1038             :                 | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
    1039           4 :         io.ntcreatex.in.root_fid.fnum = dnum;
    1040           4 :         io.ntcreatex.in.security_flags = 0;
    1041           4 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1042           4 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1043           4 :         io.ntcreatex.in.alloc_size = 0;
    1044           4 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1045           4 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1046           4 :         io.ntcreatex.in.create_options = 0;
    1047           4 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1048           4 :         io.ntcreatex.in.fname = relname;
    1049             : 
    1050           4 :         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
    1051             :                                            NT_STATUS_OK,
    1052             :                                            ret, done, "smb_open on the file failed");
    1053             : 
    1054           4 :         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
    1055           4 :         smbcli_close(cli->tree, dnum);
    1056             : 
    1057           4 :         ret = true;
    1058           4 : done:
    1059           4 :         smbcli_deltree(cli->tree, dirname1);
    1060           4 :         return ret;
    1061             : }
    1062             : 
    1063           4 : bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_state *cli)
    1064             : {
    1065           0 :         union smb_open io;
    1066           4 :         const char *fname = "testfile";
    1067           4 :         bool ret = false;
    1068           0 :         struct smbcli_request *req;
    1069           0 :         struct smb_echo echo_req;
    1070             : 
    1071           4 :         smbcli_unlink(cli->tree, fname);
    1072             : 
    1073           4 :         ZERO_STRUCT(io);
    1074           4 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1075           4 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1076           4 :         io.ntcreatex.in.root_fid.fnum = 0;
    1077           4 :         io.ntcreatex.in.security_flags = 0;
    1078           4 :         io.ntcreatex.in.access_mask =
    1079             :                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
    1080           4 :         io.ntcreatex.in.alloc_size = 0;
    1081           4 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
    1082           4 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1083           4 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
    1084           4 :         io.ntcreatex.in.create_options = 0;
    1085           4 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1086           4 :         io.ntcreatex.in.fname = "testfile";
    1087           4 :         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
    1088             :                                            NT_STATUS_OK,
    1089             :                                            ret, done, "first smb_open on the file failed");
    1090             : 
    1091             :         /*
    1092             :          * Create a conflicting open, causing the one-second delay
    1093             :          */
    1094             : 
    1095           4 :         torture_assert_goto(tctx, req = smb_raw_open_send(cli->tree, &io),
    1096             :                             ret, done, "smb_raw_open_send on the file failed");
    1097             : 
    1098             :         /*
    1099             :          * Pull the VUID from under that request. As of Nov 3, 2008 all Samba3
    1100             :          * versions (3.0, 3.2 and master) would spin sending ERRinvuid errors
    1101             :          * as long as the client is still connected.
    1102             :          */
    1103             : 
    1104           4 :         torture_assert_ntstatus_equal_goto(tctx, smb_raw_ulogoff(cli->session),
    1105             :                                            NT_STATUS_OK,
    1106             :                                            ret, done, "ulogoff failed failed");
    1107             : 
    1108           4 :         echo_req.in.repeat_count = 1;
    1109           4 :         echo_req.in.size = 1;
    1110           4 :         echo_req.in.data = discard_const_p(uint8_t, "");
    1111             : 
    1112           4 :         torture_assert_ntstatus_equal_goto(tctx, smb_raw_echo(cli->session->transport, &echo_req),
    1113             :                                            NT_STATUS_OK,
    1114             :                                            ret, done, "smb_raw_echo failed");
    1115             : 
    1116           4 :         ret = true;
    1117           4 :  done:
    1118           4 :         return ret;
    1119             : }
    1120             : 
    1121           4 : bool torture_samba3_check_openX_badname(struct torture_context *tctx, struct smbcli_state *cli)
    1122             : {
    1123           0 :         NTSTATUS status;
    1124           4 :         bool ret = false;
    1125           4 :         int fnum = -1;
    1126           4 :         DATA_BLOB name_blob = data_blob_talloc(cli->tree, NULL, 65535);
    1127             : 
    1128           4 :         if (name_blob.data == NULL) {
    1129           0 :                 return false;
    1130             :         }
    1131           4 :         memset(name_blob.data, 0xcc, 65535);
    1132           4 :         status = raw_smbcli_openX_name_blob(cli->tree, &name_blob, O_RDWR, DENY_NONE, &fnum);
    1133           4 :         CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_INVALID);
    1134           4 :         ret = true;
    1135             : 
    1136           4 :         return ret;
    1137             : }

Generated by: LCOV version 1.14