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