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