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