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