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