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