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