fdfd947d5e3759ecf89b53b22f77a04381b7ec3a
[samba.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/util.h"
27 #include "torture/smb2/proto.h"
28 #include "../libcli/smb/smbXcli_base.h"
29 #include "lib/cmdline/cmdline.h"
30 #include "auth/credentials/credentials.h"
31 #include "auth/credentials/credentials_krb5.h"
32 #include "libcli/security/security.h"
33 #include "libcli/resolve/resolve.h"
34 #include "lib/param/param.h"
35 #include "lib/util/tevent_ntstatus.h"
36
37 #define CHECK_CREATED(tctx, __io, __created, __attribute)                       \
38         do {                                                                    \
39                 torture_assert_int_equal(tctx, (__io)->out.create_action,       \
40                                                 NTCREATEX_ACTION_ ## __created, \
41                                                 "out.create_action 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 #define WAIT_FOR_ASYNC_RESPONSE(req) \
52         while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { \
53                 if (tevent_loop_once(tctx->ev) != 0) { \
54                         break; \
55                 } \
56         }
57
58 /**
59  * basic test for doing a session reconnect
60  */
61 bool test_session_reconnect1(struct torture_context *tctx, struct smb2_tree *tree)
62 {
63         NTSTATUS status;
64         TALLOC_CTX *mem_ctx = talloc_new(tctx);
65         char fname[256];
66         struct smb2_handle _h1;
67         struct smb2_handle *h1 = NULL;
68         struct smb2_handle _h2;
69         struct smb2_handle *h2 = NULL;
70         struct smb2_create io1, io2;
71         uint64_t previous_session_id;
72         bool ret = true;
73         struct smb2_tree *tree2 = NULL;
74         union smb_fileinfo qfinfo;
75
76         /* Add some random component to the file name. */
77         snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
78                  generate_random_str(tctx, 8));
79
80         smb2_util_unlink(tree, fname);
81
82         smb2_oplock_create_share(&io1, fname,
83                                  smb2_util_share_access(""),
84                                  smb2_util_oplock_level("b"));
85
86         status = smb2_create(tree, mem_ctx, &io1);
87         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
88                                         "smb2_create failed");
89         _h1 = io1.out.file.handle;
90         h1 = &_h1;
91         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
92         torture_assert_int_equal(tctx, io1.out.oplock_level,
93                                         smb2_util_oplock_level("b"),
94                                         "oplock_level incorrect");
95
96         /* disconnect, reconnect and then do durable reopen */
97         previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
98
99         torture_assert_goto(tctx, torture_smb2_connection_ext(tctx, previous_session_id,
100                             &tree->session->transport->options, &tree2),
101                             ret, done,
102                             "session reconnect failed\n");
103
104         /* try to access the file via the old handle */
105
106         ZERO_STRUCT(qfinfo);
107         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
108         qfinfo.generic.in.file.handle = _h1;
109         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
110         torture_assert_ntstatus_equal_goto(tctx, status,
111                                            NT_STATUS_USER_SESSION_DELETED,
112                                            ret, done, "smb2_getinfo_file "
113                                            "returned unexpected status");
114         h1 = NULL;
115
116         smb2_oplock_create_share(&io2, fname,
117                                  smb2_util_share_access(""),
118                                  smb2_util_oplock_level("b"));
119
120         status = smb2_create(tree2, mem_ctx, &io2);
121         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
122                                         "smb2_create failed");
123
124         CHECK_CREATED(tctx, &io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
125         torture_assert_int_equal(tctx, io1.out.oplock_level,
126                                         smb2_util_oplock_level("b"),
127                                         "oplock_level incorrect");
128         _h2 = io2.out.file.handle;
129         h2 = &_h2;
130
131 done:
132         if (h1 != NULL) {
133                 smb2_util_close(tree, *h1);
134         }
135         if (h2 != NULL) {
136                 smb2_util_close(tree2, *h2);
137         }
138
139         if (tree2 != NULL) {
140                 smb2_util_unlink(tree2, fname);
141         }
142         smb2_util_unlink(tree, fname);
143
144         talloc_free(tree);
145         talloc_free(tree2);
146
147         talloc_free(mem_ctx);
148
149         return ret;
150 }
151
152 /**
153  * basic test for doing a session reconnect on one connection
154  */
155 bool test_session_reconnect2(struct torture_context *tctx, struct smb2_tree *tree)
156 {
157         NTSTATUS status;
158         TALLOC_CTX *mem_ctx = talloc_new(tctx);
159         char fname[256];
160         struct smb2_handle _h1;
161         struct smb2_handle *h1 = NULL;
162         struct smb2_create io1;
163         uint64_t previous_session_id;
164         bool ret = true;
165         struct smb2_session *session2 = NULL;
166         union smb_fileinfo qfinfo;
167
168         /* Add some random component to the file name. */
169         snprintf(fname, sizeof(fname), "session_reconnect_%s.dat",
170                  generate_random_str(tctx, 8));
171
172         smb2_util_unlink(tree, fname);
173
174         smb2_oplock_create_share(&io1, fname,
175                                  smb2_util_share_access(""),
176                                  smb2_util_oplock_level("b"));
177         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
178
179         status = smb2_create(tree, mem_ctx, &io1);
180         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
181                                         "smb2_create failed");
182         _h1 = io1.out.file.handle;
183         h1 = &_h1;
184         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
185         torture_assert_int_equal(tctx, io1.out.oplock_level,
186                                         smb2_util_oplock_level("b"),
187                                         "oplock_level incorrect");
188
189         /* disconnect, reconnect and then do durable reopen */
190         previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);
191
192         torture_assert(tctx, torture_smb2_session_setup(tctx, tree->session->transport,
193                                 previous_session_id, tctx, &session2),
194                                 "session reconnect (on the same connection) failed");
195
196         /* try to access the file via the old handle */
197
198         ZERO_STRUCT(qfinfo);
199         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
200         qfinfo.generic.in.file.handle = _h1;
201         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
202         torture_assert_ntstatus_equal_goto(tctx, status,
203                                            NT_STATUS_USER_SESSION_DELETED,
204                                            ret, done, "smb2_getinfo_file "
205                                            "returned unexpected status");
206         h1 = NULL;
207
208 done:
209         if (h1 != NULL) {
210                 smb2_util_close(tree, *h1);
211         }
212
213         talloc_free(tree);
214         talloc_free(session2);
215
216         talloc_free(mem_ctx);
217
218         return ret;
219 }
220
221 bool test_session_reauth1(struct torture_context *tctx, struct smb2_tree *tree)
222 {
223         NTSTATUS status;
224         TALLOC_CTX *mem_ctx = talloc_new(tctx);
225         char fname[256];
226         struct smb2_handle _h1;
227         struct smb2_handle *h1 = NULL;
228         struct smb2_create io1;
229         bool ret = true;
230         union smb_fileinfo qfinfo;
231
232         /* Add some random component to the file name. */
233         snprintf(fname, sizeof(fname), "session_reauth1_%s.dat",
234                  generate_random_str(tctx, 8));
235
236         smb2_util_unlink(tree, fname);
237
238         smb2_oplock_create_share(&io1, fname,
239                                  smb2_util_share_access(""),
240                                  smb2_util_oplock_level("b"));
241
242         status = smb2_create(tree, mem_ctx, &io1);
243         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
244                                         "smb2_create failed");
245         _h1 = io1.out.file.handle;
246         h1 = &_h1;
247         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
248         torture_assert_int_equal(tctx, io1.out.oplock_level,
249                                         smb2_util_oplock_level("b"),
250                                         "oplock_level incorrect");
251
252         status = smb2_session_setup_spnego(tree->session,
253                                            samba_cmdline_get_creds(),
254                                            0 /* previous_session_id */);
255         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
256                                         "smb2_session_setup_spnego failed");
257
258         /* try to access the file via the old handle */
259
260         ZERO_STRUCT(qfinfo);
261         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
262         qfinfo.generic.in.file.handle = _h1;
263         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
264         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
265                                         "smb2_getinfo_file failed");
266
267         status = smb2_session_setup_spnego(tree->session,
268                                            samba_cmdline_get_creds(),
269                                            0 /* previous_session_id */);
270         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
271                                         "smb2_session_setup_spnego failed");
272
273         /* try to access the file via the old handle */
274
275         ZERO_STRUCT(qfinfo);
276         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
277         qfinfo.generic.in.file.handle = _h1;
278         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
279         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
280                                         "smb2_getinfo_file failed");
281
282 done:
283         if (h1 != NULL) {
284                 smb2_util_close(tree, *h1);
285         }
286
287         smb2_util_unlink(tree, fname);
288
289         talloc_free(tree);
290
291         talloc_free(mem_ctx);
292
293         return ret;
294 }
295
296 bool test_session_reauth2(struct torture_context *tctx, struct smb2_tree *tree)
297 {
298         NTSTATUS status;
299         TALLOC_CTX *mem_ctx = talloc_new(tctx);
300         char fname[256];
301         struct smb2_handle _h1;
302         struct smb2_handle *h1 = NULL;
303         struct smb2_create io1;
304         bool ret = true;
305         union smb_fileinfo qfinfo;
306         struct cli_credentials *anon_creds = NULL;
307
308         /* Add some random component to the file name. */
309         snprintf(fname, sizeof(fname), "session_reauth2_%s.dat",
310                  generate_random_str(tctx, 8));
311
312         smb2_util_unlink(tree, fname);
313
314         smb2_oplock_create_share(&io1, fname,
315                                  smb2_util_share_access(""),
316                                  smb2_util_oplock_level("b"));
317
318         status = smb2_create(tree, mem_ctx, &io1);
319         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
320                                         "smb2_create failed");
321         _h1 = io1.out.file.handle;
322         h1 = &_h1;
323         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
324         torture_assert_int_equal(tctx, io1.out.oplock_level,
325                                         smb2_util_oplock_level("b"),
326                                         "oplock_level incorrect");
327
328         /* re-authenticate as anonymous */
329
330         anon_creds = cli_credentials_init_anon(mem_ctx);
331         torture_assert(tctx, (anon_creds != NULL), "talloc error");
332
333         status = smb2_session_setup_spnego(tree->session,
334                                            anon_creds,
335                                            0 /* previous_session_id */);
336         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
337                                         "smb2_session_setup_spnego failed");
338
339         /* try to access the file via the old handle */
340
341         ZERO_STRUCT(qfinfo);
342         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
343         qfinfo.generic.in.file.handle = _h1;
344         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
345         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
346                                         "smb2_getinfo_file failed");
347
348         /* re-authenticate as original user again */
349
350         status = smb2_session_setup_spnego(tree->session,
351                                            samba_cmdline_get_creds(),
352                                            0 /* previous_session_id */);
353         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
354                                         "smb2_session_setup_spnego failed");
355
356         /* try to access the file via the old handle */
357
358         ZERO_STRUCT(qfinfo);
359         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
360         qfinfo.generic.in.file.handle = _h1;
361         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
362         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
363                                         "smb2_getinfo_file failed");
364
365 done:
366         if (h1 != NULL) {
367                 smb2_util_close(tree, *h1);
368         }
369
370         smb2_util_unlink(tree, fname);
371
372         talloc_free(tree);
373
374         talloc_free(mem_ctx);
375
376         return ret;
377 }
378
379 /**
380  * test getting security descriptor after reauth
381  */
382 bool test_session_reauth3(struct torture_context *tctx, struct smb2_tree *tree)
383 {
384         NTSTATUS status;
385         TALLOC_CTX *mem_ctx = talloc_new(tctx);
386         char fname[256];
387         struct smb2_handle _h1;
388         struct smb2_handle *h1 = NULL;
389         struct smb2_create io1;
390         bool ret = true;
391         union smb_fileinfo qfinfo;
392         struct cli_credentials *anon_creds = NULL;
393         uint32_t secinfo_flags = SECINFO_OWNER
394                                 | SECINFO_GROUP
395                                 | SECINFO_DACL
396                                 | SECINFO_PROTECTED_DACL
397                                 | SECINFO_UNPROTECTED_DACL;
398
399         /* Add some random component to the file name. */
400         snprintf(fname, sizeof(fname), "session_reauth3_%s.dat",
401                  generate_random_str(tctx, 8));
402
403         smb2_util_unlink(tree, fname);
404
405         smb2_oplock_create_share(&io1, fname,
406                                  smb2_util_share_access(""),
407                                  smb2_util_oplock_level("b"));
408
409         status = smb2_create(tree, mem_ctx, &io1);
410         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
411                                         "smb2_create failed");
412         _h1 = io1.out.file.handle;
413         h1 = &_h1;
414         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
415         torture_assert_int_equal(tctx, io1.out.oplock_level,
416                                         smb2_util_oplock_level("b"),
417                                         "oplock_level incorrect");
418
419         /* get the security descriptor */
420
421         ZERO_STRUCT(qfinfo);
422
423         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
424         qfinfo.query_secdesc.in.file.handle = _h1;
425         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
426
427         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
428         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
429                                         "smb2_getinfo_file failed");
430
431         /* re-authenticate as anonymous */
432
433         anon_creds = cli_credentials_init_anon(mem_ctx);
434         torture_assert(tctx, (anon_creds != NULL), "talloc error");
435
436         status = smb2_session_setup_spnego(tree->session,
437                                            anon_creds,
438                                            0 /* previous_session_id */);
439         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
440                                         "smb2_session_setup_spnego failed");
441
442         /* try to access the file via the old handle */
443
444         ZERO_STRUCT(qfinfo);
445
446         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
447         qfinfo.query_secdesc.in.file.handle = _h1;
448         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
449
450         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
451         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
452                                         "smb2_getinfo_file failed");
453
454         /* re-authenticate as original user again */
455
456         status = smb2_session_setup_spnego(tree->session,
457                                            samba_cmdline_get_creds(),
458                                            0 /* previous_session_id */);
459         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
460                                         "smb2_session_setup_spnego failed");
461
462         /* try to access the file via the old handle */
463
464         ZERO_STRUCT(qfinfo);
465
466         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
467         qfinfo.query_secdesc.in.file.handle = _h1;
468         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
469
470         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
471         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
472                                         "smb2_getinfo_file failed");
473
474 done:
475         if (h1 != NULL) {
476                 smb2_util_close(tree, *h1);
477         }
478
479         smb2_util_unlink(tree, fname);
480
481         talloc_free(tree);
482
483         talloc_free(mem_ctx);
484
485         return ret;
486 }
487
488 /**
489  * test setting security descriptor after reauth.
490  */
491 bool test_session_reauth4(struct torture_context *tctx, struct smb2_tree *tree)
492 {
493         NTSTATUS status;
494         TALLOC_CTX *mem_ctx = talloc_new(tctx);
495         char fname[256];
496         struct smb2_handle _h1;
497         struct smb2_handle *h1 = NULL;
498         struct smb2_create io1;
499         bool ret = true;
500         union smb_fileinfo qfinfo;
501         union smb_setfileinfo sfinfo;
502         struct cli_credentials *anon_creds = NULL;
503         uint32_t secinfo_flags = SECINFO_OWNER
504                                 | SECINFO_GROUP
505                                 | SECINFO_DACL
506                                 | SECINFO_PROTECTED_DACL
507                                 | SECINFO_UNPROTECTED_DACL;
508         struct security_descriptor *sd1;
509         struct security_ace ace;
510         struct dom_sid *extra_sid;
511
512         /* Add some random component to the file name. */
513         snprintf(fname, sizeof(fname), "session_reauth4_%s.dat",
514                  generate_random_str(tctx, 8));
515
516         smb2_util_unlink(tree, fname);
517
518         smb2_oplock_create_share(&io1, fname,
519                                  smb2_util_share_access(""),
520                                  smb2_util_oplock_level("b"));
521
522         status = smb2_create(tree, mem_ctx, &io1);
523         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
524                                         "smb2_create failed");
525         _h1 = io1.out.file.handle;
526         h1 = &_h1;
527         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
528         torture_assert_int_equal(tctx, io1.out.oplock_level,
529                                         smb2_util_oplock_level("b"),
530                                         "oplock_level incorrect");
531
532         /* get the security descriptor */
533
534         ZERO_STRUCT(qfinfo);
535
536         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
537         qfinfo.query_secdesc.in.file.handle = _h1;
538         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
539
540         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
541         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
542                                         "smb2_getinfo_file failed");
543
544         sd1 = qfinfo.query_secdesc.out.sd;
545
546         /* re-authenticate as anonymous */
547
548         anon_creds = cli_credentials_init_anon(mem_ctx);
549         torture_assert(tctx, (anon_creds != NULL), "talloc error");
550
551         status = smb2_session_setup_spnego(tree->session,
552                                            anon_creds,
553                                            0 /* previous_session_id */);
554         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
555                                         "smb2_session_setup_spnego failed");
556
557         /* give full access on the file to anonymous */
558
559         extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
560
561         ZERO_STRUCT(ace);
562         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
563         ace.flags = 0;
564         ace.access_mask = SEC_STD_ALL | SEC_FILE_ALL;
565         ace.trustee = *extra_sid;
566
567         status = security_descriptor_dacl_add(sd1, &ace);
568         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
569                                         "security_descriptor_dacl_add failed");
570
571         ZERO_STRUCT(sfinfo);
572         sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
573         sfinfo.set_secdesc.in.file.handle = _h1;
574         sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
575         sfinfo.set_secdesc.in.sd = sd1;
576
577         status = smb2_setinfo_file(tree, &sfinfo);
578         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
579                                         "smb2_setinfo_file failed");
580
581         /* re-authenticate as original user again */
582
583         status = smb2_session_setup_spnego(tree->session,
584                                            samba_cmdline_get_creds(),
585                                            0 /* previous_session_id */);
586         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
587                                         "smb2_session_setup_spnego failed");
588
589         /* re-get the security descriptor */
590
591         ZERO_STRUCT(qfinfo);
592
593         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
594         qfinfo.query_secdesc.in.file.handle = _h1;
595         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
596
597         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
598         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
599                                         "smb2_getinfo_file failed");
600
601         ret = true;
602
603 done:
604         if (h1 != NULL) {
605                 smb2_util_close(tree, *h1);
606         }
607
608         smb2_util_unlink(tree, fname);
609
610         talloc_free(tree);
611
612         talloc_free(mem_ctx);
613
614         return ret;
615 }
616
617 /**
618  * test renaming after reauth.
619  * compare security descriptors before and after rename/reauth
620  */
621 bool test_session_reauth5(struct torture_context *tctx, struct smb2_tree *tree)
622 {
623         NTSTATUS status;
624         TALLOC_CTX *mem_ctx = talloc_new(tctx);
625         char dname[128];
626         char fname[256];
627         char fname2[256];
628         struct smb2_handle _dh1;
629         struct smb2_handle *dh1 = NULL;
630         struct smb2_handle _h1;
631         struct smb2_handle *h1 = NULL;
632         struct smb2_create io1;
633         bool ret = true;
634         bool ok;
635         union smb_fileinfo qfinfo;
636         union smb_setfileinfo sfinfo;
637         struct cli_credentials *anon_creds = NULL;
638         uint32_t secinfo_flags = SECINFO_OWNER
639                                 | SECINFO_GROUP
640                                 | SECINFO_DACL
641                                 | SECINFO_PROTECTED_DACL
642                                 | SECINFO_UNPROTECTED_DACL;
643         struct security_descriptor *f_sd1;
644         struct security_descriptor *d_sd1 = NULL;
645         struct security_ace ace;
646         struct dom_sid *extra_sid;
647
648         /* Add some random component to the file name. */
649         snprintf(dname, sizeof(dname), "session_reauth5_%s.d",
650                  generate_random_str(tctx, 8));
651         snprintf(fname, sizeof(fname), "%s\\file.dat", dname);
652
653         ok = smb2_util_setup_dir(tctx, tree, dname);
654         torture_assert(tctx, ok, "smb2_util_setup_dir not ok");
655
656         status = torture_smb2_testdir(tree, dname, &_dh1);
657         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
658                                         "torture_smb2_testdir failed");
659         dh1 = &_dh1;
660
661         smb2_oplock_create_share(&io1, fname,
662                                  smb2_util_share_access(""),
663                                  smb2_util_oplock_level("b"));
664
665         status = smb2_create(tree, mem_ctx, &io1);
666         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
667                                         "smb2_create failed");
668         _h1 = io1.out.file.handle;
669         h1 = &_h1;
670         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
671         torture_assert_int_equal(tctx, io1.out.oplock_level,
672                                         smb2_util_oplock_level("b"),
673                                         "oplock_level incorrect");
674
675         /* get the security descriptor */
676
677         ZERO_STRUCT(qfinfo);
678
679         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
680         qfinfo.query_secdesc.in.file.handle = _h1;
681         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
682
683         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
684         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
685                                         "smb2_getinfo_file failed");
686
687         f_sd1 = qfinfo.query_secdesc.out.sd;
688
689         /* re-authenticate as anonymous */
690
691         anon_creds = cli_credentials_init_anon(mem_ctx);
692         torture_assert(tctx, (anon_creds != NULL), "talloc error");
693
694         status = smb2_session_setup_spnego(tree->session,
695                                            anon_creds,
696                                            0 /* previous_session_id */);
697         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
698                                         "smb2_session_setup_spnego failed");
699
700         /* try to rename the file: fails */
701
702         snprintf(fname2, sizeof(fname2), "%s\\file2.dat", dname);
703
704         status = smb2_util_unlink(tree, fname2);
705         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
706                                         "smb2_util_unlink failed");
707
708
709         ZERO_STRUCT(sfinfo);
710         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
711         sfinfo.rename_information.in.file.handle = _h1;
712         sfinfo.rename_information.in.overwrite = true;
713         sfinfo.rename_information.in.new_name = fname2;
714
715         status = smb2_setinfo_file(tree, &sfinfo);
716         torture_assert_ntstatus_equal_goto(tctx, status,
717                                            NT_STATUS_ACCESS_DENIED,
718                                            ret, done, "smb2_setinfo_file "
719                                            "returned unexpected status");
720
721         /* re-authenticate as original user again */
722
723         status = smb2_session_setup_spnego(tree->session,
724                                            samba_cmdline_get_creds(),
725                                            0 /* previous_session_id */);
726         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
727                                         "smb2_session_setup_spnego failed");
728
729         /* give full access on the file to anonymous */
730
731         extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS);
732
733         ZERO_STRUCT(ace);
734         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
735         ace.flags = 0;
736         ace.access_mask = SEC_RIGHTS_FILE_ALL;
737         ace.trustee = *extra_sid;
738
739         status = security_descriptor_dacl_add(f_sd1, &ace);
740         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
741                                         "security_descriptor_dacl_add failed");
742
743         ZERO_STRUCT(sfinfo);
744         sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
745         sfinfo.set_secdesc.in.file.handle = _h1;
746         sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
747         sfinfo.set_secdesc.in.sd = f_sd1;
748
749         status = smb2_setinfo_file(tree, &sfinfo);
750         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
751                                         "smb2_setinfo_file failed");
752
753         /* re-get the security descriptor */
754
755         ZERO_STRUCT(qfinfo);
756
757         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
758         qfinfo.query_secdesc.in.file.handle = _h1;
759         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
760
761         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
762         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
763                                         "smb2_getinfo_file failed");
764
765         /* re-authenticate as anonymous - again */
766
767         anon_creds = cli_credentials_init_anon(mem_ctx);
768         torture_assert(tctx, (anon_creds != NULL), "talloc error");
769
770         status = smb2_session_setup_spnego(tree->session,
771                                            anon_creds,
772                                            0 /* previous_session_id */);
773         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
774                                         "smb2_session_setup_spnego failed");
775
776         /* try to rename the file: fails */
777
778         ZERO_STRUCT(sfinfo);
779         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
780         sfinfo.rename_information.in.file.handle = _h1;
781         sfinfo.rename_information.in.overwrite = true;
782         sfinfo.rename_information.in.new_name = fname2;
783
784         status = smb2_setinfo_file(tree, &sfinfo);
785         torture_assert_ntstatus_equal_goto(tctx, status,
786                                            NT_STATUS_ACCESS_DENIED,
787                                            ret, done, "smb2_setinfo_file "
788                                            "returned unexpected status");
789
790         /* give full access on the parent dir to anonymous */
791
792         ZERO_STRUCT(qfinfo);
793
794         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
795         qfinfo.query_secdesc.in.file.handle = _dh1;
796         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
797
798         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
799         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
800                                         "smb2_getinfo_file failed");
801
802         d_sd1 = qfinfo.query_secdesc.out.sd;
803
804         ZERO_STRUCT(ace);
805         ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
806         ace.flags = 0;
807         ace.access_mask = SEC_RIGHTS_FILE_ALL;
808         ace.trustee = *extra_sid;
809
810         status = security_descriptor_dacl_add(d_sd1, &ace);
811         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
812                                         "security_descriptor_dacl_add failed");
813
814         ZERO_STRUCT(sfinfo);
815         sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
816         sfinfo.set_secdesc.in.file.handle = _dh1;
817         sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags;
818         sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL;
819         sfinfo.set_secdesc.in.sd = d_sd1;
820
821         status = smb2_setinfo_file(tree, &sfinfo);
822         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
823                                         "smb2_setinfo_file failed");
824
825         ZERO_STRUCT(qfinfo);
826
827         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
828         qfinfo.query_secdesc.in.file.handle = _dh1;
829         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
830
831         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
832         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
833                                         "smb2_getinfo_file failed");
834
835         status = smb2_util_close(tree, _dh1);
836         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
837                                         "smb2_util_close failed");
838         dh1 = NULL;
839
840         /* try to rename the file: still fails */
841
842         ZERO_STRUCT(sfinfo);
843         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
844         sfinfo.rename_information.in.file.handle = _h1;
845         sfinfo.rename_information.in.overwrite = true;
846         sfinfo.rename_information.in.new_name = fname2;
847
848         status = smb2_setinfo_file(tree, &sfinfo);
849         torture_assert_ntstatus_equal_goto(tctx, status,
850                                         NT_STATUS_ACCESS_DENIED,
851                                         ret, done, "smb2_setinfo_file "
852                                         "returned unexpected status");
853
854         /* re-authenticate as original user - again */
855
856         status = smb2_session_setup_spnego(tree->session,
857                                            samba_cmdline_get_creds(),
858                                            0 /* previous_session_id */);
859         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
860                                         "smb2_session_setup_spnego failed");
861
862         /* rename the file - for verification that it works */
863
864         ZERO_STRUCT(sfinfo);
865         sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
866         sfinfo.rename_information.in.file.handle = _h1;
867         sfinfo.rename_information.in.overwrite = true;
868         sfinfo.rename_information.in.new_name = fname2;
869
870         status = smb2_setinfo_file(tree, &sfinfo);
871         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
872                                         "smb2_setinfo_file failed");
873
874         /* closs the file, check it is gone and reopen under the new name */
875
876         status = smb2_util_close(tree, _h1);
877         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
878                                         "smb2_util_close failed");
879         ZERO_STRUCT(io1);
880
881         smb2_generic_create_share(&io1,
882                                   NULL /* lease */, false /* dir */,
883                                   fname,
884                                   NTCREATEX_DISP_OPEN,
885                                   smb2_util_share_access(""),
886                                   smb2_util_oplock_level("b"),
887                                   0 /* leasekey */, 0 /* leasestate */);
888
889         status = smb2_create(tree, mem_ctx, &io1);
890         torture_assert_ntstatus_equal_goto(tctx, status,
891                                         NT_STATUS_OBJECT_NAME_NOT_FOUND,
892                                         ret, done, "smb2_create "
893                                         "returned unexpected status");
894
895         ZERO_STRUCT(io1);
896
897         smb2_generic_create_share(&io1,
898                                   NULL /* lease */, false /* dir */,
899                                   fname2,
900                                   NTCREATEX_DISP_OPEN,
901                                   smb2_util_share_access(""),
902                                   smb2_util_oplock_level("b"),
903                                   0 /* leasekey */, 0 /* leasestate */);
904
905         status = smb2_create(tree, mem_ctx, &io1);
906         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
907                                         "smb2_create failed");
908         _h1 = io1.out.file.handle;
909         h1 = &_h1;
910         CHECK_CREATED(tctx, &io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
911         torture_assert_int_equal(tctx, io1.out.oplock_level,
912                                         smb2_util_oplock_level("b"),
913                                         "oplock_level incorrect");
914
915         /* try to access the file via the old handle */
916
917         ZERO_STRUCT(qfinfo);
918
919         qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
920         qfinfo.query_secdesc.in.file.handle = _h1;
921         qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags;
922
923         status = smb2_getinfo_file(tree, mem_ctx, &qfinfo);
924         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
925                                         "smb2_getinfo_file failed");
926
927 done:
928         if (dh1 != NULL) {
929                 smb2_util_close(tree, *dh1);
930         }
931         if (h1 != NULL) {
932                 smb2_util_close(tree, *h1);
933         }
934
935         smb2_deltree(tree, dname);
936
937         talloc_free(tree);
938
939         talloc_free(mem_ctx);
940
941         return ret;
942 }
943
944 /**
945  * do reauth with wrong credentials,
946  * hence triggering the error path in reauth.
947  * The invalid reauth deletes the session.
948  */
949 bool test_session_reauth6(struct torture_context *tctx, struct smb2_tree *tree)
950 {
951         NTSTATUS status;
952         TALLOC_CTX *mem_ctx = talloc_new(tctx);
953         char fname[256];
954         struct smb2_handle _h1;
955         struct smb2_handle *h1 = NULL;
956         struct smb2_create io1;
957         bool ret = true;
958         char *corrupted_password;
959         struct cli_credentials *broken_creds;
960         bool ok;
961         bool encrypted;
962         NTSTATUS expected;
963         enum credentials_use_kerberos krb_state;
964
965         krb_state = cli_credentials_get_kerberos_state(
966                         samba_cmdline_get_creds());
967         if (krb_state == CRED_USE_KERBEROS_REQUIRED) {
968                 torture_skip(tctx,
969                              "Can't test failing session setup with kerberos.");
970         }
971
972         encrypted = smb2cli_tcon_is_encryption_on(tree->smbXcli);
973
974         /* Add some random component to the file name. */
975         snprintf(fname, sizeof(fname), "session_reauth1_%s.dat",
976                  generate_random_str(tctx, 8));
977
978         smb2_util_unlink(tree, fname);
979
980         smb2_oplock_create_share(&io1, fname,
981                                  smb2_util_share_access(""),
982                                  smb2_util_oplock_level("b"));
983         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
984
985         status = smb2_create(tree, mem_ctx, &io1);
986         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
987                                         "smb2_create failed");
988         _h1 = io1.out.file.handle;
989         h1 = &_h1;
990         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
991         torture_assert_int_equal(tctx, io1.out.oplock_level,
992                                         smb2_util_oplock_level("b"),
993                                         "oplock_level incorrect");
994
995         /*
996          * reauthentication with invalid credentials:
997          */
998
999         broken_creds = cli_credentials_shallow_copy(mem_ctx,
1000                                             samba_cmdline_get_creds());
1001         torture_assert(tctx, (broken_creds != NULL), "talloc error");
1002
1003         corrupted_password = talloc_asprintf(mem_ctx, "%s%s",
1004                                 cli_credentials_get_password(broken_creds),
1005                                 "corrupt");
1006         torture_assert(tctx, (corrupted_password != NULL), "talloc error");
1007
1008         ok = cli_credentials_set_password(broken_creds, corrupted_password,
1009                                           CRED_SPECIFIED);
1010         torture_assert(tctx, ok, "cli_credentials_set_password not ok");
1011
1012         status = smb2_session_setup_spnego(tree->session,
1013                                            broken_creds,
1014                                            0 /* previous_session_id */);
1015         torture_assert_ntstatus_equal_goto(tctx, status,
1016                                         NT_STATUS_LOGON_FAILURE, ret, done,
1017                                         "smb2_session_setup_spnego "
1018                                         "returned unexpected status");
1019
1020         torture_comment(tctx, "did failed reauth\n");
1021         /*
1022          * now verify that the invalid session reauth has closed our session
1023          */
1024
1025         if (encrypted) {
1026                 expected = NT_STATUS_CONNECTION_DISCONNECTED;
1027         } else {
1028                 expected = NT_STATUS_USER_SESSION_DELETED;
1029         }
1030
1031         smb2_oplock_create_share(&io1, fname,
1032                                  smb2_util_share_access(""),
1033                                  smb2_util_oplock_level("b"));
1034
1035         status = smb2_create(tree, mem_ctx, &io1);
1036         torture_assert_ntstatus_equal_goto(tctx, status, expected,
1037                                         ret, done, "smb2_create "
1038                                         "returned unexpected status");
1039
1040 done:
1041         if (h1 != NULL) {
1042                 smb2_util_close(tree, *h1);
1043         }
1044
1045         smb2_util_unlink(tree, fname);
1046
1047         talloc_free(tree);
1048
1049         talloc_free(mem_ctx);
1050
1051         return ret;
1052 }
1053
1054
1055 static bool test_session_expire1i(struct torture_context *tctx,
1056                                   bool force_signing,
1057                                   bool force_encryption)
1058 {
1059         NTSTATUS status;
1060         bool ret = false;
1061         struct smbcli_options options;
1062         const char *host = torture_setting_string(tctx, "host", NULL);
1063         const char *share = torture_setting_string(tctx, "share", NULL);
1064         struct cli_credentials *credentials = samba_cmdline_get_creds();
1065         struct smb2_tree *tree = NULL;
1066         enum credentials_use_kerberos use_kerberos;
1067         char fname[256];
1068         struct smb2_handle _h1;
1069         struct smb2_handle *h1 = NULL;
1070         struct smb2_create io1;
1071         union smb_fileinfo qfinfo;
1072         size_t i;
1073
1074         use_kerberos = cli_credentials_get_kerberos_state(credentials);
1075         if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
1076                 torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
1077                 torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
1078         }
1079
1080         torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED,
1081                                  "please use -k yes");
1082
1083         cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1084
1085         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
1086
1087         lpcfg_smbcli_options(tctx->lp_ctx, &options);
1088         if (force_signing) {
1089                 options.signing = SMB_SIGNING_REQUIRED;
1090         }
1091
1092         status = smb2_connect(tctx,
1093                               host,
1094                               lpcfg_smb_ports(tctx->lp_ctx),
1095                               share,
1096                               lpcfg_resolve_context(tctx->lp_ctx),
1097                               credentials,
1098                               &tree,
1099                               tctx->ev,
1100                               &options,
1101                               lpcfg_socket_options(tctx->lp_ctx),
1102                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1103                               );
1104         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1105                                         "smb2_connect failed");
1106
1107         if (force_encryption) {
1108                 status = smb2cli_session_encryption_on(tree->session->smbXcli);
1109                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1110                                         "smb2cli_session_encryption_on failed");
1111         }
1112
1113         /* Add some random component to the file name. */
1114         snprintf(fname, sizeof(fname), "session_expire1_%s.dat",
1115                  generate_random_str(tctx, 8));
1116
1117         smb2_util_unlink(tree, fname);
1118
1119         smb2_oplock_create_share(&io1, fname,
1120                                  smb2_util_share_access(""),
1121                                  smb2_util_oplock_level("b"));
1122         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1123
1124         status = smb2_create(tree, tctx, &io1);
1125         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1126                                         "smb2_create failed");
1127         _h1 = io1.out.file.handle;
1128         h1 = &_h1;
1129         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1130         torture_assert_int_equal(tctx, io1.out.oplock_level,
1131                                         smb2_util_oplock_level("b"),
1132                                         "oplock_level incorrect");
1133
1134         /* get the security descriptor */
1135
1136         ZERO_STRUCT(qfinfo);
1137
1138         qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
1139         qfinfo.access_information.in.file.handle = _h1;
1140
1141         for (i=0; i < 2; i++) {
1142                 torture_comment(tctx, "query info => OK\n");
1143
1144                 ZERO_STRUCT(qfinfo.access_information.out);
1145                 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1146                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1147                                                 "smb2_getinfo_file failed");
1148
1149                 torture_comment(tctx, "sleep 10 seconds\n");
1150                 smb_msleep(10*1000);
1151
1152                 torture_comment(tctx, "query info => EXPIRED\n");
1153                 ZERO_STRUCT(qfinfo.access_information.out);
1154                 status = smb2_getinfo_file(tree, tctx, &qfinfo);
1155                 torture_assert_ntstatus_equal_goto(tctx, status,
1156                                         NT_STATUS_NETWORK_SESSION_EXPIRED,
1157                                         ret, done, "smb2_getinfo_file "
1158                                         "returned unexpected status");
1159
1160                 /*
1161                  * the krb5 library may not handle expired creds
1162                  * well, lets start with an empty ccache.
1163                  */
1164                 cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1165
1166                 if (!force_encryption) {
1167                         smb2cli_session_require_signed_response(
1168                                 tree->session->smbXcli, true);
1169                 }
1170
1171                 torture_comment(tctx, "reauth => OK\n");
1172                 status = smb2_session_setup_spnego(tree->session,
1173                                                    credentials,
1174                                                    0 /* previous_session_id */);
1175                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1176                                         "smb2_session_setup_spnego failed");
1177
1178                 smb2cli_session_require_signed_response(
1179                         tree->session->smbXcli, false);
1180         }
1181
1182         ZERO_STRUCT(qfinfo.access_information.out);
1183         status = smb2_getinfo_file(tree, tctx, &qfinfo);
1184         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1185                                         "smb2_getinfo_file failed");
1186
1187         ret = true;
1188 done:
1189         cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1190
1191         if (h1 != NULL) {
1192                 smb2_util_close(tree, *h1);
1193         }
1194
1195         talloc_free(tree);
1196         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
1197         return ret;
1198 }
1199
1200 static bool test_session_expire1n(struct torture_context *tctx)
1201 {
1202         return test_session_expire1i(tctx,
1203                                      false,   /* force_signing */
1204                                      false); /* force_encryption */
1205 }
1206
1207 static bool test_session_expire1s(struct torture_context *tctx)
1208 {
1209         return test_session_expire1i(tctx,
1210                                      true,   /* force_signing */
1211                                      false); /* force_encryption */
1212 }
1213
1214 static bool test_session_expire1e(struct torture_context *tctx)
1215 {
1216         return test_session_expire1i(tctx,
1217                                      true,   /* force_signing */
1218                                      true); /* force_encryption */
1219 }
1220
1221 static bool test_session_expire2i(struct torture_context *tctx,
1222                                   bool force_encryption)
1223 {
1224         NTSTATUS status;
1225         bool ret = false;
1226         struct smbcli_options options;
1227         const char *host = torture_setting_string(tctx, "host", NULL);
1228         const char *share = torture_setting_string(tctx, "share", NULL);
1229         struct cli_credentials *credentials = samba_cmdline_get_creds();
1230         struct smb2_tree *tree = NULL;
1231         const char *unc = NULL;
1232         struct smb2_tree *tree2 = NULL;
1233         struct tevent_req *subreq = NULL;
1234         uint32_t timeout_msec;
1235         enum credentials_use_kerberos use_kerberos;
1236         uint32_t caps;
1237         char fname[256];
1238         struct smb2_handle dh;
1239         struct smb2_handle dh2;
1240         struct smb2_handle _h1;
1241         struct smb2_handle *h1 = NULL;
1242         struct smb2_create io1;
1243         union smb_fileinfo qfinfo;
1244         union smb_setfileinfo sfinfo;
1245         struct smb2_flush flsh;
1246         struct smb2_read rd;
1247         const uint8_t wd = 0;
1248         struct smb2_lock lck;
1249         struct smb2_lock_element el;
1250         struct smb2_ioctl ctl;
1251         struct smb2_break oack;
1252         struct smb2_lease_break_ack lack;
1253         struct smb2_find fnd;
1254         union smb_search_data *d = NULL;
1255         unsigned int count;
1256         struct smb2_request *req = NULL;
1257         struct smb2_notify ntf1;
1258         struct smb2_notify ntf2;
1259
1260         use_kerberos = cli_credentials_get_kerberos_state(credentials);
1261         if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
1262                 torture_warning(tctx, "smb2.session.expire2 requires -k yes!");
1263                 torture_skip(tctx, "smb2.session.expire2 requires -k yes!");
1264         }
1265
1266         torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED,
1267                                  "please use -k yes");
1268
1269         cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1270
1271         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
1272
1273         lpcfg_smbcli_options(tctx->lp_ctx, &options);
1274         options.signing = SMB_SIGNING_REQUIRED;
1275
1276         unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
1277         torture_assert(tctx, unc != NULL, "talloc_asprintf");
1278
1279         status = smb2_connect(tctx,
1280                               host,
1281                               lpcfg_smb_ports(tctx->lp_ctx),
1282                               share,
1283                               lpcfg_resolve_context(tctx->lp_ctx),
1284                               credentials,
1285                               &tree,
1286                               tctx->ev,
1287                               &options,
1288                               lpcfg_socket_options(tctx->lp_ctx),
1289                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1290                               );
1291         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1292                                         "smb2_connect failed");
1293
1294         if (force_encryption) {
1295                 status = smb2cli_session_encryption_on(tree->session->smbXcli);
1296                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1297                                         "smb2cli_session_encryption_on failed");
1298         }
1299
1300         caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
1301
1302         /* Add some random component to the file name. */
1303         snprintf(fname, sizeof(fname), "session_expire2_%s.dat",
1304                  generate_random_str(tctx, 8));
1305
1306         smb2_util_unlink(tree, fname);
1307
1308         status = smb2_util_roothandle(tree, &dh);
1309         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1310                                         "smb2_util_roothandle failed");
1311
1312         smb2_oplock_create_share(&io1, fname,
1313                                  smb2_util_share_access(""),
1314                                  smb2_util_oplock_level("b"));
1315         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1316
1317         status = smb2_create(tree, tctx, &io1);
1318         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1319                                         "smb2_create failed");
1320         _h1 = io1.out.file.handle;
1321         h1 = &_h1;
1322         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1323         torture_assert_int_equal(tctx, io1.out.oplock_level,
1324                                         smb2_util_oplock_level("b"),
1325                                         "oplock_level incorrect");
1326
1327         /* get the security descriptor */
1328
1329         ZERO_STRUCT(qfinfo);
1330
1331         qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
1332         qfinfo.access_information.in.file.handle = _h1;
1333
1334         torture_comment(tctx, "query info => OK\n");
1335
1336         ZERO_STRUCT(qfinfo.access_information.out);
1337         status = smb2_getinfo_file(tree, tctx, &qfinfo);
1338         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1339                                         "smb2_getinfo_file failed");
1340
1341         torture_comment(tctx, "lock => OK\n");
1342         ZERO_STRUCT(lck);
1343         lck.in.locks            = &el;
1344         lck.in.lock_count       = 0x0001;
1345         lck.in.lock_sequence    = 0x00000000;
1346         lck.in.file.handle      = *h1;
1347         ZERO_STRUCT(el);
1348         el.flags                = SMB2_LOCK_FLAG_EXCLUSIVE |
1349                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1350         el.offset               = 0x0000000000000000;
1351         el.length               = 0x0000000000000001;
1352         status = smb2_lock(tree, &lck);
1353         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1354                                         "smb2_lock lock failed");
1355
1356         torture_comment(tctx, "1st notify => PENDING\n");
1357         ZERO_STRUCT(ntf1);
1358         ntf1.in.file.handle     = dh;
1359         ntf1.in.recursive       = 0x0000;
1360         ntf1.in.buffer_size     = 128;
1361         ntf1.in.completion_filter= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1362         ntf1.in.unknown         = 0x00000000;
1363         req = smb2_notify_send(tree, &ntf1);
1364
1365         while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) {
1366                 if (tevent_loop_once(tctx->ev) != 0) {
1367                         break;
1368                 }
1369         }
1370
1371         torture_assert_goto(tctx, req->state <= SMB2_REQUEST_RECV, ret, done,
1372                             "smb2_notify finished");
1373
1374         torture_comment(tctx, "sleep 10 seconds\n");
1375         smb_msleep(10*1000);
1376
1377         torture_comment(tctx, "query info => EXPIRED\n");
1378         ZERO_STRUCT(qfinfo.access_information.out);
1379         status = smb2_getinfo_file(tree, tctx, &qfinfo);
1380         torture_assert_ntstatus_equal_goto(tctx, status,
1381                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1382                                 ret, done, "smb2_getinfo_file "
1383                                 "returned unexpected status");
1384
1385
1386         torture_comment(tctx, "set info => EXPIRED\n");
1387         ZERO_STRUCT(sfinfo);
1388         sfinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION;
1389         sfinfo.end_of_file_info.in.file.handle = *h1;
1390         sfinfo.end_of_file_info.in.size = 1;
1391         status = smb2_setinfo_file(tree, &sfinfo);
1392         torture_assert_ntstatus_equal_goto(tctx, status,
1393                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1394                                 ret, done, "smb2_setinfo_file "
1395                                 "returned unexpected status");
1396
1397         torture_comment(tctx, "flush => EXPIRED\n");
1398         ZERO_STRUCT(flsh);
1399         flsh.in.file.handle = *h1;
1400         status = smb2_flush(tree, &flsh);
1401         torture_assert_ntstatus_equal_goto(tctx, status,
1402                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1403                                 ret, done, "smb2_flush "
1404                                 "returned unexpected status");
1405
1406         torture_comment(tctx, "read => EXPIRED\n");
1407         ZERO_STRUCT(rd);
1408         rd.in.file.handle = *h1;
1409         rd.in.length      = 5;
1410         rd.in.offset      = 0;
1411         status = smb2_read(tree, tctx, &rd);
1412         torture_assert_ntstatus_equal_goto(tctx, status,
1413                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1414                                 ret, done, "smb2_read "
1415                                 "returned unexpected status");
1416
1417         torture_comment(tctx, "write => EXPIRED\n");
1418         status = smb2_util_write(tree, *h1, &wd, 0, 1);
1419         torture_assert_ntstatus_equal_goto(tctx, status,
1420                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1421                                 ret, done, "smb2_util_write "
1422                                 "returned unexpected status");
1423
1424         torture_comment(tctx, "ioctl => EXPIRED\n");
1425         ZERO_STRUCT(ctl);
1426         ctl.in.file.handle = *h1;
1427         ctl.in.function = FSCTL_SRV_ENUM_SNAPS;
1428         ctl.in.max_output_response = 16;
1429         ctl.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
1430         status = smb2_ioctl(tree, tctx, &ctl);
1431         torture_assert_ntstatus_equal_goto(tctx, status,
1432                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1433                                 ret, done, "smb2_ioctl "
1434                                 "returned unexpected status");
1435
1436         torture_comment(tctx, "oplock ack => EXPIRED\n");
1437         ZERO_STRUCT(oack);
1438         oack.in.file.handle = *h1;
1439         status = smb2_break(tree, &oack);
1440         torture_assert_ntstatus_equal_goto(tctx, status,
1441                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1442                                 ret, done, "smb2_break "
1443                                 "returned unexpected status");
1444
1445         if (caps & SMB2_CAP_LEASING) {
1446                 torture_comment(tctx, "lease ack => EXPIRED\n");
1447                 ZERO_STRUCT(lack);
1448                 lack.in.lease.lease_version = 1;
1449                 lack.in.lease.lease_key.data[0] = 1;
1450                 lack.in.lease.lease_key.data[1] = 2;
1451                 status = smb2_lease_break_ack(tree, &lack);
1452                 torture_assert_ntstatus_equal_goto(tctx, status,
1453                                         NT_STATUS_NETWORK_SESSION_EXPIRED,
1454                                         ret, done, "smb2_break "
1455                                         "returned unexpected status");
1456         }
1457
1458         torture_comment(tctx, "query directory => EXPIRED\n");
1459         ZERO_STRUCT(fnd);
1460         fnd.in.file.handle      = dh;
1461         fnd.in.pattern          = "*";
1462         fnd.in.continue_flags   = SMB2_CONTINUE_FLAG_SINGLE;
1463         fnd.in.max_response_size= 0x100;
1464         fnd.in.level            = SMB2_FIND_BOTH_DIRECTORY_INFO;
1465         status = smb2_find_level(tree, tree, &fnd, &count, &d);
1466         torture_assert_ntstatus_equal_goto(tctx, status,
1467                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1468                                 ret, done, "smb2_find_level "
1469                                 "returned unexpected status");
1470
1471         torture_comment(tctx, "1st notify => CANCEL\n");
1472         smb2_cancel(req);
1473
1474         torture_comment(tctx, "2nd notify => EXPIRED\n");
1475         ZERO_STRUCT(ntf2);
1476         ntf2.in.file.handle     = dh;
1477         ntf2.in.recursive       = 0x0000;
1478         ntf2.in.buffer_size     = 128;
1479         ntf2.in.completion_filter= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1480         ntf2.in.unknown         = 0x00000000;
1481         status = smb2_notify(tree, tctx, &ntf2);
1482         torture_assert_ntstatus_equal_goto(tctx, status,
1483                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1484                                 ret, done, "smb2_notify "
1485                                 "returned unexpected status");
1486
1487         torture_assert_goto(tctx, req->state > SMB2_REQUEST_RECV, ret, done,
1488                             "smb2_notify (1st) not finished");
1489
1490         status = smb2_notify_recv(req, tctx, &ntf1);
1491         torture_assert_ntstatus_equal_goto(tctx, status,
1492                                 NT_STATUS_CANCELLED,
1493                                 ret, done, "smb2_notify cancelled"
1494                                 "returned unexpected status");
1495
1496         torture_comment(tctx, "tcon => EXPIRED\n");
1497         tree2 = smb2_tree_init(tree->session, tctx, false);
1498         torture_assert(tctx, tree2 != NULL, "smb2_tree_init");
1499         timeout_msec = tree->session->transport->options.request_timeout * 1000;
1500         subreq = smb2cli_tcon_send(tree2, tctx->ev,
1501                                    tree2->session->transport->conn,
1502                                    timeout_msec,
1503                                    tree2->session->smbXcli,
1504                                    tree2->smbXcli,
1505                                    0, /* flags */
1506                                    unc);
1507         torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send");
1508         torture_assert(tctx,
1509                        tevent_req_poll_ntstatus(subreq, tctx->ev, &status),
1510                        "tevent_req_poll_ntstatus");
1511         status = smb2cli_tcon_recv(subreq);
1512         TALLOC_FREE(subreq);
1513         torture_assert_ntstatus_equal_goto(tctx, status,
1514                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1515                                 ret, done, "smb2cli_tcon"
1516                                 "returned unexpected status");
1517
1518         torture_comment(tctx, "create => EXPIRED\n");
1519         status = smb2_util_roothandle(tree, &dh2);
1520         torture_assert_ntstatus_equal_goto(tctx, status,
1521                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1522                                 ret, done, "smb2_util_roothandle"
1523                                 "returned unexpected status");
1524
1525         torture_comment(tctx, "tdis => EXPIRED\n");
1526         status = smb2_tdis(tree);
1527         torture_assert_ntstatus_equal_goto(tctx, status,
1528                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1529                                 ret, done, "smb2cli_tdis"
1530                                 "returned unexpected status");
1531
1532         /*
1533          * (Un)Lock, Close and Logoff are still possible
1534          */
1535
1536         torture_comment(tctx, "1st unlock => OK\n");
1537         el.flags                = SMB2_LOCK_FLAG_UNLOCK;
1538         status = smb2_lock(tree, &lck);
1539         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1540                                         "smb2_lock unlock failed");
1541
1542         torture_comment(tctx, "2nd unlock => RANGE_NOT_LOCKED\n");
1543         status = smb2_lock(tree, &lck);
1544         torture_assert_ntstatus_equal_goto(tctx, status,
1545                                 NT_STATUS_RANGE_NOT_LOCKED,
1546                                 ret, done, "smb2_lock 2nd unlock"
1547                                 "returned unexpected status");
1548
1549         torture_comment(tctx, "lock => EXPIRED\n");
1550         el.flags                = SMB2_LOCK_FLAG_EXCLUSIVE |
1551                                   SMB2_LOCK_FLAG_FAIL_IMMEDIATELY;
1552         status = smb2_lock(tree, &lck);
1553         torture_assert_ntstatus_equal_goto(tctx, status,
1554                                 NT_STATUS_NETWORK_SESSION_EXPIRED,
1555                                 ret, done, "smb2_util_roothandle"
1556                                 "returned unexpected status");
1557
1558         torture_comment(tctx, "close => OK\n");
1559         status = smb2_util_close(tree, *h1);
1560         h1 = NULL;
1561         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1562                                         "smb2_close failed");
1563
1564         torture_comment(tctx, "echo without session => OK\n");
1565         status = smb2_keepalive(tree->session->transport);
1566         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1567                                         "smb2_keepalive without session failed");
1568
1569         torture_comment(tctx, "echo with session => OK\n");
1570         req = smb2_keepalive_send(tree->session->transport, tree->session);
1571         status = smb2_keepalive_recv(req);
1572         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1573                                         "smb2_keepalive with session failed");
1574
1575         torture_comment(tctx, "logoff => OK\n");
1576         status = smb2_logoff(tree->session);
1577         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1578                                         "smb2_logoff failed");
1579
1580         ret = true;
1581 done:
1582         cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1583
1584         if (h1 != NULL) {
1585                 smb2_util_close(tree, *h1);
1586         }
1587
1588         talloc_free(tree);
1589         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
1590         return ret;
1591 }
1592
1593 static bool test_session_expire2s(struct torture_context *tctx)
1594 {
1595         return test_session_expire2i(tctx,
1596                                      false); /* force_encryption */
1597 }
1598
1599 static bool test_session_expire2e(struct torture_context *tctx)
1600 {
1601         return test_session_expire2i(tctx,
1602                                      true); /* force_encryption */
1603 }
1604
1605 static bool test_session_expire_disconnect(struct torture_context *tctx)
1606 {
1607         NTSTATUS status;
1608         bool ret = false;
1609         struct smbcli_options options;
1610         const char *host = torture_setting_string(tctx, "host", NULL);
1611         const char *share = torture_setting_string(tctx, "share", NULL);
1612         struct cli_credentials *credentials = samba_cmdline_get_creds();
1613         struct smb2_tree *tree = NULL;
1614         enum credentials_use_kerberos use_kerberos;
1615         char fname[256];
1616         struct smb2_handle _h1;
1617         struct smb2_handle *h1 = NULL;
1618         struct smb2_create io1;
1619         union smb_fileinfo qfinfo;
1620         bool connected;
1621
1622         use_kerberos = cli_credentials_get_kerberos_state(credentials);
1623         if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
1624                 torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
1625                 torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
1626         }
1627
1628         cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1629
1630         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
1631         lpcfg_smbcli_options(tctx->lp_ctx, &options);
1632         options.signing = SMB_SIGNING_REQUIRED;
1633
1634         status = smb2_connect(tctx,
1635                               host,
1636                               lpcfg_smb_ports(tctx->lp_ctx),
1637                               share,
1638                               lpcfg_resolve_context(tctx->lp_ctx),
1639                               credentials,
1640                               &tree,
1641                               tctx->ev,
1642                               &options,
1643                               lpcfg_socket_options(tctx->lp_ctx),
1644                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1645                               );
1646         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1647                                         "smb2_connect failed");
1648
1649         smbXcli_session_set_disconnect_expired(tree->session->smbXcli);
1650
1651         /* Add some random component to the file name. */
1652         snprintf(fname, sizeof(fname), "session_expire1_%s.dat",
1653                  generate_random_str(tctx, 8));
1654
1655         smb2_util_unlink(tree, fname);
1656
1657         smb2_oplock_create_share(&io1, fname,
1658                                  smb2_util_share_access(""),
1659                                  smb2_util_oplock_level("b"));
1660         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
1661
1662         status = smb2_create(tree, tctx, &io1);
1663         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1664                                         "smb2_create failed");
1665         _h1 = io1.out.file.handle;
1666         h1 = &_h1;
1667         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1668         torture_assert_int_equal(tctx, io1.out.oplock_level,
1669                                         smb2_util_oplock_level("b"),
1670                                         "oplock_level incorrect");
1671
1672         /* get the security descriptor */
1673
1674         ZERO_STRUCT(qfinfo);
1675
1676         qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION;
1677         qfinfo.access_information.in.file.handle = _h1;
1678
1679         torture_comment(tctx, "query info => OK\n");
1680
1681         ZERO_STRUCT(qfinfo.access_information.out);
1682         status = smb2_getinfo_file(tree, tctx, &qfinfo);
1683         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1684                                         "smb2_getinfo_file failed");
1685
1686         torture_comment(tctx, "sleep 10 seconds\n");
1687         smb_msleep(10*1000);
1688
1689         torture_comment(tctx, "query info => EXPIRED\n");
1690         ZERO_STRUCT(qfinfo.access_information.out);
1691         status = smb2_getinfo_file(tree, tctx, &qfinfo);
1692         torture_assert_ntstatus_equal_goto(tctx, status,
1693                                            NT_STATUS_NETWORK_SESSION_EXPIRED,
1694                                            ret, done, "smb2_getinfo_file "
1695                                            "returned unexpected status");
1696
1697         connected = smbXcli_conn_is_connected(tree->session->transport->conn);
1698         torture_assert_goto(tctx, !connected, ret, done, "connected\n");
1699
1700         ret = true;
1701 done:
1702         cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
1703
1704         if (h1 != NULL) {
1705                 smb2_util_close(tree, *h1);
1706         }
1707
1708         talloc_free(tree);
1709         lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0");
1710         return ret;
1711 }
1712
1713 bool test_session_bind1(struct torture_context *tctx, struct smb2_tree *tree1)
1714 {
1715         const char *host = torture_setting_string(tctx, "host", NULL);
1716         const char *share = torture_setting_string(tctx, "share", NULL);
1717         struct cli_credentials *credentials = samba_cmdline_get_creds();
1718         NTSTATUS status;
1719         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1720         char fname[256];
1721         struct smb2_handle _h1;
1722         struct smb2_handle *h1 = NULL;
1723         struct smb2_create io1;
1724         union smb_fileinfo qfinfo;
1725         bool ret = false;
1726         struct smb2_tree *tree2 = NULL;
1727         struct smb2_transport *transport1 = tree1->session->transport;
1728         struct smbcli_options options2;
1729         struct smb2_transport *transport2 = NULL;
1730         struct smb2_session *session1_1 = tree1->session;
1731         struct smb2_session *session1_2 = NULL;
1732         struct smb2_session *session2_1 = NULL;
1733         struct smb2_session *session2_2 = NULL;
1734         uint32_t caps;
1735
1736         caps = smb2cli_conn_server_capabilities(transport1->conn);
1737         if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
1738                 torture_skip(tctx, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
1739         }
1740
1741         /*
1742          * We always want signing for this test!
1743          */
1744         smb2cli_tcon_should_sign(tree1->smbXcli, true);
1745         options2 = transport1->options;
1746         options2.signing = SMB_SIGNING_REQUIRED;
1747
1748         /* Add some random component to the file name. */
1749         snprintf(fname, sizeof(fname), "session_bind1_%s.dat",
1750                  generate_random_str(tctx, 8));
1751
1752         smb2_util_unlink(tree1, fname);
1753
1754         smb2_oplock_create_share(&io1, fname,
1755                                  smb2_util_share_access(""),
1756                                  smb2_util_oplock_level("b"));
1757
1758         status = smb2_create(tree1, mem_ctx, &io1);
1759         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1760                                         "smb2_create failed");
1761         _h1 = io1.out.file.handle;
1762         h1 = &_h1;
1763         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1764         torture_assert_int_equal(tctx, io1.out.oplock_level,
1765                                         smb2_util_oplock_level("b"),
1766                                         "oplock_level incorrect");
1767
1768         status = smb2_connect(tctx,
1769                               host,
1770                               lpcfg_smb_ports(tctx->lp_ctx),
1771                               share,
1772                               lpcfg_resolve_context(tctx->lp_ctx),
1773                               credentials,
1774                               &tree2,
1775                               tctx->ev,
1776                               &options2,
1777                               lpcfg_socket_options(tctx->lp_ctx),
1778                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1779                               );
1780         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1781                                         "smb2_connect failed");
1782         session2_2 = tree2->session;
1783         transport2 = tree2->session->transport;
1784
1785         /*
1786          * Now bind the 2nd transport connection to the 1st session
1787          */
1788         session1_2 = smb2_session_channel(transport2,
1789                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
1790                                           tree2,
1791                                           session1_1);
1792         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
1793
1794         status = smb2_session_setup_spnego(session1_2,
1795                                            samba_cmdline_get_creds(),
1796                                            0 /* previous_session_id */);
1797         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1798                                         "smb2_session_setup_spnego failed");
1799
1800         /* use the 1st connection, 1st session */
1801         ZERO_STRUCT(qfinfo);
1802         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
1803         qfinfo.generic.in.file.handle = _h1;
1804         tree1->session = session1_1;
1805         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
1806         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1807                                         "smb2_getinfo_file failed");
1808
1809         /* use the 2nd connection, 1st session */
1810         ZERO_STRUCT(qfinfo);
1811         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
1812         qfinfo.generic.in.file.handle = _h1;
1813         tree1->session = session1_2;
1814         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
1815         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1816                                         "smb2_getinfo_file failed");
1817
1818         tree1->session = session1_1;
1819         status = smb2_util_close(tree1, *h1);
1820         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1821                                         "smb2_util_close failed");
1822         h1 = NULL;
1823
1824         /*
1825          * Now bind the 1st transport connection to the 2nd session
1826          */
1827         session2_1 = smb2_session_channel(transport1,
1828                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
1829                                           tree1,
1830                                           session2_2);
1831         torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed");
1832
1833         status = smb2_session_setup_spnego(session2_1,
1834                                            samba_cmdline_get_creds(),
1835                                            0 /* previous_session_id */);
1836         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1837                                         "smb2_session_setup_spnego failed");
1838
1839         tree2->session = session2_1;
1840         status = smb2_util_unlink(tree2, fname);
1841         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1842                                         "smb2_util_unlink failed");
1843         ret = true;
1844 done:
1845         talloc_free(tree2);
1846         tree1->session = session1_1;
1847
1848         if (h1 != NULL) {
1849                 smb2_util_close(tree1, *h1);
1850         }
1851
1852         smb2_util_unlink(tree1, fname);
1853
1854         talloc_free(tree1);
1855
1856         talloc_free(mem_ctx);
1857
1858         return ret;
1859 }
1860
1861 static bool test_session_bind2(struct torture_context *tctx, struct smb2_tree *tree1)
1862 {
1863         const char *host = torture_setting_string(tctx, "host", NULL);
1864         const char *share = torture_setting_string(tctx, "share", NULL);
1865         struct cli_credentials *credentials = samba_cmdline_get_creds();
1866         NTSTATUS status;
1867         TALLOC_CTX *mem_ctx = talloc_new(tctx);
1868         char fname1[256];
1869         char fname2[256];
1870         struct smb2_handle _h1f1;
1871         struct smb2_handle *h1f1 = NULL;
1872         struct smb2_handle _h1f2;
1873         struct smb2_handle *h1f2 = NULL;
1874         struct smb2_handle _h2f2;
1875         struct smb2_handle *h2f2 = NULL;
1876         struct smb2_create io1f1;
1877         struct smb2_create io1f2;
1878         struct smb2_create io2f1;
1879         struct smb2_create io2f2;
1880         union smb_fileinfo qfinfo;
1881         bool ret = false;
1882         struct smb2_transport *transport1 = tree1->session->transport;
1883         struct smbcli_options options2;
1884         struct smb2_tree *tree2 = NULL;
1885         struct smb2_transport *transport2 = NULL;
1886         struct smbcli_options options3;
1887         struct smb2_tree *tree3 = NULL;
1888         struct smb2_transport *transport3 = NULL;
1889         struct smb2_session *session1_1 = tree1->session;
1890         struct smb2_session *session1_2 = NULL;
1891         struct smb2_session *session1_3 = NULL;
1892         struct smb2_session *session2_1 = NULL;
1893         struct smb2_session *session2_2 = NULL;
1894         struct smb2_session *session2_3 = NULL;
1895         uint32_t caps;
1896
1897         caps = smb2cli_conn_server_capabilities(transport1->conn);
1898         if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
1899                 torture_skip(tctx, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
1900         }
1901
1902         /*
1903          * We always want signing for this test!
1904          */
1905         smb2cli_tcon_should_sign(tree1->smbXcli, true);
1906         options2 = transport1->options;
1907         options2.signing = SMB_SIGNING_REQUIRED;
1908
1909         /* Add some random component to the file name. */
1910         snprintf(fname1, sizeof(fname1), "session_bind2_1_%s.dat",
1911                  generate_random_str(tctx, 8));
1912         snprintf(fname2, sizeof(fname2), "session_bind2_2_%s.dat",
1913                  generate_random_str(tctx, 8));
1914
1915         smb2_util_unlink(tree1, fname1);
1916         smb2_util_unlink(tree1, fname2);
1917
1918         smb2_oplock_create_share(&io1f1, fname1,
1919                                  smb2_util_share_access(""),
1920                                  smb2_util_oplock_level(""));
1921         smb2_oplock_create_share(&io1f2, fname2,
1922                                  smb2_util_share_access(""),
1923                                  smb2_util_oplock_level(""));
1924
1925         status = smb2_create(tree1, mem_ctx, &io1f1);
1926         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1927                                         "smb2_create failed");
1928         _h1f1 = io1f1.out.file.handle;
1929         h1f1 = &_h1f1;
1930         CHECK_CREATED(tctx, &io1f1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1931         torture_assert_int_equal(tctx, io1f1.out.oplock_level,
1932                                         smb2_util_oplock_level(""),
1933                                         "oplock_level incorrect");
1934
1935         status = smb2_connect(tctx,
1936                               host,
1937                               lpcfg_smb_ports(tctx->lp_ctx),
1938                               share,
1939                               lpcfg_resolve_context(tctx->lp_ctx),
1940                               credentials,
1941                               &tree2,
1942                               tctx->ev,
1943                               &options2,
1944                               lpcfg_socket_options(tctx->lp_ctx),
1945                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1946                               );
1947         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1948                                         "smb2_connect failed");
1949         session2_2 = tree2->session;
1950         transport2 = tree2->session->transport;
1951         smb2cli_tcon_should_sign(tree2->smbXcli, true);
1952
1953         smb2_oplock_create_share(&io2f1, fname1,
1954                                  smb2_util_share_access(""),
1955                                  smb2_util_oplock_level(""));
1956         smb2_oplock_create_share(&io2f2, fname2,
1957                                  smb2_util_share_access(""),
1958                                  smb2_util_oplock_level(""));
1959
1960         status = smb2_create(tree2, mem_ctx, &io2f2);
1961         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1962                                         "smb2_create failed");
1963         _h2f2 = io2f2.out.file.handle;
1964         h2f2 = &_h2f2;
1965         CHECK_CREATED(tctx, &io2f2, CREATED, FILE_ATTRIBUTE_ARCHIVE);
1966         torture_assert_int_equal(tctx, io2f2.out.oplock_level,
1967                                         smb2_util_oplock_level(""),
1968                                         "oplock_level incorrect");
1969
1970         options3 = transport1->options;
1971         options3.signing = SMB_SIGNING_REQUIRED;
1972         options3.only_negprot = true;
1973
1974         status = smb2_connect(tctx,
1975                               host,
1976                               lpcfg_smb_ports(tctx->lp_ctx),
1977                               share,
1978                               lpcfg_resolve_context(tctx->lp_ctx),
1979                               credentials,
1980                               &tree3,
1981                               tctx->ev,
1982                               &options3,
1983                               lpcfg_socket_options(tctx->lp_ctx),
1984                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
1985                               );
1986         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
1987                                         "smb2_connect failed");
1988         transport3 = tree3->session->transport;
1989
1990         /*
1991          * Create a fake session for the 2nd transport connection to the 1st session
1992          */
1993         session1_2 = smb2_session_channel(transport2,
1994                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
1995                                           tree1,
1996                                           session1_1);
1997         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
1998
1999         /*
2000          * Now bind the 3rd transport connection to the 1st session
2001          */
2002         session1_3 = smb2_session_channel(transport3,
2003                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2004                                           tree1,
2005                                           session1_1);
2006         torture_assert(tctx, session1_3 != NULL, "smb2_session_channel failed");
2007
2008         status = smb2_session_setup_spnego(session1_3,
2009                                            credentials,
2010                                            0 /* previous_session_id */);
2011         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2012                                         "smb2_session_setup_spnego failed");
2013
2014         /*
2015          * Create a fake session for the 1st transport connection to the 2nd session
2016          */
2017         session2_1 = smb2_session_channel(transport1,
2018                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2019                                           tree2,
2020                                           session2_2);
2021         torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed");
2022
2023         /*
2024          * Now bind the 3rd transport connection to the 2nd session
2025          */
2026         session2_3 = smb2_session_channel(transport3,
2027                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2028                                           tree2,
2029                                           session2_2);
2030         torture_assert(tctx, session2_3 != NULL, "smb2_session_channel failed");
2031
2032         status = smb2_session_setup_spnego(session2_3,
2033                                            credentials,
2034                                            0 /* previous_session_id */);
2035         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2036                                         "smb2_session_setup_spnego failed");
2037
2038         ZERO_STRUCT(qfinfo);
2039         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2040         qfinfo.generic.in.file.handle = _h1f1;
2041         tree1->session = session1_1;
2042         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
2043         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2044                                         "smb2_getinfo_file failed");
2045         tree1->session = session1_2;
2046         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
2047         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2048                                         "smb2_getinfo_file failed");
2049         tree1->session = session1_3;
2050         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
2051         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2052                                         "smb2_getinfo_file failed");
2053
2054         ZERO_STRUCT(qfinfo);
2055         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2056         qfinfo.generic.in.file.handle = _h2f2;
2057         tree2->session = session2_1;
2058         status = smb2_getinfo_file(tree2, mem_ctx, &qfinfo);
2059         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2060                                         "smb2_getinfo_file failed");
2061         tree2->session = session2_2;
2062         status = smb2_getinfo_file(tree2, mem_ctx, &qfinfo);
2063         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2064                                         "smb2_getinfo_file failed");
2065         tree2->session = session2_3;
2066         status = smb2_getinfo_file(tree2, mem_ctx, &qfinfo);
2067         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2068                                         "smb2_getinfo_file failed");
2069
2070         tree1->session = session1_1;
2071         status = smb2_create(tree1, mem_ctx, &io1f2);
2072         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done,
2073                                         "smb2_create failed");
2074         tree1->session = session1_2;
2075         status = smb2_create(tree1, mem_ctx, &io1f2);
2076         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2077                                         "smb2_create failed");
2078         tree1->session = session1_3;
2079         status = smb2_create(tree1, mem_ctx, &io1f2);
2080         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done,
2081                                         "smb2_create failed");
2082
2083         tree2->session = session2_1;
2084         status = smb2_create(tree2, mem_ctx, &io2f1);
2085         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2086                                         "smb2_create failed");
2087         tree2->session = session2_2;
2088         status = smb2_create(tree2, mem_ctx, &io2f1);
2089         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done,
2090                                         "smb2_create failed");
2091         tree2->session = session2_3;
2092         status = smb2_create(tree2, mem_ctx, &io2f1);
2093         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done,
2094                                         "smb2_create failed");
2095
2096         smbXcli_conn_disconnect(transport3->conn, NT_STATUS_LOCAL_DISCONNECT);
2097         smb_msleep(500);
2098
2099         tree1->session = session1_1;
2100         status = smb2_create(tree1, mem_ctx, &io1f2);
2101         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done,
2102                                         "smb2_create failed");
2103         tree1->session = session1_2;
2104         status = smb2_create(tree1, mem_ctx, &io1f2);
2105         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2106                                         "smb2_create failed");
2107
2108         tree2->session = session2_1;
2109         status = smb2_create(tree2, mem_ctx, &io2f1);
2110         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2111                                         "smb2_create failed");
2112         tree2->session = session2_2;
2113         status = smb2_create(tree2, mem_ctx, &io2f1);
2114         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_SHARING_VIOLATION, ret, done,
2115                                         "smb2_create failed");
2116
2117         smbXcli_conn_disconnect(transport2->conn, NT_STATUS_LOCAL_DISCONNECT);
2118         smb_msleep(500);
2119         h2f2 = NULL;
2120
2121         tree1->session = session1_1;
2122         status = smb2_create(tree1, mem_ctx, &io1f2);
2123         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2124                                         "smb2_create failed");
2125         _h1f2 = io1f2.out.file.handle;
2126         h1f2 = &_h1f2;
2127         CHECK_CREATED(tctx, &io1f2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
2128         torture_assert_int_equal(tctx, io1f2.out.oplock_level,
2129                                         smb2_util_oplock_level(""),
2130                                         "oplock_level incorrect");
2131
2132         tree1->session = session1_1;
2133         status = smb2_util_close(tree1, *h1f1);
2134         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2135                                         "smb2_util_close failed");
2136         h1f1 = NULL;
2137
2138         ret = true;
2139 done:
2140
2141         smbXcli_conn_disconnect(transport3->conn, NT_STATUS_LOCAL_DISCONNECT);
2142         smbXcli_conn_disconnect(transport2->conn, NT_STATUS_LOCAL_DISCONNECT);
2143
2144         tree1->session = session1_1;
2145         tree2->session = session2_2;
2146
2147         if (h1f1 != NULL) {
2148                 smb2_util_close(tree1, *h1f1);
2149         }
2150         if (h1f2 != NULL) {
2151                 smb2_util_close(tree1, *h1f2);
2152         }
2153         if (h2f2 != NULL) {
2154                 smb2_util_close(tree2, *h2f2);
2155         }
2156
2157         smb2_util_unlink(tree1, fname1);
2158         smb2_util_unlink(tree1, fname2);
2159
2160         talloc_free(tree1);
2161
2162         talloc_free(mem_ctx);
2163
2164         return ret;
2165 }
2166
2167 static bool test_session_bind_auth_mismatch(struct torture_context *tctx,
2168                                             struct smb2_tree *tree1,
2169                                             const char *testname,
2170                                             struct cli_credentials *creds1,
2171                                             struct cli_credentials *creds2,
2172                                             bool creds2_require_ok)
2173 {
2174         const char *host = torture_setting_string(tctx, "host", NULL);
2175         const char *share = torture_setting_string(tctx, "share", NULL);
2176         NTSTATUS status;
2177         TALLOC_CTX *mem_ctx = talloc_new(tctx);
2178         char fname[256];
2179         struct smb2_handle _h1;
2180         struct smb2_handle *h1 = NULL;
2181         struct smb2_create io1;
2182         union smb_fileinfo qfinfo;
2183         bool ret = false;
2184         struct smb2_tree *tree2 = NULL;
2185         struct smb2_transport *transport1 = tree1->session->transport;
2186         struct smbcli_options options2;
2187         struct smb2_transport *transport2 = NULL;
2188         struct smb2_session *session1_1 = tree1->session;
2189         struct smb2_session *session1_2 = NULL;
2190         struct smb2_session *session2_1 = NULL;
2191         struct smb2_session *session2_2 = NULL;
2192         struct smb2_session *session3_1 = NULL;
2193         uint32_t caps;
2194         bool encrypted;
2195         bool creds2_got_ok = false;
2196
2197         encrypted = smb2cli_tcon_is_encryption_on(tree1->smbXcli);
2198
2199         caps = smb2cli_conn_server_capabilities(transport1->conn);
2200         if (!(caps & SMB2_CAP_MULTI_CHANNEL)) {
2201                 torture_skip(tctx, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n");
2202         }
2203
2204         /*
2205          * We always want signing for this test!
2206          */
2207         smb2cli_tcon_should_sign(tree1->smbXcli, true);
2208         options2 = transport1->options;
2209         options2.signing = SMB_SIGNING_REQUIRED;
2210
2211         /* Add some random component to the file name. */
2212         snprintf(fname, sizeof(fname), "%s_%s.dat", testname,
2213                  generate_random_str(tctx, 8));
2214
2215         smb2_util_unlink(tree1, fname);
2216
2217         smb2_oplock_create_share(&io1, fname,
2218                                  smb2_util_share_access(""),
2219                                  smb2_util_oplock_level("b"));
2220
2221         status = smb2_create(tree1, mem_ctx, &io1);
2222         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2223                                         "smb2_create failed");
2224         _h1 = io1.out.file.handle;
2225         h1 = &_h1;
2226         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
2227         torture_assert_int_equal(tctx, io1.out.oplock_level,
2228                                         smb2_util_oplock_level("b"),
2229                                         "oplock_level incorrect");
2230
2231         status = smb2_connect(tctx,
2232                               host,
2233                               lpcfg_smb_ports(tctx->lp_ctx),
2234                               share,
2235                               lpcfg_resolve_context(tctx->lp_ctx),
2236                               creds1,
2237                               &tree2,
2238                               tctx->ev,
2239                               &options2,
2240                               lpcfg_socket_options(tctx->lp_ctx),
2241                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
2242                               );
2243         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2244                                         "smb2_connect failed");
2245         session2_2 = tree2->session;
2246         transport2 = tree2->session->transport;
2247
2248         /*
2249          * Now bind the 2nd transport connection to the 1st session
2250          */
2251         session1_2 = smb2_session_channel(transport2,
2252                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2253                                           tree2,
2254                                           session1_1);
2255         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
2256
2257         status = smb2_session_setup_spnego(session1_2,
2258                                            creds1,
2259                                            0 /* previous_session_id */);
2260         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2261                                         "smb2_session_setup_spnego failed");
2262
2263         /* use the 1st connection, 1st session */
2264         ZERO_STRUCT(qfinfo);
2265         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2266         qfinfo.generic.in.file.handle = _h1;
2267         tree1->session = session1_1;
2268         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
2269         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2270                                         "smb2_getinfo_file failed");
2271
2272         /* use the 2nd connection, 1st session */
2273         ZERO_STRUCT(qfinfo);
2274         qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2275         qfinfo.generic.in.file.handle = _h1;
2276         tree1->session = session1_2;
2277         status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
2278         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2279                                         "smb2_getinfo_file failed");
2280
2281         tree1->session = session1_1;
2282         status = smb2_util_close(tree1, *h1);
2283         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2284                                         "smb2_util_close failed");
2285         h1 = NULL;
2286
2287         /*
2288          * Create a 3rd session in order to check if the invalid (creds2)
2289          * are mapped to guest.
2290          */
2291         session3_1 = smb2_session_init(transport1,
2292                                        lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2293                                        tctx);
2294         torture_assert(tctx, session3_1 != NULL, "smb2_session_channel failed");
2295
2296         status = smb2_session_setup_spnego(session3_1,
2297                                            creds2,
2298                                            0 /* previous_session_id */);
2299         if (creds2_require_ok) {
2300                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2301                                         "smb2_session_setup_spnego worked");
2302                 creds2_got_ok = true;
2303         } else if (NT_STATUS_IS_OK(status)) {
2304                 bool authentiated = smbXcli_session_is_authenticated(session3_1->smbXcli);
2305                 torture_assert(tctx, !authentiated, "Invalid credentials allowed!");
2306                 creds2_got_ok = true;
2307         } else {
2308                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_LOGON_FAILURE, ret, done,
2309                                         "smb2_session_setup_spnego worked");
2310         }
2311
2312         /*
2313          * Now bind the 1st transport connection to the 2nd session
2314          */
2315         session2_1 = smb2_session_channel(transport1,
2316                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2317                                           tree1,
2318                                           session2_2);
2319         torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed");
2320
2321         tree2->session = session2_1;
2322         status = smb2_util_unlink(tree2, fname);
2323         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2324                                         "smb2_util_unlink worked on invalid channel");
2325
2326         status = smb2_session_setup_spnego(session2_1,
2327                                            creds2,
2328                                            0 /* previous_session_id */);
2329         if (creds2_got_ok) {
2330                 /*
2331                  * attaching with a different user (guest or anonymous) results
2332                  * in ACCESS_DENIED.
2333                  */
2334                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_ACCESS_DENIED, ret, done,
2335                                         "smb2_session_setup_spnego worked");
2336         } else {
2337                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_LOGON_FAILURE, ret, done,
2338                                         "smb2_session_setup_spnego worked");
2339         }
2340
2341         tree2->session = session2_1;
2342         status = smb2_util_unlink(tree2, fname);
2343         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2344                                         "smb2_util_unlink worked on invalid channel");
2345
2346         tree2->session = session2_2;
2347         status = smb2_util_unlink(tree2, fname);
2348         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2349                                         "smb2_util_unlink failed");
2350         status = smb2_util_unlink(tree2, fname);
2351         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
2352                                         "smb2_util_unlink worked");
2353         if (creds2_got_ok) {
2354                 /*
2355                  * We got ACCESS_DENIED on the session bind
2356                  * with a different user, now check that
2357                  * the correct user can actually bind on
2358                  * the same connection.
2359                  */
2360                 TALLOC_FREE(session2_1);
2361                 session2_1 = smb2_session_channel(transport1,
2362                                                   lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2363                                                   tree1,
2364                                                   session2_2);
2365                 torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed");
2366
2367                 status = smb2_session_setup_spnego(session2_1,
2368                                                    creds1,
2369                                                    0 /* previous_session_id */);
2370                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2371                                         "smb2_session_setup_spnego failed");
2372                 tree2->session = session2_1;
2373                 status = smb2_util_unlink(tree2, fname);
2374                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
2375                                                 "smb2_util_unlink worked");
2376                 tree2->session = session2_2;
2377         }
2378
2379         tree1->session = session1_1;
2380         status = smb2_util_unlink(tree1, fname);
2381         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
2382                                         "smb2_util_unlink worked");
2383
2384         tree1->session = session1_2;
2385         status = smb2_util_unlink(tree1, fname);
2386         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
2387                                         "smb2_util_unlink worked");
2388
2389         if (creds2_got_ok) {
2390                 /*
2391                  * With valid credentials, there's no point to test a failing
2392                  * reauth.
2393                  */
2394                 ret = true;
2395                 goto done;
2396         }
2397
2398         /*
2399          * Do a failing reauth the 2nd channel
2400          */
2401         status = smb2_session_setup_spnego(session1_2,
2402                                            creds2,
2403                                            0 /* previous_session_id */);
2404         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_LOGON_FAILURE, ret, done,
2405                                         "smb2_session_setup_spnego worked");
2406
2407         tree1->session = session1_1;
2408         status = smb2_util_unlink(tree1, fname);
2409         if (encrypted) {
2410                 torture_assert_goto(tctx, !smbXcli_conn_is_connected(transport1->conn), ret, done,
2411                                                 "smb2_util_unlink worked");
2412         } else {
2413                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2414                                                 "smb2_util_unlink worked");
2415         }
2416
2417         tree1->session = session1_2;
2418         status = smb2_util_unlink(tree1, fname);
2419         if (encrypted) {
2420                 torture_assert_goto(tctx, !smbXcli_conn_is_connected(transport2->conn), ret, done,
2421                                                 "smb2_util_unlink worked");
2422         } else {
2423                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_USER_SESSION_DELETED, ret, done,
2424                                                 "smb2_util_unlink worked");
2425         }
2426
2427         status = smb2_util_unlink(tree2, fname);
2428         if (encrypted) {
2429                 torture_assert_goto(tctx, !smbXcli_conn_is_connected(transport1->conn), ret, done,
2430                                                 "smb2_util_unlink worked");
2431                 torture_assert_goto(tctx, !smbXcli_conn_is_connected(transport2->conn), ret, done,
2432                                                 "smb2_util_unlink worked");
2433         } else {
2434                 torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND, ret, done,
2435                                                 "smb2_util_unlink worked");
2436         }
2437
2438         ret = true;
2439 done:
2440         talloc_free(tree2);
2441         tree1->session = session1_1;
2442
2443         if (h1 != NULL) {
2444                 smb2_util_close(tree1, *h1);
2445         }
2446
2447         smb2_util_unlink(tree1, fname);
2448
2449         talloc_free(tree1);
2450
2451         talloc_free(mem_ctx);
2452
2453         return ret;
2454 }
2455
2456 static bool test_session_bind_invalid_auth(struct torture_context *tctx, struct smb2_tree *tree1)
2457 {
2458         struct cli_credentials *credentials = samba_cmdline_get_creds();
2459         struct cli_credentials *invalid_credentials = NULL;
2460         bool ret = false;
2461
2462         invalid_credentials = cli_credentials_init(tctx);
2463         torture_assert(tctx, (invalid_credentials != NULL), "talloc error");
2464         cli_credentials_set_username(invalid_credentials, "__none__invalid__none__", CRED_SPECIFIED);
2465         cli_credentials_set_domain(invalid_credentials, "__none__invalid__none__", CRED_SPECIFIED);
2466         cli_credentials_set_password(invalid_credentials, "__none__invalid__none__", CRED_SPECIFIED);
2467         cli_credentials_set_realm(invalid_credentials, NULL, CRED_SPECIFIED);
2468         cli_credentials_set_workstation(invalid_credentials, "", CRED_UNINITIALISED);
2469
2470         ret = test_session_bind_auth_mismatch(tctx, tree1, __func__,
2471                                               credentials,
2472                                               invalid_credentials,
2473                                               false);
2474         return ret;
2475 }
2476
2477 static bool test_session_bind_different_user(struct torture_context *tctx, struct smb2_tree *tree1)
2478 {
2479         struct cli_credentials *credentials1 = samba_cmdline_get_creds();
2480         struct cli_credentials *credentials2 = torture_user2_credentials(tctx, tctx);
2481         char *u1 = cli_credentials_get_unparsed_name(credentials1, tctx);
2482         char *u2 = cli_credentials_get_unparsed_name(credentials2, tctx);
2483         bool ret = false;
2484         bool bval;
2485
2486         torture_assert(tctx, (credentials2 != NULL), "talloc error");
2487         bval = cli_credentials_is_anonymous(credentials2);
2488         if (bval) {
2489                 torture_skip(tctx, "valid user2 credentials are required");
2490         }
2491         bval = strequal(u1, u2);
2492         if (bval) {
2493                 torture_skip(tctx, "different user2 credentials are required");
2494         }
2495
2496         ret = test_session_bind_auth_mismatch(tctx, tree1, __func__,
2497                                               credentials1,
2498                                               credentials2,
2499                                               true);
2500         return ret;
2501 }
2502
2503 static bool test_session_bind_negative_smbXtoX(struct torture_context *tctx,
2504                                                const char *testname,
2505                                                struct cli_credentials *credentials,
2506                                                const struct smbcli_options *options1,
2507                                                const struct smbcli_options *options2,
2508                                                NTSTATUS bind_reject_status)
2509 {
2510         const char *host = torture_setting_string(tctx, "host", NULL);
2511         const char *share = torture_setting_string(tctx, "share", NULL);
2512         NTSTATUS status;
2513         bool ret = false;
2514         struct smb2_tree *tree1 = NULL;
2515         struct smb2_session *session1_1 = NULL;
2516         char fname[256];
2517         struct smb2_handle _h1;
2518         struct smb2_handle *h1 = NULL;
2519         struct smb2_create io1;
2520         union smb_fileinfo qfinfo1;
2521         struct smb2_tree *tree2_0 = NULL;
2522         struct smb2_transport *transport2 = NULL;
2523         struct smb2_session *session1_2 = NULL;
2524         uint64_t session1_id = 0;
2525         uint16_t session1_flags = 0;
2526         NTSTATUS deleted_status = NT_STATUS_USER_SESSION_DELETED;
2527
2528         status = smb2_connect(tctx,
2529                               host,
2530                               lpcfg_smb_ports(tctx->lp_ctx),
2531                               share,
2532                               lpcfg_resolve_context(tctx->lp_ctx),
2533                               credentials,
2534                               &tree1,
2535                               tctx->ev,
2536                               options1,
2537                               lpcfg_socket_options(tctx->lp_ctx),
2538                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
2539                               );
2540         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2541                                         "smb2_connect options1 failed");
2542         session1_1 = tree1->session;
2543         session1_id = smb2cli_session_current_id(session1_1->smbXcli);
2544         session1_flags = smb2cli_session_get_flags(session1_1->smbXcli);
2545
2546         /* Add some random component to the file name. */
2547         snprintf(fname, sizeof(fname), "%s_%s.dat",
2548                  testname, generate_random_str(tctx, 8));
2549
2550         smb2_util_unlink(tree1, fname);
2551
2552         smb2_oplock_create_share(&io1, fname,
2553                                  smb2_util_share_access(""),
2554                                  smb2_util_oplock_level("b"));
2555
2556         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
2557         status = smb2_create(tree1, tctx, &io1);
2558         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2559                                         "smb2_create failed");
2560         _h1 = io1.out.file.handle;
2561         h1 = &_h1;
2562         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
2563         torture_assert_int_equal(tctx, io1.out.oplock_level,
2564                                         smb2_util_oplock_level("b"),
2565                                         "oplock_level incorrect");
2566
2567         status = smb2_connect(tctx,
2568                               host,
2569                               lpcfg_smb_ports(tctx->lp_ctx),
2570                               share,
2571                               lpcfg_resolve_context(tctx->lp_ctx),
2572                               credentials,
2573                               &tree2_0,
2574                               tctx->ev,
2575                               options2,
2576                               lpcfg_socket_options(tctx->lp_ctx),
2577                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
2578                               );
2579         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2580                                         "smb2_connect options2 failed");
2581         transport2 = tree2_0->session->transport;
2582
2583         /*
2584          * Now bind the 2nd transport connection to the 1st session
2585          */
2586         session1_2 = smb2_session_channel(transport2,
2587                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2588                                           tree2_0,
2589                                           session1_1);
2590         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
2591
2592         status = smb2_session_setup_spnego(session1_2,
2593                                            credentials,
2594                                            0 /* previous_session_id */);
2595         torture_assert_ntstatus_equal_goto(tctx, status, bind_reject_status, ret, done,
2596                                            "smb2_session_setup_spnego failed");
2597         if (NT_STATUS_IS_OK(bind_reject_status)) {
2598                 ZERO_STRUCT(qfinfo1);
2599                 qfinfo1.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2600                 qfinfo1.generic.in.file.handle = _h1;
2601                 tree1->session = session1_2;
2602                 status = smb2_getinfo_file(tree1, tctx, &qfinfo1);
2603                 tree1->session = session1_1;
2604                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2605                                         "smb2_getinfo_file failed");
2606         }
2607         TALLOC_FREE(session1_2);
2608
2609         /* Check the initial session is still alive */
2610         ZERO_STRUCT(qfinfo1);
2611         qfinfo1.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2612         qfinfo1.generic.in.file.handle = _h1;
2613         status = smb2_getinfo_file(tree1, tctx, &qfinfo1);
2614         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2615                                         "smb2_getinfo_file failed");
2616
2617         if (NT_STATUS_IS_OK(bind_reject_status)) {
2618                 deleted_status = NT_STATUS_ACCESS_DENIED;
2619                 bind_reject_status = NT_STATUS_ACCESS_DENIED;
2620         }
2621
2622         /*
2623          * I guess this is not part of MultipleChannel_Negative_SMB2002,
2624          * but we should also check the status without
2625          * SMB2_SESSION_FLAG_BINDING.
2626          */
2627         session1_2 = smb2_session_channel(transport2,
2628                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2629                                           tree2_0,
2630                                           session1_1);
2631         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
2632         session1_2->needs_bind = false;
2633
2634         status = smb2_session_setup_spnego(session1_2,
2635                                            credentials,
2636                                            0 /* previous_session_id */);
2637         torture_assert_ntstatus_equal_goto(tctx, status, deleted_status, ret, done,
2638                                            "smb2_session_setup_spnego failed");
2639         TALLOC_FREE(session1_2);
2640
2641         /*
2642          * ... and we should also check the status without any existing
2643          * session keys.
2644          */
2645         session1_2 = smb2_session_init(transport2,
2646                                        lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2647                                        tree2_0);
2648         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
2649         talloc_steal(tree2_0->session, transport2);
2650         smb2cli_session_set_id_and_flags(session1_2->smbXcli,
2651                                          session1_id, session1_flags);
2652
2653         status = smb2_session_setup_spnego(session1_2,
2654                                            credentials,
2655                                            0 /* previous_session_id */);
2656         torture_assert_ntstatus_equal_goto(tctx, status, deleted_status, ret, done,
2657                                            "smb2_session_setup_spnego failed");
2658         TALLOC_FREE(session1_2);
2659
2660         /* Check the initial session is still alive */
2661         ZERO_STRUCT(qfinfo1);
2662         qfinfo1.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2663         qfinfo1.generic.in.file.handle = _h1;
2664         status = smb2_getinfo_file(tree1, tctx, &qfinfo1);
2665         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2666                                         "smb2_getinfo_file failed");
2667
2668         /*
2669          * Now bind the 2nd transport connection to the 1st session (again)
2670          */
2671         session1_2 = smb2_session_channel(transport2,
2672                                           lpcfg_gensec_settings(tctx, tctx->lp_ctx),
2673                                           tree2_0,
2674                                           session1_1);
2675         torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed");
2676
2677         status = smb2_session_setup_spnego(session1_2,
2678                                            credentials,
2679                                            0 /* previous_session_id */);
2680         torture_assert_ntstatus_equal_goto(tctx, status, bind_reject_status, ret, done,
2681                                            "smb2_session_setup_spnego failed");
2682         TALLOC_FREE(session1_2);
2683
2684         /* Check the initial session is still alive */
2685         ZERO_STRUCT(qfinfo1);
2686         qfinfo1.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
2687         qfinfo1.generic.in.file.handle = _h1;
2688         status = smb2_getinfo_file(tree1, tctx, &qfinfo1);
2689         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
2690                                         "smb2_getinfo_file failed");
2691
2692         ret = true;
2693 done:
2694         talloc_free(tree2_0);
2695         if (h1 != NULL) {
2696                 smb2_util_close(tree1, *h1);
2697         }
2698         talloc_free(tree1);
2699
2700         return ret;
2701 }
2702
2703 /*
2704  * This is similar to the MultipleChannel_Negative_SMB2002 test
2705  * from the Windows Protocol Test Suite.
2706  *
2707  * It demonstrates that the server needs to do lookup
2708  * in the global session table in order to get the signing
2709  * and error code of invalid session setups correct.
2710  *
2711  * See: https://bugzilla.samba.org/show_bug.cgi?id=14512
2712  *
2713  * Note you can ignore tree0...
2714  */
2715 static bool test_session_bind_negative_smb202(struct torture_context *tctx, struct smb2_tree *tree0)
2716 {
2717         struct cli_credentials *credentials = samba_cmdline_get_creds();
2718         bool ret = false;
2719         struct smb2_transport *transport0 = tree0->session->transport;
2720         struct smbcli_options options1;
2721         struct smbcli_options options2;
2722         bool encrypted;
2723
2724         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
2725         if (encrypted) {
2726                 torture_skip(tctx,
2727                              "Can't test SMB 2.02 if encrytion is required");
2728         }
2729
2730         options1 = transport0->options;
2731         options1.client_guid = GUID_zero();
2732         options1.max_protocol = PROTOCOL_SMB2_02;
2733
2734         options2 = options1;
2735         options2.only_negprot = true;
2736
2737         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
2738                                                  credentials,
2739                                                  &options1, &options2,
2740                                                  NT_STATUS_REQUEST_NOT_ACCEPTED);
2741         talloc_free(tree0);
2742         return ret;
2743 }
2744
2745 static bool test_session_bind_negative_smb210s(struct torture_context *tctx, struct smb2_tree *tree0)
2746 {
2747         struct cli_credentials *credentials = samba_cmdline_get_creds();
2748         bool ret = false;
2749         struct smb2_transport *transport0 = tree0->session->transport;
2750         struct smbcli_options options1;
2751         struct smbcli_options options2;
2752         bool encrypted;
2753
2754         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
2755         if (encrypted) {
2756                 torture_skip(tctx,
2757                              "Can't test SMB 2.10 if encrytion is required");
2758         }
2759
2760         options1 = transport0->options;
2761         options1.client_guid = GUID_random();
2762         options1.max_protocol = PROTOCOL_SMB2_10;
2763
2764         /* same client guid */
2765         options2 = options1;
2766         options2.only_negprot = true;
2767
2768         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
2769                                                  credentials,
2770                                                  &options1, &options2,
2771                                                  NT_STATUS_REQUEST_NOT_ACCEPTED);
2772         talloc_free(tree0);
2773         return ret;
2774 }
2775
2776 static bool test_session_bind_negative_smb210d(struct torture_context *tctx, struct smb2_tree *tree0)
2777 {
2778         struct cli_credentials *credentials = samba_cmdline_get_creds();
2779         bool ret = false;
2780         struct smb2_transport *transport0 = tree0->session->transport;
2781         struct smbcli_options options1;
2782         struct smbcli_options options2;
2783         bool encrypted;
2784
2785         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
2786         if (encrypted) {
2787                 torture_skip(tctx,
2788                              "Can't test SMB 2.10 if encrytion is required");
2789         }
2790
2791         options1 = transport0->options;
2792         options1.client_guid = GUID_random();
2793         options1.max_protocol = PROTOCOL_SMB2_10;
2794
2795         /* different client guid */
2796         options2 = options1;
2797         options2.client_guid = GUID_random();
2798         options2.only_negprot = true;
2799
2800         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
2801                                                  credentials,
2802                                                  &options1, &options2,
2803                                                  NT_STATUS_REQUEST_NOT_ACCEPTED);
2804         talloc_free(tree0);
2805         return ret;
2806 }
2807
2808 static bool test_session_bind_negative_smb2to3s(struct torture_context *tctx, struct smb2_tree *tree0)
2809 {
2810         struct cli_credentials *credentials = samba_cmdline_get_creds();
2811         bool ret = false;
2812         struct smb2_transport *transport0 = tree0->session->transport;
2813         struct smbcli_options options1;
2814         struct smbcli_options options2;
2815         bool encrypted;
2816
2817         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
2818         if (encrypted) {
2819                 torture_skip(tctx,
2820                              "Can't test SMB 2.10 if encrytion is required");
2821         }
2822
2823         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) {
2824                 torture_skip(tctx,
2825                              "Can't test without SMB3 support");
2826         }
2827
2828         options1 = transport0->options;
2829         options1.client_guid = GUID_random();
2830         options1.min_protocol = PROTOCOL_SMB2_02;
2831         options1.max_protocol = PROTOCOL_SMB2_10;
2832
2833         /* same client guid */
2834         options2 = options1;
2835         options2.only_negprot = true;
2836         options2.min_protocol = PROTOCOL_SMB3_00;
2837         options2.max_protocol = PROTOCOL_SMB3_11;
2838         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
2839                 .num_algos = 1,
2840                 .algos = {
2841                         SMB2_SIGNING_AES128_CMAC,
2842                 },
2843         };
2844
2845         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
2846                                                  credentials,
2847                                                  &options1, &options2,
2848                                                  NT_STATUS_INVALID_PARAMETER);
2849         talloc_free(tree0);
2850         return ret;
2851 }
2852
2853 static bool test_session_bind_negative_smb2to3d(struct torture_context *tctx, struct smb2_tree *tree0)
2854 {
2855         struct cli_credentials *credentials = samba_cmdline_get_creds();
2856         bool ret = false;
2857         struct smb2_transport *transport0 = tree0->session->transport;
2858         struct smbcli_options options1;
2859         struct smbcli_options options2;
2860         bool encrypted;
2861
2862         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
2863         if (encrypted) {
2864                 torture_skip(tctx,
2865                              "Can't test SMB 2.10 if encrytion is required");
2866         }
2867
2868         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) {
2869                 torture_skip(tctx,
2870                              "Can't test without SMB3 support");
2871         }
2872
2873         options1 = transport0->options;
2874         options1.client_guid = GUID_random();
2875         options1.min_protocol = PROTOCOL_SMB2_02;
2876         options1.max_protocol = PROTOCOL_SMB2_10;
2877
2878         /* different client guid */
2879         options2 = options1;
2880         options2.client_guid = GUID_random();
2881         options2.only_negprot = true;
2882         options2.min_protocol = PROTOCOL_SMB3_00;
2883         options2.max_protocol = PROTOCOL_SMB3_11;
2884         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
2885                 .num_algos = 1,
2886                 .algos = {
2887                         SMB2_SIGNING_AES128_CMAC,
2888                 },
2889         };
2890
2891         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
2892                                                  credentials,
2893                                                  &options1, &options2,
2894                                                  NT_STATUS_INVALID_PARAMETER);
2895         talloc_free(tree0);
2896         return ret;
2897 }
2898
2899 static bool test_session_bind_negative_smb3to2s(struct torture_context *tctx, struct smb2_tree *tree0)
2900 {
2901         struct cli_credentials *credentials = samba_cmdline_get_creds();
2902         bool ret = false;
2903         struct smb2_transport *transport0 = tree0->session->transport;
2904         struct smbcli_options options1;
2905         struct smbcli_options options2;
2906         bool encrypted;
2907
2908         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
2909         if (encrypted) {
2910                 torture_skip(tctx,
2911                              "Can't test SMB 2.10 if encrytion is required");
2912         }
2913
2914         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) {
2915                 torture_skip(tctx,
2916                              "Can't test without SMB3 support");
2917         }
2918
2919         options1 = transport0->options;
2920         options1.client_guid = GUID_random();
2921         options1.min_protocol = PROTOCOL_SMB3_00;
2922         options1.max_protocol = PROTOCOL_SMB3_11;
2923         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
2924                 .num_algos = 1,
2925                 .algos = {
2926                         SMB2_SIGNING_AES128_CMAC,
2927                 },
2928         };
2929
2930         /* same client guid */
2931         options2 = options1;
2932         options2.only_negprot = true;
2933         options2.min_protocol = PROTOCOL_SMB2_02;
2934         options2.max_protocol = PROTOCOL_SMB2_10;
2935         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
2936                 .num_algos = 1,
2937                 .algos = {
2938                         SMB2_SIGNING_HMAC_SHA256,
2939                 },
2940         };
2941
2942         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
2943                                                  credentials,
2944                                                  &options1, &options2,
2945                                                  NT_STATUS_REQUEST_NOT_ACCEPTED);
2946         talloc_free(tree0);
2947         return ret;
2948 }
2949
2950 static bool test_session_bind_negative_smb3to2d(struct torture_context *tctx, struct smb2_tree *tree0)
2951 {
2952         struct cli_credentials *credentials = samba_cmdline_get_creds();
2953         bool ret = false;
2954         struct smb2_transport *transport0 = tree0->session->transport;
2955         struct smbcli_options options1;
2956         struct smbcli_options options2;
2957         bool encrypted;
2958
2959         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
2960         if (encrypted) {
2961                 torture_skip(tctx,
2962                              "Can't test SMB 2.10 if encrytion is required");
2963         }
2964
2965         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) {
2966                 torture_skip(tctx,
2967                              "Can't test without SMB3 support");
2968         }
2969
2970         options1 = transport0->options;
2971         options1.client_guid = GUID_random();
2972         options1.min_protocol = PROTOCOL_SMB3_00;
2973         options1.max_protocol = PROTOCOL_SMB3_11;
2974         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
2975                 .num_algos = 1,
2976                 .algos = {
2977                         SMB2_SIGNING_AES128_CMAC,
2978                 },
2979         };
2980
2981         /* different client guid */
2982         options2 = options1;
2983         options2.client_guid = GUID_random();
2984         options2.only_negprot = true;
2985         options2.min_protocol = PROTOCOL_SMB2_02;
2986         options2.max_protocol = PROTOCOL_SMB2_10;
2987         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
2988                 .num_algos = 1,
2989                 .algos = {
2990                         SMB2_SIGNING_HMAC_SHA256,
2991                 },
2992         };
2993
2994         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
2995                                                  credentials,
2996                                                  &options1, &options2,
2997                                                  NT_STATUS_REQUEST_NOT_ACCEPTED);
2998         talloc_free(tree0);
2999         return ret;
3000 }
3001
3002 static bool test_session_bind_negative_smb3to3s(struct torture_context *tctx, struct smb2_tree *tree0)
3003 {
3004         struct cli_credentials *credentials = samba_cmdline_get_creds();
3005         bool ret = false;
3006         struct smb2_transport *transport0 = tree0->session->transport;
3007         struct smbcli_options options1;
3008         struct smbcli_options options2;
3009
3010         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3011                 torture_skip(tctx,
3012                              "Can't test without SMB 3.1.1 support");
3013         }
3014
3015         options1 = transport0->options;
3016         options1.client_guid = GUID_random();
3017         options1.min_protocol = PROTOCOL_SMB3_02;
3018         options1.max_protocol = PROTOCOL_SMB3_02;
3019
3020         /* same client guid */
3021         options2 = options1;
3022         options2.only_negprot = true;
3023         options2.min_protocol = PROTOCOL_SMB3_11;
3024         options2.max_protocol = PROTOCOL_SMB3_11;
3025         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3026                 .num_algos = 1,
3027                 .algos = {
3028                         SMB2_SIGNING_AES128_CMAC,
3029                 },
3030         };
3031
3032         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3033                                                  credentials,
3034                                                  &options1, &options2,
3035                                                  NT_STATUS_INVALID_PARAMETER);
3036         talloc_free(tree0);
3037         return ret;
3038 }
3039
3040 static bool test_session_bind_negative_smb3to3d(struct torture_context *tctx, struct smb2_tree *tree0)
3041 {
3042         struct cli_credentials *credentials = samba_cmdline_get_creds();
3043         bool ret = false;
3044         struct smb2_transport *transport0 = tree0->session->transport;
3045         struct smbcli_options options1;
3046         struct smbcli_options options2;
3047
3048         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3049                 torture_skip(tctx,
3050                              "Can't test without SMB 3.1.1 support");
3051         }
3052
3053         options1 = transport0->options;
3054         options1.client_guid = GUID_random();
3055         options1.min_protocol = PROTOCOL_SMB3_02;
3056         options1.max_protocol = PROTOCOL_SMB3_02;
3057
3058         /* different client guid */
3059         options2 = options1;
3060         options2.client_guid = GUID_random();
3061         options2.only_negprot = true;
3062         options2.min_protocol = PROTOCOL_SMB3_11;
3063         options2.max_protocol = PROTOCOL_SMB3_11;
3064         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3065                 .num_algos = 1,
3066                 .algos = {
3067                         SMB2_SIGNING_AES128_CMAC,
3068                 },
3069         };
3070
3071         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3072                                                  credentials,
3073                                                  &options1, &options2,
3074                                                  NT_STATUS_INVALID_PARAMETER);
3075         talloc_free(tree0);
3076         return ret;
3077 }
3078
3079 static bool test_session_bind_negative_smb3encGtoCs(struct torture_context *tctx, struct smb2_tree *tree0)
3080 {
3081         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3082         struct cli_credentials *credentials = NULL;
3083         bool ret = false;
3084         struct smb2_transport *transport0 = tree0->session->transport;
3085         struct smbcli_options options1;
3086         struct smbcli_options options2;
3087         bool ok;
3088
3089         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3090                 torture_skip(tctx,
3091                              "Can't test without SMB 3.1.1 support");
3092         }
3093
3094         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3095         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3096         ok = cli_credentials_set_smb_encryption(credentials,
3097                                                 SMB_ENCRYPTION_REQUIRED,
3098                                                 CRED_SPECIFIED);
3099         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3100
3101         options1 = transport0->options;
3102         options1.client_guid = GUID_random();
3103         options1.min_protocol = PROTOCOL_SMB3_11;
3104         options1.max_protocol = PROTOCOL_SMB3_11;
3105         options1.signing = SMB_SIGNING_REQUIRED;
3106         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3107                 .num_algos = 1,
3108                 .algos = {
3109                         SMB2_ENCRYPTION_AES128_GCM,
3110                 },
3111         };
3112
3113         /* same client guid */
3114         options2 = options1;
3115         options2.only_negprot = true;
3116         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3117                 .num_algos = 1,
3118                 .algos = {
3119                         SMB2_ENCRYPTION_AES128_CCM,
3120                 },
3121         };
3122
3123         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3124                                                  credentials,
3125                                                  &options1, &options2,
3126                                                  NT_STATUS_INVALID_PARAMETER);
3127         talloc_free(tree0);
3128         return ret;
3129 }
3130
3131 static bool test_session_bind_negative_smb3encGtoCd(struct torture_context *tctx, struct smb2_tree *tree0)
3132 {
3133         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3134         struct cli_credentials *credentials = NULL;
3135         bool ret = false;
3136         struct smb2_transport *transport0 = tree0->session->transport;
3137         struct smbcli_options options1;
3138         struct smbcli_options options2;
3139         bool ok;
3140
3141         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3142                 torture_skip(tctx,
3143                              "Can't test without SMB 3.1.1 support");
3144         }
3145
3146         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3147         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3148         ok = cli_credentials_set_smb_encryption(credentials,
3149                                                 SMB_ENCRYPTION_REQUIRED,
3150                                                 CRED_SPECIFIED);
3151         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3152
3153         options1 = transport0->options;
3154         options1.client_guid = GUID_random();
3155         options1.min_protocol = PROTOCOL_SMB3_11;
3156         options1.max_protocol = PROTOCOL_SMB3_11;
3157         options1.signing = SMB_SIGNING_REQUIRED;
3158         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3159                 .num_algos = 1,
3160                 .algos = {
3161                         SMB2_ENCRYPTION_AES128_GCM,
3162                 },
3163         };
3164
3165         /* different client guid */
3166         options2 = options1;
3167         options2.client_guid = GUID_random();
3168         options2.only_negprot = true;
3169         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3170                 .num_algos = 1,
3171                 .algos = {
3172                         SMB2_ENCRYPTION_AES128_CCM,
3173                 },
3174         };
3175
3176         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3177                                                  credentials,
3178                                                  &options1, &options2,
3179                                                  NT_STATUS_INVALID_PARAMETER);
3180         talloc_free(tree0);
3181         return ret;
3182 }
3183
3184 static bool test_session_bind_negative_smb3signCtoHs(struct torture_context *tctx, struct smb2_tree *tree0)
3185 {
3186         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3187         struct cli_credentials *credentials = NULL;
3188         bool ret = false;
3189         struct smb2_transport *transport0 = tree0->session->transport;
3190         struct smbcli_options options1;
3191         struct smbcli_options options2;
3192         bool ok;
3193
3194         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3195                 torture_skip(tctx,
3196                              "Can't test without SMB 3.1.1 support");
3197         }
3198
3199         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3200                 torture_skip(tctx,
3201                              "Can't test without SMB 3.1.1 signing negotiation support");
3202         }
3203
3204         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3205         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3206         ok = cli_credentials_set_smb_encryption(credentials,
3207                                                 SMB_ENCRYPTION_REQUIRED,
3208                                                 CRED_SPECIFIED);
3209         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3210
3211         options1 = transport0->options;
3212         options1.client_guid = GUID_random();
3213         options1.min_protocol = PROTOCOL_SMB3_11;
3214         options1.max_protocol = PROTOCOL_SMB3_11;
3215         options1.signing = SMB_SIGNING_REQUIRED;
3216         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3217                 .num_algos = 1,
3218                 .algos = {
3219                         SMB2_SIGNING_AES128_CMAC,
3220                 },
3221         };
3222
3223         /* same client guid */
3224         options2 = options1;
3225         options2.only_negprot = true;
3226         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3227                 .num_algos = 1,
3228                 .algos = {
3229                         SMB2_SIGNING_HMAC_SHA256,
3230                 },
3231         };
3232
3233         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3234                                                  credentials,
3235                                                  &options1, &options2,
3236                                                  NT_STATUS_OK);
3237         talloc_free(tree0);
3238         return ret;
3239 }
3240
3241 static bool test_session_bind_negative_smb3signCtoHd(struct torture_context *tctx, struct smb2_tree *tree0)
3242 {
3243         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3244         struct cli_credentials *credentials = NULL;
3245         bool ret = false;
3246         struct smb2_transport *transport0 = tree0->session->transport;
3247         struct smbcli_options options1;
3248         struct smbcli_options options2;
3249         bool ok;
3250
3251         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3252                 torture_skip(tctx,
3253                              "Can't test without SMB 3.1.1 support");
3254         }
3255
3256         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3257                 torture_skip(tctx,
3258                              "Can't test without SMB 3.1.1 signing negotiation support");
3259         }
3260
3261         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3262         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3263         ok = cli_credentials_set_smb_encryption(credentials,
3264                                                 SMB_ENCRYPTION_REQUIRED,
3265                                                 CRED_SPECIFIED);
3266         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3267
3268         options1 = transport0->options;
3269         options1.client_guid = GUID_random();
3270         options1.min_protocol = PROTOCOL_SMB3_11;
3271         options1.max_protocol = PROTOCOL_SMB3_11;
3272         options1.signing = SMB_SIGNING_REQUIRED;
3273         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3274                 .num_algos = 1,
3275                 .algos = {
3276                         SMB2_SIGNING_AES128_CMAC,
3277                 },
3278         };
3279
3280         /* different client guid */
3281         options2 = options1;
3282         options2.client_guid = GUID_random();
3283         options2.only_negprot = true;
3284         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3285                 .num_algos = 1,
3286                 .algos = {
3287                         SMB2_SIGNING_HMAC_SHA256,
3288                 },
3289         };
3290
3291         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3292                                                  credentials,
3293                                                  &options1, &options2,
3294                                                  NT_STATUS_OK);
3295         talloc_free(tree0);
3296         return ret;
3297 }
3298
3299 static bool test_session_bind_negative_smb3signHtoCs(struct torture_context *tctx, struct smb2_tree *tree0)
3300 {
3301         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3302         struct cli_credentials *credentials = NULL;
3303         bool ret = false;
3304         struct smb2_transport *transport0 = tree0->session->transport;
3305         struct smbcli_options options1;
3306         struct smbcli_options options2;
3307         bool ok;
3308
3309         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3310                 torture_skip(tctx,
3311                              "Can't test without SMB 3.1.1 support");
3312         }
3313
3314         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3315                 torture_skip(tctx,
3316                              "Can't test without SMB 3.1.1 signing negotiation support");
3317         }
3318
3319         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3320         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3321         ok = cli_credentials_set_smb_encryption(credentials,
3322                                                 SMB_ENCRYPTION_REQUIRED,
3323                                                 CRED_SPECIFIED);
3324         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3325
3326         options1 = transport0->options;
3327         options1.client_guid = GUID_random();
3328         options1.min_protocol = PROTOCOL_SMB3_11;
3329         options1.max_protocol = PROTOCOL_SMB3_11;
3330         options1.signing = SMB_SIGNING_REQUIRED;
3331         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3332                 .num_algos = 1,
3333                 .algos = {
3334                         SMB2_SIGNING_HMAC_SHA256,
3335                 },
3336         };
3337
3338         /* same client guid */
3339         options2 = options1;
3340         options2.only_negprot = true;
3341         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3342                 .num_algos = 1,
3343                 .algos = {
3344                         SMB2_SIGNING_AES128_CMAC,
3345                 },
3346         };
3347
3348         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3349                                                  credentials,
3350                                                  &options1, &options2,
3351                                                  NT_STATUS_OK);
3352         talloc_free(tree0);
3353         return ret;
3354 }
3355
3356 static bool test_session_bind_negative_smb3signHtoCd(struct torture_context *tctx, struct smb2_tree *tree0)
3357 {
3358         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3359         struct cli_credentials *credentials = NULL;
3360         bool ret = false;
3361         struct smb2_transport *transport0 = tree0->session->transport;
3362         struct smbcli_options options1;
3363         struct smbcli_options options2;
3364         bool ok;
3365
3366         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3367                 torture_skip(tctx,
3368                              "Can't test without SMB 3.1.1 support");
3369         }
3370
3371         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3372                 torture_skip(tctx,
3373                              "Can't test without SMB 3.1.1 signing negotiation support");
3374         }
3375
3376         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3377         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3378         ok = cli_credentials_set_smb_encryption(credentials,
3379                                                 SMB_ENCRYPTION_REQUIRED,
3380                                                 CRED_SPECIFIED);
3381         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3382
3383         options1 = transport0->options;
3384         options1.client_guid = GUID_random();
3385         options1.min_protocol = PROTOCOL_SMB3_11;
3386         options1.max_protocol = PROTOCOL_SMB3_11;
3387         options1.signing = SMB_SIGNING_REQUIRED;
3388         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3389                 .num_algos = 1,
3390                 .algos = {
3391                         SMB2_SIGNING_HMAC_SHA256,
3392                 },
3393         };
3394
3395         /* different client guid */
3396         options2 = options1;
3397         options2.client_guid = GUID_random();
3398         options2.only_negprot = true;
3399         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3400                 .num_algos = 1,
3401                 .algos = {
3402                         SMB2_SIGNING_AES128_CMAC,
3403                 },
3404         };
3405
3406         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3407                                                  credentials,
3408                                                  &options1, &options2,
3409                                                  NT_STATUS_OK);
3410         talloc_free(tree0);
3411         return ret;
3412 }
3413
3414 static bool test_session_bind_negative_smb3signHtoGs(struct torture_context *tctx, struct smb2_tree *tree0)
3415 {
3416         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3417         struct cli_credentials *credentials = NULL;
3418         bool ret = false;
3419         struct smb2_transport *transport0 = tree0->session->transport;
3420         struct smbcli_options options1;
3421         struct smbcli_options options2;
3422         bool ok;
3423
3424         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3425                 torture_skip(tctx,
3426                              "Can't test without SMB 3.1.1 support");
3427         }
3428
3429         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3430                 torture_skip(tctx,
3431                              "Can't test without SMB 3.1.1 signing negotiation support");
3432         }
3433
3434         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3435         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3436         ok = cli_credentials_set_smb_encryption(credentials,
3437                                                 SMB_ENCRYPTION_REQUIRED,
3438                                                 CRED_SPECIFIED);
3439         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3440
3441         options1 = transport0->options;
3442         options1.client_guid = GUID_random();
3443         options1.min_protocol = PROTOCOL_SMB3_11;
3444         options1.max_protocol = PROTOCOL_SMB3_11;
3445         options1.signing = SMB_SIGNING_REQUIRED;
3446         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3447                 .num_algos = 1,
3448                 .algos = {
3449                         SMB2_SIGNING_HMAC_SHA256,
3450                 },
3451         };
3452
3453         /* same client guid */
3454         options2 = options1;
3455         options2.only_negprot = true;
3456         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3457                 .num_algos = 1,
3458                 .algos = {
3459                         SMB2_SIGNING_AES128_GMAC,
3460                 },
3461         };
3462
3463         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3464                                                  credentials,
3465                                                  &options1, &options2,
3466                                                  NT_STATUS_NOT_SUPPORTED);
3467         talloc_free(tree0);
3468         return ret;
3469 }
3470
3471 static bool test_session_bind_negative_smb3signHtoGd(struct torture_context *tctx, struct smb2_tree *tree0)
3472 {
3473         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3474         struct cli_credentials *credentials = NULL;
3475         bool ret = false;
3476         struct smb2_transport *transport0 = tree0->session->transport;
3477         struct smbcli_options options1;
3478         struct smbcli_options options2;
3479         bool ok;
3480
3481         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3482                 torture_skip(tctx,
3483                              "Can't test without SMB 3.1.1 support");
3484         }
3485
3486         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3487                 torture_skip(tctx,
3488                              "Can't test without SMB 3.1.1 signing negotiation support");
3489         }
3490
3491         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3492         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3493         ok = cli_credentials_set_smb_encryption(credentials,
3494                                                 SMB_ENCRYPTION_REQUIRED,
3495                                                 CRED_SPECIFIED);
3496         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3497
3498         options1 = transport0->options;
3499         options1.client_guid = GUID_random();
3500         options1.min_protocol = PROTOCOL_SMB3_11;
3501         options1.max_protocol = PROTOCOL_SMB3_11;
3502         options1.signing = SMB_SIGNING_REQUIRED;
3503         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3504                 .num_algos = 1,
3505                 .algos = {
3506                         SMB2_SIGNING_HMAC_SHA256,
3507                 },
3508         };
3509
3510         /* different client guid */
3511         options2 = options1;
3512         options2.client_guid = GUID_random();
3513         options2.only_negprot = true;
3514         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3515                 .num_algos = 1,
3516                 .algos = {
3517                         SMB2_SIGNING_AES128_GMAC,
3518                 },
3519         };
3520
3521         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3522                                                  credentials,
3523                                                  &options1, &options2,
3524                                                  NT_STATUS_NOT_SUPPORTED);
3525         talloc_free(tree0);
3526         return ret;
3527 }
3528
3529 static bool test_session_bind_negative_smb3signCtoGs(struct torture_context *tctx, struct smb2_tree *tree0)
3530 {
3531         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3532         struct cli_credentials *credentials = NULL;
3533         bool ret = false;
3534         struct smb2_transport *transport0 = tree0->session->transport;
3535         struct smbcli_options options1;
3536         struct smbcli_options options2;
3537         bool ok;
3538
3539         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3540                 torture_skip(tctx,
3541                              "Can't test without SMB 3.1.1 support");
3542         }
3543
3544         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3545                 torture_skip(tctx,
3546                              "Can't test without SMB 3.1.1 signing negotiation support");
3547         }
3548
3549         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3550         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3551         ok = cli_credentials_set_smb_encryption(credentials,
3552                                                 SMB_ENCRYPTION_REQUIRED,
3553                                                 CRED_SPECIFIED);
3554         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3555
3556         options1 = transport0->options;
3557         options1.client_guid = GUID_random();
3558         options1.min_protocol = PROTOCOL_SMB3_11;
3559         options1.max_protocol = PROTOCOL_SMB3_11;
3560         options1.signing = SMB_SIGNING_REQUIRED;
3561         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3562                 .num_algos = 1,
3563                 .algos = {
3564                         SMB2_SIGNING_AES128_CMAC,
3565                 },
3566         };
3567
3568         /* same client guid */
3569         options2 = options1;
3570         options2.only_negprot = true;
3571         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3572                 .num_algos = 1,
3573                 .algos = {
3574                         SMB2_SIGNING_AES128_GMAC,
3575                 },
3576         };
3577
3578         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3579                                                  credentials,
3580                                                  &options1, &options2,
3581                                                  NT_STATUS_NOT_SUPPORTED);
3582         talloc_free(tree0);
3583         return ret;
3584 }
3585
3586 static bool test_session_bind_negative_smb3signCtoGd(struct torture_context *tctx, struct smb2_tree *tree0)
3587 {
3588         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3589         struct cli_credentials *credentials = NULL;
3590         bool ret = false;
3591         struct smb2_transport *transport0 = tree0->session->transport;
3592         struct smbcli_options options1;
3593         struct smbcli_options options2;
3594         bool ok;
3595
3596         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3597                 torture_skip(tctx,
3598                              "Can't test without SMB 3.1.1 support");
3599         }
3600
3601         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3602                 torture_skip(tctx,
3603                              "Can't test without SMB 3.1.1 signing negotiation support");
3604         }
3605
3606         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3607         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3608         ok = cli_credentials_set_smb_encryption(credentials,
3609                                                 SMB_ENCRYPTION_REQUIRED,
3610                                                 CRED_SPECIFIED);
3611         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3612
3613         options1 = transport0->options;
3614         options1.client_guid = GUID_random();
3615         options1.min_protocol = PROTOCOL_SMB3_11;
3616         options1.max_protocol = PROTOCOL_SMB3_11;
3617         options1.signing = SMB_SIGNING_REQUIRED;
3618         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3619                 .num_algos = 1,
3620                 .algos = {
3621                         SMB2_SIGNING_AES128_CMAC,
3622                 },
3623         };
3624
3625         /* different client guid */
3626         options2 = options1;
3627         options2.client_guid = GUID_random();
3628         options2.only_negprot = true;
3629         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3630                 .num_algos = 1,
3631                 .algos = {
3632                         SMB2_SIGNING_AES128_GMAC,
3633                 },
3634         };
3635
3636         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3637                                                  credentials,
3638                                                  &options1, &options2,
3639                                                  NT_STATUS_NOT_SUPPORTED);
3640         talloc_free(tree0);
3641         return ret;
3642 }
3643
3644 static bool test_session_bind_negative_smb3signGtoCs(struct torture_context *tctx, struct smb2_tree *tree0)
3645 {
3646         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3647         struct cli_credentials *credentials = NULL;
3648         bool ret = false;
3649         struct smb2_transport *transport0 = tree0->session->transport;
3650         struct smbcli_options options1;
3651         struct smbcli_options options2;
3652         bool ok;
3653
3654         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3655                 torture_skip(tctx,
3656                              "Can't test without SMB 3.1.1 support");
3657         }
3658
3659         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3660                 torture_skip(tctx,
3661                              "Can't test without SMB 3.1.1 signing negotiation support");
3662         }
3663
3664         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3665         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3666         ok = cli_credentials_set_smb_encryption(credentials,
3667                                                 SMB_ENCRYPTION_REQUIRED,
3668                                                 CRED_SPECIFIED);
3669         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3670
3671         options1 = transport0->options;
3672         options1.client_guid = GUID_random();
3673         options1.min_protocol = PROTOCOL_SMB3_11;
3674         options1.max_protocol = PROTOCOL_SMB3_11;
3675         options1.signing = SMB_SIGNING_REQUIRED;
3676         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3677                 .num_algos = 1,
3678                 .algos = {
3679                         SMB2_SIGNING_AES128_GMAC,
3680                 },
3681         };
3682
3683         /* same client guid */
3684         options2 = options1;
3685         options2.only_negprot = true;
3686         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3687                 .num_algos = 1,
3688                 .algos = {
3689                         SMB2_SIGNING_AES128_CMAC,
3690                 },
3691         };
3692
3693         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3694                                                  credentials,
3695                                                  &options1, &options2,
3696                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
3697         talloc_free(tree0);
3698         return ret;
3699 }
3700
3701 static bool test_session_bind_negative_smb3signGtoCd(struct torture_context *tctx, struct smb2_tree *tree0)
3702 {
3703         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3704         struct cli_credentials *credentials = NULL;
3705         bool ret = false;
3706         struct smb2_transport *transport0 = tree0->session->transport;
3707         struct smbcli_options options1;
3708         struct smbcli_options options2;
3709         bool ok;
3710
3711         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3712                 torture_skip(tctx,
3713                              "Can't test without SMB 3.1.1 support");
3714         }
3715
3716         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3717                 torture_skip(tctx,
3718                              "Can't test without SMB 3.1.1 signing negotiation support");
3719         }
3720
3721         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3722         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3723         ok = cli_credentials_set_smb_encryption(credentials,
3724                                                 SMB_ENCRYPTION_REQUIRED,
3725                                                 CRED_SPECIFIED);
3726         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3727
3728         options1 = transport0->options;
3729         options1.client_guid = GUID_random();
3730         options1.min_protocol = PROTOCOL_SMB3_11;
3731         options1.max_protocol = PROTOCOL_SMB3_11;
3732         options1.signing = SMB_SIGNING_REQUIRED;
3733         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3734                 .num_algos = 1,
3735                 .algos = {
3736                         SMB2_SIGNING_AES128_GMAC,
3737                 },
3738         };
3739
3740         /* different client guid */
3741         options2 = options1;
3742         options2.client_guid = GUID_random();
3743         options2.only_negprot = true;
3744         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3745                 .num_algos = 1,
3746                 .algos = {
3747                         SMB2_SIGNING_AES128_CMAC,
3748                 },
3749         };
3750
3751         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3752                                                  credentials,
3753                                                  &options1, &options2,
3754                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
3755         talloc_free(tree0);
3756         return ret;
3757 }
3758
3759 static bool test_session_bind_negative_smb3signGtoHs(struct torture_context *tctx, struct smb2_tree *tree0)
3760 {
3761         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3762         struct cli_credentials *credentials = NULL;
3763         bool ret = false;
3764         struct smb2_transport *transport0 = tree0->session->transport;
3765         struct smbcli_options options1;
3766         struct smbcli_options options2;
3767         bool ok;
3768
3769         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3770                 torture_skip(tctx,
3771                              "Can't test without SMB 3.1.1 support");
3772         }
3773
3774         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3775                 torture_skip(tctx,
3776                              "Can't test without SMB 3.1.1 signing negotiation support");
3777         }
3778
3779         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3780         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3781         ok = cli_credentials_set_smb_encryption(credentials,
3782                                                 SMB_ENCRYPTION_REQUIRED,
3783                                                 CRED_SPECIFIED);
3784         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3785
3786         options1 = transport0->options;
3787         options1.client_guid = GUID_random();
3788         options1.min_protocol = PROTOCOL_SMB3_11;
3789         options1.max_protocol = PROTOCOL_SMB3_11;
3790         options1.signing = SMB_SIGNING_REQUIRED;
3791         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3792                 .num_algos = 1,
3793                 .algos = {
3794                         SMB2_SIGNING_AES128_GMAC,
3795                 },
3796         };
3797
3798         /* same client guid */
3799         options2 = options1;
3800         options2.only_negprot = true;
3801         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3802                 .num_algos = 1,
3803                 .algos = {
3804                         SMB2_SIGNING_HMAC_SHA256,
3805                 },
3806         };
3807
3808         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3809                                                  credentials,
3810                                                  &options1, &options2,
3811                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
3812         talloc_free(tree0);
3813         return ret;
3814 }
3815
3816 static bool test_session_bind_negative_smb3signGtoHd(struct torture_context *tctx, struct smb2_tree *tree0)
3817 {
3818         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3819         struct cli_credentials *credentials = NULL;
3820         bool ret = false;
3821         struct smb2_transport *transport0 = tree0->session->transport;
3822         struct smbcli_options options1;
3823         struct smbcli_options options2;
3824         bool ok;
3825
3826         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3827                 torture_skip(tctx,
3828                              "Can't test without SMB 3.1.1 support");
3829         }
3830
3831         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3832                 torture_skip(tctx,
3833                              "Can't test without SMB 3.1.1 signing negotiation support");
3834         }
3835
3836         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3837         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3838         ok = cli_credentials_set_smb_encryption(credentials,
3839                                                 SMB_ENCRYPTION_REQUIRED,
3840                                                 CRED_SPECIFIED);
3841         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3842
3843         options1 = transport0->options;
3844         options1.client_guid = GUID_random();
3845         options1.min_protocol = PROTOCOL_SMB3_11;
3846         options1.max_protocol = PROTOCOL_SMB3_11;
3847         options1.signing = SMB_SIGNING_REQUIRED;
3848         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3849                 .num_algos = 1,
3850                 .algos = {
3851                         SMB2_SIGNING_AES128_GMAC,
3852                 },
3853         };
3854
3855         /* different client guid */
3856         options2 = options1;
3857         options2.client_guid = GUID_random();
3858         options2.only_negprot = true;
3859         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3860                 .num_algos = 1,
3861                 .algos = {
3862                         SMB2_SIGNING_HMAC_SHA256,
3863                 },
3864         };
3865
3866         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3867                                                  credentials,
3868                                                  &options1, &options2,
3869                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
3870         talloc_free(tree0);
3871         return ret;
3872 }
3873
3874 static bool test_session_bind_negative_smb3sneGtoCs(struct torture_context *tctx, struct smb2_tree *tree0)
3875 {
3876         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3877         struct cli_credentials *credentials = NULL;
3878         bool ret = false;
3879         struct smb2_transport *transport0 = tree0->session->transport;
3880         struct smbcli_options options1;
3881         struct smbcli_options options2;
3882         bool ok;
3883
3884         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3885                 torture_skip(tctx,
3886                              "Can't test without SMB 3.1.1 support");
3887         }
3888
3889         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3890                 torture_skip(tctx,
3891                              "Can't test without SMB 3.1.1 signing negotiation support");
3892         }
3893
3894         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3895         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3896         ok = cli_credentials_set_smb_encryption(credentials,
3897                                                 SMB_ENCRYPTION_REQUIRED,
3898                                                 CRED_SPECIFIED);
3899         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3900
3901         options1 = transport0->options;
3902         options1.client_guid = GUID_random();
3903         options1.min_protocol = PROTOCOL_SMB3_11;
3904         options1.max_protocol = PROTOCOL_SMB3_11;
3905         options1.signing = SMB_SIGNING_REQUIRED;
3906         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3907                 .num_algos = 1,
3908                 .algos = {
3909                         SMB2_SIGNING_AES128_GMAC,
3910                 },
3911         };
3912         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3913                 .num_algos = 1,
3914                 .algos = {
3915                         SMB2_ENCRYPTION_AES128_GCM,
3916                 },
3917         };
3918
3919         /* same client guid */
3920         options2 = options1;
3921         options2.only_negprot = true;
3922         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3923                 .num_algos = 1,
3924                 .algos = {
3925                         SMB2_SIGNING_AES128_CMAC,
3926                 },
3927         };
3928         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3929                 .num_algos = 1,
3930                 .algos = {
3931                         SMB2_ENCRYPTION_AES128_CCM,
3932                 },
3933         };
3934
3935         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
3936                                                  credentials,
3937                                                  &options1, &options2,
3938                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
3939         talloc_free(tree0);
3940         return ret;
3941 }
3942
3943 static bool test_session_bind_negative_smb3sneGtoCd(struct torture_context *tctx, struct smb2_tree *tree0)
3944 {
3945         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
3946         struct cli_credentials *credentials = NULL;
3947         bool ret = false;
3948         struct smb2_transport *transport0 = tree0->session->transport;
3949         struct smbcli_options options1;
3950         struct smbcli_options options2;
3951         bool ok;
3952
3953         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
3954                 torture_skip(tctx,
3955                              "Can't test without SMB 3.1.1 support");
3956         }
3957
3958         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
3959                 torture_skip(tctx,
3960                              "Can't test without SMB 3.1.1 signing negotiation support");
3961         }
3962
3963         credentials = cli_credentials_shallow_copy(tctx, credentials0);
3964         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
3965         ok = cli_credentials_set_smb_encryption(credentials,
3966                                                 SMB_ENCRYPTION_REQUIRED,
3967                                                 CRED_SPECIFIED);
3968         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
3969
3970         options1 = transport0->options;
3971         options1.client_guid = GUID_random();
3972         options1.min_protocol = PROTOCOL_SMB3_11;
3973         options1.max_protocol = PROTOCOL_SMB3_11;
3974         options1.signing = SMB_SIGNING_REQUIRED;
3975         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3976                 .num_algos = 1,
3977                 .algos = {
3978                         SMB2_SIGNING_AES128_GMAC,
3979                 },
3980         };
3981         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3982                 .num_algos = 1,
3983                 .algos = {
3984                         SMB2_ENCRYPTION_AES128_GCM,
3985                 },
3986         };
3987
3988         /* different client guid */
3989         options2 = options1;
3990         options2.client_guid = GUID_random();
3991         options2.only_negprot = true;
3992         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
3993                 .num_algos = 1,
3994                 .algos = {
3995                         SMB2_SIGNING_AES128_CMAC,
3996                 },
3997         };
3998         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
3999                 .num_algos = 1,
4000                 .algos = {
4001                         SMB2_ENCRYPTION_AES128_CCM,
4002                 },
4003         };
4004
4005         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4006                                                  credentials,
4007                                                  &options1, &options2,
4008                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
4009         talloc_free(tree0);
4010         return ret;
4011 }
4012
4013 static bool test_session_bind_negative_smb3sneGtoHs(struct torture_context *tctx, struct smb2_tree *tree0)
4014 {
4015         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4016         struct cli_credentials *credentials = NULL;
4017         bool ret = false;
4018         struct smb2_transport *transport0 = tree0->session->transport;
4019         struct smbcli_options options1;
4020         struct smbcli_options options2;
4021         bool ok;
4022
4023         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4024                 torture_skip(tctx,
4025                              "Can't test without SMB 3.1.1 support");
4026         }
4027
4028         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4029                 torture_skip(tctx,
4030                              "Can't test without SMB 3.1.1 signing negotiation support");
4031         }
4032
4033         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4034         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4035         ok = cli_credentials_set_smb_encryption(credentials,
4036                                                 SMB_ENCRYPTION_REQUIRED,
4037                                                 CRED_SPECIFIED);
4038         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4039
4040         options1 = transport0->options;
4041         options1.client_guid = GUID_random();
4042         options1.min_protocol = PROTOCOL_SMB3_11;
4043         options1.max_protocol = PROTOCOL_SMB3_11;
4044         options1.signing = SMB_SIGNING_REQUIRED;
4045         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4046                 .num_algos = 1,
4047                 .algos = {
4048                         SMB2_SIGNING_AES128_GMAC,
4049                 },
4050         };
4051         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4052                 .num_algos = 1,
4053                 .algos = {
4054                         SMB2_ENCRYPTION_AES128_GCM,
4055                 },
4056         };
4057
4058         /* same client guid */
4059         options2 = options1;
4060         options2.only_negprot = true;
4061         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4062                 .num_algos = 1,
4063                 .algos = {
4064                         SMB2_SIGNING_HMAC_SHA256,
4065                 },
4066         };
4067         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4068                 .num_algos = 1,
4069                 .algos = {
4070                         SMB2_ENCRYPTION_AES128_CCM,
4071                 },
4072         };
4073
4074         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4075                                                  credentials,
4076                                                  &options1, &options2,
4077                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
4078         talloc_free(tree0);
4079         return ret;
4080 }
4081
4082 static bool test_session_bind_negative_smb3sneGtoHd(struct torture_context *tctx, struct smb2_tree *tree0)
4083 {
4084         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4085         struct cli_credentials *credentials = NULL;
4086         bool ret = false;
4087         struct smb2_transport *transport0 = tree0->session->transport;
4088         struct smbcli_options options1;
4089         struct smbcli_options options2;
4090         bool ok;
4091
4092         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4093                 torture_skip(tctx,
4094                              "Can't test without SMB 3.1.1 support");
4095         }
4096
4097         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4098                 torture_skip(tctx,
4099                              "Can't test without SMB 3.1.1 signing negotiation support");
4100         }
4101
4102         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4103         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4104         ok = cli_credentials_set_smb_encryption(credentials,
4105                                                 SMB_ENCRYPTION_REQUIRED,
4106                                                 CRED_SPECIFIED);
4107         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4108
4109         options1 = transport0->options;
4110         options1.client_guid = GUID_random();
4111         options1.min_protocol = PROTOCOL_SMB3_11;
4112         options1.max_protocol = PROTOCOL_SMB3_11;
4113         options1.signing = SMB_SIGNING_REQUIRED;
4114         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4115                 .num_algos = 1,
4116                 .algos = {
4117                         SMB2_SIGNING_AES128_GMAC,
4118                 },
4119         };
4120         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4121                 .num_algos = 1,
4122                 .algos = {
4123                         SMB2_ENCRYPTION_AES128_GCM,
4124                 },
4125         };
4126
4127         /* different client guid */
4128         options2 = options1;
4129         options2.client_guid = GUID_random();
4130         options2.only_negprot = true;
4131         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4132                 .num_algos = 1,
4133                 .algos = {
4134                         SMB2_SIGNING_HMAC_SHA256,
4135                 },
4136         };
4137         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4138                 .num_algos = 1,
4139                 .algos = {
4140                         SMB2_ENCRYPTION_AES128_CCM,
4141                 },
4142         };
4143
4144         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4145                                                  credentials,
4146                                                  &options1, &options2,
4147                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
4148         talloc_free(tree0);
4149         return ret;
4150 }
4151
4152 static bool test_session_bind_negative_smb3sneCtoGs(struct torture_context *tctx, struct smb2_tree *tree0)
4153 {
4154         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4155         struct cli_credentials *credentials = NULL;
4156         bool ret = false;
4157         struct smb2_transport *transport0 = tree0->session->transport;
4158         struct smbcli_options options1;
4159         struct smbcli_options options2;
4160         bool ok;
4161
4162         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4163                 torture_skip(tctx,
4164                              "Can't test without SMB 3.1.1 support");
4165         }
4166
4167         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4168                 torture_skip(tctx,
4169                              "Can't test without SMB 3.1.1 signing negotiation support");
4170         }
4171
4172         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4173         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4174         ok = cli_credentials_set_smb_encryption(credentials,
4175                                                 SMB_ENCRYPTION_REQUIRED,
4176                                                 CRED_SPECIFIED);
4177         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4178
4179         options1 = transport0->options;
4180         options1.client_guid = GUID_random();
4181         options1.min_protocol = PROTOCOL_SMB3_11;
4182         options1.max_protocol = PROTOCOL_SMB3_11;
4183         options1.signing = SMB_SIGNING_REQUIRED;
4184         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4185                 .num_algos = 1,
4186                 .algos = {
4187                         SMB2_SIGNING_AES128_CMAC,
4188                 },
4189         };
4190         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4191                 .num_algos = 1,
4192                 .algos = {
4193                         SMB2_ENCRYPTION_AES128_CCM,
4194                 },
4195         };
4196
4197         /* same client guid */
4198         options2 = options1;
4199         options2.only_negprot = true;
4200         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4201                 .num_algos = 1,
4202                 .algos = {
4203                         SMB2_SIGNING_AES128_GMAC,
4204                 },
4205         };
4206         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4207                 .num_algos = 1,
4208                 .algos = {
4209                         SMB2_ENCRYPTION_AES128_GCM,
4210                 },
4211         };
4212
4213         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4214                                                  credentials,
4215                                                  &options1, &options2,
4216                                                  NT_STATUS_NOT_SUPPORTED);
4217         talloc_free(tree0);
4218         return ret;
4219 }
4220
4221 static bool test_session_bind_negative_smb3sneCtoGd(struct torture_context *tctx, struct smb2_tree *tree0)
4222 {
4223         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4224         struct cli_credentials *credentials = NULL;
4225         bool ret = false;
4226         struct smb2_transport *transport0 = tree0->session->transport;
4227         struct smbcli_options options1;
4228         struct smbcli_options options2;
4229         bool ok;
4230
4231         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4232                 torture_skip(tctx,
4233                              "Can't test without SMB 3.1.1 support");
4234         }
4235
4236         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4237                 torture_skip(tctx,
4238                              "Can't test without SMB 3.1.1 signing negotiation support");
4239         }
4240
4241         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4242         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4243         ok = cli_credentials_set_smb_encryption(credentials,
4244                                                 SMB_ENCRYPTION_REQUIRED,
4245                                                 CRED_SPECIFIED);
4246         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4247
4248         options1 = transport0->options;
4249         options1.client_guid = GUID_random();
4250         options1.min_protocol = PROTOCOL_SMB3_11;
4251         options1.max_protocol = PROTOCOL_SMB3_11;
4252         options1.signing = SMB_SIGNING_REQUIRED;
4253         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4254                 .num_algos = 1,
4255                 .algos = {
4256                         SMB2_SIGNING_AES128_CMAC,
4257                 },
4258         };
4259         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4260                 .num_algos = 1,
4261                 .algos = {
4262                         SMB2_ENCRYPTION_AES128_CCM,
4263                 },
4264         };
4265
4266         /* different client guid */
4267         options2 = options1;
4268         options2.client_guid = GUID_random();
4269         options2.only_negprot = true;
4270         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4271                 .num_algos = 1,
4272                 .algos = {
4273                         SMB2_SIGNING_AES128_GMAC,
4274                 },
4275         };
4276         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4277                 .num_algos = 1,
4278                 .algos = {
4279                         SMB2_ENCRYPTION_AES128_GCM,
4280                 },
4281         };
4282
4283         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4284                                                  credentials,
4285                                                  &options1, &options2,
4286                                                  NT_STATUS_NOT_SUPPORTED);
4287         talloc_free(tree0);
4288         return ret;
4289 }
4290
4291 static bool test_session_bind_negative_smb3sneHtoGs(struct torture_context *tctx, struct smb2_tree *tree0)
4292 {
4293         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4294         struct cli_credentials *credentials = NULL;
4295         bool ret = false;
4296         struct smb2_transport *transport0 = tree0->session->transport;
4297         struct smbcli_options options1;
4298         struct smbcli_options options2;
4299         bool ok;
4300
4301         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4302                 torture_skip(tctx,
4303                              "Can't test without SMB 3.1.1 support");
4304         }
4305
4306         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4307                 torture_skip(tctx,
4308                              "Can't test without SMB 3.1.1 signing negotiation support");
4309         }
4310
4311         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4312         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4313         ok = cli_credentials_set_smb_encryption(credentials,
4314                                                 SMB_ENCRYPTION_REQUIRED,
4315                                                 CRED_SPECIFIED);
4316         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4317
4318         options1 = transport0->options;
4319         options1.client_guid = GUID_random();
4320         options1.min_protocol = PROTOCOL_SMB3_11;
4321         options1.max_protocol = PROTOCOL_SMB3_11;
4322         options1.signing = SMB_SIGNING_REQUIRED;
4323         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4324                 .num_algos = 1,
4325                 .algos = {
4326                         SMB2_SIGNING_HMAC_SHA256,
4327                 },
4328         };
4329         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4330                 .num_algos = 1,
4331                 .algos = {
4332                         SMB2_ENCRYPTION_AES128_CCM,
4333                 },
4334         };
4335
4336         /* same client guid */
4337         options2 = options1;
4338         options2.only_negprot = true;
4339         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4340                 .num_algos = 1,
4341                 .algos = {
4342                         SMB2_SIGNING_AES128_GMAC,
4343                 },
4344         };
4345         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4346                 .num_algos = 1,
4347                 .algos = {
4348                         SMB2_ENCRYPTION_AES128_GCM,
4349                 },
4350         };
4351
4352         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4353                                                  credentials,
4354                                                  &options1, &options2,
4355                                                  NT_STATUS_NOT_SUPPORTED);
4356         talloc_free(tree0);
4357         return ret;
4358 }
4359
4360 static bool test_session_bind_negative_smb3sneHtoGd(struct torture_context *tctx, struct smb2_tree *tree0)
4361 {
4362         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4363         struct cli_credentials *credentials = NULL;
4364         bool ret = false;
4365         struct smb2_transport *transport0 = tree0->session->transport;
4366         struct smbcli_options options1;
4367         struct smbcli_options options2;
4368         bool ok;
4369
4370         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4371                 torture_skip(tctx,
4372                              "Can't test without SMB 3.1.1 support");
4373         }
4374
4375         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4376                 torture_skip(tctx,
4377                              "Can't test without SMB 3.1.1 signing negotiation support");
4378         }
4379
4380         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4381         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4382         ok = cli_credentials_set_smb_encryption(credentials,
4383                                                 SMB_ENCRYPTION_REQUIRED,
4384                                                 CRED_SPECIFIED);
4385         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4386
4387         options1 = transport0->options;
4388         options1.client_guid = GUID_random();
4389         options1.min_protocol = PROTOCOL_SMB3_11;
4390         options1.max_protocol = PROTOCOL_SMB3_11;
4391         options1.signing = SMB_SIGNING_REQUIRED;
4392         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4393                 .num_algos = 1,
4394                 .algos = {
4395                         SMB2_SIGNING_HMAC_SHA256,
4396                 },
4397         };
4398         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4399                 .num_algos = 1,
4400                 .algos = {
4401                         SMB2_ENCRYPTION_AES128_CCM,
4402                 },
4403         };
4404
4405         /* different client guid */
4406         options2 = options1;
4407         options2.client_guid = GUID_random();
4408         options2.only_negprot = true;
4409         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4410                 .num_algos = 1,
4411                 .algos = {
4412                         SMB2_SIGNING_AES128_GMAC,
4413                 },
4414         };
4415         options2.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
4416                 .num_algos = 1,
4417                 .algos = {
4418                         SMB2_ENCRYPTION_AES128_GCM,
4419                 },
4420         };
4421
4422         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4423                                                  credentials,
4424                                                  &options1, &options2,
4425                                                  NT_STATUS_NOT_SUPPORTED);
4426         talloc_free(tree0);
4427         return ret;
4428 }
4429
4430 static bool test_session_bind_negative_smb3signC30toGs(struct torture_context *tctx, struct smb2_tree *tree0)
4431 {
4432         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4433         struct cli_credentials *credentials = NULL;
4434         bool ret = false;
4435         struct smb2_transport *transport0 = tree0->session->transport;
4436         struct smbcli_options options1;
4437         struct smbcli_options options2;
4438         bool ok;
4439
4440         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4441                 torture_skip(tctx,
4442                              "Can't test without SMB 3.1.1 support");
4443         }
4444
4445         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4446                 torture_skip(tctx,
4447                              "Can't test without SMB 3.1.1 signing negotiation support");
4448         }
4449
4450         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4451         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4452         ok = cli_credentials_set_smb_encryption(credentials,
4453                                                 SMB_ENCRYPTION_REQUIRED,
4454                                                 CRED_SPECIFIED);
4455         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4456
4457         options1 = transport0->options;
4458         options1.client_guid = GUID_random();
4459         options1.min_protocol = PROTOCOL_SMB3_00;
4460         options1.max_protocol = PROTOCOL_SMB3_02;
4461         options1.signing = SMB_SIGNING_REQUIRED;
4462
4463         /* same client guid */
4464         options2 = options1;
4465         options2.only_negprot = true;
4466         options2.min_protocol = PROTOCOL_SMB3_11;
4467         options2.max_protocol = PROTOCOL_SMB3_11;
4468         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4469                 .num_algos = 1,
4470                 .algos = {
4471                         SMB2_SIGNING_AES128_GMAC,
4472                 },
4473         };
4474
4475         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4476                                                  credentials,
4477                                                  &options1, &options2,
4478                                                  NT_STATUS_NOT_SUPPORTED);
4479         talloc_free(tree0);
4480         return ret;
4481 }
4482
4483 static bool test_session_bind_negative_smb3signC30toGd(struct torture_context *tctx, struct smb2_tree *tree0)
4484 {
4485         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4486         struct cli_credentials *credentials = NULL;
4487         bool ret = false;
4488         struct smb2_transport *transport0 = tree0->session->transport;
4489         struct smbcli_options options1;
4490         struct smbcli_options options2;
4491         bool ok;
4492
4493         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4494                 torture_skip(tctx,
4495                              "Can't test without SMB 3.1.1 support");
4496         }
4497
4498         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4499                 torture_skip(tctx,
4500                              "Can't test without SMB 3.1.1 signing negotiation support");
4501         }
4502
4503         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4504         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4505         ok = cli_credentials_set_smb_encryption(credentials,
4506                                                 SMB_ENCRYPTION_REQUIRED,
4507                                                 CRED_SPECIFIED);
4508         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4509
4510         options1 = transport0->options;
4511         options1.client_guid = GUID_random();
4512         options1.min_protocol = PROTOCOL_SMB3_00;
4513         options1.max_protocol = PROTOCOL_SMB3_02;
4514         options1.signing = SMB_SIGNING_REQUIRED;
4515
4516         /* different client guid */
4517         options2 = options1;
4518         options2.client_guid = GUID_random();
4519         options2.only_negprot = true;
4520         options2.min_protocol = PROTOCOL_SMB3_11;
4521         options2.max_protocol = PROTOCOL_SMB3_11;
4522         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4523                 .num_algos = 1,
4524                 .algos = {
4525                         SMB2_SIGNING_AES128_GMAC,
4526                 },
4527         };
4528
4529         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4530                                                  credentials,
4531                                                  &options1, &options2,
4532                                                  NT_STATUS_NOT_SUPPORTED);
4533         talloc_free(tree0);
4534         return ret;
4535 }
4536
4537 static bool test_session_bind_negative_smb3signH2XtoGs(struct torture_context *tctx, struct smb2_tree *tree0)
4538 {
4539         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4540         struct cli_credentials *credentials = NULL;
4541         bool ret = false;
4542         struct smb2_transport *transport0 = tree0->session->transport;
4543         struct smbcli_options options1;
4544         struct smbcli_options options2;
4545         bool ok;
4546         bool encrypted;
4547
4548         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
4549         if (encrypted) {
4550                 torture_skip(tctx,
4551                              "Can't test SMB 2.10 if encrytion is required");
4552         }
4553
4554         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4555                 torture_skip(tctx,
4556                              "Can't test without SMB 3.1.1 support");
4557         }
4558
4559         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4560                 torture_skip(tctx,
4561                              "Can't test without SMB 3.1.1 signing negotiation support");
4562         }
4563
4564         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4565         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4566         ok = cli_credentials_set_smb_encryption(credentials,
4567                                                 SMB_ENCRYPTION_OFF,
4568                                                 CRED_SPECIFIED);
4569         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4570
4571         options1 = transport0->options;
4572         options1.client_guid = GUID_random();
4573         options1.min_protocol = PROTOCOL_SMB2_02;
4574         options1.max_protocol = PROTOCOL_SMB2_10;
4575         options1.signing = SMB_SIGNING_REQUIRED;
4576
4577         /* same client guid */
4578         options2 = options1;
4579         options2.only_negprot = true;
4580         options2.min_protocol = PROTOCOL_SMB3_11;
4581         options2.max_protocol = PROTOCOL_SMB3_11;
4582         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4583                 .num_algos = 1,
4584                 .algos = {
4585                         SMB2_SIGNING_AES128_GMAC,
4586                 },
4587         };
4588
4589         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4590                                                  credentials,
4591                                                  &options1, &options2,
4592                                                  NT_STATUS_NOT_SUPPORTED);
4593         talloc_free(tree0);
4594         return ret;
4595 }
4596
4597 static bool test_session_bind_negative_smb3signH2XtoGd(struct torture_context *tctx, struct smb2_tree *tree0)
4598 {
4599         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4600         struct cli_credentials *credentials = NULL;
4601         bool ret = false;
4602         struct smb2_transport *transport0 = tree0->session->transport;
4603         struct smbcli_options options1;
4604         struct smbcli_options options2;
4605         bool ok;
4606         bool encrypted;
4607
4608         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
4609         if (encrypted) {
4610                 torture_skip(tctx,
4611                              "Can't test SMB 2.10 if encrytion is required");
4612         }
4613
4614         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4615                 torture_skip(tctx,
4616                              "Can't test without SMB 3.1.1 support");
4617         }
4618
4619         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4620                 torture_skip(tctx,
4621                              "Can't test without SMB 3.1.1 signing negotiation support");
4622         }
4623
4624         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4625         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4626         ok = cli_credentials_set_smb_encryption(credentials,
4627                                                 SMB_ENCRYPTION_OFF,
4628                                                 CRED_SPECIFIED);
4629         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4630
4631         options1 = transport0->options;
4632         options1.client_guid = GUID_random();
4633         options1.min_protocol = PROTOCOL_SMB2_02;
4634         options1.max_protocol = PROTOCOL_SMB2_10;
4635         options1.signing = SMB_SIGNING_REQUIRED;
4636
4637         /* different client guid */
4638         options2 = options1;
4639         options2.client_guid = GUID_random();
4640         options2.only_negprot = true;
4641         options2.min_protocol = PROTOCOL_SMB3_11;
4642         options2.max_protocol = PROTOCOL_SMB3_11;
4643         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4644                 .num_algos = 1,
4645                 .algos = {
4646                         SMB2_SIGNING_AES128_GMAC,
4647                 },
4648         };
4649
4650         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4651                                                  credentials,
4652                                                  &options1, &options2,
4653                                                  NT_STATUS_NOT_SUPPORTED);
4654         talloc_free(tree0);
4655         return ret;
4656 }
4657
4658 static bool test_session_bind_negative_smb3signGtoC30s(struct torture_context *tctx, struct smb2_tree *tree0)
4659 {
4660         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4661         struct cli_credentials *credentials = NULL;
4662         bool ret = false;
4663         struct smb2_transport *transport0 = tree0->session->transport;
4664         struct smbcli_options options1;
4665         struct smbcli_options options2;
4666         bool ok;
4667
4668         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4669                 torture_skip(tctx,
4670                              "Can't test without SMB 3.1.1 support");
4671         }
4672
4673         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4674                 torture_skip(tctx,
4675                              "Can't test without SMB 3.1.1 signing negotiation support");
4676         }
4677
4678         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4679         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4680         ok = cli_credentials_set_smb_encryption(credentials,
4681                                                 SMB_ENCRYPTION_REQUIRED,
4682                                                 CRED_SPECIFIED);
4683         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4684
4685         options1 = transport0->options;
4686         options1.client_guid = GUID_random();
4687         options1.min_protocol = PROTOCOL_SMB3_11;
4688         options1.max_protocol = PROTOCOL_SMB3_11;
4689         options1.signing = SMB_SIGNING_REQUIRED;
4690         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4691                 .num_algos = 1,
4692                 .algos = {
4693                         SMB2_SIGNING_AES128_GMAC,
4694                 },
4695         };
4696
4697         /* same client guid */
4698         options2 = options1;
4699         options2.only_negprot = true;
4700         options2.min_protocol = PROTOCOL_SMB3_00;
4701         options2.max_protocol = PROTOCOL_SMB3_02;
4702         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4703                 .num_algos = 1,
4704                 .algos = {
4705                         SMB2_SIGNING_AES128_CMAC,
4706                 },
4707         };
4708
4709         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4710                                                  credentials,
4711                                                  &options1, &options2,
4712                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
4713         talloc_free(tree0);
4714         return ret;
4715 }
4716
4717 static bool test_session_bind_negative_smb3signGtoC30d(struct torture_context *tctx, struct smb2_tree *tree0)
4718 {
4719         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4720         struct cli_credentials *credentials = NULL;
4721         bool ret = false;
4722         struct smb2_transport *transport0 = tree0->session->transport;
4723         struct smbcli_options options1;
4724         struct smbcli_options options2;
4725         bool ok;
4726
4727         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4728                 torture_skip(tctx,
4729                              "Can't test without SMB 3.1.1 support");
4730         }
4731
4732         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4733                 torture_skip(tctx,
4734                              "Can't test without SMB 3.1.1 signing negotiation support");
4735         }
4736
4737         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4738         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4739         ok = cli_credentials_set_smb_encryption(credentials,
4740                                                 SMB_ENCRYPTION_REQUIRED,
4741                                                 CRED_SPECIFIED);
4742         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4743
4744         options1 = transport0->options;
4745         options1.client_guid = GUID_random();
4746         options1.min_protocol = PROTOCOL_SMB3_11;
4747         options1.max_protocol = PROTOCOL_SMB3_11;
4748         options1.signing = SMB_SIGNING_REQUIRED;
4749         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4750                 .num_algos = 1,
4751                 .algos = {
4752                         SMB2_SIGNING_AES128_GMAC,
4753                 },
4754         };
4755
4756         /* different client guid */
4757         options2 = options1;
4758         options2.client_guid = GUID_random();
4759         options2.only_negprot = true;
4760         options2.min_protocol = PROTOCOL_SMB3_00;
4761         options2.max_protocol = PROTOCOL_SMB3_02;
4762         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4763                 .num_algos = 1,
4764                 .algos = {
4765                         SMB2_SIGNING_AES128_CMAC,
4766                 },
4767         };
4768
4769         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4770                                                  credentials,
4771                                                  &options1, &options2,
4772                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
4773         talloc_free(tree0);
4774         return ret;
4775 }
4776
4777 static bool test_session_bind_negative_smb3signGtoH2Xs(struct torture_context *tctx, struct smb2_tree *tree0)
4778 {
4779         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4780         struct cli_credentials *credentials = NULL;
4781         bool ret = false;
4782         struct smb2_transport *transport0 = tree0->session->transport;
4783         struct smbcli_options options1;
4784         struct smbcli_options options2;
4785         bool ok;
4786         bool encrypted;
4787
4788         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
4789         if (encrypted) {
4790                 torture_skip(tctx,
4791                              "Can't test SMB 2.10 if encrytion is required");
4792         }
4793
4794         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4795                 torture_skip(tctx,
4796                              "Can't test without SMB 3.1.1 support");
4797         }
4798
4799         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4800                 torture_skip(tctx,
4801                              "Can't test without SMB 3.1.1 signing negotiation support");
4802         }
4803
4804         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4805         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4806         ok = cli_credentials_set_smb_encryption(credentials,
4807                                                 SMB_ENCRYPTION_REQUIRED,
4808                                                 CRED_SPECIFIED);
4809         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4810
4811         options1 = transport0->options;
4812         options1.client_guid = GUID_random();
4813         options1.min_protocol = PROTOCOL_SMB3_11;
4814         options1.max_protocol = PROTOCOL_SMB3_11;
4815         options1.signing = SMB_SIGNING_REQUIRED;
4816         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4817                 .num_algos = 1,
4818                 .algos = {
4819                         SMB2_SIGNING_AES128_GMAC,
4820                 },
4821         };
4822
4823         /* same client guid */
4824         options2 = options1;
4825         options2.only_negprot = true;
4826         options2.min_protocol = PROTOCOL_SMB2_02;
4827         options2.max_protocol = PROTOCOL_SMB2_10;
4828         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4829                 .num_algos = 1,
4830                 .algos = {
4831                         SMB2_SIGNING_HMAC_SHA256,
4832                 },
4833         };
4834
4835         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4836                                                  credentials,
4837                                                  &options1, &options2,
4838                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
4839         talloc_free(tree0);
4840         return ret;
4841 }
4842
4843 static bool test_session_bind_negative_smb3signGtoH2Xd(struct torture_context *tctx, struct smb2_tree *tree0)
4844 {
4845         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
4846         struct cli_credentials *credentials = NULL;
4847         bool ret = false;
4848         struct smb2_transport *transport0 = tree0->session->transport;
4849         struct smbcli_options options1;
4850         struct smbcli_options options2;
4851         bool ok;
4852         bool encrypted;
4853
4854         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
4855         if (encrypted) {
4856                 torture_skip(tctx,
4857                              "Can't test SMB 2.10 if encrytion is required");
4858         }
4859
4860         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
4861                 torture_skip(tctx,
4862                              "Can't test without SMB 3.1.1 support");
4863         }
4864
4865         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
4866                 torture_skip(tctx,
4867                              "Can't test without SMB 3.1.1 signing negotiation support");
4868         }
4869
4870         credentials = cli_credentials_shallow_copy(tctx, credentials0);
4871         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
4872         ok = cli_credentials_set_smb_encryption(credentials,
4873                                                 SMB_ENCRYPTION_REQUIRED,
4874                                                 CRED_SPECIFIED);
4875         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
4876
4877         options1 = transport0->options;
4878         options1.client_guid = GUID_random();
4879         options1.min_protocol = PROTOCOL_SMB3_11;
4880         options1.max_protocol = PROTOCOL_SMB3_11;
4881         options1.signing = SMB_SIGNING_REQUIRED;
4882         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4883                 .num_algos = 1,
4884                 .algos = {
4885                         SMB2_SIGNING_AES128_GMAC,
4886                 },
4887         };
4888
4889         /* different client guid */
4890         options2 = options1;
4891         options2.client_guid = GUID_random();
4892         options2.only_negprot = true;
4893         options2.min_protocol = PROTOCOL_SMB2_02;
4894         options2.max_protocol = PROTOCOL_SMB2_10;
4895         options2.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
4896                 .num_algos = 1,
4897                 .algos = {
4898                         SMB2_SIGNING_HMAC_SHA256,
4899                 },
4900         };
4901
4902         ret = test_session_bind_negative_smbXtoX(tctx, __func__,
4903                                                  credentials,
4904                                                  &options1, &options2,
4905                                                  NT_STATUS_REQUEST_OUT_OF_SEQUENCE);
4906         talloc_free(tree0);
4907         return ret;
4908 }
4909
4910 static bool test_session_two_logoff(struct torture_context *tctx,
4911                                     struct smb2_tree *tree1)
4912 {
4913         NTSTATUS status;
4914         bool ret = true;
4915         struct smbcli_options transport2_options;
4916         struct smb2_tree *tree2 = NULL;
4917         struct smb2_session *session2 = NULL;
4918         struct smb2_session *session1 = tree1->session;
4919         struct smb2_transport *transport1 = tree1->session->transport;
4920         struct smb2_transport *transport2;
4921         bool ok;
4922
4923         /* Connect 2nd connection */
4924         torture_comment(tctx, "connect tree2 with the same client_guid\n");
4925         transport2_options = transport1->options;
4926         ok = torture_smb2_connection_ext(tctx, 0, &transport2_options, &tree2);
4927         torture_assert(tctx, ok, "couldn't connect tree2\n");
4928         transport2 = tree2->session->transport;
4929         session2 = tree2->session;
4930
4931         torture_comment(tctx, "session2: logoff\n");
4932         status = smb2_logoff(session2);
4933         torture_assert_ntstatus_ok(tctx, status, "session2: logoff");
4934         torture_comment(tctx, "transport2: keepalive\n");
4935         status = smb2_keepalive(transport2);
4936         torture_assert_ntstatus_ok(tctx, status, "transport2: keepalive");
4937         torture_comment(tctx, "transport2: disconnect\n");
4938         TALLOC_FREE(tree2);
4939
4940         torture_comment(tctx, "session1: logoff\n");
4941         status = smb2_logoff(session1);
4942         torture_assert_ntstatus_ok(tctx, status, "session1: logoff");
4943         torture_comment(tctx, "transport1: keepalive\n");
4944         status = smb2_keepalive(transport1);
4945         torture_assert_ntstatus_ok(tctx, status, "transport1: keepalive");
4946         torture_comment(tctx, "transport1: disconnect\n");
4947         TALLOC_FREE(tree1);
4948
4949         return ret;
4950 }
4951
4952 static bool test_session_sign_enc(struct torture_context *tctx,
4953                                   const char *testname,
4954                                   struct cli_credentials *credentials1,
4955                                   const struct smbcli_options *options1)
4956 {
4957         const char *host = torture_setting_string(tctx, "host", NULL);
4958         const char *share = torture_setting_string(tctx, "share", NULL);
4959         NTSTATUS status;
4960         bool ret = false;
4961         struct smb2_tree *tree1 = NULL;
4962         char fname[256];
4963         struct smb2_handle rh = {{0}};
4964         struct smb2_handle _h1;
4965         struct smb2_handle *h1 = NULL;
4966         struct smb2_create io1;
4967         union smb_fileinfo qfinfo1;
4968         union smb_notify notify;
4969         struct smb2_request *req = NULL;
4970
4971         status = smb2_connect(tctx,
4972                               host,
4973                               lpcfg_smb_ports(tctx->lp_ctx),
4974                               share,
4975                               lpcfg_resolve_context(tctx->lp_ctx),
4976                               credentials1,
4977                               &tree1,
4978                               tctx->ev,
4979                               options1,
4980                               lpcfg_socket_options(tctx->lp_ctx),
4981                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
4982                               );
4983         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4984                                         "smb2_connect options1 failed");
4985
4986         status = smb2_util_roothandle(tree1, &rh);
4987         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
4988                                         "smb2_util_roothandle failed");
4989
4990         /* Add some random component to the file name. */
4991         snprintf(fname, sizeof(fname), "%s_%s.dat",
4992                  testname, generate_random_str(tctx, 8));
4993
4994         smb2_util_unlink(tree1, fname);
4995
4996         smb2_oplock_create_share(&io1, fname,
4997                                  smb2_util_share_access(""),
4998                                  smb2_util_oplock_level("b"));
4999
5000         io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE;
5001         status = smb2_create(tree1, tctx, &io1);
5002         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5003                                         "smb2_create failed");
5004         _h1 = io1.out.file.handle;
5005         h1 = &_h1;
5006         CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE);
5007         torture_assert_int_equal(tctx, io1.out.oplock_level,
5008                                         smb2_util_oplock_level("b"),
5009                                         "oplock_level incorrect");
5010
5011         /* Check the initial session is still alive */
5012         ZERO_STRUCT(qfinfo1);
5013         qfinfo1.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
5014         qfinfo1.generic.in.file.handle = _h1;
5015         status = smb2_getinfo_file(tree1, tctx, &qfinfo1);
5016         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5017                                         "smb2_getinfo_file failed");
5018
5019         /* ask for a change notify,
5020            on file or directory name changes */
5021         ZERO_STRUCT(notify);
5022         notify.smb2.level = RAW_NOTIFY_SMB2;
5023         notify.smb2.in.buffer_size = 1000;
5024         notify.smb2.in.completion_filter = FILE_NOTIFY_CHANGE_NAME;
5025         notify.smb2.in.file.handle = rh;
5026         notify.smb2.in.recursive = true;
5027
5028         req = smb2_notify_send(tree1, &(notify.smb2));
5029         WAIT_FOR_ASYNC_RESPONSE(req);
5030
5031         status = smb2_cancel(req);
5032         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5033                                         "smb2_cancel failed");
5034
5035         status = smb2_notify_recv(req, tctx, &(notify.smb2));
5036         torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_CANCELLED,
5037                                            ret, done,
5038                                            "smb2_notify_recv failed");
5039
5040         /* Check the initial session is still alive */
5041         ZERO_STRUCT(qfinfo1);
5042         qfinfo1.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
5043         qfinfo1.generic.in.file.handle = _h1;
5044         status = smb2_getinfo_file(tree1, tctx, &qfinfo1);
5045         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
5046                                         "smb2_getinfo_file failed");
5047
5048         ret = true;
5049 done:
5050         if (h1 != NULL) {
5051                 smb2_util_close(tree1, *h1);
5052         }
5053         TALLOC_FREE(tree1);
5054
5055         return ret;
5056 }
5057
5058 static bool test_session_signing_hmac_sha_256(struct torture_context *tctx, struct smb2_tree *tree0)
5059 {
5060         struct cli_credentials *credentials = samba_cmdline_get_creds();
5061         bool ret = false;
5062         struct smb2_transport *transport0 = tree0->session->transport;
5063         struct smbcli_options options1;
5064         bool encrypted;
5065
5066         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
5067         if (encrypted) {
5068                 torture_skip(tctx,
5069                              "Can't test signing only if encrytion is required");
5070         }
5071
5072         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
5073                 torture_skip(tctx,
5074                              "Can't test without SMB 3.1.1 support");
5075         }
5076
5077         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
5078                 torture_skip(tctx,
5079                              "Can't test without SMB 3.1.1 signing negotiation support");
5080         }
5081
5082         options1 = transport0->options;
5083         options1.client_guid = GUID_random();
5084         options1.min_protocol = PROTOCOL_SMB3_11;
5085         options1.max_protocol = PROTOCOL_SMB3_11;
5086         options1.signing = SMB_SIGNING_REQUIRED;
5087         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
5088                 .num_algos = 1,
5089                 .algos = {
5090                         SMB2_SIGNING_HMAC_SHA256,
5091                 },
5092         };
5093
5094         ret = test_session_sign_enc(tctx,
5095                                     __func__,
5096                                     credentials,
5097                                     &options1);
5098         TALLOC_FREE(tree0);
5099         return ret;
5100 }
5101
5102 static bool test_session_signing_aes_128_cmac(struct torture_context *tctx, struct smb2_tree *tree0)
5103 {
5104         struct cli_credentials *credentials = samba_cmdline_get_creds();
5105         bool ret = false;
5106         struct smb2_transport *transport0 = tree0->session->transport;
5107         struct smbcli_options options1;
5108         bool encrypted;
5109
5110         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
5111         if (encrypted) {
5112                 torture_skip(tctx,
5113                              "Can't test signing only if encrytion is required");
5114         }
5115
5116         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
5117                 torture_skip(tctx,
5118                              "Can't test without SMB 3.1.1 support");
5119         }
5120
5121         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
5122                 torture_skip(tctx,
5123                              "Can't test without SMB 3.1.1 signing negotiation support");
5124         }
5125
5126         options1 = transport0->options;
5127         options1.client_guid = GUID_random();
5128         options1.min_protocol = PROTOCOL_SMB3_11;
5129         options1.max_protocol = PROTOCOL_SMB3_11;
5130         options1.signing = SMB_SIGNING_REQUIRED;
5131         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
5132                 .num_algos = 1,
5133                 .algos = {
5134                         SMB2_SIGNING_AES128_CMAC,
5135                 },
5136         };
5137
5138         ret = test_session_sign_enc(tctx,
5139                                     __func__,
5140                                     credentials,
5141                                     &options1);
5142         TALLOC_FREE(tree0);
5143         return ret;
5144 }
5145
5146 static bool test_session_signing_aes_128_gmac(struct torture_context *tctx, struct smb2_tree *tree0)
5147 {
5148         struct cli_credentials *credentials = samba_cmdline_get_creds();
5149         bool ret = false;
5150         struct smb2_transport *transport0 = tree0->session->transport;
5151         struct smbcli_options options1;
5152         bool encrypted;
5153
5154         encrypted = smb2cli_tcon_is_encryption_on(tree0->smbXcli);
5155         if (encrypted) {
5156                 torture_skip(tctx,
5157                              "Can't test signing only if encrytion is required");
5158         }
5159
5160         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
5161                 torture_skip(tctx,
5162                              "Can't test without SMB 3.1.1 support");
5163         }
5164
5165         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
5166                 torture_skip(tctx,
5167                              "Can't test without SMB 3.1.1 signing negotiation support");
5168         }
5169
5170         options1 = transport0->options;
5171         options1.client_guid = GUID_random();
5172         options1.min_protocol = PROTOCOL_SMB3_11;
5173         options1.max_protocol = PROTOCOL_SMB3_11;
5174         options1.signing = SMB_SIGNING_REQUIRED;
5175         options1.smb3_capabilities.signing = (struct smb3_signing_capabilities) {
5176                 .num_algos = 1,
5177                 .algos = {
5178                         SMB2_SIGNING_AES128_GMAC,
5179                 },
5180         };
5181
5182         ret = test_session_sign_enc(tctx,
5183                                     __func__,
5184                                     credentials,
5185                                     &options1);
5186         TALLOC_FREE(tree0);
5187         return ret;
5188 }
5189
5190 static bool test_session_encryption_aes_128_ccm(struct torture_context *tctx, struct smb2_tree *tree0)
5191 {
5192         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
5193         struct cli_credentials *credentials = NULL;
5194         bool ret = false;
5195         struct smb2_transport *transport0 = tree0->session->transport;
5196         struct smbcli_options options1;
5197         bool ok;
5198
5199         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
5200                 torture_skip(tctx,
5201                              "Can't test without SMB 3.1.1 support");
5202         }
5203
5204         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
5205                 torture_skip(tctx,
5206                              "Can't test without SMB 3.1.1 signing negotiation support");
5207         }
5208
5209         credentials = cli_credentials_shallow_copy(tctx, credentials0);
5210         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
5211         ok = cli_credentials_set_smb_encryption(credentials,
5212                                                 SMB_ENCRYPTION_REQUIRED,
5213                                                 CRED_SPECIFIED);
5214         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
5215
5216         options1 = transport0->options;
5217         options1.client_guid = GUID_random();
5218         options1.min_protocol = PROTOCOL_SMB3_11;
5219         options1.max_protocol = PROTOCOL_SMB3_11;
5220         options1.signing = SMB_SIGNING_REQUIRED;
5221         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
5222                 .num_algos = 1,
5223                 .algos = {
5224                         SMB2_ENCRYPTION_AES128_CCM,
5225                 },
5226         };
5227
5228         ret = test_session_sign_enc(tctx,
5229                                     __func__,
5230                                     credentials,
5231                                     &options1);
5232         TALLOC_FREE(tree0);
5233         return ret;
5234 }
5235
5236 static bool test_session_encryption_aes_128_gcm(struct torture_context *tctx, struct smb2_tree *tree0)
5237 {
5238         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
5239         struct cli_credentials *credentials = NULL;
5240         bool ret = false;
5241         struct smb2_transport *transport0 = tree0->session->transport;
5242         struct smbcli_options options1;
5243         bool ok;
5244
5245         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
5246                 torture_skip(tctx,
5247                              "Can't test without SMB 3.1.1 support");
5248         }
5249
5250         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
5251                 torture_skip(tctx,
5252                              "Can't test without SMB 3.1.1 signing negotiation support");
5253         }
5254
5255         credentials = cli_credentials_shallow_copy(tctx, credentials0);
5256         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
5257         ok = cli_credentials_set_smb_encryption(credentials,
5258                                                 SMB_ENCRYPTION_REQUIRED,
5259                                                 CRED_SPECIFIED);
5260         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
5261
5262         options1 = transport0->options;
5263         options1.client_guid = GUID_random();
5264         options1.min_protocol = PROTOCOL_SMB3_11;
5265         options1.max_protocol = PROTOCOL_SMB3_11;
5266         options1.signing = SMB_SIGNING_REQUIRED;
5267         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
5268                 .num_algos = 1,
5269                 .algos = {
5270                         SMB2_ENCRYPTION_AES128_GCM,
5271                 },
5272         };
5273
5274         ret = test_session_sign_enc(tctx,
5275                                     __func__,
5276                                     credentials,
5277                                     &options1);
5278         TALLOC_FREE(tree0);
5279         return ret;
5280 }
5281
5282 static bool test_session_encryption_aes_256_ccm(struct torture_context *tctx, struct smb2_tree *tree0)
5283 {
5284         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
5285         struct cli_credentials *credentials = NULL;
5286         bool ret = false;
5287         struct smb2_transport *transport0 = tree0->session->transport;
5288         struct smbcli_options options1;
5289         bool ok;
5290
5291         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
5292                 torture_skip(tctx,
5293                              "Can't test without SMB 3.1.1 support");
5294         }
5295
5296         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
5297                 torture_skip(tctx,
5298                              "Can't test without SMB 3.1.1 signing negotiation support");
5299         }
5300
5301         credentials = cli_credentials_shallow_copy(tctx, credentials0);
5302         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
5303         ok = cli_credentials_set_smb_encryption(credentials,
5304                                                 SMB_ENCRYPTION_REQUIRED,
5305                                                 CRED_SPECIFIED);
5306         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
5307
5308         options1 = transport0->options;
5309         options1.client_guid = GUID_random();
5310         options1.min_protocol = PROTOCOL_SMB3_11;
5311         options1.max_protocol = PROTOCOL_SMB3_11;
5312         options1.signing = SMB_SIGNING_REQUIRED;
5313         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
5314                 .num_algos = 1,
5315                 .algos = {
5316                         SMB2_ENCRYPTION_AES256_CCM,
5317                 },
5318         };
5319
5320         ret = test_session_sign_enc(tctx,
5321                                     __func__,
5322                                     credentials,
5323                                     &options1);
5324         TALLOC_FREE(tree0);
5325         return ret;
5326 }
5327
5328 static bool test_session_encryption_aes_256_gcm(struct torture_context *tctx, struct smb2_tree *tree0)
5329 {
5330         struct cli_credentials *credentials0 = samba_cmdline_get_creds();
5331         struct cli_credentials *credentials = NULL;
5332         bool ret = false;
5333         struct smb2_transport *transport0 = tree0->session->transport;
5334         struct smbcli_options options1;
5335         bool ok;
5336
5337         if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_11) {
5338                 torture_skip(tctx,
5339                              "Can't test without SMB 3.1.1 support");
5340         }
5341
5342         if (smb2cli_conn_server_signing_algo(transport0->conn) < SMB2_SIGNING_AES128_GMAC) {
5343                 torture_skip(tctx,
5344                              "Can't test without SMB 3.1.1 signing negotiation support");
5345         }
5346
5347         credentials = cli_credentials_shallow_copy(tctx, credentials0);
5348         torture_assert(tctx, credentials != NULL, "cli_credentials_shallow_copy");
5349         ok = cli_credentials_set_smb_encryption(credentials,
5350                                                 SMB_ENCRYPTION_REQUIRED,
5351                                                 CRED_SPECIFIED);
5352         torture_assert(tctx, ok, "cli_credentials_set_smb_encryption");
5353
5354         options1 = transport0->options;
5355         options1.client_guid = GUID_random();
5356         options1.min_protocol = PROTOCOL_SMB3_11;
5357         options1.max_protocol = PROTOCOL_SMB3_11;
5358         options1.signing = SMB_SIGNING_REQUIRED;
5359         options1.smb3_capabilities.encryption = (struct smb3_encryption_capabilities) {
5360                 .num_algos = 1,
5361                 .algos = {
5362                         SMB2_ENCRYPTION_AES256_GCM,
5363                 },
5364         };
5365
5366         ret = test_session_sign_enc(tctx,
5367                                     __func__,
5368                                     credentials,
5369                                     &options1);
5370         TALLOC_FREE(tree0);
5371         return ret;
5372 }
5373
5374 static bool test_session_ntlmssp_bug14932(struct torture_context *tctx, struct smb2_tree *tree)
5375 {
5376         struct cli_credentials *ntlm_creds =
5377                 cli_credentials_shallow_copy(tctx, samba_cmdline_get_creds());
5378         NTSTATUS status;
5379         bool ret = true;
5380         /*
5381          * This is a NTLMv2_RESPONSE with the strange
5382          * NTLMv2_CLIENT_CHALLENGE used by the net diag
5383          * tool.
5384          *
5385          * As we expect an error anyway we fill the
5386          * Response part with 0xab...
5387          */
5388         static const char *netapp_magic =
5389                 "\xab\xab\xab\xab\xab\xab\xab\xab"
5390                 "\xab\xab\xab\xab\xab\xab\xab\xab"
5391                 "\x01\x01\x00\x00\x00\x00\x00\x00"
5392                 "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f"
5393                 "\xb8\x82\x3a\xf1\xb3\xdd\x08\x15"
5394                 "\x00\x00\x00\x00\x11\xa2\x08\x81"
5395                 "\x50\x38\x22\x78\x2b\x94\x47\xfe"
5396                 "\x54\x94\x7b\xff\x17\x27\x5a\xb4"
5397                 "\xf4\x18\xba\xdc\x2c\x38\xfd\x5b"
5398                 "\xfb\x0e\xc1\x85\x1e\xcc\x92\xbb"
5399                 "\x9b\xb1\xc4\xd5\x53\x14\xff\x8c"
5400                 "\x76\x49\xf5\x45\x90\x19\xa2";
5401         DATA_BLOB lm_response = data_blob_talloc_zero(tctx, 24);
5402         DATA_BLOB lm_session_key = data_blob_talloc_zero(tctx, 16);
5403         DATA_BLOB nt_response = data_blob_const(netapp_magic, 95);
5404         DATA_BLOB nt_session_key = data_blob_talloc_zero(tctx, 16);
5405
5406         cli_credentials_set_kerberos_state(ntlm_creds,
5407                                            CRED_USE_KERBEROS_DISABLED,
5408                                            CRED_SPECIFIED);
5409         cli_credentials_set_ntlm_response(ntlm_creds,
5410                                           &lm_response,
5411                                           &lm_session_key,
5412                                           &nt_response,
5413                                           &nt_session_key,
5414                                           CRED_SPECIFIED);
5415         status = smb2_session_setup_spnego(tree->session,
5416                                            ntlm_creds,
5417                                            0 /* previous_session_id */);
5418         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER,
5419                                       "smb2_session_setup_spnego failed");
5420
5421         return ret;
5422 }
5423
5424 struct torture_suite *torture_smb2_session_init(TALLOC_CTX *ctx)
5425 {
5426         struct torture_suite *suite =
5427             torture_suite_create(ctx, "session");
5428
5429         torture_suite_add_1smb2_test(suite, "reconnect1", test_session_reconnect1);
5430         torture_suite_add_1smb2_test(suite, "reconnect2", test_session_reconnect2);
5431         torture_suite_add_1smb2_test(suite, "reauth1", test_session_reauth1);
5432         torture_suite_add_1smb2_test(suite, "reauth2", test_session_reauth2);
5433         torture_suite_add_1smb2_test(suite, "reauth3", test_session_reauth3);
5434         torture_suite_add_1smb2_test(suite, "reauth4", test_session_reauth4);
5435         torture_suite_add_1smb2_test(suite, "reauth5", test_session_reauth5);
5436         torture_suite_add_1smb2_test(suite, "reauth6", test_session_reauth6);
5437         torture_suite_add_simple_test(suite, "expire1n", test_session_expire1n);
5438         torture_suite_add_simple_test(suite, "expire1s", test_session_expire1s);
5439         torture_suite_add_simple_test(suite, "expire1e", test_session_expire1e);
5440         torture_suite_add_simple_test(suite, "expire2s", test_session_expire2s);
5441         torture_suite_add_simple_test(suite, "expire2e", test_session_expire2e);
5442         torture_suite_add_simple_test(suite, "expire_disconnect",
5443                                       test_session_expire_disconnect);
5444         torture_suite_add_1smb2_test(suite, "bind1", test_session_bind1);
5445         torture_suite_add_1smb2_test(suite, "bind2", test_session_bind2);
5446         torture_suite_add_1smb2_test(suite, "bind_invalid_auth", test_session_bind_invalid_auth);
5447         torture_suite_add_1smb2_test(suite, "bind_different_user", test_session_bind_different_user);
5448         torture_suite_add_1smb2_test(suite, "bind_negative_smb202", test_session_bind_negative_smb202);
5449         torture_suite_add_1smb2_test(suite, "bind_negative_smb210s", test_session_bind_negative_smb210s);
5450         torture_suite_add_1smb2_test(suite, "bind_negative_smb210d", test_session_bind_negative_smb210d);
5451         torture_suite_add_1smb2_test(suite, "bind_negative_smb2to3s", test_session_bind_negative_smb2to3s);
5452         torture_suite_add_1smb2_test(suite, "bind_negative_smb2to3d", test_session_bind_negative_smb2to3d);
5453         torture_suite_add_1smb2_test(suite, "bind_negative_smb3to2s", test_session_bind_negative_smb3to2s);
5454         torture_suite_add_1smb2_test(suite, "bind_negative_smb3to2d", test_session_bind_negative_smb3to2d);
5455         torture_suite_add_1smb2_test(suite, "bind_negative_smb3to3s", test_session_bind_negative_smb3to3s);
5456         torture_suite_add_1smb2_test(suite, "bind_negative_smb3to3d", test_session_bind_negative_smb3to3d);
5457         torture_suite_add_1smb2_test(suite, "bind_negative_smb3encGtoCs", test_session_bind_negative_smb3encGtoCs);
5458         torture_suite_add_1smb2_test(suite, "bind_negative_smb3encGtoCd", test_session_bind_negative_smb3encGtoCd);
5459         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signCtoHs", test_session_bind_negative_smb3signCtoHs);
5460         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signCtoHd", test_session_bind_negative_smb3signCtoHd);
5461         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signCtoGs", test_session_bind_negative_smb3signCtoGs);
5462         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signCtoGd", test_session_bind_negative_smb3signCtoGd);
5463         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signHtoCs", test_session_bind_negative_smb3signHtoCs);
5464         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signHtoCd", test_session_bind_negative_smb3signHtoCd);
5465         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signHtoGs", test_session_bind_negative_smb3signHtoGs);
5466         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signHtoGd", test_session_bind_negative_smb3signHtoGd);
5467         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoCs", test_session_bind_negative_smb3signGtoCs);
5468         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoCd", test_session_bind_negative_smb3signGtoCd);
5469         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoHs", test_session_bind_negative_smb3signGtoHs);
5470         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoHd", test_session_bind_negative_smb3signGtoHd);
5471         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneGtoCs", test_session_bind_negative_smb3sneGtoCs);
5472         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneGtoCd", test_session_bind_negative_smb3sneGtoCd);
5473         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneGtoHs", test_session_bind_negative_smb3sneGtoHs);
5474         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneGtoHd", test_session_bind_negative_smb3sneGtoHd);
5475         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneCtoGs", test_session_bind_negative_smb3sneCtoGs);
5476         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneCtoGd", test_session_bind_negative_smb3sneCtoGd);
5477         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneHtoGs", test_session_bind_negative_smb3sneHtoGs);
5478         torture_suite_add_1smb2_test(suite, "bind_negative_smb3sneHtoGd", test_session_bind_negative_smb3sneHtoGd);
5479         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signC30toGs", test_session_bind_negative_smb3signC30toGs);
5480         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signC30toGd", test_session_bind_negative_smb3signC30toGd);
5481         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signH2XtoGs", test_session_bind_negative_smb3signH2XtoGs);
5482         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signH2XtoGd", test_session_bind_negative_smb3signH2XtoGd);
5483         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoC30s", test_session_bind_negative_smb3signGtoC30s);
5484         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoC30d", test_session_bind_negative_smb3signGtoC30d);
5485         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoH2Xs", test_session_bind_negative_smb3signGtoH2Xs);
5486         torture_suite_add_1smb2_test(suite, "bind_negative_smb3signGtoH2Xd", test_session_bind_negative_smb3signGtoH2Xd);
5487         torture_suite_add_1smb2_test(suite, "two_logoff", test_session_two_logoff);
5488         torture_suite_add_1smb2_test(suite, "signing-hmac-sha-256", test_session_signing_hmac_sha_256);
5489         torture_suite_add_1smb2_test(suite, "signing-aes-128-cmac", test_session_signing_aes_128_cmac);
5490         torture_suite_add_1smb2_test(suite, "signing-aes-128-gmac", test_session_signing_aes_128_gmac);
5491         torture_suite_add_1smb2_test(suite, "encryption-aes-128-ccm", test_session_encryption_aes_128_ccm);
5492         torture_suite_add_1smb2_test(suite, "encryption-aes-128-gcm", test_session_encryption_aes_128_gcm);
5493         torture_suite_add_1smb2_test(suite, "encryption-aes-256-ccm", test_session_encryption_aes_256_ccm);
5494         torture_suite_add_1smb2_test(suite, "encryption-aes-256-gcm", test_session_encryption_aes_256_gcm);
5495         torture_suite_add_1smb2_test(suite, "ntlmssp_bug14932", test_session_ntlmssp_bug14932);
5496
5497         suite->description = talloc_strdup(suite, "SMB2-SESSION tests");
5498
5499         return suite;
5500 }