~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/torture/raw/context.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 suite for session setup operations
 
4
   Copyright (C) Andrew Tridgell 2003
 
5
   
 
6
   This program is free software; you can redistribute it and/or modify
 
7
   it under the terms of the GNU General Public License as published by
 
8
   the Free Software Foundation; either version 3 of the License, or
 
9
   (at your option) any later version.
 
10
   
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
   
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include "includes.h"
 
21
#include "torture/torture.h"
 
22
#include "libcli/raw/libcliraw.h"
 
23
#include "libcli/raw/raw_proto.h"
 
24
#include "libcli/composite/composite.h"
 
25
#include "libcli/smb_composite/smb_composite.h"
 
26
#include "lib/cmdline/popt_common.h"
 
27
#include "lib/events/events.h"
 
28
#include "libcli/libcli.h"
 
29
#include "torture/util.h"
 
30
#include "auth/credentials/credentials.h"
 
31
#include "param/param.h"
 
32
 
 
33
#define BASEDIR "\\rawcontext"
 
34
 
 
35
#define CHECK_STATUS(status, correct) do { \
 
36
        if (!NT_STATUS_EQUAL(status, correct)) { \
 
37
                printf("(%s) Incorrect status %s - should be %s\n", \
 
38
                       __location__, nt_errstr(status), nt_errstr(correct)); \
 
39
                ret = false; \
 
40
                goto done; \
 
41
        }} while (0)
 
42
 
 
43
#define CHECK_VALUE(v, correct) do { \
 
44
        if ((v) != (correct)) { \
 
45
                printf("(%s) Incorrect value %s=%d - should be %d\n", \
 
46
                       __location__, #v, v, correct); \
 
47
                ret = false; \
 
48
                goto done; \
 
49
        }} while (0)
 
50
 
 
51
#define CHECK_NOT_VALUE(v, correct) do { \
 
52
        if ((v) == (correct)) { \
 
53
                printf("(%s) Incorrect value %s=%d - should not be %d\n", \
 
54
                       __location__, #v, v, correct); \
 
55
                ret = false; \
 
56
                goto done; \
 
57
        }} while (0)
 
58
 
 
59
 
 
60
/*
 
61
  test session ops
 
62
*/
 
63
static bool test_session(struct smbcli_state *cli, struct torture_context *tctx)
 
64
{
 
65
        NTSTATUS status;
 
66
        bool ret = true;
 
67
        struct smbcli_session *session;
 
68
        struct smbcli_session *session2;
 
69
        struct smbcli_session *session3;
 
70
        struct smbcli_session *session4;
 
71
        struct cli_credentials *anon_creds;
 
72
        struct smbcli_session *sessions[15];
 
73
        struct composite_context *composite_contexts[15];
 
74
        struct smbcli_tree *tree;
 
75
        struct smb_composite_sesssetup setup;
 
76
        struct smb_composite_sesssetup setups[15];
 
77
        struct gensec_settings *gensec_settings;
 
78
        union smb_open io;
 
79
        union smb_write wr;
 
80
        union smb_close cl;
 
81
        int fnum;
 
82
        const char *fname = BASEDIR "\\test.txt";
 
83
        uint8_t c = 1;
 
84
        int i;
 
85
        struct smbcli_session_options options;
 
86
 
 
87
        printf("TESTING SESSION HANDLING\n");
 
88
 
 
89
        if (!torture_setup_dir(cli, BASEDIR)) {
 
90
                return false;
 
91
        }
 
92
 
 
93
        printf("create a second security context on the same transport\n");
 
94
 
 
95
        lp_smbcli_session_options(tctx->lp_ctx, &options);
 
96
        gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 
97
 
 
98
        session = smbcli_session_init(cli->transport, tctx, false, options);
 
99
 
 
100
        setup.in.sesskey = cli->transport->negotiate.sesskey;
 
101
        setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 
102
        setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
103
 
 
104
        setup.in.credentials = cmdline_credentials;
 
105
        setup.in.gensec_settings = gensec_settings;
 
106
 
 
107
        status = smb_composite_sesssetup(session, &setup);
 
108
        CHECK_STATUS(status, NT_STATUS_OK);
 
109
        
 
110
        session->vuid = setup.out.vuid;
 
111
 
 
112
        printf("create a third security context on the same transport, with vuid set\n");
 
113
        session2 = smbcli_session_init(cli->transport, tctx, false, options);
 
114
 
 
115
        session2->vuid = session->vuid;
 
116
        setup.in.sesskey = cli->transport->negotiate.sesskey;
 
117
        setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 
118
        setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
119
 
 
120
        setup.in.credentials = cmdline_credentials;
 
121
 
 
122
        status = smb_composite_sesssetup(session2, &setup);
 
123
        CHECK_STATUS(status, NT_STATUS_OK);
 
124
 
 
125
        session2->vuid = setup.out.vuid;
 
126
        printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
 
127
        
 
128
        if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
 
129
                /* Samba4 currently fails this - we need to determine if this insane behaviour is important */
 
130
                if (session2->vuid == session->vuid) {
 
131
                        printf("server allows the user to re-use an existing vuid in session setup \n");
 
132
                }
 
133
        } else {
 
134
                CHECK_NOT_VALUE(session2->vuid, session->vuid);
 
135
        }
 
