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