~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/raw/samba3misc.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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)); \
 
35
                ret = false; \
 
36
        } \
 
37
} while (0)
 
38
 
 
39
bool torture_samba3_checkfsp(struct torture_context *torture)
 
40
{
 
41
        struct smbcli_state *cli;
 
42
        const char *fname = "test.txt";
 
43
        const char *dirname = "testdir";
 
44
        int fnum;
 
45
        NTSTATUS status;
 
46
        bool ret = true;
 
47
        TALLOC_CTX *mem_ctx;
 
48
        ssize_t nread;
 
49
        char buf[16];
 
50
        struct smbcli_tree *tree2;
 
51
 
 
52
        if ((mem_ctx = talloc_init("torture_samba3_checkfsp")) == NULL) {
 
53
                d_printf("talloc_init failed\n");
 
54
                return false;
 
55
        }
 
56
 
 
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");
 
61
                ret = false;
 
62
                goto done;
 
63
        }
 
64
 
 
65
        smbcli_deltree(cli->tree, dirname);
 
66
 
 
67
        status = torture_second_tcon(torture, cli->session,
 
68
                                     torture_setting_string(torture, "share", NULL),
 
69
                                     &tree2);
 
70
        CHECK_STATUS(status, NT_STATUS_OK);
 
71
        if (!NT_STATUS_IS_OK(status))
 
72
                goto done;
 
73
 
 
74
        /* Try a read on an invalid FID */
 
75
 
 
76
        nread = smbcli_read(cli->tree, 4711, buf, 0, sizeof(buf));
 
77
        CHECK_STATUS(smbcli_nt_error(cli->tree), NT_STATUS_INVALID_HANDLE);
 
78
 
 
79
        /* Try a read on a directory handle */
 
80
 
 
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));
 
84
                ret = false;
 
85
                goto done;
 
86
        }
 
87
 
 
88
        /* Open the directory */
 
89
        {
 
90
                union smb_open io;
 
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",
 
106
                                 nt_errstr(status));
 
107
                        ret = false;
 
108
                        goto done;
 
109
                }
 
110
                fnum = io.ntcreatex.out.file.fnum;
 
111
        }
 
112
 
 
113
        /* Try a read on the directory */
 
114
 
 
115
        nread = smbcli_read(cli->tree, fnum, buf, 0, sizeof(buf));
 
116
        if (nread >= 0) {
 
117
                d_printf("smbcli_read on a directory succeeded, expected "
 
118
                         "failure\n");
 
119
                ret = false;
 
120
        }
 
121
 
 
122
        CHECK_STATUS(smbcli_nt_error(cli->tree),
 
123
                     NT_STATUS_INVALID_DEVICE_REQUEST);
 
124
 
 
125
        /* Same test on the second tcon */
 
126
 
 
127
        nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
 
128
        if (nread >= 0) {
 
129
                d_printf("smbcli_read on a directory succeeded, expected "
 
130
                         "failure\n");
 
131
                ret = false;
 
132
        }
 
133
 
 
134
        CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
 
135
 
 
136
        smbcli_close(cli->tree, fnum);
 
137
 
 
138
        /* Try a normal file read on a second tcon */
 
139
 
 
140
        fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 
141
        if (fnum == -1) {
 
142
                d_printf("Failed to create %s - %s\n", fname,
 
143
                         smbcli_errstr(cli->tree));
 
144
                ret = false;
 
145
                goto done;
 
146
        }
 
147
 
 
148
        nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
 
149
        CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
 
150
 
 
151
        smbcli_close(cli->tree, fnum);
 
152
 
 
153
 done:
 
154
        smbcli_deltree(cli->tree, dirname);
 
155
        torture_close_connection(cli);
 
156
        talloc_free(mem_ctx);
 
157
 
 
158
        return ret;
 
159
}
 
160
 
 
161
static NTSTATUS raw_smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
 
162
{
 
163
        union smb_open open_parms;
 
164
        uint_t openfn=0;
 
165
        uint_t accessmode=0;
 
166
        TALLOC_CTX *mem_ctx;
 
167
        NTSTATUS status;
 
168
 
 
169
        mem_ctx = talloc_init("raw_open");
 
170
        if (!mem_ctx) return NT_STATUS_NO_MEMORY;
 
171
 
 
172
        if (flags & O_CREAT) {
 
173
                openfn |= OPENX_OPEN_FUNC_CREATE;
 
174
        }
 
175
        if (!(flags & O_EXCL)) {
 
176
                if (flags & O_TRUNC) {
 
177
                        openfn |= OPENX_OPEN_FUNC_TRUNC;
 
178
                } else {
 
179
                        openfn |= OPENX_OPEN_FUNC_OPEN;
 
180
                }
 
181
        }
 
182
 
 
183
        accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
 
184
 
 
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;
 
191
        }
 