136
        talloc_free(session2);
 
137
 
 
138
        if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
 
139
                printf("create a fourth security context on the same transport, without extended security\n");
 
140
                session3 = smbcli_session_init(cli->transport, tctx, false, options);
 
141
 
 
142
                session3->vuid = session->vuid;
 
143
                setup.in.sesskey = cli->transport->negotiate.sesskey;
 
144
                setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
 
145
                setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
146
        
 
147
                setup.in.credentials = cmdline_credentials;
 
148
 
 
149
                status = smb_composite_sesssetup(session3, &setup);
 
150
                CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
 
151
 
 
152
                printf("create a fouth anonymous security context on the same transport, without extended security\n");
 
153
                session4 = smbcli_session_init(cli->transport, tctx, false, options);
 
154
 
 
155
                session4->vuid = session->vuid;
 
156
                setup.in.sesskey = cli->transport->negotiate.sesskey;
 
157
                setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
 
158
                setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
159
                
 
160
                anon_creds = cli_credentials_init(tctx);
 
161
                cli_credentials_set_conf(anon_creds, tctx->lp_ctx);
 
162
                cli_credentials_set_anonymous(anon_creds);
 
163
 
 
164
                setup.in.credentials = anon_creds;
 
165
        
 
166
                status = smb_composite_sesssetup(session3, &setup);
 
167
                CHECK_STATUS(status, NT_STATUS_OK);
 
168
 
 
169
                talloc_free(session4);
 
170
        }
 
171
                
 
172
        printf("use the same tree as the existing connection\n");
 
173
        tree = smbcli_tree_init(session, tctx, false);
 
174
        tree->tid = cli->tree->tid;
 
175
 
 
176
        printf("create a file using the new vuid\n");
 
177
        io.generic.level = RAW_OPEN_NTCREATEX;
 
178
        io.ntcreatex.in.root_fid = 0;
 
179
        io.ntcreatex.in.flags = 0;
 
180
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
181
        io.ntcreatex.in.create_options = 0;
 
182
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
183
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
184
        io.ntcreatex.in.alloc_size = 0;
 
185
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
186
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
187
        io.ntcreatex.in.security_flags = 0;
 
188
        io.ntcreatex.in.fname = fname;
 
189
        status = smb_raw_open(tree, tctx, &io);
 
190
        CHECK_STATUS(status, NT_STATUS_OK);
 
191
        fnum = io.ntcreatex.out.file.fnum;
 
192
 
 
193
        printf("write using the old vuid\n");
 
194
        wr.generic.level = RAW_WRITE_WRITEX;
 
195
        wr.writex.in.file.fnum = fnum;
 
196
        wr.writex.in.offset = 0;
 
197
        wr.writex.in.wmode = 0;
 
198
        wr.writex.in.remaining = 0;
 
199
        wr.writex.in.count = 1;
 
200
        wr.writex.in.data = &c;
 
201
 
 
202
        status = smb_raw_write(cli->tree, &wr);
 
203
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
204
 
 
205
        printf("write with the new vuid\n");
 
206
        status = smb_raw_write(tree, &wr);
 
207
        CHECK_STATUS(status, NT_STATUS_OK);
 
208
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
209
 
 
210
        printf("logoff the new vuid\n");
 
211
        status = smb_raw_ulogoff(session);
 
212
        CHECK_STATUS(status, NT_STATUS_OK);
 
213
 
 
214
        printf("the new vuid should not now be accessible\n");
 
215
        status = smb_raw_write(tree, &wr);
 
216
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
217
 
 
218
        printf("second logoff for the new vuid should fail\n");
 
219
        status = smb_raw_ulogoff(session);
 
220
        CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRbaduid));
 
221
        talloc_free(session);
 
222
 
 
223
        printf("the fnum should have been auto-closed\n");
 
224
        cl.close.level = RAW_CLOSE_CLOSE;
 
225
        cl.close.in.file.fnum = fnum;
 
226
        cl.close.in.write_time = 0;
 
227
        status = smb_raw_close(cli->tree, &cl);
 
228
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
229
 
 
230
        printf("create %d secondary security contexts on the same transport\n", 
 
231
               (int)ARRAY_SIZE(sessions));
 
232
        for (i=0; i <ARRAY_SIZE(sessions); i++) {
 
233
                setups[i].in.sesskey = cli->transport->negotiate.sesskey;
 
234
                setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 
235
                setups[i].in.workgroup = lp_workgroup(tctx->lp_ctx);
 
236
                
 
237
                setups[i].in.credentials = cmdline_credentials;
 
238
                setups[i].in.gensec_settings = gensec_settings;
 
239
 
 
240
                sessions[i] = smbcli_session_init(cli->transport, tctx, false, options);
 
241
                composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
 
242
 
 
243
        }
 
