s3:torture/test_smb2: do a reauth over multiple channels in SMB2-MULTI-CHANNEL
[ddiss/samba.git] / source3 / torture / test_smb2.c
1 /*
2    Unix SMB/CIFS implementation.
3    Initial test for the smb2 client lib
4    Copyright (C) Volker Lendecke 2011
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "torture/proto.h"
22 #include "client.h"
23 #include "../libcli/smb/smbXcli_base.h"
24 #include "libsmb/smb2cli.h"
25 #include "libcli/security/security.h"
26 #include "libsmb/proto.h"
27 #include "auth/gensec/gensec.h"
28 #include "auth_generic.h"
29
30 extern fstring host, workgroup, share, password, username, myname;
31
32 bool run_smb2_basic(int dummy)
33 {
34         struct cli_state *cli;
35         NTSTATUS status;
36         uint64_t fid_persistent, fid_volatile;
37         const char *hello = "Hello, world\n";
38         uint8_t *result;
39         uint32_t nread;
40         uint8_t *dir_data;
41         uint32_t dir_data_length;
42         uint32_t saved_tid = 0;
43         uint64_t saved_uid = 0;
44
45         printf("Starting SMB2-BASIC\n");
46
47         if (!torture_init_connection(&cli)) {
48                 return false;
49         }
50         cli->smb2.pid = 0xFEFF;
51
52         status = smbXcli_negprot(cli->conn, cli->timeout,
53                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
54         if (!NT_STATUS_IS_OK(status)) {
55                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
56                 return false;
57         }
58
59         status = cli_session_setup(cli, username,
60                                    password, strlen(password),
61                                    password, strlen(password),
62                                    workgroup);
63         if (!NT_STATUS_IS_OK(status)) {
64                 printf("cli_session_setup returned %s\n", nt_errstr(status));
65                 return false;
66         }
67
68         status = cli_tree_connect(cli, share, "?????", "", 0);
69         if (!NT_STATUS_IS_OK(status)) {
70                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
71                 return false;
72         }
73
74         status = smb2cli_create(cli, "smb2-basic.txt",
75                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
76                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
77                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
78                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
79                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
80                         FILE_CREATE, /* create_disposition, */
81                         FILE_DELETE_ON_CLOSE, /* create_options, */
82                         NULL, /* smb2_create_blobs *blobs */
83                         &fid_persistent,
84                         &fid_volatile);
85         if (!NT_STATUS_IS_OK(status)) {
86                 printf("smb2cli_create returned %s\n", nt_errstr(status));
87                 return false;
88         }
89
90         status = smb2cli_write(cli, strlen(hello), 0, fid_persistent,
91                                fid_volatile, 0, 0, (const uint8_t *)hello);
92         if (!NT_STATUS_IS_OK(status)) {
93                 printf("smb2cli_write returned %s\n", nt_errstr(status));
94                 return false;
95         }
96
97         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
98         if (!NT_STATUS_IS_OK(status)) {
99                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
100                 return false;
101         }
102
103         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
104                                fid_volatile, 2, 0,
105                                talloc_tos(), &result, &nread);
106         if (!NT_STATUS_IS_OK(status)) {
107                 printf("smb2cli_read returned %s\n", nt_errstr(status));
108                 return false;
109         }
110
111         if (nread != strlen(hello)) {
112                 printf("smb2cli_read returned %d bytes, expected %d\n",
113                        (int)nread, (int)strlen(hello));
114                 return false;
115         }
116
117         if (memcmp(hello, result, nread) != 0) {
118                 printf("smb2cli_read returned '%s', expected '%s'\n",
119                        result, hello);
120                 return false;
121         }
122
123         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
124         if (!NT_STATUS_IS_OK(status)) {
125                 printf("smb2cli_close returned %s\n", nt_errstr(status));
126                 return false;
127         }
128
129         status = smb2cli_create(cli, "",
130                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
131                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
132                         SEC_STD_SYNCHRONIZE|
133                         SEC_DIR_LIST|
134                         SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
135                         0, /* file_attributes, */
136                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
137                         FILE_OPEN, /* create_disposition, */
138                         FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
139                         NULL, /* smb2_create_blobs *blobs */
140                         &fid_persistent,
141                         &fid_volatile);
142         if (!NT_STATUS_IS_OK(status)) {
143                 printf("smb2cli_create returned %s\n", nt_errstr(status));
144                 return false;
145         }
146
147         status = smb2cli_query_directory(
148                 cli, 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
149                 talloc_tos(), &dir_data, &dir_data_length);
150
151         if (!NT_STATUS_IS_OK(status)) {
152                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
153                 return false;
154         }
155
156         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
157         if (!NT_STATUS_IS_OK(status)) {
158                 printf("smb2cli_close returned %s\n", nt_errstr(status));
159                 return false;
160         }
161
162         saved_tid = cli->smb2.tid;
163         status = smb2cli_tdis(cli);
164         if (!NT_STATUS_IS_OK(status)) {
165                 printf("smb2cli_tdis returned %s\n", nt_errstr(status));
166                 return false;
167         }
168         cli->smb2.tid = saved_tid;
169
170         status = smb2cli_tdis(cli);
171         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
172                 printf("2nd smb2cli_tdis returned %s\n", nt_errstr(status));
173                 return false;
174         }
175
176         saved_uid = smb2cli_session_current_id(cli->smb2.session);
177         status = smb2cli_logoff(cli);
178         if (!NT_STATUS_IS_OK(status)) {
179                 printf("smb2cli_logoff returned %s\n", nt_errstr(status));
180                 return false;
181         }
182
183         cli->smb2.session = smbXcli_session_create(cli, cli->conn);
184         if (cli->smb2.session == NULL) {
185                 printf("smbXcli_session_create() returned NULL\n");
186                 return false;
187         }
188
189         smb2cli_session_set_id_and_flags(cli->smb2.session, saved_uid, 0);
190
191         status = smb2cli_logoff(cli);
192         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
193                 printf("2nd smb2cli_logoff returned %s\n", nt_errstr(status));
194                 return false;
195         }
196
197         return true;
198 }
199
200 bool run_smb2_negprot(int dummy)
201 {
202         struct cli_state *cli;
203         NTSTATUS status;
204         enum protocol_types protocol;
205         const char *name = NULL;
206
207         printf("Starting SMB2-NEGPROT\n");
208
209         if (!torture_init_connection(&cli)) {
210                 return false;
211         }
212         cli->smb2.pid = 0xFEFF;
213
214         status = smbXcli_negprot(cli->conn, cli->timeout,
215                                  PROTOCOL_CORE, PROTOCOL_SMB2_24);
216         if (!NT_STATUS_IS_OK(status)) {
217                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
218                 return false;
219         }
220
221         protocol = smbXcli_conn_protocol(cli->conn);
222
223         switch (protocol) {
224         case PROTOCOL_SMB2_02:
225                 name = "SMB2_02";
226                 break;
227         case PROTOCOL_SMB2_10:
228                 name = "SMB2_10";
229                 break;
230         case PROTOCOL_SMB2_22:
231                 name = "SMB2_22";
232                 break;
233         case PROTOCOL_SMB2_24:
234                 name = "SMB2_24";
235                 break;
236         default:
237                 break;
238         }
239
240         if (name) {
241                 printf("Server supports %s\n", name);
242         } else {
243                 printf("Server DOES NOT support SMB2\n");
244                 return false;
245         }
246
247         status = smbXcli_negprot(cli->conn, cli->timeout,
248                                  protocol, protocol);
249         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
250             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
251             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
252                 printf("2nd smbXcli_negprot should disconnect - returned %s\n",
253                         nt_errstr(status));
254                 return false;
255         }
256
257         if (smbXcli_conn_is_connected(cli->conn)) {
258                 printf("2nd smbXcli_negprot should disconnect "
259                        "- still connected\n");
260                 return false;
261         }
262
263         return true;
264 }
265
266 bool run_smb2_session_reconnect(int dummy)
267 {
268         struct cli_state *cli1;
269         struct cli_state *cli2;
270         NTSTATUS status;
271         bool ok;
272         uint64_t fid_persistent, fid_volatile;
273         struct tevent_context *ev;
274         struct tevent_req *subreq;
275         DATA_BLOB in_blob = data_blob_null;
276         DATA_BLOB out_blob;
277         DATA_BLOB session_key;
278         struct auth_generic_state *auth_generic_state;
279         struct iovec *recv_iov;
280         const char *hello = "Hello, world\n";
281         uint8_t *result;
282         uint32_t nread;
283
284         printf("Starting SMB2-SESSION-RECONNECT\n");
285
286         if (!torture_init_connection(&cli1)) {
287                 return false;
288         }
289         cli1->smb2.pid = 0xFEFF;
290
291         status = smbXcli_negprot(cli1->conn, cli1->timeout,
292                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
293         if (!NT_STATUS_IS_OK(status)) {
294                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
295                 return false;
296         }
297
298         status = cli_session_setup(cli1, username,
299                                    password, strlen(password),
300                                    password, strlen(password),
301                                    workgroup);
302         if (!NT_STATUS_IS_OK(status)) {
303                 printf("cli_session_setup returned %s\n", nt_errstr(status));
304                 return false;
305         }
306
307         status = cli_tree_connect(cli1, share, "?????", "", 0);
308         if (!NT_STATUS_IS_OK(status)) {
309                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
310                 return false;
311         }
312
313         status = smb2cli_create(cli1, "session-reconnect.txt",
314                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
315                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
316                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
317                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
318                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
319                         FILE_CREATE, /* create_disposition, */
320                         FILE_DELETE_ON_CLOSE, /* create_options, */
321                         NULL, /* smb2_create_blobs *blobs */
322                         &fid_persistent,
323                         &fid_volatile);
324         if (!NT_STATUS_IS_OK(status)) {
325                 printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
326                 return false;
327         }
328
329         status = smb2cli_write(cli1, strlen(hello), 0, fid_persistent,
330                                fid_volatile, 0, 0, (const uint8_t *)hello);
331         if (!NT_STATUS_IS_OK(status)) {
332                 printf("smb2cli_write returned %s\n", nt_errstr(status));
333                 return false;
334         }
335
336         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
337         if (!NT_STATUS_IS_OK(status)) {
338                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
339                 return false;
340         }
341
342         status = smb2cli_read(cli1, 0x10000, 0, fid_persistent,
343                                fid_volatile, 2, 0,
344                                talloc_tos(), &result, &nread);
345         if (!NT_STATUS_IS_OK(status)) {
346                 printf("smb2cli_read returned %s\n", nt_errstr(status));
347                 return false;
348         }
349
350         if (nread != strlen(hello)) {
351                 printf("smb2cli_read returned %d bytes, expected %d\n",
352                        (int)nread, (int)strlen(hello));
353                 return false;
354         }
355
356         if (memcmp(hello, result, nread) != 0) {
357                 printf("smb2cli_read returned '%s', expected '%s'\n",
358                        result, hello);
359                 return false;
360         }
361
362         /* prepare second session */
363
364         if (!torture_init_connection(&cli2)) {
365                 return false;
366         }
367         cli2->smb2.pid = 0xFEFF;
368
369         status = smbXcli_negprot(cli2->conn, cli2->timeout,
370                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
371         if (!NT_STATUS_IS_OK(status)) {
372                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
373                 return false;
374         }
375
376         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
377         if (!NT_STATUS_IS_OK(status)) {
378                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
379                 return false;
380         }
381
382         gensec_want_feature(auth_generic_state->gensec_security,
383                             GENSEC_FEATURE_SESSION_KEY);
384         status = auth_generic_set_username(auth_generic_state, username);
385         if (!NT_STATUS_IS_OK(status)) {
386                 printf("auth_generic_set_username returned %s\n", nt_errstr(status));
387                 return false;
388         }
389
390         status = auth_generic_set_domain(auth_generic_state, workgroup);
391         if (!NT_STATUS_IS_OK(status)) {
392                 printf("auth_generic_set_domain returned %s\n", nt_errstr(status));
393                 return false;
394         }
395
396         status = auth_generic_set_password(auth_generic_state, password);
397         if (!NT_STATUS_IS_OK(status)) {
398                 printf("auth_generic_set_password returned %s\n", nt_errstr(status));
399                 return false;
400         }
401
402         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
403         if (!NT_STATUS_IS_OK(status)) {
404                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
405                 return false;
406         }
407
408         ev = event_context_init(talloc_tos());
409         if (ev == NULL) {
410                 printf("event_context_init() returned NULL\n");
411                 return false;
412         }
413
414         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, data_blob_null, &in_blob);
415         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
416                 printf("gensec_update returned %s\n", nt_errstr(status));
417                 return false;
418         }
419
420         cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
421
422         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
423                                             cli2->conn,
424                                             cli2->timeout,
425                                             cli2->smb2.session,
426                                             0x0, /* in_flags */
427                                             SMB2_CAP_DFS, /* in_capabilities */
428                                             0, /* in_channel */
429                                             /* in_previous_session_id: */
430                                             smb2cli_session_current_id(cli1->smb2.session),
431                                             &in_blob); /* in_security_buffer */
432         if (subreq == NULL) {
433                 printf("smb2cli_session_setup_send() returned NULL\n");
434                 return false;
435         }
436
437         ok = tevent_req_poll(subreq, ev);
438         if (!ok) {
439                 printf("tevent_req_poll() returned false\n");
440                 return false;
441         }
442
443         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
444                                             NULL, &out_blob);
445         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
446                 printf("smb2cli_session_setup_recv returned %s\n",
447                         nt_errstr(status));
448                 return false;
449         }
450
451         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, out_blob, &in_blob);
452         if (!NT_STATUS_IS_OK(status)) {
453                 printf("auth_generic_update returned %s\n", nt_errstr(status));
454                 return false;
455         }
456
457         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
458                                             cli2->conn,
459                                             cli2->timeout,
460                                             cli2->smb2.session,
461                                             0x0, /* in_flags */
462                                             SMB2_CAP_DFS, /* in_capabilities */
463                                             0, /* in_channel */
464                                             /* in_previous_session_id: */
465                                             smb2cli_session_current_id(cli1->smb2.session),
466                                             &in_blob); /* in_security_buffer */
467         if (subreq == NULL) {
468                 printf("smb2cli_session_setup_send() returned NULL\n");
469                 return false;
470         }
471
472         ok = tevent_req_poll(subreq, ev);
473         if (!ok) {
474                 printf("tevent_req_poll() returned false\n");
475                 return false;
476         }
477
478         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
479                                             &recv_iov, &out_blob);
480         if (!NT_STATUS_IS_OK(status)) {
481                 printf("smb2cli_session_setup_recv returned %s\n",
482                         nt_errstr(status));
483                 return false;
484         }
485
486         status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
487                                     &session_key);
488         if (!NT_STATUS_IS_OK(status)) {
489                 printf("gensec_session_key returned %s\n",
490                         nt_errstr(status));
491                 return false;
492         }
493
494         /* check file operation on the old client */
495
496         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
497         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
498                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
499                 return false;
500         }
501
502         status = cli_tree_connect(cli1, share, "?????", "", 0);
503         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
504                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
505                 return false;
506         }
507
508         /*
509          * checking file operations without signing.
510          * on w2k8r2 at least, flush, read and write also work the same way,
511          * while create gives ACCESS_DENIED without signing
512          */
513         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
514         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
515                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
516                 return false;
517         }
518
519         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
520                                fid_volatile, 0, 0, (const uint8_t *)hello);
521         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
522                 printf("smb2cli_write returned %s\n", nt_errstr(status));
523                 return false;
524         }
525
526         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
527                                fid_volatile, 2, 0,
528                                talloc_tos(), &result, &nread);
529         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
530                 printf("smb2cli_read returned %s\n", nt_errstr(status));
531                 return false;
532         }
533
534         status = smb2cli_create(cli2, "session-reconnect.txt",
535                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
536                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
537                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
538                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
539                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
540                         FILE_CREATE, /* create_disposition, */
541                         FILE_DELETE_ON_CLOSE, /* create_options, */
542                         NULL, /* smb2_create_blobs *blobs */
543                         &fid_persistent,
544                         &fid_volatile);
545         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
546             !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
547                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
548                 return false;
549         }
550
551         /* now grab the session key and try with signing */
552
553         status = smb2cli_session_set_session_key(cli2->smb2.session,
554                                                  session_key,
555                                                  recv_iov);
556         if (!NT_STATUS_IS_OK(status)) {
557                 printf("smb2cli_session_set_session_key %s\n", nt_errstr(status));
558                 return false;
559         }
560
561         /* the tid seems to be irrelevant at this stage */
562
563         cli2->smb2.tid = cli1->smb2.tid;
564
565         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
566         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
567                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
568                 return false;
569         }
570
571         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
572                                fid_volatile, 0, 0, (const uint8_t *)hello);
573         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
574                 printf("smb2cli_write returned %s\n", nt_errstr(status));
575                 return false;
576         }
577
578         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
579                                fid_volatile, 2, 0,
580                                talloc_tos(), &result, &nread);
581         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
582                 printf("smb2cli_read returned %s\n", nt_errstr(status));
583                 return false;
584         }
585
586         status = smb2cli_create(cli2, "session-reconnect.txt",
587                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
588                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
589                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
590                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
591                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
592                         FILE_CREATE, /* create_disposition, */
593                         FILE_DELETE_ON_CLOSE, /* create_options, */
594                         NULL, /* smb2_create_blobs *blobs */
595                         &fid_persistent,
596                         &fid_volatile);
597         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
598                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
599                 return false;
600         }
601
602         /* now do a new tcon and test file calls again */
603
604         status = cli_tree_connect(cli2, share, "?????", "", 0);
605         if (!NT_STATUS_IS_OK(status)) {
606                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
607                 return false;
608         }
609
610         status = smb2cli_create(cli2, "session-reconnect.txt",
611                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
612                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
613                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
614                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
615                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
616                         FILE_CREATE, /* create_disposition, */
617                         FILE_DELETE_ON_CLOSE, /* create_options, */
618                         NULL, /* smb2_create_blobs *blobs */
619                         &fid_persistent,
620                         &fid_volatile);
621         if (!NT_STATUS_IS_OK(status)) {
622                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
623                 return false;
624         }
625
626         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
627                                fid_volatile, 0, 0, (const uint8_t *)hello);
628         if (!NT_STATUS_IS_OK(status)) {
629                 printf("smb2cli_write returned %s\n", nt_errstr(status));
630                 return false;
631         }
632
633         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
634         if (!NT_STATUS_IS_OK(status)) {
635                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
636                 return false;
637         }
638
639         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
640                                fid_volatile, 2, 0,
641                                talloc_tos(), &result, &nread);
642         if (!NT_STATUS_IS_OK(status)) {
643                 printf("smb2cli_read returned %s\n", nt_errstr(status));
644                 return false;
645         }
646
647         if (nread != strlen(hello)) {
648                 printf("smb2cli_read returned %d bytes, expected %d\n",
649                        (int)nread, (int)strlen(hello));
650                 return false;
651         }
652
653         if (memcmp(hello, result, nread) != 0) {
654                 printf("smb2cli_read returned '%s', expected '%s'\n",
655                        result, hello);
656                 return false;
657         }
658
659         return true;
660 }
661
662 bool run_smb2_tcon_dependence(int dummy)
663 {
664         struct cli_state *cli;
665         NTSTATUS status;
666         uint64_t fid_persistent, fid_volatile;
667         const char *hello = "Hello, world\n";
668         uint8_t *result;
669         uint32_t nread;
670
671         printf("Starting SMB2-TCON-DEPENDENCE\n");
672
673         if (!torture_init_connection(&cli)) {
674                 return false;
675         }
676         cli->smb2.pid = 0xFEFF;
677
678         status = smbXcli_negprot(cli->conn, cli->timeout,
679                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
680         if (!NT_STATUS_IS_OK(status)) {
681                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
682                 return false;
683         }
684
685         status = cli_session_setup(cli, username,
686                                    password, strlen(password),
687                                    password, strlen(password),
688                                    workgroup);
689         if (!NT_STATUS_IS_OK(status)) {
690                 printf("cli_session_setup returned %s\n", nt_errstr(status));
691                 return false;
692         }
693
694         status = cli_tree_connect(cli, share, "?????", "", 0);
695         if (!NT_STATUS_IS_OK(status)) {
696                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
697                 return false;
698         }
699
700         status = smb2cli_create(cli, "tcon_depedence.txt",
701                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
702                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
703                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
704                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
705                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
706                         FILE_CREATE, /* create_disposition, */
707                         FILE_DELETE_ON_CLOSE, /* create_options, */
708                         NULL, /* smb2_create_blobs *blobs */
709                         &fid_persistent,
710                         &fid_volatile);
711         if (!NT_STATUS_IS_OK(status)) {
712                 printf("smb2cli_create on cli %s\n", nt_errstr(status));
713                 return false;
714         }
715
716         status = smb2cli_write(cli, strlen(hello), 0, fid_persistent,
717                                fid_volatile, 0, 0, (const uint8_t *)hello);
718         if (!NT_STATUS_IS_OK(status)) {
719                 printf("smb2cli_write returned %s\n", nt_errstr(status));
720                 return false;
721         }
722
723         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
724         if (!NT_STATUS_IS_OK(status)) {
725                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
726                 return false;
727         }
728
729         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
730                                fid_volatile, 2, 0,
731                                talloc_tos(), &result, &nread);
732         if (!NT_STATUS_IS_OK(status)) {
733                 printf("smb2cli_read returned %s\n", nt_errstr(status));
734                 return false;
735         }
736
737         if (nread != strlen(hello)) {
738                 printf("smb2cli_read returned %d bytes, expected %d\n",
739                        (int)nread, (int)strlen(hello));
740                 return false;
741         }
742
743         if (memcmp(hello, result, nread) != 0) {
744                 printf("smb2cli_read returned '%s', expected '%s'\n",
745                        result, hello);
746                 return false;
747         }
748
749         /* check behaviour with wrong tid... */
750
751         cli->smb2.tid++;
752
753         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
754                                fid_volatile, 2, 0,
755                                talloc_tos(), &result, &nread);
756         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
757                 printf("smb2cli_read returned %s\n", nt_errstr(status));
758                 return false;
759         }
760
761         cli->smb2.tid--;
762
763         return true;
764 }
765
766 bool run_smb2_multi_channel(int dummy)
767 {
768         struct cli_state *cli1;
769         struct cli_state *cli2;
770         struct cli_state *cli3;
771         NTSTATUS status;
772         bool ok;
773         uint64_t fid_persistent, fid_volatile;
774         struct tevent_context *ev;
775         struct tevent_req *subreq;
776         DATA_BLOB in_blob = data_blob_null;
777         DATA_BLOB out_blob;
778         DATA_BLOB channel_session_key;
779         struct auth_generic_state *auth_generic_state;
780         struct iovec *recv_iov;
781         const char *hello = "Hello, world\n";
782         uint8_t *result;
783         uint32_t nread;
784
785         printf("Starting SMB2-MULTI-CHANNEL\n");
786
787         if (!torture_init_connection(&cli1)) {
788                 return false;
789         }
790         cli1->smb2.pid = 0xFEFF;
791
792         if (!torture_init_connection(&cli2)) {
793                 return false;
794         }
795         cli2->smb2.pid = 0xFEFF;
796
797         if (!torture_init_connection(&cli3)) {
798                 return false;
799         }
800         cli3->smb2.pid = 0xFEFF;
801
802         status = smbXcli_negprot(cli1->conn, cli1->timeout,
803                                  PROTOCOL_SMB2_22, PROTOCOL_SMB2_24);
804         if (!NT_STATUS_IS_OK(status)) {
805                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
806                 return false;
807         }
808
809         status = smbXcli_negprot(cli2->conn, cli2->timeout,
810                                  PROTOCOL_SMB2_22, PROTOCOL_SMB2_24);
811         if (!NT_STATUS_IS_OK(status)) {
812                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
813                 return false;
814         }
815
816         status = smbXcli_negprot(cli3->conn, cli3->timeout,
817                                  PROTOCOL_SMB2_22, PROTOCOL_SMB2_24);
818         if (!NT_STATUS_IS_OK(status)) {
819                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
820                 return false;
821         }
822
823         status = cli_session_setup(cli1, username,
824                                    password, strlen(password),
825                                    password, strlen(password),
826                                    workgroup);
827         if (!NT_STATUS_IS_OK(status)) {
828                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
829                 return false;
830         }
831
832         status = cli_tree_connect(cli1, share, "?????", "", 0);
833         if (!NT_STATUS_IS_OK(status)) {
834                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
835                 return false;
836         }
837
838         status = smb2cli_session_create_channel(cli2,
839                                                 cli1->smb2.session,
840                                                 cli2->conn,
841                                                 &cli2->smb2.session);
842         if (!NT_STATUS_IS_OK(status)) {
843                 printf("smb2cli_session_create_channel returned %s\n",
844                         nt_errstr(status));
845                 return false;
846         }
847
848         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
849         if (!NT_STATUS_IS_OK(status)) {
850                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
851                 return false;
852         }
853
854         gensec_want_feature(auth_generic_state->gensec_security,
855                             GENSEC_FEATURE_SESSION_KEY);
856         status = auth_generic_set_username(auth_generic_state, username);
857         if (!NT_STATUS_IS_OK(status)) {
858                 printf("auth_generic_set_username returned %s\n", nt_errstr(status));
859                 return false;
860         }
861
862         status = auth_generic_set_domain(auth_generic_state, workgroup);
863         if (!NT_STATUS_IS_OK(status)) {
864                 printf("auth_generic_set_domain returned %s\n", nt_errstr(status));
865                 return false;
866         }
867
868         status = auth_generic_set_password(auth_generic_state, password);
869         if (!NT_STATUS_IS_OK(status)) {
870                 printf("auth_generic_set_password returned %s\n", nt_errstr(status));
871                 return false;
872         }
873
874         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
875         if (!NT_STATUS_IS_OK(status)) {
876                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
877                 return false;
878         }
879
880         ev = event_context_init(talloc_tos());
881         if (ev == NULL) {
882                 printf("event_context_init() returned NULL\n");
883                 return false;
884         }
885
886         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, data_blob_null, &in_blob);
887         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
888                 printf("gensec_update returned %s\n", nt_errstr(status));
889                 return false;
890         }
891
892         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
893                                             cli2->conn,
894                                             cli2->timeout,
895                                             cli2->smb2.session,
896                                             0x01, /* in_flags */
897                                             SMB2_CAP_DFS, /* in_capabilities */
898                                             0, /* in_channel */
899                                             0, /* in_previous_session_id */
900                                             &in_blob); /* in_security_buffer */
901         if (subreq == NULL) {
902                 printf("smb2cli_session_setup_send() returned NULL\n");
903                 return false;
904         }
905
906         ok = tevent_req_poll(subreq, ev);
907         if (!ok) {
908                 printf("tevent_req_poll() returned false\n");
909                 return false;
910         }
911
912         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
913                                             NULL, &out_blob);
914         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
915                 printf("smb2cli_session_setup_recv returned %s\n",
916                         nt_errstr(status));
917                 return false;
918         }
919
920         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, out_blob, &in_blob);
921         if (!NT_STATUS_IS_OK(status)) {
922                 printf("auth_generic_update returned %s\n", nt_errstr(status));
923                 return false;
924         }
925
926         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
927                                             cli2->conn,
928                                             cli2->timeout,
929                                             cli2->smb2.session,
930                                             0x01, /* in_flags */
931                                             SMB2_CAP_DFS, /* in_capabilities */
932                                             0, /* in_channel */
933                                             0, /* in_previous_session_id */
934                                             &in_blob); /* in_security_buffer */
935         if (subreq == NULL) {
936                 printf("smb2cli_session_setup_send() returned NULL\n");
937                 return false;
938         }
939
940         ok = tevent_req_poll(subreq, ev);
941         if (!ok) {
942                 printf("tevent_req_poll() returned false\n");
943                 return false;
944         }
945
946         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
947                                             &recv_iov, &out_blob);
948         if (!NT_STATUS_IS_OK(status)) {
949                 printf("smb2cli_session_setup_recv returned %s\n",
950                         nt_errstr(status));
951                 return false;
952         }
953
954         status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
955                                     &channel_session_key);
956         if (!NT_STATUS_IS_OK(status)) {
957                 printf("gensec_session_key returned %s\n",
958                         nt_errstr(status));
959                 return false;
960         }
961
962         status = smb2cli_session_set_channel_key(cli2->smb2.session,
963                                                  channel_session_key,
964                                                  recv_iov);
965         if (!NT_STATUS_IS_OK(status)) {
966                 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
967                 return false;
968         }
969
970         cli2->smb2.tid = cli1->smb2.tid;
971
972         status = smb2cli_session_create_channel(cli3,
973                                                 cli2->smb2.session,
974                                                 cli3->conn,
975                                                 &cli3->smb2.session);
976         if (!NT_STATUS_IS_OK(status)) {
977                 printf("smb2cli_session_create_channel returned %s\n",
978                         nt_errstr(status));
979                 return false;
980         }
981
982         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
983         if (!NT_STATUS_IS_OK(status)) {
984                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
985                 return false;
986         }
987
988         gensec_want_feature(auth_generic_state->gensec_security,
989                             GENSEC_FEATURE_SESSION_KEY);
990         status = auth_generic_set_username(auth_generic_state, username);
991         if (!NT_STATUS_IS_OK(status)) {
992                 printf("auth_generic_set_username returned %s\n", nt_errstr(status));
993                 return false;
994         }
995
996         status = auth_generic_set_domain(auth_generic_state, workgroup);
997         if (!NT_STATUS_IS_OK(status)) {
998                 printf("auth_generic_set_domain returned %s\n", nt_errstr(status));
999                 return false;
1000         }
1001
1002         status = auth_generic_set_password(auth_generic_state, password);
1003         if (!NT_STATUS_IS_OK(status)) {
1004                 printf("auth_generic_set_password returned %s\n", nt_errstr(status));
1005                 return false;
1006         }
1007
1008         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1009         if (!NT_STATUS_IS_OK(status)) {
1010                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1011                 return false;
1012         }
1013
1014         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, data_blob_null, &in_blob);
1015         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1016                 printf("gensec_update returned %s\n", nt_errstr(status));
1017                 return false;
1018         }
1019
1020         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1021                                             cli3->conn,
1022                                             cli3->timeout,
1023                                             cli3->smb2.session,
1024                                             0x01, /* in_flags */
1025                                             SMB2_CAP_DFS, /* in_capabilities */
1026                                             0, /* in_channel */
1027                                             0, /* in_previous_session_id */
1028                                             &in_blob); /* in_security_buffer */
1029         if (subreq == NULL) {
1030                 printf("smb2cli_session_setup_send() returned NULL\n");
1031                 return false;
1032         }
1033
1034         ok = tevent_req_poll(subreq, ev);
1035         if (!ok) {
1036                 printf("tevent_req_poll() returned false\n");
1037                 return false;
1038         }
1039
1040         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1041                                             NULL, &out_blob);
1042         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1043                 printf("smb2cli_session_setup_recv returned %s\n",
1044                         nt_errstr(status));
1045                 return false;
1046         }
1047
1048         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, out_blob, &in_blob);
1049         if (!NT_STATUS_IS_OK(status)) {
1050                 printf("auth_generic_update returned %s\n", nt_errstr(status));
1051                 return false;
1052         }
1053
1054         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1055                                             cli3->conn,
1056                                             cli3->timeout,
1057                                             cli3->smb2.session,
1058                                             0x01, /* in_flags */
1059                                             SMB2_CAP_DFS, /* in_capabilities */
1060                                             0, /* in_channel */
1061                                             0, /* in_previous_session_id */
1062                                             &in_blob); /* in_security_buffer */
1063         if (subreq == NULL) {
1064                 printf("smb2cli_session_setup_send() returned NULL\n");
1065                 return false;
1066         }
1067
1068         ok = tevent_req_poll(subreq, ev);
1069         if (!ok) {
1070                 printf("tevent_req_poll() returned false\n");
1071                 return false;
1072         }
1073
1074         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1075                                             &recv_iov, &out_blob);
1076         if (!NT_STATUS_IS_OK(status)) {
1077                 printf("smb2cli_session_setup_recv returned %s\n",
1078                         nt_errstr(status));
1079                 return false;
1080         }
1081
1082         status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1083                                     &channel_session_key);
1084         if (!NT_STATUS_IS_OK(status)) {
1085                 printf("gensec_session_key returned %s\n",
1086                         nt_errstr(status));
1087                 return false;
1088         }
1089
1090         status = smb2cli_session_set_channel_key(cli3->smb2.session,
1091                                                  channel_session_key,
1092                                                  recv_iov);
1093         if (!NT_STATUS_IS_OK(status)) {
1094                 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1095                 return false;
1096         }
1097
1098         cli3->smb2.tid = cli2->smb2.tid;
1099
1100         status = smb2cli_create(cli2, "multi-channel.txt",
1101                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1102                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1103                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1104                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1105                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1106                         FILE_CREATE, /* create_disposition, */
1107                         FILE_DELETE_ON_CLOSE, /* create_options, */
1108                         NULL, /* smb2_create_blobs *blobs */
1109                         &fid_persistent,
1110                         &fid_volatile);
1111         if (!NT_STATUS_IS_OK(status)) {
1112                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
1113                 return false;
1114         }
1115
1116         status = smb2cli_write(cli1, strlen(hello), 0, fid_persistent,
1117                                fid_volatile, 0, 0, (const uint8_t *)hello);
1118         if (!NT_STATUS_IS_OK(status)) {
1119                 printf("smb2cli_write returned %s\n", nt_errstr(status));
1120                 return false;
1121         }
1122
1123         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
1124         if (!NT_STATUS_IS_OK(status)) {
1125                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1126                 return false;
1127         }
1128
1129         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
1130         if (!NT_STATUS_IS_OK(status)) {
1131                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1132                 return false;
1133         }
1134
1135         status = smb2cli_flush(cli3, fid_persistent, fid_volatile);
1136         if (!NT_STATUS_IS_OK(status)) {
1137                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1138                 return false;
1139         }
1140
1141         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
1142                                fid_volatile, 2, 0,
1143                                talloc_tos(), &result, &nread);
1144         if (!NT_STATUS_IS_OK(status)) {
1145                 printf("smb2cli_read returned %s\n", nt_errstr(status));
1146                 return false;
1147         }
1148
1149         if (nread != strlen(hello)) {
1150                 printf("smb2cli_read returned %d bytes, expected %d\n",
1151                        (int)nread, (int)strlen(hello));
1152                 return false;
1153         }
1154
1155         if (memcmp(hello, result, nread) != 0) {
1156                 printf("smb2cli_read returned '%s', expected '%s'\n",
1157                        result, hello);
1158                 return false;
1159         }
1160
1161         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1162         if (!NT_STATUS_IS_OK(status)) {
1163                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1164                 return false;
1165         }
1166
1167         gensec_want_feature(auth_generic_state->gensec_security,
1168                             GENSEC_FEATURE_SESSION_KEY);
1169         status = auth_generic_set_username(auth_generic_state, username);
1170         if (!NT_STATUS_IS_OK(status)) {
1171                 printf("auth_generic_set_username returned %s\n", nt_errstr(status));
1172                 return false;
1173         }
1174
1175         status = auth_generic_set_domain(auth_generic_state, workgroup);
1176         if (!NT_STATUS_IS_OK(status)) {
1177                 printf("auth_generic_set_domain returned %s\n", nt_errstr(status));
1178                 return false;
1179         }
1180
1181         status = auth_generic_set_password(auth_generic_state, password);
1182         if (!NT_STATUS_IS_OK(status)) {
1183                 printf("auth_generic_set_password returned %s\n", nt_errstr(status));
1184                 return false;
1185         }
1186
1187         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1188         if (!NT_STATUS_IS_OK(status)) {
1189                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1190                 return false;
1191         }
1192
1193         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, data_blob_null, &in_blob);
1194         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1195                 printf("gensec_update returned %s\n", nt_errstr(status));
1196                 return false;
1197         }
1198
1199         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1200                                             cli3->conn,
1201                                             cli3->timeout,
1202                                             cli3->smb2.session,
1203                                             0x0, /* in_flags */
1204                                             SMB2_CAP_DFS, /* in_capabilities */
1205                                             0, /* in_channel */
1206                                             0, /* in_previous_session_id */
1207                                             &in_blob); /* in_security_buffer */
1208         if (subreq == NULL) {
1209                 printf("smb2cli_session_setup_send() returned NULL\n");
1210                 return false;
1211         }
1212
1213         ok = tevent_req_poll(subreq, ev);
1214         if (!ok) {
1215                 printf("tevent_req_poll() returned false\n");
1216                 return false;
1217         }
1218
1219         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1220                                             NULL, &out_blob);
1221         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1222                 printf("smb2cli_session_setup_recv returned %s\n",
1223                         nt_errstr(status));
1224                 return false;
1225         }
1226
1227         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, out_blob, &in_blob);
1228         if (!NT_STATUS_IS_OK(status)) {
1229                 printf("auth_generic_update returned %s\n", nt_errstr(status));
1230                 return false;
1231         }
1232
1233         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1234                                             cli2->conn,
1235                                             cli2->timeout,
1236                                             cli2->smb2.session,
1237                                             0x0, /* in_flags */
1238                                             SMB2_CAP_DFS, /* in_capabilities */
1239                                             0, /* in_channel */
1240                                             0, /* in_previous_session_id */
1241                                             &in_blob); /* in_security_buffer */
1242         if (subreq == NULL) {
1243                 printf("smb2cli_session_setup_send() returned NULL\n");
1244                 return false;
1245         }
1246
1247         ok = tevent_req_poll(subreq, ev);
1248         if (!ok) {
1249                 printf("tevent_req_poll() returned false\n");
1250                 return false;
1251         }
1252
1253         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1254                                             &recv_iov, &out_blob);
1255         if (!NT_STATUS_IS_OK(status)) {
1256                 printf("smb2cli_session_setup_recv returned %s\n",
1257                         nt_errstr(status));
1258                 return false;
1259         }
1260
1261         status = smb2cli_close(cli3, 0, fid_persistent, fid_volatile);
1262         if (!NT_STATUS_IS_OK(status)) {
1263                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1264                 return false;
1265         }
1266
1267         status = smb2cli_flush(cli3, fid_persistent, fid_volatile);
1268         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1269                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1270                 return false;
1271         }
1272
1273         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
1274         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1275                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1276                 return false;
1277         }
1278
1279         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
1280         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1281                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1282                 return false;
1283         }
1284
1285         return true;
1286 }
1287
1288 bool run_smb2_session_reauth(int dummy)
1289 {
1290         struct cli_state *cli;
1291         NTSTATUS status;
1292         bool ok;
1293         uint64_t fid_persistent, fid_volatile;
1294         uint64_t dir_persistent, dir_volatile;
1295         uint8_t *dir_data;
1296         uint32_t dir_data_length;
1297         struct tevent_context *ev;
1298         struct tevent_req *subreq;
1299         DATA_BLOB in_blob = data_blob_null;
1300         DATA_BLOB out_blob;
1301         struct auth_generic_state *auth_generic_state;
1302         struct iovec *recv_iov;
1303         uint32_t saved_tid;
1304
1305         printf("Starting SMB2-SESSION_REAUTH\n");
1306
1307         if (!torture_init_connection(&cli)) {
1308                 return false;
1309         }
1310         cli->smb2.pid = 0xFEFF;
1311
1312         /*
1313          * PROTOCOL_SMB2_22 has a bug in win8pre0
1314          * it behaves like PROTOCOL_SMB2_02
1315          * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
1316          * while it allows it on PROTOCOL_SMB2_02.
1317          */
1318         status = smbXcli_negprot(cli->conn, cli->timeout,
1319                                  PROTOCOL_SMB2_10, PROTOCOL_SMB2_10);
1320         if (!NT_STATUS_IS_OK(status)) {
1321                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1322                 return false;
1323         }
1324
1325         status = cli_session_setup(cli, username,
1326                                    password, strlen(password),
1327                                    password, strlen(password),
1328                                    workgroup);
1329         if (!NT_STATUS_IS_OK(status)) {
1330                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
1331                 return false;
1332         }
1333
1334         status = cli_tree_connect(cli, share, "?????", "", 0);
1335         if (!NT_STATUS_IS_OK(status)) {
1336                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1337                 return false;
1338         }
1339
1340         status = smb2cli_create(cli, "session-reauth.txt",
1341                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1342                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1343                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1344                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1345                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1346                         FILE_CREATE, /* create_disposition, */
1347                         FILE_DELETE_ON_CLOSE, /* create_options, */
1348                         NULL, /* smb2_create_blobs *blobs */
1349                         &fid_persistent,
1350                         &fid_volatile);
1351         if (!NT_STATUS_IS_OK(status)) {
1352                 printf("smb2cli_create %s\n", nt_errstr(status));
1353                 return false;
1354         }
1355
1356         status = smb2cli_create(cli, "",
1357                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1358                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1359                         SEC_STD_SYNCHRONIZE|
1360                         SEC_DIR_LIST|
1361                         SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1362                         0, /* file_attributes, */
1363                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1364                         FILE_OPEN, /* create_disposition, */
1365                         FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
1366                         NULL, /* smb2_create_blobs *blobs */
1367                         &dir_persistent,
1368                         &dir_volatile);
1369         if (!NT_STATUS_IS_OK(status)) {
1370                 printf("smb2cli_create returned %s\n", nt_errstr(status));
1371                 return false;
1372         }
1373
1374         status = smb2cli_query_directory(
1375                 cli, 1, 0x3, 0, dir_persistent, dir_volatile,
1376                 "session-reauth.txt", 0xffff,
1377                 talloc_tos(), &dir_data, &dir_data_length);
1378         if (!NT_STATUS_IS_OK(status)) {
1379                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1380                 return false;
1381         }
1382
1383         status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1384         if (!NT_STATUS_IS_OK(status)) {
1385                 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1386                 return false;
1387         }
1388
1389         gensec_want_feature(auth_generic_state->gensec_security,
1390                             GENSEC_FEATURE_SESSION_KEY);
1391         status = auth_generic_set_username(auth_generic_state, username);
1392         if (!NT_STATUS_IS_OK(status)) {
1393                 printf("auth_generic_set_username returned %s\n", nt_errstr(status));
1394                 return false;
1395         }
1396
1397         status = auth_generic_set_domain(auth_generic_state, workgroup);
1398         if (!NT_STATUS_IS_OK(status)) {
1399                 printf("auth_generic_set_domain returned %s\n", nt_errstr(status));
1400                 return false;
1401         }
1402
1403         status = auth_generic_set_password(auth_generic_state, password);
1404         if (!NT_STATUS_IS_OK(status)) {
1405                 printf("auth_generic_set_password returned %s\n", nt_errstr(status));
1406                 return false;
1407         }
1408
1409         status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1410         if (!NT_STATUS_IS_OK(status)) {
1411                 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1412                 return false;
1413         }
1414
1415         ev = event_context_init(talloc_tos());
1416         if (ev == NULL) {
1417                 printf("event_context_init() returned NULL\n");
1418                 return false;
1419         }
1420
1421         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, data_blob_null, &in_blob);
1422         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1423                 printf("gensec_update returned %s\n", nt_errstr(status));
1424                 return false;
1425         }
1426
1427         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1428                                             cli->conn,
1429                                             cli->timeout,
1430                                             cli->smb2.session,
1431                                             0x0, /* in_flags */
1432                                             SMB2_CAP_DFS, /* in_capabilities */
1433                                             0, /* in_channel */
1434                                             0, /* in_previous_session_id */
1435                                             &in_blob); /* in_security_buffer */
1436         if (subreq == NULL) {
1437                 printf("smb2cli_session_setup_send() returned NULL\n");
1438                 return false;
1439         }
1440
1441         ok = tevent_req_poll(subreq, ev);
1442         if (!ok) {
1443                 printf("tevent_req_poll() returned false\n");
1444                 return false;
1445         }
1446
1447         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1448                                             NULL, &out_blob);
1449         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1450                 printf("smb2cli_session_setup_recv returned %s\n",
1451                         nt_errstr(status));
1452                 return false;
1453         }
1454
1455         status = gensec_update(auth_generic_state->gensec_security, talloc_tos(), ev, out_blob, &in_blob);
1456         if (!NT_STATUS_IS_OK(status)) {
1457                 printf("auth_generic_update returned %s\n", nt_errstr(status));
1458                 return false;
1459         }
1460
1461         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
1462         if (!NT_STATUS_IS_OK(status)) {
1463                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1464                 return false;
1465         }
1466
1467         status = smb2cli_query_directory(
1468                 cli, 1, 0x3, 0, dir_persistent, dir_volatile,
1469                 "session-reauth.txt", 0xffff,
1470                 talloc_tos(), &dir_data, &dir_data_length);
1471         if (!NT_STATUS_IS_OK(status)) {
1472                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1473                 return false;
1474         }
1475
1476         status = smb2cli_create(cli, "session-reauth-invalid.txt",
1477                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1478                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1479                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1480                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1481                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1482                         FILE_CREATE, /* create_disposition, */
1483                         FILE_DELETE_ON_CLOSE, /* create_options, */
1484                         NULL, /* smb2_create_blobs *blobs */
1485                         &fid_persistent,
1486                         &fid_volatile);
1487         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1488                 printf("smb2cli_create %s\n", nt_errstr(status));
1489                 return false;
1490         }
1491
1492         status = smb2cli_create(cli, "",
1493                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1494                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1495                         SEC_STD_SYNCHRONIZE|
1496                         SEC_DIR_LIST|
1497                         SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1498                         0, /* file_attributes, */
1499                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1500                         FILE_OPEN, /* create_disposition, */
1501                         FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
1502                         NULL, /* smb2_create_blobs *blobs */
1503                         &dir_persistent,
1504                         &dir_volatile);
1505         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1506                 printf("smb2cli_create returned %s\n", nt_errstr(status));
1507                 return false;
1508         }
1509
1510         saved_tid = cli->smb2.tid;
1511         status = cli_tree_connect(cli, share, "?????", "", 0);
1512         if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1513                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1514                 return false;
1515         }
1516         cli->smb2.tid = saved_tid;
1517
1518         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1519                                             cli->conn,
1520                                             cli->timeout,
1521                                             cli->smb2.session,
1522                                             0x0, /* in_flags */
1523                                             SMB2_CAP_DFS, /* in_capabilities */
1524                                             0, /* in_channel */
1525                                             0, /* in_previous_session_id */
1526                                             &in_blob); /* in_security_buffer */
1527         if (subreq == NULL) {
1528                 printf("smb2cli_session_setup_send() returned NULL\n");
1529                 return false;
1530         }
1531
1532         ok = tevent_req_poll(subreq, ev);
1533         if (!ok) {
1534                 printf("tevent_req_poll() returned false\n");
1535                 return false;
1536         }
1537
1538         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1539                                             &recv_iov, &out_blob);
1540         if (!NT_STATUS_IS_OK(status)) {
1541                 printf("smb2cli_session_setup_recv returned %s\n",
1542                         nt_errstr(status));
1543                 return false;
1544         }
1545
1546         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
1547         if (!NT_STATUS_IS_OK(status)) {
1548                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1549                 return false;
1550         }
1551
1552         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
1553         if (!NT_STATUS_IS_OK(status)) {
1554                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1555                 return false;
1556         }
1557
1558         status = smb2cli_create(cli, "session-reauth.txt",
1559                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1560                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1561                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1562                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1563                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1564                         FILE_CREATE, /* create_disposition, */
1565                         FILE_DELETE_ON_CLOSE, /* create_options, */
1566                         NULL, /* smb2_create_blobs *blobs */
1567                         &fid_persistent,
1568                         &fid_volatile);
1569         if (!NT_STATUS_IS_OK(status)) {
1570                 printf("smb2cli_create %s\n", nt_errstr(status));
1571                 return false;
1572         }
1573
1574         status = smb2cli_query_directory(
1575                 cli, 1, 0x3, 0, dir_persistent, dir_volatile,
1576                 "session-reauth.txt", 0xffff,
1577                 talloc_tos(), &dir_data, &dir_data_length);
1578         if (!NT_STATUS_IS_OK(status)) {
1579                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1580                 return false;
1581         }
1582
1583         status = smb2cli_close(cli, 0, dir_persistent, dir_volatile);
1584         if (!NT_STATUS_IS_OK(status)) {
1585                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1586                 return false;
1587         }
1588
1589         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
1590         if (!NT_STATUS_IS_OK(status)) {
1591                 printf("smb2cli_close returned %s\n", nt_errstr(status));
1592                 return false;
1593         }
1594
1595         saved_tid = cli->smb2.tid;
1596         status = cli_tree_connect(cli, share, "?????", "", 0);
1597         if (!NT_STATUS_IS_OK(status)) {
1598                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1599                 return false;
1600         }
1601         cli->smb2.tid = saved_tid;
1602
1603         return true;
1604 }