LCOV - code coverage report
Current view: top level - source4/torture/basic - base.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 591 1118 52.9 %
Date: 2024-02-28 12:06:22 Functions: 17 23 73.9 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB torture tester
       4             :    Copyright (C) Andrew Tridgell 1997-2003
       5             :    Copyright (C) Jelmer Vernooij 2006
       6             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "torture/smbtorture.h"
      23             : #include "torture/basic/proto.h"
      24             : #include "libcli/libcli.h"
      25             : #include "libcli/raw/raw_proto.h"
      26             : #include "torture/util.h"
      27             : #include "system/filesys.h"
      28             : #include "system/time.h"
      29             : #include "libcli/resolve/resolve.h"
      30             : #include "lib/events/events.h"
      31             : #include "param/param.h"
      32             : 
      33             : 
      34             : #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
      35             : 
      36             : 
      37           6 : static struct smbcli_state *open_nbt_connection(struct torture_context *tctx)
      38             : {
      39           0 :         struct nbt_name called, calling;
      40           0 :         struct smbcli_state *cli;
      41           6 :         const char *host = torture_setting_string(tctx, "host", NULL);
      42           0 :         struct smbcli_options options;
      43           0 :         bool ok;
      44             : 
      45           6 :         make_nbt_name_client(&calling, lpcfg_netbios_name(tctx->lp_ctx));
      46             : 
      47           6 :         nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
      48             : 
      49           6 :         cli = smbcli_state_init(NULL);
      50           6 :         if (!cli) {
      51           0 :                 torture_result(tctx, TORTURE_FAIL, "Failed initialize smbcli_struct to connect with %s\n", host);
      52           0 :                 goto failed;
      53             :         }
      54             : 
      55           6 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
      56             : 
      57           6 :         ok = smbcli_socket_connect(cli, host, lpcfg_smb_ports(tctx->lp_ctx),
      58             :                                    tctx->ev,
      59             :                                    lpcfg_resolve_context(tctx->lp_ctx),
      60             :                                    &options,
      61             :                                    lpcfg_socket_options(tctx->lp_ctx),
      62             :                                    &calling, &called);
      63           6 :         if (!ok) {
      64           0 :                 torture_result(tctx, TORTURE_FAIL, "Failed to connect with %s\n", host);
      65           0 :                 goto failed;
      66             :         }
      67             : 
      68           6 :         cli->transport = smbcli_transport_init(cli->sock, cli,
      69             :                                                true, &cli->options);
      70           6 :         cli->sock = NULL;
      71           6 :         if (!cli->transport) {
      72           0 :                 torture_result(tctx, TORTURE_FAIL, "smbcli_transport_init failed\n");
      73           0 :                 goto failed;
      74             :         }
      75             : 
      76           6 :         return cli;
      77             : 
      78           0 : failed:
      79           0 :         talloc_free(cli);
      80           0 :         return NULL;
      81             : }
      82             : 
      83          70 : static bool tcon_devtest(struct torture_context *tctx, 
      84             :                                                  struct smbcli_state *cli,
      85             :                                                  const char *myshare, const char *devtype,
      86             :                                                  NTSTATUS expected_error)
      87             : {
      88          10 :         bool status;
      89          70 :         const char *password = torture_setting_string(tctx, "password", NULL);
      90             : 
      91          70 :         status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype, 
      92             :                                                 password));
      93             : 
      94          70 :         torture_comment(tctx, "Trying share %s with devtype %s\n", myshare, devtype);
      95             : 
      96          70 :         if (NT_STATUS_IS_OK(expected_error)) {
      97          28 :                 if (!status) {
      98           0 :                         torture_fail(tctx, talloc_asprintf(tctx, 
      99             :                                    "tconX to share %s with type %s "
     100             :                                "should have succeeded but failed",
     101             :                                myshare, devtype));
     102             :                 }
     103          28 :                 smbcli_tdis(cli);
     104             :         } else {
     105          42 :                 if (status) {
     106           0 :                         torture_fail(tctx, talloc_asprintf(tctx, 
     107             :                                    "tconx to share %s with type %s "
     108             :                                "should have failed but succeeded",
     109             :                                myshare, devtype));
     110             :                 } else {
     111          42 :                         if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
     112             :                                             expected_error)) {
     113             :                         } else {
     114           0 :                                 torture_fail(tctx, "Returned unexpected error");
     115             :                         }
     116             :                 }
     117             :         }
     118          60 :         return true;
     119             : }
     120             : 
     121             : 
     122             : 
     123             : /**
     124             : test whether fnums and tids open on one VC are available on another (a major
     125             : security hole)
     126             : */
     127           6 : static bool run_fdpasstest(struct torture_context *tctx,
     128             :                                                    struct smbcli_state *cli1, 
     129             :                                                    struct smbcli_state *cli2)
     130             : {
     131           6 :         const char *fname = "\\fdpass.tst";
     132           0 :         int fnum1, oldtid;
     133           0 :         uint8_t buf[1024];
     134             : 
     135           6 :         smbcli_unlink(cli1->tree, fname);
     136             : 
     137           6 :         torture_comment(tctx, "Opening a file on connection 1\n");
     138             : 
     139           6 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     140           6 :         torture_assert(tctx, fnum1 != -1, 
     141             :                         talloc_asprintf(tctx, 
     142             :                         "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));
     143             : 
     144           6 :         torture_comment(tctx, "writing to file on connection 1\n");
     145             : 
     146           6 :         torture_assert(tctx, 
     147             :                 smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) == 13,
     148             :                 talloc_asprintf(tctx, 
     149             :                 "write failed (%s)\n", smbcli_errstr(cli1->tree)));
     150             : 
     151           6 :         oldtid = cli2->tree->tid;
     152           6 :         cli2->session->vuid = cli1->session->vuid;
     153           6 :         cli2->tree->tid = cli1->tree->tid;
     154           6 :         cli2->session->pid = cli1->session->pid;
     155             : 
     156           6 :         torture_comment(tctx, "reading from file on connection 2\n");
     157             : 
     158           6 :         torture_assert(tctx, smbcli_read(cli2->tree, fnum1, buf, 0, 13) != 13,
     159             :                                    talloc_asprintf(tctx,
     160             :                 "read succeeded! nasty security hole [%s]\n", buf));
     161             : 
     162           6 :         smbcli_close(cli1->tree, fnum1);
     163           6 :         smbcli_unlink(cli1->tree, fname);
     164             : 
     165           6 :         cli2->tree->tid = oldtid;
     166             : 
     167           6 :         return true;
     168             : }
     169             : 
     170             : /**
     171             :   This checks how the getatr calls works
     172             : */
     173           7 : static bool run_attrtest(struct torture_context *tctx, 
     174             :                                                  struct smbcli_state *cli)
     175             : {
     176           1 :         int fnum;
     177           1 :         time_t t, t2;
     178           7 :         const char *fname = "\\attrib123456789.tst";
     179           7 :         bool correct = true;
     180             : 
     181           7 :         smbcli_unlink(cli->tree, fname);
     182           7 :         fnum = smbcli_open(cli->tree, fname, 
     183             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
     184           7 :         smbcli_close(cli->tree, fnum);
     185             : 
     186           7 :         if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
     187           0 :                 torture_result(tctx, TORTURE_FAIL, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
     188           0 :                 correct = false;
     189             :         }
     190             : 
     191           7 :         torture_comment(tctx, "New file time is %s", ctime(&t));
     192             : 
     193           7 :         if (labs(t - time(NULL)) > 60*60*24*10) {
     194           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: SMBgetatr bug. time is %s",
     195             :                        ctime(&t));
     196           0 :                 t = time(NULL);
     197           0 :                 correct = false;
     198             :         }
     199             : 
     200           7 :         t2 = t-60*60*24; /* 1 day ago */
     201             : 
     202           7 :         torture_comment(tctx, "Setting file time to %s", ctime(&t2));
     203             : 
     204           7 :         if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
     205           0 :                 torture_comment(tctx, "setatr failed (%s)\n", smbcli_errstr(cli->tree));
     206           0 :                 correct = true;
     207             :         }
     208             : 
     209           7 :         if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
     210           0 :                 torture_comment(tctx, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
     211           0 :                 correct = true;
     212             :         }
     213             : 
     214           7 :         torture_comment(tctx, "Retrieved file time as %s", ctime(&t));
     215             : 
     216           7 :         if (t != t2) {
     217           0 :                 torture_comment(tctx, "ERROR: getatr/setatr bug. times are\n%s",
     218             :                        ctime(&t));
     219           0 :                 torture_comment(tctx, "%s", ctime(&t2));
     220           0 :                 correct = true;
     221             :         }
     222             : 
     223           7 :         smbcli_unlink(cli->tree, fname);
     224             : 
     225           7 :         return correct;
     226             : }
     227             : 
     228             : /**
     229             :   This checks a couple of trans2 calls
     230             : */
     231           6 : static bool run_trans2test(struct torture_context *tctx, 
     232             :                                                    struct smbcli_state *cli)
     233             : {
     234           0 :         int fnum;
     235           0 :         size_t size;
     236           0 :         time_t c_time, a_time, m_time, w_time, m_time2;
     237           6 :         const char *fname = "\\trans2.tst";
     238           6 :         const char *dname = "\\trans2";
     239           6 :         const char *fname2 = "\\trans2\\trans2.tst";
     240           0 :         const char *pname;
     241           6 :         bool correct = true;
     242             : 
     243           6 :         smbcli_unlink(cli->tree, fname);
     244             : 
     245           6 :         torture_comment(tctx, "Testing qfileinfo\n");
     246             :         
     247           6 :         fnum = smbcli_open(cli->tree, fname, 
     248             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
     249           6 :         if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
     250             :                            NULL, NULL))) {
     251           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
     252           0 :                 correct = false;
     253             :         }
     254             : 
     255           6 :         torture_comment(tctx, "Testing NAME_INFO\n");
     256             : 
     257           6 :         if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
     258           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
     259           0 :                 correct = false;
     260             :         }
     261             : 
     262           6 :         if (!pname || strcmp(pname, fname)) {
     263           0 :                 torture_result(tctx, TORTURE_FAIL, "qfilename gave different name? [%s] [%s]\n",
     264             :                        fname, pname);
     265           0 :                 correct = false;
     266             :         }
     267             : 
     268           6 :         smbcli_close(cli->tree, fnum);
     269           6 :         smbcli_unlink(cli->tree, fname);
     270             : 
     271           6 :         fnum = smbcli_open(cli->tree, fname, 
     272             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
     273           6 :         if (fnum == -1) {
     274           0 :                 torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
     275           0 :                 return false;
     276             :         }
     277           6 :         smbcli_close(cli->tree, fnum);
     278             : 
     279           6 :         torture_comment(tctx, "Checking for sticky create times\n");
     280             : 
     281           6 :         if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
     282           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
     283           0 :                 correct = false;
     284             :         } else {
     285           6 :                 time_t t = time(NULL);
     286             : 
     287           6 :                 if (c_time != m_time) {
     288           0 :                         torture_comment(tctx, "create time=%s", ctime(&c_time));
     289           0 :                         torture_comment(tctx, "modify time=%s", ctime(&m_time));
     290           0 :                         torture_comment(tctx, "This system appears to have sticky create times\n");
     291             :                 }
     292           6 :                 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
     293           0 :                         torture_comment(tctx, "access time=%s", ctime(&a_time));
     294           0 :                         torture_result(tctx, TORTURE_FAIL, "This system appears to set a midnight access time\n");
     295           0 :                         correct = false;
     296             :                 }
     297             : 
     298           6 :                 if (labs(m_time - t) > 60*60*24*7) {
     299           0 :                         torture_result(tctx, TORTURE_FAIL, "ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
     300           0 :                         correct = false;
     301             :                 }
     302             :         }
     303             : 
     304             : 
     305           6 :         smbcli_unlink(cli->tree, fname);
     306           6 :         fnum = smbcli_open(cli->tree, fname, 
     307             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
     308           6 :         smbcli_close(cli->tree, fnum);
     309           6 :         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
     310           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
     311           0 :                 correct = false;
     312             :         } else {
     313           6 :                 if (w_time < 60*60*24*2) {
     314           0 :                         torture_comment(tctx, "write time=%s", ctime(&w_time));
     315           0 :                         torture_result(tctx, TORTURE_FAIL, "This system appears to set a initial 0 write time\n");
     316           0 :                         correct = false;
     317             :                 }
     318             :         }
     319             : 
     320           6 :         smbcli_unlink(cli->tree, fname);
     321             : 
     322             : 
     323             :         /* check if the server updates the directory modification time
     324             :            when creating a new file */
     325           6 :         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
     326           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
     327           0 :                 correct = false;
     328             :         }
     329           6 :         sleep(3);
     330           6 :         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
     331           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
     332           0 :                 correct = false;
     333             :         }
     334             : 
     335           6 :         fnum = smbcli_open(cli->tree, fname2, 
     336             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
     337           6 :         smbcli_write(cli->tree, fnum,  0, &fnum, 0, sizeof(fnum));
     338           6 :         smbcli_close(cli->tree, fnum);
     339           6 :         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
     340           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
     341           0 :                 correct = false;
     342             :         } else {
     343           6 :                 if (m_time2 == m_time) {
     344           0 :                         torture_result(tctx, TORTURE_FAIL, "This system does not update directory modification times\n");
     345           0 :                         correct = false;
     346             :                 }
     347             :         }
     348           6 :         smbcli_unlink(cli->tree, fname2);
     349           6 :         smbcli_rmdir(cli->tree, dname);
     350             : 
     351           6 :         return correct;
     352             : }
     353             : 
     354             : /* send smb negprot commands, not reading the response */
     355           6 : static bool run_negprot_nowait(struct torture_context *tctx)
     356             : {
     357           0 :         int i;
     358           0 :         struct smbcli_state *cli, *cli2;
     359           6 :         bool correct = true;
     360             : 
     361           6 :         torture_comment(tctx, "starting negprot nowait test\n");
     362             : 
     363           6 :         cli = open_nbt_connection(tctx);
     364           6 :         if (!cli) {
     365           0 :                 return false;
     366             :         }
     367             : 
     368           6 :         torture_comment(tctx, "Filling send buffer\n");
     369             : 
     370         606 :         for (i=0;i<100;i++) {
     371           0 :                 struct tevent_req *req;
     372         600 :                 req = smb_raw_negotiate_send(cli, tctx->ev,
     373             :                                              cli->transport,
     374             :                                              PROTOCOL_CORE,
     375             :                                              PROTOCOL_NT1);
     376         600 :                 tevent_loop_once(tctx->ev);
     377         600 :                 if (!tevent_req_is_in_progress(req)) {
     378           0 :                         NTSTATUS status;
     379             : 
     380           0 :                         status = smb_raw_negotiate_recv(req);
     381           0 :                         TALLOC_FREE(req);
     382           0 :                         if (i > 0) {
     383           0 :                                 torture_comment(tctx, "Failed to fill pipe packet[%d] - %s (ignored)\n",
     384             :                                                 i+1, nt_errstr(status));
     385           0 :                                 break;
     386             :                         } else {
     387           0 :                                 torture_result(tctx, TORTURE_FAIL, "Failed to fill pipe - %s \n",
     388             :                                                 nt_errstr(status));
     389           0 :                                 torture_close_connection(cli);
     390           0 :                                 return false;
     391             :                         }
     392             :                 }
     393             :         }
     394             : 
     395           6 :         torture_comment(tctx, "Opening secondary connection\n");
     396           6 :         if (!torture_open_connection(&cli2, tctx, 1)) {
     397           0 :                 torture_result(tctx, TORTURE_FAIL, "Failed to open secondary connection\n");
     398           0 :                 correct = false;
     399             :         }
     400             : 
     401           6 :         if (!torture_close_connection(cli2)) {
     402           0 :                 torture_result(tctx, TORTURE_FAIL, "Failed to close secondary connection\n");
     403           0 :                 correct = false;
     404             :         }
     405             : 
     406           6 :         torture_close_connection(cli);
     407             : 
     408           6 :         return correct;
     409             : }
     410             : 
     411             : /**
     412             :   this checks to see if a secondary tconx can use open files from an
     413             :   earlier tconx
     414             :  */
     415           7 : static bool run_tcon_test(struct torture_context *tctx, struct smbcli_state *cli)
     416             : {
     417           7 :         const char *fname = "\\tcontest.tmp";
     418           1 :         int fnum1;
     419           1 :         uint16_t cnum1, cnum2, cnum3;
     420           1 :         uint16_t vuid1, vuid2;
     421           1 :         uint8_t buf[4];
     422           7 :         bool ret = true;
     423           1 :         struct smbcli_tree *tree1;
     424           7 :         const char *host = torture_setting_string(tctx, "host", NULL);
     425           7 :         const char *share = torture_setting_string(tctx, "share", NULL);
     426           7 :         const char *password = torture_setting_string(tctx, "password", NULL);
     427             : 
     428           7 :         if (smbcli_deltree(cli->tree, fname) == -1) {
     429           0 :                 torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
     430             :         }
     431             : 
     432           7 :         fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     433           7 :         if (fnum1 == -1) {
     434           0 :                 torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
     435           0 :                 return false;
     436             :         }
     437             : 
     438           7 :         cnum1 = cli->tree->tid;
     439           7 :         vuid1 = cli->session->vuid;
     440             : 
     441           7 :         memset(buf, 0, 4); /* init buf so valgrind won't complain */
     442           7 :         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
     443           0 :                 torture_result(tctx, TORTURE_FAIL, "initial write failed (%s)\n", smbcli_errstr(cli->tree));
     444           0 :                 return false;
     445             :         }
     446             : 
     447           7 :         tree1 = cli->tree;   /* save old tree connection */
     448           7 :         if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
     449           0 :                 torture_result(tctx, TORTURE_FAIL, "%s refused 2nd tree connect (%s)\n", host,
     450             :                            smbcli_errstr(cli->tree));
     451           0 :                 return false;
     452             :         }
     453             : 
     454           7 :         cnum2 = cli->tree->tid;
     455           7 :         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
     456           7 :         vuid2 = cli->session->vuid + 1;
     457             : 
     458             :         /* try a write with the wrong tid */
     459           7 :         cli->tree->tid = cnum2;
     460             : 
     461           7 :         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
     462           0 :                 torture_result(tctx, TORTURE_FAIL, "* server allows write with wrong TID\n");
     463           0 :                 ret = false;
     464             :         } else {
     465           7 :                 torture_comment(tctx, "server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
     466             :         }
     467             : 
     468             : 
     469             :         /* try a write with an invalid tid */
     470           7 :         cli->tree->tid = cnum3;
     471             : 
     472           7 :         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
     473           0 :                 torture_result(tctx, TORTURE_FAIL, "* server allows write with invalid TID\n");
     474           0 :                 ret = false;
     475             :         } else {
     476           7 :                 torture_comment(tctx, "server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
     477             :         }
     478             : 
     479             :         /* try a write with an invalid vuid */
     480           7 :         cli->session->vuid = vuid2;
     481           7 :         cli->tree->tid = cnum1;
     482             : 
     483           7 :         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
     484           0 :                 torture_result(tctx, TORTURE_FAIL, "* server allows write with invalid VUID\n");
     485           0 :                 ret = false;
     486             :         } else {
     487           7 :                 torture_comment(tctx, "server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
     488             :         }
     489             : 
     490           7 :         cli->session->vuid = vuid1;
     491           7 :         cli->tree->tid = cnum1;
     492             : 
     493           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
     494           0 :                 torture_result(tctx, TORTURE_FAIL, "close failed (%s)\n", smbcli_errstr(cli->tree));
     495           0 :                 return false;
     496             :         }
     497             : 
     498           7 :         cli->tree->tid = cnum2;
     499             : 
     500           7 :         if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
     501           0 :                 torture_result(tctx, TORTURE_FAIL, "secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
     502           0 :                 return false;
     503             :         }
     504             : 
     505           7 :         cli->tree = tree1;  /* restore initial tree */
     506           7 :         cli->tree->tid = cnum1;
     507             : 
     508           7 :         smbcli_unlink(tree1, fname);
     509             : 
     510           7 :         return ret;
     511             : }
     512             : 
     513             : /**
     514             :  checks for correct tconX support
     515             :  */
     516           7 : static bool run_tcon_devtype_test(struct torture_context *tctx, 
     517             :                                                                   struct smbcli_state *cli1)
     518             : {
     519           7 :         const char *share = torture_setting_string(tctx, "share", NULL);
     520             : 
     521           7 :         if (!tcon_devtest(tctx, cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
     522           0 :                 return false;
     523             : 
     524           7 :         if (!tcon_devtest(tctx, cli1, "IPC$", "?????", NT_STATUS_OK))
     525           0 :                 return false;
     526             : 
     527           7 :         if (!tcon_devtest(tctx, cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
     528           0 :                 return false;
     529             : 
     530           7 :         if (!tcon_devtest(tctx, cli1, "IPC$", "IPC", NT_STATUS_OK))
     531           0 :                 return false;
     532             :                         
     533           7 :         if (!tcon_devtest(tctx, cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
     534           0 :                 return false;
     535             : 
     536           7 :         if (!tcon_devtest(tctx, cli1, share, "A:", NT_STATUS_OK))
     537           0 :                 return false;
     538             : 
     539           7 :         if (!tcon_devtest(tctx, cli1, share, "?????", NT_STATUS_OK))
     540           0 :                 return false;
     541             : 
     542           7 :         if (!tcon_devtest(tctx, cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
     543           0 :                 return false;
     544             : 
     545           7 :         if (!tcon_devtest(tctx, cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
     546           0 :                 return false;
     547             :                         
     548           7 :         if (!tcon_devtest(tctx, cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
     549           0 :                 return false;
     550             : 
     551           7 :         return true;
     552             : }
     553             : 
     554          22 : static bool rw_torture2(struct torture_context *tctx,
     555             :                                                 struct smbcli_state *c1, struct smbcli_state *c2)
     556             : {
     557          22 :         const char *lockfname = "\\torture2.lck";
     558           0 :         int fnum1;
     559           0 :         int fnum2;
     560           0 :         int i;
     561           0 :         uint8_t buf[131072];
     562           0 :         uint8_t buf_rd[131072];
     563          22 :         bool correct = true;
     564           0 :         ssize_t bytes_read, bytes_written;
     565             : 
     566          22 :         torture_assert(tctx, smbcli_deltree(c1->tree, lockfname) != -1,
     567             :                                    talloc_asprintf(tctx, 
     568             :                 "unlink failed (%s)", smbcli_errstr(c1->tree)));
     569             : 
     570          22 :         fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL, 
     571             :                          DENY_NONE);
     572          22 :         torture_assert(tctx, fnum1 != -1, 
     573             :                                    talloc_asprintf(tctx, 
     574             :                 "first open read/write of %s failed (%s)",
     575             :                                 lockfname, smbcli_errstr(c1->tree)));
     576          22 :         fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY, 
     577             :                          DENY_NONE);
     578          22 :         torture_assert(tctx, fnum2 != -1, 
     579             :                                    talloc_asprintf(tctx, 
     580             :                 "second open read-only of %s failed (%s)",
     581             :                                 lockfname, smbcli_errstr(c2->tree)));
     582             : 
     583          22 :         torture_comment(tctx, "Checking data integrity over %d ops\n", 
     584             :                                         torture_numops);
     585             : 
     586         242 :         for (i=0;i<torture_numops;i++)
     587             :         {
     588         220 :                 size_t buf_size = ((unsigned int)random()%(sizeof(buf)-1))+ 1;
     589         220 :                 if (i % 10 == 0) {
     590          22 :                         if (torture_setting_bool(tctx, "progress", true)) {
     591           0 :                                 torture_comment(tctx, "%d\r", i); fflush(stdout);
     592             :                         }
     593             :                 }
     594             : 
     595         220 :                 generate_random_buffer(buf, buf_size);
     596             : 
     597         220 :                 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
     598           0 :                         torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c1->tree));
     599           0 :                         torture_result(tctx, TORTURE_FAIL, "wrote %d, expected %d\n", (int)bytes_written, (int)buf_size); 
     600           0 :                         correct = false;
     601           0 :                         break;
     602             :                 }
     603             : 
     604         220 :                 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
     605           0 :                         torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c2->tree));
     606           0 :                         torture_result(tctx, TORTURE_FAIL, "read %d, expected %d\n", (int)bytes_read, (int)buf_size); 
     607           0 :                         correct = false;
     608           0 :                         break;
     609             :                 }
     610             : 
     611         220 :                 torture_assert_mem_equal(tctx, buf_rd, buf, buf_size, 
     612             :                         "read/write compare failed\n");
     613             :         }
     614             : 
     615          22 :         torture_assert_ntstatus_ok(tctx, smbcli_close(c2->tree, fnum2), 
     616             :                 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c2->tree)));
     617          22 :         torture_assert_ntstatus_ok(tctx, smbcli_close(c1->tree, fnum1),
     618             :                 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c1->tree)));
     619             : 
     620          22 :         torture_assert_ntstatus_ok(tctx, smbcli_unlink(c1->tree, lockfname),
     621             :                 talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(c1->tree)));
     622             : 
     623          22 :         torture_comment(tctx, "\n");
     624             : 
     625          22 :         return correct;
     626             : }
     627             : 
     628             : 
     629             : 
     630          11 : static bool run_readwritetest(struct torture_context *tctx,
     631             :                                                           struct smbcli_state *cli1,
     632             :                                                           struct smbcli_state *cli2)
     633             : {
     634          11 :         torture_comment(tctx, "Running readwritetest v1\n");
     635          11 :         if (!rw_torture2(tctx, cli1, cli2)) 
     636           0 :                 return false;
     637             : 
     638          11 :         torture_comment(tctx, "Running readwritetest v2\n");
     639             : 
     640          11 :         if (!rw_torture2(tctx, cli1, cli1))
     641           0 :                 return false;
     642             : 
     643          11 :         return true;
     644             : }
     645             : 
     646             : /*
     647             : test the timing of deferred open requests
     648             : */
     649           0 : static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
     650             : {
     651           0 :         const char *fname = "\\defer_open_test.dat";
     652           0 :         int i = 0;
     653           0 :         bool correct = true;
     654           0 :         int nsec;
     655           0 :         int msec;
     656           0 :         double sec;
     657           0 :         NTSTATUS status;
     658             : 
     659           0 :         nsec = torture_setting_int(tctx, "sharedelay", 1000000);
     660           0 :         msec = nsec / 1000;
     661           0 :         sec = ((double)nsec) / ((double) 1000000);
     662             : 
     663           0 :         torture_comment(tctx, "pid %u: Testing deferred open requests.\n",
     664           0 :                         (unsigned)getpid());
     665             : 
     666           0 :         while (i < 4) {
     667           0 :                 int fnum = -1;
     668           0 :                 int j = 1;
     669             : 
     670           0 :                 do {
     671           0 :                         struct timeval tv;
     672           0 :                         tv = timeval_current();
     673             : 
     674           0 :                         torture_comment(tctx,
     675             :                                         "pid %u: create[%d,%d]...\n",
     676           0 :                                         (unsigned)getpid(), i, j);
     677             : 
     678           0 :                         fnum = smbcli_nt_create_full(cli->tree, fname, 0, 
     679             :                                                      SEC_RIGHTS_FILE_ALL,
     680             :                                                      FILE_ATTRIBUTE_NORMAL, 
     681             :                                                      NTCREATEX_SHARE_ACCESS_NONE,
     682             :                                                      NTCREATEX_DISP_OPEN_IF, 0, 0);
     683           0 :                         status = smbcli_nt_error(cli->tree);
     684             : 
     685           0 :                         torture_comment(tctx,
     686             :                                         "pid %u: create[%d,%d] gave fnum %d, status %s\n",
     687           0 :                                         (unsigned)getpid(), i, j, fnum,
     688             :                                         nt_errstr(status));
     689             : 
     690           0 :                         if (fnum != -1) {
     691           0 :                                 break;
     692             :                         }
     693             : 
     694           0 :                         if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
     695           0 :                                 double e = timeval_elapsed(&tv);
     696             : 
     697           0 :                                 torture_comment(tctx, "pid %u: create[%d,%d] "
     698             :                                                 "time elapsed: %.2f (1 sec = %.2f)\n",
     699           0 :                                                 (unsigned)getpid(), i, j, e, sec);
     700           0 :                                 if (e < (0.5 * sec) || e > ((1.5 * sec) + 1.5)) {
     701           0 :                                         torture_comment(tctx, "pid %u: create[%d,%d] "
     702             :                                                         "timing incorrect\n",
     703           0 :                                                         (unsigned)getpid(), i, j);
     704           0 :                                         torture_result(tctx, TORTURE_FAIL, "Timing incorrect %.2f violation 1 sec == %.2f\n",
     705             :                                                 e, sec);
     706           0 :                                         return false;
     707             :                                 }
     708             :                         }
     709             : 
     710           0 :                         j++;
     711             : 
     712           0 :                 } while (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
     713             : 
     714           0 :                 torture_comment(tctx,
     715             :                                 "pid %u: create loop %d done: fnum %d, status %s\n",
     716           0 :                                 (unsigned)getpid(), i, fnum, nt_errstr(status));
     717             : 
     718           0 :                 torture_assert(tctx, fnum != -1,
     719             :                                talloc_asprintf(tctx,
     720             :                                         "pid %u: Failed to open %s, error=%s\n",
     721             :                                         (unsigned)getpid(), fname,
     722             :                                         smbcli_errstr(cli->tree)));
     723             : 
     724           0 :                 torture_comment(tctx, "pid %u: open %d\n", (unsigned)getpid(), i);
     725             : 
     726           0 :                 smb_msleep(10 * msec);
     727             : 
     728           0 :                 status = smbcli_close(cli->tree, fnum);
     729             : 
     730           0 :                 torture_comment(tctx, "pid %u: open %d closed, status %s\n",
     731           0 :                                 (unsigned)getpid(), i, nt_errstr(status));
     732             : 
     733           0 :                 torture_assert(tctx, !NT_STATUS_IS_ERR(status),
     734             :                                talloc_asprintf(tctx,
     735             :                                                "pid %u: Failed to close %s, "
     736             :                                                "error=%s\n",
     737             :                                                (unsigned)getpid(), fname,
     738             :                                                smbcli_errstr(cli->tree)));
     739             : 
     740           0 :                 smb_msleep(2 * msec);
     741             : 
     742           0 :                 i++;
     743             :         }
     744             : 
     745           0 :         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
     746             :                 /* All until the last unlink will fail with sharing violation
     747             :                    but also the last request can fail since the file could have
     748             :                    been successfully deleted by another (test) process */
     749           0 :                 status = smbcli_nt_error(cli->tree);
     750           0 :                 if ((!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION))
     751           0 :                         && (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND))) {
     752           0 :                         torture_result(tctx, TORTURE_FAIL, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
     753           0 :                         correct = false;
     754             :                 }
     755             :         }
     756             : 
     757           0 :         torture_comment(tctx, "pid %u: deferred test finished\n",
     758           0 :                         (unsigned)getpid());
     759           0 :         return correct;
     760             : }
     761             : 
     762             : /**
     763             :   Try with a wrong vuid and check error message.
     764             :  */
     765             : 
     766           6 : static bool run_vuidtest(struct torture_context *tctx, 
     767             :                                                  struct smbcli_state *cli)
     768             : {
     769           6 :         const char *fname = "\\vuid.tst";
     770           0 :         int fnum;
     771           0 :         size_t size;
     772           0 :         time_t c_time, a_time, m_time;
     773             : 
     774           0 :         NTSTATUS result;
     775             : 
     776           6 :         smbcli_unlink(cli->tree, fname);
     777             : 
     778           6 :         fnum = smbcli_open(cli->tree, fname, 
     779             :                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
     780             : 
     781           6 :         cli->session->vuid += 1234;
     782             : 
     783           6 :         torture_comment(tctx, "Testing qfileinfo with wrong vuid\n");
     784             :         
     785           6 :         if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
     786             :                                                    &size, &c_time, &a_time,
     787             :                                                    &m_time, NULL, NULL))) {
     788           0 :                 torture_fail(tctx, "qfileinfo passed with wrong vuid");
     789             :         }
     790             : 
     791           6 :         if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status, 
     792           2 :                              NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
     793           2 :             !NT_STATUS_EQUAL(cli->transport->error.e.nt_status, 
     794             :                              NT_STATUS_INVALID_HANDLE)) {
     795           0 :                 torture_fail(tctx, talloc_asprintf(tctx, 
     796             :                                 "qfileinfo should have returned DOS error "
     797             :                        "ERRSRV:ERRbaduid\n  but returned %s",
     798             :                        smbcli_errstr(cli->tree)));
     799             :         }
     800             : 
     801           6 :         cli->session->vuid -= 1234;
     802             : 
     803           6 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum),
     804             :                 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(cli->tree)));
     805             : 
     806           6 :         smbcli_unlink(cli->tree, fname);
     807             : 
     808           6 :         return true;
     809             : }
     810             : 
     811             : /*
     812             :   Test open mode returns on read-only files.
     813             :  */
     814           7 :  static bool run_opentest(struct torture_context *tctx, struct smbcli_state *cli1, 
     815             :                                                   struct smbcli_state *cli2)
     816             : {
     817           7 :         const char *fname = "\\readonly.file";
     818           1 :         char *control_char_fname;
     819           1 :         int fnum1, fnum2;
     820           1 :         uint8_t buf[20];
     821           1 :         size_t fsize;
     822           7 :         bool correct = true;
     823           1 :         char *tmp_path;
     824           7 :         int failures = 0;
     825           1 :         int i;
     826             : 
     827           7 :         control_char_fname = talloc_strdup(tctx, "\\readonly.afile");
     828           7 :         torture_assert_not_null(tctx, control_char_fname, "asprintf failed\n");
     829             : 
     830         224 :         for (i = 1; i <= 0x1f; i++) {
     831         217 :                 control_char_fname[10] = i;
     832         217 :                 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
     833             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
     834             :                 
     835         217 :                 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname, 
     836         217 :                                 NT_STATUS_OBJECT_NAME_INVALID)) {
     837           0 :                         torture_result(tctx, TORTURE_FAIL, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
     838             :                                         smbcli_errstr(cli1->tree), i);
     839           0 :                         failures++;
     840             :                 }
     841             : 
     842         217 :                 if (fnum1 != -1) {
     843           0 :                         smbcli_close(cli1->tree, fnum1);
     844             :                 }
     845         217 :                 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
     846         217 :                 smbcli_unlink(cli1->tree, control_char_fname);
     847             :         }
     848           7 :         TALLOC_FREE(control_char_fname);
     849             : 
     850           7 :         if (!failures)
     851           7 :                 torture_comment(tctx, "Create file with control char names passed.\n");
     852             : 
     853           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
     854           7 :         smbcli_unlink(cli1->tree, fname);
     855             :         
     856           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     857           7 :         if (fnum1 == -1) {
     858           0 :                 torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
     859           0 :                 return false;
     860             :         }
     861             : 
     862           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
     863           0 :                 torture_result(tctx, TORTURE_FAIL, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
     864           0 :                 return false;
     865             :         }
     866             :         
     867           7 :         if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
     868           0 :                 torture_result(tctx, TORTURE_FAIL,
     869             :                         __location__ ": smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
     870           0 :                 CHECK_MAX_FAILURES(error_test1);
     871           0 :                 return false;
     872             :         }
     873             :         
     874           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
     875           7 :         if (fnum1 == -1) {
     876           0 :                 torture_result(tctx, TORTURE_FAIL,
     877             :                         __location__ ": open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
     878           0 :                 CHECK_MAX_FAILURES(error_test1);
     879           0 :                 return false;
     880             :         }
     881             :         
     882             :         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
     883           7 :         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
     884             :         
     885           7 :         if (check_error(__location__, cli1, ERRDOS, ERRnoaccess, 
     886           7 :                         NT_STATUS_ACCESS_DENIED)) {
     887           5 :                 torture_comment(tctx, "correct error code ERRDOS/ERRnoaccess returned\n");
     888             :         }
     889             :         
     890           7 :         torture_comment(tctx, "finished open test 1\n");
     891             : 
     892           7 : error_test1:
     893           7 :         smbcli_close(cli1->tree, fnum1);
     894             :         
     895             :         /* Now try not readonly and ensure ERRbadshare is returned. */
     896             :         
     897           7 :         smbcli_setatr(cli1->tree, fname, 0, 0);
     898             :         
     899           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
     900           7 :         if (fnum1 == -1) {
     901           0 :                 torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
     902           0 :                 return false;
     903             :         }
     904             :         
     905             :         /* This will fail - but the error should be ERRshare. */
     906           7 :         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
     907             :         
     908           7 :         if (check_error(__location__, cli1, ERRDOS, ERRbadshare, 
     909           7 :                         NT_STATUS_SHARING_VIOLATION)) {
     910           7 :                 torture_comment(tctx, "correct error code ERRDOS/ERRbadshare returned\n");
     911             :         }
     912             :         
     913           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
     914           0 :                 torture_result(tctx, TORTURE_FAIL, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
     915           0 :                 return false;
     916             :         }
     917             :         
     918           7 :         smbcli_unlink(cli1->tree, fname);
     919             :         
     920           7 :         torture_comment(tctx, "finished open test 2\n");
     921             :         
     922             :         /* Test truncate open disposition on file opened for read. */
     923             :         
     924           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     925           7 :         if (fnum1 == -1) {
     926           0 :                 torture_result(tctx, TORTURE_FAIL, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
     927           0 :                 return false;
     928             :         }
     929             :         
     930             :         /* write 20 bytes. */
     931             :         
     932           7 :         memset(buf, '\0', 20);
     933             : 
     934           7 :         if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
     935           0 :                 torture_result(tctx, TORTURE_FAIL, "write failed (%s)\n", smbcli_errstr(cli1->tree));
     936           0 :                 correct = false;
     937             :         }
     938             : 
     939           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
     940           0 :                 torture_result(tctx, TORTURE_FAIL, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
     941           0 :                 return false;
     942             :         }
     943             :         
     944             :         /* Ensure size == 20. */
     945           7 :         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
     946           0 :                 torture_result(tctx, TORTURE_FAIL,
     947             :                         __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
     948           0 :                 CHECK_MAX_FAILURES(error_test3);
     949           0 :                 return false;
     950             :         }
     951             :         
     952           7 :         if (fsize != 20) {
     953           0 :                 torture_result(tctx, TORTURE_FAIL,
     954             :                         __location__ ": (3) file size != 20\n");
     955           0 :                 CHECK_MAX_FAILURES(error_test3);
     956           0 :                 return false;
     957             :         }
     958             : 
     959             :         /* Now test if we can truncate a file opened for readonly. */
     960             :         
     961           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
     962           7 :         if (fnum1 == -1) {
     963           0 :                 torture_result(tctx, TORTURE_FAIL,
     964             :                         __location__ ": (3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
     965           0 :                 CHECK_MAX_FAILURES(error_test3);
     966           0 :                 return false;
     967             :         }
     968             :         
     969           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
     970           0 :                 torture_result(tctx, TORTURE_FAIL,
     971             :                         __location__ ": close2 failed (%s)\n", smbcli_errstr(cli1->tree));
     972           0 :                 return false;
     973             :         }
     974             : 
     975             :         /* Ensure size == 0. */
     976           7 :         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
     977           0 :                 torture_result(tctx, TORTURE_FAIL,
     978             :                         __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
     979           0 :                 CHECK_MAX_FAILURES(error_test3);
     980           0 :                 return false;
     981             :         }
     982             : 
     983           7 :         if (fsize != 0) {
     984           0 :                 torture_result(tctx, TORTURE_FAIL,
     985             :                         __location__ ": (3) file size != 0\n");
     986           0 :                 CHECK_MAX_FAILURES(error_test3);
     987           0 :                 return false;
     988             :         }
     989           7 :         torture_comment(tctx, "finished open test 3\n");
     990           7 : error_test3:    
     991             : 
     992           7 :         fnum1 = fnum2 = -1;
     993           7 :         smbcli_unlink(cli1->tree, fname);
     994             : 
     995             : 
     996           7 :         torture_comment(tctx, "Testing ctemp\n");
     997           7 :         fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
     998           7 :         if (fnum1 == -1) {
     999           0 :                 torture_result(tctx, TORTURE_FAIL,
    1000             :                         __location__ ": ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
    1001           0 :                 CHECK_MAX_FAILURES(error_test4);
    1002           0 :                 return false;
    1003             :         }
    1004           7 :         torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
    1005             : 
    1006           7 : error_test4:
    1007           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1008           0 :                 torture_comment(tctx, "close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
    1009             :         }
    1010           7 :         if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
    1011           0 :                 torture_comment(tctx, "unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
    1012             :         }
    1013             : 
    1014             :         /* Test the non-io opens... */
    1015             : 
    1016           7 :         torture_comment(tctx, "Test #1 testing 2 non-io opens (no delete)\n");
    1017           7 :         fnum1 = fnum2 = -1;
    1018           7 :         smbcli_setatr(cli2->tree, fname, 0, 0);
    1019           7 :         smbcli_unlink(cli2->tree, fname);
    1020             : 
    1021           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1022             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    1023             : 
    1024           7 :         if (fnum1 == -1) {
    1025           0 :                 torture_result(tctx, TORTURE_FAIL,
    1026             :                         __location__ ": Test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1027           0 :                 CHECK_MAX_FAILURES(error_test10);
    1028           0 :                 return false;
    1029             :         }
    1030             : 
    1031           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1032             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
    1033           7 :         if (fnum2 == -1) {
    1034           0 :                 torture_result(tctx, TORTURE_FAIL,
    1035             :                         __location__ ": Test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1036           0 :                 CHECK_MAX_FAILURES(error_test10);
    1037           0 :                 return false;
    1038             :         }
    1039             : 
    1040           7 :         torture_comment(tctx, "non-io open test #1 passed.\n");
    1041           7 : error_test10:
    1042             : 
    1043           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1044           0 :                 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1045             :         }
    1046           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
    1047           0 :                 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1048             :         }
    1049             : 
    1050           7 :         torture_comment(tctx, "Test #2 testing 2 non-io opens (first with delete)\n");
    1051           7 :         fnum1 = fnum2 = -1;
    1052           7 :         smbcli_unlink(cli1->tree, fname);
    1053             : 
    1054           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1055             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    1056             : 
    1057           7 :         if (fnum1 == -1) {
    1058           0 :                 torture_result(tctx, TORTURE_FAIL,
    1059             :                         __location__ ": Test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1060           0 :                 CHECK_MAX_FAILURES(error_test20);
    1061           0 :                 return false;
    1062             :         }
    1063             : 
    1064           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1065             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
    1066             : 
    1067           7 :         if (fnum2 == -1) {
    1068           0 :                 torture_result(tctx, TORTURE_FAIL,
    1069             :                         __location__ ": Test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1070           0 :                 CHECK_MAX_FAILURES(error_test20);
    1071           0 :                 return false;
    1072             :         }
    1073             : 
    1074           7 :         torture_comment(tctx, "non-io open test #2 passed.\n");
    1075           7 : error_test20:
    1076             : 
    1077           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1078           0 :                 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1079             :         }
    1080           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
    1081           0 :                 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1082             :         }
    1083             : 
    1084           7 :         fnum1 = fnum2 = -1;
    1085           7 :         smbcli_unlink(cli1->tree, fname);
    1086             : 
    1087           7 :         torture_comment(tctx, "Test #3 testing 2 non-io opens (second with delete)\n");
    1088             : 
    1089           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1090             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    1091             : 
    1092           7 :         if (fnum1 == -1) {
    1093           0 :                 torture_result(tctx, TORTURE_FAIL,
    1094             :                         __location__ ": Test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1095           0 :                 CHECK_MAX_FAILURES(error_test30);
    1096           0 :                 return false;
    1097             :         }
    1098             : 
    1099           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1100             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
    1101             : 
    1102           7 :         if (fnum2 == -1) {
    1103           0 :                 torture_result(tctx, TORTURE_FAIL,
    1104             :                         __location__ ": Test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1105           0 :                 CHECK_MAX_FAILURES(error_test30);
    1106           0 :                 return false;
    1107             :         }
    1108             : 
    1109           7 :         torture_comment(tctx, "non-io open test #3 passed.\n");
    1110           7 : error_test30:
    1111             : 
    1112           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1113           0 :                 torture_comment(tctx, "Test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1114             :         }
    1115           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
    1116           0 :                 torture_comment(tctx, "Test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1117             :         }
    1118             : 
    1119           7 :         torture_comment(tctx, "Test #4 testing 2 non-io opens (both with delete)\n");
    1120           7 :         fnum1 = fnum2 = -1;
    1121           7 :         smbcli_unlink(cli1->tree, fname);
    1122             : 
    1123           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1124             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    1125             : 
    1126           7 :         if (fnum1 == -1) {
    1127           0 :                 torture_result(tctx, TORTURE_FAIL,
    1128             :                         __location__ ": Test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1129           0 :                 CHECK_MAX_FAILURES(error_test40);
    1130           0 :                 return false;
    1131             :         }
    1132             : 
    1133           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1134             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
    1135             : 
    1136           7 :         if (fnum2 != -1) {
    1137           0 :                 torture_result(tctx, TORTURE_FAIL,
    1138             :                         __location__ ": Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1139           0 :                 CHECK_MAX_FAILURES(error_test40);
    1140           0 :                 return false;
    1141             :         }
    1142             : 
    1143           7 :         torture_comment(tctx, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
    1144             : 
    1145           7 :         torture_comment(tctx, "non-io open test #4 passed.\n");
    1146           7 : error_test40:
    1147             : 
    1148           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1149           0 :                 torture_comment(tctx, "Test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1150             :         }
    1151           7 :         if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
    1152           0 :                 torture_comment(tctx, "Test 4 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1153             :         }
    1154             : 
    1155           7 :         torture_comment(tctx, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
    1156           7 :         fnum1 = fnum2 = -1;
    1157           7 :         smbcli_unlink(cli1->tree, fname);
    1158             : 
    1159           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1160             :                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    1161             : 
    1162           7 :         if (fnum1 == -1) {
    1163           0 :                 torture_result(tctx, TORTURE_FAIL,
    1164             :                         __location__ ": Test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1165           0 :                 CHECK_MAX_FAILURES(error_test50);
    1166           0 :                 return false;
    1167             :         }
    1168             : 
    1169           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1170             :                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
    1171             : 
    1172           7 :         if (fnum2 == -1) {
    1173           0 :                 torture_result(tctx, TORTURE_FAIL,
    1174             :                         __location__ ": Test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1175           0 :                 CHECK_MAX_FAILURES(error_test50);
    1176           0 :                 return false;
    1177             :         }
    1178             : 
    1179           7 :         torture_comment(tctx, "non-io open test #5 passed.\n");
    1180           7 : error_test50:
    1181             : 
    1182           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1183           0 :                 torture_comment(tctx, "Test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1184             :         }
    1185             : 
    1186           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
    1187           0 :                 torture_comment(tctx, "Test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1188             :         }
    1189             : 
    1190           7 :         torture_comment(tctx, "Test #6 testing 1 non-io open, one io open\n");
    1191           7 :         fnum1 = fnum2 = -1;
    1192           7 :         smbcli_unlink(cli1->tree, fname);
    1193             : 
    1194           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
    1195             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    1196             : 
    1197           7 :         if (fnum1 == -1) {
    1198           0 :                 torture_result(tctx, TORTURE_FAIL,
    1199             :                         __location__ ": Test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1200           0 :                 CHECK_MAX_FAILURES(error_test60);
    1201           0 :                 return false;
    1202             :         }
    1203             : 
    1204           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1205             :                                    NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
    1206             : 
    1207           7 :         if (fnum2 == -1) {
    1208           0 :                 torture_result(tctx, TORTURE_FAIL,
    1209             :                         __location__ ": Test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1210           0 :                 CHECK_MAX_FAILURES(error_test60);
    1211           0 :                 return false;
    1212             :         }
    1213             : 
    1214           7 :         torture_comment(tctx, "non-io open test #6 passed.\n");
    1215           7 : error_test60:
    1216             : 
    1217           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1218           0 :                 torture_comment(tctx, "Test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1219             :         }
    1220             : 
    1221           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
    1222           0 :                 torture_comment(tctx, "Test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1223             :         }
    1224             : 
    1225           7 :         torture_comment(tctx, "Test #7 testing 1 non-io open, one io open with delete\n");
    1226           7 :         fnum1 = fnum2 = -1;
    1227           7 :         smbcli_unlink(cli1->tree, fname);
    1228             : 
    1229           7 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
    1230             :                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
    1231             : 
    1232           7 :         if (fnum1 == -1) {
    1233           0 :                 torture_result(tctx, TORTURE_FAIL,
    1234             :                         __location__ ": Test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1235           0 :                 CHECK_MAX_FAILURES(error_test70);
    1236           0 :                 return false;
    1237             :         }
    1238             : 
    1239           7 :         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
    1240             :                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
    1241             : 
    1242           7 :         if (fnum2 != -1) {
    1243           0 :                 torture_result(tctx, TORTURE_FAIL,
    1244             :                         __location__ ": Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1245           0 :                 CHECK_MAX_FAILURES(error_test70);
    1246           0 :                 return false;
    1247             :         }
    1248             : 
    1249           7 :         torture_comment(tctx, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
    1250             : 
    1251           7 :         torture_comment(tctx, "non-io open test #7 passed.\n");
    1252           7 : error_test70:
    1253             : 
    1254           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1255           0 :                 torture_comment(tctx, "Test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1256             :         }
    1257           7 :         if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
    1258           0 :                 torture_comment(tctx, "Test 7 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
    1259             :         }
    1260             : 
    1261           7 :         torture_comment(tctx, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
    1262           7 :         fnum1 = fnum2 = -1;
    1263           7 :         smbcli_unlink(cli1->tree, fname);
    1264             : 
    1265           7 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
    1266           7 :         if (fnum1 == -1) {
    1267           0 :                 torture_result(tctx, TORTURE_FAIL, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1268           0 :                 return false;
    1269             :         }
    1270             :         
    1271             :         /* write 20 bytes. */
    1272             :         
    1273           7 :         memset(buf, '\0', 20);
    1274             : 
    1275           7 :         if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
    1276           0 :                 torture_result(tctx, TORTURE_FAIL, "(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
    1277           0 :                 correct = false;
    1278             :         }
    1279             : 
    1280             :         /* Ensure size == 20. */
    1281           7 :         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
    1282           0 :                 torture_result(tctx, TORTURE_FAIL,
    1283             :                         __location__ ": (8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
    1284           0 :                 CHECK_MAX_FAILURES(error_test80);
    1285           0 :                 return false;
    1286             :         }
    1287             :         
    1288           7 :         if (fsize != 20) {
    1289           0 :                 torture_result(tctx, TORTURE_FAIL,
    1290             :                         __location__ ": (8) file size %lu != 20\n", (unsigned long)fsize);
    1291           0 :                 CHECK_MAX_FAILURES(error_test80);
    1292           0 :                 return false;
    1293             :         }
    1294             : 
    1295             :         /* Get an exclusive lock on the open file. */
    1296           7 :         if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
    1297           0 :                 torture_result(tctx, TORTURE_FAIL,
    1298             :                         __location__ ": (8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
    1299           0 :                 CHECK_MAX_FAILURES(error_test80);
    1300           0 :                 return false;
    1301             :         }
    1302             : 
    1303           7 :         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
    1304           7 :         if (fnum1 == -1) {
    1305           0 :                 torture_result(tctx, TORTURE_FAIL, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
    1306           0 :                 return false;
    1307             :         }
    1308             : 
    1309             :         /* Ensure size == 0. */
    1310           7 :         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
    1311           0 :                 torture_result(tctx, TORTURE_FAIL,
    1312             :                         __location__ ": (8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
    1313           0 :                 CHECK_MAX_FAILURES(error_test80);
    1314           0 :                 return false;
    1315             :         }
    1316             :         
    1317           7 :         if (fsize != 0) {
    1318           0 :                 torture_result(tctx, TORTURE_FAIL,
    1319             :                         __location__ ": (8) file size %lu != 0\n", (unsigned long)fsize);
    1320           0 :                 CHECK_MAX_FAILURES(error_test80);
    1321           0 :                 return false;
    1322             :         }
    1323             : 
    1324           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
    1325           0 :                 torture_result(tctx, TORTURE_FAIL, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
    1326           0 :                 return false;
    1327             :         }
    1328             :         
    1329           7 :         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
    1330           0 :                 torture_result(tctx, TORTURE_FAIL, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
    1331           0 :                 return false;
    1332             :         }
    1333             :         
    1334           7 : error_test80:
    1335             : 
    1336           7 :         torture_comment(tctx, "open test #8 passed.\n");
    1337             : 
    1338           7 :         smbcli_unlink(cli1->tree, fname);
    1339             : 
    1340           7 :         return failures > 0 ? false : correct;
    1341             : }
    1342             : 
    1343             : /* FIRST_DESIRED_ACCESS   0xf019f */
    1344             : #define FIRST_DESIRED_ACCESS   SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
    1345             :                                SEC_FILE_READ_EA|                           /* 0xf */ \
    1346             :                                SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE|     /* 0x90 */ \
    1347             :                                SEC_FILE_WRITE_ATTRIBUTE|                  /* 0x100 */ \
    1348             :                                SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
    1349             :                                SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER     /* 0xf0000 */
    1350             : /* SECOND_DESIRED_ACCESS  0xe0080 */
    1351             : #define SECOND_DESIRED_ACCESS  SEC_FILE_READ_ATTRIBUTE|                   /* 0x80 */ \
    1352             :                                SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
    1353             :                                SEC_STD_WRITE_OWNER                      /* 0xe0000 */
    1354             : 
    1355             : #if 0
    1356             : #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTE|                   /* 0x80 */ \
    1357             :                                READ_CONTROL|WRITE_DAC|\
    1358             :                                SEC_FILE_READ_DATA|\
    1359             :                                WRITE_OWNER                      /* */
    1360             : #endif
    1361             : 
    1362             : 
    1363             : 
    1364             : /**
    1365             :   Test ntcreate calls made by xcopy
    1366             :  */
    1367          30 : static bool run_xcopy(struct torture_context *tctx,
    1368             :                                           struct smbcli_state *cli1)
    1369             : {
    1370          30 :         const char *fname = "\\test.txt";
    1371           0 :         int fnum1, fnum2;
    1372             : 
    1373          30 :         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1374             :                                       FIRST_DESIRED_ACCESS, 
    1375             :                                       FILE_ATTRIBUTE_ARCHIVE,
    1376             :                                       NTCREATEX_SHARE_ACCESS_NONE, 
    1377             :                                       NTCREATEX_DISP_OVERWRITE_IF, 
    1378             :                                       0x4044, 0);
    1379             : 
    1380          30 :         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, 
    1381             :                                 "First open failed - %s", smbcli_errstr(cli1->tree)));
    1382             : 
    1383          30 :         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
    1384             :                                    SECOND_DESIRED_ACCESS, 0,
    1385             :                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 
    1386             :                                    0x200000, 0);
    1387          30 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, 
    1388             :                                 "second open failed - %s", smbcli_errstr(cli1->tree)));
    1389             :         
    1390          30 :         return true;
    1391             : }
    1392             : 
    1393           0 : static bool run_iometer(struct torture_context *tctx,
    1394             :                                                 struct smbcli_state *cli)
    1395             : {
    1396           0 :         const char *fname = "\\iobw.tst";
    1397           0 :         int fnum;
    1398           0 :         size_t filesize;
    1399           0 :         NTSTATUS status;
    1400           0 :         char buf[2048];
    1401           0 :         int ops;
    1402             : 
    1403           0 :         memset(buf, 0, sizeof(buf));
    1404             : 
    1405           0 :         status = smbcli_getatr(cli->tree, fname, NULL, &filesize, NULL);
    1406           0 :         torture_assert_ntstatus_ok(tctx, status, 
    1407             :                 talloc_asprintf(tctx, "smbcli_getatr failed: %s", nt_errstr(status)));
    1408             : 
    1409           0 :         torture_comment(tctx, "size: %d\n", (int)filesize);
    1410             : 
    1411           0 :         filesize -= (sizeof(buf) - 1);
    1412             : 
    1413           0 :         fnum = smbcli_nt_create_full(cli->tree, fname, 0x16,
    1414             :                                      0x2019f, 0, 0x3, 3, 0x42, 0x3);
    1415           0 :         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open failed: %s", 
    1416             :                                    smbcli_errstr(cli->tree)));
    1417             : 
    1418           0 :         ops = 0;
    1419             : 
    1420           0 :         while (true) {
    1421           0 :                 int i, num_reads, num_writes;
    1422             : 
    1423           0 :                 num_reads = random() % 10;
    1424           0 :                 num_writes = random() % 3;
    1425             : 
    1426           0 :                 for (i=0; i<num_reads; i++) {
    1427           0 :                         ssize_t res;
    1428           0 :                         if (ops++ > torture_numops) {
    1429           0 :                                 return true;
    1430             :                         }
    1431           0 :                         res = smbcli_read(cli->tree, fnum, buf,
    1432           0 :                                           random() % filesize, sizeof(buf));
    1433           0 :                         torture_assert(tctx, res == sizeof(buf), 
    1434             :                                                    talloc_asprintf(tctx, "read failed: %s",
    1435             :                                                                                    smbcli_errstr(cli->tree)));
    1436             :                 }
    1437           0 :                 for (i=0; i<num_writes; i++) {
    1438           0 :                         ssize_t res;
    1439           0 :                         if (ops++ > torture_numops) {
    1440           0 :                                 return true;
    1441             :                         }
    1442           0 :                         res = smbcli_write(cli->tree, fnum, 0, buf,
    1443           0 :                                           random() % filesize, sizeof(buf));
    1444           0 :                         torture_assert(tctx, res == sizeof(buf),
    1445             :                                                    talloc_asprintf(tctx, "read failed: %s",
    1446             :                                        smbcli_errstr(cli->tree)));
    1447             :                 }
    1448             :         }
    1449             : }
    1450             : 
    1451             : /**
    1452             :   tries variants of chkpath
    1453             :  */
    1454           7 : static bool torture_chkpath_test(struct torture_context *tctx, 
    1455             :                                                                  struct smbcli_state *cli)
    1456             : {
    1457           1 :         int fnum;
    1458           1 :         bool ret;
    1459             : 
    1460           7 :         torture_comment(tctx, "Testing valid and invalid paths\n");
    1461             : 
    1462             :         /* cleanup from an old run */
    1463           7 :         smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
    1464           7 :         smbcli_unlink_wcard(cli->tree, "\\chkpath.dir\\*");
    1465           7 :         smbcli_rmdir(cli->tree, "\\chkpath.dir");
    1466             : 
    1467           7 :         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
    1468           0 :                 torture_result(tctx, TORTURE_FAIL, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
    1469           0 :                 return false;
    1470             :         }
    1471             : 
    1472           7 :         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
    1473           0 :                 torture_result(tctx, TORTURE_FAIL, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
    1474           0 :                 return false;
    1475             :         }
    1476             : 
    1477           7 :         fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
    1478           7 :         if (fnum == -1) {
    1479           0 :                 torture_result(tctx, TORTURE_FAIL, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
    1480           0 :                 return false;
    1481             :         }
    1482           7 :         smbcli_close(cli->tree, fnum);
    1483             : 
    1484           7 :         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
    1485           0 :                 torture_result(tctx, TORTURE_FAIL, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
    1486           0 :                 ret = false;
    1487             :         }
    1488             : 
    1489           7 :         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
    1490           0 :                 torture_result(tctx, TORTURE_FAIL, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
    1491           0 :                 ret = false;
    1492             :         }
    1493             : 
    1494           7 :         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
    1495           7 :                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
    1496           7 :                                   NT_STATUS_NOT_A_DIRECTORY);
    1497             :         } else {
    1498           0 :                 torture_result(tctx, TORTURE_FAIL, "* chkpath on a file should fail\n");
    1499           0 :                 ret = false;
    1500             :         }
    1501             : 
    1502           7 :         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
    1503           7 :                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
    1504           7 :                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
    1505             :         } else {
    1506           0 :                 torture_result(tctx, TORTURE_FAIL, "* chkpath on a non existent file should fail\n");
    1507           0 :                 ret = false;
    1508             :         }
    1509             : 
    1510           7 :         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
    1511           7 :                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
    1512           7 :                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
    1513             :         } else {
    1514           0 :                 torture_result(tctx, TORTURE_FAIL, "* chkpath on a non existent component should fail\n");
    1515           0 :                 ret = false;
    1516             :         }
    1517             : 
    1518           7 :         smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
    1519           7 :         smbcli_unlink_wcard(cli->tree, "\\chkpath.dir\\*");
    1520           7 :         smbcli_rmdir(cli->tree, "\\chkpath.dir");
    1521             : 
    1522           7 :         return ret;
    1523             : }
    1524             : 
    1525             : /*
    1526             :  * This is a test to exercise some weird Samba3 error paths.
    1527             :  */
    1528             : 
    1529           4 : static bool torture_samba3_errorpaths(struct torture_context *tctx)
    1530             : {
    1531           0 :         bool nt_status_support;
    1532           0 :         bool client_ntlmv2_auth;
    1533           4 :         struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
    1534           4 :         bool result = false;
    1535           0 :         int fnum;
    1536           4 :         const char *os2_fname = ".+,;=[].";
    1537           4 :         const char *dname = "samba3_errordir";
    1538           0 :         union smb_open io;
    1539           0 :         NTSTATUS status;
    1540             : 
    1541           4 :         nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
    1542           4 :         client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(tctx->lp_ctx);
    1543             : 
    1544           4 :         if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
    1545           0 :                 torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = yes'\n");
    1546           0 :                 goto fail;
    1547             :         }
    1548           4 :         if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "yes")) {
    1549           0 :                 torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = yes'\n");
    1550           0 :                 goto fail;
    1551             :         }
    1552             : 
    1553           4 :         if (!torture_open_connection(&cli_nt, tctx, 0)) {
    1554           0 :                 goto fail;
    1555             :         }
    1556             : 
    1557           4 :         if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
    1558           0 :                 torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = no'\n");
    1559           0 :                 goto fail;
    1560             :         }
    1561           4 :         if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "no")) {
    1562           0 :                 torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = no'\n");
    1563           0 :                 goto fail;
    1564             :         }
    1565             : 
    1566           4 :         if (!torture_open_connection(&cli_dos, tctx, 1)) {
    1567           0 :                 goto fail;
    1568             :         }
    1569             : 
    1570           4 :         if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
    1571             :                             nt_status_support ? "yes":"no")) {
    1572           0 :                 torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support'");
    1573           0 :                 goto fail;
    1574             :         }
    1575           4 :         if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth",
    1576             :                                client_ntlmv2_auth ? "yes":"no")) {
    1577           0 :                 torture_result(tctx, TORTURE_FAIL, "Could not reset 'client ntlmv2 auth'");
    1578           0 :                 goto fail;
    1579             :         }
    1580             : 
    1581           4 :         smbcli_unlink(cli_nt->tree, os2_fname);
    1582           4 :         smbcli_rmdir(cli_nt->tree, dname);
    1583             : 
    1584           4 :         if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
    1585           0 :                 torture_result(tctx, TORTURE_FAIL, "smbcli_mkdir(%s) failed: %s\n", dname,
    1586           0 :                        smbcli_errstr(cli_nt->tree));
    1587           0 :                 goto fail;
    1588             :         }
    1589             : 
    1590           4 :         io.generic.level = RAW_OPEN_NTCREATEX;
    1591           4 :         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
    1592           4 :         io.ntcreatex.in.root_fid.fnum = 0;
    1593           4 :         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1594           4 :         io.ntcreatex.in.alloc_size = 1024*1024;
    1595           4 :         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1596           4 :         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
    1597           4 :         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
    1598           4 :         io.ntcreatex.in.create_options = 0;
    1599           4 :         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
    1600           4 :         io.ntcreatex.in.security_flags = 0;
    1601           4 :         io.ntcreatex.in.fname = dname;
    1602             : 
    1603           4 :         status = smb_raw_open(cli_nt->tree, tctx, &io);
    1604           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
    1605           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
    1606             :                        __location__, nt_errstr(status),
    1607           0 :                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
    1608           0 :                 goto fail;
    1609             :         }
    1610           4 :         status = smb_raw_open(cli_dos->tree, tctx, &io);
    1611           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
    1612           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
    1613             :                        __location__, nt_errstr(status),
    1614           0 :                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
    1615           0 :                 goto fail;
    1616             :         }
    1617             : 
    1618           4 :         status = smbcli_mkdir(cli_nt->tree, dname);
    1619           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
    1620           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
    1621             :                        __location__, nt_errstr(status),
    1622           0 :                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
    1623           0 :                 goto fail;
    1624             :         }
    1625           4 :         status = smbcli_mkdir(cli_dos->tree, dname);
    1626           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
    1627           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
    1628             :                        __location__, nt_errstr(status),
    1629           0 :                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
    1630           0 :                 goto fail;
    1631             :         }
    1632             : 
    1633             :         {
    1634           0 :                 union smb_mkdir md;
    1635           4 :                 md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
    1636           4 :                 md.t2mkdir.in.path = dname;
    1637           4 :                 md.t2mkdir.in.num_eas = 0;
    1638           4 :                 md.t2mkdir.in.eas = NULL;
    1639             : 
    1640           4 :                 status = smb_raw_mkdir(cli_nt->tree, &md);
    1641           4 :                 if (!NT_STATUS_EQUAL(status,
    1642             :                                      NT_STATUS_OBJECT_NAME_COLLISION)) {
    1643           0 :                         torture_comment(
    1644             :                                 tctx, "(%s) incorrect status %s should be "
    1645             :                                 "NT_STATUS_OBJECT_NAME_COLLISION\n",
    1646             :                                 __location__, nt_errstr(status));
    1647           0 :                         goto fail;
    1648             :                 }
    1649           4 :                 status = smb_raw_mkdir(cli_dos->tree, &md);
    1650           4 :                 if (!NT_STATUS_EQUAL(status,
    1651             :                                      NT_STATUS_DOS(ERRDOS, ERRrename))) {
    1652           0 :                         torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s "
    1653             :                                         "should be ERRDOS:ERRrename\n",
    1654             :                                         __location__, nt_errstr(status));
    1655           0 :                         goto fail;
    1656             :                 }
    1657             :         }
    1658             : 
    1659           4 :         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1660           4 :         status = smb_raw_open(cli_nt->tree, tctx, &io);
    1661           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
    1662           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
    1663             :                        __location__, nt_errstr(status),
    1664           0 :                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
    1665           0 :                 goto fail;
    1666             :         }
    1667             : 
    1668           4 :         status = smb_raw_open(cli_dos->tree, tctx, &io);
    1669           4 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
    1670           0 :                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
    1671             :                        __location__, nt_errstr(status),
    1672           0 :                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
    1673           0 :                 goto fail;
    1674             :         }
    1675             : 
    1676             :         {
    1677             :                 /* Test an invalid DOS deny mode */
    1678           4 :                 const char *fname = "test.txt";
    1679             : 
    1680           4 :                 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
    1681           4 :                 if (fnum != -1) {
    1682           0 :                         torture_result(tctx, TORTURE_FAIL, "Open(%s) with invalid deny mode succeeded -- "
    1683             :                                "expected failure\n", fname);
    1684           0 :                         smbcli_close(cli_nt->tree, fnum);
    1685           0 :                         goto fail;
    1686             :                 }
    1687           4 :                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
    1688             :                                      NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
    1689           0 :                         torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS/ERRbadaccess, "
    1690           0 :                                "got %s\n", smbcli_errstr(cli_nt->tree));
    1691           0 :                         goto fail;
    1692             :                 }
    1693             : 
    1694           4 :                 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
    1695           4 :                 if (fnum != -1) {
    1696           0 :                         torture_result(tctx, TORTURE_FAIL, "Open(%s) with invalid deny mode succeeded -- "
    1697             :                                "expected failure\n", fname);
    1698           0 :                         smbcli_close(cli_nt->tree, fnum);
    1699           0 :                         goto fail;
    1700             :                 }
    1701           4 :                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
    1702             :                                      NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
    1703           0 :                         torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS:ERRbadaccess, "
    1704           0 :                                "got %s\n", smbcli_errstr(cli_nt->tree));
    1705           0 :                         goto fail;
    1706             :                 }
    1707             :         }
    1708             : 
    1709             :         {
    1710             :                 /*
    1711             :                  * Samba 3.0.23 has a bug that an existing file can be opened
    1712             :                  * as a directory using ntcreate&x. Test this.
    1713             :                  */
    1714             : 
    1715           4 :                 const char *fname = "\\test_dir.txt";
    1716             : 
    1717           4 :                 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
    1718             :                                    DENY_NONE);
    1719           4 :                 if (fnum == -1) {
    1720           0 :                         d_printf("(%s) smbcli_open failed: %s\n", __location__,
    1721           0 :                                  smbcli_errstr(cli_nt->tree));
    1722             :                 }
    1723           4 :                 smbcli_close(cli_nt->tree, fnum);
    1724             : 
    1725           4 :                 io.generic.level = RAW_OPEN_NTCREATEX;
    1726           4 :                 io.ntcreatex.in.root_fid.fnum = 0;
    1727           4 :                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
    1728           4 :                 io.ntcreatex.in.alloc_size = 0;
    1729           4 :                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
    1730           4 :                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
    1731             :                         NTCREATEX_SHARE_ACCESS_WRITE|
    1732             :                         NTCREATEX_SHARE_ACCESS_DELETE;
    1733           4 :                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1734           4 :                 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
    1735           4 :                 io.ntcreatex.in.impersonation =
    1736             :                         NTCREATEX_IMPERSONATION_ANONYMOUS;
    1737           4 :                 io.ntcreatex.in.security_flags = 0;
    1738           4 :                 io.ntcreatex.in.fname = fname;
    1739           4 :                 io.ntcreatex.in.flags = 0;
    1740             : 
    1741           4 :                 status = smb_raw_open(cli_nt->tree, tctx, &io);
    1742           4 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
    1743           0 :                         torture_result(tctx, TORTURE_FAIL, "ntcreate as dir gave %s, "
    1744             :                                         "expected NT_STATUS_NOT_A_DIRECTORY\n",
    1745             :                                         nt_errstr(status));
    1746           0 :                         result = false;
    1747             :                 }
    1748             : 
    1749           4 :                 if (NT_STATUS_IS_OK(status)) {
    1750           0 :                         smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum);
    1751             :                 }
    1752             : 
    1753           4 :                 status = smb_raw_open(cli_dos->tree, tctx, &io);
    1754           4 :                 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
    1755             :                                                            ERRbaddirectory))) {
    1756           0 :                         torture_result(tctx, TORTURE_FAIL, "ntcreate as dir gave %s, "
    1757             :                                         "expected NT_STATUS_NOT_A_DIRECTORY\n",
    1758             :                                         nt_errstr(status));
    1759           0 :                         result = false;
    1760             :                 }
    1761             : 
    1762           4 :                 if (NT_STATUS_IS_OK(status)) {
    1763           0 :                         smbcli_close(cli_dos->tree,
    1764           0 :                                      io.ntcreatex.out.file.fnum);
    1765             :                 }
    1766             : 
    1767           4 :                 smbcli_unlink(cli_nt->tree, fname);
    1768             :         }
    1769             : 
    1770           4 :         if (!torture_setting_bool(tctx, "samba3", false)) {
    1771           0 :                 goto done;
    1772             :         }
    1773             : 
    1774           4 :         fnum = smbcli_open(cli_dos->tree, os2_fname, 
    1775             :                            O_RDWR | O_CREAT | O_TRUNC,
    1776             :                            DENY_NONE);
    1777           4 :         if (fnum != -1) {
    1778           0 :                 torture_result(tctx, TORTURE_FAIL, "Open(%s) succeeded -- expected failure\n",
    1779             :                        os2_fname);
    1780           0 :                 smbcli_close(cli_dos->tree, fnum);
    1781           0 :                 goto fail;
    1782             :         }
    1783             : 
    1784           4 :         if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
    1785             :                              NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
    1786           0 :                 torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
    1787           0 :                        smbcli_errstr(cli_dos->tree));
    1788           0 :                 goto fail;
    1789             :         }
    1790             : 
    1791           4 :         fnum = smbcli_open(cli_nt->tree, os2_fname, 
    1792             :                            O_RDWR | O_CREAT | O_TRUNC,
    1793             :                            DENY_NONE);
    1794           4 :         if (fnum != -1) {
    1795           0 :                 torture_result(tctx, TORTURE_FAIL, "Open(%s) succeeded -- expected failure\n",
    1796             :                        os2_fname);
    1797           0 :                 smbcli_close(cli_nt->tree, fnum);
    1798           0 :                 goto fail;
    1799             :         }
    1800             : 
    1801           4 :         if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
    1802             :                              NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    1803           0 :                 torture_result(tctx, TORTURE_FAIL, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
    1804           0 :                        "got %s\n", smbcli_errstr(cli_nt->tree));
    1805           0 :                 goto fail;
    1806             :         }
    1807             : 
    1808           4 :  done:
    1809           4 :         result = true;
    1810             : 
    1811           4 :  fail:
    1812           4 :         if (cli_dos != NULL) {
    1813           4 :                 torture_close_connection(cli_dos);
    1814             :         }
    1815           4 :         if (cli_nt != NULL) {
    1816           4 :                 torture_close_connection(cli_nt);
    1817             :         }
    1818             :         
    1819           4 :         return result;
    1820             : }
    1821             : 
    1822             : /**
    1823             :   This checks file/dir birthtime
    1824             : */
    1825           0 : static void list_fn(struct clilist_file_info *finfo, const char *name,
    1826             :                         void *state){
    1827             : 
    1828             :         /* Just to change dir access time*/
    1829           0 :         sleep(5);
    1830             : 
    1831           0 : }
    1832             : 
    1833           0 : static bool run_birthtimetest(struct torture_context *tctx,
    1834             :                                                    struct smbcli_state *cli)
    1835             : {
    1836           0 :         int fnum;
    1837           0 :         size_t size;
    1838           0 :         time_t c_time, a_time, m_time, w_time, c_time1;
    1839           0 :         const char *fname = "\\birthtime.tst";
    1840           0 :         const char *dname = "\\birthtime";
    1841           0 :         const char *fname2 = "\\birthtime\\birthtime.tst";
    1842           0 :         bool correct = true;
    1843           0 :         uint8_t buf[16];
    1844             : 
    1845             : 
    1846           0 :         smbcli_unlink(cli->tree, fname);
    1847             : 
    1848           0 :         torture_comment(tctx, "Testing Birthtime for File\n");
    1849             : 
    1850             :         /* Save File birthtime/creationtime */
    1851           0 :         fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
    1852             :                                 DENY_NONE);
    1853           0 :         if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size,
    1854             :                                 &c_time, &a_time, &m_time, NULL, NULL))) {
    1855           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qfileinfo failed (%s)\n",
    1856             :                                 smbcli_errstr(cli->tree));
    1857           0 :                 correct = false;
    1858             :         }
    1859           0 :         smbcli_close(cli->tree, fnum);
    1860             : 
    1861           0 :         sleep(10);
    1862             : 
    1863             :         /* Change in File attribute changes file change time*/
    1864           0 :         smbcli_setatr(cli->tree, fname, FILE_ATTRIBUTE_SYSTEM, 0);
    1865             : 
    1866           0 :         fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT , DENY_NONE);
    1867             :         /* Writing updates modification time*/
    1868           0 :         smbcli_smbwrite(cli->tree, fnum,  &fname, 0, sizeof(fname));
    1869             :         /*Reading updates access time */
    1870           0 :         smbcli_read(cli->tree, fnum, buf, 0, 13);
    1871           0 :         smbcli_close(cli->tree, fnum);
    1872             : 
    1873           0 :         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time1,
    1874             :                         &a_time, &m_time, &w_time, &size, NULL, NULL))) {
    1875           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
    1876             :                         smbcli_errstr(cli->tree));
    1877           0 :                 correct = false;
    1878             :         } else {
    1879           0 :                 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
    1880             :                         (long) c_time, (long) c_time1);
    1881           0 :                 if (c_time1 != c_time) {
    1882           0 :                         torture_result(tctx, TORTURE_FAIL, "This system updated file \
    1883             :                                         birth times! Not expected!\n");
    1884           0 :                         correct = false;
    1885             :                 }
    1886             :         }
    1887           0 :         smbcli_unlink(cli->tree, fname);
    1888             : 
    1889           0 :         torture_comment(tctx, "Testing Birthtime for Directory\n");
    1890             : 
    1891             :         /* check if the server does not update the directory birth time
    1892             :           when creating a new file */
    1893           0 :         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
    1894           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: mkdir failed (%s)\n",
    1895             :                                 smbcli_errstr(cli->tree));
    1896           0 :                 correct = false;
    1897             :         }
    1898           0 :         sleep(3);
    1899           0 :         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
    1900             :                         &c_time,&a_time,&m_time,&w_time, &size, NULL, NULL))){
    1901           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
    1902             :                                 smbcli_errstr(cli->tree));
    1903           0 :                 correct = false;
    1904             :         }
    1905             : 
    1906             :         /* Creating a new file changes dir modification time and change time*/
    1907           0 :         smbcli_unlink(cli->tree, fname2);
    1908           0 :         fnum = smbcli_open(cli->tree, fname2, O_RDWR | O_CREAT | O_TRUNC,
    1909             :                         DENY_NONE);
    1910           0 :         smbcli_smbwrite(cli->tree, fnum,  &fnum, 0, sizeof(fnum));
    1911           0 :         smbcli_read(cli->tree, fnum, buf, 0, 13);
    1912           0 :         smbcli_close(cli->tree, fnum);
    1913             : 
    1914             :         /* dir listing changes dir access time*/
    1915           0 :         smbcli_list(cli->tree, "\\birthtime\\*", 0, list_fn, cli );
    1916             : 
    1917           0 :         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
    1918             :                         &c_time1, &a_time, &m_time,&w_time,&size,NULL,NULL))){
    1919           0 :                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
    1920             :                                 smbcli_errstr(cli->tree));
    1921           0 :                 correct = false;
    1922             :         } else {
    1923           0 :                 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
    1924             :                         (long) c_time, (long) c_time1);
    1925           0 :                 if (c_time1 != c_time) {
    1926           0 :                         torture_result(tctx, TORTURE_FAIL, "This system  updated directory \
    1927             :                                         birth times! Not Expected!\n");
    1928           0 :                         correct = false;
    1929             :                 }
    1930             :         }
    1931           0 :         smbcli_unlink(cli->tree, fname2);
    1932           0 :         smbcli_rmdir(cli->tree, dname);
    1933             : 
    1934           0 :         return correct;
    1935             : }
    1936             : 
    1937             : /**
    1938             :   SMB1 TWRP open on root of share.
    1939             :  */
    1940           2 : static bool torture_smb1_twrp_openroot(struct torture_context *tctx,
    1941             :                         struct smbcli_state *cli)
    1942             : {
    1943           2 :         const char *snapshot = NULL;
    1944           2 :         const char *p = NULL;
    1945           0 :         NTSTATUS status;
    1946           2 :         struct tm tm = {};
    1947           2 :         bool ret = true;
    1948             : 
    1949           2 :         snapshot = torture_setting_string(tctx, "twrp_snapshot", NULL);
    1950           2 :         if (snapshot == NULL) {
    1951           0 :                 torture_skip(tctx, "missing 'twrp_snapshot' option\n");
    1952             :         }
    1953             : 
    1954           2 :         torture_comment(tctx, "Testing open of root of "
    1955             :                 "share with timewarp (%s)\n",
    1956             :                 snapshot);
    1957             : 
    1958           2 :         setenv("TZ", "GMT", 1);
    1959             : 
    1960           2 :         p = strptime(snapshot, "@GMT-%Y.%m.%d-%H.%M.%S", &tm);
    1961           2 :         torture_assert_goto(tctx, p != NULL, ret, done, "strptime\n");
    1962           2 :         torture_assert_goto(tctx, *p == '\0', ret, done, "strptime\n");
    1963             : 
    1964           2 :         cli->session->flags2 |= FLAGS2_REPARSE_PATH;
    1965           2 :         status = smbcli_chkpath(cli->tree, snapshot);
    1966           2 :         cli->session->flags2 &= ~FLAGS2_REPARSE_PATH;
    1967             : 
    1968           2 :         if (NT_STATUS_IS_ERR(status)) {
    1969           0 :                 torture_result(tctx,
    1970             :                         TORTURE_FAIL,
    1971             :                         "smbcli_chkpath on %s : %s\n",
    1972             :                         snapshot,
    1973             :                         smbcli_errstr(cli->tree));
    1974           0 :                 return false;
    1975             :         }
    1976             : 
    1977           2 :   done:
    1978             : 
    1979           2 :         return ret;
    1980             : }
    1981             : 
    1982           0 : static void torture_smb1_find_gmt_mask_list_fn(struct clilist_file_info *finfo,
    1983             :                                                const char *name,
    1984             :                                                void *state)
    1985             : {
    1986           0 : }
    1987             : 
    1988             : /**
    1989             :  * SMB1 @GMT token as search mask is valid
    1990             :  */
    1991           0 : static bool torture_smb1_find_gmt_mask(struct torture_context *tctx,
    1992             :                                        struct smbcli_state *cli)
    1993             : {
    1994           0 :         const char *dname = "\\torture_smb1_find_gmt_mask";
    1995           0 :         const char *path = "\\torture_smb1_find_gmt_mask\\@GMT-2022.11.24-16.24.00";
    1996           0 :         int fnum;
    1997           0 :         int n;
    1998           0 :         NTSTATUS status;
    1999           0 :         bool ret = true;
    2000             : 
    2001           0 :         smbcli_unlink(cli->tree, path);
    2002           0 :         smbcli_rmdir(cli->tree, dname);
    2003             : 
    2004           0 :         status = smbcli_mkdir(cli->tree, dname);
    2005           0 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
    2006             :                                         "smbcli_mkdir() failed\n");
    2007           0 :         fnum = smbcli_open(cli->tree, path, O_RDWR | O_CREAT, DENY_NONE);
    2008           0 :         smbcli_close(cli->tree, fnum);
    2009             : 
    2010             :         /* Note: we don't set FLAGS2_REPARSE_PATH, so this is just a path */
    2011           0 :         n = smbcli_list(cli->tree, path, 0, torture_smb1_find_gmt_mask_list_fn, cli);
    2012           0 :         torture_assert_int_equal_goto(tctx, n, 1, ret, done, "Wrong count\n");
    2013             : 
    2014           0 : done:
    2015           0 :         smbcli_unlink(cli->tree, path);
    2016           0 :         smbcli_rmdir(cli->tree, dname);
    2017           0 :         return ret;
    2018             : }
    2019             : 
    2020        2379 : NTSTATUS torture_base_init(TALLOC_CTX *ctx)
    2021             : {
    2022        2379 :         struct torture_suite *suite = torture_suite_create(ctx, "base");
    2023             : 
    2024        2379 :         torture_suite_add_2smb_test(suite, "fdpass", run_fdpasstest);
    2025        2379 :         torture_suite_add_suite(suite, torture_base_locktest(suite));
    2026        2379 :         torture_suite_add_1smb_test(suite, "unlink", torture_unlinktest);
    2027        2379 :         torture_suite_add_1smb_test(suite, "attr",   run_attrtest);
    2028        2379 :         torture_suite_add_1smb_test(suite, "trans2", run_trans2test);
    2029        2379 :         torture_suite_add_1smb_test(suite, "birthtime", run_birthtimetest);
    2030        2379 :         torture_suite_add_simple_test(suite, "negnowait", run_negprot_nowait);
    2031        2379 :         torture_suite_add_1smb_test(suite, "dir1",  torture_dirtest1);
    2032        2379 :         torture_suite_add_1smb_test(suite, "dir2",  torture_dirtest2);
    2033        2379 :         torture_suite_add_1smb_test(suite, "deny1",  torture_denytest1);
    2034        2379 :         torture_suite_add_2smb_test(suite, "deny2",  torture_denytest2);
    2035        2379 :         torture_suite_add_2smb_test(suite, "deny3",  torture_denytest3);
    2036        2379 :         torture_suite_add_1smb_test(suite, "denydos",  torture_denydos_sharing);
    2037        2379 :         torture_suite_add_smb_multi_test(suite, "ntdeny1", torture_ntdenytest1);
    2038        2379 :         torture_suite_add_2smb_test(suite, "ntdeny2",  torture_ntdenytest2);
    2039        2379 :         torture_suite_add_1smb_test(suite, "tcon",  run_tcon_test);
    2040        2379 :         torture_suite_add_1smb_test(suite, "tcondev",  run_tcon_devtype_test);
    2041        2379 :         torture_suite_add_1smb_test(suite, "vuid", run_vuidtest);
    2042        2379 :         torture_suite_add_2smb_test(suite, "rw1",  run_readwritetest);
    2043        2379 :         torture_suite_add_2smb_test(suite, "open", run_opentest);
    2044        2379 :         torture_suite_add_smb_multi_test(suite, "defer_open", run_deferopen);
    2045        2379 :         torture_suite_add_1smb_test(suite, "xcopy", run_xcopy);
    2046        2379 :         torture_suite_add_1smb_test(suite, "iometer", run_iometer);
    2047        2379 :         torture_suite_add_1smb_test(suite, "rename", torture_test_rename);
    2048        2379 :         torture_suite_add_suite(suite, torture_test_delete(suite));
    2049        2379 :         torture_suite_add_1smb_test(suite, "properties", torture_test_properties);
    2050        2379 :         torture_suite_add_1smb_test(suite, "mangle", torture_mangle);
    2051        2379 :         torture_suite_add_1smb_test(suite, "openattr", torture_openattrtest);
    2052        2379 :         torture_suite_add_1smb_test(suite, "winattr", torture_winattrtest);
    2053        2379 :         torture_suite_add_suite(suite, torture_charset(suite));
    2054        2379 :         torture_suite_add_1smb_test(suite, "chkpath",  torture_chkpath_test);
    2055        2379 :         torture_suite_add_1smb_test(suite, "secleak",  torture_sec_leak);
    2056        2379 :         torture_suite_add_simple_test(suite, "disconnect",  torture_disconnect);
    2057        2379 :         torture_suite_add_suite(suite, torture_delay_write(suite));
    2058        2379 :         torture_suite_add_simple_test(suite, "samba3error", torture_samba3_errorpaths);
    2059        2379 :         torture_suite_add_1smb_test(suite, "casetable", torture_casetable);
    2060        2379 :         torture_suite_add_1smb_test(suite, "utable", torture_utable);
    2061        2379 :         torture_suite_add_simple_test(suite, "smb", torture_smb_scan);
    2062        2379 :         torture_suite_add_suite(suite, torture_trans2_aliases(suite));
    2063        2379 :         torture_suite_add_1smb_test(suite, "trans2-scan", torture_trans2_scan);
    2064        2379 :         torture_suite_add_1smb_test(suite, "nttrans", torture_nttrans_scan);
    2065        2379 :         torture_suite_add_1smb_test(suite, "createx_access", torture_createx_access);
    2066        2379 :         torture_suite_add_2smb_test(suite, "createx_sharemodes_file", torture_createx_sharemodes_file);
    2067        2379 :         torture_suite_add_2smb_test(suite, "createx_sharemodes_dir", torture_createx_sharemodes_dir);
    2068        2379 :         torture_suite_add_1smb_test(suite, "maximum_allowed", torture_maximum_allowed);
    2069             : 
    2070        2379 :         torture_suite_add_simple_test(suite, "bench-holdcon", torture_holdcon);
    2071        2379 :         torture_suite_add_1smb_test(suite, "bench-holdopen", torture_holdopen);
    2072        2379 :         torture_suite_add_simple_test(suite, "bench-readwrite", run_benchrw);
    2073        2379 :         torture_suite_add_smb_multi_test(suite, "bench-torture", run_torture);
    2074        2379 :         torture_suite_add_1smb_test(suite, "scan-pipe_number", run_pipe_number);
    2075        2379 :         torture_suite_add_1smb_test(suite, "scan-ioctl", torture_ioctl_test);
    2076        2379 :         torture_suite_add_1smb_test(suite, "scan-maxfid", torture_maxfid_test);
    2077        2379 :         torture_suite_add_1smb_test(suite,
    2078             :                         "smb1-twrp-openroot",
    2079             :                         torture_smb1_twrp_openroot);
    2080        2379 :         torture_suite_add_1smb_test(suite,
    2081             :                         "smb1-find-gmt-mask",
    2082             :                         torture_smb1_find_gmt_mask);
    2083             : 
    2084        2379 :         suite->description = talloc_strdup(suite, 
    2085             :                                         "Basic SMB tests (imported from the original smbtorture)");
    2086             : 
    2087        2379 :         torture_register_suite(ctx, suite);
    2088             : 
    2089        2379 :         return NT_STATUS_OK;
    2090             : }

Generated by: LCOV version 1.14