244
 
 
245
 
 
246
        printf("finishing %d secondary security contexts on the same transport\n", 
 
247
               (int)ARRAY_SIZE(sessions));
 
248
        for (i=0; i< ARRAY_SIZE(sessions); i++) {
 
249
                status = smb_composite_sesssetup_recv(composite_contexts[i]);
 
250
                CHECK_STATUS(status, NT_STATUS_OK);
 
251
                sessions[i]->vuid = setups[i].out.vuid;
 
252
                printf("VUID: %d\n", sessions[i]->vuid);
 
253
                status = smb_raw_ulogoff(sessions[i]);
 
254
                CHECK_STATUS(status, NT_STATUS_OK);
 
255
        }
 
256
 
 
257
 
 
258
        talloc_free(tree);
 
259
        
 
260
done:
 
261
        return ret;
 
262
}
 
263
 
 
264
 
 
265
/*
 
266
  test tree ops
 
267
*/
 
268
static bool test_tree(struct smbcli_state *cli, struct torture_context *tctx)
 
269
{
 
270
        NTSTATUS status;
 
271
        bool ret = true;
 
272
        const char *share, *host;
 
273
        struct smbcli_tree *tree;
 
274
        union smb_tcon tcon;
 
275
        union smb_open io;
 
276
        union smb_write wr;
 
277
        union smb_close cl;
 
278
        int fnum;
 
279
        const char *fname = BASEDIR "\\test.txt";
 
280
        uint8_t c = 1;
 
281
 
 
282
        printf("TESTING TREE HANDLING\n");
 
283
 
 
284
        if (!torture_setup_dir(cli, BASEDIR)) {
 
285
                return false;
 
286
        }
 
287
 
 
288
        share = torture_setting_string(tctx, "share", NULL);
 
289
        host  = torture_setting_string(tctx, "host", NULL);
 
290
        
 
291
        printf("create a second tree context on the same session\n");
 
292
        tree = smbcli_tree_init(cli->session, tctx, false);
 
293
 
 
294
        tcon.generic.level = RAW_TCON_TCONX;
 
295
        tcon.tconx.in.flags = 0;
 
296
        tcon.tconx.in.password = data_blob(NULL, 0);
 
297
        tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
 
298
        tcon.tconx.in.device = "A:";    
 
299
        status = smb_raw_tcon(tree, tctx, &tcon);
 
300
        CHECK_STATUS(status, NT_STATUS_OK);
 
301
        
 
302
 
 
303
        tree->tid = tcon.tconx.out.tid;
 
304
        printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
 
305
 
 
306
        printf("try a tconx with a bad device type\n");
 
307
        tcon.tconx.in.device = "FOO";   
 
308
        status = smb_raw_tcon(tree, tctx, &tcon);
 
309
        CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
 
310
 
 
311
 
 
312
        printf("create a file using the new tid\n");
 
313
        io.generic.level = RAW_OPEN_NTCREATEX;
 
314
        io.ntcreatex.in.root_fid = 0;
 
315
        io.ntcreatex.in.flags = 0;
 
316
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
317
        io.ntcreatex.in.create_options = 0;
 
318
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
319
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
320
        io.ntcreatex.in.alloc_size = 0;
 
321
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
322
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
323
        io.ntcreatex.in.security_flags = 0;
 
324
        io.ntcreatex.in.fname = fname;
 
325
        status = smb_raw_open(tree, tctx, &io);
 
326
        CHECK_STATUS(status, NT_STATUS_OK);
 
327
        fnum = io.ntcreatex.out.file.fnum;
 
328
 
 
329
        printf("write using the old tid\n");
 
330
        wr.generic.level = RAW_WRITE_WRITEX;
 
331
        wr.writex.in.file.fnum = fnum;
 
332
        wr.writex.in.offset = 0;
 
333
        wr.writex.in.wmode = 0;
 
334
        wr.writex.in.remaining = 0;
 
335
        wr.writex.in.count = 1;
 
336
        wr.writex.in.data = &c;
 
337
 
 
338
        status = smb_raw_write(cli->tree, &wr);
 
339
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
340
 
 
341
        printf("write with the new tid\n");
 
342
        status = smb_raw_write(tree, &wr);
 
343
        CHECK_STATUS(status, NT_STATUS_OK);
 
344
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
345
 
 
346
        printf("disconnect the new tid\n");
 
347
        status = smb_tree_disconnect(tree);
 
348
        CHECK_STATUS(status, NT_STATUS_OK);
 
349
 
 
350
        printf("the new tid should not now be accessible\n");
 
351
        status = smb_raw_write(tree, &wr);
 
352
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
353
 
 
354
        printf("the fnum should have been auto-closed\n");
 
355
        cl.close.level = RAW_CLOSE_CLOSE;
 
356
        cl.close.in.file.fnum = fnum;
 
357
        cl.close.in.write_time = 0;
 
358
        status = smb_raw_close(cli->tree, &cl);
 
359
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
360
 
 
361
        /* close down the new tree */
 
362
        talloc_free(tree);
 
363
        
 
364
done:
 
365
        return ret;
 
366
}
 
