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