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