2 Unix SMB/CIFS implementation.
3 Test some misc Samba3 code paths
4 Copyright (C) Volker Lendecke 2006
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.
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.
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/>.
21 #include "torture/torture.h"
22 #include "libcli/raw/libcliraw.h"
23 #include "system/time.h"
24 #include "system/filesys.h"
25 #include "libcli/libcli.h"
26 #include "torture/util.h"
27 #include "lib/events/events.h"
28 #include "param/param.h"
30 #define CHECK_STATUS(status, correct) do { \
31 if (!NT_STATUS_EQUAL(status, correct)) { \
32 printf("(%s) Incorrect status %s - should be %s\n", \
33 __location__, nt_errstr(status), nt_errstr(correct)); \
38 bool torture_samba3_checkfsp(struct torture_context *torture)
40 struct smbcli_state *cli;
41 const char *fname = "test.txt";
42 const char *dirname = "testdir";
49 struct smbcli_tree *tree2;
51 if ((mem_ctx = talloc_init("torture_samba3_checkfsp")) == NULL) {
52 d_printf("talloc_init failed\n");
56 if (!torture_open_connection_share(
57 torture, &cli, torture_setting_string(torture, "host", NULL),
58 torture_setting_string(torture, "share", NULL), NULL)) {
59 d_printf("torture_open_connection_share failed\n");
64 smbcli_deltree(cli->tree, dirname);
66 status = torture_second_tcon(torture, cli->session,
67 torture_setting_string(torture, "share", NULL),
69 CHECK_STATUS(status, NT_STATUS_OK);
70 if (!NT_STATUS_IS_OK(status))
73 /* Try a read on an invalid FID */
75 nread = smbcli_read(cli->tree, 4711, buf, 0, sizeof(buf));
76 CHECK_STATUS(smbcli_nt_error(cli->tree), NT_STATUS_INVALID_HANDLE);
78 /* Try a read on a directory handle */
80 status = smbcli_mkdir(cli->tree, dirname);
81 if (!NT_STATUS_IS_OK(status)) {
82 d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
87 /* Open the directory */
90 io.generic.level = RAW_OPEN_NTCREATEX;
91 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
92 io.ntcreatex.in.root_fid = 0;
93 io.ntcreatex.in.security_flags = 0;
94 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
95 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
96 io.ntcreatex.in.alloc_size = 0;
97 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
98 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
99 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
100 io.ntcreatex.in.create_options = 0;
101 io.ntcreatex.in.fname = dirname;
102 status = smb_raw_open(cli->tree, mem_ctx, &io);
103 if (!NT_STATUS_IS_OK(status)) {
104 d_printf("smb_open on the directory failed: %s\n",
109 fnum = io.ntcreatex.out.file.fnum;
112 /* Try a read on the directory */
114 nread = smbcli_read(cli->tree, fnum, buf, 0, sizeof(buf));
116 d_printf("smbcli_read on a directory succeeded, expected "
121 CHECK_STATUS(smbcli_nt_error(cli->tree),
122 NT_STATUS_INVALID_DEVICE_REQUEST);
124 /* Same test on the second tcon */
126 nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
128 d_printf("smbcli_read on a directory succeeded, expected "
133 CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
135 smbcli_close(cli->tree, fnum);
137 /* Try a normal file read on a second tcon */
139 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
141 d_printf("Failed to create %s - %s\n", fname,
142 smbcli_errstr(cli->tree));
147 nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
148 CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
150 smbcli_close(cli->tree, fnum);
153 smbcli_deltree(cli->tree, dirname);
154 torture_close_connection(cli);
155 talloc_free(mem_ctx);
160 static NTSTATUS raw_smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
162 union smb_open open_parms;
168 mem_ctx = talloc_init("raw_open");
169 if (!mem_ctx) return NT_STATUS_NO_MEMORY;
171 if (flags & O_CREAT) {
172 openfn |= OPENX_OPEN_FUNC_CREATE;
174 if (!(flags & O_EXCL)) {
175 if (flags & O_TRUNC) {
176 openfn |= OPENX_OPEN_FUNC_TRUNC;
178 openfn |= OPENX_OPEN_FUNC_OPEN;
182 accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
184 if ((flags & O_ACCMODE) == O_RDWR) {
185 accessmode |= OPENX_MODE_ACCESS_RDWR;
186 } else if ((flags & O_ACCMODE) == O_WRONLY) {
187 accessmode |= OPENX_MODE_ACCESS_WRITE;
188 } else if ((flags & O_ACCMODE) == O_RDONLY) {
189 accessmode |= OPENX_MODE_ACCESS_READ;
193 if ((flags & O_SYNC) == O_SYNC) {
194 accessmode |= OPENX_MODE_WRITE_THRU;
198 if (share_mode == DENY_FCB) {
199 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
202 open_parms.openx.level = RAW_OPEN_OPENX;
203 open_parms.openx.in.flags = 0;
204 open_parms.openx.in.open_mode = accessmode;
205 open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
206 open_parms.openx.in.file_attrs = 0;
207 open_parms.openx.in.write_time = 0;
208 open_parms.openx.in.open_func = openfn;
209 open_parms.openx.in.size = 0;
210 open_parms.openx.in.timeout = 0;
211 open_parms.openx.in.fname = fname;
213 status = smb_raw_open(tree, mem_ctx, &open_parms);
214 talloc_free(mem_ctx);
216 if (fnum && NT_STATUS_IS_OK(status)) {
217 *fnum = open_parms.openx.out.file.fnum;
223 static NTSTATUS raw_smbcli_t2open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
231 mem_ctx = talloc_init("raw_t2open");
232 if (!mem_ctx) return NT_STATUS_NO_MEMORY;
234 if (flags & O_CREAT) {
235 openfn |= OPENX_OPEN_FUNC_CREATE;
237 if (!(flags & O_EXCL)) {
238 if (flags & O_TRUNC) {
239 openfn |= OPENX_OPEN_FUNC_TRUNC;
241 openfn |= OPENX_OPEN_FUNC_OPEN;
245 accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
247 if ((flags & O_ACCMODE) == O_RDWR) {
248 accessmode |= OPENX_MODE_ACCESS_RDWR;
249 } else if ((flags & O_ACCMODE) == O_WRONLY) {
250 accessmode |= OPENX_MODE_ACCESS_WRITE;
251 } else if ((flags & O_ACCMODE) == O_RDONLY) {
252 accessmode |= OPENX_MODE_ACCESS_READ;
256 if ((flags & O_SYNC) == O_SYNC) {
257 accessmode |= OPENX_MODE_WRITE_THRU;
261 if (share_mode == DENY_FCB) {
262 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
265 memset(&io, '\0', sizeof(io));
266 io.t2open.level = RAW_OPEN_T2OPEN;
267 io.t2open.in.flags = 0;
268 io.t2open.in.open_mode = accessmode;
269 io.t2open.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
270 io.t2open.in.file_attrs = 0;
271 io.t2open.in.write_time = 0;
272 io.t2open.in.open_func = openfn;
273 io.t2open.in.size = 0;
274 io.t2open.in.timeout = 0;
275 io.t2open.in.fname = fname;
277 io.t2open.in.num_eas = 1;
278 io.t2open.in.eas = talloc_array(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
279 io.t2open.in.eas[0].flags = 0;
280 io.t2open.in.eas[0].name.s = ".CLASSINFO";
281 io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
283 status = smb_raw_open(tree, mem_ctx, &io);
284 talloc_free(mem_ctx);
286 if (fnum && NT_STATUS_IS_OK(status)) {
287 *fnum = io.openx.out.file.fnum;
293 static NTSTATUS raw_smbcli_ntcreate(struct smbcli_tree *tree, const char *fname, int *fnum)
299 mem_ctx = talloc_init("raw_t2open");
300 if (!mem_ctx) return NT_STATUS_NO_MEMORY;
302 memset(&io, '\0', sizeof(io));
303 io.generic.level = RAW_OPEN_NTCREATEX;
304 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
305 io.ntcreatex.in.root_fid = 0;
306 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
307 io.ntcreatex.in.alloc_size = 0;
308 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
309 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
310 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
311 io.ntcreatex.in.create_options = 0;
312 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
313 io.ntcreatex.in.security_flags = 0;
314 io.ntcreatex.in.fname = fname;
316 status = smb_raw_open(tree, mem_ctx, &io);
317 talloc_free(mem_ctx);
319 if (fnum && NT_STATUS_IS_OK(status)) {
320 *fnum = io.openx.out.file.fnum;
327 bool torture_samba3_badpath(struct torture_context *torture)
329 struct smbcli_state *cli_nt;
330 struct smbcli_state *cli_dos;
331 const char *fname = "test.txt";
332 const char *fname1 = "test1.txt";
333 const char *dirname = "testdir";
340 BOOL nt_status_support;
342 if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
343 d_printf("talloc_init failed\n");
347 nt_status_support = lp_nt_status_support();
349 if (!lp_set_cmdline(global_loadparm, "nt status support", "yes")) {
350 printf("Could not set 'nt status support = yes'\n");
354 if (!torture_open_connection(&cli_nt, 0)) {
358 if (!lp_set_cmdline(global_loadparm, "nt status support", "no")) {
359 printf("Could not set 'nt status support = yes'\n");
363 if (!torture_open_connection(&cli_dos, 1)) {
367 if (!lp_set_cmdline(global_loadparm, "nt status support",
368 nt_status_support ? "yes":"no")) {
369 printf("Could not reset 'nt status support = yes'");
373 smbcli_deltree(cli_nt->tree, dirname);
375 status = smbcli_mkdir(cli_nt->tree, dirname);
376 if (!NT_STATUS_IS_OK(status)) {
377 d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
382 status = smbcli_chkpath(cli_nt->tree, dirname);
383 CHECK_STATUS(status, NT_STATUS_OK);
385 status = smbcli_chkpath(cli_nt->tree,
386 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
387 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
389 status = smbcli_chkpath(cli_dos->tree,
390 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
391 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
393 status = smbcli_chkpath(cli_nt->tree,
394 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
396 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
397 status = smbcli_chkpath(cli_dos->tree,
398 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
400 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
402 if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
405 fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
407 d_printf("Could not create file %s: %s\n", fpath,
408 smbcli_errstr(cli_nt->tree));
411 smbcli_close(cli_nt->tree, fnum);
413 if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
416 fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
418 d_printf("Could not create file %s: %s\n", fpath1,
419 smbcli_errstr(cli_nt->tree));
422 smbcli_close(cli_nt->tree, fnum);
425 * Do a whole bunch of error code checks on chkpath
428 status = smbcli_chkpath(cli_nt->tree, fpath);
429 CHECK_STATUS(status, NT_STATUS_NOT_A_DIRECTORY);
430 status = smbcli_chkpath(cli_dos->tree, fpath);
431 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
433 status = smbcli_chkpath(cli_nt->tree, "..");
434 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
435 status = smbcli_chkpath(cli_dos->tree, "..");
436 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
438 status = smbcli_chkpath(cli_nt->tree, ".");
439 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
440 status = smbcli_chkpath(cli_dos->tree, ".");
441 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
443 status = smbcli_chkpath(cli_nt->tree, "\t");
444 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
445 status = smbcli_chkpath(cli_dos->tree, "\t");
446 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
448 status = smbcli_chkpath(cli_nt->tree, "\t\\bla");
449 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
450 status = smbcli_chkpath(cli_dos->tree, "\t\\bla");
451 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
453 status = smbcli_chkpath(cli_nt->tree, "<");
454 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
455 status = smbcli_chkpath(cli_dos->tree, "<");
456 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
458 status = smbcli_chkpath(cli_nt->tree, "<\\bla");
459 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
460 status = smbcli_chkpath(cli_dos->tree, "<\\bla");
461 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
464 * .... And the same gang against getatr. Note that the DOS error codes
468 status = smbcli_getatr(cli_nt->tree, fpath, NULL, NULL, NULL);
469 CHECK_STATUS(status, NT_STATUS_OK);
470 status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
471 CHECK_STATUS(status, NT_STATUS_OK);
473 status = smbcli_getatr(cli_nt->tree, "..", NULL, NULL, NULL);
474 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
475 status = smbcli_getatr(cli_dos->tree, "..", NULL, NULL, NULL);
476 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
478 status = smbcli_getatr(cli_nt->tree, ".", NULL, NULL, NULL);
479 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
480 status = smbcli_getatr(cli_dos->tree, ".", NULL, NULL, NULL);
481 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
483 status = smbcli_getatr(cli_nt->tree, "\t", NULL, NULL, NULL);
484 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
485 status = smbcli_getatr(cli_dos->tree, "\t", NULL, NULL, NULL);
486 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
488 status = smbcli_getatr(cli_nt->tree, "\t\\bla", NULL, NULL, NULL);
489 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
490 status = smbcli_getatr(cli_dos->tree, "\t\\bla", NULL, NULL, NULL);
491 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
493 status = smbcli_getatr(cli_nt->tree, "<", NULL, NULL, NULL);
494 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
495 status = smbcli_getatr(cli_dos->tree, "<", NULL, NULL, NULL);
496 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
498 status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
499 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
500 status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
501 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
503 /* Try the same set with openX. */
505 status = raw_smbcli_open(cli_nt->tree, "..", O_RDONLY, DENY_NONE, NULL);
506 CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
507 status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
508 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
510 status = raw_smbcli_open(cli_nt->tree, ".", O_RDONLY, DENY_NONE, NULL);
511 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
512 status = raw_smbcli_open(cli_dos->tree, ".", O_RDONLY, DENY_NONE, NULL);
513 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
515 status = raw_smbcli_open(cli_nt->tree, "\t", O_RDONLY, DENY_NONE, NULL);
516 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
517 status = raw_smbcli_open(cli_dos->tree, "\t", O_RDONLY, DENY_NONE, NULL);
518 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
520 status = raw_smbcli_open(cli_nt->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
521 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
522 status = raw_smbcli_open(cli_dos->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
523 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
525 status = raw_smbcli_open(cli_nt->tree, "<", O_RDONLY, DENY_NONE, NULL);
526 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
527 status = raw_smbcli_open(cli_dos->tree, "<", O_RDONLY, DENY_NONE, NULL);
528 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
530 status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
531 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
532 status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
533 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
535 /* Let's test EEXIST error code mapping. */
536 status = raw_smbcli_open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
537 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
538 status = raw_smbcli_open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
539 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
541 status = raw_smbcli_t2open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
542 if (!NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
543 || !torture_setting_bool(torture, "samba3", false)) {
544 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
545 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
547 status = raw_smbcli_t2open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
548 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,ERReasnotsupported))
549 || !torture_setting_bool(torture, "samba3", false)) {
550 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
551 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
554 status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
555 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
556 status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
557 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
559 /* Try the rename test. */
562 memset(&io, '\0', sizeof(io));
563 io.rename.in.pattern1 = fpath1;
564 io.rename.in.pattern2 = fpath;
566 /* Try with SMBmv rename. */
567 status = smb_raw_rename(cli_nt->tree, &io);
568 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
569 status = smb_raw_rename(cli_dos->tree, &io);
570 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));
572 /* Try with NT rename. */
573 io.generic.level = RAW_RENAME_NTRENAME;
574 io.ntrename.in.old_name = fpath1;
575 io.ntrename.in.new_name = fpath;
576 io.ntrename.in.attrib = 0;
577 io.ntrename.in.cluster_size = 0;
578 io.ntrename.in.flags = RENAME_FLAG_RENAME;
580 status = smb_raw_rename(cli_nt->tree, &io);
581 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
582 status = smb_raw_rename(cli_dos->tree, &io);
583 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));
592 if (cli_nt != NULL) {
593 smbcli_deltree(cli_nt->tree, dirname);
594 torture_close_connection(cli_nt);
596 if (cli_dos != NULL) {
597 torture_close_connection(cli_dos);
599 talloc_free(mem_ctx);
604 static void count_fn(struct clilist_file_info *info, const char *name,
607 int *counter = (int *)private_data;
611 bool torture_samba3_caseinsensitive(struct torture_context *torture)
613 struct smbcli_state *cli;
616 const char *dirname = "insensitive";
617 const char *ucase_dirname = "InSeNsItIvE";
618 const char *fname = "foo";
624 if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) {
625 d_printf("talloc_init failed\n");
629 if (!torture_open_connection(&cli, 0)) {
633 smbcli_deltree(cli->tree, dirname);
635 status = smbcli_mkdir(cli->tree, dirname);
636 if (!NT_STATUS_IS_OK(status)) {
637 d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
641 if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
644 fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
646 d_printf("Could not create file %s: %s\n", fpath,
647 smbcli_errstr(cli->tree));
650 smbcli_close(cli->tree, fnum);
652 smbcli_list(cli->tree, talloc_asprintf(
653 mem_ctx, "%s\\*", ucase_dirname),
654 FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN
655 |FILE_ATTRIBUTE_SYSTEM,
656 count_fn, (void *)&counter);
662 d_fprintf(stderr, "expected 3 entries, got %d\n", counter);
667 talloc_free(mem_ctx);
672 * Check that Samba3 correctly deals with conflicting posix byte range locks
673 * on an underlying file
676 bool torture_samba3_posixtimedlock(struct torture_context *tctx)
678 struct smbcli_state *cli;
681 const char *dirname = "posixlock";
682 const char *fname = "locked";
684 const char *localdir;
685 const char *localname;
689 struct flock posix_lock;
692 struct smb_lock_entry lock_entry;
693 struct smbcli_request *req;
695 if (!torture_open_connection(&cli, 0)) {
700 smbcli_deltree(cli->tree, dirname);
702 status = smbcli_mkdir(cli->tree, dirname);
703 if (!NT_STATUS_IS_OK(status)) {
704 torture_warning(tctx, "smbcli_mkdir failed: %s\n",
710 if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
711 torture_warning(tctx, "talloc failed\n");
715 fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
717 torture_warning(tctx, "Could not create file %s: %s\n", fpath,
718 smbcli_errstr(cli->tree));
723 if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
724 torture_warning(tctx, "Need 'localdir' setting\n");
729 if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
731 torture_warning(tctx, "talloc failed\n");
737 * Lock a byte range from posix
740 fd = open(localname, O_RDWR);
742 torture_warning(tctx, "open(%s) failed: %s\n",
743 localname, strerror(errno));
747 posix_lock.l_type = F_WRLCK;
748 posix_lock.l_whence = SEEK_SET;
749 posix_lock.l_start = 0;
750 posix_lock.l_len = 1;
752 if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
753 torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
759 * Try a cifs brlock without timeout to see if posix locking = yes
762 io.lockx.in.ulock_cnt = 0;
763 io.lockx.in.lock_cnt = 1;
765 lock_entry.count = 1;
766 lock_entry.offset = 0;
767 lock_entry.pid = cli->tree->session->pid;
769 io.lockx.level = RAW_LOCK_LOCKX;
770 io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
771 io.lockx.in.timeout = 0;
772 io.lockx.in.locks = &lock_entry;
773 io.lockx.in.file.fnum = fnum;
775 status = smb_raw_lock(cli->tree, &io);
778 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
785 * Now fire off a timed brlock, unlock the posix lock and see if the
786 * timed lock gets through.
789 io.lockx.in.timeout = 5000;
791 req = smb_raw_lock_send(cli->tree, &io);
793 torture_warning(tctx, "smb_raw_lock_send failed\n");
799 * Ship the async timed request to the server
801 event_loop_once(req->transport->socket->event.ctx);
806 status = smbcli_request_simple_recv(req);
808 CHECK_STATUS(status, NT_STATUS_OK);
812 smbcli_close(cli->tree, fnum);
817 smbcli_deltree(cli->tree, dirname);
821 bool torture_samba3_rootdirfid(struct torture_context *tctx)
823 struct smbcli_state *cli;
827 const char *fname = "testfile";
830 if (!torture_open_connection(&cli, 0)) {
835 smbcli_unlink(cli->tree, fname);
837 io.generic.level = RAW_OPEN_NTCREATEX;
838 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
839 io.ntcreatex.in.root_fid = 0;
840 io.ntcreatex.in.security_flags = 0;
841 io.ntcreatex.in.access_mask =
842 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
843 io.ntcreatex.in.alloc_size = 0;
844 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
845 io.ntcreatex.in.share_access =
846 NTCREATEX_SHARE_ACCESS_READ
847 | NTCREATEX_SHARE_ACCESS_READ;
848 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
849 io.ntcreatex.in.create_options = 0;
850 io.ntcreatex.in.fname = "\\";
851 status = smb_raw_open(cli->tree, tctx, &io);
852 if (!NT_STATUS_IS_OK(status)) {
853 d_printf("smb_open on the directory failed: %s\n",
858 dnum = io.ntcreatex.out.file.fnum;
860 io.ntcreatex.in.flags =
861 NTCREATEX_FLAGS_REQUEST_OPLOCK
862 | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
863 io.ntcreatex.in.root_fid = dnum;
864 io.ntcreatex.in.security_flags = 0;
865 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
866 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
867 io.ntcreatex.in.alloc_size = 0;
868 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
869 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
870 io.ntcreatex.in.create_options = 0;
871 io.ntcreatex.in.fname = fname;
873 status = smb_raw_open(cli->tree, tctx, &io);
874 if (!NT_STATUS_IS_OK(status)) {
875 d_printf("smb_open on the file %s failed: %s\n",
876 fname, nt_errstr(status));
881 smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
882 smbcli_close(cli->tree, dnum);
883 smbcli_unlink(cli->tree, fname);