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