192
 
 
193
#if defined(O_SYNC)
 
194
        if ((flags & O_SYNC) == O_SYNC) {
 
195
                accessmode |= OPENX_MODE_WRITE_THRU;
 
196
        }
 
197
#endif
 
198
 
 
199
        if (share_mode == DENY_FCB) {
 
200
                accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
 
201
        }
 
202
 
 
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;
 
213
 
 
214
        status = smb_raw_open(tree, mem_ctx, &open_parms);
 
215
        talloc_free(mem_ctx);
 
216
 
 
217
        if (fnum && NT_STATUS_IS_OK(status)) {
 
218
                *fnum = open_parms.openx.out.file.fnum;
 
219
        }
 
220
 
 
221
        return status;
 
222
}
 
223
 
 
224
static NTSTATUS raw_smbcli_t2open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
 
225
{
 
226
        union smb_open io;
 
227
        uint_t openfn=0;
 
228
        uint_t accessmode=0;
 
229
        TALLOC_CTX *mem_ctx;
 
230
        NTSTATUS status;
 
231
 
 
232
        mem_ctx = talloc_init("raw_t2open");
 
233
        if (!mem_ctx) return NT_STATUS_NO_MEMORY;
 
234
 
 
235
        if (flags & O_CREAT) {
 
236
                openfn |= OPENX_OPEN_FUNC_CREATE;
 
237
        }
 
238
        if (!(flags & O_EXCL)) {
 
239
                if (flags & O_TRUNC) {
 
240
                        openfn |= OPENX_OPEN_FUNC_TRUNC;
 
241
                } else {
 
242
                        openfn |= OPENX_OPEN_FUNC_OPEN;
 
243
                }
 
244
        }
 
245
 
 
246
        accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
 
247
 
 
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;
 
254
        }
 
255
 
 
256
#if defined(O_SYNC)
 
257
        if ((flags & O_SYNC) == O_SYNC) {
 
258
                accessmode |= OPENX_MODE_WRITE_THRU;
 
259
        }
 
260
#endif
 
261
 
 
262
        if (share_mode == DENY_FCB) {
 
263
                accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
 
264
        }
 
265
 
 
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;
 
277
 
 
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);
 
283
 
 
284
        status = smb_raw_open(tree, mem_ctx, &io);
 
285
        talloc_free(mem_ctx);
 
286
 
 
287
        if (fnum && NT_STATUS_IS_OK(status)) {
 
288
                *fnum = io.openx.out.file.fnum;
 
289
        }
 
290
 
 
291
        return status;
 
292
}
 
293
 
 
294
static NTSTATUS raw_smbcli_ntcreate(struct smbcli_tree *tree, const char *fname, int *fnum)
 
295
{
 
296
        union smb_open io;
 
297
        TALLOC_CTX *mem_ctx;
 
298
        NTSTATUS status;
 
299
 
 
300
        mem_ctx = talloc_init("raw_t2open");
 
301
        if (!mem_ctx) return NT_STATUS_NO_MEMORY;
 
302
 
 
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;
 
316
 
 
317
        status = smb_raw_open(tree, mem_ctx, &io);
 
318
        talloc_free(mem_ctx);
 
319
 
 
320
        if (fnum && NT_STATUS_IS_OK(status)) {
 
321
                *fnum = io.openx.out.file.fnum;
 
322
        }
 
323
 
 
324
        return status;
 
325
}
 
326
 
 
327
 
 
328
bool torture_samba3_badpath(struct torture_context *torture)
 
329
{
 
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";
 
335
        char *fpath;
 
336
        char *fpath1;
 
337
        int fnum;
 
338
        NTSTATUS status;
 
339
        bool ret = true;
 
340
        TALLOC_CTX *mem_ctx;
 
341
        bool nt_status_support;
 
342
 
 
343
        if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
 
344
                d_printf("talloc_init failed\n");
 
345
                return false;
 
346
        }
 
347
 
 
348
        nt_status_support = lp_nt_status_support(torture->lp_ctx);
 
349
 
 
350
        if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "yes")) {
 
351
                printf("Could not set 'nt status support = yes'\n");
 
352
                goto fail;
 
353
        }
 
354
 
 
355
        if (!torture_open_connection(&cli_nt, torture, 0)) {
 
356
                goto fail;
 
357
        }
 
358
 
 
359
        if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "no")) {
 
360
                printf("Could not set 'nt status support = yes'\n");
 
361
                goto fail;
 
362
        }
 
