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/composite/composite.h"
24 #include "libcli/smb_composite/smb_composite.h"
25 #include "lib/cmdline/popt_common.h"
26 #include "lib/events/events.h"
27 #include "libcli/libcli.h"
28 #include "torture/util.h"
29 #include "auth/credentials/credentials.h"
30 #include "param/param.h"
32 #define BASEDIR "\\rawcontext"
34 #define CHECK_STATUS(status, correct) do { \
35 if (!NT_STATUS_EQUAL(status, correct)) { \
36 printf("(%s) Incorrect status %s - should be %s\n", \
37 __location__, nt_errstr(status), nt_errstr(correct)); \
42 #define CHECK_VALUE(v, correct) do { \
43 if ((v) != (correct)) { \
44 printf("(%s) Incorrect value %s=%d - should be %d\n", \
45 __location__, #v, v, correct); \
50 #define CHECK_NOT_VALUE(v, correct) do { \
51 if ((v) == (correct)) { \
52 printf("(%s) Incorrect value %s=%d - should not be %d\n", \
53 __location__, #v, v, correct); \
62 static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
66 struct smbcli_session *session;
67 struct smbcli_session *session2;
68 struct smbcli_session *session3;
69 struct smbcli_session *session4;
70 struct cli_credentials *anon_creds;
71 struct smbcli_session *sessions[15];
72 struct composite_context *composite_contexts[15];
73 struct smbcli_tree *tree;
74 struct smb_composite_sesssetup setup;
75 struct smb_composite_sesssetup setups[15];
80 const char *fname = BASEDIR "\\test.txt";
84 printf("TESTING SESSION HANDLING\n");
86 if (!torture_setup_dir(cli, BASEDIR)) {
90 printf("create a second security context on the same transport\n");
91 session = smbcli_session_init(cli->transport, mem_ctx, False);
93 setup.in.sesskey = cli->transport->negotiate.sesskey;
94 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
95 setup.in.workgroup = lp_workgroup();
97 setup.in.credentials = cmdline_credentials;
99 status = smb_composite_sesssetup(session, &setup);
100 CHECK_STATUS(status, NT_STATUS_OK);
102 session->vuid = setup.out.vuid;
104 printf("create a third security context on the same transport, with vuid set\n");
105 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
107 session2->vuid = session->vuid;
108 setup.in.sesskey = cli->transport->negotiate.sesskey;
109 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
110 setup.in.workgroup = lp_workgroup();
112 setup.in.credentials = cmdline_credentials;
114 status = smb_composite_sesssetup(session2, &setup);
115 CHECK_STATUS(status, NT_STATUS_OK);
117 session2->vuid = setup.out.vuid;
118 printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
120 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
121 /* Samba4 currently fails this - we need to determine if this insane behaviour is important */
122 if (session2->vuid == session->vuid) {
123 printf("server allows the user to re-use an existing vuid in session setup \n");
126 CHECK_NOT_VALUE(session2->vuid, session->vuid);
128 talloc_free(session2);
130 if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
131 printf("create a fourth security context on the same transport, without extended security\n");
132 session3 = smbcli_session_init(cli->transport, mem_ctx, False);
134 session3->vuid = session->vuid;
135 setup.in.sesskey = cli->transport->negotiate.sesskey;
136 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
137 setup.in.workgroup = lp_workgroup();
139 setup.in.credentials = cmdline_credentials;
142 status = smb_composite_sesssetup(session3, &setup);
143 CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
145 printf("create a fouth anonymous security context on the same transport, without extended security\n");
146 session4 = smbcli_session_init(cli->transport, mem_ctx, False);
148 session4->vuid = session->vuid;
149 setup.in.sesskey = cli->transport->negotiate.sesskey;
150 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
151 setup.in.workgroup = lp_workgroup();
153 anon_creds = cli_credentials_init(mem_ctx);
154 cli_credentials_set_conf(anon_creds);
155 cli_credentials_set_anonymous(anon_creds);
157 setup.in.credentials = anon_creds;
159 status = smb_composite_sesssetup(session3, &setup);
160 CHECK_STATUS(status, NT_STATUS_OK);
162 talloc_free(session4);
165 printf("use the same tree as the existing connection\n");
166 tree = smbcli_tree_init(session, mem_ctx, False);
167 tree->tid = cli->tree->tid;
169 printf("create a file using the new vuid\n");
170 io.generic.level = RAW_OPEN_NTCREATEX;
171 io.ntcreatex.in.root_fid = 0;
172 io.ntcreatex.in.flags = 0;
173 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
174 io.ntcreatex.in.create_options = 0;
175 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
176 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
177 io.ntcreatex.in.alloc_size = 0;
178 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
179 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
180 io.ntcreatex.in.security_flags = 0;
181 io.ntcreatex.in.fname = fname;
182 status = smb_raw_open(tree, mem_ctx, &io);
183 CHECK_STATUS(status, NT_STATUS_OK);
184 fnum = io.ntcreatex.out.file.fnum;
186 printf("write using the old vuid\n");
187 wr.generic.level = RAW_WRITE_WRITEX;
188 wr.writex.in.file.fnum = fnum;
189 wr.writex.in.offset = 0;
190 wr.writex.in.wmode = 0;
191 wr.writex.in.remaining = 0;
192 wr.writex.in.count = 1;
193 wr.writex.in.data = &c;
195 status = smb_raw_write(cli->tree, &wr);
196 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
198 printf("write with the new vuid\n");
199 status = smb_raw_write(tree, &wr);
200 CHECK_STATUS(status, NT_STATUS_OK);
201 CHECK_VALUE(wr.writex.out.nwritten, 1);
203 printf("logoff the new vuid\n");
204 status = smb_raw_ulogoff(session);
205 CHECK_STATUS(status, NT_STATUS_OK);
207 printf("the new vuid should not now be accessible\n");
208 status = smb_raw_write(tree, &wr);
209 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
211 printf("second logoff for the new vuid should fail\n");
212 status = smb_raw_ulogoff(session);
213 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRbaduid));
214 talloc_free(session);
216 printf("the fnum should have been auto-closed\n");
217 cl.close.level = RAW_CLOSE_CLOSE;
218 cl.close.in.file.fnum = fnum;
219 cl.close.in.write_time = 0;
220 status = smb_raw_close(cli->tree, &cl);
221 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
223 printf("create %d secondary security contexts on the same transport\n",
224 (int)ARRAY_SIZE(sessions));
225 for (i=0; i <ARRAY_SIZE(sessions); i++) {
226 setups[i].in.sesskey = cli->transport->negotiate.sesskey;
227 setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
228 setups[i].in.workgroup = lp_workgroup();
230 setups[i].in.credentials = cmdline_credentials;
232 sessions[i] = smbcli_session_init(cli->transport, mem_ctx, False);
233 composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
238 printf("finishing %d secondary security contexts on the same transport\n",
239 (int)ARRAY_SIZE(sessions));
240 for (i=0; i< ARRAY_SIZE(sessions); i++) {
241 status = smb_composite_sesssetup_recv(composite_contexts[i]);
242 CHECK_STATUS(status, NT_STATUS_OK);
243 sessions[i]->vuid = setups[i].out.vuid;
244 printf("VUID: %d\n", sessions[i]->vuid);
245 status = smb_raw_ulogoff(sessions[i]);
246 CHECK_STATUS(status, NT_STATUS_OK);
260 static BOOL test_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
264 const char *share, *host;
265 struct smbcli_tree *tree;
271 const char *fname = BASEDIR "\\test.txt";
274 printf("TESTING TREE HANDLING\n");
276 if (!torture_setup_dir(cli, BASEDIR)) {
280 share = lp_parm_string(NULL, "torture", "share");
281 host = lp_parm_string(NULL, "torture", "host");
283 printf("create a second tree context on the same session\n");
284 tree = smbcli_tree_init(cli->session, mem_ctx, False);
286 tcon.generic.level = RAW_TCON_TCONX;
287 tcon.tconx.in.flags = 0;
288 tcon.tconx.in.password = data_blob(NULL, 0);
289 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
290 tcon.tconx.in.device = "A:";
291 status = smb_raw_tcon(tree, mem_ctx, &tcon);
292 CHECK_STATUS(status, NT_STATUS_OK);
295 tree->tid = tcon.tconx.out.tid;
296 printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
298 printf("try a tconx with a bad device type\n");
299 tcon.tconx.in.device = "FOO";
300 status = smb_raw_tcon(tree, mem_ctx, &tcon);
301 CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
304 printf("create a file using the new tid\n");
305 io.generic.level = RAW_OPEN_NTCREATEX;
306 io.ntcreatex.in.root_fid = 0;
307 io.ntcreatex.in.flags = 0;
308 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
309 io.ntcreatex.in.create_options = 0;
310 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
311 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
312 io.ntcreatex.in.alloc_size = 0;
313 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
314 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
315 io.ntcreatex.in.security_flags = 0;
316 io.ntcreatex.in.fname = fname;
317 status = smb_raw_open(tree, mem_ctx, &io);
318 CHECK_STATUS(status, NT_STATUS_OK);
319 fnum = io.ntcreatex.out.file.fnum;
321 printf("write using the old tid\n");
322 wr.generic.level = RAW_WRITE_WRITEX;
323 wr.writex.in.file.fnum = fnum;
324 wr.writex.in.offset = 0;
325 wr.writex.in.wmode = 0;
326 wr.writex.in.remaining = 0;
327 wr.writex.in.count = 1;
328 wr.writex.in.data = &c;
330 status = smb_raw_write(cli->tree, &wr);
331 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
333 printf("write with the new tid\n");
334 status = smb_raw_write(tree, &wr);
335 CHECK_STATUS(status, NT_STATUS_OK);
336 CHECK_VALUE(wr.writex.out.nwritten, 1);
338 printf("disconnect the new tid\n");
339 status = smb_tree_disconnect(tree);
340 CHECK_STATUS(status, NT_STATUS_OK);
342 printf("the new tid should not now be accessible\n");
343 status = smb_raw_write(tree, &wr);
344 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
346 printf("the fnum should have been auto-closed\n");
347 cl.close.level = RAW_CLOSE_CLOSE;
348 cl.close.in.file.fnum = fnum;
349 cl.close.in.write_time = 0;
350 status = smb_raw_close(cli->tree, &cl);
351 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
353 /* close down the new tree */
361 test tree with ulogoff
362 this demonstrates that a tcon isn't autoclosed by a ulogoff
363 the tcon can be reused using any other valid session later
365 static BOOL test_tree_ulogoff(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
369 const char *share, *host;
370 struct smbcli_session *session1;
371 struct smbcli_session *session2;
372 struct smb_composite_sesssetup setup;
373 struct smbcli_tree *tree;
378 const char *fname1 = BASEDIR "\\test1.txt";
379 const char *fname2 = BASEDIR "\\test2.txt";
382 printf("TESTING TREE with ulogoff\n");
384 if (!torture_setup_dir(cli, BASEDIR)) {
388 share = lp_parm_string(NULL, "torture", "share");
389 host = lp_parm_string(NULL, "torture", "host");
391 printf("create the first new sessions\n");
392 session1 = smbcli_session_init(cli->transport, mem_ctx, False);
393 setup.in.sesskey = cli->transport->negotiate.sesskey;
394 setup.in.capabilities = cli->transport->negotiate.capabilities;
395 setup.in.workgroup = lp_workgroup();
396 setup.in.credentials = cmdline_credentials;
397 status = smb_composite_sesssetup(session1, &setup);
398 CHECK_STATUS(status, NT_STATUS_OK);
399 session1->vuid = setup.out.vuid;
400 printf("vuid1=%d\n", session1->vuid);
402 printf("create a tree context on the with vuid1\n");
403 tree = smbcli_tree_init(session1, mem_ctx, False);
404 tcon.generic.level = RAW_TCON_TCONX;
405 tcon.tconx.in.flags = 0;
406 tcon.tconx.in.password = data_blob(NULL, 0);
407 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
408 tcon.tconx.in.device = "A:";
409 status = smb_raw_tcon(tree, mem_ctx, &tcon);
410 CHECK_STATUS(status, NT_STATUS_OK);
411 tree->tid = tcon.tconx.out.tid;
412 printf("tid=%d\n", tree->tid);
414 printf("create a file using vuid1\n");
415 io.generic.level = RAW_OPEN_NTCREATEX;
416 io.ntcreatex.in.root_fid = 0;
417 io.ntcreatex.in.flags = 0;
418 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
419 io.ntcreatex.in.create_options = 0;
420 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
421 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
422 io.ntcreatex.in.alloc_size = 0;
423 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
424 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
425 io.ntcreatex.in.security_flags = 0;
426 io.ntcreatex.in.fname = fname1;
427 status = smb_raw_open(tree, mem_ctx, &io);
428 CHECK_STATUS(status, NT_STATUS_OK);
429 fnum1 = io.ntcreatex.out.file.fnum;
431 printf("write using vuid1\n");
432 wr.generic.level = RAW_WRITE_WRITEX;
433 wr.writex.in.file.fnum = fnum1;
434 wr.writex.in.offset = 0;
435 wr.writex.in.wmode = 0;
436 wr.writex.in.remaining = 0;
437 wr.writex.in.count = 1;
438 wr.writex.in.data = &c;
439 status = smb_raw_write(tree, &wr);
440 CHECK_STATUS(status, NT_STATUS_OK);
441 CHECK_VALUE(wr.writex.out.nwritten, 1);
443 printf("ulogoff the vuid1\n");
444 status = smb_raw_ulogoff(session1);
445 CHECK_STATUS(status, NT_STATUS_OK);
447 printf("create the second new sessions\n");
448 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
449 setup.in.sesskey = cli->transport->negotiate.sesskey;
450 setup.in.capabilities = cli->transport->negotiate.capabilities;
451 setup.in.workgroup = lp_workgroup();
452 setup.in.credentials = cmdline_credentials;
453 status = smb_composite_sesssetup(session2, &setup);
454 CHECK_STATUS(status, NT_STATUS_OK);
455 session2->vuid = setup.out.vuid;
456 printf("vuid2=%d\n", session2->vuid);
458 printf("use the existing tree with vuid2\n");
459 tree->session = session2;
461 printf("create a file using vuid2\n");
462 io.generic.level = RAW_OPEN_NTCREATEX;
463 io.ntcreatex.in.root_fid = 0;
464 io.ntcreatex.in.flags = 0;
465 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
466 io.ntcreatex.in.create_options = 0;
467 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
468 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
469 io.ntcreatex.in.alloc_size = 0;
470 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
471 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
472 io.ntcreatex.in.security_flags = 0;
473 io.ntcreatex.in.fname = fname2;
474 status = smb_raw_open(tree, mem_ctx, &io);
475 CHECK_STATUS(status, NT_STATUS_OK);
476 fnum2 = io.ntcreatex.out.file.fnum;
478 printf("write using vuid2\n");
479 wr.generic.level = RAW_WRITE_WRITEX;
480 wr.writex.in.file.fnum = fnum2;
481 wr.writex.in.offset = 0;
482 wr.writex.in.wmode = 0;
483 wr.writex.in.remaining = 0;
484 wr.writex.in.count = 1;
485 wr.writex.in.data = &c;
486 status = smb_raw_write(tree, &wr);
487 CHECK_STATUS(status, NT_STATUS_OK);
488 CHECK_VALUE(wr.writex.out.nwritten, 1);
490 printf("ulogoff the vuid2\n");
491 status = smb_raw_ulogoff(session2);
492 CHECK_STATUS(status, NT_STATUS_OK);
494 /* this also demonstrates that SMBtdis doesn't need a valid vuid */
495 printf("disconnect the existing tree connection\n");
496 status = smb_tree_disconnect(tree);
497 CHECK_STATUS(status, NT_STATUS_OK);
499 printf("disconnect the existing tree connection\n");
500 status = smb_tree_disconnect(tree);
501 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
503 /* close down the new tree */
512 this test demonstrates that exit() only sees the PID
513 used for the open() calls
515 static BOOL test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
523 const char *fname = BASEDIR "\\test.txt";
527 printf("TESTING PID HANDLING exit() only cares about open() PID\n");
529 if (!torture_setup_dir(cli, BASEDIR)) {
533 pid1 = cli->session->pid;
536 printf("pid1=%d pid2=%d\n", pid1, pid2);
538 printf("create a file using pid1\n");
539 cli->session->pid = pid1;
540 io.generic.level = RAW_OPEN_NTCREATEX;
541 io.ntcreatex.in.root_fid = 0;
542 io.ntcreatex.in.flags = 0;
543 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
544 io.ntcreatex.in.create_options = 0;
545 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
546 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
547 io.ntcreatex.in.alloc_size = 0;
548 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
549 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
550 io.ntcreatex.in.security_flags = 0;
551 io.ntcreatex.in.fname = fname;
552 status = smb_raw_open(cli->tree, mem_ctx, &io);
553 CHECK_STATUS(status, NT_STATUS_OK);
554 fnum = io.ntcreatex.out.file.fnum;
556 printf("write using pid2\n");
557 cli->session->pid = pid2;
558 wr.generic.level = RAW_WRITE_WRITEX;
559 wr.writex.in.file.fnum = fnum;
560 wr.writex.in.offset = 0;
561 wr.writex.in.wmode = 0;
562 wr.writex.in.remaining = 0;
563 wr.writex.in.count = 1;
564 wr.writex.in.data = &c;
565 status = smb_raw_write(cli->tree, &wr);
566 CHECK_STATUS(status, NT_STATUS_OK);
567 CHECK_VALUE(wr.writex.out.nwritten, 1);
569 printf("exit pid2\n");
570 cli->session->pid = pid2;
571 status = smb_raw_exit(cli->session);
572 CHECK_STATUS(status, NT_STATUS_OK);
574 printf("the fnum should still be accessible via pid2\n");
575 cli->session->pid = pid2;
576 status = smb_raw_write(cli->tree, &wr);
577 CHECK_STATUS(status, NT_STATUS_OK);
578 CHECK_VALUE(wr.writex.out.nwritten, 1);
580 printf("exit pid2\n");
581 cli->session->pid = pid2;
582 status = smb_raw_exit(cli->session);
583 CHECK_STATUS(status, NT_STATUS_OK);
585 printf("the fnum should still be accessible via pid1 and pid2\n");
586 cli->session->pid = pid1;
587 status = smb_raw_write(cli->tree, &wr);
588 CHECK_STATUS(status, NT_STATUS_OK);
589 CHECK_VALUE(wr.writex.out.nwritten, 1);
590 cli->session->pid = pid2;
591 status = smb_raw_write(cli->tree, &wr);
592 CHECK_STATUS(status, NT_STATUS_OK);
593 CHECK_VALUE(wr.writex.out.nwritten, 1);
595 printf("exit pid1\n");
596 cli->session->pid = pid1;
597 status = smb_raw_exit(cli->session);
598 CHECK_STATUS(status, NT_STATUS_OK);
600 printf("the fnum should not now be accessible via pid1 or pid2\n");
601 cli->session->pid = pid1;
602 status = smb_raw_write(cli->tree, &wr);
603 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
604 cli->session->pid = pid2;
605 status = smb_raw_write(cli->tree, &wr);
606 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
608 printf("the fnum should have been auto-closed\n");
609 cli->session->pid = pid1;
610 cl.close.level = RAW_CLOSE_CLOSE;
611 cl.close.in.file.fnum = fnum;
612 cl.close.in.write_time = 0;
613 status = smb_raw_close(cli->tree, &cl);
614 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
621 test pid ops with 2 sessions
623 static BOOL test_pid_2sess(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
627 struct smbcli_session *session;
628 struct smb_composite_sesssetup setup;
633 const char *fname = BASEDIR "\\test.txt";
635 uint16_t vuid1, vuid2;
637 printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
639 if (!torture_setup_dir(cli, BASEDIR)) {
643 printf("create a second security context on the same transport\n");
644 session = smbcli_session_init(cli->transport, mem_ctx, False);
646 setup.in.sesskey = cli->transport->negotiate.sesskey;
647 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
648 setup.in.workgroup = lp_workgroup();
650 setup.in.credentials = cmdline_credentials;
652 status = smb_composite_sesssetup(session, &setup);
653 CHECK_STATUS(status, NT_STATUS_OK);
654 session->vuid = setup.out.vuid;
656 vuid1 = cli->session->vuid;
657 vuid2 = session->vuid;
659 printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
661 printf("create a file using the vuid1\n");
662 cli->session->vuid = vuid1;
663 io.generic.level = RAW_OPEN_NTCREATEX;
664 io.ntcreatex.in.root_fid = 0;
665 io.ntcreatex.in.flags = 0;
666 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
667 io.ntcreatex.in.create_options = 0;
668 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
669 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
670 io.ntcreatex.in.alloc_size = 0;
671 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
672 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
673 io.ntcreatex.in.security_flags = 0;
674 io.ntcreatex.in.fname = fname;
675 status = smb_raw_open(cli->tree, mem_ctx, &io);
676 CHECK_STATUS(status, NT_STATUS_OK);
677 fnum = io.ntcreatex.out.file.fnum;
679 printf("write using the vuid1 (fnum=%d)\n", fnum);
680 cli->session->vuid = vuid1;
681 wr.generic.level = RAW_WRITE_WRITEX;
682 wr.writex.in.file.fnum = fnum;
683 wr.writex.in.offset = 0;
684 wr.writex.in.wmode = 0;
685 wr.writex.in.remaining = 0;
686 wr.writex.in.count = 1;
687 wr.writex.in.data = &c;
689 status = smb_raw_write(cli->tree, &wr);
690 CHECK_STATUS(status, NT_STATUS_OK);
691 CHECK_VALUE(wr.writex.out.nwritten, 1);
693 printf("exit the pid with vuid2\n");
694 cli->session->vuid = vuid2;
695 status = smb_raw_exit(cli->session);
696 CHECK_STATUS(status, NT_STATUS_OK);
698 printf("the fnum should still be accessible\n");
699 cli->session->vuid = vuid1;
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 vuid1\n");
705 cli->session->vuid = vuid1;
706 status = smb_raw_exit(cli->session);
707 CHECK_STATUS(status, NT_STATUS_OK);
709 printf("the fnum should not now be accessible\n");
710 status = smb_raw_write(cli->tree, &wr);
711 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
713 printf("the fnum should have been auto-closed\n");
714 cl.close.level = RAW_CLOSE_CLOSE;
715 cl.close.in.file.fnum = fnum;
716 cl.close.in.write_time = 0;
717 status = smb_raw_close(cli->tree, &cl);
718 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
725 test pid ops with 2 tcons
727 static BOOL test_pid_2tcon(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
731 const char *share, *host;
732 struct smbcli_tree *tree;
738 const char *fname1 = BASEDIR "\\test1.txt";
739 const char *fname2 = BASEDIR "\\test2.txt";
743 printf("TESTING PID HANDLING WITH 2 TCONS\n");
745 if (!torture_setup_dir(cli, BASEDIR)) {
749 share = lp_parm_string(NULL, "torture", "share");
750 host = lp_parm_string(NULL, "torture", "host");
752 printf("create a second tree context on the same session\n");
753 tree = smbcli_tree_init(cli->session, mem_ctx, False);
755 tcon.generic.level = RAW_TCON_TCONX;
756 tcon.tconx.in.flags = 0;
757 tcon.tconx.in.password = data_blob(NULL, 0);
758 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
759 tcon.tconx.in.device = "A:";
760 status = smb_raw_tcon(tree, mem_ctx, &tcon);
761 CHECK_STATUS(status, NT_STATUS_OK);
763 tree->tid = tcon.tconx.out.tid;
765 tid1 = cli->tree->tid;
767 printf("tid1=%d tid2=%d\n", tid1, tid2);
769 printf("create a file using the tid1\n");
770 cli->tree->tid = tid1;
771 io.generic.level = RAW_OPEN_NTCREATEX;
772 io.ntcreatex.in.root_fid = 0;
773 io.ntcreatex.in.flags = 0;
774 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
775 io.ntcreatex.in.create_options = 0;
776 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
777 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
778 io.ntcreatex.in.alloc_size = 0;
779 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
780 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
781 io.ntcreatex.in.security_flags = 0;
782 io.ntcreatex.in.fname = fname1;
783 status = smb_raw_open(cli->tree, mem_ctx, &io);
784 CHECK_STATUS(status, NT_STATUS_OK);
785 fnum1 = io.ntcreatex.out.file.fnum;
787 printf("write using the tid1\n");
788 wr.generic.level = RAW_WRITE_WRITEX;
789 wr.writex.in.file.fnum = fnum1;
790 wr.writex.in.offset = 0;
791 wr.writex.in.wmode = 0;
792 wr.writex.in.remaining = 0;
793 wr.writex.in.count = 1;
794 wr.writex.in.data = &c;
796 status = smb_raw_write(cli->tree, &wr);
797 CHECK_STATUS(status, NT_STATUS_OK);
798 CHECK_VALUE(wr.writex.out.nwritten, 1);
800 printf("create a file using the tid2\n");
801 cli->tree->tid = tid2;
802 io.generic.level = RAW_OPEN_NTCREATEX;
803 io.ntcreatex.in.root_fid = 0;
804 io.ntcreatex.in.flags = 0;
805 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
806 io.ntcreatex.in.create_options = 0;
807 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
808 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
809 io.ntcreatex.in.alloc_size = 0;
810 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
811 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
812 io.ntcreatex.in.security_flags = 0;
813 io.ntcreatex.in.fname = fname2;
814 status = smb_raw_open(cli->tree, mem_ctx, &io);
815 CHECK_STATUS(status, NT_STATUS_OK);
816 fnum2 = io.ntcreatex.out.file.fnum;
818 printf("write using the tid2\n");
819 wr.generic.level = RAW_WRITE_WRITEX;
820 wr.writex.in.file.fnum = fnum2;
821 wr.writex.in.offset = 0;
822 wr.writex.in.wmode = 0;
823 wr.writex.in.remaining = 0;
824 wr.writex.in.count = 1;
825 wr.writex.in.data = &c;
827 status = smb_raw_write(cli->tree, &wr);
828 CHECK_STATUS(status, NT_STATUS_OK);
829 CHECK_VALUE(wr.writex.out.nwritten, 1);
831 printf("exit the pid\n");
832 status = smb_raw_exit(cli->session);
833 CHECK_STATUS(status, NT_STATUS_OK);
835 printf("the fnum1 on tid1 should not be accessible\n");
836 cli->tree->tid = tid1;
837 wr.writex.in.file.fnum = fnum1;
838 status = smb_raw_write(cli->tree, &wr);
839 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
841 printf("the fnum1 on tid1 should have been auto-closed\n");
842 cl.close.level = RAW_CLOSE_CLOSE;
843 cl.close.in.file.fnum = fnum1;
844 cl.close.in.write_time = 0;
845 status = smb_raw_close(cli->tree, &cl);
846 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
848 printf("the fnum2 on tid2 should not be accessible\n");
849 cli->tree->tid = tid2;
850 wr.writex.in.file.fnum = fnum2;
851 status = smb_raw_write(cli->tree, &wr);
852 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
854 printf("the fnum2 on tid2 should have been auto-closed\n");
855 cl.close.level = RAW_CLOSE_CLOSE;
856 cl.close.in.file.fnum = fnum2;
857 cl.close.in.write_time = 0;
858 status = smb_raw_close(cli->tree, &cl);
859 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
867 basic testing of session/tree context calls
869 static bool torture_raw_context_int(struct torture_context *tctx,
870 struct smbcli_state *cli)
874 ret &= test_session(cli, tctx);
875 ret &= test_tree(cli, tctx);
876 ret &= test_tree_ulogoff(cli, tctx);
877 ret &= test_pid_exit_only_sees_open(cli, tctx);
878 ret &= test_pid_2sess(cli, tctx);
879 ret &= test_pid_2tcon(cli, tctx);
881 smb_raw_exit(cli->session);
882 smbcli_deltree(cli->tree, BASEDIR);
887 basic testing of session/tree context calls
889 bool torture_raw_context(struct torture_context *torture,
890 struct smbcli_state *cli)
893 if (lp_use_spnego()) {
894 ret &= torture_raw_context_int(torture, cli);
895 lp_set_cmdline(global_loadparm, "use spnego", "False");
898 ret &= torture_raw_context_int(torture, cli);