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