363
 
 
364
        if (!torture_open_connection(&cli_dos, torture, 1)) {
 
365
                goto fail;
 
366
        }
 
367
 
 
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'");
 
371
                goto fail;
 
372
        }
 
373
 
 
374
        smbcli_deltree(cli_nt->tree, dirname);
 
375
 
 
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));
 
379
                ret = false;
 
380
                goto done;
 
381
        }
 
382
 
 
383
        status = smbcli_chkpath(cli_nt->tree, dirname);
 
384
        CHECK_STATUS(status, NT_STATUS_OK);
 
385
 
 
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);
 
389
 
 
390
        status = smbcli_chkpath(cli_dos->tree,
 
391
                                talloc_asprintf(mem_ctx, "%s\\bla", dirname));
 
392
        CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 
393
 
 
394
        status = smbcli_chkpath(cli_nt->tree,
 
395
                                talloc_asprintf(mem_ctx, "%s\\bla\\blub",
 
396
                                                dirname));
 
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",
 
400
                                                dirname));
 
401
        CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 
402
 
 
403
        if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
 
404
                goto fail;
 
405
        }
 
406
        fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
 
407
        if (fnum == -1) {
 
408
                d_printf("Could not create file %s: %s\n", fpath,
 
409
                         smbcli_errstr(cli_nt->tree));
 
410
                goto fail;
 
411
        }
 
412
        smbcli_close(cli_nt->tree, fnum);
 
413
 
 
414
        if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
 
415
                goto fail;
 
416
        }
 
417
        fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
 
418
        if (fnum == -1) {
 
419
                d_printf("Could not create file %s: %s\n", fpath1,
 
420
                         smbcli_errstr(cli_nt->tree));
 
421
                goto fail;
 
422
        }
 
423
        smbcli_close(cli_nt->tree, fnum);
 
424
 
 
425
        /*
 
426
         * Do a whole bunch of error code checks on chkpath
 
427
         */
 
428
 
 
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));
 
433
 
 
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));
 
438
 
 
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));
 
443
 
 
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));
 
448
 
 
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));
 
453
 
 
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));
 
458
 
 
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));
 
463
 
 
464
        /*
 
465
         * .... And the same gang against getatr. Note that the DOS error codes
 
466
         * differ....
 
467
         */
 
468
 
 
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);
 
473
 
 
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));
 
478
 
 
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));
 
483
 
 
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));
 
488
 
 
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));
 
493
 
 
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));
 
498
 
 
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));
 
503
 
 
504
        /* Try the same set with openX. */
 
505
 
 
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));
 
510
 
 
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));
 
515
 
 
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));
 
520
 
 
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));
 
525
 
 
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));
 
530
 
 
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));
 
535
 
 
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));
 
541
 
 
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);
 
547
        }
 
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));
 
553
        }
 
554
 
 
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));
 
559
 
 
560
        /* Try the rename test. */
 
561
        {
 
562
                union smb_rename io;
 
563
                memset(&io, '\0', sizeof(io));
 
564
                io.rename.in.pattern1 = fpath1;
 
565
                io.rename.in.pattern2 = fpath;
 
566
 
 
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));
 
572
 
 
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;
 
580
 
 
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));
 
585
        }
 
586
 
 
587
        goto done;
 
588
 
 
589
 fail:
 
590
        ret = false;
 
591
 
 
592
 done:
 
593
        if (cli_nt != NULL) {
 
594
                smbcli_deltree(cli_nt->tree, dirname);
 
595
                torture_close_connection(cli_nt);
 
596
        }
 
597
        if (cli_dos != NULL) {
 
598
                torture_close_connection(cli_dos);
 
599
        }
 
600
        talloc_free(mem_ctx);
 
601
 
 
602
        return ret;
 
603
}
 
604
 
 
605
static void count_fn(struct clilist_file_info *info, const char *name,
 
606
                     void *private_data)
 
607
{
 
608
        int *counter = (int *)private_data;
 
609
        *counter += 1;
 
610
}
 
611
 
 
612
bool torture_samba3_caseinsensitive(struct torture_context *torture)
 
613
{
 
614
        struct smbcli_state *cli;
 
615
        TALLOC_CTX *mem_ctx;
 
616
        NTSTATUS status;
 
617
        const char *dirname = "insensitive";
 
618
        const char *ucase_dirname = "InSeNsItIvE";
 
619
        const char *fname = "foo";
 
620
        char *fpath;
 
621
        int fnum;
 
622
        int counter = 0;
 
623
        bool ret = true;
 
624
 
 
625
        if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) {
 
626
                d_printf("talloc_init failed\n");
 
627
                return false;
 
628
        }
 