367
 
 
368
/*
 
369
  test tree with ulogoff
 
370
  this demonstrates that a tcon isn't autoclosed by a ulogoff
 
371
  the tcon can be reused using any other valid session later
 
372
*/
 
373
static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context *tctx)
 
374
{
 
375
        NTSTATUS status;
 
376
        bool ret = true;
 
377
        const char *share, *host;
 
378
        struct smbcli_session *session1;
 
379
        struct smbcli_session *session2;
 
380
        struct smb_composite_sesssetup setup;
 
381
        struct smbcli_tree *tree;
 
382
        union smb_tcon tcon;
 
383
        union smb_open io;
 
384
        union smb_write wr;
 
385
        int fnum1, fnum2;
 
386
        const char *fname1 = BASEDIR "\\test1.txt";
 
387
        const char *fname2 = BASEDIR "\\test2.txt";
 
388
        uint8_t c = 1;
 
389
        struct smbcli_session_options options;
 
390
 
 
391
        printf("TESTING TREE with ulogoff\n");
 
392
 
 
393
        if (!torture_setup_dir(cli, BASEDIR)) {
 
394
                return false;
 
395
        }
 
396
 
 
397
        share = torture_setting_string(tctx, "share", NULL);
 
398
        host  = torture_setting_string(tctx, "host", NULL);
 
399
 
 
400
        lp_smbcli_session_options(tctx->lp_ctx, &options);
 
401
 
 
402
        printf("create the first new sessions\n");
 
403
        session1 = smbcli_session_init(cli->transport, tctx, false, options);
 
404
        setup.in.sesskey = cli->transport->negotiate.sesskey;
 
405
        setup.in.capabilities = cli->transport->negotiate.capabilities;
 
406
        setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
407
        setup.in.credentials = cmdline_credentials;
 
408
        setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 
409
        status = smb_composite_sesssetup(session1, &setup);
 
410
        CHECK_STATUS(status, NT_STATUS_OK);
 
411
        session1->vuid = setup.out.vuid;
 
412
        printf("vuid1=%d\n", session1->vuid);
 
413
 
 
414
        printf("create a tree context on the with vuid1\n");
 
415
        tree = smbcli_tree_init(session1, tctx, false);
 
416
        tcon.generic.level = RAW_TCON_TCONX;
 
417
        tcon.tconx.in.flags = 0;
 
418
        tcon.tconx.in.password = data_blob(NULL, 0);
 
419
        tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
 
420
        tcon.tconx.in.device = "A:";
 
421
        status = smb_raw_tcon(tree, tctx, &tcon);
 
422
        CHECK_STATUS(status, NT_STATUS_OK);
 
423
        tree->tid = tcon.tconx.out.tid;
 
424
        printf("tid=%d\n", tree->tid);
 
425
 
 
426
        printf("create a file using vuid1\n");
 
427
        io.generic.level = RAW_OPEN_NTCREATEX;
 
428
        io.ntcreatex.in.root_fid = 0;
 
429
        io.ntcreatex.in.flags = 0;
 
430
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
431
        io.ntcreatex.in.create_options = 0;
 
432
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
433
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
434
        io.ntcreatex.in.alloc_size = 0;
 
435
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
436
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
437
        io.ntcreatex.in.security_flags = 0;
 
438
        io.ntcreatex.in.fname = fname1;
 
439
        status = smb_raw_open(tree, tctx, &io);
 
440
        CHECK_STATUS(status, NT_STATUS_OK);
 
441
        fnum1 = io.ntcreatex.out.file.fnum;
 
442
 
 
443
        printf("write using vuid1\n");
 
444
        wr.generic.level = RAW_WRITE_WRITEX;
 
445
        wr.writex.in.file.fnum = fnum1;
 
446
        wr.writex.in.offset = 0;
 
447
        wr.writex.in.wmode = 0;
 
448
        wr.writex.in.remaining = 0;
 
449
        wr.writex.in.count = 1;
 
450
        wr.writex.in.data = &c;
 
451
        status = smb_raw_write(tree, &wr);
 
452
        CHECK_STATUS(status, NT_STATUS_OK);
 
453
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
454
 
 
455
        printf("ulogoff the vuid1\n");
 
456
        status = smb_raw_ulogoff(session1);
 
457
        CHECK_STATUS(status, NT_STATUS_OK);
 
458
 
 
459
        printf("create the second new sessions\n");
 
460
        session2 = smbcli_session_init(cli->transport, tctx, false, options);
 
461
        setup.in.sesskey = cli->transport->negotiate.sesskey;
 
462
        setup.in.capabilities = cli->transport->negotiate.capabilities;
 
463
        setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
464
        setup.in.credentials = cmdline_credentials;
 
465
        setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 
466
        status = smb_composite_sesssetup(session2, &setup);
 
467
        CHECK_STATUS(status, NT_STATUS_OK);
 
468
        session2->vuid = setup.out.vuid;
 
469
        printf("vuid2=%d\n", session2->vuid);
 
470
 
 
471
        printf("use the existing tree with vuid2\n");
 
472
        tree->session = session2;
 
473
 
 
474
        printf("create a file using vuid2\n");
 
475
        io.generic.level = RAW_OPEN_NTCREATEX;
 
476
        io.ntcreatex.in.root_fid = 0;
 
477
        io.ntcreatex.in.flags = 0;
 
478
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
479
        io.ntcreatex.in.create_options = 0;
 
480
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
481
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
482
        io.ntcreatex.in.alloc_size = 0;
 
483
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
484
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
485
        io.ntcreatex.in.security_flags = 0;
 
486
        io.ntcreatex.in.fname = fname2;
 
487
        status = smb_raw_open(tree, tctx, &io);
 
488
        CHECK_STATUS(status, NT_STATUS_OK);
 
489
        fnum2 = io.ntcreatex.out.file.fnum;
 
490
 
 
491
        printf("write using vuid2\n");
 
492
        wr.generic.level = RAW_WRITE_WRITEX;
 
493
        wr.writex.in.file.fnum = fnum2;
 
494
        wr.writex.in.offset = 0;
 
495
        wr.writex.in.wmode = 0;
 
496
        wr.writex.in.remaining = 0;
 
497
        wr.writex.in.count = 1;
 
498
        wr.writex.in.data = &c;
 
499
        status = smb_raw_write(tree, &wr);
 
500
        CHECK_STATUS(status, NT_STATUS_OK);
 
501
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
502
 
 
503
        printf("ulogoff the vuid2\n");
 
504
        status = smb_raw_ulogoff(session2);
 
505
        CHECK_STATUS(status, NT_STATUS_OK);
 
506
 
 
507
        /* this also demonstrates that SMBtdis doesn't need a valid vuid */
 
508
        printf("disconnect the existing tree connection\n");
 
509
        status = smb_tree_disconnect(tree);
 
510
        CHECK_STATUS(status, NT_STATUS_OK);
 
511
 
 
512
        printf("disconnect the existing tree connection\n");
 
513
        status = smb_tree_disconnect(tree);
 
514
        CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
 
515
 
 
516
        /* close down the new tree */
 
517
        talloc_free(tree);
 
518
        
 
519
done:
 
520
        return ret;
 
521
}
 
