~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/basic/locking.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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