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