RAW-OPLOCK: be more strict with share modes against windows and samba4
[gd/samba-autobuild/.git] / source4 / torture / raw / oplock.c
1 /* 
2    Unix SMB/CIFS implementation.
3    basic raw test suite for oplocks
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 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "torture/torture.h"
22 #include "librpc/gen_ndr/security.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/libcli.h"
25 #include "torture/util.h"
26 #include "lib/events/events.h"
27
28 #define CHECK_VAL(v, correct) do { \
29         if ((v) != (correct)) { \
30                 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
31                                 __location__, #v, (int)v, (int)correct); \
32                 ret = false; \
33         }} while (0)
34
35 #define CHECK_STRMATCH(v, correct) do { \
36         if (!v || strstr((v),(correct)) == NULL) { \
37                 torture_result(tctx, TORTURE_FAIL,  "(%s): wrong value for %s got '%s' - should be '%s'\n", \
38                                 __location__, #v, v?v:"NULL", correct); \
39                 ret = false; \
40         } \
41 } while (0)
42
43 #define CHECK_STATUS(tctx, status, correct) do { \
44         if (!NT_STATUS_EQUAL(status, correct)) { \
45                 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
46                        nt_errstr(status), nt_errstr(correct)); \
47                 ret = false; \
48                 goto done; \
49         }} while (0)
50
51
52 static struct {
53         int fnum;
54         uint8_t level;
55         int count;
56         int failures;
57 } break_info;
58
59 #define BASEDIR "\\test_oplock"
60
61 /*
62   a handler function for oplock break requests. Ack it as a break to level II if possible
63 */
64 static bool oplock_handler_ack_to_levelII(struct smbcli_transport *transport, 
65                                           uint16_t tid, uint16_t fnum, 
66                                           uint8_t level, void *private)
67 {
68         struct smbcli_tree *tree = (struct smbcli_tree *)private;
69         break_info.fnum = fnum;
70         break_info.level = level;
71         break_info.count++;
72
73         printf("Acking to level II in oplock handler\n");
74
75         return smbcli_oplock_ack(tree, fnum, level);
76 }
77
78 /*
79   a handler function for oplock break requests. Ack it as a break to none
80 */
81 static bool oplock_handler_ack_to_none(struct smbcli_transport *transport, 
82                                        uint16_t tid, uint16_t fnum, 
83                                        uint8_t level, void *private)
84 {
85         struct smbcli_tree *tree = (struct smbcli_tree *)private;
86         break_info.fnum = fnum;
87         break_info.level = level;
88         break_info.count++;
89
90         printf("Acking to none in oplock handler\n");
91
92         return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
93 }
94
95 static void oplock_handler_close_recv(struct smbcli_request *req)
96 {
97         NTSTATUS status;
98         status = smbcli_request_simple_recv(req);
99         if (!NT_STATUS_IS_OK(status)) {
100                 printf("close failed in oplock_handler_close\n");
101                 break_info.failures++;
102         }
103 }
104
105 /*
106   a handler function for oplock break requests - close the file
107 */
108 static bool oplock_handler_close(struct smbcli_transport *transport, uint16_t tid, 
109                                  uint16_t fnum, uint8_t level, void *private)
110 {
111         union smb_close io;
112         struct smbcli_tree *tree = (struct smbcli_tree *)private;
113         struct smbcli_request *req;
114
115         break_info.fnum = fnum;
116         break_info.level = level;
117         break_info.count++;
118
119         io.close.level = RAW_CLOSE_CLOSE;
120         io.close.in.file.fnum = fnum;
121         io.close.in.write_time = 0;
122         req = smb_raw_close_send(tree, &io);
123         if (req == NULL) {
124                 printf("failed to send close in oplock_handler_close\n");
125                 return false;
126         }
127
128         req->async.fn = oplock_handler_close_recv;
129         req->async.private = NULL;
130
131         return true;
132 }
133
134 static bool test_raw_oplock_exclusive1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
135 {
136         const char *fname = BASEDIR "\\test_exclusive1.dat";
137         NTSTATUS status;
138         bool ret = true;
139         union smb_open io;
140         union smb_unlink unl;
141         uint16_t fnum=0;
142
143         if (!torture_setup_dir(cli1, BASEDIR)) {
144                 return false;
145         }
146
147         /* cleanup */
148         smbcli_unlink(cli1->tree, fname);
149
150         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
151
152         /*
153           base ntcreatex parms
154         */
155         io.generic.level = RAW_OPEN_NTCREATEX;
156         io.ntcreatex.in.root_fid = 0;
157         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
158         io.ntcreatex.in.alloc_size = 0;
159         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
160         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
161         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
162         io.ntcreatex.in.create_options = 0;
163         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
164         io.ntcreatex.in.security_flags = 0;
165         io.ntcreatex.in.fname = fname;
166
167         torture_comment(tctx, "open a file with an exclusive oplock (share mode: none)\n");
168         ZERO_STRUCT(break_info);
169         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
170
171         status = smb_raw_open(cli1->tree, tctx, &io);
172         CHECK_STATUS(tctx, status, NT_STATUS_OK);
173         fnum = io.ntcreatex.out.file.fnum;
174         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
175
176         torture_comment(tctx, "a 2nd open should not cause a break\n");
177         status = smb_raw_open(cli2->tree, tctx, &io);
178         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
179         CHECK_VAL(break_info.count, 0);
180         CHECK_VAL(break_info.failures, 0);
181
182         torture_comment(tctx, "unlink it - should also be no break\n");
183         unl.unlink.in.pattern = fname;
184         unl.unlink.in.attrib = 0;
185         status = smb_raw_unlink(cli2->tree, &unl);
186         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
187         CHECK_VAL(break_info.count, 0);
188         CHECK_VAL(break_info.failures, 0);
189
190         smbcli_close(cli1->tree, fnum);
191
192 done:
193         smb_raw_exit(cli1->session);
194         smb_raw_exit(cli2->session);
195         smbcli_deltree(cli1->tree, BASEDIR);
196         return ret;
197 }
198
199 static bool test_raw_oplock_exclusive2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
200 {
201         const char *fname = BASEDIR "\\test_exclusive2.dat";
202         NTSTATUS status;
203         bool ret = true;
204         union smb_open io;
205         union smb_unlink unl;
206         uint16_t fnum=0, fnum2=0;
207
208         if (!torture_setup_dir(cli1, BASEDIR)) {
209                 return false;
210         }
211
212         /* cleanup */
213         smbcli_unlink(cli1->tree, fname);
214
215         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
216
217         /*
218           base ntcreatex parms
219         */
220         io.generic.level = RAW_OPEN_NTCREATEX;
221         io.ntcreatex.in.root_fid = 0;
222         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
223         io.ntcreatex.in.alloc_size = 0;
224         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
225         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
226         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
227         io.ntcreatex.in.create_options = 0;
228         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
229         io.ntcreatex.in.security_flags = 0;
230         io.ntcreatex.in.fname = fname;
231
232         torture_comment(tctx, "open a file with an exclusive oplock (share mode: all)\n");
233         ZERO_STRUCT(break_info);
234         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
235         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
236                 NTCREATEX_SHARE_ACCESS_WRITE|
237                 NTCREATEX_SHARE_ACCESS_DELETE;
238
239         status = smb_raw_open(cli1->tree, tctx, &io);
240         CHECK_STATUS(tctx, status, NT_STATUS_OK);
241         fnum = io.ntcreatex.out.file.fnum;
242         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
243
244         torture_comment(tctx, "a 2nd open should cause a break to level 2\n");
245         status = smb_raw_open(cli2->tree, tctx, &io);
246         CHECK_STATUS(tctx, status, NT_STATUS_OK);
247         fnum2 = io.ntcreatex.out.file.fnum;
248         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
249         CHECK_VAL(break_info.count, 1);
250         CHECK_VAL(break_info.fnum, fnum);
251         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
252         CHECK_VAL(break_info.failures, 0);
253         ZERO_STRUCT(break_info);
254
255         /* now we have 2 level II oplocks... */
256         torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
257         unl.unlink.in.pattern = fname;
258         unl.unlink.in.attrib = 0;
259         status = smb_raw_unlink(cli2->tree, &unl);
260         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
261         CHECK_VAL(break_info.count, 0);
262         CHECK_VAL(break_info.failures, 0);
263
264         torture_comment(tctx, "close 1st handle\n");
265         smbcli_close(cli1->tree, fnum);
266
267         torture_comment(tctx, "try to unlink it - should not cause a break, but a sharing violation\n");
268         unl.unlink.in.pattern = fname;
269         unl.unlink.in.attrib = 0;
270         status = smb_raw_unlink(cli2->tree, &unl);
271         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
272         CHECK_VAL(break_info.count, 0);
273         CHECK_VAL(break_info.failures, 0);
274
275         torture_comment(tctx, "close 1st handle\n");
276         smbcli_close(cli2->tree, fnum2);
277
278         torture_comment(tctx, "unlink it\n");
279         unl.unlink.in.pattern = fname;
280         unl.unlink.in.attrib = 0;
281         status = smb_raw_unlink(cli2->tree, &unl);
282         CHECK_STATUS(tctx, status, NT_STATUS_OK);
283         CHECK_VAL(break_info.count, 0);
284         CHECK_VAL(break_info.failures, 0);
285
286 done:
287         smb_raw_exit(cli1->session);
288         smb_raw_exit(cli2->session);
289         smbcli_deltree(cli1->tree, BASEDIR);
290         return ret;
291 }
292
293 static bool test_raw_oplock_exclusive3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
294 {
295         const char *fname = BASEDIR "\\test_exclusive3.dat";
296         NTSTATUS status;
297         bool ret = true;
298         union smb_open io;
299         union smb_setfileinfo sfi;
300         uint16_t fnum=0;
301         bool s3 = torture_setting_bool(tctx, "samba3", false);
302
303         if (!torture_setup_dir(cli1, BASEDIR)) {
304                 return false;
305         }
306
307         /* cleanup */
308         smbcli_unlink(cli1->tree, fname);
309
310         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
311
312         /*
313           base ntcreatex parms
314         */
315         io.generic.level = RAW_OPEN_NTCREATEX;
316         io.ntcreatex.in.root_fid = 0;
317         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
318         io.ntcreatex.in.alloc_size = 0;
319         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
320         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
321         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
322         io.ntcreatex.in.create_options = 0;
323         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
324         io.ntcreatex.in.security_flags = 0;
325         io.ntcreatex.in.fname = fname;
326
327         torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
328                         s3?"all":"none");
329         ZERO_STRUCT(break_info);
330         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
331         if (s3) {
332                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
333                         NTCREATEX_SHARE_ACCESS_WRITE|
334                         NTCREATEX_SHARE_ACCESS_DELETE;
335         }
336
337         status = smb_raw_open(cli1->tree, tctx, &io);
338         CHECK_STATUS(tctx, status, NT_STATUS_OK);
339         fnum = io.ntcreatex.out.file.fnum;
340         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
341
342         torture_comment(tctx, "setpathinfo EOF should trigger a break to none\n");
343         ZERO_STRUCT(sfi);
344         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
345         sfi.generic.in.file.path = fname;
346         sfi.end_of_file_info.in.size = 100;
347
348         status = smb_raw_setpathinfo(cli2->tree, &sfi);
349
350         CHECK_STATUS(tctx, status, NT_STATUS_OK);
351         CHECK_VAL(break_info.count, 1);
352         CHECK_VAL(break_info.failures, 0);
353         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
354
355         smbcli_close(cli1->tree, fnum);
356
357 done:
358         smb_raw_exit(cli1->session);
359         smb_raw_exit(cli2->session);
360         smbcli_deltree(cli1->tree, BASEDIR);
361         return ret;
362 }
363
364 static bool test_raw_oplock_exclusive4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
365 {
366         const char *fname = BASEDIR "\\test_exclusive4.dat";
367         NTSTATUS status;
368         bool ret = true;
369         union smb_open io;
370         uint16_t fnum=0, fnum2=0;
371
372         if (!torture_setup_dir(cli1, BASEDIR)) {
373                 return false;
374         }
375
376         /* cleanup */
377         smbcli_unlink(cli1->tree, fname);
378
379         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
380
381         /*
382           base ntcreatex parms
383         */
384         io.generic.level = RAW_OPEN_NTCREATEX;
385         io.ntcreatex.in.root_fid = 0;
386         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
387         io.ntcreatex.in.alloc_size = 0;
388         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
389         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
390         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
391         io.ntcreatex.in.create_options = 0;
392         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
393         io.ntcreatex.in.security_flags = 0;
394         io.ntcreatex.in.fname = fname;
395
396         torture_comment(tctx, "open with exclusive oplock\n");
397         ZERO_STRUCT(break_info);
398         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
399
400         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
401         status = smb_raw_open(cli1->tree, tctx, &io);
402         CHECK_STATUS(tctx, status, NT_STATUS_OK);
403         fnum = io.ntcreatex.out.file.fnum;
404         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
405
406         ZERO_STRUCT(break_info);
407         torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
408
409         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
410         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
411         status = smb_raw_open(cli2->tree, tctx, &io);
412         CHECK_STATUS(tctx, status, NT_STATUS_OK);
413         fnum2 = io.ntcreatex.out.file.fnum;
414         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
415         CHECK_VAL(break_info.count, 0);
416         CHECK_VAL(break_info.failures, 0);
417
418         smbcli_close(cli1->tree, fnum);
419         smbcli_close(cli2->tree, fnum2);
420
421 done:
422         smb_raw_exit(cli1->session);
423         smb_raw_exit(cli2->session);
424         smbcli_deltree(cli1->tree, BASEDIR);
425         return ret;
426 }
427
428 static bool test_raw_oplock_exclusive5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
429 {
430         const char *fname = BASEDIR "\\test_exclusive5.dat";
431         NTSTATUS status;
432         bool ret = true;
433         union smb_open io;
434         uint16_t fnum=0, fnum2=0;
435
436         if (!torture_setup_dir(cli1, BASEDIR)) {
437                 return false;
438         }
439
440         /* cleanup */
441         smbcli_unlink(cli1->tree, fname);
442
443         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
444         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
445
446         /*
447           base ntcreatex parms
448         */
449         io.generic.level = RAW_OPEN_NTCREATEX;
450         io.ntcreatex.in.root_fid = 0;
451         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
452         io.ntcreatex.in.alloc_size = 0;
453         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
454         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
455         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
456         io.ntcreatex.in.create_options = 0;
457         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
458         io.ntcreatex.in.security_flags = 0;
459         io.ntcreatex.in.fname = fname;
460
461         torture_comment(tctx, "open with exclusive oplock\n");
462         ZERO_STRUCT(break_info);
463         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
464
465
466         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
467         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
468                 NTCREATEX_SHARE_ACCESS_WRITE|
469                 NTCREATEX_SHARE_ACCESS_DELETE;
470         status = smb_raw_open(cli1->tree, tctx, &io);
471         CHECK_STATUS(tctx, status, NT_STATUS_OK);
472         fnum = io.ntcreatex.out.file.fnum;
473         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
474
475         ZERO_STRUCT(break_info);
476
477         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
478
479         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
480         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
481         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
482         status = smb_raw_open(cli2->tree, tctx, &io);
483         CHECK_STATUS(tctx, status, NT_STATUS_OK);
484         fnum2 = io.ntcreatex.out.file.fnum;
485         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
486         CHECK_VAL(break_info.count, 1);
487         CHECK_VAL(break_info.failures, 0);
488
489         smbcli_close(cli1->tree, fnum);
490         smbcli_close(cli2->tree, fnum2);
491
492 done:
493         smb_raw_exit(cli1->session);
494         smb_raw_exit(cli2->session);
495         smbcli_deltree(cli1->tree, BASEDIR);
496         return ret;
497 }
498
499 static bool test_raw_oplock_exclusive6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
500 {
501         const char *fname1 = BASEDIR "\\test_exclusive6_1.dat";
502         const char *fname2 = BASEDIR "\\test_exclusive6_2.dat";
503         NTSTATUS status;
504         bool ret = true;
505         union smb_open io;
506         union smb_rename rn;
507         uint16_t fnum=0;
508         bool s3 = torture_setting_bool(tctx, "samba3", false);
509
510         if (!torture_setup_dir(cli1, BASEDIR)) {
511                 return false;
512         }
513
514         /* cleanup */
515         smbcli_unlink(cli1->tree, fname1);
516         smbcli_unlink(cli1->tree, fname2);
517
518         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
519
520         /*
521           base ntcreatex parms
522         */
523         io.generic.level = RAW_OPEN_NTCREATEX;
524         io.ntcreatex.in.root_fid = 0;
525         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
526         io.ntcreatex.in.alloc_size = 0;
527         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
528         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
529         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
530         io.ntcreatex.in.create_options = 0;
531         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
532         io.ntcreatex.in.security_flags = 0;
533         io.ntcreatex.in.fname = fname1;
534
535         /* we should use no share mode, when samba3 passes this */
536         torture_comment(tctx, "open a file with an exclusive oplock (share mode: %s)\n",
537                         s3?"all":"none");
538         ZERO_STRUCT(break_info);
539         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK;
540         if (s3) {
541                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
542                         NTCREATEX_SHARE_ACCESS_WRITE|
543                         NTCREATEX_SHARE_ACCESS_DELETE;
544         }
545
546         status = smb_raw_open(cli1->tree, tctx, &io);
547         CHECK_STATUS(tctx, status, NT_STATUS_OK);
548         fnum = io.ntcreatex.out.file.fnum;
549         CHECK_VAL(io.ntcreatex.out.oplock_level, EXCLUSIVE_OPLOCK_RETURN);
550
551         torture_comment(tctx, "rename should not generate a break but get a sharing violation\n");
552         ZERO_STRUCT(rn);
553         rn.generic.level = RAW_RENAME_RENAME;
554         rn.rename.in.pattern1 = fname1;
555         rn.rename.in.pattern2 = fname2;
556         rn.rename.in.attrib = 0;
557
558         printf("trying rename while first file open\n");
559         status = smb_raw_rename(cli2->tree, &rn);
560
561         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
562         CHECK_VAL(break_info.count, 0);
563         CHECK_VAL(break_info.failures, 0);
564
565         smbcli_close(cli1->tree, fnum);
566
567 done:
568         smb_raw_exit(cli1->session);
569         smb_raw_exit(cli2->session);
570         smbcli_deltree(cli1->tree, BASEDIR);
571         return ret;
572 }
573
574 static bool test_raw_oplock_batch1(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
575 {
576         const char *fname = BASEDIR "\\test_batch1.dat";
577         NTSTATUS status;
578         bool ret = true;
579         union smb_open io;
580         union smb_unlink unl;
581         uint16_t fnum=0;
582         char c = 0;
583
584         if (!torture_setup_dir(cli1, BASEDIR)) {
585                 return false;
586         }
587
588         /* cleanup */
589         smbcli_unlink(cli1->tree, fname);
590
591         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
592
593         /*
594           base ntcreatex parms
595         */
596         io.generic.level = RAW_OPEN_NTCREATEX;
597         io.ntcreatex.in.root_fid = 0;
598         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
599         io.ntcreatex.in.alloc_size = 0;
600         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
601         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
602         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
603         io.ntcreatex.in.create_options = 0;
604         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
605         io.ntcreatex.in.security_flags = 0;
606         io.ntcreatex.in.fname = fname;
607
608         /*
609           with a batch oplock we get a break
610         */
611         torture_comment(tctx, "open with batch oplock\n");
612         ZERO_STRUCT(break_info);
613         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
614                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
615                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
616         status = smb_raw_open(cli1->tree, tctx, &io);
617         CHECK_STATUS(tctx, status, NT_STATUS_OK);
618         fnum = io.ntcreatex.out.file.fnum;
619         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
620
621         torture_comment(tctx, "unlink should generate a break\n");
622         unl.unlink.in.pattern = fname;
623         unl.unlink.in.attrib = 0;
624         status = smb_raw_unlink(cli2->tree, &unl);
625         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
626
627         CHECK_VAL(break_info.count, 1);
628         CHECK_VAL(break_info.fnum, fnum);
629         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
630         CHECK_VAL(break_info.failures, 0);
631
632         torture_comment(tctx, "2nd unlink should not generate a break\n");
633         ZERO_STRUCT(break_info);
634         status = smb_raw_unlink(cli2->tree, &unl);
635         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
636
637         CHECK_VAL(break_info.count, 0);
638
639         torture_comment(tctx, "writing should generate a self break to none\n");
640         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
641         msleep(100);
642         smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
643
644         CHECK_VAL(break_info.count, 1);
645         CHECK_VAL(break_info.fnum, fnum);
646         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_NONE);
647         CHECK_VAL(break_info.failures, 0);
648
649         smbcli_close(cli1->tree, fnum);
650
651 done:
652         smb_raw_exit(cli1->session);
653         smb_raw_exit(cli2->session);
654         smbcli_deltree(cli1->tree, BASEDIR);
655         return ret;
656 }
657
658 static bool test_raw_oplock_batch2(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
659 {
660         const char *fname = BASEDIR "\\test_batch2.dat";
661         NTSTATUS status;
662         bool ret = true;
663         union smb_open io;
664         union smb_unlink unl;
665         uint16_t fnum=0;
666         char c = 0;
667
668         if (!torture_setup_dir(cli1, BASEDIR)) {
669                 return false;
670         }
671
672         /* cleanup */
673         smbcli_unlink(cli1->tree, fname);
674
675         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
676
677         /*
678           base ntcreatex parms
679         */
680         io.generic.level = RAW_OPEN_NTCREATEX;
681         io.ntcreatex.in.root_fid = 0;
682         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
683         io.ntcreatex.in.alloc_size = 0;
684         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
685         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
686         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
687         io.ntcreatex.in.create_options = 0;
688         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
689         io.ntcreatex.in.security_flags = 0;
690         io.ntcreatex.in.fname = fname;
691
692         torture_comment(tctx, "open with batch oplock\n");
693         ZERO_STRUCT(break_info);
694         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
695                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
696                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
697         status = smb_raw_open(cli1->tree, tctx, &io);
698         CHECK_STATUS(tctx, status, NT_STATUS_OK);
699         fnum = io.ntcreatex.out.file.fnum;
700         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
701
702         torture_comment(tctx, "unlink should generate a break, which we ack as break to none\n");
703         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_none, cli1->tree);
704         unl.unlink.in.pattern = fname;
705         unl.unlink.in.attrib = 0;
706         status = smb_raw_unlink(cli2->tree, &unl);
707         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
708
709         CHECK_VAL(break_info.count, 1);
710         CHECK_VAL(break_info.fnum, fnum);
711         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
712         CHECK_VAL(break_info.failures, 0);
713
714         torture_comment(tctx, "2nd unlink should not generate a break\n");
715         ZERO_STRUCT(break_info);
716         status = smb_raw_unlink(cli2->tree, &unl);
717         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
718
719         CHECK_VAL(break_info.count, 0);
720
721         torture_comment(tctx, "writing should not generate a break\n");
722         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
723         msleep(100);
724         smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
725
726         CHECK_VAL(break_info.count, 0);
727
728         smbcli_close(cli1->tree, fnum);
729
730 done:
731         smb_raw_exit(cli1->session);
732         smb_raw_exit(cli2->session);
733         smbcli_deltree(cli1->tree, BASEDIR);
734         return ret;
735 }
736
737 static bool test_raw_oplock_batch3(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
738 {
739         const char *fname = BASEDIR "\\test_batch3.dat";
740         NTSTATUS status;
741         bool ret = true;
742         union smb_open io;
743         union smb_unlink unl;
744         uint16_t fnum=0;
745
746         if (!torture_setup_dir(cli1, BASEDIR)) {
747                 return false;
748         }
749
750         /* cleanup */
751         smbcli_unlink(cli1->tree, fname);
752
753         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
754
755         /*
756           base ntcreatex parms
757         */
758         io.generic.level = RAW_OPEN_NTCREATEX;
759         io.ntcreatex.in.root_fid = 0;
760         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
761         io.ntcreatex.in.alloc_size = 0;
762         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
763         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
764         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
765         io.ntcreatex.in.create_options = 0;
766         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
767         io.ntcreatex.in.security_flags = 0;
768         io.ntcreatex.in.fname = fname;
769
770         torture_comment(tctx, "if we close on break then the unlink can succeed\n");
771         ZERO_STRUCT(break_info);
772         smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
773         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
774                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
775                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
776         status = smb_raw_open(cli1->tree, tctx, &io);
777         CHECK_STATUS(tctx, status, NT_STATUS_OK);
778         fnum = io.ntcreatex.out.file.fnum;
779         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
780
781         unl.unlink.in.pattern = fname;
782         unl.unlink.in.attrib = 0;
783         ZERO_STRUCT(break_info);
784         status = smb_raw_unlink(cli2->tree, &unl);
785         CHECK_STATUS(tctx, status, NT_STATUS_OK);
786
787         CHECK_VAL(break_info.count, 1);
788         CHECK_VAL(break_info.fnum, fnum);
789         CHECK_VAL(break_info.level, 1);
790         CHECK_VAL(break_info.failures, 0);
791
792         smbcli_close(cli1->tree, fnum);
793
794 done:
795         smb_raw_exit(cli1->session);
796         smb_raw_exit(cli2->session);
797         smbcli_deltree(cli1->tree, BASEDIR);
798         return ret;
799 }
800
801 static bool test_raw_oplock_batch4(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
802 {
803         const char *fname = BASEDIR "\\test_batch4.dat";
804         NTSTATUS status;
805         bool ret = true;
806         union smb_open io;
807         union smb_read rd;
808         uint16_t fnum=0;
809
810         if (!torture_setup_dir(cli1, BASEDIR)) {
811                 return false;
812         }
813
814         /* cleanup */
815         smbcli_unlink(cli1->tree, fname);
816
817         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
818
819         /*
820           base ntcreatex parms
821         */
822         io.generic.level = RAW_OPEN_NTCREATEX;
823         io.ntcreatex.in.root_fid = 0;
824         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
825         io.ntcreatex.in.alloc_size = 0;
826         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
827         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
828         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
829         io.ntcreatex.in.create_options = 0;
830         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
831         io.ntcreatex.in.security_flags = 0;
832         io.ntcreatex.in.fname = fname;
833
834         torture_comment(tctx, "a self read should not cause a break\n");
835         ZERO_STRUCT(break_info);
836         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
837
838         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
839                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
840                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
841         status = smb_raw_open(cli1->tree, tctx, &io);
842         CHECK_STATUS(tctx, status, NT_STATUS_OK);
843         fnum = io.ntcreatex.out.file.fnum;
844         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
845
846         rd.read.level = RAW_READ_READ;
847         rd.read.in.file.fnum = fnum;
848         rd.read.in.count = 1;
849         rd.read.in.offset = 0;
850         rd.read.in.remaining = 0;
851         status = smb_raw_read(cli1->tree, &rd);
852         CHECK_STATUS(tctx, status, NT_STATUS_OK);
853         CHECK_VAL(break_info.count, 0);
854         CHECK_VAL(break_info.failures, 0);
855
856         smbcli_close(cli1->tree, fnum);
857
858 done:
859         smb_raw_exit(cli1->session);
860         smb_raw_exit(cli2->session);
861         smbcli_deltree(cli1->tree, BASEDIR);
862         return ret;
863 }
864
865 static bool test_raw_oplock_batch5(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
866 {
867         const char *fname = BASEDIR "\\test_batch5.dat";
868         NTSTATUS status;
869         bool ret = true;
870         union smb_open io;
871         uint16_t fnum=0;
872
873         if (!torture_setup_dir(cli1, BASEDIR)) {
874                 return false;
875         }
876
877         /* cleanup */
878         smbcli_unlink(cli1->tree, fname);
879
880         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
881
882         /*
883           base ntcreatex parms
884         */
885         io.generic.level = RAW_OPEN_NTCREATEX;
886         io.ntcreatex.in.root_fid = 0;
887         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
888         io.ntcreatex.in.alloc_size = 0;
889         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
890         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
891         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
892         io.ntcreatex.in.create_options = 0;
893         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
894         io.ntcreatex.in.security_flags = 0;
895         io.ntcreatex.in.fname = fname;
896
897         torture_comment(tctx, "a 2nd open should give a break\n");
898         ZERO_STRUCT(break_info);
899         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
900
901         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
902                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
903                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
904         status = smb_raw_open(cli1->tree, tctx, &io);
905         CHECK_STATUS(tctx, status, NT_STATUS_OK);
906         fnum = io.ntcreatex.out.file.fnum;
907         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
908
909         ZERO_STRUCT(break_info);
910
911         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
912         status = smb_raw_open(cli2->tree, tctx, &io);
913         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
914
915         CHECK_VAL(break_info.count, 1);
916         CHECK_VAL(break_info.fnum, fnum);
917         CHECK_VAL(break_info.level, 1);
918         CHECK_VAL(break_info.failures, 0);
919
920         smbcli_close(cli1->tree, fnum);
921
922 done:
923         smb_raw_exit(cli1->session);
924         smb_raw_exit(cli2->session);
925         smbcli_deltree(cli1->tree, BASEDIR);
926         return ret;
927 }
928
929 static bool test_raw_oplock_batch6(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
930 {
931         const char *fname = BASEDIR "\\test_batch6.dat";
932         NTSTATUS status;
933         bool ret = true;
934         union smb_open io;
935         uint16_t fnum=0, fnum2=0;
936         char c = 0;
937
938         if (!torture_setup_dir(cli1, BASEDIR)) {
939                 return false;
940         }
941
942         /* cleanup */
943         smbcli_unlink(cli1->tree, fname);
944
945         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
946
947         /*
948           base ntcreatex parms
949         */
950         io.generic.level = RAW_OPEN_NTCREATEX;
951         io.ntcreatex.in.root_fid = 0;
952         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
953         io.ntcreatex.in.alloc_size = 0;
954         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
955         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
956         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
957         io.ntcreatex.in.create_options = 0;
958         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
959         io.ntcreatex.in.security_flags = 0;
960         io.ntcreatex.in.fname = fname;
961
962         torture_comment(tctx, "a 2nd open should give a break to level II if the first open allowed shared read\n");
963         ZERO_STRUCT(break_info);
964         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
965         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
966
967         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE;
968         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
969         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
970                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
971                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
972         status = smb_raw_open(cli1->tree, tctx, &io);
973         CHECK_STATUS(tctx, status, NT_STATUS_OK);
974         fnum = io.ntcreatex.out.file.fnum;
975         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
976
977         ZERO_STRUCT(break_info);
978
979         status = smb_raw_open(cli2->tree, tctx, &io);
980         CHECK_STATUS(tctx, status, NT_STATUS_OK);
981         fnum2 = io.ntcreatex.out.file.fnum;
982         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
983
984         CHECK_VAL(break_info.count, 1);
985         CHECK_VAL(break_info.fnum, fnum);
986         CHECK_VAL(break_info.level, 1);
987         CHECK_VAL(break_info.failures, 0);
988         ZERO_STRUCT(break_info);
989
990         torture_comment(tctx, "write should trigger a break to none on both\n");
991         smbcli_write(cli1->tree, fnum, 0, &c, 0, 1);
992         msleep(100);
993         smbcli_write(cli1->tree, fnum, 0, &c, 1, 1);
994
995         CHECK_VAL(break_info.count, 2);
996         CHECK_VAL(break_info.level, 0);
997         CHECK_VAL(break_info.failures, 0);
998
999         smbcli_close(cli1->tree, fnum);
1000         smbcli_close(cli2->tree, fnum2);
1001
1002
1003 done:
1004         smb_raw_exit(cli1->session);
1005         smb_raw_exit(cli2->session);
1006         smbcli_deltree(cli1->tree, BASEDIR);
1007         return ret;
1008 }
1009
1010 static bool test_raw_oplock_batch7(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1011 {
1012         const char *fname = BASEDIR "\\test_batch7.dat";
1013         NTSTATUS status;
1014         bool ret = true;
1015         union smb_open io;
1016         uint16_t fnum=0, fnum2=0;
1017
1018         if (!torture_setup_dir(cli1, BASEDIR)) {
1019                 return false;
1020         }
1021
1022         /* cleanup */
1023         smbcli_unlink(cli1->tree, fname);
1024
1025         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1026
1027         /*
1028           base ntcreatex parms
1029         */
1030         io.generic.level = RAW_OPEN_NTCREATEX;
1031         io.ntcreatex.in.root_fid = 0;
1032         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1033         io.ntcreatex.in.alloc_size = 0;
1034         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1035         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1036         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1037         io.ntcreatex.in.create_options = 0;
1038         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1039         io.ntcreatex.in.security_flags = 0;
1040         io.ntcreatex.in.fname = fname;
1041
1042         torture_comment(tctx, "a 2nd open should get an oplock when we close instead of ack\n");
1043         ZERO_STRUCT(break_info);
1044         smbcli_oplock_handler(cli1->transport, oplock_handler_close, cli1->tree);
1045
1046         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1047         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1048         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1049                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1050                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1051         status = smb_raw_open(cli1->tree, tctx, &io);
1052         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1053         fnum2 = io.ntcreatex.out.file.fnum;
1054         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1055
1056         ZERO_STRUCT(break_info);
1057
1058         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1059                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1060                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1061         status = smb_raw_open(cli2->tree, tctx, &io);
1062         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1063         fnum = io.ntcreatex.out.file.fnum;
1064         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1065
1066         CHECK_VAL(break_info.count, 1);
1067         CHECK_VAL(break_info.fnum, fnum2);
1068         CHECK_VAL(break_info.level, 1);
1069         CHECK_VAL(break_info.failures, 0);
1070         
1071         smbcli_close(cli2->tree, fnum);
1072
1073 done:
1074         smb_raw_exit(cli1->session);
1075         smb_raw_exit(cli2->session);
1076         smbcli_deltree(cli1->tree, BASEDIR);
1077         return ret;
1078 }
1079
1080 static bool test_raw_oplock_batch8(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1081 {
1082         const char *fname = BASEDIR "\\test_batch8.dat";
1083         NTSTATUS status;
1084         bool ret = true;
1085         union smb_open io;
1086         uint16_t fnum=0, fnum2=0;
1087
1088         if (!torture_setup_dir(cli1, BASEDIR)) {
1089                 return false;
1090         }
1091
1092         /* cleanup */
1093         smbcli_unlink(cli1->tree, fname);
1094
1095         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1096
1097         /*
1098           base ntcreatex parms
1099         */
1100         io.generic.level = RAW_OPEN_NTCREATEX;
1101         io.ntcreatex.in.root_fid = 0;
1102         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1103         io.ntcreatex.in.alloc_size = 0;
1104         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1105         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1106         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1107         io.ntcreatex.in.create_options = 0;
1108         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1109         io.ntcreatex.in.security_flags = 0;
1110         io.ntcreatex.in.fname = fname;
1111
1112         torture_comment(tctx, "open with batch oplock\n");
1113         ZERO_STRUCT(break_info);
1114         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1115
1116         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1117                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1118                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1119         status = smb_raw_open(cli1->tree, tctx, &io);
1120         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1121         fnum = io.ntcreatex.out.file.fnum;
1122         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1123
1124         ZERO_STRUCT(break_info);
1125         torture_comment(tctx, "second open with attributes only shouldn't cause oplock break\n");
1126
1127         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1128                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1129                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1130         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1131         status = smb_raw_open(cli2->tree, tctx, &io);
1132         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1133         fnum2 = io.ntcreatex.out.file.fnum;
1134         CHECK_VAL(io.ntcreatex.out.oplock_level, NO_OPLOCK_RETURN);
1135         CHECK_VAL(break_info.count, 0);
1136         CHECK_VAL(break_info.failures, 0);
1137
1138         smbcli_close(cli1->tree, fnum);
1139         smbcli_close(cli2->tree, fnum2);
1140
1141 done:
1142         smb_raw_exit(cli1->session);
1143         smb_raw_exit(cli2->session);
1144         smbcli_deltree(cli1->tree, BASEDIR);
1145         return ret;
1146 }
1147
1148 static bool test_raw_oplock_batch9(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1149 {
1150         const char *fname = BASEDIR "\\test_batch9.dat";
1151         NTSTATUS status;
1152         bool ret = true;
1153         union smb_open io;
1154         uint16_t fnum=0, fnum2=0;
1155         char c = 0;
1156
1157         if (!torture_setup_dir(cli1, BASEDIR)) {
1158                 return false;
1159         }
1160
1161         /* cleanup */
1162         smbcli_unlink(cli1->tree, fname);
1163
1164         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1165
1166         /*
1167           base ntcreatex parms
1168         */
1169         io.generic.level = RAW_OPEN_NTCREATEX;
1170         io.ntcreatex.in.root_fid = 0;
1171         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1172         io.ntcreatex.in.alloc_size = 0;
1173         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1174         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1175         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1176         io.ntcreatex.in.create_options = 0;
1177         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1178         io.ntcreatex.in.security_flags = 0;
1179         io.ntcreatex.in.fname = fname;
1180
1181         torture_comment(tctx, "open with attributes only can create file\n");
1182
1183         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1184                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1185                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1186         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1187         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1188         status = smb_raw_open(cli1->tree, tctx, &io);
1189         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1190         fnum = io.ntcreatex.out.file.fnum;
1191         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1192
1193         torture_comment(tctx, "Subsequent normal open should break oplock on attribute only open to level II\n");
1194
1195         ZERO_STRUCT(break_info);
1196         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1197
1198         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1199                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1200                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1201         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1202         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1203         status = smb_raw_open(cli2->tree, tctx, &io);
1204         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1205         fnum2 = io.ntcreatex.out.file.fnum;
1206         CHECK_VAL(break_info.count, 1);
1207         CHECK_VAL(break_info.fnum, fnum);
1208         CHECK_VAL(break_info.failures, 0);
1209         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1210         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1211         smbcli_close(cli2->tree, fnum2);
1212
1213         torture_comment(tctx, "third oplocked open should grant level2 without break\n");
1214         ZERO_STRUCT(break_info);
1215         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1216         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1217         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1218                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1219                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1220         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1221         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1222         status = smb_raw_open(cli2->tree, tctx, &io);
1223         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1224         fnum2 = io.ntcreatex.out.file.fnum;
1225         CHECK_VAL(break_info.count, 0);
1226         CHECK_VAL(break_info.failures, 0);
1227         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1228
1229         ZERO_STRUCT(break_info);
1230
1231         torture_comment(tctx, "write should trigger a break to none on both\n");
1232         smbcli_write(cli2->tree, fnum2, 0, &c, 0, 1);
1233
1234         /* Now the oplock break request comes in. But right now we can't
1235          * answer it. Do another write */
1236
1237         msleep(100);
1238         smbcli_write(cli2->tree, fnum2, 0, &c, 1, 1);
1239
1240         CHECK_VAL(break_info.count, 2);
1241         CHECK_VAL(break_info.level, 0);
1242         CHECK_VAL(break_info.failures, 0);
1243
1244         smbcli_close(cli1->tree, fnum);
1245         smbcli_close(cli2->tree, fnum2);
1246
1247 done:
1248         smb_raw_exit(cli1->session);
1249         smb_raw_exit(cli2->session);
1250         smbcli_deltree(cli1->tree, BASEDIR);
1251         return ret;
1252 }
1253
1254 static bool test_raw_oplock_batch10(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1255 {
1256         const char *fname = BASEDIR "\\test_batch10.dat";
1257         NTSTATUS status;
1258         bool ret = true;
1259         union smb_open io;
1260         uint16_t fnum=0, fnum2=0;
1261
1262         if (!torture_setup_dir(cli1, BASEDIR)) {
1263                 return false;
1264         }
1265
1266         /* cleanup */
1267         smbcli_unlink(cli1->tree, fname);
1268
1269         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1270
1271         /*
1272           base ntcreatex parms
1273         */
1274         io.generic.level = RAW_OPEN_NTCREATEX;
1275         io.ntcreatex.in.root_fid = 0;
1276         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1277         io.ntcreatex.in.alloc_size = 0;
1278         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1279         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1280         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1281         io.ntcreatex.in.create_options = 0;
1282         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1283         io.ntcreatex.in.security_flags = 0;
1284         io.ntcreatex.in.fname = fname;
1285
1286         torture_comment(tctx, "Open with oplock after a non-oplock open should grant level2\n");
1287         ZERO_STRUCT(break_info);
1288         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1289         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1290         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1291                 NTCREATEX_SHARE_ACCESS_WRITE|
1292                 NTCREATEX_SHARE_ACCESS_DELETE;
1293         status = smb_raw_open(cli1->tree, tctx, &io);
1294         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1295         fnum = io.ntcreatex.out.file.fnum;
1296         CHECK_VAL(break_info.count, 0);
1297         CHECK_VAL(break_info.failures, 0);
1298         CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
1299
1300         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli2->tree);
1301
1302         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1303                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1304                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1305         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1306         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1307                 NTCREATEX_SHARE_ACCESS_WRITE|
1308                 NTCREATEX_SHARE_ACCESS_DELETE;
1309         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1310         status = smb_raw_open(cli2->tree, tctx, &io);
1311         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1312         fnum2 = io.ntcreatex.out.file.fnum;
1313         CHECK_VAL(break_info.count, 0);
1314         CHECK_VAL(break_info.failures, 0);
1315         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1316
1317         torture_comment(tctx, "write should trigger a break to none\n");
1318         {
1319                 union smb_write wr;
1320                 wr.write.level = RAW_WRITE_WRITE;
1321                 wr.write.in.file.fnum = fnum;
1322                 wr.write.in.count = 1;
1323                 wr.write.in.offset = 0;
1324                 wr.write.in.remaining = 0;
1325                 wr.write.in.data = (const uint8_t *)"x";
1326                 status = smb_raw_write(cli1->tree, &wr);
1327                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1328         }
1329
1330         /* Now the oplock break request comes in. But right now we can't
1331          * answer it. Do another write */
1332
1333         msleep(100);
1334         
1335         {
1336                 union smb_write wr;
1337                 wr.write.level = RAW_WRITE_WRITE;
1338                 wr.write.in.file.fnum = fnum;
1339                 wr.write.in.count = 1;
1340                 wr.write.in.offset = 0;
1341                 wr.write.in.remaining = 0;
1342                 wr.write.in.data = (const uint8_t *)"x";
1343                 status = smb_raw_write(cli1->tree, &wr);
1344                 CHECK_STATUS(tctx, status, NT_STATUS_OK);
1345         }
1346
1347         CHECK_VAL(break_info.count, 1);
1348         CHECK_VAL(break_info.fnum, fnum2);
1349         CHECK_VAL(break_info.level, 0);
1350         CHECK_VAL(break_info.failures, 0);
1351
1352         smbcli_close(cli1->tree, fnum);
1353         smbcli_close(cli2->tree, fnum2);
1354
1355 done:
1356         smb_raw_exit(cli1->session);
1357         smb_raw_exit(cli2->session);
1358         smbcli_deltree(cli1->tree, BASEDIR);
1359         return ret;
1360 }
1361
1362 static bool test_raw_oplock_batch11(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1363 {
1364         const char *fname = BASEDIR "\\test_batch11.dat";
1365         NTSTATUS status;
1366         bool ret = true;
1367         union smb_open io;
1368         union smb_setfileinfo sfi;
1369         uint16_t fnum=0;
1370
1371         if (!torture_setup_dir(cli1, BASEDIR)) {
1372                 return false;
1373         }
1374
1375         /* cleanup */
1376         smbcli_unlink(cli1->tree, fname);
1377
1378         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1379
1380         /*
1381           base ntcreatex parms
1382         */
1383         io.generic.level = RAW_OPEN_NTCREATEX;
1384         io.ntcreatex.in.root_fid = 0;
1385         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1386         io.ntcreatex.in.alloc_size = 0;
1387         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1388         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1389         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1390         io.ntcreatex.in.create_options = 0;
1391         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1392         io.ntcreatex.in.security_flags = 0;
1393         io.ntcreatex.in.fname = fname;
1394
1395         /* Test if a set-eof on pathname breaks an exclusive oplock. */
1396         torture_comment(tctx, "Test if setpathinfo set EOF breaks oplocks.\n");
1397
1398         ZERO_STRUCT(break_info);
1399         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1400
1401         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1402                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1403                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1404         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1405         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1406                 NTCREATEX_SHARE_ACCESS_WRITE|
1407                 NTCREATEX_SHARE_ACCESS_DELETE;
1408         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1409         status = smb_raw_open(cli1->tree, tctx, &io);
1410         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1411         fnum = io.ntcreatex.out.file.fnum;
1412         CHECK_VAL(break_info.count, 0);
1413         CHECK_VAL(break_info.failures, 0);
1414         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1415         
1416         ZERO_STRUCT(sfi);
1417         sfi.generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1418         sfi.generic.in.file.path = fname;
1419         sfi.end_of_file_info.in.size = 100;
1420
1421         status = smb_raw_setpathinfo(cli2->tree, &sfi);
1422
1423         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1424         CHECK_VAL(break_info.count, 1);
1425         CHECK_VAL(break_info.failures, 0);
1426         CHECK_VAL(break_info.level, 0);
1427
1428         smbcli_close(cli1->tree, fnum);
1429
1430 done:
1431         smb_raw_exit(cli1->session);
1432         smb_raw_exit(cli2->session);
1433         smbcli_deltree(cli1->tree, BASEDIR);
1434         return ret;
1435 }
1436
1437 static bool test_raw_oplock_batch12(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1438 {
1439         const char *fname = BASEDIR "\\test_batch12.dat";
1440         NTSTATUS status;
1441         bool ret = true;
1442         union smb_open io;
1443         union smb_setfileinfo sfi;
1444         uint16_t fnum=0;
1445
1446         if (!torture_setup_dir(cli1, BASEDIR)) {
1447                 return false;
1448         }
1449
1450         /* cleanup */
1451         smbcli_unlink(cli1->tree, fname);
1452
1453         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1454
1455         /*
1456           base ntcreatex parms
1457         */
1458         io.generic.level = RAW_OPEN_NTCREATEX;
1459         io.ntcreatex.in.root_fid = 0;
1460         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1461         io.ntcreatex.in.alloc_size = 0;
1462         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1463         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1464         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1465         io.ntcreatex.in.create_options = 0;
1466         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1467         io.ntcreatex.in.security_flags = 0;
1468         io.ntcreatex.in.fname = fname;
1469
1470         /* Test if a set-allocation size on pathname breaks an exclusive oplock. */
1471         torture_comment(tctx, "Test if setpathinfo allocation size breaks oplocks.\n");
1472
1473         ZERO_STRUCT(break_info);
1474         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1475
1476         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1477                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1478                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1479         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1480         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1481                 NTCREATEX_SHARE_ACCESS_WRITE|
1482                 NTCREATEX_SHARE_ACCESS_DELETE;
1483         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1484         status = smb_raw_open(cli1->tree, tctx, &io);
1485         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1486         fnum = io.ntcreatex.out.file.fnum;
1487         CHECK_VAL(break_info.count, 0);
1488         CHECK_VAL(break_info.failures, 0);
1489         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1490         
1491         ZERO_STRUCT(sfi);
1492         sfi.generic.level = SMB_SFILEINFO_ALLOCATION_INFORMATION;
1493         sfi.generic.in.file.path = fname;
1494         sfi.allocation_info.in.alloc_size = 65536 * 8;
1495
1496         status = smb_raw_setpathinfo(cli2->tree, &sfi);
1497
1498         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1499         CHECK_VAL(break_info.count, 1);
1500         CHECK_VAL(break_info.failures, 0);
1501         CHECK_VAL(break_info.level, 0);
1502
1503         smbcli_close(cli1->tree, fnum);
1504
1505 done:
1506         smb_raw_exit(cli1->session);
1507         smb_raw_exit(cli2->session);
1508         smbcli_deltree(cli1->tree, BASEDIR);
1509         return ret;
1510 }
1511
1512 static bool test_raw_oplock_batch13(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1513 {
1514         const char *fname = BASEDIR "\\test_batch13.dat";
1515         NTSTATUS status;
1516         bool ret = true;
1517         union smb_open io;
1518         uint16_t fnum=0, fnum2=0;
1519
1520         if (!torture_setup_dir(cli1, BASEDIR)) {
1521                 return false;
1522         }
1523
1524         /* cleanup */
1525         smbcli_unlink(cli1->tree, fname);
1526
1527         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1528         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1529
1530         /*
1531           base ntcreatex parms
1532         */
1533         io.generic.level = RAW_OPEN_NTCREATEX;
1534         io.ntcreatex.in.root_fid = 0;
1535         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1536         io.ntcreatex.in.alloc_size = 0;
1537         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1538         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1539         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1540         io.ntcreatex.in.create_options = 0;
1541         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1542         io.ntcreatex.in.security_flags = 0;
1543         io.ntcreatex.in.fname = fname;
1544
1545         torture_comment(tctx, "open with batch oplock\n");
1546         ZERO_STRUCT(break_info);
1547         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1548
1549
1550         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1551                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1552                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1553         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1554                 NTCREATEX_SHARE_ACCESS_WRITE|
1555                 NTCREATEX_SHARE_ACCESS_DELETE;
1556         status = smb_raw_open(cli1->tree, tctx, &io);
1557         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1558         fnum = io.ntcreatex.out.file.fnum;
1559         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1560
1561         ZERO_STRUCT(break_info);
1562
1563         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break\n");
1564
1565         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1566                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1567                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1568         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1569         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1570                 NTCREATEX_SHARE_ACCESS_WRITE|
1571                 NTCREATEX_SHARE_ACCESS_DELETE;
1572         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1573         status = smb_raw_open(cli2->tree, tctx, &io);
1574         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1575         fnum2 = io.ntcreatex.out.file.fnum;
1576         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1577         CHECK_VAL(break_info.count, 1);
1578         CHECK_VAL(break_info.failures, 0);
1579
1580         smbcli_close(cli1->tree, fnum);
1581         smbcli_close(cli2->tree, fnum2);
1582
1583 done:
1584         smb_raw_exit(cli1->session);
1585         smb_raw_exit(cli2->session);
1586         smbcli_deltree(cli1->tree, BASEDIR);
1587         return ret;
1588 }
1589
1590 static bool test_raw_oplock_batch14(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1591 {
1592         const char *fname = BASEDIR "\\test_batch14.dat";
1593         NTSTATUS status;
1594         bool ret = true;
1595         union smb_open io;
1596         uint16_t fnum=0, fnum2=0;
1597
1598         if (!torture_setup_dir(cli1, BASEDIR)) {
1599                 return false;
1600         }
1601
1602         /* cleanup */
1603         smbcli_unlink(cli1->tree, fname);
1604
1605         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1606
1607         /*
1608           base ntcreatex parms
1609         */
1610         io.generic.level = RAW_OPEN_NTCREATEX;
1611         io.ntcreatex.in.root_fid = 0;
1612         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1613         io.ntcreatex.in.alloc_size = 0;
1614         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1615         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1616         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1617         io.ntcreatex.in.create_options = 0;
1618         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1619         io.ntcreatex.in.security_flags = 0;
1620         io.ntcreatex.in.fname = fname;
1621
1622         torture_comment(tctx, "open with batch oplock\n");
1623         ZERO_STRUCT(break_info);
1624         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1625
1626         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1627                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1628                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1629         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1630                 NTCREATEX_SHARE_ACCESS_WRITE|
1631                 NTCREATEX_SHARE_ACCESS_DELETE;
1632         status = smb_raw_open(cli1->tree, tctx, &io);
1633         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1634         fnum = io.ntcreatex.out.file.fnum;
1635         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1636
1637         ZERO_STRUCT(break_info);
1638
1639         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break\n");
1640
1641         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
1642                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
1643                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1644         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1645         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1646                 NTCREATEX_SHARE_ACCESS_WRITE|
1647                 NTCREATEX_SHARE_ACCESS_DELETE;
1648         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
1649         status = smb_raw_open(cli2->tree, tctx, &io);
1650         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1651         fnum2 = io.ntcreatex.out.file.fnum;
1652         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1653         CHECK_VAL(break_info.count, 1);
1654         CHECK_VAL(break_info.failures, 0);
1655
1656         smbcli_close(cli1->tree, fnum);
1657         smbcli_close(cli2->tree, fnum2);
1658 done:
1659         smb_raw_exit(cli1->session);
1660         smb_raw_exit(cli2->session);
1661         smbcli_deltree(cli1->tree, BASEDIR);
1662         return ret;
1663 }
1664
1665 static bool test_raw_oplock_batch15(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1666 {
1667         const char *fname = BASEDIR "\\test_batch15.dat";
1668         NTSTATUS status;
1669         bool ret = true;
1670         union smb_open io;
1671         union smb_fileinfo qfi;
1672         uint16_t fnum=0;
1673
1674         if (!torture_setup_dir(cli1, BASEDIR)) {
1675                 return false;
1676         }
1677
1678         /* cleanup */
1679         smbcli_unlink(cli1->tree, fname);
1680
1681         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1682
1683         /*
1684           base ntcreatex parms
1685         */
1686         io.generic.level = RAW_OPEN_NTCREATEX;
1687         io.ntcreatex.in.root_fid = 0;
1688         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1689         io.ntcreatex.in.alloc_size = 0;
1690         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1691         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1692         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1693         io.ntcreatex.in.create_options = 0;
1694         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1695         io.ntcreatex.in.security_flags = 0;
1696         io.ntcreatex.in.fname = fname;
1697
1698         /* Test if a qpathinfo all info on pathname breaks a batch oplock. */
1699         torture_comment(tctx, "Test if qpathinfo all info breaks a batch oplock (should not).\n");
1700
1701         ZERO_STRUCT(break_info);
1702         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1703
1704         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1705                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1706                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1707         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1708         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1709                 NTCREATEX_SHARE_ACCESS_WRITE|
1710                 NTCREATEX_SHARE_ACCESS_DELETE;
1711         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1712         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1713         status = smb_raw_open(cli1->tree, tctx, &io);
1714         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1715         fnum = io.ntcreatex.out.file.fnum;
1716         CHECK_VAL(break_info.count, 0);
1717         CHECK_VAL(break_info.failures, 0);
1718         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1719
1720         ZERO_STRUCT(qfi);
1721         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
1722         qfi.generic.in.file.path = fname;
1723
1724         status = smb_raw_pathinfo(cli2->tree, tctx, &qfi);
1725
1726         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1727         CHECK_VAL(break_info.count, 0);
1728
1729         smbcli_close(cli1->tree, fnum);
1730
1731 done:
1732         smb_raw_exit(cli1->session);
1733         smb_raw_exit(cli2->session);
1734         smbcli_deltree(cli1->tree, BASEDIR);
1735         return ret;
1736 }
1737
1738 static bool test_raw_oplock_batch16(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1739 {
1740         const char *fname = BASEDIR "\\test_batch16.dat";
1741         NTSTATUS status;
1742         bool ret = true;
1743         union smb_open io;
1744         uint16_t fnum=0, fnum2=0;
1745
1746         if (!torture_setup_dir(cli1, BASEDIR)) {
1747                 return false;
1748         }
1749
1750         /* cleanup */
1751         smbcli_unlink(cli1->tree, fname);
1752
1753         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1754         smbcli_oplock_handler(cli2->transport, oplock_handler_ack_to_levelII, cli1->tree);
1755
1756         /*
1757           base ntcreatex parms
1758         */
1759         io.generic.level = RAW_OPEN_NTCREATEX;
1760         io.ntcreatex.in.root_fid = 0;
1761         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1762         io.ntcreatex.in.alloc_size = 0;
1763         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1764         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1765         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1766         io.ntcreatex.in.create_options = 0;
1767         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1768         io.ntcreatex.in.security_flags = 0;
1769         io.ntcreatex.in.fname = fname;
1770
1771         torture_comment(tctx, "open with batch oplock\n");
1772         ZERO_STRUCT(break_info);
1773         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1774
1775
1776         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1777                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1778                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1779         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1780                 NTCREATEX_SHARE_ACCESS_WRITE|
1781                 NTCREATEX_SHARE_ACCESS_DELETE;
1782         status = smb_raw_open(cli1->tree, tctx, &io);
1783         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1784         fnum = io.ntcreatex.out.file.fnum;
1785         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1786
1787         ZERO_STRUCT(break_info);
1788
1789         torture_comment(tctx, "second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break\n");
1790
1791         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1792                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1793                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1794         io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE|SEC_STD_SYNCHRONIZE;
1795         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1796                 NTCREATEX_SHARE_ACCESS_WRITE|
1797                 NTCREATEX_SHARE_ACCESS_DELETE;
1798         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
1799         status = smb_raw_open(cli2->tree, tctx, &io);
1800         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1801         fnum2 = io.ntcreatex.out.file.fnum;
1802         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
1803         CHECK_VAL(break_info.count, 1);
1804         CHECK_VAL(break_info.failures, 0);
1805
1806         smbcli_close(cli1->tree, fnum);
1807         smbcli_close(cli2->tree, fnum2);
1808
1809 done:
1810         smb_raw_exit(cli1->session);
1811         smb_raw_exit(cli2->session);
1812         smbcli_deltree(cli1->tree, BASEDIR);
1813         return ret;
1814 }
1815
1816 static bool test_raw_oplock_batch17(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1817 {
1818         const char *fname1 = BASEDIR "\\test_batch17_1.dat";
1819         const char *fname2 = BASEDIR "\\test_batch17_2.dat";
1820         NTSTATUS status;
1821         bool ret = true;
1822         union smb_open io;
1823         union smb_rename rn;
1824         uint16_t fnum=0;
1825         bool s3 = torture_setting_bool(tctx, "samba3", false);
1826
1827         if (!torture_setup_dir(cli1, BASEDIR)) {
1828                 return false;
1829         }
1830
1831         /* cleanup */
1832         smbcli_unlink(cli1->tree, fname1);
1833         smbcli_unlink(cli1->tree, fname2);
1834
1835         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1836
1837         /*
1838           base ntcreatex parms
1839         */
1840         io.generic.level = RAW_OPEN_NTCREATEX;
1841         io.ntcreatex.in.root_fid = 0;
1842         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1843         io.ntcreatex.in.alloc_size = 0;
1844         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1845         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1846         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1847         io.ntcreatex.in.create_options = 0;
1848         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1849         io.ntcreatex.in.security_flags = 0;
1850         io.ntcreatex.in.fname = fname1;
1851
1852         /* we should use no share mode, when samba3 passes this */
1853         torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1854                         s3?"all":"none");
1855         ZERO_STRUCT(break_info);
1856         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1857                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1858                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1859         if (s3) {
1860                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1861                         NTCREATEX_SHARE_ACCESS_WRITE|
1862                         NTCREATEX_SHARE_ACCESS_DELETE;
1863         }
1864
1865         status = smb_raw_open(cli1->tree, tctx, &io);
1866         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1867         fnum = io.ntcreatex.out.file.fnum;
1868         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1869
1870         torture_comment(tctx, "rename should trigger a break\n");
1871         ZERO_STRUCT(rn);
1872         rn.generic.level = RAW_RENAME_RENAME;
1873         rn.rename.in.pattern1 = fname1;
1874         rn.rename.in.pattern2 = fname2;
1875         rn.rename.in.attrib = 0;
1876
1877         printf("trying rename while first file open\n");
1878         status = smb_raw_rename(cli2->tree, &rn);
1879
1880         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1881         CHECK_VAL(break_info.count, 1);
1882         CHECK_VAL(break_info.failures, 0);
1883         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1884
1885         smbcli_close(cli1->tree, fnum);
1886
1887 done:
1888         smb_raw_exit(cli1->session);
1889         smb_raw_exit(cli2->session);
1890         smbcli_deltree(cli1->tree, BASEDIR);
1891         return ret;
1892 }
1893
1894 static bool test_raw_oplock_batch18(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1895 {
1896         const char *fname1 = BASEDIR "\\test_batch18_1.dat";
1897         const char *fname2 = BASEDIR "\\test_batch18_2.dat";
1898         NTSTATUS status;
1899         bool ret = true;
1900         union smb_open io;
1901         union smb_rename rn;
1902         uint16_t fnum=0;
1903         bool s3 = torture_setting_bool(tctx, "samba3", false);
1904
1905         if (!torture_setup_dir(cli1, BASEDIR)) {
1906                 return false;
1907         }
1908
1909         /* cleanup */
1910         smbcli_unlink(cli1->tree, fname1);
1911         smbcli_unlink(cli1->tree, fname2);
1912
1913         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1914
1915         /*
1916           base ntcreatex parms
1917         */
1918         io.generic.level = RAW_OPEN_NTCREATEX;
1919         io.ntcreatex.in.root_fid = 0;
1920         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1921         io.ntcreatex.in.alloc_size = 0;
1922         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1923         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1924         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1925         io.ntcreatex.in.create_options = 0;
1926         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1927         io.ntcreatex.in.security_flags = 0;
1928         io.ntcreatex.in.fname = fname1;
1929
1930         /* we should use no share mode, when samba3 passes this */
1931         torture_comment(tctx, "open a file with an batch oplock (share mode: %s)\n",
1932                         s3?"all":"none");
1933         ZERO_STRUCT(break_info);
1934         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
1935                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
1936                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1937         if (s3) {
1938                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1939                         NTCREATEX_SHARE_ACCESS_WRITE|
1940                         NTCREATEX_SHARE_ACCESS_DELETE;
1941         }
1942
1943         status = smb_raw_open(cli1->tree, tctx, &io);
1944         CHECK_STATUS(tctx, status, NT_STATUS_OK);
1945         fnum = io.ntcreatex.out.file.fnum;
1946         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
1947
1948         torture_comment(tctx, "ntrename should trigger a break\n");
1949         ZERO_STRUCT(rn);
1950         rn.generic.level = RAW_RENAME_NTRENAME;
1951         rn.ntrename.in.attrib   = 0;
1952         rn.ntrename.in.flags    = RENAME_FLAG_RENAME;
1953         rn.ntrename.in.old_name = fname1;
1954         rn.ntrename.in.new_name = fname2;
1955         printf("trying rename while first file open\n");
1956         status = smb_raw_rename(cli2->tree, &rn);
1957
1958         CHECK_STATUS(tctx, status, NT_STATUS_SHARING_VIOLATION);
1959         CHECK_VAL(break_info.count, 1);
1960         CHECK_VAL(break_info.failures, 0);
1961         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
1962
1963         smbcli_close(cli1->tree, fnum);
1964
1965 done:
1966         smb_raw_exit(cli1->session);
1967         smb_raw_exit(cli2->session);
1968         smbcli_deltree(cli1->tree, BASEDIR);
1969         return ret;
1970 }
1971
1972 static bool test_raw_oplock_batch19(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
1973 {
1974         const char *fname1 = BASEDIR "\\test_batch19_1.dat";
1975         const char *fname2 = BASEDIR "\\test_batch19_2.dat";
1976         const char *fname3 = BASEDIR "\\test_batch19_3.dat";
1977         NTSTATUS status;
1978         bool ret = true;
1979         union smb_open io;
1980         union smb_fileinfo qfi;
1981         union smb_setfileinfo sfi;
1982         uint16_t fnum=0;
1983
1984         if (torture_setting_bool(tctx, "samba3", false)) {
1985                 torture_skip(tctx, "BACHT19 disabled against samba3\n");
1986         }
1987
1988         if (!torture_setup_dir(cli1, BASEDIR)) {
1989                 return false;
1990         }
1991
1992         /* cleanup */
1993         smbcli_unlink(cli1->tree, fname1);
1994         smbcli_unlink(cli1->tree, fname2);
1995         smbcli_unlink(cli1->tree, fname3);
1996
1997         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
1998
1999         /*
2000           base ntcreatex parms
2001         */
2002         io.generic.level = RAW_OPEN_NTCREATEX;
2003         io.ntcreatex.in.root_fid = 0;
2004         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2005         io.ntcreatex.in.alloc_size = 0;
2006         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2007         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2008         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2009         io.ntcreatex.in.create_options = 0;
2010         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2011         io.ntcreatex.in.security_flags = 0;
2012         io.ntcreatex.in.fname = fname1;
2013
2014         torture_comment(tctx, "open a file with an batch oplock (share mode: none)\n");
2015         ZERO_STRUCT(break_info);
2016         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2017                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2018                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2019         status = smb_raw_open(cli1->tree, tctx, &io);
2020         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2021         fnum = io.ntcreatex.out.file.fnum;
2022         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2023
2024         torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2025         ZERO_STRUCT(sfi);
2026         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2027         sfi.generic.in.file.path = fname1;
2028         sfi.rename_information.in.overwrite     = 0;
2029         sfi.rename_information.in.root_fid      = 0;
2030         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
2031
2032         status = smb_raw_setpathinfo(cli2->tree, &sfi);
2033
2034         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2035         CHECK_VAL(break_info.count, 0);
2036
2037         ZERO_STRUCT(qfi);
2038         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2039         qfi.generic.in.file.fnum = fnum;
2040
2041         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2042         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2043         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2044
2045         torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2046         ZERO_STRUCT(sfi);
2047         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2048         sfi.generic.in.file.fnum = fnum;
2049         sfi.rename_information.in.overwrite     = 0;
2050         sfi.rename_information.in.root_fid      = 0;
2051         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
2052
2053         status = smb_raw_setfileinfo(cli1->tree, &sfi);
2054         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2055         CHECK_VAL(break_info.count, 0);
2056
2057         ZERO_STRUCT(qfi);
2058         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2059         qfi.generic.in.file.fnum = fnum;
2060
2061         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2062         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2063         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2064
2065         smbcli_close(cli1->tree, fnum);
2066
2067 done:
2068         smb_raw_exit(cli1->session);
2069         smb_raw_exit(cli2->session);
2070         smbcli_deltree(cli1->tree, BASEDIR);
2071         return ret;
2072 }
2073
2074 static bool test_raw_oplock_batch20(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2)
2075 {
2076         const char *fname1 = BASEDIR "\\test_batch20_1.dat";
2077         const char *fname2 = BASEDIR "\\test_batch20_2.dat";
2078         const char *fname3 = BASEDIR "\\test_batch20_3.dat";
2079         NTSTATUS status;
2080         bool ret = true;
2081         union smb_open io;
2082         union smb_fileinfo qfi;
2083         union smb_setfileinfo sfi;
2084         uint16_t fnum=0,fnum2=0;
2085
2086         if (torture_setting_bool(tctx, "samba3", false)) {
2087                 torture_skip(tctx, "BACHT20 disabled against samba3\n");
2088         }
2089
2090         if (!torture_setup_dir(cli1, BASEDIR)) {
2091                 return false;
2092         }
2093
2094         /* cleanup */
2095         smbcli_unlink(cli1->tree, fname1);
2096         smbcli_unlink(cli1->tree, fname2);
2097         smbcli_unlink(cli1->tree, fname3);
2098
2099         smbcli_oplock_handler(cli1->transport, oplock_handler_ack_to_levelII, cli1->tree);
2100
2101         /*
2102           base ntcreatex parms
2103         */
2104         io.generic.level = RAW_OPEN_NTCREATEX;
2105         io.ntcreatex.in.root_fid = 0;
2106         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2107         io.ntcreatex.in.alloc_size = 0;
2108         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2109         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2110         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2111         io.ntcreatex.in.create_options = 0;
2112         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2113         io.ntcreatex.in.security_flags = 0;
2114         io.ntcreatex.in.fname = fname1;
2115
2116         torture_comment(tctx, "open a file with an batch oplock (share mode: all)\n");
2117         ZERO_STRUCT(break_info);
2118         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2119                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2120                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2121         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2122                 NTCREATEX_SHARE_ACCESS_WRITE|
2123                 NTCREATEX_SHARE_ACCESS_DELETE;
2124         status = smb_raw_open(cli1->tree, tctx, &io);
2125         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2126         fnum = io.ntcreatex.out.file.fnum;
2127         CHECK_VAL(io.ntcreatex.out.oplock_level, BATCH_OPLOCK_RETURN);
2128
2129         torture_comment(tctx, "setpathinfo rename info should not trigger a break nor a violation\n");
2130         ZERO_STRUCT(sfi);
2131         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2132         sfi.generic.in.file.path = fname1;
2133         sfi.rename_information.in.overwrite     = 0;
2134         sfi.rename_information.in.root_fid      = 0;
2135         sfi.rename_information.in.new_name      = fname2+strlen(BASEDIR)+1;
2136
2137         status = smb_raw_setpathinfo(cli2->tree, &sfi);
2138
2139         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2140         CHECK_VAL(break_info.count, 0);
2141
2142         ZERO_STRUCT(qfi);
2143         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2144         qfi.generic.in.file.fnum = fnum;
2145
2146         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2147         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2148         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname2);
2149
2150         /* we should use no share mode, when samba3 passes this */
2151         torture_comment(tctx, "open a file with the new name an batch oplock (share mode: all)\n");
2152         ZERO_STRUCT(break_info);
2153         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED |
2154                 NTCREATEX_FLAGS_REQUEST_OPLOCK |
2155                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2156         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
2157                 NTCREATEX_SHARE_ACCESS_WRITE|
2158                 NTCREATEX_SHARE_ACCESS_DELETE;
2159         io.ntcreatex.in.fname = fname2;
2160         status = smb_raw_open(cli2->tree, tctx, &io);
2161         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2162         fnum2 = io.ntcreatex.out.file.fnum;
2163         CHECK_VAL(io.ntcreatex.out.oplock_level, LEVEL_II_OPLOCK_RETURN);
2164         CHECK_VAL(break_info.count, 1);
2165         CHECK_VAL(break_info.failures, 0);
2166         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2167
2168         torture_comment(tctx, "setfileinfo rename info should not trigger a break nor a violation\n");
2169         ZERO_STRUCT(sfi);
2170         sfi.generic.level = RAW_SFILEINFO_RENAME_INFORMATION;
2171         sfi.generic.in.file.fnum = fnum;
2172         sfi.rename_information.in.overwrite     = 0;
2173         sfi.rename_information.in.root_fid      = 0;
2174         sfi.rename_information.in.new_name      = fname3+strlen(BASEDIR)+1;
2175
2176         status = smb_raw_setfileinfo(cli1->tree, &sfi);
2177         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2178         CHECK_VAL(break_info.count, 1);
2179         CHECK_VAL(break_info.failures, 0);
2180         CHECK_VAL(break_info.level, OPLOCK_BREAK_TO_LEVEL_II);
2181
2182         ZERO_STRUCT(qfi);
2183         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2184         qfi.generic.in.file.fnum = fnum;
2185
2186         status = smb_raw_fileinfo(cli1->tree, tctx, &qfi);
2187         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2188         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2189
2190         ZERO_STRUCT(qfi);
2191         qfi.generic.level = RAW_FILEINFO_ALL_INFORMATION;
2192         qfi.generic.in.file.fnum = fnum2;
2193
2194         status = smb_raw_fileinfo(cli2->tree, tctx, &qfi);
2195         CHECK_STATUS(tctx, status, NT_STATUS_OK);
2196         CHECK_STRMATCH(qfi.all_info.out.fname.s, fname3);
2197
2198         smbcli_close(cli1->tree, fnum);
2199
2200 done:
2201         smb_raw_exit(cli1->session);
2202         smb_raw_exit(cli2->session);
2203         smbcli_deltree(cli1->tree, BASEDIR);
2204         return ret;
2205 }
2206
2207 /* 
2208    basic testing of oplocks
2209 */
2210 struct torture_suite *torture_raw_oplock(TALLOC_CTX *mem_ctx)
2211 {
2212         struct torture_suite *suite = torture_suite_create(mem_ctx, "OPLOCK");
2213
2214         torture_suite_add_2smb_test(suite, "EXCLUSIVE1", test_raw_oplock_exclusive1);
2215         torture_suite_add_2smb_test(suite, "EXCLUSIVE2", test_raw_oplock_exclusive2);
2216         torture_suite_add_2smb_test(suite, "EXCLUSIVE3", test_raw_oplock_exclusive3);
2217         torture_suite_add_2smb_test(suite, "EXCLUSIVE4", test_raw_oplock_exclusive4);
2218         torture_suite_add_2smb_test(suite, "EXCLUSIVE5", test_raw_oplock_exclusive5);
2219         torture_suite_add_2smb_test(suite, "EXCLUSIVE6", test_raw_oplock_exclusive6);
2220         torture_suite_add_2smb_test(suite, "BATCH1", test_raw_oplock_batch1);
2221         torture_suite_add_2smb_test(suite, "BATCH2", test_raw_oplock_batch2);
2222         torture_suite_add_2smb_test(suite, "BATCH3", test_raw_oplock_batch3);
2223         torture_suite_add_2smb_test(suite, "BATCH4", test_raw_oplock_batch4);
2224         torture_suite_add_2smb_test(suite, "BATCH5", test_raw_oplock_batch5);
2225         torture_suite_add_2smb_test(suite, "BATCH6", test_raw_oplock_batch6);
2226         torture_suite_add_2smb_test(suite, "BATCH7", test_raw_oplock_batch7);
2227         torture_suite_add_2smb_test(suite, "BATCH8", test_raw_oplock_batch8);
2228         torture_suite_add_2smb_test(suite, "BATCH9", test_raw_oplock_batch9);
2229         torture_suite_add_2smb_test(suite, "BATCH10", test_raw_oplock_batch10);
2230         torture_suite_add_2smb_test(suite, "BATCH11", test_raw_oplock_batch11);
2231         torture_suite_add_2smb_test(suite, "BATCH12", test_raw_oplock_batch12);
2232         torture_suite_add_2smb_test(suite, "BATCH13", test_raw_oplock_batch13);
2233         torture_suite_add_2smb_test(suite, "BATCH14", test_raw_oplock_batch14);
2234         torture_suite_add_2smb_test(suite, "BATCH15", test_raw_oplock_batch15);
2235         torture_suite_add_2smb_test(suite, "BATCH16", test_raw_oplock_batch16);
2236         torture_suite_add_2smb_test(suite, "BATCH17", test_raw_oplock_batch17);
2237         torture_suite_add_2smb_test(suite, "BATCH18", test_raw_oplock_batch18);
2238         torture_suite_add_2smb_test(suite, "BATCH19", test_raw_oplock_batch19);
2239         torture_suite_add_2smb_test(suite, "BATCH20", test_raw_oplock_batch20);
2240
2241         return suite;
2242 }
2243
2244 /* 
2245    stress testing of oplocks
2246 */
2247 bool torture_bench_oplock(struct torture_context *torture)
2248 {
2249         struct smbcli_state **cli;
2250         bool ret = true;
2251         TALLOC_CTX *mem_ctx = talloc_new(torture);
2252         int torture_nprocs = torture_setting_int(torture, "nprocs", 4);
2253         int i, count=0;
2254         int timelimit = torture_setting_int(torture, "timelimit", 10);
2255         union smb_open io;
2256         struct timeval tv;
2257         struct event_context *ev = event_context_find(mem_ctx);
2258
2259         cli = talloc_array(mem_ctx, struct smbcli_state *, torture_nprocs);
2260
2261         torture_comment(torture, "Opening %d connections\n", torture_nprocs);
2262         for (i=0;i<torture_nprocs;i++) {
2263                 if (!torture_open_connection_ev(&cli[i], i, torture, ev)) {
2264                         return false;
2265                 }
2266                 talloc_steal(mem_ctx, cli[i]);
2267                 smbcli_oplock_handler(cli[i]->transport, oplock_handler_close, 
2268                                       cli[i]->tree);
2269         }
2270
2271         if (!torture_setup_dir(cli[0], BASEDIR)) {
2272                 ret = false;
2273                 goto done;
2274         }
2275
2276         io.ntcreatex.level = RAW_OPEN_NTCREATEX;
2277         io.ntcreatex.in.root_fid = 0;
2278         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2279         io.ntcreatex.in.alloc_size = 0;
2280         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2281         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
2282         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2283         io.ntcreatex.in.create_options = 0;
2284         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2285         io.ntcreatex.in.security_flags = 0;
2286         io.ntcreatex.in.fname = BASEDIR "\\test.dat";
2287         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
2288                 NTCREATEX_FLAGS_REQUEST_OPLOCK | 
2289                 NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2290
2291         tv = timeval_current(); 
2292
2293         /*
2294           we open the same file with SHARE_ACCESS_NONE from all the
2295           connections in a round robin fashion. Each open causes an
2296           oplock break on the previous connection, which is answered
2297           by the oplock_handler_close() to close the file.
2298
2299           This measures how fast we can pass on oplocks, and stresses
2300           the oplock handling code
2301         */
2302         torture_comment(torture, "Running for %d seconds\n", timelimit);
2303         while (timeval_elapsed(&tv) < timelimit) {
2304                 for (i=0;i<torture_nprocs;i++) {
2305                         NTSTATUS status;
2306
2307                         status = smb_raw_open(cli[i]->tree, mem_ctx, &io);
2308                         CHECK_STATUS(torture, status, NT_STATUS_OK);
2309                         count++;
2310                 }
2311
2312                 if (torture_setting_bool(torture, "progress", true)) {
2313                         torture_comment(torture, "%.2f ops/second\r", count/timeval_elapsed(&tv));
2314                 }
2315         }
2316
2317         torture_comment(torture, "%.2f ops/second\n", count/timeval_elapsed(&tv));
2318
2319         smb_raw_exit(cli[torture_nprocs-1]->session);
2320         
2321 done:
2322         smb_raw_exit(cli[0]->session);
2323         smbcli_deltree(cli[0]->tree, BASEDIR);
2324         talloc_free(mem_ctx);
2325         return ret;
2326 }
2327
2328
2329 static struct hold_oplock_info {
2330         const char *fname;
2331         bool close_on_break;
2332         uint32_t share_access;
2333         uint16_t fnum;
2334 } hold_info[] = {
2335         { BASEDIR "\\notshared_close", true,  
2336           NTCREATEX_SHARE_ACCESS_NONE, },
2337         { BASEDIR "\\notshared_noclose", false, 
2338           NTCREATEX_SHARE_ACCESS_NONE, },
2339         { BASEDIR "\\shared_close", true,  
2340           NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2341         { BASEDIR "\\shared_noclose", false,  
2342           NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, },
2343 };
2344
2345 static bool oplock_handler_hold(struct smbcli_transport *transport, 
2346                                 uint16_t tid, uint16_t fnum, uint8_t level, 
2347                                 void *private)
2348 {
2349         struct smbcli_tree *tree = (struct smbcli_tree *)private;
2350         struct hold_oplock_info *info;
2351         int i;
2352
2353         for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2354                 if (hold_info[i].fnum == fnum) break;
2355         }
2356
2357         if (i == ARRAY_SIZE(hold_info)) {
2358                 printf("oplock break for unknown fnum %u\n", fnum);
2359                 return false;
2360         }
2361
2362         info = &hold_info[i];
2363
2364         if (info->close_on_break) {
2365                 printf("oplock break on %s - closing\n",
2366                        info->fname);
2367                 oplock_handler_close(transport, tid, fnum, level, private);
2368                 return true;
2369         }
2370
2371         printf("oplock break on %s - acking break\n", info->fname);
2372
2373         return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);
2374 }
2375
2376
2377 /* 
2378    used for manual testing of oplocks - especially interaction with
2379    other filesystems (such as NFS and local access)
2380 */
2381 bool torture_hold_oplock(struct torture_context *torture, 
2382                          struct smbcli_state *cli)
2383 {
2384         struct event_context *ev = 
2385                 (struct event_context *)cli->transport->socket->event.ctx;
2386         int i;
2387
2388         printf("Setting up open files with oplocks in %s\n", BASEDIR);
2389
2390         if (!torture_setup_dir(cli, BASEDIR)) {
2391                 return false;
2392         }
2393
2394         smbcli_oplock_handler(cli->transport, oplock_handler_hold, cli->tree);
2395
2396         /* setup the files */
2397         for (i=0;i<ARRAY_SIZE(hold_info);i++) {
2398                 union smb_open io;
2399                 NTSTATUS status;
2400                 char c = 1;
2401
2402                 io.generic.level = RAW_OPEN_NTCREATEX;
2403                 io.ntcreatex.in.root_fid = 0;
2404                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
2405                 io.ntcreatex.in.alloc_size = 0;
2406                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
2407                 io.ntcreatex.in.share_access = hold_info[i].share_access;
2408                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
2409                 io.ntcreatex.in.create_options = 0;
2410                 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
2411                 io.ntcreatex.in.security_flags = 0;
2412                 io.ntcreatex.in.fname = hold_info[i].fname;
2413                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED | 
2414                         NTCREATEX_FLAGS_REQUEST_OPLOCK |
2415                         NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
2416                 printf("opening %s\n", hold_info[i].fname);
2417
2418                 status = smb_raw_open(cli->tree, cli, &io);
2419                 if (!NT_STATUS_IS_OK(status)) {
2420                         printf("Failed to open %s - %s\n", 
2421                                hold_info[i].fname, nt_errstr(status));
2422                         return false;
2423                 }
2424
2425                 if (io.ntcreatex.out.oplock_level != BATCH_OPLOCK_RETURN) {
2426                         printf("Oplock not granted for %s - expected %d but got %d\n", 
2427                                hold_info[i].fname, BATCH_OPLOCK_RETURN, 
2428                                 io.ntcreatex.out.oplock_level);
2429                         return false;
2430                 }
2431                 hold_info[i].fnum = io.ntcreatex.out.file.fnum;
2432
2433                 /* make the file non-zero size */
2434                 if (smbcli_write(cli->tree, hold_info[i].fnum, 0, &c, 0, 1) != 1) {
2435                         printf("Failed to write to file\n");
2436                         return false;
2437                 }
2438         }
2439
2440         printf("Waiting for oplock events\n");
2441         event_loop_wait(ev);
2442
2443         return true;
2444 }