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 "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"
31
#define CHECK_STATUS(status, correct) do { \
32
if (!NT_STATUS_EQUAL(status, correct)) { \
33
printf("(%s) Incorrect status %s - should be %s\n", \
34
__location__, nt_errstr(status), nt_errstr(correct)); \
39
bool torture_samba3_checkfsp(struct torture_context *torture)
41
struct smbcli_state *cli;
42
const char *fname = "test.txt";
43
const char *dirname = "testdir";
50
struct smbcli_tree *tree2;
52
if ((mem_ctx = talloc_init("torture_samba3_checkfsp")) == NULL) {
53
d_printf("talloc_init failed\n");
57
if (!torture_open_connection_share(
58
torture, &cli, torture, torture_setting_string(torture, "host", NULL),
59
torture_setting_string(torture, "share", NULL), torture->ev)) {
60
d_printf("torture_open_connection_share failed\n");
65
smbcli_deltree(cli->tree, dirname);
67
status = torture_second_tcon(torture, cli->session,
68
torture_setting_string(torture, "share", NULL),
70
CHECK_STATUS(status, NT_STATUS_OK);
71
if (!NT_STATUS_IS_OK(status))
74
/* Try a read on an invalid FID */
76
nread = smbcli_read(cli->tree, 4711, buf, 0, sizeof(buf));
77
CHECK_STATUS(smbcli_nt_error(cli->tree), NT_STATUS_INVALID_HANDLE);
79
/* Try a read on a directory handle */
81
status = smbcli_mkdir(cli->tree, dirname);
82
if (!NT_STATUS_IS_OK(status)) {
83
d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
88
/* Open the directory */
91
io.generic.level = RAW_OPEN_NTCREATEX;
92
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
93
io.ntcreatex.in.root_fid = 0;
94
io.ntcreatex.in.security_flags = 0;
95
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
96
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
97
io.ntcreatex.in.alloc_size = 0;
98
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
99
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
100
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
101
io.ntcreatex.in.create_options = 0;
102
io.ntcreatex.in.fname = dirname;
103
status = smb_raw_open(cli->tree, mem_ctx, &io);
104
if (!NT_STATUS_IS_OK(status)) {
105
d_printf("smb_open on the directory failed: %s\n",
110
fnum = io.ntcreatex.out.file.fnum;
113
/* Try a read on the directory */
115
nread = smbcli_read(cli->tree, fnum, buf, 0, sizeof(buf));
117
d_printf("smbcli_read on a directory succeeded, expected "
122
CHECK_STATUS(smbcli_nt_error(cli->tree),
123
NT_STATUS_INVALID_DEVICE_REQUEST);
125
/* Same test on the second tcon */
127
nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
129
d_printf("smbcli_read on a directory succeeded, expected "
134
CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
136
smbcli_close(cli->tree, fnum);
138
/* Try a normal file read on a second tcon */
140
fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
142
d_printf("Failed to create %s - %s\n", fname,
143
smbcli_errstr(cli->tree));
148
nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
149
CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
151
smbcli_close(cli->tree, fnum);
154
smbcli_deltree(cli->tree, dirname);
155
torture_close_connection(cli);
156
talloc_free(mem_ctx);
161
static NTSTATUS raw_smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
163
union smb_open open_parms;
169
mem_ctx = talloc_init("raw_open");
170
if (!mem_ctx) return NT_STATUS_NO_MEMORY;
172
if (flags & O_CREAT) {
173
openfn |= OPENX_OPEN_FUNC_CREATE;
175
if (!(flags & O_EXCL)) {
176
if (flags & O_TRUNC) {
177
openfn |= OPENX_OPEN_FUNC_TRUNC;
179
openfn |= OPENX_OPEN_FUNC_OPEN;
183
accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
185
if ((flags & O_ACCMODE) == O_RDWR) {
186
accessmode |= OPENX_MODE_ACCESS_RDWR;
187
} else if ((flags & O_ACCMODE) == O_WRONLY) {
188
accessmode |= OPENX_MODE_ACCESS_WRITE;
189
} else if ((flags & O_ACCMODE) == O_RDONLY) {
190
accessmode |= OPENX_MODE_ACCESS_READ;
194
if ((flags & O_SYNC) == O_SYNC) {
195
accessmode |= OPENX_MODE_WRITE_THRU;
199
if (share_mode == DENY_FCB) {
200
accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
203
open_parms.openx.level = RAW_OPEN_OPENX;
204
open_parms.openx.in.flags = 0;
205
open_parms.openx.in.open_mode = accessmode;
206
open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
207
open_parms.openx.in.file_attrs = 0;
208
open_parms.openx.in.write_time = 0;
209
open_parms.openx.in.open_func = openfn;
210
open_parms.openx.in.size = 0;
211
open_parms.openx.in.timeout = 0;
212
open_parms.openx.in.fname = fname;
214
status = smb_raw_open(tree, mem_ctx, &open_parms);
215
talloc_free(mem_ctx);
217
if (fnum && NT_STATUS_IS_OK(status)) {
218
*fnum = open_parms.openx.out.file.fnum;
224
static NTSTATUS raw_smbcli_t2open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
232
mem_ctx = talloc_init("raw_t2open");
233
if (!mem_ctx) return NT_STATUS_NO_MEMORY;
235
if (flags & O_CREAT) {
236
openfn |= OPENX_OPEN_FUNC_CREATE;
238
if (!(flags & O_EXCL)) {
239
if (flags & O_TRUNC) {
240
openfn |= OPENX_OPEN_FUNC_TRUNC;
242
openfn |= OPENX_OPEN_FUNC_OPEN;
246
accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
248
if ((flags & O_ACCMODE) == O_RDWR) {
249
accessmode |= OPENX_MODE_ACCESS_RDWR;
250
} else if ((flags & O_ACCMODE) == O_WRONLY) {
251
accessmode |= OPENX_MODE_ACCESS_WRITE;
252
} else if ((flags & O_ACCMODE) == O_RDONLY) {
253
accessmode |= OPENX_MODE_ACCESS_READ;
257
if ((flags & O_SYNC) == O_SYNC) {
258
accessmode |= OPENX_MODE_WRITE_THRU;
262
if (share_mode == DENY_FCB) {
263
accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
266
memset(&io, '\0', sizeof(io));
267
io.t2open.level = RAW_OPEN_T2OPEN;
268
io.t2open.in.flags = 0;
269
io.t2open.in.open_mode = accessmode;
270
io.t2open.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
271
io.t2open.in.file_attrs = 0;
272
io.t2open.in.write_time = 0;
273
io.t2open.in.open_func = openfn;
274
io.t2open.in.size = 0;
275
io.t2open.in.timeout = 0;
276
io.t2open.in.fname = fname;
278
io.t2open.in.num_eas = 1;
279
io.t2open.in.eas = talloc_array(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
280
io.t2open.in.eas[0].flags = 0;
281
io.t2open.in.eas[0].name.s = ".CLASSINFO";
282
io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
284
status = smb_raw_open(tree, mem_ctx, &io);
285
talloc_free(mem_ctx);
287
if (fnum && NT_STATUS_IS_OK(status)) {
288
*fnum = io.openx.out.file.fnum;
294
static NTSTATUS raw_smbcli_ntcreate(struct smbcli_tree *tree, const char *fname, int *fnum)
300
mem_ctx = talloc_init("raw_t2open");
301
if (!mem_ctx) return NT_STATUS_NO_MEMORY;
303
memset(&io, '\0', sizeof(io));
304
io.generic.level = RAW_OPEN_NTCREATEX;
305
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
306
io.ntcreatex.in.root_fid = 0;
307
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
308
io.ntcreatex.in.alloc_size = 0;
309
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
310
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
311
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
312
io.ntcreatex.in.create_options = 0;
313
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
314
io.ntcreatex.in.security_flags = 0;
315
io.ntcreatex.in.fname = fname;
317
status = smb_raw_open(tree, mem_ctx, &io);
318
talloc_free(mem_ctx);
320
if (fnum && NT_STATUS_IS_OK(status)) {
321
*fnum = io.openx.out.file.fnum;
328
bool torture_samba3_badpath(struct torture_context *torture)
330
struct smbcli_state *cli_nt;
331
struct smbcli_state *cli_dos;
332
const char *fname = "test.txt";
333
const char *fname1 = "test1.txt";
334
const char *dirname = "testdir";
341
bool nt_status_support;
343
if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
344
d_printf("talloc_init failed\n");
348
nt_status_support = lp_nt_status_support(torture->lp_ctx);
350
if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "yes")) {
351
printf("Could not set 'nt status support = yes'\n");
355
if (!torture_open_connection(&cli_nt, torture, 0)) {
359
if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "no")) {
360
printf("Could not set 'nt status support = yes'\n");
364
if (!torture_open_connection(&cli_dos, torture, 1)) {
368
if (!lp_set_cmdline(torture->lp_ctx, "nt status support",
369
nt_status_support ? "yes":"no")) {
370
printf("Could not reset 'nt status support = yes'");
374
smbcli_deltree(cli_nt->tree, dirname);
376
status = smbcli_mkdir(cli_nt->tree, dirname);
377
if (!NT_STATUS_IS_OK(status)) {
378
d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
383
status = smbcli_chkpath(cli_nt->tree, dirname);
384
CHECK_STATUS(status, NT_STATUS_OK);
386
status = smbcli_chkpath(cli_nt->tree,
387
talloc_asprintf(mem_ctx, "%s\\bla", dirname));
388
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
390
status = smbcli_chkpath(cli_dos->tree,
391
talloc_asprintf(mem_ctx, "%s\\bla", dirname));
392
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
394
status = smbcli_chkpath(cli_nt->tree,
395
talloc_asprintf(mem_ctx, "%s\\bla\\blub",
397
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
398
status = smbcli_chkpath(cli_dos->tree,
399
talloc_asprintf(mem_ctx, "%s\\bla\\blub",
401
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
403
if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
406
fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
408
d_printf("Could not create file %s: %s\n", fpath,
409
smbcli_errstr(cli_nt->tree));
412
smbcli_close(cli_nt->tree, fnum);
414
if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
417
fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
419
d_printf("Could not create file %s: %s\n", fpath1,
420
smbcli_errstr(cli_nt->tree));
423
smbcli_close(cli_nt->tree, fnum);
426
* Do a whole bunch of error code checks on chkpath
429
status = smbcli_chkpath(cli_nt->tree, fpath);
430
CHECK_STATUS(status, NT_STATUS_NOT_A_DIRECTORY);
431
status = smbcli_chkpath(cli_dos->tree, fpath);
432
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
434
status = smbcli_chkpath(cli_nt->tree, "..");
435
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
436
status = smbcli_chkpath(cli_dos->tree, "..");
437
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
439
status = smbcli_chkpath(cli_nt->tree, ".");
440
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
441
status = smbcli_chkpath(cli_dos->tree, ".");
442
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
444
status = smbcli_chkpath(cli_nt->tree, "\t");
445
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
446
status = smbcli_chkpath(cli_dos->tree, "\t");
447
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
449
status = smbcli_chkpath(cli_nt->tree, "\t\\bla");
450
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
451
status = smbcli_chkpath(cli_dos->tree, "\t\\bla");
452
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
454
status = smbcli_chkpath(cli_nt->tree, "<");
455
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
456
status = smbcli_chkpath(cli_dos->tree, "<");
457
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
459
status = smbcli_chkpath(cli_nt->tree, "<\\bla");
460
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
461
status = smbcli_chkpath(cli_dos->tree, "<\\bla");
462
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
465
* .... And the same gang against getatr. Note that the DOS error codes
469
status = smbcli_getatr(cli_nt->tree, fpath, NULL, NULL, NULL);
470
CHECK_STATUS(status, NT_STATUS_OK);
471
status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
472
CHECK_STATUS(status, NT_STATUS_OK);
474
status = smbcli_getatr(cli_nt->tree, "..", NULL, NULL, NULL);
475
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
476
status = smbcli_getatr(cli_dos->tree, "..", NULL, NULL, NULL);
477
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
479
status = smbcli_getatr(cli_nt->tree, ".", NULL, NULL, NULL);
480
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
481
status = smbcli_getatr(cli_dos->tree, ".", NULL, NULL, NULL);
482
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
484
status = smbcli_getatr(cli_nt->tree, "\t", NULL, NULL, NULL);
485
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
486
status = smbcli_getatr(cli_dos->tree, "\t", NULL, NULL, NULL);
487
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
489
status = smbcli_getatr(cli_nt->tree, "\t\\bla", NULL, NULL, NULL);
490
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
491
status = smbcli_getatr(cli_dos->tree, "\t\\bla", NULL, NULL, NULL);
492
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
494
status = smbcli_getatr(cli_nt->tree, "<", NULL, NULL, NULL);
495
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
496
status = smbcli_getatr(cli_dos->tree, "<", NULL, NULL, NULL);
497
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
499
status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
500
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
501
status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
502
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
504
/* Try the same set with openX. */
506
status = raw_smbcli_open(cli_nt->tree, "..", O_RDONLY, DENY_NONE, NULL);
507
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
508
status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
509
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
511
status = raw_smbcli_open(cli_nt->tree, ".", O_RDONLY, DENY_NONE, NULL);
512
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
513
status = raw_smbcli_open(cli_dos->tree, ".", O_RDONLY, DENY_NONE, NULL);
514
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
516
status = raw_smbcli_open(cli_nt->tree, "\t", O_RDONLY, DENY_NONE, NULL);
517
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
518
status = raw_smbcli_open(cli_dos->tree, "\t", O_RDONLY, DENY_NONE, NULL);
519
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
521
status = raw_smbcli_open(cli_nt->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
522
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
523
status = raw_smbcli_open(cli_dos->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
524
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
526
status = raw_smbcli_open(cli_nt->tree, "<", O_RDONLY, DENY_NONE, NULL);
527
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
528
status = raw_smbcli_open(cli_dos->tree, "<", O_RDONLY, DENY_NONE, NULL);
529
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
531
status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
532
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
533
status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
534
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
536
/* Let's test EEXIST error code mapping. */
537
status = raw_smbcli_open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
538
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
539
status = raw_smbcli_open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
540
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
542
status = raw_smbcli_t2open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
543
if (!NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
544
|| !torture_setting_bool(torture, "samba3", false)) {
545
/* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
546
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
548
status = raw_smbcli_t2open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
549
if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,ERReasnotsupported))
550
|| !torture_setting_bool(torture, "samba3", false)) {
551
/* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
552
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
555
status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
556
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
557
status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
558
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
560
/* Try the rename test. */
563
memset(&io, '\0', sizeof(io));
564
io.rename.in.pattern1 = fpath1;
565
io.rename.in.pattern2 = fpath;
567
/* Try with SMBmv rename. */
568
status = smb_raw_rename(cli_nt->tree, &io);
569
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
570
status = smb_raw_rename(cli_dos->tree, &io);
571
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));
573
/* Try with NT rename. */
574
io.generic.level = RAW_RENAME_NTRENAME;
575
io.ntrename.in.old_name = fpath1;
576
io.ntrename.in.new_name = fpath;
577
io.ntrename.in.attrib = 0;
578
io.ntrename.in.cluster_size = 0;
579
io.ntrename.in.flags = RENAME_FLAG_RENAME;
581
status = smb_raw_rename(cli_nt->tree, &io);
582
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
583
status = smb_raw_rename(cli_dos->tree, &io);
584
CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));
593
if (cli_nt != NULL) {
594
smbcli_deltree(cli_nt->tree, dirname);
595
torture_close_connection(cli_nt);
597
if (cli_dos != NULL) {
598
torture_close_connection(cli_dos);
600
talloc_free(mem_ctx);
605
static void count_fn(struct clilist_file_info *info, const char *name,
608
int *counter = (int *)private_data;
612
bool torture_samba3_caseinsensitive(struct torture_context *torture)
614
struct smbcli_state *cli;
617
const char *dirname = "insensitive";
618
const char *ucase_dirname = "InSeNsItIvE";
619
const char *fname = "foo";
625
if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) {
626
d_printf("talloc_init failed\n");
630
if (!torture_open_connection(&cli, torture, 0)) {
634
smbcli_deltree(cli->tree, dirname);
636
status = smbcli_mkdir(cli->tree, dirname);
637
if (!NT_STATUS_IS_OK(status)) {
638
d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
642
if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
645
fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
647
d_printf("Could not create file %s: %s\n", fpath,
648
smbcli_errstr(cli->tree));
651
smbcli_close(cli->tree, fnum);
653
smbcli_list(cli->tree, talloc_asprintf(
654
mem_ctx, "%s\\*", ucase_dirname),
655
FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN
656
|FILE_ATTRIBUTE_SYSTEM,
657
count_fn, (void *)&counter);
663
d_fprintf(stderr, "expected 3 entries, got %d\n", counter);
668
talloc_free(mem_ctx);
673
* Check that Samba3 correctly deals with conflicting posix byte range locks
674
* on an underlying file
676
* Note: This test depends on "posix locking = yes".
677
* Note: To run this test, use "--option=torture:localdir=<LOCALDIR>"
680
bool torture_samba3_posixtimedlock(struct torture_context *tctx)
682
struct smbcli_state *cli;
685
const char *dirname = "posixlock";
686
const char *fname = "locked";
688
const char *localdir;
689
const char *localname;
693
struct flock posix_lock;
696
struct smb_lock_entry lock_entry;
697
struct smbcli_request *req;
699
if (!torture_open_connection(&cli, tctx, 0)) {
704
smbcli_deltree(cli->tree, dirname);
706
status = smbcli_mkdir(cli->tree, dirname);
707
if (!NT_STATUS_IS_OK(status)) {
708
torture_warning(tctx, "smbcli_mkdir failed: %s\n",
714
if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
715
torture_warning(tctx, "talloc failed\n");
719
fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
721
torture_warning(tctx, "Could not create file %s: %s\n", fpath,
722
smbcli_errstr(cli->tree));
727
if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
728
torture_warning(tctx, "Need 'localdir' setting\n");
733
if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
735
torture_warning(tctx, "talloc failed\n");
741
* Lock a byte range from posix
744
fd = open(localname, O_RDWR);
746
torture_warning(tctx, "open(%s) failed: %s\n",
747
localname, strerror(errno));
751
posix_lock.l_type = F_WRLCK;
752
posix_lock.l_whence = SEEK_SET;
753
posix_lock.l_start = 0;
754
posix_lock.l_len = 1;
756
if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
757
torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
763
* Try a cifs brlock without timeout to see if posix locking = yes
766
io.lockx.in.ulock_cnt = 0;
767
io.lockx.in.lock_cnt = 1;
769
lock_entry.count = 1;
770
lock_entry.offset = 0;
771
lock_entry.pid = cli->tree->session->pid;
773
io.lockx.level = RAW_LOCK_LOCKX;
774
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
775
io.lockx.in.timeout = 0;
776
io.lockx.in.locks = &lock_entry;
777
io.lockx.in.file.fnum = fnum;
779
status = smb_raw_lock(cli->tree, &io);
782
CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
789
* Now fire off a timed brlock, unlock the posix lock and see if the
790
* timed lock gets through.
793
io.lockx.in.timeout = 5000;
795
req = smb_raw_lock_send(cli->tree, &io);
797
torture_warning(tctx, "smb_raw_lock_send failed\n");
803
* Ship the async timed request to the server
805
event_loop_once(req->transport->socket->event.ctx);
810
status = smbcli_request_simple_recv(req);
812
CHECK_STATUS(status, NT_STATUS_OK);
816
smbcli_close(cli->tree, fnum);
821
smbcli_deltree(cli->tree, dirname);
825
bool torture_samba3_rootdirfid(struct torture_context *tctx)
827
struct smbcli_state *cli;
831
const char *fname = "testfile";
834
if (!torture_open_connection(&cli, tctx, 0)) {
839
smbcli_unlink(cli->tree, fname);
842
io.generic.level = RAW_OPEN_NTCREATEX;
843
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
844
io.ntcreatex.in.root_fid = 0;
845
io.ntcreatex.in.security_flags = 0;
846
io.ntcreatex.in.access_mask =
847
SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
848
io.ntcreatex.in.alloc_size = 0;
849
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
850
io.ntcreatex.in.share_access =
851
NTCREATEX_SHARE_ACCESS_READ
852
| NTCREATEX_SHARE_ACCESS_READ;
853
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
854
io.ntcreatex.in.create_options = 0;
855
io.ntcreatex.in.fname = "\\";
856
status = smb_raw_open(cli->tree, tctx, &io);
857
if (!NT_STATUS_IS_OK(status)) {
858
d_printf("smb_open on the directory failed: %s\n",
863
dnum = io.ntcreatex.out.file.fnum;
865
io.ntcreatex.in.flags =
866
NTCREATEX_FLAGS_REQUEST_OPLOCK
867
| NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
868
io.ntcreatex.in.root_fid = dnum;
869
io.ntcreatex.in.security_flags = 0;
870
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
871
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
872
io.ntcreatex.in.alloc_size = 0;
873
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
874
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
875
io.ntcreatex.in.create_options = 0;
876
io.ntcreatex.in.fname = fname;
878
status = smb_raw_open(cli->tree, tctx, &io);
879
if (!NT_STATUS_IS_OK(status)) {
880
d_printf("smb_open on the file %s failed: %s\n",
881
fname, nt_errstr(status));
886
smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
887
smbcli_close(cli->tree, dnum);
888
smbcli_unlink(cli->tree, fname);
895
bool torture_samba3_oplock_logoff(struct torture_context *tctx)
897
struct smbcli_state *cli;
901
const char *fname = "testfile";
903
struct smbcli_request *req;
904
struct smb_echo echo_req;
906
if (!torture_open_connection(&cli, tctx, 0)) {
911
smbcli_unlink(cli->tree, fname);
914
io.generic.level = RAW_OPEN_NTCREATEX;
915
io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
916
io.ntcreatex.in.root_fid = 0;
917
io.ntcreatex.in.security_flags = 0;
918
io.ntcreatex.in.access_mask =
919
SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
920
io.ntcreatex.in.alloc_size = 0;
921
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
922
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
923
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
924
io.ntcreatex.in.create_options = 0;
925
io.ntcreatex.in.fname = "testfile";
926
status = smb_raw_open(cli->tree, tctx, &io);
927
if (!NT_STATUS_IS_OK(status)) {
928
d_printf("first smb_open failed: %s\n", nt_errstr(status));
932
fnum1 = io.ntcreatex.out.file.fnum;
935
* Create a conflicting open, causing the one-second delay
938
req = smb_raw_open_send(cli->tree, &io);
940
d_printf("smb_raw_open_send failed\n");
946
* Pull the VUID from under that request. As of Nov 3, 2008 all Samba3
947
* versions (3.0, 3.2 and master) would spin sending ERRinvuid errors
948
* as long as the client is still connected.
951
status = smb_raw_ulogoff(cli->session);
953
if (!NT_STATUS_IS_OK(status)) {
954
d_printf("ulogoff failed: %s\n", nt_errstr(status));
959
echo_req.in.repeat_count = 1;
960
echo_req.in.size = 1;
961
echo_req.in.data = (uint8_t *)"";
963
status = smb_raw_echo(cli->session->transport, &echo_req);
964
if (!NT_STATUS_IS_OK(status)) {
965
d_printf("smb_raw_echo returned %s\n",