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