522
 
 
523
/*
 
524
  test pid ops
 
525
  this test demonstrates that exit() only sees the PID
 
526
  used for the open() calls
 
527
*/
 
528
static bool test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
529
{
 
530
        NTSTATUS status;
 
531
        bool ret = true;
 
532
        union smb_open io;
 
533
        union smb_write wr;
 
534
        union smb_close cl;
 
535
        int fnum;
 
536
        const char *fname = BASEDIR "\\test.txt";
 
537
        uint8_t c = 1;
 
538
        uint16_t pid1, pid2;
 
539
 
 
540
        printf("TESTING PID HANDLING exit() only cares about open() PID\n");
 
541
 
 
542
        if (!torture_setup_dir(cli, BASEDIR)) {
 
543
                return false;
 
544
        }
 
545
 
 
546
        pid1 = cli->session->pid;
 
547
        pid2 = pid1 + 1;
 
548
 
 
549
        printf("pid1=%d pid2=%d\n", pid1, pid2);
 
550
 
 
551
        printf("create a file using pid1\n");
 
552
        cli->session->pid = pid1;
 
553
        io.generic.level = RAW_OPEN_NTCREATEX;
 
554
        io.ntcreatex.in.root_fid = 0;
 
555
        io.ntcreatex.in.flags = 0;
 
556
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
557
        io.ntcreatex.in.create_options = 0;
 
558
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
559
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
560
        io.ntcreatex.in.alloc_size = 0;
 
561
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
562
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
563
        io.ntcreatex.in.security_flags = 0;
 
564
        io.ntcreatex.in.fname = fname;
 
565
        status = smb_raw_open(cli->tree, mem_ctx, &io);
 
566
        CHECK_STATUS(status, NT_STATUS_OK);
 
567
        fnum = io.ntcreatex.out.file.fnum;
 
568
 
 
569
        printf("write using pid2\n");
 
570
        cli->session->pid = pid2;
 
571
        wr.generic.level = RAW_WRITE_WRITEX;
 
572
        wr.writex.in.file.fnum = fnum;
 
573
        wr.writex.in.offset = 0;
 
574
        wr.writex.in.wmode = 0;
 
575
        wr.writex.in.remaining = 0;
 
576
        wr.writex.in.count = 1;
 
577
        wr.writex.in.data = &c;
 
578
        status = smb_raw_write(cli->tree, &wr);
 
579
        CHECK_STATUS(status, NT_STATUS_OK);
 
580
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
581
 
 
582
        printf("exit pid2\n");
 
583
        cli->session->pid = pid2;
 
584
        status = smb_raw_exit(cli->session);
 
585
        CHECK_STATUS(status, NT_STATUS_OK);
 
586
 
 
587
        printf("the fnum should still be accessible via pid2\n");
 
588
        cli->session->pid = pid2;
 
589
        status = smb_raw_write(cli->tree, &wr);
 
590
        CHECK_STATUS(status, NT_STATUS_OK);
 
591
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
592
 
 
593
        printf("exit pid2\n");
 
594
        cli->session->pid = pid2;
 
595
        status = smb_raw_exit(cli->session);
 
596
        CHECK_STATUS(status, NT_STATUS_OK);
 
597
 
 
598
        printf("the fnum should still be accessible via pid1 and pid2\n");
 
599
        cli->session->pid = pid1;
 
600
        status = smb_raw_write(cli->tree, &wr);
 
601
        CHECK_STATUS(status, NT_STATUS_OK);
 
602
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
603
        cli->session->pid = pid2;
 
604
        status = smb_raw_write(cli->tree, &wr);
 
605
        CHECK_STATUS(status, NT_STATUS_OK);
 
606
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
607
 
 
608
        printf("exit pid1\n");
 
609
        cli->session->pid = pid1;
 
610
        status = smb_raw_exit(cli->session);
 
611
        CHECK_STATUS(status, NT_STATUS_OK);
 
612
 
 
613
        printf("the fnum should not now be accessible via pid1 or pid2\n");
 
614
        cli->session->pid = pid1;
 
615
        status = smb_raw_write(cli->tree, &wr);
 
616
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
617
        cli->session->pid = pid2;
 
618
        status = smb_raw_write(cli->tree, &wr);
 
619
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
620
 
 
621
        printf("the fnum should have been auto-closed\n");
 
622
        cli->session->pid = pid1;
 
623
        cl.close.level = RAW_CLOSE_CLOSE;
 
624
        cl.close.in.file.fnum = fnum;
 
625
        cl.close.in.write_time = 0;
 
626
        status = smb_raw_close(cli->tree, &cl);
 
627
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
628
 
 
629
done:
 
630
        return ret;
 
631
}
 
