s3:torture: add a new test SMB2-TCON-DEPENDENCE
[tridge/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/ntlmssp/ntlmssp.h"
28
29 extern fstring host, workgroup, share, password, username, myname;
30
31 bool run_smb2_basic(int dummy)
32 {
33         struct cli_state *cli;
34         NTSTATUS status;
35         uint64_t fid_persistent, fid_volatile;
36         const char *hello = "Hello, world\n";
37         uint8_t *result;
38         uint32_t nread;
39         uint8_t *dir_data;
40         uint32_t dir_data_length;
41
42         printf("Starting SMB2-BASIC\n");
43
44         if (!torture_init_connection(&cli)) {
45                 return false;
46         }
47         cli->smb2.pid = 0xFEFF;
48
49         status = smbXcli_negprot(cli->conn, cli->timeout,
50                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
51         if (!NT_STATUS_IS_OK(status)) {
52                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
53                 return false;
54         }
55
56         status = cli_session_setup(cli, username,
57                                    password, strlen(password),
58                                    password, strlen(password),
59                                    workgroup);
60         if (!NT_STATUS_IS_OK(status)) {
61                 printf("cli_session_setup returned %s\n", nt_errstr(status));
62                 return false;
63         }
64
65         status = cli_tree_connect(cli, share, "?????", "", 0);
66         if (!NT_STATUS_IS_OK(status)) {
67                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
68                 return false;
69         }
70
71         status = smb2cli_create(cli, "smb2-basic.txt",
72                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
73                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
74                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
75                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
76                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
77                         FILE_CREATE, /* create_disposition, */
78                         FILE_DELETE_ON_CLOSE, /* create_options, */
79                         NULL, /* smb2_create_blobs *blobs */
80                         &fid_persistent,
81                         &fid_volatile);
82         if (!NT_STATUS_IS_OK(status)) {
83                 printf("smb2cli_create returned %s\n", nt_errstr(status));
84                 return false;
85         }
86
87         status = smb2cli_write(cli, strlen(hello), 0, fid_persistent,
88                                fid_volatile, 0, 0, (const uint8_t *)hello);
89         if (!NT_STATUS_IS_OK(status)) {
90                 printf("smb2cli_write returned %s\n", nt_errstr(status));
91                 return false;
92         }
93
94         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
95         if (!NT_STATUS_IS_OK(status)) {
96                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
97                 return false;
98         }
99
100         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
101                                fid_volatile, 2, 0,
102                                talloc_tos(), &result, &nread);
103         if (!NT_STATUS_IS_OK(status)) {
104                 printf("smb2cli_read returned %s\n", nt_errstr(status));
105                 return false;
106         }
107
108         if (nread != strlen(hello)) {
109                 printf("smb2cli_read returned %d bytes, expected %d\n",
110                        (int)nread, (int)strlen(hello));
111                 return false;
112         }
113
114         if (memcmp(hello, result, nread) != 0) {
115                 printf("smb2cli_read returned '%s', expected '%s'\n",
116                        result, hello);
117                 return false;
118         }
119
120         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
121         if (!NT_STATUS_IS_OK(status)) {
122                 printf("smb2cli_close returned %s\n", nt_errstr(status));
123                 return false;
124         }
125
126         status = smb2cli_create(cli, "",
127                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
128                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
129                         SEC_STD_SYNCHRONIZE|
130                         SEC_DIR_LIST|
131                         SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
132                         0, /* file_attributes, */
133                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
134                         FILE_OPEN, /* create_disposition, */
135                         FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
136                         NULL, /* smb2_create_blobs *blobs */
137                         &fid_persistent,
138                         &fid_volatile);
139         if (!NT_STATUS_IS_OK(status)) {
140                 printf("smb2cli_create returned %s\n", nt_errstr(status));
141                 return false;
142         }
143
144         status = smb2cli_query_directory(
145                 cli, 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
146                 talloc_tos(), &dir_data, &dir_data_length);
147
148         if (!NT_STATUS_IS_OK(status)) {
149                 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
150                 return false;
151         }
152
153         status = smb2cli_close(cli, 0, fid_persistent, fid_volatile);
154         if (!NT_STATUS_IS_OK(status)) {
155                 printf("smb2cli_close returned %s\n", nt_errstr(status));
156                 return false;
157         }
158
159         return true;
160 }
161
162 bool run_smb2_negprot(int dummy)
163 {
164         struct cli_state *cli;
165         NTSTATUS status;
166         enum protocol_types protocol;
167         const char *name = NULL;
168
169         printf("Starting SMB2-NEGPROT\n");
170
171         if (!torture_init_connection(&cli)) {
172                 return false;
173         }
174         cli->smb2.pid = 0xFEFF;
175
176         status = smbXcli_negprot(cli->conn, cli->timeout,
177                                  PROTOCOL_CORE, PROTOCOL_SMB2_22);
178         if (!NT_STATUS_IS_OK(status)) {
179                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
180                 return false;
181         }
182
183         protocol = smbXcli_conn_protocol(cli->conn);
184
185         switch (protocol) {
186         case PROTOCOL_SMB2_02:
187                 name = "SMB2_02";
188                 break;
189         case PROTOCOL_SMB2_10:
190                 name = "SMB2_10";
191                 break;
192         case PROTOCOL_SMB2_22:
193                 name = "SMB2_22";
194                 break;
195         default:
196                 break;
197         }
198
199         if (name) {
200                 printf("Server supports %s\n", name);
201         } else {
202                 printf("Server DOES NOT support SMB2\n");
203                 return false;
204         }
205
206         status = smbXcli_negprot(cli->conn, cli->timeout,
207                                  protocol, protocol);
208         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
209             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
210             !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
211                 printf("2nd smbXcli_negprot should disconnect - returned %s\n",
212                         nt_errstr(status));
213                 return false;
214         }
215
216         if (smbXcli_conn_is_connected(cli->conn)) {
217                 printf("2nd smbXcli_negprot should disconnect "
218                        "- still connected\n");
219                 return false;
220         }
221
222         return true;
223 }
224
225 bool run_smb2_session_reconnect(int dummy)
226 {
227         struct cli_state *cli1;
228         struct cli_state *cli2;
229         NTSTATUS status;
230         bool ok;
231         uint64_t fid_persistent, fid_volatile;
232         struct tevent_context *ev;
233         struct tevent_req *subreq;
234         DATA_BLOB in_blob = data_blob_null;
235         DATA_BLOB out_blob;
236         struct ntlmssp_state *ntlmssp;
237         struct iovec *recv_iov;
238         const char *hello = "Hello, world\n";
239         uint8_t *result;
240         uint32_t nread;
241
242         printf("Starting SMB2-SESSION-RECONNECT\n");
243
244         if (!torture_init_connection(&cli1)) {
245                 return false;
246         }
247         cli1->smb2.pid = 0xFEFF;
248
249         status = smbXcli_negprot(cli1->conn, cli1->timeout,
250                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_22);
251         if (!NT_STATUS_IS_OK(status)) {
252                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
253                 return false;
254         }
255
256         status = cli_session_setup(cli1, username,
257                                    password, strlen(password),
258                                    password, strlen(password),
259                                    workgroup);
260         if (!NT_STATUS_IS_OK(status)) {
261                 printf("cli_session_setup returned %s\n", nt_errstr(status));
262                 return false;
263         }
264
265         status = cli_tree_connect(cli1, share, "?????", "", 0);
266         if (!NT_STATUS_IS_OK(status)) {
267                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
268                 return false;
269         }
270
271         status = smb2cli_create(cli1, "session-reconnect.txt",
272                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
273                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
274                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
275                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
276                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
277                         FILE_CREATE, /* create_disposition, */
278                         FILE_DELETE_ON_CLOSE, /* create_options, */
279                         NULL, /* smb2_create_blobs *blobs */
280                         &fid_persistent,
281                         &fid_volatile);
282         if (!NT_STATUS_IS_OK(status)) {
283                 printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
284                 return false;
285         }
286
287         status = smb2cli_write(cli1, strlen(hello), 0, fid_persistent,
288                                fid_volatile, 0, 0, (const uint8_t *)hello);
289         if (!NT_STATUS_IS_OK(status)) {
290                 printf("smb2cli_write returned %s\n", nt_errstr(status));
291                 return false;
292         }
293
294         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
295         if (!NT_STATUS_IS_OK(status)) {
296                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
297                 return false;
298         }
299
300         status = smb2cli_read(cli1, 0x10000, 0, fid_persistent,
301                                fid_volatile, 2, 0,
302                                talloc_tos(), &result, &nread);
303         if (!NT_STATUS_IS_OK(status)) {
304                 printf("smb2cli_read returned %s\n", nt_errstr(status));
305                 return false;
306         }
307
308         if (nread != strlen(hello)) {
309                 printf("smb2cli_read returned %d bytes, expected %d\n",
310                        (int)nread, (int)strlen(hello));
311                 return false;
312         }
313
314         if (memcmp(hello, result, nread) != 0) {
315                 printf("smb2cli_read returned '%s', expected '%s'\n",
316                        result, hello);
317                 return false;
318         }
319
320         /* prepare second session */
321
322         if (!torture_init_connection(&cli2)) {
323                 return false;
324         }
325         cli2->smb2.pid = 0xFEFF;
326
327         status = smbXcli_negprot(cli2->conn, cli2->timeout,
328                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_22);
329         if (!NT_STATUS_IS_OK(status)) {
330                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
331                 return false;
332         }
333
334         status = ntlmssp_client_start(talloc_tos(),
335                                       lp_netbios_name(),
336                                       lp_workgroup(),
337                                       lp_client_ntlmv2_auth(),
338                                       &ntlmssp);
339         if (!NT_STATUS_IS_OK(status)) {
340                 printf("ntlmssp_client_start returned %s\n", nt_errstr(status));
341                 return false;
342         }
343
344         ntlmssp_want_feature(ntlmssp,
345                              NTLMSSP_FEATURE_SESSION_KEY);
346         status = ntlmssp_set_username(ntlmssp, username);
347         if (!NT_STATUS_IS_OK(status)) {
348                 printf("ntlmssp_set_username returned %s\n", nt_errstr(status));
349                 return false;
350         }
351
352         status = ntlmssp_set_domain(ntlmssp, workgroup);
353         if (!NT_STATUS_IS_OK(status)) {
354                 printf("ntlmssp_set_domain returned %s\n", nt_errstr(status));
355                 return false;
356         }
357
358         status = ntlmssp_set_password(ntlmssp, password);
359         if (!NT_STATUS_IS_OK(status)) {
360                 printf("ntlmssp_set_password returned %s\n", nt_errstr(status));
361                 return false;
362         }
363
364         status = ntlmssp_update(ntlmssp, data_blob_null, &in_blob);
365         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
366                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
367                 return false;
368         }
369
370         cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
371
372         ev = event_context_init(talloc_tos());
373         if (ev == NULL) {
374                 printf("event_context_init() returned NULL\n");
375                 return false;
376         }
377
378         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
379                                             cli2->conn,
380                                             cli2->timeout,
381                                             cli2->smb2.session,
382                                             0x0, /* in_flags */
383                                             SMB2_CAP_DFS, /* in_capabilities */
384                                             0, /* in_channel */
385                                             cli1->smb2.session, /* in_previous_session */
386                                             &in_blob); /* in_security_buffer */
387         if (subreq == NULL) {
388                 printf("smb2cli_session_setup_send() returned NULL\n");
389                 return false;
390         }
391
392         ok = tevent_req_poll(subreq, ev);
393         if (!ok) {
394                 printf("tevent_req_poll() returned false\n");
395                 return false;
396         }
397
398         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
399                                             NULL, &out_blob);
400         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
401                 printf("smb2cli_session_setup_recv returned %s\n",
402                         nt_errstr(status));
403                 return false;
404         }
405
406         status = ntlmssp_update(ntlmssp, out_blob, &in_blob);
407         if (!NT_STATUS_IS_OK(status)) {
408                 printf("ntlmssp_update returned %s\n", nt_errstr(status));
409                 return false;
410         }
411
412         subreq = smb2cli_session_setup_send(talloc_tos(), ev,
413                                             cli2->conn,
414                                             cli2->timeout,
415                                             cli2->smb2.session,
416                                             0x0, /* in_flags */
417                                             SMB2_CAP_DFS, /* in_capabilities */
418                                             0, /* in_channel */
419                                             cli1->smb2.session, /* in_previous_session */
420                                             &in_blob); /* in_security_buffer */
421         if (subreq == NULL) {
422                 printf("smb2cli_session_setup_send() returned NULL\n");
423                 return false;
424         }
425
426         ok = tevent_req_poll(subreq, ev);
427         if (!ok) {
428                 printf("tevent_req_poll() returned false\n");
429                 return false;
430         }
431
432         status = smb2cli_session_setup_recv(subreq, talloc_tos(),
433                                             &recv_iov, &out_blob);
434         if (!NT_STATUS_IS_OK(status)) {
435                 printf("smb2cli_session_setup_recv returned %s\n",
436                         nt_errstr(status));
437                 return false;
438         }
439
440         status = smb2_signing_check_pdu(ntlmssp->session_key, recv_iov, 3);
441         if (!NT_STATUS_IS_OK(status)) {
442                 printf("check pdu returned %s\n", nt_errstr(status));
443                 return false;
444         }
445
446         /* check file operation on the old client */
447
448         status = smb2cli_flush(cli1, fid_persistent, fid_volatile);
449         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
450                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
451                 return false;
452         }
453
454         status = cli_tree_connect(cli1, share, "?????", "", 0);
455         if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
456                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
457                 return false;
458         }
459
460         /*
461          * checking file operations without signing.
462          * on w2k8r2 at least, flush, read and write also work the same way,
463          * while create gives ACCESS_DENIED without signing
464          */
465         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
466         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
467                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
468                 return false;
469         }
470
471         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
472                                fid_volatile, 0, 0, (const uint8_t *)hello);
473         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
474                 printf("smb2cli_write returned %s\n", nt_errstr(status));
475                 return false;
476         }
477
478         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
479                                fid_volatile, 2, 0,
480                                talloc_tos(), &result, &nread);
481         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
482                 printf("smb2cli_read returned %s\n", nt_errstr(status));
483                 return false;
484         }
485
486         status = smb2cli_create(cli2, "session-reconnect.txt",
487                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
488                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
489                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
490                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
491                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
492                         FILE_CREATE, /* create_disposition, */
493                         FILE_DELETE_ON_CLOSE, /* create_options, */
494                         NULL, /* smb2_create_blobs *blobs */
495                         &fid_persistent,
496                         &fid_volatile);
497         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
498                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
499                 return false;
500         }
501
502         /* now grab the session key and try with signing */
503
504         status = smb2cli_session_update_session_key(cli2->smb2.session,
505                                                     ntlmssp->session_key,
506                                                     recv_iov);
507         if (!NT_STATUS_IS_OK(status)) {
508                 printf("smb2cli_session_update_session_key %s\n", nt_errstr(status));
509                 return false;
510         }
511
512         /* the tid seems to be irrelevant at this stage */
513
514         cli2->smb2.tid = cli1->smb2.tid;
515
516         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
517         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
518                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
519                 return false;
520         }
521
522         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
523                                fid_volatile, 0, 0, (const uint8_t *)hello);
524         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
525                 printf("smb2cli_write returned %s\n", nt_errstr(status));
526                 return false;
527         }
528
529         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
530                                fid_volatile, 2, 0,
531                                talloc_tos(), &result, &nread);
532         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
533                 printf("smb2cli_read returned %s\n", nt_errstr(status));
534                 return false;
535         }
536
537         status = smb2cli_create(cli2, "session-reconnect.txt",
538                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
539                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
540                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
541                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
542                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
543                         FILE_CREATE, /* create_disposition, */
544                         FILE_DELETE_ON_CLOSE, /* create_options, */
545                         NULL, /* smb2_create_blobs *blobs */
546                         &fid_persistent,
547                         &fid_volatile);
548         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
549                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
550                 return false;
551         }
552
553         /* now do a new tcon and test file calls again */
554
555         status = cli_tree_connect(cli2, share, "?????", "", 0);
556         if (!NT_STATUS_IS_OK(status)) {
557                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
558                 return false;
559         }
560
561         status = smb2cli_create(cli2, "session-reconnect.txt",
562                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
563                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
564                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
565                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
566                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
567                         FILE_CREATE, /* create_disposition, */
568                         FILE_DELETE_ON_CLOSE, /* create_options, */
569                         NULL, /* smb2_create_blobs *blobs */
570                         &fid_persistent,
571                         &fid_volatile);
572         if (!NT_STATUS_IS_OK(status)) {
573                 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
574                 return false;
575         }
576
577         status = smb2cli_write(cli2, strlen(hello), 0, fid_persistent,
578                                fid_volatile, 0, 0, (const uint8_t *)hello);
579         if (!NT_STATUS_IS_OK(status)) {
580                 printf("smb2cli_write returned %s\n", nt_errstr(status));
581                 return false;
582         }
583
584         status = smb2cli_flush(cli2, fid_persistent, fid_volatile);
585         if (!NT_STATUS_IS_OK(status)) {
586                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
587                 return false;
588         }
589
590         status = smb2cli_read(cli2, 0x10000, 0, fid_persistent,
591                                fid_volatile, 2, 0,
592                                talloc_tos(), &result, &nread);
593         if (!NT_STATUS_IS_OK(status)) {
594                 printf("smb2cli_read returned %s\n", nt_errstr(status));
595                 return false;
596         }
597
598         if (nread != strlen(hello)) {
599                 printf("smb2cli_read returned %d bytes, expected %d\n",
600                        (int)nread, (int)strlen(hello));
601                 return false;
602         }
603
604         if (memcmp(hello, result, nread) != 0) {
605                 printf("smb2cli_read returned '%s', expected '%s'\n",
606                        result, hello);
607                 return false;
608         }
609
610         return true;
611 }
612
613 bool run_smb2_tcon_dependence(int dummy)
614 {
615         struct cli_state *cli;
616         NTSTATUS status;
617         uint64_t fid_persistent, fid_volatile;
618         const char *hello = "Hello, world\n";
619         uint8_t *result;
620         uint32_t nread;
621
622         printf("Starting SMB2-TCON-DEPENDENCE\n");
623
624         if (!torture_init_connection(&cli)) {
625                 return false;
626         }
627         cli->smb2.pid = 0xFEFF;
628
629         status = smbXcli_negprot(cli->conn, cli->timeout,
630                                  PROTOCOL_SMB2_02, PROTOCOL_SMB2_22);
631         if (!NT_STATUS_IS_OK(status)) {
632                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
633                 return false;
634         }
635
636         status = cli_session_setup(cli, username,
637                                    password, strlen(password),
638                                    password, strlen(password),
639                                    workgroup);
640         if (!NT_STATUS_IS_OK(status)) {
641                 printf("cli_session_setup returned %s\n", nt_errstr(status));
642                 return false;
643         }
644
645         status = cli_tree_connect(cli, share, "?????", "", 0);
646         if (!NT_STATUS_IS_OK(status)) {
647                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
648                 return false;
649         }
650
651         status = smb2cli_create(cli, "tcon_depedence.txt",
652                         SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
653                         SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
654                         SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
655                         FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
656                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
657                         FILE_CREATE, /* create_disposition, */
658                         FILE_DELETE_ON_CLOSE, /* create_options, */
659                         NULL, /* smb2_create_blobs *blobs */
660                         &fid_persistent,
661                         &fid_volatile);
662         if (!NT_STATUS_IS_OK(status)) {
663                 printf("smb2cli_create on cli %s\n", nt_errstr(status));
664                 return false;
665         }
666
667         status = smb2cli_write(cli, strlen(hello), 0, fid_persistent,
668                                fid_volatile, 0, 0, (const uint8_t *)hello);
669         if (!NT_STATUS_IS_OK(status)) {
670                 printf("smb2cli_write returned %s\n", nt_errstr(status));
671                 return false;
672         }
673
674         status = smb2cli_flush(cli, fid_persistent, fid_volatile);
675         if (!NT_STATUS_IS_OK(status)) {
676                 printf("smb2cli_flush returned %s\n", nt_errstr(status));
677                 return false;
678         }
679
680         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
681                                fid_volatile, 2, 0,
682                                talloc_tos(), &result, &nread);
683         if (!NT_STATUS_IS_OK(status)) {
684                 printf("smb2cli_read returned %s\n", nt_errstr(status));
685                 return false;
686         }
687
688         if (nread != strlen(hello)) {
689                 printf("smb2cli_read returned %d bytes, expected %d\n",
690                        (int)nread, (int)strlen(hello));
691                 return false;
692         }
693
694         if (memcmp(hello, result, nread) != 0) {
695                 printf("smb2cli_read returned '%s', expected '%s'\n",
696                        result, hello);
697                 return false;
698         }
699
700         /* check behaviour with wrong tid... */
701
702         cli->smb2.tid++;
703
704         status = smb2cli_read(cli, 0x10000, 0, fid_persistent,
705                                fid_volatile, 2, 0,
706                                talloc_tos(), &result, &nread);
707         if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
708                 printf("smb2cli_read returned %s\n", nt_errstr(status));
709                 return false;
710         }
711
712         cli->smb2.tid--;
713
714         return true;
715 }