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