632
 
 
633
/*
 
634
  test pid ops with 2 sessions
 
635
*/
 
636
static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tctx)
 
637
{
 
638
        NTSTATUS status;
 
639
        bool ret = true;
 
640
        struct smbcli_session *session;
 
641
        struct smb_composite_sesssetup setup;
 
642
        union smb_open io;
 
643
        union smb_write wr;
 
644
        union smb_close cl;
 
645
        int fnum;
 
646
        const char *fname = BASEDIR "\\test.txt";
 
647
        uint8_t c = 1;
 
648
        uint16_t vuid1, vuid2;
 
649
        struct smbcli_session_options options;
 
650
 
 
651
        printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
 
652
 
 
653
        if (!torture_setup_dir(cli, BASEDIR)) {
 
654
                return false;
 
655
        }
 
656
 
 
657
        lp_smbcli_session_options(tctx->lp_ctx, &options);
 
658
 
 
659
        printf("create a second security context on the same transport\n");
 
660
        session = smbcli_session_init(cli->transport, tctx, false, options);
 
661
 
 
662
        setup.in.sesskey = cli->transport->negotiate.sesskey;
 
663
        setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 
664
        setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 
665
        setup.in.credentials = cmdline_credentials;
 
666
        setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 
667
 
 
668
        status = smb_composite_sesssetup(session, &setup);
 
669
        CHECK_STATUS(status, NT_STATUS_OK);     
 
670
        session->vuid = setup.out.vuid;
 
671
 
 
672
        vuid1 = cli->session->vuid;
 
673
        vuid2 = session->vuid;
 
674
 
 
675
        printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
 
676
 
 
677
        printf("create a file using the vuid1\n");
 
678
        cli->session->vuid = vuid1;
 
679
        io.generic.level = RAW_OPEN_NTCREATEX;
 
680
        io.ntcreatex.in.root_fid = 0;
 
681
        io.ntcreatex.in.flags = 0;
 
682
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
683
        io.ntcreatex.in.create_options = 0;
 
684
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
685
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
686
        io.ntcreatex.in.alloc_size = 0;
 
687
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
688
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
689
        io.ntcreatex.in.security_flags = 0;
 
690
        io.ntcreatex.in.fname = fname;
 
691
        status = smb_raw_open(cli->tree, tctx, &io);
 
692
        CHECK_STATUS(status, NT_STATUS_OK);
 
693
        fnum = io.ntcreatex.out.file.fnum;
 
694
 
 
695
        printf("write using the vuid1 (fnum=%d)\n", fnum);
 
696
        cli->session->vuid = vuid1;
 
697
        wr.generic.level = RAW_WRITE_WRITEX;
 
698
        wr.writex.in.file.fnum = fnum;
 
699
        wr.writex.in.offset = 0;
 
700
        wr.writex.in.wmode = 0;
 
701
        wr.writex.in.remaining = 0;
 
702
        wr.writex.in.count = 1;
 
703
        wr.writex.in.data = &c;
 
704
 
 
705
        status = smb_raw_write(cli->tree, &wr);
 
706
        CHECK_STATUS(status, NT_STATUS_OK);
 
707
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
708
 
 
709
        printf("exit the pid with vuid2\n");
 
710
        cli->session->vuid = vuid2;
 
711
        status = smb_raw_exit(cli->session);
 
712
        CHECK_STATUS(status, NT_STATUS_OK);
 
713
 
 
714
        printf("the fnum should still be accessible\n");
 
715
        cli->session->vuid = vuid1;
 
716
        status = smb_raw_write(cli->tree, &wr);
 
717
        CHECK_STATUS(status, NT_STATUS_OK);
 
718
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
719
 
 
720
        printf("exit the pid with vuid1\n");
 
721
        cli->session->vuid = vuid1;
 
722
        status = smb_raw_exit(cli->session);
 
723
        CHECK_STATUS(status, NT_STATUS_OK);
 
724
 
 
725
        printf("the fnum should not now be accessible\n");
 
726
        status = smb_raw_write(cli->tree, &wr);
 
727
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
728
 
 
729
        printf("the fnum should have been auto-closed\n");
 
730
        cl.close.level = RAW_CLOSE_CLOSE;
 
731
        cl.close.in.file.fnum = fnum;
 
732
        cl.close.in.write_time = 0;
 
733
        status = smb_raw_close(cli->tree, &cl);
 
734
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
735
 
 
736
done:
 
737
        return ret;
 
738
}
 
