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