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];
81 const char *fname = BASEDIR "\\test.txt";
84 struct smbcli_session_options options;
86 printf("TESTING SESSION HANDLING\n");
88 if (!torture_setup_dir(cli, BASEDIR)) {
92 printf("create a second security context on the same transport\n");
94 lp_smbcli_session_options(tctx->lp_ctx, &options);
96 session = smbcli_session_init(cli->transport, tctx, false, options);
98 setup.in.sesskey = cli->transport->negotiate.sesskey;
99 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
100 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
102 setup.in.credentials = cmdline_credentials;
104 status = smb_composite_sesssetup(session, &setup);
105 CHECK_STATUS(status, NT_STATUS_OK);
107 session->vuid = setup.out.vuid;
109 printf("create a third security context on the same transport, with vuid set\n");
110 session2 = smbcli_session_init(cli->transport, tctx, false, options);
112 session2->vuid = session->vuid;
113 setup.in.sesskey = cli->transport->negotiate.sesskey;
114 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
115 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
117 setup.in.credentials = cmdline_credentials;
119 status = smb_composite_sesssetup(session2, &setup);
120 CHECK_STATUS(status, NT_STATUS_OK);
122 session2->vuid = setup.out.vuid;
123 printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
125 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
126 /* Samba4 currently fails this - we need to determine if this insane behaviour is important */
127 if (session2->vuid == session->vuid) {
128 printf("server allows the user to re-use an existing vuid in session setup \n");
131 CHECK_NOT_VALUE(session2->vuid, session->vuid);
133 talloc_free(session2);
135 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
136 printf("create a fourth security context on the same transport, without extended security\n");
137 session3 = smbcli_session_init(cli->transport, tctx, false, options);
139 session3->vuid = session->vuid;
140 setup.in.sesskey = cli->transport->negotiate.sesskey;
141 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
142 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
144 setup.in.credentials = cmdline_credentials;
147 status = smb_composite_sesssetup(session3, &setup);
148 CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
150 printf("create a fouth anonymous security context on the same transport, without extended security\n");
151 session4 = smbcli_session_init(cli->transport, tctx, false, options);
153 session4->vuid = session->vuid;
154 setup.in.sesskey = cli->transport->negotiate.sesskey;
155 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
156 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
158 anon_creds = cli_credentials_init(tctx);
159 cli_credentials_set_conf(anon_creds, tctx->lp_ctx);
160 cli_credentials_set_anonymous(anon_creds);
162 setup.in.credentials = anon_creds;
164 status = smb_composite_sesssetup(session3, &setup);
165 CHECK_STATUS(status, NT_STATUS_OK);
167 talloc_free(session4);
170 printf("use the same tree as the existing connection\n");
171 tree = smbcli_tree_init(session, tctx, false);
172 tree->tid = cli->tree->tid;
174 printf("create a file using the new vuid\n");
175 io.generic.level = RAW_OPEN_NTCREATEX;
176 io.ntcreatex.in.root_fid = 0;
177 io.ntcreatex.in.flags = 0;
178 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
179 io.ntcreatex.in.create_options = 0;
180 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
181 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
182 io.ntcreatex.in.alloc_size = 0;
183 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
184 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
185 io.ntcreatex.in.security_flags = 0;
186 io.ntcreatex.in.fname = fname;
187 status = smb_raw_open(tree, tctx, &io);
188 CHECK_STATUS(status, NT_STATUS_OK);
189 fnum = io.ntcreatex.out.file.fnum;
191 printf("write using the old vuid\n");
192 wr.generic.level = RAW_WRITE_WRITEX;
193 wr.writex.in.file.fnum = fnum;
194 wr.writex.in.offset = 0;
195 wr.writex.in.wmode = 0;
196 wr.writex.in.remaining = 0;
197 wr.writex.in.count = 1;
198 wr.writex.in.data = &c;
200 status = smb_raw_write(cli->tree, &wr);
201 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
203 printf("write with the new vuid\n");
204 status = smb_raw_write(tree, &wr);
205 CHECK_STATUS(status, NT_STATUS_OK);
206 CHECK_VALUE(wr.writex.out.nwritten, 1);
208 printf("logoff the new vuid\n");
209 status = smb_raw_ulogoff(session);
210 CHECK_STATUS(status, NT_STATUS_OK);
212 printf("the new vuid should not now be accessible\n");
213 status = smb_raw_write(tree, &wr);
214 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
216 printf("second logoff for the new vuid should fail\n");
217 status = smb_raw_ulogoff(session);
218 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRbaduid));
219 talloc_free(session);
221 printf("the fnum should have been auto-closed\n");
222 cl.close.level = RAW_CLOSE_CLOSE;
223 cl.close.in.file.fnum = fnum;
224 cl.close.in.write_time = 0;
225 status = smb_raw_close(cli->tree, &cl);
226 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
228 printf("create %d secondary security contexts on the same transport\n",
229 (int)ARRAY_SIZE(sessions));
230 for (i=0; i <ARRAY_SIZE(sessions); i++) {
231 setups[i].in.sesskey = cli->transport->negotiate.sesskey;
232 setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
233 setups[i].in.workgroup = lp_workgroup(tctx->lp_ctx);
235 setups[i].in.credentials = cmdline_credentials;
237 sessions[i] = smbcli_session_init(cli->transport, tctx, false, options);
238 composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
243 printf("finishing %d secondary security contexts on the same transport\n",
244 (int)ARRAY_SIZE(sessions));
245 for (i=0; i< ARRAY_SIZE(sessions); i++) {
246 status = smb_composite_sesssetup_recv(composite_contexts[i]);
247 CHECK_STATUS(status, NT_STATUS_OK);
248 sessions[i]->vuid = setups[i].out.vuid;
249 printf("VUID: %d\n", sessions[i]->vuid);
250 status = smb_raw_ulogoff(sessions[i]);
251 CHECK_STATUS(status, NT_STATUS_OK);
265 static bool test_tree(struct smbcli_state *cli, struct torture_context *tctx)
269 const char *share, *host;
270 struct smbcli_tree *tree;
276 const char *fname = BASEDIR "\\test.txt";
279 printf("TESTING TREE HANDLING\n");
281 if (!torture_setup_dir(cli, BASEDIR)) {
285 share = torture_setting_string(tctx, "share", NULL);
286 host = torture_setting_string(tctx, "host", NULL);
288 printf("create a second tree context on the same session\n");
289 tree = smbcli_tree_init(cli->session, tctx, false);
291 tcon.generic.level = RAW_TCON_TCONX;
292 tcon.tconx.in.flags = 0;
293 tcon.tconx.in.password = data_blob(NULL, 0);
294 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
295 tcon.tconx.in.device = "A:";
296 status = smb_raw_tcon(tree, tctx, &tcon);
297 CHECK_STATUS(status, NT_STATUS_OK);
300 tree->tid = tcon.tconx.out.tid;
301 printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
303 printf("try a tconx with a bad device type\n");
304 tcon.tconx.in.device = "FOO";
305 status = smb_raw_tcon(tree, tctx, &tcon);
306 CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
309 printf("create a file using the new tid\n");
310 io.generic.level = RAW_OPEN_NTCREATEX;
311 io.ntcreatex.in.root_fid = 0;
312 io.ntcreatex.in.flags = 0;
313 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
314 io.ntcreatex.in.create_options = 0;
315 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
316 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
317 io.ntcreatex.in.alloc_size = 0;
318 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
319 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
320 io.ntcreatex.in.security_flags = 0;
321 io.ntcreatex.in.fname = fname;
322 status = smb_raw_open(tree, tctx, &io);
323 CHECK_STATUS(status, NT_STATUS_OK);
324 fnum = io.ntcreatex.out.file.fnum;
326 printf("write using the old tid\n");
327 wr.generic.level = RAW_WRITE_WRITEX;
328 wr.writex.in.file.fnum = fnum;
329 wr.writex.in.offset = 0;
330 wr.writex.in.wmode = 0;
331 wr.writex.in.remaining = 0;
332 wr.writex.in.count = 1;
333 wr.writex.in.data = &c;
335 status = smb_raw_write(cli->tree, &wr);
336 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
338 printf("write with the new tid\n");
339 status = smb_raw_write(tree, &wr);
340 CHECK_STATUS(status, NT_STATUS_OK);
341 CHECK_VALUE(wr.writex.out.nwritten, 1);
343 printf("disconnect the new tid\n");
344 status = smb_tree_disconnect(tree);
345 CHECK_STATUS(status, NT_STATUS_OK);
347 printf("the new tid should not now be accessible\n");
348 status = smb_raw_write(tree, &wr);
349 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
351 printf("the fnum should have been auto-closed\n");
352 cl.close.level = RAW_CLOSE_CLOSE;
353 cl.close.in.file.fnum = fnum;
354 cl.close.in.write_time = 0;
355 status = smb_raw_close(cli->tree, &cl);
356 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
358 /* close down the new tree */
366 test tree with ulogoff
367 this demonstrates that a tcon isn't autoclosed by a ulogoff
368 the tcon can be reused using any other valid session later
370 static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context *tctx)
374 const char *share, *host;
375 struct smbcli_session *session1;
376 struct smbcli_session *session2;
377 struct smb_composite_sesssetup setup;
378 struct smbcli_tree *tree;
383 const char *fname1 = BASEDIR "\\test1.txt";
384 const char *fname2 = BASEDIR "\\test2.txt";
386 struct smbcli_session_options options;
388 printf("TESTING TREE with ulogoff\n");
390 if (!torture_setup_dir(cli, BASEDIR)) {
394 share = torture_setting_string(tctx, "share", NULL);
395 host = torture_setting_string(tctx, "host", NULL);
397 lp_smbcli_session_options(tctx->lp_ctx, &options);
399 printf("create the first new sessions\n");
400 session1 = smbcli_session_init(cli->transport, tctx, false, options);
401 setup.in.sesskey = cli->transport->negotiate.sesskey;
402 setup.in.capabilities = cli->transport->negotiate.capabilities;
403 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
404 setup.in.credentials = cmdline_credentials;
405 status = smb_composite_sesssetup(session1, &setup);
406 CHECK_STATUS(status, NT_STATUS_OK);
407 session1->vuid = setup.out.vuid;
408 printf("vuid1=%d\n", session1->vuid);
410 printf("create a tree context on the with vuid1\n");
411 tree = smbcli_tree_init(session1, tctx, false);
412 tcon.generic.level = RAW_TCON_TCONX;
413 tcon.tconx.in.flags = 0;
414 tcon.tconx.in.password = data_blob(NULL, 0);
415 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
416 tcon.tconx.in.device = "A:";
417 status = smb_raw_tcon(tree, tctx, &tcon);
418 CHECK_STATUS(status, NT_STATUS_OK);
419 tree->tid = tcon.tconx.out.tid;
420 printf("tid=%d\n", tree->tid);
422 printf("create a file using vuid1\n");
423 io.generic.level = RAW_OPEN_NTCREATEX;
424 io.ntcreatex.in.root_fid = 0;
425 io.ntcreatex.in.flags = 0;
426 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
427 io.ntcreatex.in.create_options = 0;
428 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
429 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
430 io.ntcreatex.in.alloc_size = 0;
431 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
432 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
433 io.ntcreatex.in.security_flags = 0;
434 io.ntcreatex.in.fname = fname1;
435 status = smb_raw_open(tree, tctx, &io);
436 CHECK_STATUS(status, NT_STATUS_OK);
437 fnum1 = io.ntcreatex.out.file.fnum;
439 printf("write using vuid1\n");
440 wr.generic.level = RAW_WRITE_WRITEX;
441 wr.writex.in.file.fnum = fnum1;
442 wr.writex.in.offset = 0;
443 wr.writex.in.wmode = 0;
444 wr.writex.in.remaining = 0;
445 wr.writex.in.count = 1;
446 wr.writex.in.data = &c;
447 status = smb_raw_write(tree, &wr);
448 CHECK_STATUS(status, NT_STATUS_OK);
449 CHECK_VALUE(wr.writex.out.nwritten, 1);
451 printf("ulogoff the vuid1\n");
452 status = smb_raw_ulogoff(session1);
453 CHECK_STATUS(status, NT_STATUS_OK);
455 printf("create the second new sessions\n");
456 session2 = smbcli_session_init(cli->transport, tctx, false, options);
457 setup.in.sesskey = cli->transport->negotiate.sesskey;
458 setup.in.capabilities = cli->transport->negotiate.capabilities;
459 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
460 setup.in.credentials = cmdline_credentials;
461 status = smb_composite_sesssetup(session2, &setup);
462 CHECK_STATUS(status, NT_STATUS_OK);
463 session2->vuid = setup.out.vuid;
464 printf("vuid2=%d\n", session2->vuid);
466 printf("use the existing tree with vuid2\n");
467 tree->session = session2;
469 printf("create a file using vuid2\n");
470 io.generic.level = RAW_OPEN_NTCREATEX;
471 io.ntcreatex.in.root_fid = 0;
472 io.ntcreatex.in.flags = 0;
473 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
474 io.ntcreatex.in.create_options = 0;
475 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
476 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
477 io.ntcreatex.in.alloc_size = 0;
478 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
479 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
480 io.ntcreatex.in.security_flags = 0;
481 io.ntcreatex.in.fname = fname2;
482 status = smb_raw_open(tree, tctx, &io);
483 CHECK_STATUS(status, NT_STATUS_OK);
484 fnum2 = io.ntcreatex.out.file.fnum;
486 printf("write using vuid2\n");
487 wr.generic.level = RAW_WRITE_WRITEX;
488 wr.writex.in.file.fnum = fnum2;
489 wr.writex.in.offset = 0;
490 wr.writex.in.wmode = 0;
491 wr.writex.in.remaining = 0;
492 wr.writex.in.count = 1;
493 wr.writex.in.data = &c;
494 status = smb_raw_write(tree, &wr);
495 CHECK_STATUS(status, NT_STATUS_OK);
496 CHECK_VALUE(wr.writex.out.nwritten, 1);
498 printf("ulogoff the vuid2\n");
499 status = smb_raw_ulogoff(session2);
500 CHECK_STATUS(status, NT_STATUS_OK);
502 /* this also demonstrates that SMBtdis doesn't need a valid vuid */
503 printf("disconnect the existing tree connection\n");
504 status = smb_tree_disconnect(tree);
505 CHECK_STATUS(status, NT_STATUS_OK);
507 printf("disconnect the existing tree connection\n");
508 status = smb_tree_disconnect(tree);
509 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
511 /* close down the new tree */
520 this test demonstrates that exit() only sees the PID
521 used for the open() calls
523 static bool test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
531 const char *fname = BASEDIR "\\test.txt";
535 printf("TESTING PID HANDLING exit() only cares about open() PID\n");
537 if (!torture_setup_dir(cli, BASEDIR)) {
541 pid1 = cli->session->pid;
544 printf("pid1=%d pid2=%d\n", pid1, pid2);
546 printf("create a file using pid1\n");
547 cli->session->pid = pid1;
548 io.generic.level = RAW_OPEN_NTCREATEX;
549 io.ntcreatex.in.root_fid = 0;
550 io.ntcreatex.in.flags = 0;
551 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
552 io.ntcreatex.in.create_options = 0;
553 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
554 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
555 io.ntcreatex.in.alloc_size = 0;
556 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
557 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
558 io.ntcreatex.in.security_flags = 0;
559 io.ntcreatex.in.fname = fname;
560 status = smb_raw_open(cli->tree, mem_ctx, &io);
561 CHECK_STATUS(status, NT_STATUS_OK);
562 fnum = io.ntcreatex.out.file.fnum;
564 printf("write using pid2\n");
565 cli->session->pid = pid2;
566 wr.generic.level = RAW_WRITE_WRITEX;
567 wr.writex.in.file.fnum = fnum;
568 wr.writex.in.offset = 0;
569 wr.writex.in.wmode = 0;
570 wr.writex.in.remaining = 0;
571 wr.writex.in.count = 1;
572 wr.writex.in.data = &c;
573 status = smb_raw_write(cli->tree, &wr);
574 CHECK_STATUS(status, NT_STATUS_OK);
575 CHECK_VALUE(wr.writex.out.nwritten, 1);
577 printf("exit pid2\n");
578 cli->session->pid = pid2;
579 status = smb_raw_exit(cli->session);
580 CHECK_STATUS(status, NT_STATUS_OK);
582 printf("the fnum should still be accessible via pid2\n");
583 cli->session->pid = pid2;
584 status = smb_raw_write(cli->tree, &wr);
585 CHECK_STATUS(status, NT_STATUS_OK);
586 CHECK_VALUE(wr.writex.out.nwritten, 1);
588 printf("exit pid2\n");
589 cli->session->pid = pid2;
590 status = smb_raw_exit(cli->session);
591 CHECK_STATUS(status, NT_STATUS_OK);
593 printf("the fnum should still be accessible via pid1 and pid2\n");
594 cli->session->pid = pid1;
595 status = smb_raw_write(cli->tree, &wr);
596 CHECK_STATUS(status, NT_STATUS_OK);
597 CHECK_VALUE(wr.writex.out.nwritten, 1);
598 cli->session->pid = pid2;
599 status = smb_raw_write(cli->tree, &wr);
600 CHECK_STATUS(status, NT_STATUS_OK);
601 CHECK_VALUE(wr.writex.out.nwritten, 1);
603 printf("exit pid1\n");
604 cli->session->pid = pid1;
605 status = smb_raw_exit(cli->session);
606 CHECK_STATUS(status, NT_STATUS_OK);
608 printf("the fnum should not now be accessible via pid1 or pid2\n");
609 cli->session->pid = pid1;
610 status = smb_raw_write(cli->tree, &wr);
611 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
612 cli->session->pid = pid2;
613 status = smb_raw_write(cli->tree, &wr);
614 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
616 printf("the fnum should have been auto-closed\n");
617 cli->session->pid = pid1;
618 cl.close.level = RAW_CLOSE_CLOSE;
619 cl.close.in.file.fnum = fnum;
620 cl.close.in.write_time = 0;
621 status = smb_raw_close(cli->tree, &cl);
622 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
629 test pid ops with 2 sessions
631 static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tctx)
635 struct smbcli_session *session;
636 struct smb_composite_sesssetup setup;
641 const char *fname = BASEDIR "\\test.txt";
643 uint16_t vuid1, vuid2;
644 struct smbcli_session_options options;
646 printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
648 if (!torture_setup_dir(cli, BASEDIR)) {
652 lp_smbcli_session_options(tctx->lp_ctx, &options);
654 printf("create a second security context on the same transport\n");
655 session = smbcli_session_init(cli->transport, tctx, false, options);
657 setup.in.sesskey = cli->transport->negotiate.sesskey;
658 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
659 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
661 setup.in.credentials = cmdline_credentials;
663 status = smb_composite_sesssetup(session, &setup);
664 CHECK_STATUS(status, NT_STATUS_OK);
665 session->vuid = setup.out.vuid;
667 vuid1 = cli->session->vuid;
668 vuid2 = session->vuid;
670 printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
672 printf("create a file using the vuid1\n");
673 cli->session->vuid = vuid1;
674 io.generic.level = RAW_OPEN_NTCREATEX;
675 io.ntcreatex.in.root_fid = 0;
676 io.ntcreatex.in.flags = 0;
677 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
678 io.ntcreatex.in.create_options = 0;
679 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
680 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
681 io.ntcreatex.in.alloc_size = 0;
682 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
683 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
684 io.ntcreatex.in.security_flags = 0;
685 io.ntcreatex.in.fname = fname;
686 status = smb_raw_open(cli->tree, tctx, &io);
687 CHECK_STATUS(status, NT_STATUS_OK);
688 fnum = io.ntcreatex.out.file.fnum;
690 printf("write using the vuid1 (fnum=%d)\n", fnum);
691 cli->session->vuid = vuid1;
692 wr.generic.level = RAW_WRITE_WRITEX;
693 wr.writex.in.file.fnum = fnum;
694 wr.writex.in.offset = 0;
695 wr.writex.in.wmode = 0;
696 wr.writex.in.remaining = 0;
697 wr.writex.in.count = 1;
698 wr.writex.in.data = &c;
700 status = smb_raw_write(cli->tree, &wr);
701 CHECK_STATUS(status, NT_STATUS_OK);
702 CHECK_VALUE(wr.writex.out.nwritten, 1);
704 printf("exit the pid with vuid2\n");
705 cli->session->vuid = vuid2;
706 status = smb_raw_exit(cli->session);
707 CHECK_STATUS(status, NT_STATUS_OK);
709 printf("the fnum should still be accessible\n");
710 cli->session->vuid = vuid1;
711 status = smb_raw_write(cli->tree, &wr);
712 CHECK_STATUS(status, NT_STATUS_OK);
713 CHECK_VALUE(wr.writex.out.nwritten, 1);
715 printf("exit the pid with vuid1\n");
716 cli->session->vuid = vuid1;
717 status = smb_raw_exit(cli->session);
718 CHECK_STATUS(status, NT_STATUS_OK);
720 printf("the fnum should not now be accessible\n");
721 status = smb_raw_write(cli->tree, &wr);
722 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
724 printf("the fnum should have been auto-closed\n");
725 cl.close.level = RAW_CLOSE_CLOSE;
726 cl.close.in.file.fnum = fnum;
727 cl.close.in.write_time = 0;
728 status = smb_raw_close(cli->tree, &cl);
729 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
736 test pid ops with 2 tcons
738 static bool test_pid_2tcon(struct smbcli_state *cli, struct torture_context *tctx)
742 const char *share, *host;
743 struct smbcli_tree *tree;
749 const char *fname1 = BASEDIR "\\test1.txt";
750 const char *fname2 = BASEDIR "\\test2.txt";
754 printf("TESTING PID HANDLING WITH 2 TCONS\n");
756 if (!torture_setup_dir(cli, BASEDIR)) {
760 share = torture_setting_string(tctx, "share", NULL);
761 host = torture_setting_string(tctx, "host", NULL);
763 printf("create a second tree context on the same session\n");
764 tree = smbcli_tree_init(cli->session, tctx, false);
766 tcon.generic.level = RAW_TCON_TCONX;
767 tcon.tconx.in.flags = 0;
768 tcon.tconx.in.password = data_blob(NULL, 0);
769 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
770 tcon.tconx.in.device = "A:";
771 status = smb_raw_tcon(tree, tctx, &tcon);
772 CHECK_STATUS(status, NT_STATUS_OK);
774 tree->tid = tcon.tconx.out.tid;
776 tid1 = cli->tree->tid;
778 printf("tid1=%d tid2=%d\n", tid1, tid2);
780 printf("create a file using the tid1\n");
781 cli->tree->tid = tid1;
782 io.generic.level = RAW_OPEN_NTCREATEX;
783 io.ntcreatex.in.root_fid = 0;
784 io.ntcreatex.in.flags = 0;
785 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
786 io.ntcreatex.in.create_options = 0;
787 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
788 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
789 io.ntcreatex.in.alloc_size = 0;
790 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
791 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
792 io.ntcreatex.in.security_flags = 0;
793 io.ntcreatex.in.fname = fname1;
794 status = smb_raw_open(cli->tree, tctx, &io);
795 CHECK_STATUS(status, NT_STATUS_OK);
796 fnum1 = io.ntcreatex.out.file.fnum;
798 printf("write using the tid1\n");
799 wr.generic.level = RAW_WRITE_WRITEX;
800 wr.writex.in.file.fnum = fnum1;
801 wr.writex.in.offset = 0;
802 wr.writex.in.wmode = 0;
803 wr.writex.in.remaining = 0;
804 wr.writex.in.count = 1;
805 wr.writex.in.data = &c;
807 status = smb_raw_write(cli->tree, &wr);
808 CHECK_STATUS(status, NT_STATUS_OK);
809 CHECK_VALUE(wr.writex.out.nwritten, 1);
811 printf("create a file using the tid2\n");
812 cli->tree->tid = tid2;
813 io.generic.level = RAW_OPEN_NTCREATEX;
814 io.ntcreatex.in.root_fid = 0;
815 io.ntcreatex.in.flags = 0;
816 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
817 io.ntcreatex.in.create_options = 0;
818 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
819 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
820 io.ntcreatex.in.alloc_size = 0;
821 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
822 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
823 io.ntcreatex.in.security_flags = 0;
824 io.ntcreatex.in.fname = fname2;
825 status = smb_raw_open(cli->tree, tctx, &io);
826 CHECK_STATUS(status, NT_STATUS_OK);
827 fnum2 = io.ntcreatex.out.file.fnum;
829 printf("write using the tid2\n");
830 wr.generic.level = RAW_WRITE_WRITEX;
831 wr.writex.in.file.fnum = fnum2;
832 wr.writex.in.offset = 0;
833 wr.writex.in.wmode = 0;
834 wr.writex.in.remaining = 0;
835 wr.writex.in.count = 1;
836 wr.writex.in.data = &c;
838 status = smb_raw_write(cli->tree, &wr);
839 CHECK_STATUS(status, NT_STATUS_OK);
840 CHECK_VALUE(wr.writex.out.nwritten, 1);
842 printf("exit the pid\n");
843 status = smb_raw_exit(cli->session);
844 CHECK_STATUS(status, NT_STATUS_OK);
846 printf("the fnum1 on tid1 should not be accessible\n");
847 cli->tree->tid = tid1;
848 wr.writex.in.file.fnum = fnum1;
849 status = smb_raw_write(cli->tree, &wr);
850 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
852 printf("the fnum1 on tid1 should have been auto-closed\n");
853 cl.close.level = RAW_CLOSE_CLOSE;
854 cl.close.in.file.fnum = fnum1;
855 cl.close.in.write_time = 0;
856 status = smb_raw_close(cli->tree, &cl);
857 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
859 printf("the fnum2 on tid2 should not be accessible\n");
860 cli->tree->tid = tid2;
861 wr.writex.in.file.fnum = fnum2;
862 status = smb_raw_write(cli->tree, &wr);
863 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
865 printf("the fnum2 on tid2 should have been auto-closed\n");
866 cl.close.level = RAW_CLOSE_CLOSE;
867 cl.close.in.file.fnum = fnum2;
868 cl.close.in.write_time = 0;
869 status = smb_raw_close(cli->tree, &cl);
870 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
878 basic testing of session/tree context calls
880 static bool torture_raw_context_int(struct torture_context *tctx,
881 struct smbcli_state *cli)
885 ret &= test_session(cli, tctx);
886 ret &= test_tree(cli, tctx);
887 ret &= test_tree_ulogoff(cli, tctx);
888 ret &= test_pid_exit_only_sees_open(cli, tctx);
889 ret &= test_pid_2sess(cli, tctx);
890 ret &= test_pid_2tcon(cli, tctx);
892 smb_raw_exit(cli->session);
893 smbcli_deltree(cli->tree, BASEDIR);
898 basic testing of session/tree context calls
900 bool torture_raw_context(struct torture_context *torture,
901 struct smbcli_state *cli)
904 if (lp_use_spnego(torture->lp_ctx)) {
905 ret &= torture_raw_context_int(torture, cli);
906 lp_set_cmdline(torture->lp_ctx, "use spnego", "False");
909 ret &= torture_raw_context_int(torture, cli);