629
 
 
630
        if (!torture_open_connection(&cli, torture, 0)) {
 
631
                goto done;
 
632
        }
 
633
 
 
634
        smbcli_deltree(cli->tree, dirname);
 
635
 
 
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));
 
639
                goto done;
 
640
        }
 
641
 
 
642
        if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
 
643
                goto done;
 
644
        }
 
645
        fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
 
646
        if (fnum == -1) {
 
647
                d_printf("Could not create file %s: %s\n", fpath,
 
648
                         smbcli_errstr(cli->tree));
 
649
                goto done;
 
650
        }
 
651
        smbcli_close(cli->tree, fnum);
 
652
 
 
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);
 
658
 
 
659
        if (counter == 3) {
 
660
                ret = true;
 
661
        }
 
662
        else {
 
663
                d_fprintf(stderr, "expected 3 entries, got %d\n", counter);
 
664
                ret = false;
 
665
        }
 
666
 
 
667
 done:
 
668
        talloc_free(mem_ctx);
 
669
        return ret;
 
670
}
 
671
 
 
672
/*
 
673
 * Check that Samba3 correctly deals with conflicting posix byte range locks
 
674
 * on an underlying file
 
675
 *
 
676
 * Note: This test depends on "posix locking = yes".
 
677
 * Note: To run this test, use "--option=torture:localdir=<LOCALDIR>"
 
678
 */
 
679
 
 
680
bool torture_samba3_posixtimedlock(struct torture_context *tctx)
 
681
{
 
682
        struct smbcli_state *cli;
 
683
        NTSTATUS status;
 
684
        bool ret = true;
 
685
        const char *dirname = "posixlock";
 
686
        const char *fname = "locked";
 
687
        const char *fpath;
 
688
        const char *localdir;
 
689
        const char *localname;
 
690
        int fnum = -1;
 
691
 
 
692
        int fd = -1;
 
693
        struct flock posix_lock;
 
694
 
 
695
        union smb_lock io;
 
696
        struct smb_lock_entry lock_entry;
 
697
        struct smbcli_request *req;
 
698
 
 
699
        if (!torture_open_connection(&cli, tctx, 0)) {
 
700
                ret = false;
 
701
                goto done;
 
702
        }
 
703
 
 
704
        smbcli_deltree(cli->tree, dirname);
 
705
 
 
706
        status = smbcli_mkdir(cli->tree, dirname);
 
707
        if (!NT_STATUS_IS_OK(status)) {
 
708
                torture_warning(tctx, "smbcli_mkdir failed: %s\n",
 
709
                                nt_errstr(status));
 
710
                ret = false;
 
711
                goto done;
 
712
        }
 
713
 
 
714
        if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
 
715
                torture_warning(tctx, "talloc failed\n");
 
716
                ret = false;
 
717
                goto done;
 
718
        }
 
719
        fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
 
720
        if (fnum == -1) {
 
721
                torture_warning(tctx, "Could not create file %s: %s\n", fpath,
 
722
                                smbcli_errstr(cli->tree));
 
723
                ret = false;
 
724
                goto done;
 
725
        }
 
726
 
 
727
        if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
 
728
                torture_warning(tctx, "Need 'localdir' setting\n");
 
729
                ret = false;
 
730
                goto done;
 
731
        }
 
732
 
 
733
        if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
 
734
                                          fname))) {
 
735
                torture_warning(tctx, "talloc failed\n");
 
736
                ret = false;
 
737
                goto done;
 
738
        }
 
739
 
 
740
        /*
 
741
         * Lock a byte range from posix
 
742
         */
 
743
 
 
744
        fd = open(localname, O_RDWR);
 
745
        if (fd == -1) {
 
746
                torture_warning(tctx, "open(%s) failed: %s\n",
 
747
                                localname, strerror(errno));
 
748
                goto done;
 
749
        }
 
750
 
 
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;
 
755
 
 
756
        if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
 
757
                torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
 
758
                ret = false;
 
759
                goto done;
 
760
        }
 
761
 
 
762
        /*
 
763
         * Try a cifs brlock without timeout to see if posix locking = yes
 
764
         */
 
765
 
 
766
        io.lockx.in.ulock_cnt = 0;
 
767
        io.lockx.in.lock_cnt = 1;
 
768
 
 
769
        lock_entry.count = 1;
 
770
        lock_entry.offset = 0;
 
771
        lock_entry.pid = cli->tree->session->pid;
 
772
 
 
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;
 
778
 
 
779
        status = smb_raw_lock(cli->tree, &io);
 
780
 
 
781
        ret = true;
 
