s4:torture: add smb2.session.expire1
[Samba/gebeck_regimport.git] / source4 / torture / smb2 / session.c
blob6051145936b8213beeffeb782142a6e497d23bd6
1 /*
2 Unix SMB/CIFS implementation.
4 test suite for SMB2 session setups
6 Copyright (C) Michael Adam 2012
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
25 #include "torture/torture.h"
26 #include "torture/smb2/proto.h"
27 #include "../libcli/smb/smbXcli_base.h"
28 #include "lib/cmdline/popt_common.h"
29 #include "auth/credentials/credentials.h"
30 #include "libcli/security/security.h"
31 #include "libcli/resolve/resolve.h"
32 #include "lib/param/param.h"
34 #define CHECK_VAL(v, correct) do { \
35 if ((v) != (correct)) { \
36 torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
37 __location__, #v, (int)v, (int)correct); \
38 ret = false; \
39 }} while (0)
41 #define CHECK_STATUS(status, correct) do { \
42 if (!NT_STATUS_EQUAL(status, correct)) { \
43 torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
44 nt_errstr(status), nt_errstr(correct)); \
45 ret = false; \
46 goto done; \
47 }} while (0)
49 #define CHECK_CREATED(__io, __created, __attribute) \
50 do { \
51 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
52 CHECK_VAL((__io)->out.alloc_size, 0); \
53 CHECK_VAL((__io)->out.size, 0); \
54 CHECK_VAL((__io)->out.file_attr, (__attribute)); \
55 CHECK_VAL((__io)->out.reserved2, 0); \
56 } while(0)
59 /**
60 * basic test for doing a session reconnect
62 bool test_session_reconnect1(struct torture_context *tctx, struct smb2_tree *tree)
64 NTSTATUS status;
65 TALLOC_CTX *mem_ctx = talloc_new(tctx);
66 char fname[256];
67 struct smb2_handle _h1;
68 struct smb2_handle *h1 = NULL;
69 struct smb2_handle _h2;
70 struct smb2_handle *h2 = NULL;
71 struct smb2_create io1, io2;
72 uint64_t previous_session_id;
73 bool ret = true;
74 struct smb2_tree *tree2;
75 union smb_fileinfo qfinfo;
77 /* Add some random component to the file name. */
78 snprintf(fname, 256, "session_reconnect_%s.dat",
79 generate_random_str(tctx, 8));
81 smb2_util_unlink(tree, fname);
83 smb2_oplock_create_share(&io1, fname,
84 smb2_util_share_access(""),
85 smb2_util_oplock_level("b"));
87 status = smb2_create(tree, mem_ctx, &io1);
88 CHECK_STATUS(status, NT_STATUS_OK);
89 _h1 = io1.out.file.handle;
90 h1 = &_h1;
91 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
92 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
94 /* disconnect, reconnect and then do durable reopen */
95 previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
97 if (!torture_smb2_connection_ext(tctx, previous_session_id, &tree2)) {
98 torture_warning(tctx, "session reconnect failed\n");
99 ret = false;
100 goto done;
103 /* try to access the file via the old handle */
105 ZERO_STRUCT(qfinfo);
106 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
107 qfinfo.generic.in.file.handle = _h1;
108 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
109 CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
110 h1 = NULL;
112 smb2_oplock_create_share(&io2, fname,
113 smb2_util_share_access(""),
114 smb2_util_oplock_level("b"));
116 status = smb2_create(tree2, mem_ctx, &io2);
117 CHECK_STATUS(status, NT_STATUS_OK);
118 CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
119 CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b"));
120 _h2 = io2.out.file.handle;
121 h2 = &_h2;
123 done:
124 if (h1 != NULL) {
125 smb2_util_close(tree, *h1);
127 if (h2 != NULL) {
128 smb2_util_close(tree2, *h2);
131 smb2_util_unlink(tree2, fname);
133 talloc_free(tree);
134 talloc_free(tree2);
136 talloc_free(mem_ctx);
138 return ret;
142 * basic test for doing a session reconnect on one connection
144 bool test_session_reconnect2(struct torture_context *tctx, struct smb2_tree *tree)
146 NTSTATUS status;
147 TALLOC_CTX *mem_ctx = talloc_new(tctx);
148 char fname[256];
149 struct smb2_handle _h1;
150 struct smb2_handle *h1 = NULL;
151 struct smb2_create io1;
152 uint64_t previous_session_id;
153 bool ret = true;
154 struct smb2_session *session2;
155 union smb_fileinfo qfinfo;
157 /* Add some random component to the file name. */
158 snprintf(fname, 256, "session_reconnect_%s.dat",
159 generate_random_str(tctx, 8));
161 smb2_util_unlink(tree, fname);
163 smb2_oplock_create_share(&io1, fname,
164 smb2_util_share_access(""),
165 smb2_util_oplock_level("b"));
166 io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
168 status = smb2_create(tree, mem_ctx, &io1);
169 CHECK_STATUS(status, NT_STATUS_OK);
170 _h1 = io1.out.file.handle;
171 h1 = &_h1;
172 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
173 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
175 /* disconnect, reconnect and then do durable reopen */
176 previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
178 torture_assert(tctx, torture_smb2_session_setup(tctx, tree->session->transport,
179 previous_session_id, tctx, &session2),
180 "session reconnect (on the same connection) failed");
182 /* try to access the file via the old handle */
184 ZERO_STRUCT(qfinfo);
185 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
186 qfinfo.generic.in.file.handle = _h1;
187 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
188 CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);
189 h1 = NULL;
191 done:
192 if (h1 != NULL) {
193 smb2_util_close(tree, *h1);
196 talloc_free(tree);
197 talloc_free(session2);
199 talloc_free(mem_ctx);
201 return ret;
204 bool test_session_reauth1(struct torture_context *tctx, struct smb2_tree *tree)
206 NTSTATUS status;
207 TALLOC_CTX *mem_ctx = talloc_new(tctx);
208 char fname[256];
209 struct smb2_handle _h1;
210 struct smb2_handle *h1 = NULL;
211 struct smb2_create io1;
212 bool ret = true;
213 union smb_fileinfo qfinfo;
215 /* Add some random component to the file name. */
216 snprintf(fname, 256, "session_reauth1_%s.dat",
217 generate_random_str(tctx, 8));
219 smb2_util_unlink(tree, fname);
221 smb2_oplock_create_share(&io1, fname,
222 smb2_util_share_access(""),
223 smb2_util_oplock_level("b"));
225 status = smb2_create(tree, mem_ctx, &io1);
226 CHECK_STATUS(status, NT_STATUS_OK);
227 _h1 = io1.out.file.handle;
228 h1 = &_h1;
229 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
230 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
232 status = smb2_session_setup_spnego(tree->session,
233 cmdline_credentials,
234 0 /* previous_session_id */);
235 CHECK_STATUS(status, NT_STATUS_OK);
237 /* try to access the file via the old handle */
239 ZERO_STRUCT(qfinfo);
240 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
241 qfinfo.generic.in.file.handle = _h1;
242 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
243 CHECK_STATUS(status, NT_STATUS_OK);
245 status = smb2_session_setup_spnego(tree->session,
246 cmdline_credentials,
247 0 /* previous_session_id */);
248 CHECK_STATUS(status, NT_STATUS_OK);
250 /* try to access the file via the old handle */
252 ZERO_STRUCT(qfinfo);
253 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
254 qfinfo.generic.in.file.handle = _h1;
255 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
256 CHECK_STATUS(status, NT_STATUS_OK);
258 done:
259 if (h1 != NULL) {
260 smb2_util_close(tree, *h1);
263 smb2_util_unlink(tree, fname);
265 talloc_free(tree);
267 talloc_free(mem_ctx);
269 return ret;
272 bool test_session_reauth2(struct torture_context *tctx, struct smb2_tree *tree)
274 NTSTATUS status;
275 TALLOC_CTX *mem_ctx = talloc_new(tctx);
276 char fname[256];
277 struct smb2_handle _h1;
278 struct smb2_handle *h1 = NULL;
279 struct smb2_create io1;
280 bool ret = true;
281 union smb_fileinfo qfinfo;
282 struct cli_credentials *anon_creds = NULL;
284 /* Add some random component to the file name. */
285 snprintf(fname, 256, "session_reauth2_%s.dat",
286 generate_random_str(tctx, 8));
288 smb2_util_unlink(tree, fname);
290 smb2_oplock_create_share(&io1, fname,
291 smb2_util_share_access(""),
292 smb2_util_oplock_level("b"));
294 status = smb2_create(tree, mem_ctx, &io1);
295 CHECK_STATUS(status, NT_STATUS_OK);
296 _h1 = io1.out.file.handle;
297 h1 = &_h1;
298 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
299 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
301 /* re-authenticate as anonymous */
303 anon_creds = cli_credentials_init_anon(mem_ctx);
304 torture_assert(tctx, (anon_creds != NULL), "talloc error");
306 status = smb2_session_setup_spnego(tree->session,
307 anon_creds,
308 0 /* previous_session_id */);
309 CHECK_STATUS(status, NT_STATUS_OK);
311 /* try to access the file via the old handle */
313 ZERO_STRUCT(qfinfo);
314 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
315 qfinfo.generic.in.file.handle = _h1;
316 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
317 CHECK_STATUS(status, NT_STATUS_OK);
319 /* re-authenticate as original user again */
321 status = smb2_session_setup_spnego(tree->session,
322 cmdline_credentials,
323 0 /* previous_session_id */);
324 CHECK_STATUS(status, NT_STATUS_OK);
326 /* try to access the file via the old handle */
328 ZERO_STRUCT(qfinfo);
329 qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
330 qfinfo.generic.in.file.handle = _h1;
331 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
332 CHECK_STATUS(status, NT_STATUS_OK);
334 done:
335 if (h1 != NULL) {
336 smb2_util_close(tree, *h1);
339 smb2_util_unlink(tree, fname);
341 talloc_free(tree);
343 talloc_free(mem_ctx);
345 return ret;
349 * test getting security descriptor after reauth
351 bool test_session_reauth3(struct torture_context *tctx, struct smb2_tree *tree)
353 NTSTATUS status;
354 TALLOC_CTX *mem_ctx = talloc_new(tctx);
355 char fname[256];
356 struct smb2_handle _h1;
357 struct smb2_handle *h1 = NULL;
358 struct smb2_create io1;
359 bool ret = true;
360 union smb_fileinfo qfinfo;
361 struct cli_credentials *anon_creds = NULL;
362 uint32_t secinfo_flags = SECINFO_OWNER
363 | SECINFO_GROUP
364 | SECINFO_DACL
365 | SECINFO_PROTECTED_DACL
366 | SECINFO_UNPROTECTED_DACL;
368 /* Add some random component to the file name. */
369 snprintf(fname, 256, "session_reauth3_%s.dat",
370 generate_random_str(tctx, 8));
372 smb2_util_unlink(tree, fname);
374 smb2_oplock_create_share(&io1, fname,
375 smb2_util_share_access(""),
376 smb2_util_oplock_level("b"));
378 status = smb2_create(tree, mem_ctx, &io1);
379 CHECK_STATUS(status, NT_STATUS_OK);
380 _h1 = io1.out.file.handle;
381 h1 = &_h1;
382 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
383 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
385 /* get the security descriptor */
387 ZERO_STRUCT(qfinfo);
389 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
390 qfinfo.query_secdesc.in.file.handle = _h1;
391 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
393 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
394 CHECK_STATUS(status, NT_STATUS_OK);
395 /* re-authenticate as anonymous */
397 anon_creds = cli_credentials_init_anon(mem_ctx);
398 torture_assert(tctx, (anon_creds != NULL), "talloc error");
400 status = smb2_session_setup_spnego(tree->session,
401 anon_creds,
402 0 /* previous_session_id */);
403 CHECK_STATUS(status, NT_STATUS_OK);
405 /* try to access the file via the old handle */
407 ZERO_STRUCT(qfinfo);
409 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
410 qfinfo.query_secdesc.in.file.handle = _h1;
411 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
413 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
414 CHECK_STATUS(status, NT_STATUS_OK);
416 /* re-authenticate as original user again */
418 status = smb2_session_setup_spnego(tree->session,
419 cmdline_credentials,
420 0 /* previous_session_id */);
421 CHECK_STATUS(status, NT_STATUS_OK);
423 /* try to access the file via the old handle */
425 ZERO_STRUCT(qfinfo);
427 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
428 qfinfo.query_secdesc.in.file.handle = _h1;
429 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
431 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
432 CHECK_STATUS(status, NT_STATUS_OK);
434 done:
435 if (h1 != NULL) {
436 smb2_util_close(tree, *h1);
439 smb2_util_unlink(tree, fname);
441 talloc_free(tree);
443 talloc_free(mem_ctx);
445 return ret;
449 * test setting security descriptor after reauth.
451 bool test_session_reauth4(struct torture_context *tctx, struct smb2_tree *tree)
453 NTSTATUS status;
454 TALLOC_CTX *mem_ctx = talloc_new(tctx);
455 char fname[256];
456 struct smb2_handle _h1;
457 struct smb2_handle *h1 = NULL;
458 struct smb2_create io1;
459 bool ret = true;
460 union smb_fileinfo qfinfo;
461 union smb_setfileinfo sfinfo;
462 struct cli_credentials *anon_creds = NULL;
463 uint32_t secinfo_flags = SECINFO_OWNER
464 | SECINFO_GROUP
465 | SECINFO_DACL
466 | SECINFO_PROTECTED_DACL
467 | SECINFO_UNPROTECTED_DACL;
468 struct security_descriptor *sd1;
469 struct security_ace ace;
470 struct dom_sid *extra_sid;
472 /* Add some random component to the file name. */
473 snprintf(fname, 256, "session_reauth4_%s.dat",
474 generate_random_str(tctx, 8));
476 smb2_util_unlink(tree, fname);
478 smb2_oplock_create_share(&io1, fname,
479 smb2_util_share_access(""),
480 smb2_util_oplock_level("b"));
482 status = smb2_create(tree, mem_ctx, &io1);
483 CHECK_STATUS(status, NT_STATUS_OK);
484 _h1 = io1.out.file.handle;
485 h1 = &_h1;
486 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
487 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
489 /* get the security descriptor */
491 ZERO_STRUCT(qfinfo);
493 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
494 qfinfo.query_secdesc.in.file.handle = _h1;
495 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
497 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
498 CHECK_STATUS(status, NT_STATUS_OK);
500 sd1 = qfinfo.query_secdesc.out.sd;
502 /* re-authenticate as anonymous */
504 anon_creds = cli_credentials_init_anon(mem_ctx);
505 torture_assert(tctx, (anon_creds != NULL), "talloc error");
507 status = smb2_session_setup_spnego(tree->session,
508 anon_creds,
509 0 /* previous_session_id */);
510 CHECK_STATUS(status, NT_STATUS_OK);
512 /* give full access on the file to anonymous */
514 extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
516 ZERO_STRUCT(ace);
517 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
518 ace.flags = 0;
519 ace.access_mask = SEC_STD_ALL | SEC_FILE_ALL;
520 ace.trustee = *extra_sid;
522 status = security_descriptor_dacl_add(sd1, &ace);
523 CHECK_STATUS(status, NT_STATUS_OK);
525 ZERO_STRUCT(sfinfo);
526 sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
527 sfinfo.set_secdesc.in.file.handle = _h1;
528 sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
529 sfinfo.set_secdesc.in.sd = sd1;
531 status = smb2_setinfo_file(tree, &sfinfo);
532 CHECK_STATUS(status, NT_STATUS_OK);
534 /* re-authenticate as original user again */
536 status = smb2_session_setup_spnego(tree->session,
537 cmdline_credentials,
538 0 /* previous_session_id */);
539 CHECK_STATUS(status, NT_STATUS_OK);
541 /* re-get the security descriptor */
543 ZERO_STRUCT(qfinfo);
545 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
546 qfinfo.query_secdesc.in.file.handle = _h1;
547 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
549 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
550 CHECK_STATUS(status, NT_STATUS_OK);
552 ret = true;
554 done:
555 if (h1 != NULL) {
556 smb2_util_close(tree, *h1);
559 smb2_util_unlink(tree, fname);
561 talloc_free(tree);
563 talloc_free(mem_ctx);
565 return ret;
569 * test renaming after reauth.
570 * compare security descriptors before and after rename/reauth
572 bool test_session_reauth5(struct torture_context *tctx, struct smb2_tree *tree)
574 NTSTATUS status;
575 TALLOC_CTX *mem_ctx = talloc_new(tctx);
576 char fname[256];
577 char fname2[256];
578 struct smb2_handle _h1;
579 struct smb2_handle *h1 = NULL;
580 struct smb2_create io1;
581 bool ret = true;
582 union smb_fileinfo qfinfo;
583 union smb_setfileinfo sfinfo;
584 struct cli_credentials *anon_creds = NULL;
585 uint32_t secinfo_flags = SECINFO_OWNER
586 | SECINFO_GROUP
587 | SECINFO_DACL
588 | SECINFO_PROTECTED_DACL
589 | SECINFO_UNPROTECTED_DACL;
590 struct security_descriptor *sd1, *sd2;
591 struct security_ace ace;
592 struct dom_sid *extra_sid;
594 /* Add some random component to the file name. */
595 snprintf(fname, 256, "session_reauth5_%s.dat",
596 generate_random_str(tctx, 8));
598 smb2_util_unlink(tree, fname);
600 smb2_oplock_create_share(&io1, fname,
601 smb2_util_share_access(""),
602 smb2_util_oplock_level("b"));
604 status = smb2_create(tree, mem_ctx, &io1);
605 CHECK_STATUS(status, NT_STATUS_OK);
606 _h1 = io1.out.file.handle;
607 h1 = &_h1;
608 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
609 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
611 /* get the security descriptor */
613 ZERO_STRUCT(qfinfo);
615 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
616 qfinfo.query_secdesc.in.file.handle = _h1;
617 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
619 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
620 CHECK_STATUS(status, NT_STATUS_OK);
622 sd1 = qfinfo.query_secdesc.out.sd;
624 /* re-authenticate as anonymous */
626 anon_creds = cli_credentials_init_anon(mem_ctx);
627 torture_assert(tctx, (anon_creds != NULL), "talloc error");
629 status = smb2_session_setup_spnego(tree->session,
630 anon_creds,
631 0 /* previous_session_id */);
632 CHECK_STATUS(status, NT_STATUS_OK);
634 /* try to rename the file: fails */
636 snprintf(fname2, 256, "session_reauth5.2_%s.dat",
637 generate_random_str(tctx, 8));
639 smb2_util_unlink(tree, fname2);
641 ZERO_STRUCT(sfinfo);
642 sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
643 sfinfo.rename_information.in.file.handle = _h1;
644 sfinfo.rename_information.in.overwrite = true;
645 sfinfo.rename_information.in.new_name = fname2;
647 status = smb2_setinfo_file(tree, &sfinfo);
648 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
650 /* re-authenticate as original user again */
652 status = smb2_session_setup_spnego(tree->session,
653 cmdline_credentials,
654 0 /* previous_session_id */);
655 CHECK_STATUS(status, NT_STATUS_OK);
657 /* give full access on the file to anonymous */
659 extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
661 ZERO_STRUCT(ace);
662 ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
663 ace.flags = 0;
664 ace.access_mask = SEC_STD_ALL | SEC_FILE_ALL;
665 ace.trustee = *extra_sid;
667 status = security_descriptor_dacl_add(sd1, &ace);
668 CHECK_STATUS(status, NT_STATUS_OK);
670 ZERO_STRUCT(sfinfo);
671 sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
672 sfinfo.set_secdesc.in.file.handle = _h1;
673 sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
674 sfinfo.set_secdesc.in.sd = sd1;
676 status = smb2_setinfo_file(tree, &sfinfo);
677 CHECK_STATUS(status, NT_STATUS_OK);
679 /* re-get the security descriptor */
681 ZERO_STRUCT(qfinfo);
683 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
684 qfinfo.query_secdesc.in.file.handle = _h1;
685 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
687 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
688 CHECK_STATUS(status, NT_STATUS_OK);
690 /* re-authenticate as anonymous - again */
692 anon_creds = cli_credentials_init_anon(mem_ctx);
693 torture_assert(tctx, (anon_creds != NULL), "talloc error");
695 status = smb2_session_setup_spnego(tree->session,
696 anon_creds,
697 0 /* previous_session_id */);
698 CHECK_STATUS(status, NT_STATUS_OK);
700 /* try to rename the file: fails */
702 snprintf(fname2, 256, "session_reauth3.2_%s.dat",
703 generate_random_str(tctx, 8));
705 smb2_util_unlink(tree, fname2);
707 ZERO_STRUCT(sfinfo);
708 sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
709 sfinfo.rename_information.in.file.handle = _h1;
710 sfinfo.rename_information.in.overwrite = true;
711 sfinfo.rename_information.in.new_name = fname2;
713 status = smb2_setinfo_file(tree, &sfinfo);
714 CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
716 /* re-authenticate as original user - again */
718 status = smb2_session_setup_spnego(tree->session,
719 cmdline_credentials,
720 0 /* previous_session_id */);
721 CHECK_STATUS(status, NT_STATUS_OK);
723 /* rename the file - for verification that it works */
725 ZERO_STRUCT(sfinfo);
726 sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
727 sfinfo.rename_information.in.file.handle = _h1;
728 sfinfo.rename_information.in.overwrite = true;
729 sfinfo.rename_information.in.new_name = fname2;
731 status = smb2_setinfo_file(tree, &sfinfo);
732 CHECK_STATUS(status, NT_STATUS_OK);
734 /* closs the file, check it is gone and reopen under the new name */
736 smb2_util_close(tree, _h1);
738 ZERO_STRUCT(io1);
740 smb2_generic_create_share(&io1,
741 NULL /* lease */, false /* dir */,
742 fname,
743 NTCREATEX_DISP_OPEN,
744 smb2_util_share_access(""),
745 smb2_util_oplock_level("b"),
746 0 /* leasekey */, 0 /* leasestate */);
748 status = smb2_create(tree, mem_ctx, &io1);
749 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
751 ZERO_STRUCT(io1);
753 smb2_generic_create_share(&io1,
754 NULL /* lease */, false /* dir */,
755 fname2,
756 NTCREATEX_DISP_OPEN,
757 smb2_util_share_access(""),
758 smb2_util_oplock_level("b"),
759 0 /* leasekey */, 0 /* leasestate */);
761 status = smb2_create(tree, mem_ctx, &io1);
762 CHECK_STATUS(status, NT_STATUS_OK);
763 _h1 = io1.out.file.handle;
764 h1 = &_h1;
765 CHECK_CREATED(&io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
766 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
768 /* try to access the file via the old handle */
770 ZERO_STRUCT(qfinfo);
772 qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
773 qfinfo.query_secdesc.in.file.handle = _h1;
774 qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
776 status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
777 CHECK_STATUS(status, NT_STATUS_OK);
779 sd2 = qfinfo.query_secdesc.out.sd;
781 done:
782 if (h1 != NULL) {
783 smb2_util_close(tree, *h1);
786 smb2_util_unlink(tree, fname);
788 talloc_free(tree);
790 talloc_free(mem_ctx);
792 return ret;
795 static bool test_session_expire1(struct torture_context *tctx)
797 NTSTATUS status;
798 bool ret = false;
799 struct smbcli_options options;
800 const char *host = torture_setting_string(tctx, "host", NULL);
801 const char *share = torture_setting_string(tctx, "share", NULL);
802 struct cli_credentials *credentials = cmdline_credentials;
803 struct smb2_tree *tree;
804 enum credentials_use_kerberos use_kerberos;
805 char fname[256];
806 struct smb2_handle _h1;
807 struct smb2_handle *h1 = NULL;
808 struct smb2_create io1;
809 union smb_fileinfo qfinfo;
810 size_t i;
812 use_kerberos = cli_credentials_get_kerberos_state(credentials);
813 if (use_kerberos != CRED_MUST_USE_KERBEROS) {
814 torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
815 torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
818 torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
819 "please use -k yes");
821 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
823 lpcfg_smbcli_options(tctx->lp_ctx, &options);
825 status = smb2_connect(tctx,
826 host,
827 lpcfg_smb_ports(tctx->lp_ctx),
828 share,
829 lpcfg_resolve_context(tctx->lp_ctx),
830 credentials,
831 &tree,
832 tctx->ev,
833 &options,
834 lpcfg_socket_options(tctx->lp_ctx),
835 lpcfg_gensec_settings(tctx, tctx->lp_ctx)
837 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
838 "smb2_connect failed");
840 /* Add some random component to the file name. */
841 snprintf(fname, 256, "session_expire1_%s.dat",
842 generate_random_str(tctx, 8));
844 smb2_util_unlink(tree, fname);
846 smb2_oplock_create_share(&io1, fname,
847 smb2_util_share_access(""),
848 smb2_util_oplock_level("b"));
849 io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
851 status = smb2_create(tree, tctx, &io1);
852 CHECK_STATUS(status, NT_STATUS_OK);
853 _h1 = io1.out.file.handle;
854 h1 = &_h1;
855 CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
856 CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
858 /* get the security descriptor */
860 ZERO_STRUCT(qfinfo);
862 qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
863 qfinfo.access_information.in.file.handle = _h1;
865 for (i=0; i < 2; i++) {
866 torture_comment(tctx, "query info => OK\n");
868 ZERO_STRUCT(qfinfo.access_information.out);
869 status = smb2_getinfo_file(tree, tctx, &qfinfo);
870 CHECK_STATUS(status, NT_STATUS_OK);
872 torture_comment(tctx, "sleep 5 seconds\n");
873 smb_msleep(5*1000);
875 torture_comment(tctx, "query info => EXPIRED\n");
876 ZERO_STRUCT(qfinfo.access_information.out);
877 status = smb2_getinfo_file(tree, tctx, &qfinfo);
878 CHECK_STATUS(status, NT_STATUS_NETWORK_SESSION_EXPIRED);
881 * the krb5 library may not handle expired creds
882 * well, lets start with an empty ccache.
884 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
886 torture_comment(tctx, "reauth => OK\n");
887 status = smb2_session_setup_spnego(tree->session,
888 credentials,
889 0 /* previous_session_id */);
890 CHECK_STATUS(status, NT_STATUS_OK);
893 ZERO_STRUCT(qfinfo.access_information.out);
894 status = smb2_getinfo_file(tree, tctx, &qfinfo);
895 CHECK_STATUS(status, NT_STATUS_OK);
897 ret = true;
898 done:
899 if (h1 != NULL) {
900 smb2_util_close(tree, *h1);
903 talloc_free(tree);
904 lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
905 return ret;
908 struct torture_suite *torture_smb2_session_init(void)
910 struct torture_suite *suite =
911 torture_suite_create(talloc_autofree_context(), "session");
913 torture_suite_add_1smb2_test(suite, "reconnect1", test_session_reconnect1);
914 torture_suite_add_1smb2_test(suite, "reconnect2", test_session_reconnect2);
915 torture_suite_add_1smb2_test(suite, "reauth1", test_session_reauth1);
916 torture_suite_add_1smb2_test(suite, "reauth2", test_session_reauth2);
917 torture_suite_add_1smb2_test(suite, "reauth3", test_session_reauth3);
918 torture_suite_add_1smb2_test(suite, "reauth4", test_session_reauth4);
919 torture_suite_add_1smb2_test(suite, "reauth5", test_session_reauth5);
920 torture_suite_add_simple_test(suite, "expire1", test_session_expire1);
922 suite->description = talloc_strdup(suite, "SMB2-SESSION tests");
924 return suite;