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