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