LCOV - code coverage report
Current view: top level - source4/torture/basic - locking.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 360 393 91.6 %
Date: 2024-02-28 12:06:22 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    basic locking tests
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2000-2004
       7             :    Copyright (C) Jeremy Allison 2000-2004
       8             :    
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "libcli/libcli.h"
      25             : #include "torture/util.h"
      26             : #include "system/time.h"
      27             : #include "system/filesys.h"
      28             : #include "torture/basic/proto.h"
      29             : 
      30             : #define BASEDIR "\\locktest"
      31             : 
      32             : /*
      33             :   This test checks for two things:
      34             : 
      35             :   1) correct support for retaining locks over a close (ie. the server
      36             :      must not use posix semantics)
      37             :   2) support for lock timeouts
      38             :  */
      39           4 : static bool torture_locktest1(struct torture_context *tctx, 
      40             :                               struct smbcli_state *cli1,
      41             :                               struct smbcli_state *cli2)
      42             : {
      43           4 :         const char *fname = BASEDIR "\\lockt1.lck";
      44           0 :         int fnum1, fnum2, fnum3;
      45           0 :         time_t t1, t2;
      46           0 :         unsigned int lock_timeout;
      47             : 
      48           4 :         torture_assert(tctx, torture_setup_dir(cli1, BASEDIR),
      49             :                        talloc_asprintf(tctx, "Unable to set up %s", BASEDIR));
      50             : 
      51           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
      52           4 :         torture_assert(tctx, fnum1 != -1,
      53             :                                    talloc_asprintf(tctx, 
      54             :                 "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));
      55           4 :         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
      56           4 :         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, 
      57             :                 "open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));
      58           4 :         fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
      59           4 :         torture_assert(tctx, fnum3 != -1, talloc_asprintf(tctx, 
      60             :                 "open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree)));
      61             : 
      62           4 :         torture_assert_ntstatus_ok(tctx, 
      63             :                 smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK),
      64             :                 talloc_asprintf(tctx, "lock1 failed (%s)", smbcli_errstr(cli1->tree)));
      65             : 
      66           4 :         torture_assert(tctx, 
      67             :                 !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),
      68             :                 "lock2 succeeded! This is a locking bug\n");
      69             : 
      70           4 :         if (!check_error(__location__, cli2, ERRDOS, ERRlock, 
      71           4 :                          NT_STATUS_LOCK_NOT_GRANTED)) return false;
      72             : 
      73           4 :         torture_assert(tctx,
      74             :                 !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),
      75             :                 "lock2 succeeded! This is a locking bug\n");
      76             : 
      77           4 :         if (!check_error(__location__, cli2, ERRDOS, ERRlock, 
      78           4 :                                  NT_STATUS_FILE_LOCK_CONFLICT)) return false;
      79             : 
      80           4 :         torture_assert_ntstatus_ok(tctx, 
      81             :                 smbcli_lock(cli1->tree, fnum1, 5, 9, 0, WRITE_LOCK),
      82             :                 talloc_asprintf(tctx, 
      83             :                 "lock1 failed (%s)", smbcli_errstr(cli1->tree)));
      84             : 
      85           4 :         torture_assert(tctx, 
      86             :                 !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 5, 9, 0, WRITE_LOCK)),
      87             :                 "lock2 succeeded! This is a locking bug");
      88             :         
      89           4 :         if (!check_error(__location__, cli2, ERRDOS, ERRlock, 
      90           4 :                                  NT_STATUS_LOCK_NOT_GRANTED)) return false;
      91             : 
      92           4 :         torture_assert(tctx, 
      93             :                 !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),
      94             :                 "lock2 succeeded! This is a locking bug");
      95             :         
      96           4 :         if (!check_error(__location__, cli2, ERRDOS, ERRlock, 
      97           4 :                                  NT_STATUS_LOCK_NOT_GRANTED)) return false;
      98             : 
      99           4 :         torture_assert(tctx, 
     100             :                 !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),
     101             :                 "lock2 succeeded! This is a locking bug");
     102             : 
     103           4 :         if (!check_error(__location__, cli2, ERRDOS, ERRlock, 
     104           4 :                          NT_STATUS_FILE_LOCK_CONFLICT)) return false;
     105             : 
     106           4 :         lock_timeout = (6 + (random() % 20));
     107           4 :         torture_comment(tctx, "Testing lock timeout with timeout=%u\n", 
     108             :                                         lock_timeout);
     109           4 :         t1 = time_mono(NULL);
     110           4 :         torture_assert(tctx, 
     111             :                 !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)),
     112             :                 "lock3 succeeded! This is a locking bug\n");
     113             : 
     114           4 :         if (!check_error(__location__, cli2, ERRDOS, ERRlock, 
     115           4 :                                  NT_STATUS_FILE_LOCK_CONFLICT)) return false;
     116           4 :         t2 = time_mono(NULL);
     117             : 
     118           4 :         if (t2 - t1 < 5) {
     119           0 :                 torture_fail(tctx, 
     120             :                         "error: This server appears not to support timed lock requests");
     121             :         }
     122           4 :         torture_comment(tctx, "server slept for %u seconds for a %u second timeout\n",
     123             :                (unsigned int)(t2-t1), lock_timeout);
     124             : 
     125           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum2),
     126             :                 talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli1->tree)));
     127             : 
     128           4 :         torture_assert(tctx, 
     129             :                 !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK)),
     130             :                 "lock4 succeeded! This is a locking bug");
     131             :                 
     132           4 :         if (!check_error(__location__, cli2, ERRDOS, ERRlock, 
     133           4 :                          NT_STATUS_FILE_LOCK_CONFLICT)) return false;
     134             : 
     135           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     136             :                 talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli1->tree)));
     137             : 
     138           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum3),
     139             :                 talloc_asprintf(tctx, "close3 failed (%s)", smbcli_errstr(cli2->tree)));
     140             : 
     141           4 :         torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli1->tree, fname),
     142             :                 talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(cli1->tree)));
     143             : 
     144           4 :         return true;
     145             : }
     146             : 
     147             : 
     148             : /*
     149             :   This test checks that 
     150             : 
     151             :   1) the server supports multiple locking contexts on the one SMB
     152             :   connection, distinguished by PID.  
     153             : 
     154             :   2) the server correctly fails overlapping locks made by the same PID (this
     155             :      goes against POSIX behaviour, which is why it is tricky to implement)
     156             : 
     157             :   3) the server denies unlock requests by an incorrect client PID
     158             : */
     159           4 : static bool torture_locktest2(struct torture_context *tctx,
     160             :                               struct smbcli_state *cli)
     161             : {
     162           4 :         const char *fname = BASEDIR "\\lockt2.lck";
     163           0 :         int fnum1, fnum2, fnum3;
     164             : 
     165           4 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR),
     166             :                        talloc_asprintf(tctx, "Unable to set up %s", BASEDIR));
     167             : 
     168           4 :         torture_comment(tctx, "Testing pid context\n");
     169             :         
     170           4 :         cli->session->pid = 1;
     171             : 
     172           4 :         fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     173           4 :         torture_assert(tctx, fnum1 != -1, 
     174             :                 talloc_asprintf(tctx, 
     175             :                 "open of %s failed (%s)", fname, smbcli_errstr(cli->tree)));
     176             : 
     177           4 :         fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
     178           4 :         torture_assert(tctx, fnum2 != -1,
     179             :                 talloc_asprintf(tctx, "open2 of %s failed (%s)", 
     180             :                        fname, smbcli_errstr(cli->tree)));
     181             : 
     182           4 :         cli->session->pid = 2;
     183             : 
     184           4 :         fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
     185           4 :         torture_assert(tctx, fnum3 != -1,
     186             :                 talloc_asprintf(tctx, 
     187             :                 "open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)));
     188             : 
     189           4 :         cli->session->pid = 1;
     190             : 
     191           4 :         torture_assert_ntstatus_ok(tctx, 
     192             :                 smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK),
     193             :                 talloc_asprintf(tctx, 
     194             :                 "lock1 failed (%s)", smbcli_errstr(cli->tree)));
     195             : 
     196           4 :         torture_assert(tctx, 
     197             :                 !NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK)),
     198             :                 "WRITE lock1 succeeded! This is a locking bug");
     199             :                 
     200           4 :         if (!check_error(__location__, cli, ERRDOS, ERRlock, 
     201           4 :                          NT_STATUS_LOCK_NOT_GRANTED)) return false;
     202             : 
     203           4 :         torture_assert(tctx, 
     204             :                 !NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK)),
     205             :                 "WRITE lock2 succeeded! This is a locking bug");
     206             : 
     207           4 :         if (!check_error(__location__, cli, ERRDOS, ERRlock, 
     208           4 :                          NT_STATUS_LOCK_NOT_GRANTED)) return false;
     209             : 
     210           4 :         torture_assert(tctx, 
     211             :                 !NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK)),
     212             :                 "READ lock2 succeeded! This is a locking bug");
     213             : 
     214           4 :         if (!check_error(__location__, cli, ERRDOS, ERRlock, 
     215           4 :                          NT_STATUS_FILE_LOCK_CONFLICT)) return false;
     216             : 
     217           4 :         torture_assert_ntstatus_ok(tctx, 
     218             :                 smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK),
     219             :                 talloc_asprintf(tctx, 
     220             :                 "lock at 100 failed (%s)", smbcli_errstr(cli->tree)));
     221             : 
     222           4 :         cli->session->pid = 2;
     223             : 
     224           4 :         torture_assert(tctx, 
     225             :                 !NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4)),
     226             :                 "unlock at 100 succeeded! This is a locking bug");
     227             : 
     228           4 :         torture_assert(tctx, 
     229             :                 !NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4)),
     230             :                 "unlock1 succeeded! This is a locking bug");
     231             : 
     232           4 :         if (!check_error(__location__, cli, 
     233             :                                  ERRDOS, ERRnotlocked, 
     234           4 :                                  NT_STATUS_RANGE_NOT_LOCKED)) return false;
     235             : 
     236           4 :         torture_assert(tctx, 
     237             :                 !NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8)),
     238             :                 "unlock2 succeeded! This is a locking bug");
     239             : 
     240           4 :         if (!check_error(__location__, cli, 
     241             :                          ERRDOS, ERRnotlocked, 
     242           4 :                          NT_STATUS_RANGE_NOT_LOCKED)) return false;
     243             : 
     244           4 :         torture_assert(tctx, 
     245             :                 !NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK)),
     246             :                 "lock3 succeeded! This is a locking bug");
     247             : 
     248           4 :         if (!check_error(__location__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return false;
     249             : 
     250           4 :         cli->session->pid = 1;
     251             : 
     252           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum1), 
     253             :                 talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli->tree)));
     254             : 
     255           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum2),
     256             :                 talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli->tree)));
     257             : 
     258           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum3),
     259             :                 talloc_asprintf(tctx, "close3 failed (%s)", smbcli_errstr(cli->tree)));
     260             : 
     261           4 :         return true;
     262             : }
     263             : 
     264             : 
     265             : /*
     266             :   This test checks that 
     267             : 
     268             :   1) the server supports the full offset range in lock requests
     269             : */
     270           4 : static bool torture_locktest3(struct torture_context *tctx, 
     271             :                               struct smbcli_state *cli1,
     272             :                               struct smbcli_state *cli2)
     273             : {
     274           4 :         const char *fname = BASEDIR "\\lockt3.lck";
     275           0 :         int fnum1, fnum2, i;
     276           0 :         uint32_t offset;
     277           0 :         extern int torture_numops;
     278             : 
     279             : #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
     280             : 
     281           4 :         torture_comment(tctx, "Testing 32 bit offset ranges");
     282             : 
     283           4 :         torture_assert(tctx, torture_setup_dir(cli1, BASEDIR),
     284             :                        talloc_asprintf(tctx, "Unable to set up %s", BASEDIR));
     285             : 
     286           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     287           4 :         torture_assert(tctx, fnum1 != -1, 
     288             :                 talloc_asprintf(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));
     289           4 :         fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
     290           4 :         torture_assert(tctx, fnum2 != -1,
     291             :                 talloc_asprintf(tctx, "open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree)));
     292             : 
     293           4 :         torture_comment(tctx, "Establishing %d locks\n", torture_numops);
     294             : 
     295          44 :         for (offset=i=0;i<torture_numops;i++) {
     296          40 :                 NEXT_OFFSET;
     297          40 :                 torture_assert_ntstatus_ok(tctx, 
     298             :                         smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK),
     299             :                         talloc_asprintf(tctx, "lock1 %d failed (%s)", i, smbcli_errstr(cli1->tree)));
     300             : 
     301          40 :                 torture_assert_ntstatus_ok(tctx, 
     302             :                         smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK),
     303             :                         talloc_asprintf(tctx, "lock2 %d failed (%s)", 
     304             :                                i, smbcli_errstr(cli1->tree)));
     305             :         }
     306             : 
     307           4 :         torture_comment(tctx, "Testing %d locks\n", torture_numops);
     308             : 
     309          44 :         for (offset=i=0;i<torture_numops;i++) {
     310          40 :                 NEXT_OFFSET;
     311             : 
     312          40 :                 torture_assert(tctx, 
     313             :                         !NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK)),
     314             :                         talloc_asprintf(tctx, "error: lock1 %d succeeded!", i));
     315             : 
     316          40 :                 torture_assert(tctx, 
     317             :                         !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK)),
     318             :                         talloc_asprintf(tctx, "error: lock2 %d succeeded!", i));
     319             : 
     320          40 :                 torture_assert(tctx, 
     321             :                         !NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK)),
     322             :                         talloc_asprintf(tctx, "error: lock3 %d succeeded!", i));
     323             : 
     324          40 :                 torture_assert(tctx, 
     325             :                         !NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK)),
     326             :                         talloc_asprintf(tctx, "error: lock4 %d succeeded!", i));
     327             :         }
     328             : 
     329           4 :         torture_comment(tctx, "Removing %d locks\n", torture_numops);
     330             : 
     331          44 :         for (offset=i=0;i<torture_numops;i++) {
     332          40 :                 NEXT_OFFSET;
     333             : 
     334          40 :                 torture_assert_ntstatus_ok(tctx, 
     335             :                                         smbcli_unlock(cli1->tree, fnum1, offset-1, 1),
     336             :                                         talloc_asprintf(tctx, "unlock1 %d failed (%s)", 
     337             :                                i,
     338             :                                smbcli_errstr(cli1->tree)));
     339             : 
     340          40 :                 torture_assert_ntstatus_ok(tctx, 
     341             :                         smbcli_unlock(cli2->tree, fnum2, offset-2, 1),
     342             :                         talloc_asprintf(tctx, "unlock2 %d failed (%s)", 
     343             :                                i,
     344             :                                smbcli_errstr(cli1->tree)));
     345             :         }
     346             : 
     347           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     348             :                 talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli1->tree)));
     349             : 
     350           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum2),
     351             :                 talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));
     352             : 
     353           4 :         torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli1->tree, fname),
     354             :                 talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(cli1->tree)));
     355             : 
     356           4 :         return true;
     357             : }
     358             : 
     359             : #define EXPECTED(ret, v) if ((ret) != (v)) { \
     360             :         torture_comment(tctx, "** "); correct = false; \
     361             :         }
     362             : 
     363             : /*
     364             :   looks at overlapping locks
     365             : */
     366           4 : static bool torture_locktest4(struct torture_context *tctx, 
     367             :                               struct smbcli_state *cli1,
     368             :                               struct smbcli_state *cli2)
     369             : {
     370           4 :         const char *fname = BASEDIR "\\lockt4.lck";
     371           0 :         int fnum1, fnum2, f;
     372           0 :         bool ret;
     373           0 :         uint8_t buf[1000];
     374           4 :         bool correct = true;
     375             : 
     376           4 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     377           0 :                 return false;
     378             :         }
     379             : 
     380           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     381           4 :         fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
     382             : 
     383           4 :         memset(buf, 0, sizeof(buf));
     384             : 
     385           4 :         if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
     386           0 :                 torture_comment(tctx, "Failed to create file\n");
     387           0 :                 correct = false;
     388           0 :                 goto fail;
     389             :         }
     390             : 
     391           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
     392           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
     393           4 :         EXPECTED(ret, false);
     394           4 :         torture_comment(tctx, "the same process %s set overlapping write locks\n", ret?"can":"cannot");
     395             :             
     396           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
     397           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
     398           4 :         EXPECTED(ret, true);
     399           4 :         torture_comment(tctx, "the same process %s set overlapping read locks\n", ret?"can":"cannot");
     400             : 
     401           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
     402           4 :               NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
     403           4 :         EXPECTED(ret, false);
     404           4 :         torture_comment(tctx, "a different connection %s set overlapping write locks\n", ret?"can":"cannot");
     405             :             
     406           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
     407           4 :                 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
     408           4 :         EXPECTED(ret, true);
     409           4 :         torture_comment(tctx, "a different connection %s set overlapping read locks\n", ret?"can":"cannot");
     410             :         
     411           8 :         ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
     412           4 :               NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
     413           4 :         EXPECTED(ret, false);
     414           4 :         torture_comment(tctx, "a different pid %s set overlapping write locks\n", ret?"can":"cannot");
     415             :             
     416           8 :         ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
     417           4 :               NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
     418           4 :         EXPECTED(ret, true);
     419           4 :         torture_comment(tctx, "a different pid %s set overlapping read locks\n", ret?"can":"cannot");
     420             : 
     421           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
     422           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
     423           4 :         EXPECTED(ret, true);
     424           4 :         torture_comment(tctx, "the same process %s set the same read lock twice\n", ret?"can":"cannot");
     425             : 
     426           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
     427           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
     428           4 :         EXPECTED(ret, false);
     429           4 :         torture_comment(tctx, "the same process %s set the same write lock twice\n", ret?"can":"cannot");
     430             : 
     431           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
     432           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
     433           4 :         EXPECTED(ret, false);
     434           4 :         torture_comment(tctx, "the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
     435             : 
     436           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
     437           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
     438           4 :         EXPECTED(ret, true);
     439           4 :         torture_comment(tctx, "the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
     440             : 
     441           8 :         ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
     442           4 :               NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
     443           4 :         EXPECTED(ret, false);
     444           4 :         torture_comment(tctx, "a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
     445             : 
     446           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
     447           8 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
     448           4 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
     449           4 :         EXPECTED(ret, false);
     450           4 :         torture_comment(tctx, "the same process %s coalesce read locks\n", ret?"can":"cannot");
     451             : 
     452             : 
     453           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
     454           4 :               (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
     455           4 :         EXPECTED(ret, false);
     456           4 :         torture_comment(tctx, "this server %s strict write locking\n", ret?"doesn't do":"does");
     457             : 
     458           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
     459           4 :               (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
     460           4 :         EXPECTED(ret, false);
     461           4 :         torture_comment(tctx, "this server %s strict read locking\n", ret?"doesn't do":"does");
     462             : 
     463             : 
     464           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
     465           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
     466          12 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
     467           4 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
     468           4 :         EXPECTED(ret, true);
     469           4 :         torture_comment(tctx, "this server %s do recursive read locking\n", ret?"does":"doesn't");
     470             : 
     471             : 
     472           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
     473           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
     474           8 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
     475           8 :               (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
     476          12 :               !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
     477           4 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
     478           4 :         EXPECTED(ret, true);
     479           4 :         torture_comment(tctx, "this server %s do recursive lock overlays\n", ret?"does":"doesn't");
     480             : 
     481           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
     482           8 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
     483          12 :               (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&              
     484           4 :               (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);            
     485           4 :         EXPECTED(ret, true);
     486           4 :         torture_comment(tctx, "the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
     487             : 
     488           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
     489           8 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
     490          12 :               (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&              
     491           4 :               (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);            
     492           4 :         EXPECTED(ret, true);
     493           4 :         torture_comment(tctx, "the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
     494             : 
     495           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
     496           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
     497           8 :               NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
     498          12 :               !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&             
     499           4 :               (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);            
     500           4 :         EXPECTED(ret, true);
     501           4 :         torture_comment(tctx, "the same process %s remove the first lock first\n", ret?"does":"doesn't");
     502             : 
     503           4 :         smbcli_close(cli1->tree, fnum1);
     504           4 :         smbcli_close(cli2->tree, fnum2);
     505           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
     506           4 :         f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
     507           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
     508           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
     509           8 :               NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
     510          12 :               ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
     511           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
     512           4 :         smbcli_close(cli1->tree, f);
     513           4 :         smbcli_close(cli1->tree, fnum1);
     514           4 :         EXPECTED(ret, true);
     515           4 :         torture_comment(tctx, "the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
     516             : 
     517           4 :  fail:
     518           4 :         smbcli_close(cli1->tree, fnum1);
     519           4 :         smbcli_close(cli2->tree, fnum2);
     520           4 :         smbcli_unlink(cli1->tree, fname);
     521             : 
     522           4 :         return correct;
     523             : }
     524             : 
     525             : /*
     526             :   looks at lock upgrade/downgrade.
     527             : */
     528           4 : static bool torture_locktest5(struct torture_context *tctx, struct smbcli_state *cli1, 
     529             :                               struct smbcli_state *cli2)
     530             : {
     531           4 :         const char *fname = BASEDIR "\\lockt5.lck";
     532           0 :         int fnum1, fnum2, fnum3;
     533           0 :         bool ret;
     534           0 :         uint8_t buf[1000];
     535           4 :         bool correct = true;
     536             : 
     537           4 :         if (!torture_setup_dir(cli1, BASEDIR)) {
     538           0 :                 return false;
     539             :         }
     540             : 
     541           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     542           4 :         fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
     543           4 :         fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
     544             : 
     545           4 :         memset(buf, 0, sizeof(buf));
     546             : 
     547           4 :         torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) == sizeof(buf),
     548             :                 "Failed to create file");
     549             : 
     550             :         /* Check for NT bug... */
     551           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
     552           4 :                   NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
     553           4 :         smbcli_close(cli1->tree, fnum1);
     554           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
     555           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
     556           4 :         EXPECTED(ret, true);
     557           4 :         torture_comment(tctx, "this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
     558           4 :         smbcli_close(cli1->tree, fnum1);
     559           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
     560           4 :         smbcli_unlock(cli1->tree, fnum3, 0, 1);
     561             : 
     562           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
     563           4 :               NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
     564           4 :         EXPECTED(ret, true);
     565           4 :         torture_comment(tctx, "the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
     566             : 
     567           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
     568           4 :         EXPECTED(ret, false);
     569             : 
     570           4 :         torture_comment(tctx, "a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
     571             : 
     572             :         /* Unlock the process 2 lock. */
     573           4 :         smbcli_unlock(cli2->tree, fnum2, 0, 4);
     574             : 
     575           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
     576           4 :         EXPECTED(ret, false);
     577             : 
     578           4 :         torture_comment(tctx, "the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
     579             : 
     580             :         /* Unlock the process 1 fnum3 lock. */
     581           4 :         smbcli_unlock(cli1->tree, fnum3, 0, 4);
     582             : 
     583             :         /* Stack 2 more locks here. */
     584           8 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
     585           4 :                   NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
     586             : 
     587           4 :         EXPECTED(ret, true);
     588           4 :         torture_comment(tctx, "the same process %s stack read locks\n", ret?"can":"cannot");
     589             : 
     590             :         /* Unlock the first process lock, then check this was the WRITE lock that was
     591             :                 removed. */
     592             : 
     593           8 : ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
     594           4 :         NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
     595             : 
     596           4 :         EXPECTED(ret, true);
     597           4 :         torture_comment(tctx, "the first unlock removes the %s lock\n", ret?"WRITE":"READ");
     598             : 
     599             :         /* Unlock the process 2 lock. */
     600           4 :         smbcli_unlock(cli2->tree, fnum2, 0, 4);
     601             : 
     602             :         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
     603             : 
     604           4 :         ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
     605           8 :                   NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
     606           4 :                   NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
     607             : 
     608           4 :         EXPECTED(ret, true);
     609           4 :         torture_comment(tctx, "the same process %s unlock the stack of 3 locks\n", ret?"can":"cannot");
     610             : 
     611             :         /* Ensure the next unlock fails. */
     612           4 :         ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
     613           4 :         EXPECTED(ret, false);
     614           4 :         torture_comment(tctx, "the same process %s count the lock stack\n", !ret?"can":"cannot"); 
     615             : 
     616             :         /* Ensure connection 2 can get a write lock. */
     617           4 :         ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
     618           4 :         EXPECTED(ret, true);
     619             : 
     620           4 :         torture_comment(tctx, "a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
     621             : 
     622             : 
     623           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum1),
     624             :                 talloc_asprintf(tctx, "close1 failed (%s)", smbcli_errstr(cli1->tree)));
     625             : 
     626           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli2->tree, fnum2),
     627             :                 talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));
     628             : 
     629           4 :         torture_assert_ntstatus_ok(tctx, smbcli_close(cli1->tree, fnum3),
     630             :                 talloc_asprintf(tctx, "close2 failed (%s)", smbcli_errstr(cli2->tree)));
     631             : 
     632           4 :         torture_assert_ntstatus_ok(tctx, smbcli_unlink(cli1->tree, fname),
     633             :                 talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(cli1->tree)));
     634             : 
     635           4 :         return correct;
     636             : }
     637             : 
     638             : /*
     639             :   tries the unusual lockingX locktype bits
     640             : */
     641           4 : static bool torture_locktest6(struct torture_context *tctx, 
     642             :                               struct smbcli_state *cli)
     643             : {
     644           4 :         const char *fname[1] = { "\\lock6.txt" };
     645           0 :         int i;
     646           0 :         int fnum;
     647           0 :         NTSTATUS status;
     648             : 
     649           4 :         torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR);
     650             : 
     651           8 :         for (i=0;i<1;i++) {
     652           4 :                 torture_comment(tctx, "Testing %s\n", fname[i]);
     653             : 
     654           4 :                 smbcli_unlink(cli->tree, fname[i]);
     655             : 
     656           4 :                 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     657           4 :                 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
     658           4 :                 smbcli_close(cli->tree, fnum);
     659           4 :                 torture_comment(tctx, "CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
     660             : 
     661           4 :                 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
     662           4 :                 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
     663           4 :                 smbcli_close(cli->tree, fnum);
     664           4 :                 torture_comment(tctx, "CANCEL_LOCK gave %s\n", nt_errstr(status));
     665             : 
     666           4 :                 smbcli_unlink(cli->tree, fname[i]);
     667             :         }
     668             : 
     669           4 :         return true;
     670             : }
     671             : 
     672           4 : static bool torture_locktest7(struct torture_context *tctx, 
     673             :                               struct smbcli_state *cli1)
     674             : {
     675           4 :         const char *fname = BASEDIR "\\lockt7.lck";
     676           0 :         int fnum1;
     677           4 :         int fnum2 = -1;
     678           0 :         size_t size;
     679           0 :         uint8_t buf[200];
     680           4 :         bool correct = false;
     681             : 
     682           4 :         torture_assert(tctx, torture_setup_dir(cli1, BASEDIR),
     683             :                                    talloc_asprintf(tctx, "Unable to set up %s", BASEDIR));
     684             : 
     685           4 :         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
     686             : 
     687           4 :         memset(buf, 0, sizeof(buf));
     688             : 
     689           4 :         torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) == sizeof(buf),
     690             :                 "Failed to create file");
     691             : 
     692           4 :         cli1->session->pid = 1;
     693             : 
     694           4 :         torture_assert_ntstatus_ok(tctx, smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK),
     695             :                 talloc_asprintf(tctx, "Unable to apply read lock on range 130:4, error was %s", 
     696             :                        smbcli_errstr(cli1->tree)));
     697             : 
     698           4 :         torture_comment(tctx, "pid1 successfully locked range 130:4 for READ\n");
     699             : 
     700           4 :         torture_assert(tctx, smbcli_read(cli1->tree, fnum1, buf, 130, 4) == 4, 
     701             :                         talloc_asprintf(tctx, "pid1 unable to read the range 130:4, error was %s)", 
     702             :                        smbcli_errstr(cli1->tree)));
     703             : 
     704           4 :         torture_comment(tctx, "pid1 successfully read the range 130:4\n");
     705             : 
     706           4 :         if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
     707           4 :                 torture_comment(tctx, "pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
     708           4 :                 torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT,
     709             :                         "Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
     710             :         } else {
     711           0 :                 torture_fail(tctx, "pid1 successfully wrote to the range 130:4 (should be denied)");
     712             :         }
     713             : 
     714           4 :         cli1->session->pid = 2;
     715             : 
     716           4 :         if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
     717           0 :                 torture_comment(tctx, "pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
     718             :         } else {
     719           4 :                 torture_comment(tctx, "pid2 successfully read the range 130:4\n");
     720             :         }
     721             : 
     722           4 :         if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
     723           4 :                 torture_comment(tctx, "pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
     724           4 :                 torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT, 
     725             :                         "Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
     726             :         } else {
     727           0 :                 torture_fail(tctx, "pid2 successfully wrote to the range 130:4 (should be denied)"); 
     728             :         }
     729             : 
     730           4 :         cli1->session->pid = 1;
     731           4 :         smbcli_unlock(cli1->tree, fnum1, 130, 4);
     732             : 
     733           4 :         torture_assert_ntstatus_ok(tctx, smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK),
     734             :                 talloc_asprintf(tctx, "Unable to apply write lock on range 130:4, error was %s", 
     735             :                        smbcli_errstr(cli1->tree)));
     736           4 :         torture_comment(tctx, "pid1 successfully locked range 130:4 for WRITE\n");
     737             : 
     738           4 :         torture_assert(tctx, smbcli_read(cli1->tree, fnum1, buf, 130, 4) == 4, 
     739             :                 talloc_asprintf(tctx, "pid1 unable to read the range 130:4, error was %s", 
     740             :                        smbcli_errstr(cli1->tree)));
     741           4 :         torture_comment(tctx, "pid1 successfully read the range 130:4\n");
     742             : 
     743           4 :         torture_assert(tctx, smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) == 4, 
     744             :                 talloc_asprintf(tctx, "pid1 unable to write to the range 130:4, error was %s",
     745             :                        smbcli_errstr(cli1->tree)));
     746           4 :         torture_comment(tctx, "pid1 successfully wrote to the range 130:4\n");
     747             : 
     748           4 :         cli1->session->pid = 2;
     749             : 
     750           4 :         if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
     751           4 :                 torture_comment(tctx, "pid2 unable to read the range 130:4, error was %s\n", 
     752             :                        smbcli_errstr(cli1->tree));
     753           4 :                 torture_assert_ntstatus_equal(tctx, smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT, 
     754             :                         "Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)");
     755             :         } else {
     756           0 :                 torture_fail(tctx, "pid2 successfully read the range 130:4 (should be denied)");
     757             :         }
     758             : 
     759           4 :         if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
     760           4 :                 torture_comment(tctx, "pid2 unable to write to the range 130:4, error was %s\n", 
     761             :                        smbcli_errstr(cli1->tree));
     762           4 :                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree), NT_STATUS_FILE_LOCK_CONFLICT)) {
     763           0 :                         torture_comment(tctx, "Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT) (%s)\n",
     764             :                                __location__);
     765           0 :                         goto fail;
     766             :                 }
     767             :         } else {
     768           0 :                 torture_comment(tctx, "pid2 successfully wrote to the range 130:4 (should be denied) (%s)\n", 
     769             :                        __location__);
     770           0 :                 goto fail;
     771             :         }
     772             : 
     773           4 :         torture_comment(tctx, "Testing truncate of locked file.\n");
     774             : 
     775           4 :         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
     776             : 
     777           4 :         torture_assert(tctx, fnum2 != -1, "Unable to truncate locked file");
     778             : 
     779           4 :         torture_comment(tctx, "Truncated locked file.\n");
     780             : 
     781           4 :         torture_assert_ntstatus_ok(tctx, smbcli_getatr(cli1->tree, fname, NULL, &size, NULL), 
     782             :                 talloc_asprintf(tctx, "getatr failed (%s)", smbcli_errstr(cli1->tree)));
     783             : 
     784           4 :         torture_assert(tctx, size == 0, talloc_asprintf(tctx, "Unable to truncate locked file. Size was %u", (unsigned)size));
     785             : 
     786           4 :         cli1->session->pid = 1;
     787             : 
     788           4 :         smbcli_unlock(cli1->tree, fnum1, 130, 4);
     789           4 :         correct = true;
     790             : 
     791           4 : fail:
     792           4 :         smbcli_close(cli1->tree, fnum1);
     793           4 :         smbcli_close(cli1->tree, fnum2);
     794           4 :         smbcli_unlink(cli1->tree, fname);
     795             : 
     796           4 :         return correct;
     797             : }
     798             : 
     799        2379 : struct torture_suite *torture_base_locktest(TALLOC_CTX *mem_ctx)
     800             : {
     801        2379 :         struct torture_suite *suite = torture_suite_create(mem_ctx, "lock");
     802        2379 :         torture_suite_add_2smb_test(suite, "LOCK1", torture_locktest1);
     803        2379 :         torture_suite_add_1smb_test(suite, "LOCK2", torture_locktest2);
     804        2379 :         torture_suite_add_2smb_test(suite, "LOCK3", torture_locktest3);
     805        2379 :         torture_suite_add_2smb_test(suite, "LOCK4",  torture_locktest4);
     806        2379 :         torture_suite_add_2smb_test(suite, "LOCK5",  torture_locktest5);
     807        2379 :         torture_suite_add_1smb_test(suite, "LOCK6",  torture_locktest6);
     808        2379 :         torture_suite_add_1smb_test(suite, "LOCK7",  torture_locktest7);
     809             : 
     810        2379 :         return suite;
     811             : }

Generated by: LCOV version 1.14