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