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";
85 printf("TESTING SESSION HANDLING\n");
87 if (!torture_setup_dir(cli, BASEDIR)) {
91 printf("create a second security context on the same transport\n");
92 session = smbcli_session_init(cli->transport, tctx, false);
94 setup.in.sesskey = cli->transport->negotiate.sesskey;
95 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
96 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
98 setup.in.credentials = cmdline_credentials;
100 status = smb_composite_sesssetup(session, &setup);
101 CHECK_STATUS(status, NT_STATUS_OK);
103 session->vuid = setup.out.vuid;
105 printf("create a third security context on the same transport, with vuid set\n");
106 session2 = smbcli_session_init(cli->transport, tctx, false);
108 session2->vuid = session->vuid;
109 setup.in.sesskey = cli->transport->negotiate.sesskey;
110 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
111 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
113 setup.in.credentials = cmdline_credentials;
115 status = smb_composite_sesssetup(session2, &setup);
116 CHECK_STATUS(status, NT_STATUS_OK);
118 session2->vuid = setup.out.vuid;
119 printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
121 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
122 /* Samba4 currently fails this - we need to determine if this insane behaviour is important */
123 if (session2->vuid == session->vuid) {
124 printf("server allows the user to re-use an existing vuid in session setup \n");
127 CHECK_NOT_VALUE(session2->vuid, session->vuid);
129 talloc_free(session2);
131 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
132 printf("create a fourth security context on the same transport, without extended security\n");
133 session3 = smbcli_session_init(cli->transport, tctx, false);
135 session3->vuid = session->vuid;
136 setup.in.sesskey = cli->transport->negotiate.sesskey;
137 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
138 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
140 setup.in.credentials = cmdline_credentials;
143 status = smb_composite_sesssetup(session3, &setup);
144 CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
146 printf("create a fouth anonymous security context on the same transport, without extended security\n");
147 session4 = smbcli_session_init(cli->transport, tctx, false);
149 session4->vuid = session->vuid;
150 setup.in.sesskey = cli->transport->negotiate.sesskey;
151 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
152 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
154 anon_creds = cli_credentials_init(tctx);
155 cli_credentials_set_conf(anon_creds, tctx->lp_ctx);
156 cli_credentials_set_anonymous(anon_creds);
158 setup.in.credentials = anon_creds;
160 status = smb_composite_sesssetup(session3, &setup);
161 CHECK_STATUS(status, NT_STATUS_OK);
163 talloc_free(session4);
166 printf("use the same tree as the existing connection\n");
167 tree = smbcli_tree_init(session, tctx, false);
168 tree->tid = cli->tree->tid;
170 printf("create a file using the new vuid\n");
171 io.generic.level = RAW_OPEN_NTCREATEX;
172 io.ntcreatex.in.root_fid = 0;
173 io.ntcreatex.in.flags = 0;
174 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
175 io.ntcreatex.in.create_options = 0;
176 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
177 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
178 io.ntcreatex.in.alloc_size = 0;
179 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
180 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
181 io.ntcreatex.in.security_flags = 0;
182 io.ntcreatex.in.fname = fname;
183 status = smb_raw_open(tree, tctx, &io);
184 CHECK_STATUS(status, NT_STATUS_OK);
185 fnum = io.ntcreatex.out.file.fnum;
187 printf("write using the old vuid\n");
188 wr.generic.level = RAW_WRITE_WRITEX;
189 wr.writex.in.file.fnum = fnum;
190 wr.writex.in.offset = 0;
191 wr.writex.in.wmode = 0;
192 wr.writex.in.remaining = 0;
193 wr.writex.in.count = 1;
194 wr.writex.in.data = &c;
196 status = smb_raw_write(cli->tree, &wr);
197 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
199 printf("write with the new vuid\n");
200 status = smb_raw_write(tree, &wr);
201 CHECK_STATUS(status, NT_STATUS_OK);
202 CHECK_VALUE(wr.writex.out.nwritten, 1);
204 printf("logoff the new vuid\n");
205 status = smb_raw_ulogoff(session);
206 CHECK_STATUS(status, NT_STATUS_OK);
208 printf("the new vuid should not now be accessible\n");
209 status = smb_raw_write(tree, &wr);
210 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
212 printf("second logoff for the new vuid should fail\n");
213 status = smb_raw_ulogoff(session);
214 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRbaduid));
215 talloc_free(session);
217 printf("the fnum should have been auto-closed\n");
218 cl.close.level = RAW_CLOSE_CLOSE;
219 cl.close.in.file.fnum = fnum;
220 cl.close.in.write_time = 0;
221 status = smb_raw_close(cli->tree, &cl);
222 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
224 printf("create %d secondary security contexts on the same transport\n",
225 (int)ARRAY_SIZE(sessions));
226 for (i=0; i <ARRAY_SIZE(sessions); i++) {
227 setups[i].in.sesskey = cli->transport->negotiate.sesskey;
228 setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
229 setups[i].in.workgroup = lp_workgroup(tctx->lp_ctx);
231 setups[i].in.credentials = cmdline_credentials;
233 sessions[i] = smbcli_session_init(cli->transport, tctx, false);
234 composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
239 printf("finishing %d secondary security contexts on the same transport\n",
240 (int)ARRAY_SIZE(sessions));
241 for (i=0; i< ARRAY_SIZE(sessions); i++) {
242 status = smb_composite_sesssetup_recv(composite_contexts[i]);
243 CHECK_STATUS(status, NT_STATUS_OK);
244 sessions[i]->vuid = setups[i].out.vuid;
245 printf("VUID: %d\n", sessions[i]->vuid);
246 status = smb_raw_ulogoff(sessions[i]);
247 CHECK_STATUS(status, NT_STATUS_OK);
261 static bool test_tree(struct smbcli_state *cli, struct torture_context *tctx)
265 const char *share, *host;
266 struct smbcli_tree *tree;
272 const char *fname = BASEDIR "\\test.txt";
275 printf("TESTING TREE HANDLING\n");
277 if (!torture_setup_dir(cli, BASEDIR)) {
281 share = torture_setting_string(tctx, "share", NULL);
282 host = torture_setting_string(tctx, "host", NULL);
284 printf("create a second tree context on the same session\n");
285 tree = smbcli_tree_init(cli->session, tctx, false);
287 tcon.generic.level = RAW_TCON_TCONX;
288 tcon.tconx.in.flags = 0;
289 tcon.tconx.in.password = data_blob(NULL, 0);
290 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
291 tcon.tconx.in.device = "A:";
292 status = smb_raw_tcon(tree, tctx, &tcon);
293 CHECK_STATUS(status, NT_STATUS_OK);
296 tree->tid = tcon.tconx.out.tid;
297 printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
299 printf("try a tconx with a bad device type\n");
300 tcon.tconx.in.device = "FOO";
301 status = smb_raw_tcon(tree, tctx, &tcon);
302 CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
305 printf("create a file using the new tid\n");
306 io.generic.level = RAW_OPEN_NTCREATEX;
307 io.ntcreatex.in.root_fid = 0;
308 io.ntcreatex.in.flags = 0;
309 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
310 io.ntcreatex.in.create_options = 0;
311 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
312 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
313 io.ntcreatex.in.alloc_size = 0;
314 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
315 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
316 io.ntcreatex.in.security_flags = 0;
317 io.ntcreatex.in.fname = fname;
318 status = smb_raw_open(tree, tctx, &io);
319 CHECK_STATUS(status, NT_STATUS_OK);
320 fnum = io.ntcreatex.out.file.fnum;
322 printf("write using the old tid\n");
323 wr.generic.level = RAW_WRITE_WRITEX;
324 wr.writex.in.file.fnum = fnum;
325 wr.writex.in.offset = 0;
326 wr.writex.in.wmode = 0;
327 wr.writex.in.remaining = 0;
328 wr.writex.in.count = 1;
329 wr.writex.in.data = &c;
331 status = smb_raw_write(cli->tree, &wr);
332 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
334 printf("write with the new tid\n");
335 status = smb_raw_write(tree, &wr);
336 CHECK_STATUS(status, NT_STATUS_OK);
337 CHECK_VALUE(wr.writex.out.nwritten, 1);
339 printf("disconnect the new tid\n");
340 status = smb_tree_disconnect(tree);
341 CHECK_STATUS(status, NT_STATUS_OK);
343 printf("the new tid should not now be accessible\n");
344 status = smb_raw_write(tree, &wr);
345 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
347 printf("the fnum should have been auto-closed\n");
348 cl.close.level = RAW_CLOSE_CLOSE;
349 cl.close.in.file.fnum = fnum;
350 cl.close.in.write_time = 0;
351 status = smb_raw_close(cli->tree, &cl);
352 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
354 /* close down the new tree */
362 test tree with ulogoff
363 this demonstrates that a tcon isn't autoclosed by a ulogoff
364 the tcon can be reused using any other valid session later
366 static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context *tctx)
370 const char *share, *host;
371 struct smbcli_session *session1;
372 struct smbcli_session *session2;
373 struct smb_composite_sesssetup setup;
374 struct smbcli_tree *tree;
379 const char *fname1 = BASEDIR "\\test1.txt";
380 const char *fname2 = BASEDIR "\\test2.txt";
383 printf("TESTING TREE with ulogoff\n");
385 if (!torture_setup_dir(cli, BASEDIR)) {
389 share = torture_setting_string(tctx, "share", NULL);
390 host = torture_setting_string(tctx, "host", NULL);
392 printf("create the first new sessions\n");
393 session1 = smbcli_session_init(cli->transport, tctx, false);
394 setup.in.sesskey = cli->transport->negotiate.sesskey;
395 setup.in.capabilities = cli->transport->negotiate.capabilities;
396 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
397 setup.in.credentials = cmdline_credentials;
398 status = smb_composite_sesssetup(session1, &setup);
399 CHECK_STATUS(status, NT_STATUS_OK);
400 session1->vuid = setup.out.vuid;
401 printf("vuid1=%d\n", session1->vuid);
403 printf("create a tree context on the with vuid1\n");
404 tree = smbcli_tree_init(session1, tctx, false);
405 tcon.generic.level = RAW_TCON_TCONX;
406 tcon.tconx.in.flags = 0;
407 tcon.tconx.in.password = data_blob(NULL, 0);
408 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
409 tcon.tconx.in.device = "A:";
410 status = smb_raw_tcon(tree, tctx, &tcon);
411 CHECK_STATUS(status, NT_STATUS_OK);
412 tree->tid = tcon.tconx.out.tid;
413 printf("tid=%d\n", tree->tid);
415 printf("create a file using vuid1\n");
416 io.generic.level = RAW_OPEN_NTCREATEX;
417 io.ntcreatex.in.root_fid = 0;
418 io.ntcreatex.in.flags = 0;
419 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
420 io.ntcreatex.in.create_options = 0;
421 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
422 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
423 io.ntcreatex.in.alloc_size = 0;
424 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
425 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
426 io.ntcreatex.in.security_flags = 0;
427 io.ntcreatex.in.fname = fname1;
428 status = smb_raw_open(tree, tctx, &io);
429 CHECK_STATUS(status, NT_STATUS_OK);
430 fnum1 = io.ntcreatex.out.file.fnum;
432 printf("write using vuid1\n");
433 wr.generic.level = RAW_WRITE_WRITEX;
434 wr.writex.in.file.fnum = fnum1;
435 wr.writex.in.offset = 0;
436 wr.writex.in.wmode = 0;
437 wr.writex.in.remaining = 0;
438 wr.writex.in.count = 1;
439 wr.writex.in.data = &c;
440 status = smb_raw_write(tree, &wr);
441 CHECK_STATUS(status, NT_STATUS_OK);
442 CHECK_VALUE(wr.writex.out.nwritten, 1);
444 printf("ulogoff the vuid1\n");
445 status = smb_raw_ulogoff(session1);
446 CHECK_STATUS(status, NT_STATUS_OK);
448 printf("create the second new sessions\n");
449 session2 = smbcli_session_init(cli->transport, tctx, false);
450 setup.in.sesskey = cli->transport->negotiate.sesskey;
451 setup.in.capabilities = cli->transport->negotiate.capabilities;
452 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
453 setup.in.credentials = cmdline_credentials;
454 status = smb_composite_sesssetup(session2, &setup);
455 CHECK_STATUS(status, NT_STATUS_OK);
456 session2->vuid = setup.out.vuid;
457 printf("vuid2=%d\n", session2->vuid);
459 printf("use the existing tree with vuid2\n");
460 tree->session = session2;
462 printf("create a file using vuid2\n");
463 io.generic.level = RAW_OPEN_NTCREATEX;
464 io.ntcreatex.in.root_fid = 0;
465 io.ntcreatex.in.flags = 0;
466 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
467 io.ntcreatex.in.create_options = 0;
468 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
469 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
470 io.ntcreatex.in.alloc_size = 0;
471 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
472 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
473 io.ntcreatex.in.security_flags = 0;
474 io.ntcreatex.in.fname = fname2;
475 status = smb_raw_open(tree, tctx, &io);
476 CHECK_STATUS(status, NT_STATUS_OK);
477 fnum2 = io.ntcreatex.out.file.fnum;
479 printf("write using vuid2\n");
480 wr.generic.level = RAW_WRITE_WRITEX;
481 wr.writex.in.file.fnum = fnum2;
482 wr.writex.in.offset = 0;
483 wr.writex.in.wmode = 0;
484 wr.writex.in.remaining = 0;
485 wr.writex.in.count = 1;
486 wr.writex.in.data = &c;
487 status = smb_raw_write(tree, &wr);
488 CHECK_STATUS(status, NT_STATUS_OK);
489 CHECK_VALUE(wr.writex.out.nwritten, 1);
491 printf("ulogoff the vuid2\n");
492 status = smb_raw_ulogoff(session2);
493 CHECK_STATUS(status, NT_STATUS_OK);
495 /* this also demonstrates that SMBtdis doesn't need a valid vuid */
496 printf("disconnect the existing tree connection\n");
497 status = smb_tree_disconnect(tree);
498 CHECK_STATUS(status, NT_STATUS_OK);
500 printf("disconnect the existing tree connection\n");
501 status = smb_tree_disconnect(tree);
502 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
504 /* close down the new tree */
513 this test demonstrates that exit() only sees the PID
514 used for the open() calls
516 static bool test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
524 const char *fname = BASEDIR "\\test.txt";
528 printf("TESTING PID HANDLING exit() only cares about open() PID\n");
530 if (!torture_setup_dir(cli, BASEDIR)) {
534 pid1 = cli->session->pid;
537 printf("pid1=%d pid2=%d\n", pid1, pid2);
539 printf("create a file using pid1\n");
540 cli->session->pid = pid1;
541 io.generic.level = RAW_OPEN_NTCREATEX;
542 io.ntcreatex.in.root_fid = 0;
543 io.ntcreatex.in.flags = 0;
544 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
545 io.ntcreatex.in.create_options = 0;
546 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
547 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
548 io.ntcreatex.in.alloc_size = 0;
549 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
550 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
551 io.ntcreatex.in.security_flags = 0;
552 io.ntcreatex.in.fname = fname;
553 status = smb_raw_open(cli->tree, mem_ctx, &io);
554 CHECK_STATUS(status, NT_STATUS_OK);
555 fnum = io.ntcreatex.out.file.fnum;
557 printf("write using pid2\n");
558 cli->session->pid = pid2;
559 wr.generic.level = RAW_WRITE_WRITEX;
560 wr.writex.in.file.fnum = fnum;
561 wr.writex.in.offset = 0;
562 wr.writex.in.wmode = 0;
563 wr.writex.in.remaining = 0;
564 wr.writex.in.count = 1;
565 wr.writex.in.data = &c;
566 status = smb_raw_write(cli->tree, &wr);
567 CHECK_STATUS(status, NT_STATUS_OK);
568 CHECK_VALUE(wr.writex.out.nwritten, 1);
570 printf("exit pid2\n");
571 cli->session->pid = pid2;
572 status = smb_raw_exit(cli->session);
573 CHECK_STATUS(status, NT_STATUS_OK);
575 printf("the fnum should still be accessible via pid2\n");
576 cli->session->pid = pid2;
577 status = smb_raw_write(cli->tree, &wr);
578 CHECK_STATUS(status, NT_STATUS_OK);
579 CHECK_VALUE(wr.writex.out.nwritten, 1);
581 printf("exit pid2\n");
582 cli->session->pid = pid2;
583 status = smb_raw_exit(cli->session);
584 CHECK_STATUS(status, NT_STATUS_OK);
586 printf("the fnum should still be accessible via pid1 and pid2\n");
587 cli->session->pid = pid1;
588 status = smb_raw_write(cli->tree, &wr);
589 CHECK_STATUS(status, NT_STATUS_OK);
590 CHECK_VALUE(wr.writex.out.nwritten, 1);
591 cli->session->pid = pid2;
592 status = smb_raw_write(cli->tree, &wr);
593 CHECK_STATUS(status, NT_STATUS_OK);
594 CHECK_VALUE(wr.writex.out.nwritten, 1);
596 printf("exit pid1\n");
597 cli->session->pid = pid1;
598 status = smb_raw_exit(cli->session);
599 CHECK_STATUS(status, NT_STATUS_OK);
601 printf("the fnum should not now be accessible via pid1 or pid2\n");
602 cli->session->pid = pid1;
603 status = smb_raw_write(cli->tree, &wr);
604 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
605 cli->session->pid = pid2;
606 status = smb_raw_write(cli->tree, &wr);
607 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
609 printf("the fnum should have been auto-closed\n");
610 cli->session->pid = pid1;
611 cl.close.level = RAW_CLOSE_CLOSE;
612 cl.close.in.file.fnum = fnum;
613 cl.close.in.write_time = 0;
614 status = smb_raw_close(cli->tree, &cl);
615 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
622 test pid ops with 2 sessions
624 static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tctx)
628 struct smbcli_session *session;
629 struct smb_composite_sesssetup setup;
634 const char *fname = BASEDIR "\\test.txt";
636 uint16_t vuid1, vuid2;
638 printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
640 if (!torture_setup_dir(cli, BASEDIR)) {
644 printf("create a second security context on the same transport\n");
645 session = smbcli_session_init(cli->transport, tctx, false);
647 setup.in.sesskey = cli->transport->negotiate.sesskey;
648 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
649 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
651 setup.in.credentials = cmdline_credentials;
653 status = smb_composite_sesssetup(session, &setup);
654 CHECK_STATUS(status, NT_STATUS_OK);
655 session->vuid = setup.out.vuid;
657 vuid1 = cli->session->vuid;
658 vuid2 = session->vuid;
660 printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
662 printf("create a file using the vuid1\n");
663 cli->session->vuid = vuid1;
664 io.generic.level = RAW_OPEN_NTCREATEX;
665 io.ntcreatex.in.root_fid = 0;
666 io.ntcreatex.in.flags = 0;
667 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
668 io.ntcreatex.in.create_options = 0;
669 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
670 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
671 io.ntcreatex.in.alloc_size = 0;
672 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
673 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
674 io.ntcreatex.in.security_flags = 0;
675 io.ntcreatex.in.fname = fname;
676 status = smb_raw_open(cli->tree, tctx, &io);
677 CHECK_STATUS(status, NT_STATUS_OK);
678 fnum = io.ntcreatex.out.file.fnum;
680 printf("write using the vuid1 (fnum=%d)\n", fnum);
681 cli->session->vuid = vuid1;
682 wr.generic.level = RAW_WRITE_WRITEX;
683 wr.writex.in.file.fnum = fnum;
684 wr.writex.in.offset = 0;
685 wr.writex.in.wmode = 0;
686 wr.writex.in.remaining = 0;
687 wr.writex.in.count = 1;
688 wr.writex.in.data = &c;
690 status = smb_raw_write(cli->tree, &wr);
691 CHECK_STATUS(status, NT_STATUS_OK);
692 CHECK_VALUE(wr.writex.out.nwritten, 1);
694 printf("exit the pid with vuid2\n");
695 cli->session->vuid = vuid2;
696 status = smb_raw_exit(cli->session);
697 CHECK_STATUS(status, NT_STATUS_OK);
699 printf("the fnum should still be accessible\n");
700 cli->session->vuid = vuid1;
701 status = smb_raw_write(cli->tree, &wr);
702 CHECK_STATUS(status, NT_STATUS_OK);
703 CHECK_VALUE(wr.writex.out.nwritten, 1);
705 printf("exit the pid with vuid1\n");
706 cli->session->vuid = vuid1;
707 status = smb_raw_exit(cli->session);
708 CHECK_STATUS(status, NT_STATUS_OK);
710 printf("the fnum should not now be accessible\n");
711 status = smb_raw_write(cli->tree, &wr);
712 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
714 printf("the fnum should have been auto-closed\n");
715 cl.close.level = RAW_CLOSE_CLOSE;
716 cl.close.in.file.fnum = fnum;
717 cl.close.in.write_time = 0;
718 status = smb_raw_close(cli->tree, &cl);
719 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
726 test pid ops with 2 tcons
728 static bool test_pid_2tcon(struct smbcli_state *cli, struct torture_context *tctx)
732 const char *share, *host;
733 struct smbcli_tree *tree;
739 const char *fname1 = BASEDIR "\\test1.txt";
740 const char *fname2 = BASEDIR "\\test2.txt";
744 printf("TESTING PID HANDLING WITH 2 TCONS\n");
746 if (!torture_setup_dir(cli, BASEDIR)) {
750 share = torture_setting_string(tctx, "share", NULL);
751 host = torture_setting_string(tctx, "host", NULL);
753 printf("create a second tree context on the same session\n");
754 tree = smbcli_tree_init(cli->session, tctx, false);
756 tcon.generic.level = RAW_TCON_TCONX;
757 tcon.tconx.in.flags = 0;
758 tcon.tconx.in.password = data_blob(NULL, 0);
759 tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
760 tcon.tconx.in.device = "A:";
761 status = smb_raw_tcon(tree, tctx, &tcon);
762 CHECK_STATUS(status, NT_STATUS_OK);
764 tree->tid = tcon.tconx.out.tid;
766 tid1 = cli->tree->tid;
768 printf("tid1=%d tid2=%d\n", tid1, tid2);
770 printf("create a file using the tid1\n");
771 cli->tree->tid = tid1;
772 io.generic.level = RAW_OPEN_NTCREATEX;
773 io.ntcreatex.in.root_fid = 0;
774 io.ntcreatex.in.flags = 0;
775 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
776 io.ntcreatex.in.create_options = 0;
777 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
778 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
779 io.ntcreatex.in.alloc_size = 0;
780 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
781 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
782 io.ntcreatex.in.security_flags = 0;
783 io.ntcreatex.in.fname = fname1;
784 status = smb_raw_open(cli->tree, tctx, &io);
785 CHECK_STATUS(status, NT_STATUS_OK);
786 fnum1 = io.ntcreatex.out.file.fnum;
788 printf("write using the tid1\n");
789 wr.generic.level = RAW_WRITE_WRITEX;
790 wr.writex.in.file.fnum = fnum1;
791 wr.writex.in.offset = 0;
792 wr.writex.in.wmode = 0;
793 wr.writex.in.remaining = 0;
794 wr.writex.in.count = 1;
795 wr.writex.in.data = &c;
797 status = smb_raw_write(cli->tree, &wr);
798 CHECK_STATUS(status, NT_STATUS_OK);
799 CHECK_VALUE(wr.writex.out.nwritten, 1);
801 printf("create a file using the tid2\n");
802 cli->tree->tid = tid2;
803 io.generic.level = RAW_OPEN_NTCREATEX;
804 io.ntcreatex.in.root_fid = 0;
805 io.ntcreatex.in.flags = 0;
806 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
807 io.ntcreatex.in.create_options = 0;
808 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
809 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
810 io.ntcreatex.in.alloc_size = 0;
811 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
812 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
813 io.ntcreatex.in.security_flags = 0;
814 io.ntcreatex.in.fname = fname2;
815 status = smb_raw_open(cli->tree, tctx, &io);
816 CHECK_STATUS(status, NT_STATUS_OK);
817 fnum2 = io.ntcreatex.out.file.fnum;
819 printf("write using the tid2\n");
820 wr.generic.level = RAW_WRITE_WRITEX;
821 wr.writex.in.file.fnum = fnum2;
822 wr.writex.in.offset = 0;
823 wr.writex.in.wmode = 0;
824 wr.writex.in.remaining = 0;
825 wr.writex.in.count = 1;
826 wr.writex.in.data = &c;
828 status = smb_raw_write(cli->tree, &wr);
829 CHECK_STATUS(status, NT_STATUS_OK);
830 CHECK_VALUE(wr.writex.out.nwritten, 1);
832 printf("exit the pid\n");
833 status = smb_raw_exit(cli->session);
834 CHECK_STATUS(status, NT_STATUS_OK);
836 printf("the fnum1 on tid1 should not be accessible\n");
837 cli->tree->tid = tid1;
838 wr.writex.in.file.fnum = fnum1;
839 status = smb_raw_write(cli->tree, &wr);
840 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
842 printf("the fnum1 on tid1 should have been auto-closed\n");
843 cl.close.level = RAW_CLOSE_CLOSE;
844 cl.close.in.file.fnum = fnum1;
845 cl.close.in.write_time = 0;
846 status = smb_raw_close(cli->tree, &cl);
847 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
849 printf("the fnum2 on tid2 should not be accessible\n");
850 cli->tree->tid = tid2;
851 wr.writex.in.file.fnum = fnum2;
852 status = smb_raw_write(cli->tree, &wr);
853 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
855 printf("the fnum2 on tid2 should have been auto-closed\n");
856 cl.close.level = RAW_CLOSE_CLOSE;
857 cl.close.in.file.fnum = fnum2;
858 cl.close.in.write_time = 0;
859 status = smb_raw_close(cli->tree, &cl);
860 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
868 basic testing of session/tree context calls
870 static bool torture_raw_context_int(struct torture_context *tctx,
871 struct smbcli_state *cli)
875 ret &= test_session(cli, tctx);
876 ret &= test_tree(cli, tctx);
877 ret &= test_tree_ulogoff(cli, tctx);
878 ret &= test_pid_exit_only_sees_open(cli, tctx);
879 ret &= test_pid_2sess(cli, tctx);
880 ret &= test_pid_2tcon(cli, tctx);
882 smb_raw_exit(cli->session);
883 smbcli_deltree(cli->tree, BASEDIR);
888 basic testing of session/tree context calls
890 bool torture_raw_context(struct torture_context *torture,
891 struct smbcli_state *cli)
894 if (lp_use_spnego(torture->lp_ctx)) {
895 ret &= torture_raw_context_int(torture, cli);
896 lp_set_cmdline(torture->lp_ctx, "use spnego", "False");
899 ret &= torture_raw_context_int(torture, cli);