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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.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"
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 /* flush the queue */
239 for (i=0; i < ARRAY_SIZE(sessions); i++) {
240 event_loop_once(composite_contexts[0]->event_ctx);
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, TALLOC_CTX *mem_ctx)
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 = lp_parm_string(-1, "torture", "share");
286 host = lp_parm_string(-1, "torture", "host");
288 printf("create a second tree context on the same session\n");
289 tree = smbcli_tree_init(cli->session, mem_ctx, 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(mem_ctx, "\\\\%s\\%s", host, share);
295 tcon.tconx.in.device = "A:";
296 status = smb_raw_tcon(tree, mem_ctx, &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, mem_ctx, &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, mem_ctx, &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, TALLOC_CTX *mem_ctx)
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";
387 printf("TESTING TREE with ulogoff\n");
389 if (!torture_setup_dir(cli, BASEDIR)) {
393 share = lp_parm_string(-1, "torture", "share");
394 host = lp_parm_string(-1, "torture", "host");
396 printf("create the first new sessions\n");
397 session1 = smbcli_session_init(cli->transport, mem_ctx, False);
398 setup.in.sesskey = cli->transport->negotiate.sesskey;
399 setup.in.capabilities = cli->transport->negotiate.capabilities;
400 setup.in.workgroup = lp_workgroup();
401 setup.in.credentials = cmdline_credentials;
402 status = smb_composite_sesssetup(session1, &setup);
403 CHECK_STATUS(status, NT_STATUS_OK);
404 session1->vuid = setup.out.vuid;
405 printf("vuid1=%d\n", session1->vuid);
407 printf("create a tree context on the with vuid1\n");
408 tree = smbcli_tree_init(session1, mem_ctx, False);
409 tcon.generic.level = RAW_TCON_TCONX;
410 tcon.tconx.in.flags = 0;
411 tcon.tconx.in.password = data_blob(NULL, 0);
412 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
413 tcon.tconx.in.device = "A:";
414 status = smb_raw_tcon(tree, mem_ctx, &tcon);
415 CHECK_STATUS(status, NT_STATUS_OK);
416 tree->tid = tcon.tconx.out.tid;
417 printf("tid=%d\n", tree->tid);
419 printf("create a file using vuid1\n");
420 io.generic.level = RAW_OPEN_NTCREATEX;
421 io.ntcreatex.in.root_fid = 0;
422 io.ntcreatex.in.flags = 0;
423 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
424 io.ntcreatex.in.create_options = 0;
425 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
426 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
427 io.ntcreatex.in.alloc_size = 0;
428 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
429 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
430 io.ntcreatex.in.security_flags = 0;
431 io.ntcreatex.in.fname = fname1;
432 status = smb_raw_open(tree, mem_ctx, &io);
433 CHECK_STATUS(status, NT_STATUS_OK);
434 fnum1 = io.ntcreatex.out.file.fnum;
436 printf("write using vuid1\n");
437 wr.generic.level = RAW_WRITE_WRITEX;
438 wr.writex.in.file.fnum = fnum1;
439 wr.writex.in.offset = 0;
440 wr.writex.in.wmode = 0;
441 wr.writex.in.remaining = 0;
442 wr.writex.in.count = 1;
443 wr.writex.in.data = &c;
444 status = smb_raw_write(tree, &wr);
445 CHECK_STATUS(status, NT_STATUS_OK);
446 CHECK_VALUE(wr.writex.out.nwritten, 1);
448 printf("ulogoff the vuid1\n");
449 status = smb_raw_ulogoff(session1);
450 CHECK_STATUS(status, NT_STATUS_OK);
452 printf("create the second new sessions\n");
453 session2 = smbcli_session_init(cli->transport, mem_ctx, False);
454 setup.in.sesskey = cli->transport->negotiate.sesskey;
455 setup.in.capabilities = cli->transport->negotiate.capabilities;
456 setup.in.workgroup = lp_workgroup();
457 setup.in.credentials = cmdline_credentials;
458 status = smb_composite_sesssetup(session2, &setup);
459 CHECK_STATUS(status, NT_STATUS_OK);
460 session2->vuid = setup.out.vuid;
461 printf("vuid2=%d\n", session2->vuid);
463 printf("use the existing tree with vuid2\n");
464 tree->session = session2;
466 printf("create a file using vuid2\n");
467 io.generic.level = RAW_OPEN_NTCREATEX;
468 io.ntcreatex.in.root_fid = 0;
469 io.ntcreatex.in.flags = 0;
470 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
471 io.ntcreatex.in.create_options = 0;
472 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
473 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
474 io.ntcreatex.in.alloc_size = 0;
475 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
476 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
477 io.ntcreatex.in.security_flags = 0;
478 io.ntcreatex.in.fname = fname2;
479 status = smb_raw_open(tree, mem_ctx, &io);
480 CHECK_STATUS(status, NT_STATUS_OK);
481 fnum2 = io.ntcreatex.out.file.fnum;
483 printf("write using vuid2\n");
484 wr.generic.level = RAW_WRITE_WRITEX;
485 wr.writex.in.file.fnum = fnum2;
486 wr.writex.in.offset = 0;
487 wr.writex.in.wmode = 0;
488 wr.writex.in.remaining = 0;
489 wr.writex.in.count = 1;
490 wr.writex.in.data = &c;
491 status = smb_raw_write(tree, &wr);
492 CHECK_STATUS(status, NT_STATUS_OK);
493 CHECK_VALUE(wr.writex.out.nwritten, 1);
495 printf("ulogoff the vuid2\n");
496 status = smb_raw_ulogoff(session2);
497 CHECK_STATUS(status, NT_STATUS_OK);
499 /* this also demonstrates that SMBtdis doesn't need a valid vuid */
500 printf("disconnect the existing tree connection\n");
501 status = smb_tree_disconnect(tree);
502 CHECK_STATUS(status, NT_STATUS_OK);
504 printf("disconnect the existing tree connection\n");
505 status = smb_tree_disconnect(tree);
506 CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
508 /* close down the new tree */
517 this test demonstrates that exit() only sees the PID
518 used for the open() calls
520 static BOOL test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
528 const char *fname = BASEDIR "\\test.txt";
532 printf("TESTING PID HANDLING exit() only cares about open() PID\n");
534 if (!torture_setup_dir(cli, BASEDIR)) {
538 pid1 = cli->session->pid;
541 printf("pid1=%d pid2=%d\n", pid1, pid2);
543 printf("create a file using pid1\n");
544 cli->session->pid = pid1;
545 io.generic.level = RAW_OPEN_NTCREATEX;
546 io.ntcreatex.in.root_fid = 0;
547 io.ntcreatex.in.flags = 0;
548 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
549 io.ntcreatex.in.create_options = 0;
550 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
551 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
552 io.ntcreatex.in.alloc_size = 0;
553 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
554 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
555 io.ntcreatex.in.security_flags = 0;
556 io.ntcreatex.in.fname = fname;
557 status = smb_raw_open(cli->tree, mem_ctx, &io);
558 CHECK_STATUS(status, NT_STATUS_OK);
559 fnum = io.ntcreatex.out.file.fnum;
561 printf("write using pid2\n");
562 cli->session->pid = pid2;
563 wr.generic.level = RAW_WRITE_WRITEX;
564 wr.writex.in.file.fnum = fnum;
565 wr.writex.in.offset = 0;
566 wr.writex.in.wmode = 0;
567 wr.writex.in.remaining = 0;
568 wr.writex.in.count = 1;
569 wr.writex.in.data = &c;
570 status = smb_raw_write(cli->tree, &wr);
571 CHECK_STATUS(status, NT_STATUS_OK);
572 CHECK_VALUE(wr.writex.out.nwritten, 1);
574 printf("exit pid2\n");
575 cli->session->pid = pid2;
576 status = smb_raw_exit(cli->session);
577 CHECK_STATUS(status, NT_STATUS_OK);
579 printf("the fnum should still be accessible via pid2\n");
580 cli->session->pid = pid2;
581 status = smb_raw_write(cli->tree, &wr);
582 CHECK_STATUS(status, NT_STATUS_OK);
583 CHECK_VALUE(wr.writex.out.nwritten, 1);
585 printf("exit pid2\n");
586 cli->session->pid = pid2;
587 status = smb_raw_exit(cli->session);
588 CHECK_STATUS(status, NT_STATUS_OK);
590 printf("the fnum should still be accessible via pid1 and pid2\n");
591 cli->session->pid = pid1;
592 status = smb_raw_write(cli->tree, &wr);
593 CHECK_STATUS(status, NT_STATUS_OK);
594 CHECK_VALUE(wr.writex.out.nwritten, 1);
595 cli->session->pid = pid2;
596 status = smb_raw_write(cli->tree, &wr);
597 CHECK_STATUS(status, NT_STATUS_OK);
598 CHECK_VALUE(wr.writex.out.nwritten, 1);
600 printf("exit pid1\n");
601 cli->session->pid = pid1;
602 status = smb_raw_exit(cli->session);
603 CHECK_STATUS(status, NT_STATUS_OK);
605 printf("the fnum should not now be accessible via pid1 or pid2\n");
606 cli->session->pid = pid1;
607 status = smb_raw_write(cli->tree, &wr);
608 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
609 cli->session->pid = pid2;
610 status = smb_raw_write(cli->tree, &wr);
611 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
613 printf("the fnum should have been auto-closed\n");
614 cli->session->pid = pid1;
615 cl.close.level = RAW_CLOSE_CLOSE;
616 cl.close.in.file.fnum = fnum;
617 cl.close.in.write_time = 0;
618 status = smb_raw_close(cli->tree, &cl);
619 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
626 test pid ops with 2 sessions
628 static BOOL test_pid_2sess(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
632 struct smbcli_session *session;
633 struct smb_composite_sesssetup setup;
638 const char *fname = BASEDIR "\\test.txt";
640 uint16_t vuid1, vuid2;
642 printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
644 if (!torture_setup_dir(cli, BASEDIR)) {
648 printf("create a second security context on the same transport\n");
649 session = smbcli_session_init(cli->transport, mem_ctx, False);
651 setup.in.sesskey = cli->transport->negotiate.sesskey;
652 setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
653 setup.in.workgroup = lp_workgroup();
655 setup.in.credentials = cmdline_credentials;
657 status = smb_composite_sesssetup(session, &setup);
658 CHECK_STATUS(status, NT_STATUS_OK);
659 session->vuid = setup.out.vuid;
661 vuid1 = cli->session->vuid;
662 vuid2 = session->vuid;
664 printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
666 printf("create a file using the vuid1\n");
667 cli->session->vuid = vuid1;
668 io.generic.level = RAW_OPEN_NTCREATEX;
669 io.ntcreatex.in.root_fid = 0;
670 io.ntcreatex.in.flags = 0;
671 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
672 io.ntcreatex.in.create_options = 0;
673 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
674 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
675 io.ntcreatex.in.alloc_size = 0;
676 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
677 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
678 io.ntcreatex.in.security_flags = 0;
679 io.ntcreatex.in.fname = fname;
680 status = smb_raw_open(cli->tree, mem_ctx, &io);
681 CHECK_STATUS(status, NT_STATUS_OK);
682 fnum = io.ntcreatex.out.file.fnum;
684 printf("write using the vuid1 (fnum=%d)\n", fnum);
685 cli->session->vuid = vuid1;
686 wr.generic.level = RAW_WRITE_WRITEX;
687 wr.writex.in.file.fnum = fnum;
688 wr.writex.in.offset = 0;
689 wr.writex.in.wmode = 0;
690 wr.writex.in.remaining = 0;
691 wr.writex.in.count = 1;
692 wr.writex.in.data = &c;
694 status = smb_raw_write(cli->tree, &wr);
695 CHECK_STATUS(status, NT_STATUS_OK);
696 CHECK_VALUE(wr.writex.out.nwritten, 1);
698 printf("exit the pid with vuid2\n");
699 cli->session->vuid = vuid2;
700 status = smb_raw_exit(cli->session);
701 CHECK_STATUS(status, NT_STATUS_OK);
703 printf("the fnum should still be accessible\n");
704 cli->session->vuid = vuid1;
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 vuid1\n");
710 cli->session->vuid = vuid1;
711 status = smb_raw_exit(cli->session);
712 CHECK_STATUS(status, NT_STATUS_OK);
714 printf("the fnum should not now be accessible\n");
715 status = smb_raw_write(cli->tree, &wr);
716 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
718 printf("the fnum should have been auto-closed\n");
719 cl.close.level = RAW_CLOSE_CLOSE;
720 cl.close.in.file.fnum = fnum;
721 cl.close.in.write_time = 0;
722 status = smb_raw_close(cli->tree, &cl);
723 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
730 test pid ops with 2 tcons
732 static BOOL test_pid_2tcon(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
736 const char *share, *host;
737 struct smbcli_tree *tree;
743 const char *fname1 = BASEDIR "\\test1.txt";
744 const char *fname2 = BASEDIR "\\test2.txt";
748 printf("TESTING PID HANDLING WITH 2 TCONS\n");
750 if (!torture_setup_dir(cli, BASEDIR)) {
754 share = lp_parm_string(-1, "torture", "share");
755 host = lp_parm_string(-1, "torture", "host");
757 printf("create a second tree context on the same session\n");
758 tree = smbcli_tree_init(cli->session, mem_ctx, False);
760 tcon.generic.level = RAW_TCON_TCONX;
761 tcon.tconx.in.flags = 0;
762 tcon.tconx.in.password = data_blob(NULL, 0);
763 tcon.tconx.in.path = talloc_asprintf(mem_ctx, "\\\\%s\\%s", host, share);
764 tcon.tconx.in.device = "A:";
765 status = smb_raw_tcon(tree, mem_ctx, &tcon);
766 CHECK_STATUS(status, NT_STATUS_OK);
768 tree->tid = tcon.tconx.out.tid;
770 tid1 = cli->tree->tid;
772 printf("tid1=%d tid2=%d\n", tid1, tid2);
774 printf("create a file using the tid1\n");
775 cli->tree->tid = tid1;
776 io.generic.level = RAW_OPEN_NTCREATEX;
777 io.ntcreatex.in.root_fid = 0;
778 io.ntcreatex.in.flags = 0;
779 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
780 io.ntcreatex.in.create_options = 0;
781 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
782 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
783 io.ntcreatex.in.alloc_size = 0;
784 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
785 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
786 io.ntcreatex.in.security_flags = 0;
787 io.ntcreatex.in.fname = fname1;
788 status = smb_raw_open(cli->tree, mem_ctx, &io);
789 CHECK_STATUS(status, NT_STATUS_OK);
790 fnum1 = io.ntcreatex.out.file.fnum;
792 printf("write using the tid1\n");
793 wr.generic.level = RAW_WRITE_WRITEX;
794 wr.writex.in.file.fnum = fnum1;
795 wr.writex.in.offset = 0;
796 wr.writex.in.wmode = 0;
797 wr.writex.in.remaining = 0;
798 wr.writex.in.count = 1;
799 wr.writex.in.data = &c;
801 status = smb_raw_write(cli->tree, &wr);
802 CHECK_STATUS(status, NT_STATUS_OK);
803 CHECK_VALUE(wr.writex.out.nwritten, 1);
805 printf("create a file using the tid2\n");
806 cli->tree->tid = tid2;
807 io.generic.level = RAW_OPEN_NTCREATEX;
808 io.ntcreatex.in.root_fid = 0;
809 io.ntcreatex.in.flags = 0;
810 io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
811 io.ntcreatex.in.create_options = 0;
812 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
813 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
814 io.ntcreatex.in.alloc_size = 0;
815 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
816 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
817 io.ntcreatex.in.security_flags = 0;
818 io.ntcreatex.in.fname = fname2;
819 status = smb_raw_open(cli->tree, mem_ctx, &io);
820 CHECK_STATUS(status, NT_STATUS_OK);
821 fnum2 = io.ntcreatex.out.file.fnum;
823 printf("write using the tid2\n");
824 wr.generic.level = RAW_WRITE_WRITEX;
825 wr.writex.in.file.fnum = fnum2;
826 wr.writex.in.offset = 0;
827 wr.writex.in.wmode = 0;
828 wr.writex.in.remaining = 0;
829 wr.writex.in.count = 1;
830 wr.writex.in.data = &c;
832 status = smb_raw_write(cli->tree, &wr);
833 CHECK_STATUS(status, NT_STATUS_OK);
834 CHECK_VALUE(wr.writex.out.nwritten, 1);
836 printf("exit the pid\n");
837 status = smb_raw_exit(cli->session);
838 CHECK_STATUS(status, NT_STATUS_OK);
840 printf("the fnum1 on tid1 should not be accessible\n");
841 cli->tree->tid = tid1;
842 wr.writex.in.file.fnum = fnum1;
843 status = smb_raw_write(cli->tree, &wr);
844 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
846 printf("the fnum1 on tid1 should have been auto-closed\n");
847 cl.close.level = RAW_CLOSE_CLOSE;
848 cl.close.in.file.fnum = fnum1;
849 cl.close.in.write_time = 0;
850 status = smb_raw_close(cli->tree, &cl);
851 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
853 printf("the fnum2 on tid2 should not be accessible\n");
854 cli->tree->tid = tid2;
855 wr.writex.in.file.fnum = fnum2;
856 status = smb_raw_write(cli->tree, &wr);
857 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
859 printf("the fnum2 on tid2 should have been auto-closed\n");
860 cl.close.level = RAW_CLOSE_CLOSE;
861 cl.close.in.file.fnum = fnum2;
862 cl.close.in.write_time = 0;
863 status = smb_raw_close(cli->tree, &cl);
864 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
872 basic testing of session/tree context calls
874 static BOOL torture_raw_context_int(void)
876 struct smbcli_state *cli;
880 if (!torture_open_connection(&cli)) {
884 mem_ctx = talloc_init("torture_raw_context");
886 ret &= test_session(cli, mem_ctx);
887 ret &= test_tree(cli, mem_ctx);
888 ret &= test_tree_ulogoff(cli, mem_ctx);
889 ret &= test_pid_exit_only_sees_open(cli, mem_ctx);
890 ret &= test_pid_2sess(cli, mem_ctx);
891 ret &= test_pid_2tcon(cli, mem_ctx);
893 smb_raw_exit(cli->session);
894 smbcli_deltree(cli->tree, BASEDIR);
896 torture_close_connection(cli);
897 talloc_free(mem_ctx);
902 basic testing of session/tree context calls
904 BOOL torture_raw_context(struct torture_context *torture)
907 if (lp_use_spnego()) {
908 ret &= torture_raw_context_int();
909 lp_set_cmdline("use spnego", "False");
912 ret &= torture_raw_context_int();