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