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