782
        CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
 
783
 
 
784
        if (!ret) {
 
785
                goto done;
 
786
        }
 
787
 
 
788
        /*
 
789
         * Now fire off a timed brlock, unlock the posix lock and see if the
 
790
         * timed lock gets through.
 
791
         */
 
792
 
 
793
        io.lockx.in.timeout = 5000;
 
794
 
 
795
        req = smb_raw_lock_send(cli->tree, &io);
 
796
        if (req == NULL) {
 
797
                torture_warning(tctx, "smb_raw_lock_send failed\n");
 
798
                ret = false;
 
799
                goto done;
 
800
        }
 
801
 
 
802
        /*
 
803
         * Ship the async timed request to the server
 
804
         */
 
805
        event_loop_once(req->transport->socket->event.ctx);
 
806
        msleep(500);
 
807
 
 
808
        close(fd);
 
809
 
 
810
        status = smbcli_request_simple_recv(req);
 
811
 
 
812
        CHECK_STATUS(status, NT_STATUS_OK);
 
813
 
 
814
 done:
 
815
        if (fnum != -1) {
 
816
                smbcli_close(cli->tree, fnum);
 
817
        }
 
818
        if (fd != -1) {
 
819
                close(fd);
 
820
        }
 
821
        smbcli_deltree(cli->tree, dirname);
 
822
        return ret;
 
823
}
 
824
 
 
825
bool torture_samba3_rootdirfid(struct torture_context *tctx)
 
826
{
 
827
        struct smbcli_state *cli;
 
828
        NTSTATUS status;
 
829
        uint16_t dnum;
 
830
        union smb_open io;
 
831
        const char *fname = "testfile";
 
832
        bool ret = false;
 
833
 
 
834
        if (!torture_open_connection(&cli, tctx, 0)) {
 
835
                ret = false;
 
836
                goto done;
 
837
        }
 
838
 
 
839
        smbcli_unlink(cli->tree, fname);
 
840
 
 
841
        ZERO_STRUCT(io);
 
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",
 
859
                         nt_errstr(status));
 
860
                ret = false;
 
861
                goto done;
 
862
        }
 
863
        dnum = io.ntcreatex.out.file.fnum;
 
864
 
 
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;
 
877
 
 
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));
 
882
                ret = false;
 
883
                goto done;
 
884
        }
 
885
 
 
886
        smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
 
887
        smbcli_close(cli->tree, dnum);
 
888
        smbcli_unlink(cli->tree, fname);
 
889
 
 
890
        ret = true;
 
891
 done:
 
892
        return ret;
 
893
}
 
894
 
 
895
bool torture_samba3_oplock_logoff(struct torture_context *tctx)
 
896
{
 
897
        struct smbcli_state *cli;
 
898
        NTSTATUS status;
 
899
        uint16_t fnum1;
 
900
        union smb_open io;
 
901
        const char *fname = "testfile";
 
902
        bool ret = false;
 
903
        struct smbcli_request *req;
 
904
        struct smb_echo echo_req;
 
905
 
 
906
        if (!torture_open_connection(&cli, tctx, 0)) {
 
907
                ret = false;
 
908
                goto done;
 
909
        }
 
910
 
 
911
        smbcli_unlink(cli->tree, fname);
 
912
 
 
913
        ZERO_STRUCT(io);
 
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));
 
929
                ret = false;
 
930
                goto done;
 
931
        }
 
932
        fnum1 = io.ntcreatex.out.file.fnum;
 
933
 
 
934
        /*
 
935
         * Create a conflicting open, causing the one-second delay
 
936
         */
 
937
 
 
938
        req = smb_raw_open_send(cli->tree, &io);
 
939
        if (req == NULL) {
 
940
                d_printf("smb_raw_open_send failed\n");
 
941
                ret = false;
 
942
                goto done;
 
943
        }
 
944
 
 
945
        /*
 
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.
 
949
         */
 
950
 
 
951
        status = smb_raw_ulogoff(cli->session);
 
952
 
 
953
        if (!NT_STATUS_IS_OK(status)) {
 
954
                d_printf("ulogoff failed: %s\n", nt_errstr(status));
 
955
                ret = false;
 
956
                goto done;
 
957
        }
 
958
 
 
959
        echo_req.in.repeat_count = 1;
 
960
        echo_req.in.size = 1;
 
961
        echo_req.in.data = (uint8_t *)"";
 
962
 
 
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",
 
966
                         nt_errstr(status));
 
967
                ret = false;
 
968
                goto done;
 
969
        }
 
970
 
 
971
        ret = true;
 
972
 done:
 
973
        return ret;
 
974
}