2
Unix SMB/CIFS implementation.
3
test suite for session setup operations
4
Copyright (C) Andrew Tridgell 2003
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 "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"
33
#define BASEDIR "\\rawcontext"
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)); \
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); \
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); \
63
static bool test_session(struct smbcli_state *cli, struct torture_context *tctx)
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;
82
const char *fname = BASEDIR "\\test.txt";
85
struct smbcli_session_options options;
87
printf("TESTING SESSION HANDLING\n");
89
if (!torture_setup_dir(cli, BASEDIR)) {
93
printf("create a second security context on the same transport\n");
95
lp_smbcli_session_options(tctx->lp_ctx, &options);
96
gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
98
session = smbcli_session_init(cli->transport, tctx, false, options);
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);
104
setup.in.credentials = cmdline_credentials;
105
setup.in.gensec_settings = gensec_settings;
107
status = smb_composite_sesssetup(session, &setup);
108
CHECK_STATUS(status, NT_STATUS_OK);
110
session->vuid = setup.out.vuid;
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);
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);
120
setup.in.credentials = cmdline_credentials;
122
status = smb_composite_sesssetup(session2, &setup);
123
CHECK_STATUS(status, NT_STATUS_OK);
125
session2->vuid = setup.out.vuid;
126
printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
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");
134
CHECK_NOT_VALUE(session2->vuid, session->vuid);
136
talloc_free(session2);
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);
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);
147
setup.in.credentials = cmdline_credentials;
149
status = smb_composite_sesssetup(session3, &setup);
150
CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
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);
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);
160
anon_creds = cli_credentials_init(tctx);
161
cli_credentials_set_conf(anon_creds, tctx->lp_ctx);
162
cli_credentials_set_anonymous(anon_creds);
164
setup.in.credentials = anon_creds;
166
status = smb_composite_sesssetup(session3, &setup);
167
CHECK_STATUS(status, NT_STATUS_OK);
169
talloc_free(session4);
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;
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;
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;
202
status = smb_raw_write(cli->tree, &wr);
203
CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
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);
210
printf("logoff the new vuid\n");
211
status = smb_raw_ulogoff(session);
212
CHECK_STATUS(status, NT_STATUS_OK);
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);
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);
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);
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);
237
setups[i].in.credentials = cmdline_credentials;
238
setups[i].in.gensec_settings = gensec_settings;
240
sessions[i] = smbcli_session_init(cli->transport, tctx, false, options);
241
composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
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);
268
static bool test_tree(struct smbcli_state *cli, struct torture_context *tctx)
272
const char *share, *host;
273
struct smbcli_tree *tree;
279
const char *fname = BASEDIR "\\test.txt";
282
printf("TESTING TREE HANDLING\n");
284
if (!torture_setup_dir(cli, BASEDIR)) {
288
share = torture_setting_string(tctx, "share", NULL);
289
host = torture_setting_string(tctx, "host", NULL);
291
printf("create a second tree context on the same session\n");
292
tree = smbcli_tree_init(cli->session, tctx, false);
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);
303
tree->tid = tcon.tconx.out.tid;
304
printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
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);
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;
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;
338
status = smb_raw_write(cli->tree, &wr);
339
CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
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);
346
printf("disconnect the new tid\n");
347
status = smb_tree_disconnect(tree);
348
CHECK_STATUS(status, NT_STATUS_OK);
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);
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);
361
/* close down the new tree */
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
373
static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context *tctx)
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;
386
const char *fname1 = BASEDIR "\\test1.txt";
387
const char *fname2 = BASEDIR "\\test2.txt";
389
struct smbcli_session_options options;
391
printf("TESTING TREE with ulogoff\n");
393
if (!torture_setup_dir(cli, BASEDIR)) {
397
share = torture_setting_string(tctx, "share", NULL);
398
host = torture_setting_string(tctx, "host", NULL);
400
lp_smbcli_session_options(tctx->lp_ctx, &options);
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);
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);
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;
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);
455
printf("ulogoff the vuid1\n");
456
status = smb_raw_ulogoff(session1);
457
CHECK_STATUS(status, NT_STATUS_OK);
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);
471
printf("use the existing tree with vuid2\n");
472
tree->session = session2;
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;
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);
503
printf("ulogoff the vuid2\n");
504
status = smb_raw_ulogoff(session2);
505
CHECK_STATUS(status, NT_STATUS_OK);
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);
512
printf("disconnect the existing tree connection\n");
513
status = smb_tree_disconnect(tree);
514
CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
516
/* close down the new tree */
525
this test demonstrates that exit() only sees the PID
526
used for the open() calls
528
static bool test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
536
const char *fname = BASEDIR "\\test.txt";
540
printf("TESTING PID HANDLING exit() only cares about open() PID\n");
542
if (!torture_setup_dir(cli, BASEDIR)) {
546
pid1 = cli->session->pid;
549
printf("pid1=%d pid2=%d\n", pid1, pid2);
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;
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);
582
printf("exit pid2\n");
583
cli->session->pid = pid2;
584
status = smb_raw_exit(cli->session);
585
CHECK_STATUS(status, NT_STATUS_OK);
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);
593
printf("exit pid2\n");
594
cli->session->pid = pid2;
595
status = smb_raw_exit(cli->session);
596
CHECK_STATUS(status, NT_STATUS_OK);
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);
608
printf("exit pid1\n");
609
cli->session->pid = pid1;
610
status = smb_raw_exit(cli->session);
611
CHECK_STATUS(status, NT_STATUS_OK);
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);
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);
634
test pid ops with 2 sessions
636
static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tctx)
640
struct smbcli_session *session;
641
struct smb_composite_sesssetup setup;
646
const char *fname = BASEDIR "\\test.txt";
648
uint16_t vuid1, vuid2;
649
struct smbcli_session_options options;
651
printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
653
if (!torture_setup_dir(cli, BASEDIR)) {
657
lp_smbcli_session_options(tctx->lp_ctx, &options);
659
printf("create a second security context on the same transport\n");
660
session = smbcli_session_init(cli->transport, tctx, false, options);
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);
668
status = smb_composite_sesssetup(session, &setup);
669
CHECK_STATUS(status, NT_STATUS_OK);
670
session->vuid = setup.out.vuid;
672
vuid1 = cli->session->vuid;
673
vuid2 = session->vuid;
675
printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
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;
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;
705
status = smb_raw_write(cli->tree, &wr);
706
CHECK_STATUS(status, NT_STATUS_OK);
707
CHECK_VALUE(wr.writex.out.nwritten, 1);
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);
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);
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);
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);
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);
741
test pid ops with 2 tcons
743
static bool test_pid_2tcon(struct smbcli_state *cli, struct torture_context *tctx)
747
const char *share, *host;
748
struct smbcli_tree *tree;
754
const char *fname1 = BASEDIR "\\test1.txt";
755
const char *fname2 = BASEDIR "\\test2.txt";
759
printf("TESTING PID HANDLING WITH 2 TCONS\n");
761
if (!torture_setup_dir(cli, BASEDIR)) {
765
share = torture_setting_string(tctx, "share", NULL);
766
host = torture_setting_string(tctx, "host", NULL);
768
printf("create a second tree context on the same session\n");
769
tree = smbcli_tree_init(cli->session, tctx, false);
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);
779
tree->tid = tcon.tconx.out.tid;
781
tid1 = cli->tree->tid;
783
printf("tid1=%d tid2=%d\n", tid1, tid2);
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;
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;
812
status = smb_raw_write(cli->tree, &wr);
813
CHECK_STATUS(status, NT_STATUS_OK);
814
CHECK_VALUE(wr.writex.out.nwritten, 1);
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;
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;
843
status = smb_raw_write(cli->tree, &wr);
844
CHECK_STATUS(status, NT_STATUS_OK);
845
CHECK_VALUE(wr.writex.out.nwritten, 1);
847
printf("exit the pid\n");
848
status = smb_raw_exit(cli->session);
849
CHECK_STATUS(status, NT_STATUS_OK);
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);
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);
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);
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);
883
basic testing of session/tree context calls
885
static bool torture_raw_context_int(struct torture_context *tctx,
886
struct smbcli_state *cli)
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);
897
smb_raw_exit(cli->session);
898
smbcli_deltree(cli->tree, BASEDIR);
903
basic testing of session/tree context calls
905
bool torture_raw_context(struct torture_context *torture,
906
struct smbcli_state *cli)
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");
914
ret &= torture_raw_context_int(torture, cli);