r3324: made the smbtorture code completely warning free
[jelmer/samba4-debian.git] / source / torture / raw / lock.c
1 /* 
2    Unix SMB/CIFS implementation.
3    test suite for various lock operations
4    Copyright (C) Andrew Tridgell 2003
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 #define CHECK_STATUS(status, correct) do { \
24         if (!NT_STATUS_EQUAL(status, correct)) { \
25                 printf("(%s) Incorrect status %s - should be %s\n", \
26                        __location__, nt_errstr(status), nt_errstr(correct)); \
27                 ret = False; \
28                 goto done; \
29         }} while (0)
30
31 #define CHECK_VALUE(v, correct) do { \
32         if ((v) != (correct)) { \
33                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
34                        __location__, #v, v, correct); \
35                 ret = False; \
36                 goto done; \
37         }} while (0)
38
39 #define BASEDIR "\\testlock"
40
41
42 /*
43   test SMBlock and SMBunlock ops
44 */
45 static BOOL test_lock(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
46 {
47         union smb_lock io;
48         NTSTATUS status;
49         BOOL ret = True;
50         int fnum;
51         const char *fname = BASEDIR "\\test.txt";
52
53         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
54             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
55                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
56                 return False;
57         }
58
59         printf("Testing RAW_LOCK_LOCK\n");
60         io.generic.level = RAW_LOCK_LOCK;
61         
62         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
63         if (fnum == -1) {
64                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
65                 ret = False;
66                 goto done;
67         }
68
69         printf("Trying 0/0 lock\n");
70         io.lock.level = RAW_LOCK_LOCK;
71         io.lock.in.fnum = fnum;
72         io.lock.in.count = 0;
73         io.lock.in.offset = 0;
74         status = smb_raw_lock(cli->tree, &io);
75         CHECK_STATUS(status, NT_STATUS_OK);
76         cli->session->pid++;
77         status = smb_raw_lock(cli->tree, &io);
78         CHECK_STATUS(status, NT_STATUS_OK);
79         cli->session->pid--;
80         io.lock.level = RAW_LOCK_UNLOCK;
81         status = smb_raw_lock(cli->tree, &io);
82         CHECK_STATUS(status, NT_STATUS_OK);
83
84         printf("Trying 0/1 lock\n");
85         io.lock.level = RAW_LOCK_LOCK;
86         io.lock.in.fnum = fnum;
87         io.lock.in.count = 1;
88         io.lock.in.offset = 0;
89         status = smb_raw_lock(cli->tree, &io);
90         CHECK_STATUS(status, NT_STATUS_OK);
91         cli->session->pid++;
92         status = smb_raw_lock(cli->tree, &io);
93         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
94         cli->session->pid--;
95         io.lock.level = RAW_LOCK_UNLOCK;
96         status = smb_raw_lock(cli->tree, &io);
97         CHECK_STATUS(status, NT_STATUS_OK);
98         io.lock.level = RAW_LOCK_UNLOCK;
99         status = smb_raw_lock(cli->tree, &io);
100         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
101
102         printf("Trying 0xEEFFFFFF lock\n");
103         io.lock.level = RAW_LOCK_LOCK;
104         io.lock.in.fnum = fnum;
105         io.lock.in.count = 4000;
106         io.lock.in.offset = 0xEEFFFFFF;
107         status = smb_raw_lock(cli->tree, &io);
108         CHECK_STATUS(status, NT_STATUS_OK);
109         cli->session->pid++;
110         status = smb_raw_lock(cli->tree, &io);
111         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
112         cli->session->pid--;
113         io.lock.level = RAW_LOCK_UNLOCK;
114         status = smb_raw_lock(cli->tree, &io);
115         CHECK_STATUS(status, NT_STATUS_OK);
116         io.lock.level = RAW_LOCK_UNLOCK;
117         status = smb_raw_lock(cli->tree, &io);
118         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
119
120         printf("Trying 0xEF000000 lock\n");
121         io.lock.level = RAW_LOCK_LOCK;
122         io.lock.in.fnum = fnum;
123         io.lock.in.count = 4000;
124         io.lock.in.offset = 0xEEFFFFFF;
125         status = smb_raw_lock(cli->tree, &io);
126         CHECK_STATUS(status, NT_STATUS_OK);
127         cli->session->pid++;
128         status = smb_raw_lock(cli->tree, &io);
129         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
130         cli->session->pid--;
131         io.lock.level = RAW_LOCK_UNLOCK;
132         status = smb_raw_lock(cli->tree, &io);
133         CHECK_STATUS(status, NT_STATUS_OK);
134         io.lock.level = RAW_LOCK_UNLOCK;
135         status = smb_raw_lock(cli->tree, &io);
136         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
137
138         printf("Trying max lock\n");
139         io.lock.level = RAW_LOCK_LOCK;
140         io.lock.in.fnum = fnum;
141         io.lock.in.count = 4000;
142         io.lock.in.offset = 0xEF000000;
143         status = smb_raw_lock(cli->tree, &io);
144         CHECK_STATUS(status, NT_STATUS_OK);
145         cli->session->pid++;
146         status = smb_raw_lock(cli->tree, &io);
147         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
148         cli->session->pid--;
149         io.lock.level = RAW_LOCK_UNLOCK;
150         status = smb_raw_lock(cli->tree, &io);
151         CHECK_STATUS(status, NT_STATUS_OK);
152         io.lock.level = RAW_LOCK_UNLOCK;
153         status = smb_raw_lock(cli->tree, &io);
154         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
155
156         printf("Trying wrong pid unlock\n");
157         io.lock.level = RAW_LOCK_LOCK;
158         io.lock.in.fnum = fnum;
159         io.lock.in.count = 4002;
160         io.lock.in.offset = 10001;
161         status = smb_raw_lock(cli->tree, &io);
162         CHECK_STATUS(status, NT_STATUS_OK);
163         cli->session->pid++;
164         io.lock.level = RAW_LOCK_UNLOCK;
165         status = smb_raw_lock(cli->tree, &io);
166         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
167         cli->session->pid--;
168         status = smb_raw_lock(cli->tree, &io);
169         CHECK_STATUS(status, NT_STATUS_OK);
170
171 done:
172         smbcli_close(cli->tree, fnum);
173         smb_raw_exit(cli->session);
174         smbcli_deltree(cli->tree, BASEDIR);
175         return ret;
176 }
177
178
179 /*
180   test locking&X ops
181 */
182 static BOOL test_lockx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
183 {
184         union smb_lock io;
185         struct smb_lock_entry lock[1];
186         NTSTATUS status;
187         BOOL ret = True;
188         int fnum;
189         const char *fname = BASEDIR "\\test.txt";
190
191         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
192             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
193                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
194                 return False;
195         }
196
197         printf("Testing RAW_LOCK_LOCKX\n");
198         io.generic.level = RAW_LOCK_LOCKX;
199         
200         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
201         if (fnum == -1) {
202                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
203                 ret = False;
204                 goto done;
205         }
206
207         io.lockx.level = RAW_LOCK_LOCKX;
208         io.lockx.in.fnum = fnum;
209         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
210         io.lockx.in.timeout = 0;
211         io.lockx.in.ulock_cnt = 0;
212         io.lockx.in.lock_cnt = 1;
213         lock[0].pid = cli->session->pid;
214         lock[0].offset = 10;
215         lock[0].count = 1;
216         io.lockx.in.locks = &lock[0];
217         status = smb_raw_lock(cli->tree, &io);
218         CHECK_STATUS(status, NT_STATUS_OK);
219
220
221         printf("Trying 0xEEFFFFFF lock\n");
222         io.lockx.in.ulock_cnt = 0;
223         io.lockx.in.lock_cnt = 1;
224         lock[0].count = 4000;
225         lock[0].offset = 0xEEFFFFFF;
226         status = smb_raw_lock(cli->tree, &io);
227         CHECK_STATUS(status, NT_STATUS_OK);
228         lock[0].pid++;
229         status = smb_raw_lock(cli->tree, &io);
230         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
231         lock[0].pid--;
232         io.lockx.in.ulock_cnt = 1;
233         io.lockx.in.lock_cnt = 0;
234         status = smb_raw_lock(cli->tree, &io);
235         CHECK_STATUS(status, NT_STATUS_OK);
236         status = smb_raw_lock(cli->tree, &io);
237         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
238
239         printf("Trying 0xEF000000 lock\n");
240         io.lockx.in.ulock_cnt = 0;
241         io.lockx.in.lock_cnt = 1;
242         lock[0].count = 4000;
243         lock[0].offset = 0xEF000000;
244         status = smb_raw_lock(cli->tree, &io);
245         CHECK_STATUS(status, NT_STATUS_OK);
246         lock[0].pid++;
247         status = smb_raw_lock(cli->tree, &io);
248         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
249         lock[0].pid--;
250         io.lockx.in.ulock_cnt = 1;
251         io.lockx.in.lock_cnt = 0;
252         status = smb_raw_lock(cli->tree, &io);
253         CHECK_STATUS(status, NT_STATUS_OK);
254         status = smb_raw_lock(cli->tree, &io);
255         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
256
257         printf("Trying zero lock\n");
258         io.lockx.in.ulock_cnt = 0;
259         io.lockx.in.lock_cnt = 1;
260         lock[0].count = 0;
261         lock[0].offset = ~0;
262         status = smb_raw_lock(cli->tree, &io);
263         CHECK_STATUS(status, NT_STATUS_OK);
264         lock[0].pid++;
265         status = smb_raw_lock(cli->tree, &io);
266         CHECK_STATUS(status, NT_STATUS_OK);
267         lock[0].pid--;
268         io.lockx.in.ulock_cnt = 1;
269         io.lockx.in.lock_cnt = 0;
270         status = smb_raw_lock(cli->tree, &io);
271         CHECK_STATUS(status, NT_STATUS_OK);
272         status = smb_raw_lock(cli->tree, &io);
273         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
274
275         printf("Trying max lock\n");
276         io.lockx.in.ulock_cnt = 0;
277         io.lockx.in.lock_cnt = 1;
278         lock[0].count = 0;
279         lock[0].offset = ~0;
280         status = smb_raw_lock(cli->tree, &io);
281         CHECK_STATUS(status, NT_STATUS_OK);
282         lock[0].pid++;
283         status = smb_raw_lock(cli->tree, &io);
284         CHECK_STATUS(status, NT_STATUS_OK);
285         lock[0].pid--;
286         io.lockx.in.ulock_cnt = 1;
287         io.lockx.in.lock_cnt = 0;
288         status = smb_raw_lock(cli->tree, &io);
289         CHECK_STATUS(status, NT_STATUS_OK);
290         status = smb_raw_lock(cli->tree, &io);
291         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
292
293         printf("Trying 2^63\n");
294         io.lockx.in.ulock_cnt = 0;
295         io.lockx.in.lock_cnt = 1;
296         lock[0].count = 1;
297         lock[0].offset = 1;
298         lock[0].offset <<= 63;
299         status = smb_raw_lock(cli->tree, &io);
300         CHECK_STATUS(status, NT_STATUS_OK);
301         lock[0].pid++;
302         status = smb_raw_lock(cli->tree, &io);
303         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
304         lock[0].pid--;
305         io.lockx.in.ulock_cnt = 1;
306         io.lockx.in.lock_cnt = 0;
307         status = smb_raw_lock(cli->tree, &io);
308         CHECK_STATUS(status, NT_STATUS_OK);
309         status = smb_raw_lock(cli->tree, &io);
310         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
311
312         printf("Trying 2^63 - 1\n");
313         io.lockx.in.ulock_cnt = 0;
314         io.lockx.in.lock_cnt = 1;
315         lock[0].count = 1;
316         lock[0].offset = 1;
317         lock[0].offset <<= 63;
318         lock[0].offset--;
319         status = smb_raw_lock(cli->tree, &io);
320         CHECK_STATUS(status, NT_STATUS_OK);
321         lock[0].pid++;
322         status = smb_raw_lock(cli->tree, &io);
323         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
324         lock[0].pid--;
325         io.lockx.in.ulock_cnt = 1;
326         io.lockx.in.lock_cnt = 0;
327         status = smb_raw_lock(cli->tree, &io);
328         CHECK_STATUS(status, NT_STATUS_OK);
329         status = smb_raw_lock(cli->tree, &io);
330         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
331
332         printf("Trying max lock 2\n");
333         io.lockx.in.ulock_cnt = 0;
334         io.lockx.in.lock_cnt = 1;
335         lock[0].count = 1;
336         lock[0].offset = ~0;
337         status = smb_raw_lock(cli->tree, &io);
338         CHECK_STATUS(status, NT_STATUS_OK);
339         lock[0].pid++;
340         lock[0].count = 2;
341         status = smb_raw_lock(cli->tree, &io);
342         CHECK_STATUS(status, NT_STATUS_OK);
343         lock[0].pid--;
344         io.lockx.in.ulock_cnt = 1;
345         io.lockx.in.lock_cnt = 0;
346         lock[0].count = 1;
347         status = smb_raw_lock(cli->tree, &io);
348         CHECK_STATUS(status, NT_STATUS_OK);
349         status = smb_raw_lock(cli->tree, &io);
350         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
351
352 done:
353         smbcli_close(cli->tree, fnum);
354         smb_raw_exit(cli->session);
355         smbcli_deltree(cli->tree, BASEDIR);
356         return ret;
357 }
358
359
360 /*
361   test high pid
362 */
363 static BOOL test_pidhigh(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
364 {
365         union smb_lock io;
366         struct smb_lock_entry lock[1];
367         NTSTATUS status;
368         BOOL ret = True;
369         int fnum;
370         const char *fname = BASEDIR "\\test.txt";
371         char c = 1;
372
373         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
374             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
375                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
376                 return False;
377         }
378
379         printf("Testing high pid\n");
380         io.generic.level = RAW_LOCK_LOCKX;
381
382         cli->session->pid = 1;
383         
384         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
385         if (fnum == -1) {
386                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
387                 ret = False;
388                 goto done;
389         }
390
391         if (smbcli_write(cli->tree, fnum, 0, &c, 0, 1) != 1) {
392                 printf("Failed to write 1 byte - %s\n", smbcli_errstr(cli->tree));
393                 ret = False;
394                 goto done;
395         }
396
397         io.lockx.level = RAW_LOCK_LOCKX;
398         io.lockx.in.fnum = fnum;
399         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
400         io.lockx.in.timeout = 0;
401         io.lockx.in.ulock_cnt = 0;
402         io.lockx.in.lock_cnt = 1;
403         lock[0].pid = cli->session->pid;
404         lock[0].offset = 0;
405         lock[0].count = 0xFFFFFFFF;
406         io.lockx.in.locks = &lock[0];
407         status = smb_raw_lock(cli->tree, &io);
408         CHECK_STATUS(status, NT_STATUS_OK);
409
410         if (smbcli_read(cli->tree, fnum, &c, 0, 1) != 1) {
411                 printf("Failed to read 1 byte - %s\n", smbcli_errstr(cli->tree));
412                 ret = False;
413                 goto done;
414         }
415
416         cli->session->pid |= 0x10000;
417
418         cli->session->pid = 2;
419
420         if (smbcli_read(cli->tree, fnum, &c, 0, 1) == 1) {
421                 printf("pid is incorrect handled for read with lock!\n");
422                 ret = False;
423                 goto done;
424         }
425
426         cli->session->pid = 0x10001;
427
428         if (smbcli_read(cli->tree, fnum, &c, 0, 1) != 1) {
429                 printf("High pid is used on this server!\n");
430                 ret = False;
431         } else {
432                 printf("High pid is not used on this server (correct)\n");
433         }
434
435 done:
436         smbcli_close(cli->tree, fnum);
437         smb_raw_exit(cli->session);
438         smbcli_deltree(cli->tree, BASEDIR);
439         return ret;
440 }
441
442
443 /*
444   test locking&X async operation
445 */
446 static BOOL test_async(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
447 {
448         union smb_lock io;
449         struct smb_lock_entry lock[2];
450         NTSTATUS status;
451         BOOL ret = True;
452         int fnum;
453         const char *fname = BASEDIR "\\test.txt";
454         time_t t;
455         struct smbcli_request *req;
456
457         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
458             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
459                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
460                 return False;
461         }
462
463         printf("Testing LOCKING_ANDX_CANCEL_LOCK\n");
464         io.generic.level = RAW_LOCK_LOCKX;
465         
466         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
467         if (fnum == -1) {
468                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
469                 ret = False;
470                 goto done;
471         }
472
473         io.lockx.level = RAW_LOCK_LOCKX;
474         io.lockx.in.fnum = fnum;
475         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
476         io.lockx.in.timeout = 0;
477         io.lockx.in.ulock_cnt = 0;
478         io.lockx.in.lock_cnt = 1;
479         lock[0].pid = cli->session->pid;
480         lock[0].offset = 100;
481         lock[0].count = 10;
482         io.lockx.in.locks = &lock[0];
483         status = smb_raw_lock(cli->tree, &io);
484         CHECK_STATUS(status, NT_STATUS_OK);
485
486         t = time(NULL);
487
488         printf("testing cancel by CANCEL_LOCK\n");
489
490         /* setup a timed lock */
491         io.lockx.in.timeout = 10000;
492         req = smb_raw_lock_send(cli->tree, &io);
493         if (req == NULL) {
494                 printf("Failed to setup timed lock (%s)\n", __location__);
495                 ret = False;
496                 goto done;
497         }
498
499         /* cancel the wrong range */
500         lock[0].offset = 0;
501         io.lockx.in.timeout = 0;
502         io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK;
503         status = smb_raw_lock(cli->tree, &io);
504         CHECK_STATUS(status, NT_STATUS_UNSUCCESSFUL);
505
506         /* cancel with the wrong bits set */
507         lock[0].offset = 100;
508         io.lockx.in.timeout = 0;
509         io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK;
510         status = smb_raw_lock(cli->tree, &io);
511         CHECK_STATUS(status, NT_STATUS_UNSUCCESSFUL);
512
513         /* cancel the right range */
514         lock[0].offset = 100;
515         io.lockx.in.timeout = 0;
516         io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES;
517         status = smb_raw_lock(cli->tree, &io);
518         CHECK_STATUS(status, NT_STATUS_OK);
519
520         /* receive the failed lock request */
521         status = smbcli_request_simple_recv(req);
522         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
523
524         if (time(NULL) > t+2) {
525                 printf("lock cancel was not immediate (%s)\n", __location__);
526                 ret = False;
527                 goto done;
528         }
529
530         printf("testing cancel by unlock\n");
531         io.lockx.in.ulock_cnt = 0;
532         io.lockx.in.lock_cnt = 1;
533         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
534         io.lockx.in.timeout = 0;
535         status = smb_raw_lock(cli->tree, &io);
536         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
537
538         io.lockx.in.timeout = 5000;
539         req = smb_raw_lock_send(cli->tree, &io);
540         if (req == NULL) {
541                 printf("Failed to setup timed lock (%s)\n", __location__);
542                 ret = False;
543                 goto done;
544         }
545
546         io.lockx.in.ulock_cnt = 1;
547         io.lockx.in.lock_cnt = 0;
548         status = smb_raw_lock(cli->tree, &io);
549         CHECK_STATUS(status, NT_STATUS_OK);
550
551         status = smbcli_request_simple_recv(req);
552         CHECK_STATUS(status, NT_STATUS_OK);
553
554         if (time(NULL) > t+2) {
555                 printf("lock cancel by unlock was not immediate (%s)\n", __location__);
556                 ret = False;
557                 goto done;
558         }
559
560
561         printf("testing cancel by close\n");
562         io.lockx.in.ulock_cnt = 0;
563         io.lockx.in.lock_cnt = 1;
564         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
565         io.lockx.in.timeout = 0;
566         status = smb_raw_lock(cli->tree, &io);
567         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
568
569         io.lockx.in.timeout = 10000;
570         req = smb_raw_lock_send(cli->tree, &io);
571         if (req == NULL) {
572                 printf("Failed to setup timed lock (%s)\n", __location__);
573                 ret = False;
574                 goto done;
575         }
576
577         smbcli_close(cli->tree, fnum);
578
579         status = smbcli_request_simple_recv(req);
580         CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
581
582         if (time(NULL) > t+2) {
583                 printf("lock cancel by unlock was not immediate (%s)\n", __location__);
584                 ret = False;
585                 goto done;
586         }
587         
588
589 done:
590         smbcli_close(cli->tree, fnum);
591         smb_raw_exit(cli->session);
592         smbcli_deltree(cli->tree, BASEDIR);
593         return ret;
594 }
595
596
597 /*
598   test LOCKING_ANDX_CHANGE_LOCKTYPE
599 */
600 static BOOL test_changetype(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
601 {
602         union smb_lock io;
603         struct smb_lock_entry lock[2];
604         NTSTATUS status;
605         BOOL ret = True;
606         int fnum;
607         char c = 0;
608         const char *fname = BASEDIR "\\test.txt";
609
610         if (smbcli_deltree(cli->tree, BASEDIR) == -1 ||
611             NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, BASEDIR))) {
612                 printf("Unable to setup %s - %s\n", BASEDIR, smbcli_errstr(cli->tree));
613                 return False;
614         }
615
616         printf("Testing LOCKING_ANDX_CHANGE_LOCKTYPE\n");
617         io.generic.level = RAW_LOCK_LOCKX;
618         
619         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
620         if (fnum == -1) {
621                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
622                 ret = False;
623                 goto done;
624         }
625
626         io.lockx.level = RAW_LOCK_LOCKX;
627         io.lockx.in.fnum = fnum;
628         io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK;
629         io.lockx.in.timeout = 0;
630         io.lockx.in.ulock_cnt = 0;
631         io.lockx.in.lock_cnt = 1;
632         lock[0].pid = cli->session->pid;
633         lock[0].offset = 100;
634         lock[0].count = 10;
635         io.lockx.in.locks = &lock[0];
636         status = smb_raw_lock(cli->tree, &io);
637         CHECK_STATUS(status, NT_STATUS_OK);
638
639         if (smbcli_write(cli->tree, fnum, 0, &c, 100, 1) == 1) {
640                 printf("allowed write on read locked region (%s)\n", __location__);
641                 ret = False;
642                 goto done;
643         }
644
645         /* windows server don't seem to support this */
646         io.lockx.in.mode = LOCKING_ANDX_CHANGE_LOCKTYPE;
647         status = smb_raw_lock(cli->tree, &io);
648         CHECK_STATUS(status, NT_STATUS_UNSUCCESSFUL);
649
650         if (smbcli_write(cli->tree, fnum, 0, &c, 100, 1) == 1) {
651                 printf("allowed write after lock change (%s)\n", __location__);
652                 ret = False;
653                 goto done;
654         }
655
656 done:
657         smbcli_close(cli->tree, fnum);
658         smb_raw_exit(cli->session);
659         smbcli_deltree(cli->tree, BASEDIR);
660         return ret;
661 }
662
663
664 /* 
665    basic testing of lock calls
666 */
667 BOOL torture_raw_lock(void)
668 {
669         struct smbcli_state *cli;
670         BOOL ret = True;
671         TALLOC_CTX *mem_ctx;
672
673         if (!torture_open_connection(&cli)) {
674                 return False;
675         }
676
677         mem_ctx = talloc_init("torture_raw_lock");
678
679         ret &= test_lockx(cli, mem_ctx);
680         ret &= test_lock(cli, mem_ctx);
681         ret &= test_pidhigh(cli, mem_ctx);
682         ret &= test_async(cli, mem_ctx);
683         ret &= test_changetype(cli, mem_ctx);
684
685         torture_close_connection(cli);
686         talloc_destroy(mem_ctx);
687         return ret;
688 }