7bb9f64ad2d1bb422858a2967be1d87a1b9c50e4
[garming/samba-autobuild/.git] / source4 / torture / smb2 / session.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    test suite for SMB2 session setups
5
6    Copyright (C) Michael Adam 2012
7
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.
12
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.
17
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/>.
20 */
21
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"
33
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)
40
41 #define CHECK_CREATED(__io, __created, __attribute)                     \
42         do {                                                            \
43                 CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \
44                 CHECK_VAL((__io)->out.alloc_size, 0);                   \
45                 CHECK_VAL((__io)->out.size, 0);                         \
46                 CHECK_VAL((__io)->out.file_attr, (__attribute));        \
47                 CHECK_VAL((__io)->out.reserved2, 0);                    \
48         } while(0)
49
50
51 /**
52  * basic test for doing a session reconnect
53  */
54 bool test_session_reconnect1(struct torture_context *tctx, struct smb2_tree *tree)
55 {
56         NTSTATUS status;
57         TALLOC_CTX *mem_ctx = talloc_new(tctx);
58         char fname[256];
59         struct smb2_handle _h1;
60         struct smb2_handle *h1 = NULL;
61         struct smb2_handle _h2;
62         struct smb2_handle *h2 = NULL;
63         struct smb2_create io1, io2;
64         uint64_t previous_session_id;
65         bool ret = true;
66         struct smb2_tree *tree2 = NULL;
67         union smb_fileinfo qfinfo;
68
69         /* Add some random component to the file name. */
70         snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
71                  generate_random_str(tctx, 8));
72
73         smb2_util_unlink(tree, fname);
74
75         smb2_oplock_create_share(&io1, fname,
76                                  smb2_util_share_access(""),
77                                  smb2_util_oplock_level("b"));
78
79         status = smb2_create(tree, mem_ctx, &io1);
80         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
81                                         "smb2_create failed");
82         _h1 = io1.out.file.handle;
83         h1 = &_h1;
84         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
85         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
86
87         /* disconnect, reconnect and then do durable reopen */
88         previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
89
90         torture_assert_goto(tctx, torture_smb2_connection_ext(tctx, previous_session_id,
91                             &tree->session->transport->options, &tree2),
92                             ret, done,
93                             "session reconnect failed\n");
94
95         /* try to access the file via the old handle */
96
97         ZERO_STRUCT(qfinfo);
98         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
99         qfinfo.generic.in.file.handle = _h1;
100         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
101         torture_assert_ntstatus_equal_goto(tctx, status,
102                                            NT_STATUS_USER_SESSION_DELETED,
103                                            ret, done, "smb2_getinfo_file "
104                                            "returned unexpected status");
105         h1 = NULL;
106
107         smb2_oplock_create_share(&io2, fname,
108                                  smb2_util_share_access(""),
109                                  smb2_util_oplock_level("b"));
110
111         status = smb2_create(tree2, mem_ctx, &io2);
112         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
113                                         "smb2_create failed");
114
115         CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
116         CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b"));
117         _h2 = io2.out.file.handle;
118         h2 = &_h2;
119
120 done:
121         if (h1 != NULL) {
122                 smb2_util_close(tree, *h1);
123         }
124         if (h2 != NULL) {
125                 smb2_util_close(tree2, *h2);
126         }
127
128         if (tree2 != NULL) {
129                 smb2_util_unlink(tree2, fname);
130         }
131         smb2_util_unlink(tree, fname);
132
133         talloc_free(tree);
134         talloc_free(tree2);
135
136         talloc_free(mem_ctx);
137
138         return ret;
139 }
140
141 /**
142  * basic test for doing a session reconnect on one connection
143  */
144 bool test_session_reconnect2(struct torture_context *tctx, struct smb2_tree *tree)
145 {
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 = NULL;
155         union smb_fileinfo qfinfo;
156
157         /* Add some random component to the file name. */
158         snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
159                  generate_random_str(tctx, 8));
160
161         smb2_util_unlink(tree, fname);
162
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;
167
168         status = smb2_create(tree, mem_ctx, &io1);
169         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
170                                         "smb2_create failed");
171         _h1 = io1.out.file.handle;
172         h1 = &_h1;
173         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
174         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
175
176         /* disconnect, reconnect and then do durable reopen */
177         previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
178
179         torture_assert(tctx, torture_smb2_session_setup(tctx, tree->session->transport,
180                                 previous_session_id, tctx, &session2),
181                                 "session reconnect (on the same connection) failed");
182
183         /* try to access the file via the old handle */
184
185         ZERO_STRUCT(qfinfo);
186         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
187         qfinfo.generic.in.file.handle = _h1;
188         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
189         torture_assert_ntstatus_equal_goto(tctx, status,
190                                            NT_STATUS_USER_SESSION_DELETED,
191                                            ret, done, "smb2_getinfo_file "
192                                            "returned unexpected status");
193         h1 = NULL;
194
195 done:
196         if (h1 != NULL) {
197                 smb2_util_close(tree, *h1);
198         }
199
200         talloc_free(tree);
201         talloc_free(session2);
202
203         talloc_free(mem_ctx);
204
205         return ret;
206 }
207
208 bool test_session_reauth1(struct torture_context *tctx, struct smb2_tree *tree)
209 {
210         NTSTATUS status;
211         TALLOC_CTX *mem_ctx = talloc_new(tctx);
212         char fname[256];
213         struct smb2_handle _h1;
214         struct smb2_handle *h1 = NULL;
215         struct smb2_create io1;
216         bool ret = true;
217         union smb_fileinfo qfinfo;
218
219         /* Add some random component to the file name. */
220         snprintf(fname, sizeof(fname), "session_reauth1_%s.dat",
221                  generate_random_str(tctx, 8));
222
223         smb2_util_unlink(tree, fname);
224
225         smb2_oplock_create_share(&io1, fname,
226                                  smb2_util_share_access(""),
227                                  smb2_util_oplock_level("b"));
228
229         status = smb2_create(tree, mem_ctx, &io1);
230         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
231                                         "smb2_create failed");
232         _h1 = io1.out.file.handle;
233         h1 = &_h1;
234         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
235         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
236
237         status = smb2_session_setup_spnego(tree->session,
238                                            cmdline_credentials,
239                                            0 /* previous_session_id */);
240         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
241                                         "smb2_session_setup_spnego failed");
242
243         /* try to access the file via the old handle */
244
245         ZERO_STRUCT(qfinfo);
246         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
247         qfinfo.generic.in.file.handle = _h1;
248         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
249         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
250                                         "smb2_getinfo_file failed");
251
252         status = smb2_session_setup_spnego(tree->session,
253                                            cmdline_credentials,
254                                            0 /* previous_session_id */);
255         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
256                                         "smb2_session_setup_spnego failed");
257
258         /* try to access the file via the old handle */
259
260         ZERO_STRUCT(qfinfo);
261         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
262         qfinfo.generic.in.file.handle = _h1;
263         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
264         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
265                                         "smb2_getinfo_file failed");
266
267 done:
268         if (h1 != NULL) {
269                 smb2_util_close(tree, *h1);
270         }
271
272         smb2_util_unlink(tree, fname);
273
274         talloc_free(tree);
275
276         talloc_free(mem_ctx);
277
278         return ret;
279 }
280
281 bool test_session_reauth2(struct torture_context *tctx, struct smb2_tree *tree)
282 {
283         NTSTATUS status;
284         TALLOC_CTX *mem_ctx = talloc_new(tctx);
285         char fname[256];
286         struct smb2_handle _h1;
287         struct smb2_handle *h1 = NULL;
288         struct smb2_create io1;
289         bool ret = true;
290         union smb_fileinfo qfinfo;
291         struct cli_credentials *anon_creds = NULL;
292
293         /* Add some random component to the file name. */
294         snprintf(fname, sizeof(fname), "session_reauth2_%s.dat",
295                  generate_random_str(tctx, 8));
296
297         smb2_util_unlink(tree, fname);
298
299         smb2_oplock_create_share(&io1, fname,
300                                  smb2_util_share_access(""),
301                                  smb2_util_oplock_level("b"));
302
303         status = smb2_create(tree, mem_ctx, &io1);
304         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
305                                         "smb2_create failed");
306         _h1 = io1.out.file.handle;
307         h1 = &_h1;
308         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
309         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
310
311         /* re-authenticate as anonymous */
312
313         anon_creds = cli_credentials_init_anon(mem_ctx);
314         torture_assert(tctx, (anon_creds != NULL), "talloc error");
315
316         status = smb2_session_setup_spnego(tree->session,
317                                            anon_creds,
318                                            0 /* previous_session_id */);
319         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
320                                         "smb2_session_setup_spnego failed");
321
322         /* try to access the file via the old handle */
323
324         ZERO_STRUCT(qfinfo);
325         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
326         qfinfo.generic.in.file.handle = _h1;
327         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
328         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
329                                         "smb2_getinfo_file failed");
330
331         /* re-authenticate as original user again */
332
333         status = smb2_session_setup_spnego(tree->session,
334                                            cmdline_credentials,
335                                            0 /* previous_session_id */);
336         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
337                                         "smb2_session_setup_spnego failed");
338
339         /* try to access the file via the old handle */
340
341         ZERO_STRUCT(qfinfo);
342         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
343         qfinfo.generic.in.file.handle = _h1;
344         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
345         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
346                                         "smb2_getinfo_file failed");
347
348 done:
349         if (h1 != NULL) {
350                 smb2_util_close(tree, *h1);
351         }
352
353         smb2_util_unlink(tree, fname);
354
355         talloc_free(tree);
356
357         talloc_free(mem_ctx);
358
359         return ret;
360 }
361
362 /**
363  * test getting security descriptor after reauth
364  */
365 bool test_session_reauth3(struct torture_context *tctx, struct smb2_tree *tree)
366 {
367         NTSTATUS status;
368         TALLOC_CTX *mem_ctx = talloc_new(tctx);
369         char fname[256];
370         struct smb2_handle _h1;
371         struct smb2_handle *h1 = NULL;
372         struct smb2_create io1;
373         bool ret = true;
374         union smb_fileinfo qfinfo;
375         struct cli_credentials *anon_creds = NULL;
376         uint32_t secinfo_flags = SECINFO_OWNER
377                                 | SECINFO_GROUP
378                                 | SECINFO_DACL
379                                 | SECINFO_PROTECTED_DACL
380                                 | SECINFO_UNPROTECTED_DACL;
381
382         /* Add some random component to the file name. */
383         snprintf(fname, sizeof(fname), "session_reauth3_%s.dat",
384                  generate_random_str(tctx, 8));
385
386         smb2_util_unlink(tree, fname);
387
388         smb2_oplock_create_share(&io1, fname,
389                                  smb2_util_share_access(""),
390                                  smb2_util_oplock_level("b"));
391
392         status = smb2_create(tree, mem_ctx, &io1);
393         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
394                                         "smb2_create failed");
395         _h1 = io1.out.file.handle;
396         h1 = &_h1;
397         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
398         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
399
400         /* get the security descriptor */
401
402         ZERO_STRUCT(qfinfo);
403
404         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
405         qfinfo.query_secdesc.in.file.handle = _h1;
406         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
407
408         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
409         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
410                                         "smb2_getinfo_file failed");
411
412         /* re-authenticate as anonymous */
413
414         anon_creds = cli_credentials_init_anon(mem_ctx);
415         torture_assert(tctx, (anon_creds != NULL), "talloc error");
416
417         status = smb2_session_setup_spnego(tree->session,
418                                            anon_creds,
419                                            0 /* previous_session_id */);
420         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
421                                         "smb2_session_setup_spnego failed");
422
423         /* try to access the file via the old handle */
424
425         ZERO_STRUCT(qfinfo);
426
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;
430
431         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
432         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
433                                         "smb2_getinfo_file failed");
434
435         /* re-authenticate as original user again */
436
437         status = smb2_session_setup_spnego(tree->session,
438                                            cmdline_credentials,
439                                            0 /* previous_session_id */);
440         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
441                                         "smb2_session_setup_spnego failed");
442
443         /* try to access the file via the old handle */
444
445         ZERO_STRUCT(qfinfo);
446
447         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
448         qfinfo.query_secdesc.in.file.handle = _h1;
449         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
450
451         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
452         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
453                                         "smb2_getinfo_file failed");
454
455 done:
456         if (h1 != NULL) {
457                 smb2_util_close(tree, *h1);
458         }
459
460         smb2_util_unlink(tree, fname);
461
462         talloc_free(tree);
463
464         talloc_free(mem_ctx);
465
466         return ret;
467 }
468
469 /**
470  * test setting security descriptor after reauth.
471  */
472 bool test_session_reauth4(struct torture_context *tctx, struct smb2_tree *tree)
473 {
474         NTSTATUS status;
475         TALLOC_CTX *mem_ctx = talloc_new(tctx);
476         char fname[256];
477         struct smb2_handle _h1;
478         struct smb2_handle *h1 = NULL;
479         struct smb2_create io1;
480         bool ret = true;
481         union smb_fileinfo qfinfo;
482         union smb_setfileinfo sfinfo;
483         struct cli_credentials *anon_creds = NULL;
484         uint32_t secinfo_flags = SECINFO_OWNER
485                                 | SECINFO_GROUP
486                                 | SECINFO_DACL
487                                 | SECINFO_PROTECTED_DACL
488                                 | SECINFO_UNPROTECTED_DACL;
489         struct security_descriptor *sd1;
490         struct security_ace ace;
491         struct dom_sid *extra_sid;
492
493         /* Add some random component to the file name. */
494         snprintf(fname, sizeof(fname), "session_reauth4_%s.dat",
495                  generate_random_str(tctx, 8));
496
497         smb2_util_unlink(tree, fname);
498
499         smb2_oplock_create_share(&io1, fname,
500                                  smb2_util_share_access(""),
501                                  smb2_util_oplock_level("b"));
502
503         status = smb2_create(tree, mem_ctx, &io1);
504         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
505                                         "smb2_create failed");
506         _h1 = io1.out.file.handle;
507         h1 = &_h1;
508         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
509         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
510
511         /* get the security descriptor */
512
513         ZERO_STRUCT(qfinfo);
514
515         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
516         qfinfo.query_secdesc.in.file.handle = _h1;
517         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
518
519         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
520         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
521                                         "smb2_getinfo_file failed");
522
523         sd1 = qfinfo.query_secdesc.out.sd;
524
525         /* re-authenticate as anonymous */
526
527         anon_creds = cli_credentials_init_anon(mem_ctx);
528         torture_assert(tctx, (anon_creds != NULL), "talloc error");
529
530         status = smb2_session_setup_spnego(tree->session,
531                                            anon_creds,
532                                            0 /* previous_session_id */);
533         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
534                                         "smb2_session_setup_spnego failed");
535
536         /* give full access on the file to anonymous */
537
538         extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
539
540         ZERO_STRUCT(ace);
541         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
542         ace.flags = 0;
543         ace.access_mask = SEC_STD_ALL | SEC_FILE_ALL;
544         ace.trustee = *extra_sid;
545
546         status = security_descriptor_dacl_add(sd1, &ace);
547         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
548                                         "security_descriptor_dacl_add failed");
549
550         ZERO_STRUCT(sfinfo);
551         sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
552         sfinfo.set_secdesc.in.file.handle = _h1;
553         sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
554         sfinfo.set_secdesc.in.sd = sd1;
555
556         status = smb2_setinfo_file(tree, &sfinfo);
557         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
558                                         "smb2_setinfo_file failed");
559
560         /* re-authenticate as original user again */
561
562         status = smb2_session_setup_spnego(tree->session,
563                                            cmdline_credentials,
564                                            0 /* previous_session_id */);
565         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
566                                         "smb2_session_setup_spnego failed");
567
568         /* re-get the security descriptor */
569
570         ZERO_STRUCT(qfinfo);
571
572         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
573         qfinfo.query_secdesc.in.file.handle = _h1;
574         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
575
576         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
577         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
578                                         "smb2_getinfo_file failed");
579
580         ret = true;
581
582 done:
583         if (h1 != NULL) {
584                 smb2_util_close(tree, *h1);
585         }
586
587         smb2_util_unlink(tree, fname);
588
589         talloc_free(tree);
590
591         talloc_free(mem_ctx);
592
593         return ret;
594 }
595
596 /**
597  * test renaming after reauth.
598  * compare security descriptors before and after rename/reauth
599  */
600 bool test_session_reauth5(struct torture_context *tctx, struct smb2_tree *tree)
601 {
602         NTSTATUS status;
603         TALLOC_CTX *mem_ctx = talloc_new(tctx);
604         char dname[256];
605         char fname[256];
606         char fname2[256];
607         struct smb2_handle _dh1;
608         struct smb2_handle *dh1 = NULL;
609         struct smb2_handle _h1;
610         struct smb2_handle *h1 = NULL;
611         struct smb2_create io1;
612         bool ret = true;
613         bool ok;
614         union smb_fileinfo qfinfo;
615         union smb_setfileinfo sfinfo;
616         struct cli_credentials *anon_creds = NULL;
617         uint32_t secinfo_flags = SECINFO_OWNER
618                                 | SECINFO_GROUP
619                                 | SECINFO_DACL
620                                 | SECINFO_PROTECTED_DACL
621                                 | SECINFO_UNPROTECTED_DACL;
622         struct security_descriptor *f_sd1;
623         struct security_descriptor *d_sd1 = NULL;
624         struct security_ace ace;
625         struct dom_sid *extra_sid;
626
627         /* Add some random component to the file name. */
628         snprintf(dname, sizeof(dname), "session_reauth5_%s.d",
629                  generate_random_str(tctx, 8));
630         snprintf(fname, sizeof(fname), "%s\\file.dat", dname);
631
632         ok = smb2_util_setup_dir(tctx, tree, dname);
633         CHECK_VAL(ok, true);
634
635         status = torture_smb2_testdir(tree, dname, &_dh1);
636         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
637                                         "torture_smb2_testdir failed");
638         dh1 = &_dh1;
639
640         smb2_oplock_create_share(&io1, fname,
641                                  smb2_util_share_access(""),
642                                  smb2_util_oplock_level("b"));
643
644         status = smb2_create(tree, mem_ctx, &io1);
645         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
646                                         "smb2_create failed");
647         _h1 = io1.out.file.handle;
648         h1 = &_h1;
649         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
650         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
651
652         /* get the security descriptor */
653
654         ZERO_STRUCT(qfinfo);
655
656         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
657         qfinfo.query_secdesc.in.file.handle = _h1;
658         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
659
660         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
661         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
662                                         "smb2_getinfo_file failed");
663
664         f_sd1 = qfinfo.query_secdesc.out.sd;
665
666         /* re-authenticate as anonymous */
667
668         anon_creds = cli_credentials_init_anon(mem_ctx);
669         torture_assert(tctx, (anon_creds != NULL), "talloc error");
670
671         status = smb2_session_setup_spnego(tree->session,
672                                            anon_creds,
673                                            0 /* previous_session_id */);
674         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
675                                         "smb2_session_setup_spnego failed");
676
677         /* try to rename the file: fails */
678
679         snprintf(fname2, sizeof(fname2), "%s\\file2.dat", dname);
680
681         status = smb2_util_unlink(tree, fname2);
682         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
683                                         "smb2_util_unlink failed");
684
685
686         ZERO_STRUCT(sfinfo);
687         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
688         sfinfo.rename_information.in.file.handle = _h1;
689         sfinfo.rename_information.in.overwrite = true;
690         sfinfo.rename_information.in.new_name = fname2;
691
692         status = smb2_setinfo_file(tree, &sfinfo);
693         torture_assert_ntstatus_equal_goto(tctx, status,
694                                            NT_STATUS_ACCESS_DENIED,
695                                            ret, done, "smb2_setinfo_file "
696                                            "returned unexpected status");
697
698         /* re-authenticate as original user again */
699
700         status = smb2_session_setup_spnego(tree->session,
701                                            cmdline_credentials,
702                                            0 /* previous_session_id */);
703         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
704                                         "smb2_session_setup_spnego failed");
705
706         /* give full access on the file to anonymous */
707
708         extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
709
710         ZERO_STRUCT(ace);
711         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
712         ace.flags = 0;
713         ace.access_mask = SEC_RIGHTS_FILE_ALL;
714         ace.trustee = *extra_sid;
715
716         status = security_descriptor_dacl_add(f_sd1, &ace);
717         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
718                                         "security_descriptor_dacl_add failed");
719
720         ZERO_STRUCT(sfinfo);
721         sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
722         sfinfo.set_secdesc.in.file.handle = _h1;
723         sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
724         sfinfo.set_secdesc.in.sd = f_sd1;
725
726         status = smb2_setinfo_file(tree, &sfinfo);
727         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
728                                         "smb2_setinfo_file failed");
729
730         /* re-get the security descriptor */
731
732         ZERO_STRUCT(qfinfo);
733
734         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
735         qfinfo.query_secdesc.in.file.handle = _h1;
736         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
737
738         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
739         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
740                                         "smb2_getinfo_file failed");
741
742         /* re-authenticate as anonymous - again */
743
744         anon_creds = cli_credentials_init_anon(mem_ctx);
745         torture_assert(tctx, (anon_creds != NULL), "talloc error");
746
747         status = smb2_session_setup_spnego(tree->session,
748                                            anon_creds,
749                                            0 /* previous_session_id */);
750         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
751                                         "smb2_session_setup_spnego failed");
752
753         /* try to rename the file: fails */
754
755         ZERO_STRUCT(sfinfo);
756         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
757         sfinfo.rename_information.in.file.handle = _h1;
758         sfinfo.rename_information.in.overwrite = true;
759         sfinfo.rename_information.in.new_name = fname2;
760
761         status = smb2_setinfo_file(tree, &sfinfo);
762         torture_assert_ntstatus_equal_goto(tctx, status,
763                                            NT_STATUS_ACCESS_DENIED,
764                                            ret, done, "smb2_setinfo_file "
765                                            "returned unexpected status");
766
767         /* give full access on the parent dir to anonymous */
768
769         ZERO_STRUCT(qfinfo);
770
771         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
772         qfinfo.query_secdesc.in.file.handle = _dh1;
773         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
774
775         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
776         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
777                                         "smb2_getinfo_file failed");
778
779         d_sd1 = qfinfo.query_secdesc.out.sd;
780
781         ZERO_STRUCT(ace);
782         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
783         ace.flags = 0;
784         ace.access_mask = SEC_RIGHTS_FILE_ALL;
785         ace.trustee = *extra_sid;
786
787         status = security_descriptor_dacl_add(d_sd1, &ace);
788         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
789                                         "security_descriptor_dacl_add failed");
790
791         ZERO_STRUCT(sfinfo);
792         sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
793         sfinfo.set_secdesc.in.file.handle = _dh1;
794         sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
795         sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
796         sfinfo.set_secdesc.in.sd = d_sd1;
797
798         status = smb2_setinfo_file(tree, &sfinfo);
799         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
800                                         "smb2_setinfo_file failed");
801
802         ZERO_STRUCT(qfinfo);
803
804         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
805         qfinfo.query_secdesc.in.file.handle = _dh1;
806         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
807
808         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
809         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
810                                         "smb2_getinfo_file failed");
811
812         status = smb2_util_close(tree, _dh1);
813         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
814                                         "smb2_util_close failed");
815         dh1 = NULL;
816
817         /* try to rename the file: still fails */
818
819         ZERO_STRUCT(sfinfo);
820         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
821         sfinfo.rename_information.in.file.handle = _h1;
822         sfinfo.rename_information.in.overwrite = true;
823         sfinfo.rename_information.in.new_name = fname2;
824
825         status = smb2_setinfo_file(tree, &sfinfo);
826         torture_assert_ntstatus_equal_goto(tctx, status,
827                                         NT_STATUS_ACCESS_DENIED,
828                                         ret, done, "smb2_setinfo_file "
829                                         "returned unexpected status");
830
831         /* re-authenticate as original user - again */
832
833         status = smb2_session_setup_spnego(tree->session,
834                                            cmdline_credentials,
835                                            0 /* previous_session_id */);
836         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
837                                         "smb2_session_setup_spnego failed");
838
839         /* rename the file - for verification that it works */
840
841         ZERO_STRUCT(sfinfo);
842         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
843         sfinfo.rename_information.in.file.handle = _h1;
844         sfinfo.rename_information.in.overwrite = true;
845         sfinfo.rename_information.in.new_name = fname2;
846
847         status = smb2_setinfo_file(tree, &sfinfo);
848         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
849                                         "smb2_setinfo_file failed");
850
851         /* closs the file, check it is gone and reopen under the new name */
852
853         status = smb2_util_close(tree, _h1);
854         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
855                                         "smb2_util_close failed");
856         ZERO_STRUCT(io1);
857
858         smb2_generic_create_share(&io1,
859                                   NULL /* lease */, false /* dir */,
860                                   fname,
861                                   NTCREATEX_DISP_OPEN,
862                                   smb2_util_share_access(""),
863                                   smb2_util_oplock_level("b"),
864                                   0 /* leasekey */, 0 /* leasestate */);
865
866         status = smb2_create(tree, mem_ctx, &io1);
867         torture_assert_ntstatus_equal_goto(tctx, status,
868                                         NT_STATUS_OBJECT_NAME_NOT_FOUND,
869                                         ret, done, "smb2_create "
870                                         "returned unexpected status");
871
872         ZERO_STRUCT(io1);
873
874         smb2_generic_create_share(&io1,
875                                   NULL /* lease */, false /* dir */,
876                                   fname2,
877                                   NTCREATEX_DISP_OPEN,
878                                   smb2_util_share_access(""),
879                                   smb2_util_oplock_level("b"),
880                                   0 /* leasekey */, 0 /* leasestate */);
881
882         status = smb2_create(tree, mem_ctx, &io1);
883         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
884                                         "smb2_create failed");
885         _h1 = io1.out.file.handle;
886         h1 = &_h1;
887         CHECK_CREATED(&io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
888         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
889
890         /* try to access the file via the old handle */
891
892         ZERO_STRUCT(qfinfo);
893
894         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
895         qfinfo.query_secdesc.in.file.handle = _h1;
896         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
897
898         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
899         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
900                                         "smb2_getinfo_file failed");
901
902 done:
903         if (dh1 != NULL) {
904                 smb2_util_close(tree, *dh1);
905         }
906         if (h1 != NULL) {
907                 smb2_util_close(tree, *h1);
908         }
909
910         smb2_deltree(tree, dname);
911
912         talloc_free(tree);
913
914         talloc_free(mem_ctx);
915
916         return ret;
917 }
918
919 /**
920  * do reauth with wrong credentials,
921  * hence triggering the error path in reauth.
922  * The invalid reauth deletes the session.
923  */
924 bool test_session_reauth6(struct torture_context *tctx, struct smb2_tree *tree)
925 {
926         NTSTATUS status;
927         TALLOC_CTX *mem_ctx = talloc_new(tctx);
928         char fname[256];
929         struct smb2_handle _h1;
930         struct smb2_handle *h1 = NULL;
931         struct smb2_create io1;
932         bool ret = true;
933         char *corrupted_password;
934         struct cli_credentials *broken_creds;
935         bool ok;
936         bool encrypted;
937         NTSTATUS expected;
938         enum credentials_use_kerberos krb_state;
939
940         krb_state = cli_credentials_get_kerberos_state(cmdline_credentials);
941         if (krb_state == CRED_MUST_USE_KERBEROS) {
942                 torture_skip(tctx,
943                              "Can't test failing session setup with kerberos.");
944         }
945
946         encrypted = smb2cli_tcon_is_encryption_on(tree->smbXcli);
947
948         /* Add some random component to the file name. */
949         snprintf(fname, sizeof(fname), "session_reauth1_%s.dat",
950                  generate_random_str(tctx, 8));
951
952         smb2_util_unlink(tree, fname);
953
954         smb2_oplock_create_share(&io1, fname,
955                                  smb2_util_share_access(""),
956                                  smb2_util_oplock_level("b"));
957         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
958
959         status = smb2_create(tree, mem_ctx, &io1);
960         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
961                                         "smb2_create failed");
962         _h1 = io1.out.file.handle;
963         h1 = &_h1;
964         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
965         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
966
967         /*
968          * reauthentication with invalid credentials:
969          */
970
971         broken_creds = cli_credentials_shallow_copy(mem_ctx,
972                                                     cmdline_credentials);
973         torture_assert(tctx, (broken_creds != NULL), "talloc error");
974
975         corrupted_password = talloc_asprintf(mem_ctx, "%s%s",
976                                 cli_credentials_get_password(broken_creds),
977                                 "corrupt");
978         torture_assert(tctx, (corrupted_password != NULL), "talloc error");
979
980         ok = cli_credentials_set_password(broken_creds, corrupted_password,
981                                           CRED_SPECIFIED);
982         CHECK_VAL(ok, true);
983
984         status = smb2_session_setup_spnego(tree->session,
985                                            broken_creds,
986                                            0 /* previous_session_id */);
987         torture_assert_ntstatus_equal_goto(tctx, status,
988                                         NT_STATUS_LOGON_FAILURE, ret, done,
989                                         "smb2_session_setup_spnego "
990                                         "returned unexpected status");
991
992         torture_comment(tctx, "did failed reauth\n");
993         /*
994          * now verify that the invalid session reauth has closed our session
995          */
996
997         if (encrypted) {
998                 expected = NT_STATUS_CONNECTION_DISCONNECTED;
999         } else {
1000                 expected = NT_STATUS_USER_SESSION_DELETED;
1001         }
1002
1003         smb2_oplock_create_share(&io1, fname,
1004                                  smb2_util_share_access(""),
1005                                  smb2_util_oplock_level("b"));
1006
1007         status = smb2_create(tree, mem_ctx, &io1);
1008         torture_assert_ntstatus_equal_goto(tctx, status, expected,
1009                                         ret, done, "smb2_create "
1010                                         "returned unexpected status");
1011
1012 done:
1013         if (h1 != NULL) {
1014                 smb2_util_close(tree, *h1);
1015         }
1016
1017         smb2_util_unlink(tree, fname);
1018
1019         talloc_free(tree);
1020
1021         talloc_free(mem_ctx);
1022
1023         return ret;
1024 }
1025
1026
1027 static bool test_session_expire1(struct torture_context *tctx)
1028 {
1029         NTSTATUS status;
1030         bool ret = false;
1031         struct smbcli_options options;
1032         const char *host = torture_setting_string(tctx, "host", NULL);
1033         const char *share = torture_setting_string(tctx, "share", NULL);
1034         struct cli_credentials *credentials = cmdline_credentials;
1035         struct smb2_tree *tree = NULL;
1036         enum credentials_use_kerberos use_kerberos;
1037         char fname[256];
1038         struct smb2_handle _h1;
1039         struct smb2_handle *h1 = NULL;
1040         struct smb2_create io1;
1041         union smb_fileinfo qfinfo;
1042         size_t i;
1043
1044         use_kerberos = cli_credentials_get_kerberos_state(credentials);
1045         if (use_kerberos != CRED_MUST_USE_KERBEROS) {
1046                 torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
1047                 torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
1048         }
1049
1050         torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
1051                                  "please use -k yes");
1052
1053         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
1054
1055         lpcfg_smbcli_options(tctx->lp_ctx, &options);
1056
1057         status = smb2_connect(tctx,
1058                               host,
1059                               lpcfg_smb_ports(tctx->lp_ctx),
1060                               share,
1061                               lpcfg_resolve_context(tctx->lp_ctx),
1062                               credentials,
1063                               &tree,
1064                               tctx->ev,
1065                               &options,
1066                               lpcfg_socket_options(tctx->lp_ctx),
1067                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1068                               );
1069         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1070                                         "smb2_connect failed");
1071
1072         /* Add some random component to the file name. */
1073         snprintf(fname, sizeof(fname), "session_expire1_%s.dat",
1074                  generate_random_str(tctx, 8));
1075
1076         smb2_util_unlink(tree, fname);
1077
1078         smb2_oplock_create_share(&io1, fname,
1079                                  smb2_util_share_access(""),
1080                                  smb2_util_oplock_level("b"));
1081         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1082
1083         status = smb2_create(tree, tctx, &io1);
1084         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1085                                         "smb2_create failed");
1086         _h1 = io1.out.file.handle;
1087         h1 = &_h1;
1088         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1089         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
1090
1091         /* get the security descriptor */
1092
1093         ZERO_STRUCT(qfinfo);
1094
1095         qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
1096         qfinfo.access_information.in.file.handle = _h1;
1097
1098         for (i=0; i < 2; i++) {
1099                 torture_comment(tctx, "query info => OK\n");
1100
1101                 ZERO_STRUCT(qfinfo.access_information.out);
1102                 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1103                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1104                                                 "smb2_getinfo_file failed");
1105
1106                 torture_comment(tctx, "sleep 5 seconds\n");
1107                 smb_msleep(5*1000);
1108
1109                 torture_comment(tctx, "query info => EXPIRED\n");
1110                 ZERO_STRUCT(qfinfo.access_information.out);
1111                 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1112                 torture_assert_ntstatus_equal_goto(tctx, status,
1113                                         NT_STATUS_NETWORK_SESSION_EXPIRED,
1114                                         ret, done, "smb2_getinfo_file "
1115                                         "returned unexpected status");
1116
1117                 /*
1118                  * the krb5 library may not handle expired creds
1119                  * well, lets start with an empty ccache.
1120                  */
1121                 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1122
1123                 torture_comment(tctx, "reauth => OK\n");
1124                 status = smb2_session_setup_spnego(tree->session,
1125                                                    credentials,
1126                                                    0 /* previous_session_id */);
1127                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1128                                         "smb2_session_seutup_spnego failed");
1129         }
1130
1131         ZERO_STRUCT(qfinfo.access_information.out);
1132         status = smb2_getinfo_file(tree, tctx, &qfinfo);
1133         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1134                                         "smb2_getinfo_file failed");
1135
1136         ret = true;
1137 done:
1138         if (h1 != NULL) {
1139                 smb2_util_close(tree, *h1);
1140         }
1141
1142         talloc_free(tree);
1143         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
1144         return ret;
1145 }
1146
1147 bool test_session_bind1(struct torture_context *tctx, struct smb2_tree *tree1)
1148 {
1149         const char *host = torture_setting_string(tctx, "host", NULL);
1150         const char *share = torture_setting_string(tctx, "share", NULL);
1151         struct cli_credentials *credentials = cmdline_credentials;
1152         NTSTATUS status;
1153         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1154         char fname[256];
1155         struct smb2_handle _h1;
1156         struct smb2_handle *h1 = NULL;
1157         struct smb2_create io1;
1158         union smb_fileinfo qfinfo;
1159         bool ret = false;
1160         struct smb2_tree *tree2 = NULL;
1161         struct smb2_transport *transport1 = tree1->session->transport;
1162         struct smb2_transport *transport2 = NULL;
1163         struct smb2_session *session1_1 = tree1->session;
1164         struct smb2_session *session1_2 = NULL;
1165         struct smb2_session *session2_1 = NULL;
1166         struct smb2_session *session2_2 = NULL;
1167         uint32_t caps;
1168
1169         caps = smb2cli_conn_server_capabilities(transport1->conn);
1170         if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
1171                 torture_skip(tctx, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
1172         }
1173
1174         /* Add some random component to the file name. */
1175         snprintf(fname, sizeof(fname), "session_bind1_%s.dat",
1176                  generate_random_str(tctx, 8));
1177
1178         smb2_util_unlink(tree1, fname);
1179
1180         smb2_oplock_create_share(&io1, fname,
1181                                  smb2_util_share_access(""),
1182                                  smb2_util_oplock_level("b"));
1183
1184         status = smb2_create(tree1, mem_ctx, &io1);
1185         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1186                                         "smb2_create failed");
1187         _h1 = io1.out.file.handle;
1188         h1 = &_h1;
1189         CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1190         CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b"));
1191
1192         status = smb2_connect(tctx,
1193                               host,
1194                               lpcfg_smb_ports(tctx->lp_ctx),
1195                               share,
1196                               lpcfg_resolve_context(tctx->lp_ctx),
1197                               credentials,
1198                               &tree2,
1199                               tctx->ev,
1200                               &transport1->options,
1201                               lpcfg_socket_options(tctx->lp_ctx),
1202                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1203                               );
1204         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1205                                         "smb2_connect failed");
1206         session2_2 = tree2->session;
1207         transport2 = tree2->session->transport;
1208
1209         /*
1210          * Now bind the 2nd transport connection to the 1st session
1211          */
1212         session1_2 = smb2_session_channel(transport2,
1213                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
1214                                           tree2,
1215                                           session1_1);
1216         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
1217
1218         status = smb2_session_setup_spnego(session1_2,
1219                                            cmdline_credentials,
1220                                            0 /* previous_session_id */);
1221         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1222                                         "smb2_session_setup_spnego failed");
1223
1224         /* use the 1st connection, 1st session */
1225         ZERO_STRUCT(qfinfo);
1226         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
1227         qfinfo.generic.in.file.handle = _h1;
1228         tree1->session = session1_1;
1229         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
1230         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1231                                         "smb2_getinfo_file failed");
1232
1233         /* use the 2nd connection, 1st session */
1234         ZERO_STRUCT(qfinfo);
1235         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
1236         qfinfo.generic.in.file.handle = _h1;
1237         tree1->session = session1_2;
1238         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
1239         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1240                                         "smb2_getinfo_file failed");
1241
1242         tree1->session = session1_1;
1243         status = smb2_util_close(tree1, *h1);
1244         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1245                                         "smb2_util_close failed");
1246         h1 = NULL;
1247
1248         /*
1249          * Now bind the 1st transport connection to the 2nd session
1250          */
1251         session2_1 = smb2_session_channel(transport1,
1252                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
1253                                           tree1,
1254                                           session2_2);
1255         torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed");
1256
1257         status = smb2_session_setup_spnego(session2_1,
1258                                            cmdline_credentials,
1259                                            0 /* previous_session_id */);
1260         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1261                                         "smb2_session_setup_spnego failed");
1262
1263         tree2->session = session2_1;
1264         status = smb2_util_unlink(tree2, fname);
1265         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1266                                         "smb2_util_unlink failed");
1267         ret = true;
1268 done:
1269         talloc_free(tree2);
1270         tree1->session = session1_1;
1271
1272         if (h1 != NULL) {
1273                 smb2_util_close(tree1, *h1);
1274         }
1275
1276         smb2_util_unlink(tree1, fname);
1277
1278         talloc_free(tree1);
1279
1280         talloc_free(mem_ctx);
1281
1282         return ret;
1283 }
1284
1285 struct torture_suite *torture_smb2_session_init(void)
1286 {
1287         struct torture_suite *suite =
1288             torture_suite_create(talloc_autofree_context(), "session");
1289
1290         torture_suite_add_1smb2_test(suite, "reconnect1", test_session_reconnect1);
1291         torture_suite_add_1smb2_test(suite, "reconnect2", test_session_reconnect2);
1292         torture_suite_add_1smb2_test(suite, "reauth1", test_session_reauth1);
1293         torture_suite_add_1smb2_test(suite, "reauth2", test_session_reauth2);
1294         torture_suite_add_1smb2_test(suite, "reauth3", test_session_reauth3);
1295         torture_suite_add_1smb2_test(suite, "reauth4", test_session_reauth4);
1296         torture_suite_add_1smb2_test(suite, "reauth5", test_session_reauth5);
1297         torture_suite_add_1smb2_test(suite, "reauth6", test_session_reauth6);
1298         torture_suite_add_simple_test(suite, "expire1", test_session_expire1);
1299         torture_suite_add_1smb2_test(suite, "bind1", test_session_bind1);
1300
1301         suite->description = talloc_strdup(suite, "SMB2-SESSION tests");
1302
1303         return suite;
1304 }