739
 
 
740
/*
 
741
  test pid ops with 2 tcons
 
742
*/
 
743
static bool test_pid_2tcon(struct smbcli_state *cli, struct torture_context *tctx)
 
744
{
 
745
        NTSTATUS status;
 
746
        bool ret = true;
 
747
        const char *share, *host;
 
748
        struct smbcli_tree *tree;
 
749
        union smb_tcon tcon;
 
750
        union smb_open io;
 
751
        union smb_write wr;
 
752
        union smb_close cl;
 
753
        int fnum1, fnum2;
 
754
        const char *fname1 = BASEDIR "\\test1.txt";
 
755
        const char *fname2 = BASEDIR "\\test2.txt";
 
756
        uint8_t c = 1;
 
757
        uint16_t tid1, tid2;
 
758
 
 
759
        printf("TESTING PID HANDLING WITH 2 TCONS\n");
 
760
 
 
761
        if (!torture_setup_dir(cli, BASEDIR)) {
 
762
                return false;
 
763
        }
 
764
 
 
765
        share = torture_setting_string(tctx, "share", NULL);
 
766
        host  = torture_setting_string(tctx, "host", NULL);
 
767
        
 
768
        printf("create a second tree context on the same session\n");
 
769
        tree = smbcli_tree_init(cli->session, tctx, false);
 
770
 
 
771
        tcon.generic.level = RAW_TCON_TCONX;
 
772
        tcon.tconx.in.flags = 0;
 
773
        tcon.tconx.in.password = data_blob(NULL, 0);
 
774
        tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
 
775
        tcon.tconx.in.device = "A:";    
 
776
        status = smb_raw_tcon(tree, tctx, &tcon);
 
777
        CHECK_STATUS(status, NT_STATUS_OK);     
 
778
 
 
779
        tree->tid = tcon.tconx.out.tid;
 
780
 
 
781
        tid1 = cli->tree->tid;
 
782
        tid2 = tree->tid;
 
783
        printf("tid1=%d tid2=%d\n", tid1, tid2);
 
784
 
 
785
        printf("create a file using the tid1\n");
 
786
        cli->tree->tid = tid1;
 
787
        io.generic.level = RAW_OPEN_NTCREATEX;
 
788
        io.ntcreatex.in.root_fid = 0;
 
789
        io.ntcreatex.in.flags = 0;
 
790
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
791
        io.ntcreatex.in.create_options = 0;
 
792
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
793
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
794
        io.ntcreatex.in.alloc_size = 0;
 
795
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
796
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
797
        io.ntcreatex.in.security_flags = 0;
 
798
        io.ntcreatex.in.fname = fname1;
 
799
        status = smb_raw_open(cli->tree, tctx, &io);
 
800
        CHECK_STATUS(status, NT_STATUS_OK);
 
801
        fnum1 = io.ntcreatex.out.file.fnum;
 
802
 
 
803
        printf("write using the tid1\n");
 
804
        wr.generic.level = RAW_WRITE_WRITEX;
 
805
        wr.writex.in.file.fnum = fnum1;
 
806
        wr.writex.in.offset = 0;
 
807
        wr.writex.in.wmode = 0;
 
808
        wr.writex.in.remaining = 0;
 
809
        wr.writex.in.count = 1;
 
810
        wr.writex.in.data = &c;
 
811
 
 
812
        status = smb_raw_write(cli->tree, &wr);
 
813
        CHECK_STATUS(status, NT_STATUS_OK);
 
814
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
815
 
 
816
        printf("create a file using the tid2\n");
 
817
        cli->tree->tid = tid2;
 
818
        io.generic.level = RAW_OPEN_NTCREATEX;
 
819
        io.ntcreatex.in.root_fid = 0;
 
820
        io.ntcreatex.in.flags = 0;
 
821
        io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 
822
        io.ntcreatex.in.create_options = 0;
 
823
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 
824
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 
825
        io.ntcreatex.in.alloc_size = 0;
 
826
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
827
        io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 
828
        io.ntcreatex.in.security_flags = 0;
 
829
        io.ntcreatex.in.fname = fname2;
 
830
        status = smb_raw_open(cli->tree, tctx, &io);
 
831
        CHECK_STATUS(status, NT_STATUS_OK);
 
832
        fnum2 = io.ntcreatex.out.file.fnum;
 
833
 
 
834
        printf("write using the tid2\n");
 
835
        wr.generic.level = RAW_WRITE_WRITEX;
 
836
        wr.writex.in.file.fnum = fnum2;
 
837
        wr.writex.in.offset = 0;
 
838
        wr.writex.in.wmode = 0;
 
839
        wr.writex.in.remaining = 0;
 
840
        wr.writex.in.count = 1;
 
841
        wr.writex.in.data = &c;
 
842
 
 
843
        status = smb_raw_write(cli->tree, &wr);
 
844
        CHECK_STATUS(status, NT_STATUS_OK);
 
845
        CHECK_VALUE(wr.writex.out.nwritten, 1);
 
846
 
 
847
        printf("exit the pid\n");
 
848
        status = smb_raw_exit(cli->session);
 
849
        CHECK_STATUS(status, NT_STATUS_OK);
 
850
 
 
851
        printf("the fnum1 on tid1 should not be accessible\n");
 
852
        cli->tree->tid = tid1;
 
853
        wr.writex.in.file.fnum = fnum1;
 
854
        status = smb_raw_write(cli->tree, &wr);
 
855
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
856
 
 
857
        printf("the fnum1 on tid1 should have been auto-closed\n");
 
858
        cl.close.level = RAW_CLOSE_CLOSE;
 
859
        cl.close.in.file.fnum = fnum1;
 
860
        cl.close.in.write_time = 0;
 
861
        status = smb_raw_close(cli->tree, &cl);
 
862
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
863
 
 
864
        printf("the fnum2 on tid2 should not be accessible\n");
 
865
        cli->tree->tid = tid2;
 
866
        wr.writex.in.file.fnum = fnum2;
 
867
        status = smb_raw_write(cli->tree, &wr);
 
868
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
869
 
 
870
        printf("the fnum2 on tid2 should have been auto-closed\n");
 
871
        cl.close.level = RAW_CLOSE_CLOSE;
 
872
        cl.close.in.file.fnum = fnum2;
 
873
        cl.close.in.write_time = 0;
 
874
        status = smb_raw_close(cli->tree, &cl);
 
875
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
876
 
 
877
done:
 
878
        return ret;
 
879
}
 
