s4/torture: Fix misplaced positional arguments for u64 comparison
[gd/samba-autobuild/.git] / source4 / torture / raw / samba3misc.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Test some misc Samba3 code paths
4    Copyright (C) Volker Lendecke 2006
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 "libcli/raw/libcliraw.h"
23 #include "libcli/raw/raw_proto.h"
24 #include "system/time.h"
25 #include "system/filesys.h"
26 #include "libcli/libcli.h"
27 #include "torture/util.h"
28 #include "lib/events/events.h"
29 #include "param/param.h"
30 #include "torture/raw/proto.h"
31
32 /*
33  The next 2 functions are stolen from source4/libcli/raw/rawfile.c
34  but allow us to send a raw data blob instead of an OpenX name.
35 */
36
37 #define SETUP_REQUEST(cmd, wct, buflen) do { \
38         req = smbcli_request_setup(tree, cmd, wct, buflen); \
39         if (!req) return NULL; \
40 } while (0)
41
42 static struct smbcli_request *smb_raw_openX_name_blob_send(struct smbcli_tree *tree,
43                                         union smb_open *parms,
44                                         const DATA_BLOB *pname_blob)
45 {
46         struct smbcli_request *req = NULL;
47
48         if (parms->generic.level != RAW_OPEN_OPENX) {
49                 return NULL;
50         }
51
52         SETUP_REQUEST(SMBopenX, 15, 0);
53         SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
54         SSVAL(req->out.vwv, VWV(1), 0);
55         SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
56         SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
57         SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
58         SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
59         raw_push_dos_date3(tree->session->transport,
60                         req->out.vwv, VWV(6), parms->openx.in.write_time);
61         SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
62         SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
63         SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
64         SIVAL(req->out.vwv, VWV(13),0); /* reserved */
65         smbcli_req_append_blob(req, pname_blob);
66
67         if (!smbcli_request_send(req)) {
68                 smbcli_request_destroy(req);
69                 return NULL;
70         }
71
72         return req;
73 }
74
75 static NTSTATUS smb_raw_openX_name_blob(struct smbcli_tree *tree,
76                         TALLOC_CTX *mem_ctx,
77                         union smb_open *parms,
78                         const DATA_BLOB *pname_blob)
79 {
80         struct smbcli_request *req = smb_raw_openX_name_blob_send(tree, parms, pname_blob);
81         return smb_raw_open_recv(req, mem_ctx, parms);
82 }
83
84 static NTSTATUS raw_smbcli_openX_name_blob(struct smbcli_tree *tree,
85                                 const DATA_BLOB *pname_blob,
86                                 int flags,
87                                 int share_mode,
88                                 int *fnum)
89 {
90         union smb_open open_parms;
91         unsigned int openfn=0;
92         unsigned int accessmode=0;
93         TALLOC_CTX *mem_ctx;
94         NTSTATUS status;
95
96         mem_ctx = talloc_init("raw_openX_name_blob");
97         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
98
99         if (flags & O_CREAT) {
100                 openfn |= OPENX_OPEN_FUNC_CREATE;
101         }
102         if (!(flags & O_EXCL)) {
103                 if (flags & O_TRUNC) {
104                         openfn |= OPENX_OPEN_FUNC_TRUNC;
105                 } else {
106                         openfn |= OPENX_OPEN_FUNC_OPEN;
107                 }
108         }
109
110         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
111
112         if ((flags & O_ACCMODE) == O_RDWR) {
113                 accessmode |= OPENX_MODE_ACCESS_RDWR;
114         } else if ((flags & O_ACCMODE) == O_WRONLY) {
115                 accessmode |= OPENX_MODE_ACCESS_WRITE;
116         } else if ((flags & O_ACCMODE) == O_RDONLY) {
117                 accessmode |= OPENX_MODE_ACCESS_READ;
118         }
119
120 #if defined(O_SYNC)
121         if ((flags & O_SYNC) == O_SYNC) {
122                 accessmode |= OPENX_MODE_WRITE_THRU;
123         }
124 #endif
125
126         if (share_mode == DENY_FCB) {
127                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
128         }
129
130         open_parms.openx.level = RAW_OPEN_OPENX;
131         open_parms.openx.in.flags = 0;
132         open_parms.openx.in.open_mode = accessmode;
133         open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
134         open_parms.openx.in.file_attrs = 0;
135         open_parms.openx.in.write_time = 0;
136         open_parms.openx.in.open_func = openfn;
137         open_parms.openx.in.size = 0;
138         open_parms.openx.in.timeout = 0;
139         open_parms.openx.in.fname = NULL;
140
141         status = smb_raw_openX_name_blob(tree, mem_ctx, &open_parms, pname_blob);
142         talloc_free(mem_ctx);
143
144         if (fnum && NT_STATUS_IS_OK(status)) {
145                 *fnum = open_parms.openx.out.file.fnum;
146         }
147
148         return status;
149 }
150
151
152 #define CHECK_STATUS(torture, status, correct) do {     \
153         if (!NT_STATUS_EQUAL(status, correct)) { \
154                 torture_result(torture, TORTURE_FAIL, "%s: Incorrect status %s - should be %s\n", \
155                        __location__, nt_errstr(status), nt_errstr(correct)); \
156                 ret = false; \
157         } \
158 } while (0)
159
160 bool torture_samba3_checkfsp(struct torture_context *torture, struct smbcli_state *cli)
161 {
162         const char *fname = "test.txt";
163         const char *dirname = "testdir";
164         int fnum;
165         NTSTATUS status;
166         bool ret = true;
167         TALLOC_CTX *mem_ctx;
168         ssize_t nread;
169         char buf[16];
170         struct smbcli_tree *tree2;
171
172         torture_assert(torture, mem_ctx = talloc_init("torture_samba3_checkfsp"), "talloc_init failed\n");
173
174         torture_assert_ntstatus_equal(torture, torture_second_tcon(torture, cli->session,
175                                                                    torture_setting_string(torture, "share", NULL),
176                                                                    &tree2), 
177                                       NT_STATUS_OK,
178                                       "creating second tcon");
179
180         /* Try a read on an invalid FID */
181
182         nread = smbcli_read(cli->tree, 4711, buf, 0, sizeof(buf));
183         CHECK_STATUS(torture, smbcli_nt_error(cli->tree), NT_STATUS_INVALID_HANDLE);
184
185         /* Try a read on a directory handle */
186
187         torture_assert(torture, torture_setup_dir(cli, dirname), "creating test directory");
188
189         /* Open the directory */
190         {
191                 union smb_open io;
192                 io.generic.level = RAW_OPEN_NTCREATEX;
193                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
194                 io.ntcreatex.in.root_fid.fnum = 0;
195                 io.ntcreatex.in.security_flags = 0;
196                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
197                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
198                 io.ntcreatex.in.alloc_size = 0;
199                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
200                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
201                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
202                 io.ntcreatex.in.create_options = 0;
203                 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
204                 io.ntcreatex.in.fname = dirname;
205                 status = smb_raw_open(cli->tree, mem_ctx, &io);
206                 if (!NT_STATUS_IS_OK(status)) {
207                         torture_result(torture, TORTURE_FAIL, "smb_open on the directory failed: %s\n",
208                                  nt_errstr(status));
209                         ret = false;
210                         goto done;
211                 }
212                 fnum = io.ntcreatex.out.file.fnum;
213         }
214
215         /* Try a read on the directory */
216
217         nread = smbcli_read(cli->tree, fnum, buf, 0, sizeof(buf));
218         if (nread >= 0) {
219                 torture_result(torture, TORTURE_FAIL, "smbcli_read on a directory succeeded, expected "
220                          "failure\n");
221                 ret = false;
222         }
223
224         CHECK_STATUS(torture, smbcli_nt_error(cli->tree),
225                      NT_STATUS_INVALID_DEVICE_REQUEST);
226
227         /* Same test on the second tcon */
228
229         nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
230         if (nread >= 0) {
231                 torture_result(torture, TORTURE_FAIL, "smbcli_read on a directory succeeded, expected "
232                          "failure\n");
233                 ret = false;
234         }
235
236         CHECK_STATUS(torture, smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
237
238         smbcli_close(cli->tree, fnum);
239
240         /* Try a normal file read on a second tcon */
241
242         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
243         if (fnum == -1) {
244                 torture_result(torture, TORTURE_FAIL, "Failed to create %s - %s\n", fname,
245                          smbcli_errstr(cli->tree));
246                 ret = false;
247                 goto done;
248         }
249
250         nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
251         CHECK_STATUS(torture, smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
252
253         smbcli_close(cli->tree, fnum);
254
255  done:
256         smbcli_deltree(cli->tree, dirname);
257         talloc_free(mem_ctx);
258
259         return ret;
260 }
261
262 static NTSTATUS raw_smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
263 {
264         union smb_open open_parms;
265         unsigned int openfn=0;
266         unsigned int accessmode=0;
267         TALLOC_CTX *mem_ctx;
268         NTSTATUS status;
269
270         mem_ctx = talloc_init("raw_open");
271         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
272
273         if (flags & O_CREAT) {
274                 openfn |= OPENX_OPEN_FUNC_CREATE;
275         }
276         if (!(flags & O_EXCL)) {
277                 if (flags & O_TRUNC) {
278                         openfn |= OPENX_OPEN_FUNC_TRUNC;
279                 } else {
280                         openfn |= OPENX_OPEN_FUNC_OPEN;
281                 }
282         }
283
284         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
285
286         if ((flags & O_ACCMODE) == O_RDWR) {
287                 accessmode |= OPENX_MODE_ACCESS_RDWR;
288         } else if ((flags & O_ACCMODE) == O_WRONLY) {
289                 accessmode |= OPENX_MODE_ACCESS_WRITE;
290         } else if ((flags & O_ACCMODE) == O_RDONLY) {
291                 accessmode |= OPENX_MODE_ACCESS_READ;
292         }
293
294 #if defined(O_SYNC)
295         if ((flags & O_SYNC) == O_SYNC) {
296                 accessmode |= OPENX_MODE_WRITE_THRU;
297         }
298 #endif
299
300         if (share_mode == DENY_FCB) {
301                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
302         }
303
304         open_parms.openx.level = RAW_OPEN_OPENX;
305         open_parms.openx.in.flags = 0;
306         open_parms.openx.in.open_mode = accessmode;
307         open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
308         open_parms.openx.in.file_attrs = 0;
309         open_parms.openx.in.write_time = 0;
310         open_parms.openx.in.open_func = openfn;
311         open_parms.openx.in.size = 0;
312         open_parms.openx.in.timeout = 0;
313         open_parms.openx.in.fname = fname;
314
315         status = smb_raw_open(tree, mem_ctx, &open_parms);
316         talloc_free(mem_ctx);
317
318         if (fnum && NT_STATUS_IS_OK(status)) {
319                 *fnum = open_parms.openx.out.file.fnum;
320         }
321
322         return status;
323 }
324
325 static NTSTATUS raw_smbcli_t2open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
326 {
327         union smb_open io;
328         unsigned int openfn=0;
329         unsigned int accessmode=0;
330         TALLOC_CTX *mem_ctx;
331         NTSTATUS status;
332
333         mem_ctx = talloc_init("raw_t2open");
334         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
335
336         if (flags & O_CREAT) {
337                 openfn |= OPENX_OPEN_FUNC_CREATE;
338         }
339         if (!(flags & O_EXCL)) {
340                 if (flags & O_TRUNC) {
341                         openfn |= OPENX_OPEN_FUNC_TRUNC;
342                 } else {
343                         openfn |= OPENX_OPEN_FUNC_OPEN;
344                 }
345         }
346
347         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
348
349         if ((flags & O_ACCMODE) == O_RDWR) {
350                 accessmode |= OPENX_MODE_ACCESS_RDWR;
351         } else if ((flags & O_ACCMODE) == O_WRONLY) {
352                 accessmode |= OPENX_MODE_ACCESS_WRITE;
353         } else if ((flags & O_ACCMODE) == O_RDONLY) {
354                 accessmode |= OPENX_MODE_ACCESS_READ;
355         }
356
357 #if defined(O_SYNC)
358         if ((flags & O_SYNC) == O_SYNC) {
359                 accessmode |= OPENX_MODE_WRITE_THRU;
360         }
361 #endif
362
363         if (share_mode == DENY_FCB) {
364                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
365         }
366
367         memset(&io, '\0', sizeof(io));
368         io.t2open.level = RAW_OPEN_T2OPEN;
369         io.t2open.in.flags = 0;
370         io.t2open.in.open_mode = accessmode;
371         io.t2open.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
372         io.t2open.in.file_attrs = 0;
373         io.t2open.in.write_time = 0;
374         io.t2open.in.open_func = openfn;
375         io.t2open.in.size = 0;
376         io.t2open.in.timeout = 0;
377         io.t2open.in.fname = fname;
378
379         io.t2open.in.num_eas = 1;
380         io.t2open.in.eas = talloc_array(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
381         io.t2open.in.eas[0].flags = 0;
382         io.t2open.in.eas[0].name.s = ".CLASSINFO";
383         io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
384
385         status = smb_raw_open(tree, mem_ctx, &io);
386         talloc_free(mem_ctx);
387
388         if (fnum && NT_STATUS_IS_OK(status)) {
389                 *fnum = io.openx.out.file.fnum;
390         }
391
392         return status;
393 }
394
395 static NTSTATUS raw_smbcli_ntcreate(struct smbcli_tree *tree, const char *fname, int *fnum)
396 {
397         union smb_open io;
398         TALLOC_CTX *mem_ctx;
399         NTSTATUS status;
400
401         mem_ctx = talloc_init("raw_t2open");
402         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
403
404         memset(&io, '\0', sizeof(io));
405         io.generic.level = RAW_OPEN_NTCREATEX;
406         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
407         io.ntcreatex.in.root_fid.fnum = 0;
408         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
409         io.ntcreatex.in.alloc_size = 0;
410         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
411         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
412         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
413         io.ntcreatex.in.create_options = 0;
414         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
415         io.ntcreatex.in.security_flags = 0;
416         io.ntcreatex.in.fname = fname;
417
418         status = smb_raw_open(tree, mem_ctx, &io);
419         talloc_free(mem_ctx);
420
421         if (fnum && NT_STATUS_IS_OK(status)) {
422                 *fnum = io.openx.out.file.fnum;
423         }
424
425         return status;
426 }
427
428
429 bool torture_samba3_badpath(struct torture_context *torture)
430 {
431         struct smbcli_state *cli_nt = NULL;
432         struct smbcli_state *cli_dos = NULL;
433         const char *fname = "test.txt";
434         const char *fname1 = "test1.txt";
435         const char *dirname = "testdir";
436         char *fpath;
437         char *fpath1;
438         int fnum;
439         NTSTATUS status;
440         bool ret = true;
441         TALLOC_CTX *mem_ctx;
442         bool nt_status_support;
443         bool client_ntlmv2_auth;
444
445         torture_assert(torture, mem_ctx = talloc_init("torture_samba3_badpath"), "talloc_init failed");
446
447         nt_status_support = lpcfg_nt_status_support(torture->lp_ctx);
448         client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(torture->lp_ctx);
449
450         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes"), ret, fail, "Could not set 'nt status support = yes'\n");
451         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "yes"), ret, fail, "Could not set 'client ntlmv2 auth = yes'\n");
452
453         torture_assert_goto(torture, torture_open_connection(&cli_nt, torture, 0), ret, fail, "Could not open NTSTATUS connection\n");
454
455         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no"), ret, fail, "Could not set 'nt status support = no'\n");
456         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "no"), ret, fail, "Could not set 'client ntlmv2 auth = no'\n");
457
458         torture_assert_goto(torture, torture_open_connection(&cli_dos, torture, 1), ret, fail, "Could not open DOS connection\n");
459
460         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support",
461                                                        nt_status_support ? "yes":"no"), 
462                             ret, fail, "Could not set 'nt status support' back to where it was\n");
463         torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth",
464                                                        client_ntlmv2_auth ? "yes":"no"),
465                             ret, fail, "Could not set 'client ntlmv2 auth' back to where it was\n");
466
467         torture_assert(torture, torture_setup_dir(cli_nt, dirname), "creating test directory");
468
469         status = smbcli_chkpath(cli_nt->tree, dirname);
470         CHECK_STATUS(torture, status, NT_STATUS_OK);
471
472         status = smbcli_chkpath(cli_nt->tree,
473                                 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
474         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
475
476         status = smbcli_chkpath(cli_dos->tree,
477                                 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
478         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
479
480         status = smbcli_chkpath(cli_nt->tree,
481                                 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
482                                                 dirname));
483         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
484         status = smbcli_chkpath(cli_dos->tree,
485                                 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
486                                                 dirname));
487         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
488
489         torture_assert_goto(torture, fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname), 
490                             ret, fail, "Could not allocate fpath\n");
491
492         fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
493         if (fnum == -1) {
494                 torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s\n", fpath,
495                          smbcli_errstr(cli_nt->tree));
496                 goto fail;
497         }
498         smbcli_close(cli_nt->tree, fnum);
499
500         if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
501                 goto fail;
502         }
503         fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
504         if (fnum == -1) {
505                 torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s\n", fpath1,
506                          smbcli_errstr(cli_nt->tree));
507                 goto fail;
508         }
509         smbcli_close(cli_nt->tree, fnum);
510
511         /*
512          * Do a whole bunch of error code checks on chkpath
513          */
514
515         status = smbcli_chkpath(cli_nt->tree, fpath);
516         CHECK_STATUS(torture, status, NT_STATUS_NOT_A_DIRECTORY);
517         status = smbcli_chkpath(cli_dos->tree, fpath);
518         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
519
520         status = smbcli_chkpath(cli_nt->tree, "..");
521         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
522         status = smbcli_chkpath(cli_dos->tree, "..");
523         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
524
525         status = smbcli_chkpath(cli_nt->tree, ".");
526         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
527         status = smbcli_chkpath(cli_dos->tree, ".");
528         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
529
530         status = smbcli_chkpath(cli_nt->tree, "\t");
531         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
532         status = smbcli_chkpath(cli_dos->tree, "\t");
533         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
534
535         status = smbcli_chkpath(cli_nt->tree, "\t\\bla");
536         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
537         status = smbcli_chkpath(cli_dos->tree, "\t\\bla");
538         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
539
540         status = smbcli_chkpath(cli_nt->tree, "<");
541         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
542         status = smbcli_chkpath(cli_dos->tree, "<");
543         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
544
545         status = smbcli_chkpath(cli_nt->tree, "<\\bla");
546         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
547         status = smbcli_chkpath(cli_dos->tree, "<\\bla");
548         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
549
550         /*
551          * .... And the same gang against getatr. Note that the DOS error codes
552          * differ....
553          */
554
555         status = smbcli_getatr(cli_nt->tree, fpath, NULL, NULL, NULL);
556         CHECK_STATUS(torture, status, NT_STATUS_OK);
557         status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
558         CHECK_STATUS(torture, status, NT_STATUS_OK);
559
560         status = smbcli_getatr(cli_nt->tree, "..", NULL, NULL, NULL);
561         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
562         status = smbcli_getatr(cli_dos->tree, "..", NULL, NULL, NULL);
563         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
564
565         status = smbcli_getatr(cli_nt->tree, ".", NULL, NULL, NULL);
566         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
567         status = smbcli_getatr(cli_dos->tree, ".", NULL, NULL, NULL);
568         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
569
570         status = smbcli_getatr(cli_nt->tree, "\t", NULL, NULL, NULL);
571         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
572         status = smbcli_getatr(cli_dos->tree, "\t", NULL, NULL, NULL);
573         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
574
575         status = smbcli_getatr(cli_nt->tree, "\t\\bla", NULL, NULL, NULL);
576         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
577         status = smbcli_getatr(cli_dos->tree, "\t\\bla", NULL, NULL, NULL);
578         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
579
580         status = smbcli_getatr(cli_nt->tree, "<", NULL, NULL, NULL);
581         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
582         status = smbcli_getatr(cli_dos->tree, "<", NULL, NULL, NULL);
583         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
584
585         status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
586         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
587         status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
588         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
589
590         /* Try the same set with openX. */
591
592         status = raw_smbcli_open(cli_nt->tree, "..", O_RDONLY, DENY_NONE, NULL);
593         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
594         status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
595         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
596
597         status = raw_smbcli_open(cli_nt->tree, ".", O_RDONLY, DENY_NONE, NULL);
598         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
599         status = raw_smbcli_open(cli_dos->tree, ".", O_RDONLY, DENY_NONE, NULL);
600         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
601
602         status = raw_smbcli_open(cli_nt->tree, "\t", O_RDONLY, DENY_NONE, NULL);
603         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
604         status = raw_smbcli_open(cli_dos->tree, "\t", O_RDONLY, DENY_NONE, NULL);
605         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
606
607         status = raw_smbcli_open(cli_nt->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
608         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
609         status = raw_smbcli_open(cli_dos->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
610         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
611
612         status = raw_smbcli_open(cli_nt->tree, "<", O_RDONLY, DENY_NONE, NULL);
613         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
614         status = raw_smbcli_open(cli_dos->tree, "<", O_RDONLY, DENY_NONE, NULL);
615         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
616
617         status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
618         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_INVALID);
619         status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
620         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
621
622         /* Let's test EEXIST error code mapping. */
623         status = raw_smbcli_open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
624         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
625         status = raw_smbcli_open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
626         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
627
628         status = raw_smbcli_t2open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
629         if (!NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
630             || !torture_setting_bool(torture, "samba3", false)) {
631                 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
632                 CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
633         }
634         status = raw_smbcli_t2open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
635         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,ERReasnotsupported))
636             || !torture_setting_bool(torture, "samba3", false)) {
637                 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
638                 CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
639         }
640
641         status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
642         CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
643         status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
644         CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
645
646         /* Try the rename test. */
647         {
648                 union smb_rename io;
649                 memset(&io, '\0', sizeof(io));
650                 io.rename.in.pattern1 = fpath1;
651                 io.rename.in.pattern2 = fpath;
652
653                 /* Try with SMBmv rename. */
654                 status = smb_raw_rename(cli_nt->tree, &io);
655                 CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
656                 status = smb_raw_rename(cli_dos->tree, &io);
657                 CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRrename));
658
659                 /* Try with NT rename. */
660                 io.generic.level = RAW_RENAME_NTRENAME;
661                 io.ntrename.in.old_name = fpath1;
662                 io.ntrename.in.new_name = fpath;
663                 io.ntrename.in.attrib = 0;
664                 io.ntrename.in.cluster_size = 0;
665                 io.ntrename.in.flags = RENAME_FLAG_RENAME;
666
667                 status = smb_raw_rename(cli_nt->tree, &io);
668                 CHECK_STATUS(torture, status, NT_STATUS_OBJECT_NAME_COLLISION);
669                 status = smb_raw_rename(cli_dos->tree, &io);
670                 CHECK_STATUS(torture, status, NT_STATUS_DOS(ERRDOS,ERRrename));
671         }
672
673         goto done;
674
675  fail:
676         ret = false;
677
678  done:
679         if (cli_nt != NULL) {
680                 smbcli_deltree(cli_nt->tree, dirname);
681                 torture_close_connection(cli_nt);
682         }
683         if (cli_dos != NULL) {
684                 torture_close_connection(cli_dos);
685         }
686         talloc_free(mem_ctx);
687
688         return ret;
689 }
690
691 static void count_fn(struct clilist_file_info *info, const char *name,
692                      void *private_data)
693 {
694         int *counter = (int *)private_data;
695         *counter += 1;
696 }
697
698 bool torture_samba3_caseinsensitive(struct torture_context *torture, struct smbcli_state *cli)
699 {
700         TALLOC_CTX *mem_ctx;
701         const char *dirname = "insensitive";
702         const char *ucase_dirname = "InSeNsItIvE";
703         const char *fname = "foo";
704         char *fpath;
705         int fnum;
706         int counter = 0;
707         bool ret = false;
708
709         if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) {
710                 torture_result(torture, TORTURE_FAIL, "talloc_init failed\n");
711                 return false;
712         }
713
714         torture_assert(torture, torture_setup_dir(cli, dirname), "creating test directory");
715
716         if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
717                 goto done;
718         }
719         fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
720         if (fnum == -1) {
721                 torture_result(torture, TORTURE_FAIL,
722                         "Could not create file %s: %s", fpath,
723                          smbcli_errstr(cli->tree));
724                 goto done;
725         }
726         smbcli_close(cli->tree, fnum);
727
728         smbcli_list(cli->tree, talloc_asprintf(
729                             mem_ctx, "%s\\*", ucase_dirname),
730                     FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN
731                     |FILE_ATTRIBUTE_SYSTEM,
732                     count_fn, (void *)&counter);
733
734         if (counter == 3) {
735                 ret = true;
736         }
737         else {
738                 torture_result(torture, TORTURE_FAIL,
739                         "expected 3 entries, got %d", counter);
740                 ret = false;
741         }
742
743  done:
744         talloc_free(mem_ctx);
745         return ret;
746 }
747
748 static void close_locked_file(struct tevent_context *ev,
749                               struct tevent_timer *te,
750                               struct timeval now,
751                               void *private_data)
752 {
753         int *pfd = (int *)private_data;
754
755         TALLOC_FREE(te);
756
757         if (*pfd != -1) {
758                 close(*pfd);
759                 *pfd = -1;
760         }
761 }
762
763 struct lock_result_state {
764         NTSTATUS status;
765         bool done;
766 };
767
768 static void receive_lock_result(struct smbcli_request *req)
769 {
770         struct lock_result_state *state =
771                 (struct lock_result_state *)req->async.private_data;
772
773         state->status = smbcli_request_simple_recv(req);
774         state->done = true;
775 }
776
777 /*
778  * Check that Samba3 correctly deals with conflicting local posix byte range
779  * locks on an underlying file via "normal" SMB1 (without unix extensions).
780  *
781  * Note: This test depends on "posix locking = yes".
782  * Note: To run this test, use "--option=torture:localdir=<LOCALDIR>"
783  */
784
785 bool torture_samba3_posixtimedlock(struct torture_context *tctx, struct smbcli_state *cli)
786 {
787         NTSTATUS status;
788         bool ret = true;
789         const char *dirname = "posixlock";
790         const char *fname = "locked";
791         const char *fpath;
792         const char *localdir;
793         const char *localname;
794         int fnum = -1;
795
796         int fd = -1;
797         struct flock posix_lock;
798
799         union smb_lock io;
800         struct smb_lock_entry lock_entry;
801         struct smbcli_request *req;
802         struct lock_result_state lock_result;
803
804         struct tevent_timer *te;
805
806         torture_assert(tctx, torture_setup_dir(cli, dirname), "creating test directory");
807
808         if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
809                 torture_warning(tctx, "talloc failed\n");
810                 ret = false;
811                 goto done;
812         }
813         fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
814         if (fnum == -1) {
815                 torture_warning(tctx, "Could not create file %s: %s\n", fpath,
816                                 smbcli_errstr(cli->tree));
817                 ret = false;
818                 goto done;
819         }
820
821         if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
822                 torture_warning(tctx, "Need 'localdir' setting\n");
823                 ret = false;
824                 goto done;
825         }
826
827         if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
828                                           fname))) {
829                 torture_warning(tctx, "talloc failed\n");
830                 ret = false;
831                 goto done;
832         }
833
834         /*
835          * Lock a byte range from posix
836          */
837
838         fd = open(localname, O_RDWR);
839         if (fd == -1) {
840                 torture_warning(tctx, "open(%s) failed: %s\n",
841                                 localname, strerror(errno));
842                 goto done;
843         }
844
845         posix_lock.l_type = F_WRLCK;
846         posix_lock.l_whence = SEEK_SET;
847         posix_lock.l_start = 0;
848         posix_lock.l_len = 1;
849
850         if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
851                 torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
852                 ret = false;
853                 goto done;
854         }
855
856         /*
857          * Try a cifs brlock without timeout to see if posix locking = yes
858          */
859
860         io.lockx.in.ulock_cnt = 0;
861         io.lockx.in.lock_cnt = 1;
862
863         lock_entry.count = 1;
864         lock_entry.offset = 0;
865         lock_entry.pid = cli->tree->session->pid;
866
867         io.lockx.level = RAW_LOCK_LOCKX;
868         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
869         io.lockx.in.timeout = 0;
870         io.lockx.in.locks = &lock_entry;
871         io.lockx.in.file.fnum = fnum;
872
873         status = smb_raw_lock(cli->tree, &io);
874
875         ret = true;
876         CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED);
877
878         if (!ret) {
879                 goto done;
880         }
881
882         /*
883          * Now fire off a timed brlock, unlock the posix lock and see if the
884          * timed lock gets through.
885          */
886
887         io.lockx.in.timeout = 5000;
888
889         req = smb_raw_lock_send(cli->tree, &io);
890         if (req == NULL) {
891                 torture_warning(tctx, "smb_raw_lock_send failed\n");
892                 ret = false;
893                 goto done;
894         }
895
896         lock_result.done = false;
897         req->async.fn = receive_lock_result;
898         req->async.private_data = &lock_result;
899
900         te = tevent_add_timer(tctx->ev,
901                               tctx, timeval_current_ofs(1, 0),
902                               close_locked_file, &fd);
903         if (te == NULL) {
904                 torture_warning(tctx, "tevent_add_timer failed\n");
905                 ret = false;
906                 goto done;
907         }
908
909         while ((fd != -1) || (!lock_result.done)) {
910                 if (tevent_loop_once(tctx->ev) == -1) {
911                         torture_warning(tctx, "tevent_loop_once failed: %s\n",
912                                         strerror(errno));
913                         ret = false;
914                         goto done;
915                 }
916         }
917
918         CHECK_STATUS(tctx, lock_result.status, NT_STATUS_OK);
919
920  done:
921         if (fnum != -1) {
922                 smbcli_close(cli->tree, fnum);
923         }
924         if (fd != -1) {
925                 close(fd);
926         }
927         smbcli_deltree(cli->tree, dirname);
928         return ret;
929 }
930
931 bool torture_samba3_rootdirfid(struct torture_context *tctx, struct smbcli_state *cli)
932 {
933         uint16_t dnum;
934         union smb_open io;
935         const char *fname = "testfile";
936         bool ret = false;
937
938         smbcli_unlink(cli->tree, fname);
939
940         ZERO_STRUCT(io);
941         io.generic.level = RAW_OPEN_NTCREATEX;
942         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
943         io.ntcreatex.in.root_fid.fnum = 0;
944         io.ntcreatex.in.security_flags = 0;
945         io.ntcreatex.in.access_mask =
946                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
947         io.ntcreatex.in.alloc_size = 0;
948         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
949         io.ntcreatex.in.share_access =
950                 NTCREATEX_SHARE_ACCESS_READ
951                 | NTCREATEX_SHARE_ACCESS_READ;
952         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
953         io.ntcreatex.in.create_options = 0;
954         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
955         io.ntcreatex.in.fname = "\\";
956         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io), 
957                                            NT_STATUS_OK,
958                                            ret, done, "smb_open on the directory failed: %s\n");
959
960         dnum = io.ntcreatex.out.file.fnum;
961
962         io.ntcreatex.in.flags =
963                 NTCREATEX_FLAGS_REQUEST_OPLOCK
964                 | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
965         io.ntcreatex.in.root_fid.fnum = dnum;
966         io.ntcreatex.in.security_flags = 0;
967         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
968         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
969         io.ntcreatex.in.alloc_size = 0;
970         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
971         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
972         io.ntcreatex.in.create_options = 0;
973         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
974         io.ntcreatex.in.fname = fname;
975
976         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
977                                            NT_STATUS_OK,
978                                            ret, done, "smb_open on the file failed");
979
980         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
981         smbcli_close(cli->tree, dnum);
982         smbcli_unlink(cli->tree, fname);
983
984         ret = true;
985  done:
986         return ret;
987 }
988
989 bool torture_samba3_rootdirfid2(struct torture_context *tctx, struct smbcli_state *cli)
990 {
991         int fnum;
992         uint16_t dnum;
993         union smb_open io;
994         const char *dirname1 = "dir1";
995         const char *dirname2 = "dir1/dir2";
996         const char *path = "dir1/dir2/testfile";
997         const char *relname = "dir2/testfile";
998         bool ret = false;
999
1000         smbcli_deltree(cli->tree, dirname1);
1001
1002         torture_assert(tctx, torture_setup_dir(cli, dirname1), "creating test directory");
1003         torture_assert(tctx, torture_setup_dir(cli, dirname2), "creating test directory");
1004
1005         fnum = smbcli_open(cli->tree, path, O_RDWR | O_CREAT, DENY_NONE);
1006         if (fnum == -1) {
1007                 torture_result(tctx, TORTURE_FAIL,
1008                         "Could not create file: %s",
1009                          smbcli_errstr(cli->tree));
1010                 goto done;
1011         }
1012         smbcli_close(cli->tree, fnum);
1013
1014         ZERO_STRUCT(io);
1015         io.generic.level = RAW_OPEN_NTCREATEX;
1016         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1017         io.ntcreatex.in.root_fid.fnum = 0;
1018         io.ntcreatex.in.security_flags = 0;
1019         io.ntcreatex.in.access_mask =
1020                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
1021         io.ntcreatex.in.alloc_size = 0;
1022         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1023         io.ntcreatex.in.share_access =
1024                 NTCREATEX_SHARE_ACCESS_READ
1025                 | NTCREATEX_SHARE_ACCESS_READ;
1026         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1027         io.ntcreatex.in.create_options = 0;
1028         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1029         io.ntcreatex.in.fname = dirname1;
1030         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
1031                                            NT_STATUS_OK,
1032                                            ret, done, "smb_open on the directory failed: %s\n");
1033
1034         dnum = io.ntcreatex.out.file.fnum;
1035
1036         io.ntcreatex.in.flags =
1037                 NTCREATEX_FLAGS_REQUEST_OPLOCK
1038                 | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
1039         io.ntcreatex.in.root_fid.fnum = dnum;
1040         io.ntcreatex.in.security_flags = 0;
1041         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1042         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1043         io.ntcreatex.in.alloc_size = 0;
1044         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1045         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1046         io.ntcreatex.in.create_options = 0;
1047         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1048         io.ntcreatex.in.fname = relname;
1049
1050         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
1051                                            NT_STATUS_OK,
1052                                            ret, done, "smb_open on the file failed");
1053
1054         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
1055         smbcli_close(cli->tree, dnum);
1056
1057         ret = true;
1058 done:
1059         smbcli_deltree(cli->tree, dirname1);
1060         return ret;
1061 }
1062
1063 bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_state *cli)
1064 {
1065         union smb_open io;
1066         const char *fname = "testfile";
1067         bool ret = false;
1068         struct smbcli_request *req;
1069         struct smb_echo echo_req;
1070
1071         smbcli_unlink(cli->tree, fname);
1072
1073         ZERO_STRUCT(io);
1074         io.generic.level = RAW_OPEN_NTCREATEX;
1075         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1076         io.ntcreatex.in.root_fid.fnum = 0;
1077         io.ntcreatex.in.security_flags = 0;
1078         io.ntcreatex.in.access_mask =
1079                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
1080         io.ntcreatex.in.alloc_size = 0;
1081         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
1082         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1083         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
1084         io.ntcreatex.in.create_options = 0;
1085         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1086         io.ntcreatex.in.fname = "testfile";
1087         torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io),
1088                                            NT_STATUS_OK,
1089                                            ret, done, "first smb_open on the file failed");
1090
1091         /*
1092          * Create a conflicting open, causing the one-second delay
1093          */
1094
1095         torture_assert_goto(tctx, req = smb_raw_open_send(cli->tree, &io),
1096                             ret, done, "smb_raw_open_send on the file failed");
1097
1098         /*
1099          * Pull the VUID from under that request. As of Nov 3, 2008 all Samba3
1100          * versions (3.0, 3.2 and master) would spin sending ERRinvuid errors
1101          * as long as the client is still connected.
1102          */
1103
1104         torture_assert_ntstatus_equal_goto(tctx, smb_raw_ulogoff(cli->session),
1105                                            NT_STATUS_OK,
1106                                            ret, done, "ulogoff failed failed");
1107
1108         echo_req.in.repeat_count = 1;
1109         echo_req.in.size = 1;
1110         echo_req.in.data = discard_const_p(uint8_t, "");
1111
1112         torture_assert_ntstatus_equal_goto(tctx, smb_raw_echo(cli->session->transport, &echo_req),
1113                                            NT_STATUS_OK,
1114                                            ret, done, "smb_raw_echo failed");
1115
1116         ret = true;
1117  done:
1118         return ret;
1119 }
1120
1121 bool torture_samba3_check_openX_badname(struct torture_context *tctx, struct smbcli_state *cli)
1122 {
1123         NTSTATUS status;
1124         bool ret = false;
1125         int fnum = -1;
1126         DATA_BLOB name_blob = data_blob_talloc(cli->tree, NULL, 65535);
1127
1128         if (name_blob.data == NULL) {
1129                 return false;
1130         }
1131         memset(name_blob.data, 0xcc, 65535);
1132         status = raw_smbcli_openX_name_blob(cli->tree, &name_blob, O_RDWR, DENY_NONE, &fnum);
1133         CHECK_STATUS(tctx, status, NT_STATUS_OBJECT_NAME_INVALID);
1134         ret = true;
1135
1136         return ret;
1137 }