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