880
 
 
881
 
 
882
/* 
 
883
   basic testing of session/tree context calls
 
884
*/
 
885
static bool torture_raw_context_int(struct torture_context *tctx, 
 
886
                                                                        struct smbcli_state *cli)
 
887
{
 
888
        bool ret = true;
 
889
 
 
890
        ret &= test_session(cli, tctx);
 
891
        ret &= test_tree(cli, tctx);
 
892
        ret &= test_tree_ulogoff(cli, tctx);
 
893
        ret &= test_pid_exit_only_sees_open(cli, tctx);
 
894
        ret &= test_pid_2sess(cli, tctx);
 
895
        ret &= test_pid_2tcon(cli, tctx);
 
896
 
 
897
        smb_raw_exit(cli->session);
 
898
        smbcli_deltree(cli->tree, BASEDIR);
 
899
 
 
900
        return ret;
 
901
}
 
902
/* 
 
903
   basic testing of session/tree context calls
 
904
*/
 
905
bool torture_raw_context(struct torture_context *torture, 
 
906
                         struct smbcli_state *cli)
 
907
{
 
908
        bool ret = true;
 
909
        if (lp_use_spnego(torture->lp_ctx)) {
 
910
                ret &= torture_raw_context_int(torture, cli);
 
911
                lp_set_cmdline(torture->lp_ctx, "use spnego", "False");
 
912
        }
 
913
 
 
914
        ret &= torture_raw_context_int(torture, cli);
 
915
 
 
916
        return ret;
 
917
}