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