Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Initial test for the smb2 client lib
4 : Copyright (C) Volker Lendecke 2011
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "torture/proto.h"
22 : #include "client.h"
23 : #include "trans2.h"
24 : #include "../libcli/smb/smbXcli_base.h"
25 : #include "libcli/security/security.h"
26 : #include "libsmb/proto.h"
27 : #include "auth/credentials/credentials.h"
28 : #include "auth/gensec/gensec.h"
29 : #include "auth_generic.h"
30 : #include "../librpc/ndr/libndr.h"
31 : #include "libsmb/clirap.h"
32 : #include "libsmb/cli_smb2_fnum.h"
33 :
34 : extern fstring host, workgroup, share, password, username, myname;
35 : extern struct cli_credentials *torture_creds;
36 :
37 1 : bool run_smb2_basic(int dummy)
38 : {
39 : struct cli_state *cli;
40 : NTSTATUS status;
41 : uint64_t fid_persistent, fid_volatile;
42 1 : const char *hello = "Hello, world\n";
43 : uint8_t *result;
44 : uint32_t nread;
45 : uint8_t *dir_data;
46 : uint32_t dir_data_length;
47 1 : uint32_t saved_tid = 0;
48 1 : struct smbXcli_tcon *saved_tcon = NULL;
49 1 : char *saved_share = NULL;
50 1 : uint64_t saved_uid = 0;
51 :
52 1 : printf("Starting SMB2-BASIC\n");
53 :
54 1 : if (!torture_init_connection(&cli)) {
55 0 : return false;
56 : }
57 :
58 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
59 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
60 1 : if (!NT_STATUS_IS_OK(status)) {
61 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
62 0 : return false;
63 : }
64 :
65 1 : status = cli_session_setup_creds(cli, torture_creds);
66 1 : if (!NT_STATUS_IS_OK(status)) {
67 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
68 0 : return false;
69 : }
70 :
71 1 : status = cli_tree_connect(cli, share, "?????", NULL);
72 1 : if (!NT_STATUS_IS_OK(status)) {
73 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
74 0 : return false;
75 : }
76 :
77 1 : status = smb2cli_create(
78 1 : cli->conn,
79 1 : cli->timeout,
80 1 : cli->smb2.session,
81 1 : cli->smb2.tcon,
82 : "smb2-basic.txt",
83 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
84 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
85 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
86 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
87 : FILE_SHARE_READ|
88 : FILE_SHARE_WRITE|
89 : FILE_SHARE_DELETE, /* share_access, */
90 : FILE_CREATE, /* create_disposition, */
91 : FILE_DELETE_ON_CLOSE, /* create_options, */
92 : NULL, /* smb2_create_blobs *blobs */
93 : &fid_persistent,
94 : &fid_volatile,
95 : NULL,
96 : NULL,
97 : NULL,
98 : NULL);
99 1 : if (!NT_STATUS_IS_OK(status)) {
100 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
101 0 : return false;
102 : }
103 :
104 1 : status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
105 1 : cli->smb2.tcon, strlen(hello), 0, fid_persistent,
106 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
107 1 : if (!NT_STATUS_IS_OK(status)) {
108 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
109 0 : return false;
110 : }
111 :
112 1 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
113 1 : cli->smb2.tcon, fid_persistent, fid_volatile);
114 1 : if (!NT_STATUS_IS_OK(status)) {
115 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
116 0 : return false;
117 : }
118 :
119 1 : status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
120 1 : cli->smb2.tcon, 0x10000, 0, fid_persistent,
121 : fid_volatile, 2, 0,
122 : talloc_tos(), &result, &nread);
123 1 : if (!NT_STATUS_IS_OK(status)) {
124 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
125 0 : return false;
126 : }
127 :
128 1 : if (nread != strlen(hello)) {
129 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
130 0 : (int)nread, (int)strlen(hello));
131 0 : return false;
132 : }
133 :
134 1 : if (memcmp(hello, result, nread) != 0) {
135 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
136 : result, hello);
137 0 : return false;
138 : }
139 :
140 1 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
141 1 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
142 1 : if (!NT_STATUS_IS_OK(status)) {
143 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
144 0 : return false;
145 : }
146 :
147 1 : status = smb2cli_create(
148 1 : cli->conn,
149 1 : cli->timeout,
150 1 : cli->smb2.session,
151 1 : cli->smb2.tcon,
152 : "",
153 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
154 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
155 : SEC_STD_SYNCHRONIZE|
156 : SEC_DIR_LIST|
157 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
158 : 0, /* file_attributes, */
159 : FILE_SHARE_READ|
160 : FILE_SHARE_WRITE|
161 : FILE_SHARE_DELETE, /* share_access, */
162 : FILE_OPEN, /* create_disposition, */
163 : FILE_SYNCHRONOUS_IO_NONALERT|
164 : FILE_DIRECTORY_FILE, /* create_options, */
165 : NULL, /* smb2_create_blobs *blobs */
166 : &fid_persistent,
167 : &fid_volatile,
168 : NULL,
169 : NULL,
170 : NULL,
171 : NULL);
172 1 : if (!NT_STATUS_IS_OK(status)) {
173 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
174 0 : return false;
175 : }
176 :
177 1 : status = smb2cli_query_directory(
178 1 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
179 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
180 : talloc_tos(), &dir_data, &dir_data_length);
181 :
182 1 : if (!NT_STATUS_IS_OK(status)) {
183 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
184 0 : return false;
185 : }
186 :
187 1 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
188 1 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
189 1 : if (!NT_STATUS_IS_OK(status)) {
190 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
191 0 : return false;
192 : }
193 :
194 1 : saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
195 1 : cli_state_save_tcon_share(cli, &saved_tcon, &saved_share);
196 1 : cli->smb2.tcon = smbXcli_tcon_create(cli);
197 1 : smb2cli_tcon_set_values(cli->smb2.tcon,
198 : NULL, /* session */
199 : saved_tid,
200 : 0, /* type */
201 : 0, /* flags */
202 : 0, /* capabilities */
203 : 0 /* maximal_access */);
204 1 : status = smb2cli_tdis(cli->conn,
205 1 : cli->timeout,
206 1 : cli->smb2.session,
207 1 : cli->smb2.tcon);
208 1 : cli_state_restore_tcon_share(cli, saved_tcon, saved_share);
209 1 : if (!NT_STATUS_IS_OK(status)) {
210 0 : printf("smb2cli_tdis returned %s\n", nt_errstr(status));
211 0 : return false;
212 : }
213 :
214 1 : status = smb2cli_tdis(cli->conn,
215 1 : cli->timeout,
216 1 : cli->smb2.session,
217 1 : cli->smb2.tcon);
218 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
219 0 : printf("2nd smb2cli_tdis returned %s\n", nt_errstr(status));
220 0 : return false;
221 : }
222 :
223 1 : saved_uid = smb2cli_session_current_id(cli->smb2.session);
224 1 : status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
225 1 : if (!NT_STATUS_IS_OK(status)) {
226 0 : printf("smb2cli_logoff returned %s\n", nt_errstr(status));
227 0 : return false;
228 : }
229 :
230 1 : cli->smb2.session = smbXcli_session_create(cli, cli->conn);
231 1 : if (cli->smb2.session == NULL) {
232 0 : printf("smbXcli_session_create() returned NULL\n");
233 0 : return false;
234 : }
235 :
236 1 : smb2cli_session_set_id_and_flags(cli->smb2.session, saved_uid, 0);
237 :
238 1 : status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
239 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
240 0 : printf("2nd smb2cli_logoff returned %s\n", nt_errstr(status));
241 0 : return false;
242 : }
243 :
244 1 : return true;
245 : }
246 :
247 0 : bool run_smb2_negprot(int dummy)
248 : {
249 : struct cli_state *cli;
250 : NTSTATUS status;
251 : enum protocol_types protocol;
252 0 : const char *name = NULL;
253 :
254 0 : printf("Starting SMB2-NEGPROT\n");
255 :
256 0 : if (!torture_init_connection(&cli)) {
257 0 : return false;
258 : }
259 :
260 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
261 : PROTOCOL_CORE, PROTOCOL_LATEST);
262 0 : if (!NT_STATUS_IS_OK(status)) {
263 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
264 0 : return false;
265 : }
266 :
267 0 : protocol = smbXcli_conn_protocol(cli->conn);
268 0 : name = smb_protocol_types_string(protocol);
269 :
270 0 : if (protocol >= PROTOCOL_SMB2_02) {
271 0 : printf("Server supports %s\n", name);
272 : } else {
273 0 : printf("Server DOES NOT support SMB2, only %s\n", name);
274 0 : return false;
275 : }
276 :
277 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
278 : protocol, protocol);
279 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
280 0 : !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
281 0 : !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
282 0 : printf("2nd smbXcli_negprot should disconnect - returned %s\n",
283 : nt_errstr(status));
284 0 : return false;
285 : }
286 :
287 0 : if (smbXcli_conn_is_connected(cli->conn)) {
288 0 : printf("2nd smbXcli_negprot should disconnect "
289 : "- still connected\n");
290 0 : return false;
291 : }
292 :
293 0 : return true;
294 : }
295 :
296 1 : bool run_smb2_anonymous(int dummy)
297 : {
298 1 : struct cli_state *cli = NULL;
299 : NTSTATUS status;
300 1 : struct cli_credentials *anon_creds = NULL;
301 1 : bool guest = false;
302 :
303 1 : printf("Starting SMB2-ANONYMOUS\n");
304 :
305 1 : if (!torture_init_connection(&cli)) {
306 0 : return false;
307 : }
308 :
309 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
310 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
311 1 : if (!NT_STATUS_IS_OK(status)) {
312 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
313 0 : return false;
314 : }
315 :
316 1 : anon_creds = cli_credentials_init_anon(talloc_tos());
317 1 : if (anon_creds == NULL) {
318 0 : printf("cli_credentials_init_anon failed\n");
319 0 : return false;
320 : }
321 :
322 1 : status = cli_session_setup_creds(cli, anon_creds);
323 1 : if (!NT_STATUS_IS_OK(status)) {
324 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
325 0 : return false;
326 : }
327 :
328 1 : guest = smbXcli_session_is_guest(cli->smb2.session);
329 1 : if (guest) {
330 0 : printf("anonymous session should not have guest authentication\n");
331 0 : return false;
332 : }
333 :
334 1 : return true;
335 : }
336 :
337 0 : bool run_smb2_session_reconnect(int dummy)
338 : {
339 : struct cli_state *cli1;
340 : struct cli_state *cli2;
341 : NTSTATUS status;
342 : bool ok;
343 : uint64_t fid_persistent, fid_volatile;
344 : struct tevent_context *ev;
345 : struct tevent_req *subreq;
346 0 : DATA_BLOB in_blob = data_blob_null;
347 : DATA_BLOB out_blob;
348 : DATA_BLOB session_key;
349 : struct auth_generic_state *auth_generic_state;
350 : struct iovec *recv_iov;
351 0 : const char *hello = "Hello, world\n";
352 : uint8_t *result;
353 : uint32_t nread;
354 :
355 0 : printf("Starting SMB2-SESSION-RECONNECT\n");
356 :
357 0 : if (!torture_init_connection(&cli1)) {
358 0 : return false;
359 : }
360 :
361 0 : status = smbXcli_negprot(cli1->conn, cli1->timeout,
362 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
363 0 : if (!NT_STATUS_IS_OK(status)) {
364 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
365 0 : return false;
366 : }
367 :
368 0 : status = cli_session_setup_creds(cli1, torture_creds);
369 0 : if (!NT_STATUS_IS_OK(status)) {
370 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
371 0 : return false;
372 : }
373 :
374 0 : status = cli_tree_connect(cli1, share, "?????", NULL);
375 0 : if (!NT_STATUS_IS_OK(status)) {
376 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
377 0 : return false;
378 : }
379 :
380 0 : status = smb2cli_create(
381 0 : cli1->conn,
382 0 : cli1->timeout,
383 0 : cli1->smb2.session,
384 0 : cli1->smb2.tcon,
385 : "session-reconnect.txt",
386 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
387 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
388 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
389 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
390 : FILE_SHARE_READ|
391 : FILE_SHARE_WRITE|
392 : FILE_SHARE_DELETE, /* share_access, */
393 : FILE_CREATE, /* create_disposition, */
394 : FILE_DELETE_ON_CLOSE, /* create_options, */
395 : NULL, /* smb2_create_blobs *blobs */
396 : &fid_persistent,
397 : &fid_volatile,
398 : NULL,
399 : NULL,
400 : NULL,
401 : NULL);
402 0 : if (!NT_STATUS_IS_OK(status)) {
403 0 : printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
404 0 : return false;
405 : }
406 :
407 0 : status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
408 0 : cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
409 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
410 0 : if (!NT_STATUS_IS_OK(status)) {
411 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
412 0 : return false;
413 : }
414 :
415 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
416 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
417 0 : if (!NT_STATUS_IS_OK(status)) {
418 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
419 0 : return false;
420 : }
421 :
422 0 : status = smb2cli_read(cli1->conn, cli1->timeout, cli1->smb2.session,
423 0 : cli1->smb2.tcon, 0x10000, 0, fid_persistent,
424 : fid_volatile, 2, 0,
425 : talloc_tos(), &result, &nread);
426 0 : if (!NT_STATUS_IS_OK(status)) {
427 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
428 0 : return false;
429 : }
430 :
431 0 : if (nread != strlen(hello)) {
432 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
433 0 : (int)nread, (int)strlen(hello));
434 0 : return false;
435 : }
436 :
437 0 : if (memcmp(hello, result, nread) != 0) {
438 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
439 : result, hello);
440 0 : return false;
441 : }
442 :
443 : /* prepare second session */
444 :
445 0 : if (!torture_init_connection(&cli2)) {
446 0 : return false;
447 : }
448 :
449 0 : status = smbXcli_negprot(cli2->conn, cli2->timeout,
450 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
451 0 : if (!NT_STATUS_IS_OK(status)) {
452 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
453 0 : return false;
454 : }
455 :
456 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
457 0 : if (!NT_STATUS_IS_OK(status)) {
458 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
459 0 : return false;
460 : }
461 :
462 0 : gensec_want_feature(auth_generic_state->gensec_security,
463 : GENSEC_FEATURE_SESSION_KEY);
464 :
465 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
466 0 : if (!NT_STATUS_IS_OK(status)) {
467 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
468 0 : return false;
469 : }
470 :
471 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
472 0 : if (!NT_STATUS_IS_OK(status)) {
473 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
474 0 : return false;
475 : }
476 :
477 0 : ev = samba_tevent_context_init(talloc_tos());
478 0 : if (ev == NULL) {
479 0 : printf("samba_tevent_context_init() returned NULL\n");
480 0 : return false;
481 : }
482 :
483 0 : status = gensec_update(auth_generic_state->gensec_security,
484 : talloc_tos(), data_blob_null, &in_blob);
485 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
486 0 : printf("gensec_update returned %s\n", nt_errstr(status));
487 0 : return false;
488 : }
489 :
490 0 : cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
491 :
492 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
493 0 : cli2->conn,
494 0 : cli2->timeout,
495 0 : cli2->smb2.session,
496 : 0x0, /* in_flags */
497 : SMB2_CAP_DFS, /* in_capabilities */
498 : 0, /* in_channel */
499 : /* in_previous_session_id: */
500 0 : smb2cli_session_current_id(cli1->smb2.session),
501 : &in_blob); /* in_security_buffer */
502 0 : if (subreq == NULL) {
503 0 : printf("smb2cli_session_setup_send() returned NULL\n");
504 0 : return false;
505 : }
506 :
507 0 : ok = tevent_req_poll(subreq, ev);
508 0 : if (!ok) {
509 0 : printf("tevent_req_poll() returned false\n");
510 0 : return false;
511 : }
512 :
513 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
514 : NULL, &out_blob);
515 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
516 0 : printf("smb2cli_session_setup_recv returned %s\n",
517 : nt_errstr(status));
518 0 : return false;
519 : }
520 :
521 0 : status = gensec_update(auth_generic_state->gensec_security,
522 : talloc_tos(), out_blob, &in_blob);
523 0 : if (!NT_STATUS_IS_OK(status)) {
524 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
525 0 : return false;
526 : }
527 :
528 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
529 0 : cli2->conn,
530 0 : cli2->timeout,
531 0 : cli2->smb2.session,
532 : 0x0, /* in_flags */
533 : SMB2_CAP_DFS, /* in_capabilities */
534 : 0, /* in_channel */
535 : /* in_previous_session_id: */
536 0 : smb2cli_session_current_id(cli1->smb2.session),
537 : &in_blob); /* in_security_buffer */
538 0 : if (subreq == NULL) {
539 0 : printf("smb2cli_session_setup_send() returned NULL\n");
540 0 : return false;
541 : }
542 :
543 0 : ok = tevent_req_poll(subreq, ev);
544 0 : if (!ok) {
545 0 : printf("tevent_req_poll() returned false\n");
546 0 : return false;
547 : }
548 :
549 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
550 : &recv_iov, &out_blob);
551 0 : if (!NT_STATUS_IS_OK(status)) {
552 0 : printf("smb2cli_session_setup_recv returned %s\n",
553 : nt_errstr(status));
554 0 : return false;
555 : }
556 :
557 0 : status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
558 : &session_key);
559 0 : if (!NT_STATUS_IS_OK(status)) {
560 0 : printf("gensec_session_key returned %s\n",
561 : nt_errstr(status));
562 0 : return false;
563 : }
564 :
565 : /* check file operation on the old client */
566 :
567 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
568 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
569 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
570 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
571 0 : return false;
572 : }
573 :
574 0 : status = cli_tree_connect(cli1, share, "?????", NULL);
575 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
576 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
577 0 : return false;
578 : }
579 :
580 : /*
581 : * checking file operations without signing.
582 : * on w2k8r2 at least, flush, read and write also work the same way,
583 : * while create gives ACCESS_DENIED without signing
584 : */
585 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
586 0 : cli2->smb2.tcon, fid_persistent, fid_volatile);
587 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
588 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
589 : {
590 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
591 0 : return false;
592 : }
593 :
594 0 : status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
595 0 : cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
596 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
597 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
598 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
599 : {
600 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
601 0 : return false;
602 : }
603 :
604 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
605 0 : cli2->smb2.tcon, 0x10000, 0, fid_persistent,
606 : fid_volatile, 2, 0,
607 : talloc_tos(), &result, &nread);
608 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
609 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
610 : {
611 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
612 0 : return false;
613 : }
614 :
615 0 : status = smb2cli_create(
616 0 : cli2->conn,
617 0 : cli2->timeout,
618 0 : cli2->smb2.session,
619 0 : cli2->smb2.tcon,
620 : "session-reconnect.txt",
621 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
622 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
623 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
624 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
625 : FILE_SHARE_READ|
626 : FILE_SHARE_WRITE|
627 : FILE_SHARE_DELETE, /* share_access, */
628 : FILE_CREATE, /* create_disposition, */
629 : FILE_DELETE_ON_CLOSE, /* create_options, */
630 : NULL, /* smb2_create_blobs *blobs */
631 : &fid_persistent,
632 : &fid_volatile,
633 : NULL,
634 : NULL,
635 : NULL,
636 : NULL);
637 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
638 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
639 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
640 0 : return false;
641 : }
642 :
643 : /* now grab the session key and try with signing */
644 :
645 0 : status = smb2cli_session_set_session_key(cli2->smb2.session,
646 : session_key,
647 : recv_iov);
648 0 : if (!NT_STATUS_IS_OK(status)) {
649 0 : printf("smb2cli_session_set_session_key %s\n", nt_errstr(status));
650 0 : return false;
651 : }
652 :
653 : /* the tid seems to be irrelevant at this stage */
654 :
655 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
656 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
657 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
658 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
659 : {
660 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
661 0 : return false;
662 : }
663 :
664 0 : status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
665 0 : cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
666 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
667 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
668 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
669 : {
670 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
671 0 : return false;
672 : }
673 :
674 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
675 0 : cli1->smb2.tcon, 0x10000, 0, fid_persistent,
676 : fid_volatile, 2, 0,
677 : talloc_tos(), &result, &nread);
678 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
679 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
680 : {
681 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
682 0 : return false;
683 : }
684 :
685 0 : status = smb2cli_create(
686 0 : cli2->conn,
687 0 : cli2->timeout,
688 0 : cli2->smb2.session,
689 0 : cli1->smb2.tcon,
690 : "session-reconnect.txt",
691 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
692 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
693 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
694 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
695 : FILE_SHARE_READ|
696 : FILE_SHARE_WRITE|
697 : FILE_SHARE_DELETE, /* share_access, */
698 : FILE_CREATE, /* create_disposition, */
699 : FILE_DELETE_ON_CLOSE, /* create_options, */
700 : NULL, /* smb2_create_blobs *blobs */
701 : &fid_persistent,
702 : &fid_volatile,
703 : NULL,
704 : NULL,
705 : NULL,
706 : NULL);
707 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) &&
708 0 : !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
709 : {
710 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
711 0 : return false;
712 : }
713 :
714 : /* now do a new tcon and test file calls again */
715 :
716 0 : status = cli_tree_connect(cli2, share, "?????", NULL);
717 0 : if (!NT_STATUS_IS_OK(status)) {
718 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
719 0 : return false;
720 : }
721 :
722 0 : status = smb2cli_create(
723 0 : cli2->conn,
724 0 : cli2->timeout,
725 0 : cli2->smb2.session,
726 0 : cli2->smb2.tcon,
727 : "session-reconnect.txt",
728 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
729 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
730 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
731 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
732 : FILE_SHARE_READ|
733 : FILE_SHARE_WRITE|
734 : FILE_SHARE_DELETE, /* share_access, */
735 : FILE_CREATE, /* create_disposition, */
736 : FILE_DELETE_ON_CLOSE, /* create_options, */
737 : NULL, /* smb2_create_blobs *blobs */
738 : &fid_persistent,
739 : &fid_volatile,
740 : NULL,
741 : NULL,
742 : NULL,
743 : NULL);
744 0 : if (!NT_STATUS_IS_OK(status)) {
745 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
746 0 : return false;
747 : }
748 :
749 0 : status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
750 0 : cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
751 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
752 0 : if (!NT_STATUS_IS_OK(status)) {
753 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
754 0 : return false;
755 : }
756 :
757 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
758 0 : cli2->smb2.tcon, fid_persistent, fid_volatile);
759 0 : if (!NT_STATUS_IS_OK(status)) {
760 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
761 0 : return false;
762 : }
763 :
764 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
765 0 : cli2->smb2.tcon, 0x10000, 0, fid_persistent,
766 : fid_volatile, 2, 0,
767 : talloc_tos(), &result, &nread);
768 0 : if (!NT_STATUS_IS_OK(status)) {
769 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
770 0 : return false;
771 : }
772 :
773 0 : if (nread != strlen(hello)) {
774 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
775 0 : (int)nread, (int)strlen(hello));
776 0 : return false;
777 : }
778 :
779 0 : if (memcmp(hello, result, nread) != 0) {
780 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
781 : result, hello);
782 0 : return false;
783 : }
784 :
785 0 : return true;
786 : }
787 :
788 0 : bool run_smb2_tcon_dependence(int dummy)
789 : {
790 : struct cli_state *cli;
791 : NTSTATUS status;
792 : uint64_t fid_persistent, fid_volatile;
793 0 : const char *hello = "Hello, world\n";
794 : uint8_t *result;
795 : uint32_t nread;
796 : struct smbXcli_tcon *tcon2;
797 : uint32_t tcon2_id;
798 :
799 0 : printf("Starting SMB2-TCON-DEPENDENCE\n");
800 :
801 0 : if (!torture_init_connection(&cli)) {
802 0 : return false;
803 : }
804 :
805 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
806 : PROTOCOL_SMB2_02, PROTOCOL_LATEST);
807 0 : if (!NT_STATUS_IS_OK(status)) {
808 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
809 0 : return false;
810 : }
811 :
812 0 : status = cli_session_setup_creds(cli, torture_creds);
813 0 : if (!NT_STATUS_IS_OK(status)) {
814 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
815 0 : return false;
816 : }
817 :
818 0 : status = cli_tree_connect(cli, share, "?????", NULL);
819 0 : if (!NT_STATUS_IS_OK(status)) {
820 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
821 0 : return false;
822 : }
823 :
824 0 : status = smb2cli_create(
825 0 : cli->conn,
826 0 : cli->timeout,
827 0 : cli->smb2.session,
828 0 : cli->smb2.tcon,
829 : "tcon_depedence.txt",
830 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
831 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
832 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
833 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
834 : FILE_SHARE_READ|
835 : FILE_SHARE_WRITE|
836 : FILE_SHARE_DELETE, /* share_access, */
837 : FILE_CREATE, /* create_disposition, */
838 : FILE_DELETE_ON_CLOSE, /* create_options, */
839 : NULL, /* smb2_create_blobs *blobs */
840 : &fid_persistent,
841 : &fid_volatile,
842 : NULL,
843 : NULL,
844 : NULL,
845 : NULL);
846 0 : if (!NT_STATUS_IS_OK(status)) {
847 0 : printf("smb2cli_create on cli %s\n", nt_errstr(status));
848 0 : return false;
849 : }
850 :
851 0 : status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
852 0 : cli->smb2.tcon, strlen(hello), 0, fid_persistent,
853 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
854 0 : if (!NT_STATUS_IS_OK(status)) {
855 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
856 0 : return false;
857 : }
858 :
859 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
860 0 : cli->smb2.tcon, fid_persistent, fid_volatile);
861 0 : if (!NT_STATUS_IS_OK(status)) {
862 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
863 0 : return false;
864 : }
865 :
866 0 : status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
867 0 : cli->smb2.tcon, 0x10000, 0, fid_persistent,
868 : fid_volatile, 2, 0,
869 : talloc_tos(), &result, &nread);
870 0 : if (!NT_STATUS_IS_OK(status)) {
871 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
872 0 : return false;
873 : }
874 :
875 0 : if (nread != strlen(hello)) {
876 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
877 0 : (int)nread, (int)strlen(hello));
878 0 : return false;
879 : }
880 :
881 0 : if (memcmp(hello, result, nread) != 0) {
882 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
883 : result, hello);
884 0 : return false;
885 : }
886 :
887 : /* check behaviour with wrong tid... */
888 :
889 0 : tcon2 = smbXcli_tcon_create(cli);
890 0 : tcon2_id = smb2cli_tcon_current_id(cli->smb2.tcon);
891 0 : tcon2_id++;
892 0 : smb2cli_tcon_set_values(tcon2,
893 : NULL, /* session */
894 : tcon2_id,
895 : 0, /* type */
896 : 0, /* flags */
897 : 0, /* capabilities */
898 : 0 /* maximal_access */);
899 :
900 0 : status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
901 : tcon2, 0x10000, 0, fid_persistent,
902 : fid_volatile, 2, 0,
903 : talloc_tos(), &result, &nread);
904 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
905 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
906 0 : return false;
907 : }
908 :
909 0 : talloc_free(tcon2);
910 :
911 0 : return true;
912 : }
913 :
914 0 : bool run_smb2_multi_channel(int dummy)
915 : {
916 : struct cli_state *cli1;
917 : struct cli_state *cli2;
918 : struct cli_state *cli3;
919 : NTSTATUS status;
920 : bool ok;
921 : uint64_t fid_persistent, fid_volatile;
922 : struct tevent_context *ev;
923 : struct tevent_req *subreq;
924 0 : DATA_BLOB in_blob = data_blob_null;
925 : DATA_BLOB out_blob;
926 : DATA_BLOB channel_session_key;
927 : struct auth_generic_state *auth_generic_state;
928 : struct iovec *recv_iov;
929 0 : const char *hello = "Hello, world\n";
930 : uint8_t *result;
931 : uint32_t nread;
932 0 : struct GUID saved_guid = cli_state_client_guid;
933 :
934 0 : printf("Starting SMB2-MULTI-CHANNEL\n");
935 :
936 0 : cli_state_client_guid = GUID_random();
937 :
938 0 : if (!torture_init_connection(&cli1)) {
939 0 : return false;
940 : }
941 :
942 0 : if (!torture_init_connection(&cli2)) {
943 0 : return false;
944 : }
945 :
946 0 : if (!torture_init_connection(&cli3)) {
947 0 : return false;
948 : }
949 :
950 0 : cli_state_client_guid = saved_guid;
951 :
952 0 : status = smbXcli_negprot(cli1->conn, cli1->timeout,
953 : PROTOCOL_SMB3_00, PROTOCOL_LATEST);
954 0 : if (!NT_STATUS_IS_OK(status)) {
955 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
956 0 : return false;
957 : }
958 :
959 0 : status = smbXcli_negprot(cli2->conn, cli2->timeout,
960 : PROTOCOL_SMB3_00, PROTOCOL_LATEST);
961 0 : if (!NT_STATUS_IS_OK(status)) {
962 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
963 0 : return false;
964 : }
965 :
966 0 : status = smbXcli_negprot(cli3->conn, cli3->timeout,
967 : PROTOCOL_SMB3_00, PROTOCOL_LATEST);
968 0 : if (!NT_STATUS_IS_OK(status)) {
969 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
970 0 : return false;
971 : }
972 :
973 0 : status = cli_session_setup_creds(cli1, torture_creds);
974 0 : if (!NT_STATUS_IS_OK(status)) {
975 0 : printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
976 0 : return false;
977 : }
978 :
979 0 : status = cli_tree_connect(cli1, share, "?????", NULL);
980 0 : if (!NT_STATUS_IS_OK(status)) {
981 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
982 0 : return false;
983 : }
984 :
985 0 : status = smb2cli_session_create_channel(cli2,
986 0 : cli1->smb2.session,
987 0 : cli2->conn,
988 0 : &cli2->smb2.session);
989 0 : if (!NT_STATUS_IS_OK(status)) {
990 0 : printf("smb2cli_session_create_channel returned %s\n",
991 : nt_errstr(status));
992 0 : return false;
993 : }
994 :
995 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
996 0 : if (!NT_STATUS_IS_OK(status)) {
997 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
998 0 : return false;
999 : }
1000 :
1001 0 : gensec_want_feature(auth_generic_state->gensec_security,
1002 : GENSEC_FEATURE_SESSION_KEY);
1003 :
1004 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
1005 0 : if (!NT_STATUS_IS_OK(status)) {
1006 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1007 0 : return false;
1008 : }
1009 :
1010 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1011 0 : if (!NT_STATUS_IS_OK(status)) {
1012 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1013 0 : return false;
1014 : }
1015 :
1016 0 : ev = samba_tevent_context_init(talloc_tos());
1017 0 : if (ev == NULL) {
1018 0 : printf("samba_tevent_context_init() returned NULL\n");
1019 0 : return false;
1020 : }
1021 :
1022 0 : status = gensec_update(auth_generic_state->gensec_security,
1023 : talloc_tos(), data_blob_null, &in_blob);
1024 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1025 0 : printf("gensec_update returned %s\n", nt_errstr(status));
1026 0 : return false;
1027 : }
1028 :
1029 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1030 0 : cli2->conn,
1031 0 : cli2->timeout,
1032 0 : cli2->smb2.session,
1033 : 0x01, /* in_flags */
1034 : SMB2_CAP_DFS, /* in_capabilities */
1035 : 0, /* in_channel */
1036 : 0, /* in_previous_session_id */
1037 : &in_blob); /* in_security_buffer */
1038 0 : if (subreq == NULL) {
1039 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1040 0 : return false;
1041 : }
1042 :
1043 0 : ok = tevent_req_poll(subreq, ev);
1044 0 : if (!ok) {
1045 0 : printf("tevent_req_poll() returned false\n");
1046 0 : return false;
1047 : }
1048 :
1049 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1050 : NULL, &out_blob);
1051 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1052 0 : printf("smb2cli_session_setup_recv returned %s\n",
1053 : nt_errstr(status));
1054 0 : return false;
1055 : }
1056 :
1057 0 : status = gensec_update(auth_generic_state->gensec_security,
1058 : talloc_tos(), out_blob, &in_blob);
1059 0 : if (!NT_STATUS_IS_OK(status)) {
1060 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
1061 0 : return false;
1062 : }
1063 :
1064 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1065 0 : cli2->conn,
1066 0 : cli2->timeout,
1067 0 : cli2->smb2.session,
1068 : 0x01, /* in_flags */
1069 : SMB2_CAP_DFS, /* in_capabilities */
1070 : 0, /* in_channel */
1071 : 0, /* in_previous_session_id */
1072 : &in_blob); /* in_security_buffer */
1073 0 : if (subreq == NULL) {
1074 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1075 0 : return false;
1076 : }
1077 :
1078 0 : ok = tevent_req_poll(subreq, ev);
1079 0 : if (!ok) {
1080 0 : printf("tevent_req_poll() returned false\n");
1081 0 : return false;
1082 : }
1083 :
1084 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1085 : &recv_iov, &out_blob);
1086 0 : if (!NT_STATUS_IS_OK(status)) {
1087 0 : printf("smb2cli_session_setup_recv returned %s\n",
1088 : nt_errstr(status));
1089 0 : return false;
1090 : }
1091 :
1092 0 : status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1093 : &channel_session_key);
1094 0 : if (!NT_STATUS_IS_OK(status)) {
1095 0 : printf("gensec_session_key returned %s\n",
1096 : nt_errstr(status));
1097 0 : return false;
1098 : }
1099 :
1100 0 : status = smb2cli_session_set_channel_key(cli2->smb2.session,
1101 : channel_session_key,
1102 : recv_iov);
1103 0 : if (!NT_STATUS_IS_OK(status)) {
1104 0 : printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1105 0 : return false;
1106 : }
1107 :
1108 0 : status = smb2cli_session_create_channel(cli3,
1109 0 : cli1->smb2.session,
1110 0 : cli3->conn,
1111 0 : &cli3->smb2.session);
1112 0 : if (!NT_STATUS_IS_OK(status)) {
1113 0 : printf("smb2cli_session_create_channel returned %s\n",
1114 : nt_errstr(status));
1115 0 : return false;
1116 : }
1117 :
1118 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1119 0 : if (!NT_STATUS_IS_OK(status)) {
1120 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1121 0 : return false;
1122 : }
1123 :
1124 0 : gensec_want_feature(auth_generic_state->gensec_security,
1125 : GENSEC_FEATURE_SESSION_KEY);
1126 :
1127 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
1128 0 : if (!NT_STATUS_IS_OK(status)) {
1129 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1130 0 : return false;
1131 : }
1132 :
1133 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1134 0 : if (!NT_STATUS_IS_OK(status)) {
1135 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1136 0 : return false;
1137 : }
1138 :
1139 0 : status = gensec_update(auth_generic_state->gensec_security,
1140 : talloc_tos(), data_blob_null, &in_blob);
1141 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1142 0 : printf("gensec_update returned %s\n", nt_errstr(status));
1143 0 : return false;
1144 : }
1145 :
1146 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1147 0 : cli3->conn,
1148 0 : cli3->timeout,
1149 0 : cli3->smb2.session,
1150 : 0x01, /* in_flags */
1151 : SMB2_CAP_DFS, /* in_capabilities */
1152 : 0, /* in_channel */
1153 : 0, /* in_previous_session_id */
1154 : &in_blob); /* in_security_buffer */
1155 0 : if (subreq == NULL) {
1156 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1157 0 : return false;
1158 : }
1159 :
1160 0 : ok = tevent_req_poll(subreq, ev);
1161 0 : if (!ok) {
1162 0 : printf("tevent_req_poll() returned false\n");
1163 0 : return false;
1164 : }
1165 :
1166 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1167 : NULL, &out_blob);
1168 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1169 0 : printf("smb2cli_session_setup_recv returned %s\n",
1170 : nt_errstr(status));
1171 0 : return false;
1172 : }
1173 :
1174 0 : status = gensec_update(auth_generic_state->gensec_security,
1175 : talloc_tos(), out_blob, &in_blob);
1176 0 : if (!NT_STATUS_IS_OK(status)) {
1177 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
1178 0 : return false;
1179 : }
1180 :
1181 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1182 0 : cli3->conn,
1183 0 : cli3->timeout,
1184 0 : cli3->smb2.session,
1185 : 0x01, /* in_flags */
1186 : SMB2_CAP_DFS, /* in_capabilities */
1187 : 0, /* in_channel */
1188 : 0, /* in_previous_session_id */
1189 : &in_blob); /* in_security_buffer */
1190 0 : if (subreq == NULL) {
1191 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1192 0 : return false;
1193 : }
1194 :
1195 0 : ok = tevent_req_poll(subreq, ev);
1196 0 : if (!ok) {
1197 0 : printf("tevent_req_poll() returned false\n");
1198 0 : return false;
1199 : }
1200 :
1201 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1202 : &recv_iov, &out_blob);
1203 0 : if (!NT_STATUS_IS_OK(status)) {
1204 0 : printf("smb2cli_session_setup_recv returned %s\n",
1205 : nt_errstr(status));
1206 0 : return false;
1207 : }
1208 :
1209 0 : status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1210 : &channel_session_key);
1211 0 : if (!NT_STATUS_IS_OK(status)) {
1212 0 : printf("gensec_session_key returned %s\n",
1213 : nt_errstr(status));
1214 0 : return false;
1215 : }
1216 :
1217 0 : status = smb2cli_session_set_channel_key(cli3->smb2.session,
1218 : channel_session_key,
1219 : recv_iov);
1220 0 : if (!NT_STATUS_IS_OK(status)) {
1221 0 : printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1222 0 : return false;
1223 : }
1224 :
1225 0 : status = smb2cli_create(
1226 0 : cli2->conn,
1227 0 : cli2->timeout,
1228 0 : cli2->smb2.session,
1229 0 : cli1->smb2.tcon,
1230 : "multi-channel.txt",
1231 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1232 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1233 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1234 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1235 : FILE_SHARE_READ|
1236 : FILE_SHARE_WRITE|
1237 : FILE_SHARE_DELETE, /* share_access, */
1238 : FILE_CREATE, /* create_disposition, */
1239 : FILE_DELETE_ON_CLOSE, /* create_options, */
1240 : NULL, /* smb2_create_blobs *blobs */
1241 : &fid_persistent,
1242 : &fid_volatile,
1243 : NULL,
1244 : NULL,
1245 : NULL,
1246 : NULL);
1247 0 : if (!NT_STATUS_IS_OK(status)) {
1248 0 : printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
1249 0 : return false;
1250 : }
1251 :
1252 0 : status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
1253 0 : cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
1254 : fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
1255 0 : if (!NT_STATUS_IS_OK(status)) {
1256 0 : printf("smb2cli_write returned %s\n", nt_errstr(status));
1257 0 : return false;
1258 : }
1259 :
1260 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1261 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1262 0 : if (!NT_STATUS_IS_OK(status)) {
1263 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1264 0 : return false;
1265 : }
1266 :
1267 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1268 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1269 0 : if (!NT_STATUS_IS_OK(status)) {
1270 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1271 0 : return false;
1272 : }
1273 :
1274 0 : status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1275 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1276 0 : if (!NT_STATUS_IS_OK(status)) {
1277 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1278 0 : return false;
1279 : }
1280 :
1281 0 : status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
1282 0 : cli1->smb2.tcon, 0x10000, 0, fid_persistent,
1283 : fid_volatile, 2, 0,
1284 : talloc_tos(), &result, &nread);
1285 0 : if (!NT_STATUS_IS_OK(status)) {
1286 0 : printf("smb2cli_read returned %s\n", nt_errstr(status));
1287 0 : return false;
1288 : }
1289 :
1290 0 : if (nread != strlen(hello)) {
1291 0 : printf("smb2cli_read returned %d bytes, expected %d\n",
1292 0 : (int)nread, (int)strlen(hello));
1293 0 : return false;
1294 : }
1295 :
1296 0 : if (memcmp(hello, result, nread) != 0) {
1297 0 : printf("smb2cli_read returned '%s', expected '%s'\n",
1298 : result, hello);
1299 0 : return false;
1300 : }
1301 :
1302 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1303 0 : if (!NT_STATUS_IS_OK(status)) {
1304 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1305 0 : return false;
1306 : }
1307 :
1308 0 : gensec_want_feature(auth_generic_state->gensec_security,
1309 : GENSEC_FEATURE_SESSION_KEY);
1310 :
1311 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
1312 0 : if (!NT_STATUS_IS_OK(status)) {
1313 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1314 0 : return false;
1315 : }
1316 :
1317 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1318 0 : if (!NT_STATUS_IS_OK(status)) {
1319 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1320 0 : return false;
1321 : }
1322 :
1323 0 : status = gensec_update(auth_generic_state->gensec_security,
1324 : talloc_tos(), data_blob_null, &in_blob);
1325 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1326 0 : printf("gensec_update returned %s\n", nt_errstr(status));
1327 0 : return false;
1328 : }
1329 :
1330 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1331 0 : cli3->conn,
1332 0 : cli3->timeout,
1333 0 : cli3->smb2.session,
1334 : 0x0, /* in_flags */
1335 : SMB2_CAP_DFS, /* in_capabilities */
1336 : 0, /* in_channel */
1337 : 0, /* in_previous_session_id */
1338 : &in_blob); /* in_security_buffer */
1339 0 : if (subreq == NULL) {
1340 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1341 0 : return false;
1342 : }
1343 :
1344 0 : ok = tevent_req_poll(subreq, ev);
1345 0 : if (!ok) {
1346 0 : printf("tevent_req_poll() returned false\n");
1347 0 : return false;
1348 : }
1349 :
1350 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1351 : NULL, &out_blob);
1352 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1353 0 : printf("smb2cli_session_setup_recv returned %s\n",
1354 : nt_errstr(status));
1355 0 : return false;
1356 : }
1357 :
1358 0 : status = gensec_update(auth_generic_state->gensec_security,
1359 : talloc_tos(), out_blob, &in_blob);
1360 0 : if (!NT_STATUS_IS_OK(status)) {
1361 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
1362 0 : return false;
1363 : }
1364 :
1365 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1366 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1367 0 : if (!NT_STATUS_IS_OK(status)) {
1368 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1369 0 : return false;
1370 : }
1371 :
1372 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1373 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1374 0 : if (!NT_STATUS_IS_OK(status)) {
1375 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1376 0 : return false;
1377 : }
1378 :
1379 0 : status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1380 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1381 0 : if (!NT_STATUS_IS_OK(status)) {
1382 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1383 0 : return false;
1384 : }
1385 :
1386 0 : status = smb2cli_create(
1387 0 : cli1->conn,
1388 0 : cli1->timeout,
1389 0 : cli1->smb2.session,
1390 0 : cli1->smb2.tcon,
1391 : "multi-channel-invalid.txt",
1392 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1393 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1394 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1395 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1396 : FILE_SHARE_READ|
1397 : FILE_SHARE_WRITE|
1398 : FILE_SHARE_DELETE, /* share_access, */
1399 : FILE_CREATE, /* create_disposition, */
1400 : FILE_DELETE_ON_CLOSE, /* create_options, */
1401 : NULL, /* smb2_create_blobs *blobs */
1402 : &fid_persistent,
1403 : &fid_volatile,
1404 : NULL,
1405 : NULL,
1406 : NULL,
1407 : NULL);
1408 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1409 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1410 0 : return false;
1411 : }
1412 :
1413 0 : status = smb2cli_create(
1414 0 : cli2->conn,
1415 0 : cli2->timeout,
1416 0 : cli2->smb2.session,
1417 0 : cli1->smb2.tcon,
1418 : "multi-channel-invalid.txt",
1419 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1420 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1421 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1422 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1423 : FILE_SHARE_READ|
1424 : FILE_SHARE_WRITE|
1425 : FILE_SHARE_DELETE, /* share_access, */
1426 : FILE_CREATE, /* create_disposition, */
1427 : FILE_DELETE_ON_CLOSE, /* create_options, */
1428 : NULL, /* smb2_create_blobs *blobs */
1429 : &fid_persistent,
1430 : &fid_volatile,
1431 : NULL,
1432 : NULL,
1433 : NULL,
1434 : NULL);
1435 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1436 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1437 0 : return false;
1438 : }
1439 :
1440 0 : status = smb2cli_create(
1441 0 : cli3->conn,
1442 0 : cli3->timeout,
1443 0 : cli3->smb2.session,
1444 0 : cli1->smb2.tcon,
1445 : "multi-channel-invalid.txt",
1446 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1447 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1448 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1449 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1450 : FILE_SHARE_READ|
1451 : FILE_SHARE_WRITE|
1452 : FILE_SHARE_DELETE, /* share_access, */
1453 : FILE_CREATE, /* create_disposition, */
1454 : FILE_DELETE_ON_CLOSE, /* create_options, */
1455 : NULL, /* smb2_create_blobs *blobs */
1456 : &fid_persistent,
1457 : &fid_volatile,
1458 : NULL,
1459 : NULL,
1460 : NULL,
1461 : NULL);
1462 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1463 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1464 0 : return false;
1465 : }
1466 :
1467 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1468 0 : cli2->conn,
1469 0 : cli2->timeout,
1470 0 : cli2->smb2.session,
1471 : 0x0, /* in_flags */
1472 : SMB2_CAP_DFS, /* in_capabilities */
1473 : 0, /* in_channel */
1474 : 0, /* in_previous_session_id */
1475 : &in_blob); /* in_security_buffer */
1476 0 : if (subreq == NULL) {
1477 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1478 0 : return false;
1479 : }
1480 :
1481 0 : ok = tevent_req_poll(subreq, ev);
1482 0 : if (!ok) {
1483 0 : printf("tevent_req_poll() returned false\n");
1484 0 : return false;
1485 : }
1486 :
1487 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1488 : &recv_iov, &out_blob);
1489 0 : if (!NT_STATUS_IS_OK(status)) {
1490 0 : printf("smb2cli_session_setup_recv returned %s\n",
1491 : nt_errstr(status));
1492 0 : return false;
1493 : }
1494 :
1495 0 : status = smb2cli_close(cli3->conn, cli3->timeout, cli3->smb2.session,
1496 0 : cli1->smb2.tcon, 0, fid_persistent, fid_volatile);
1497 0 : if (!NT_STATUS_IS_OK(status)) {
1498 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
1499 0 : return false;
1500 : }
1501 :
1502 0 : status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1503 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1504 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1505 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1506 0 : return false;
1507 : }
1508 :
1509 0 : status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1510 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1511 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1512 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1513 0 : return false;
1514 : }
1515 :
1516 0 : status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1517 0 : cli1->smb2.tcon, fid_persistent, fid_volatile);
1518 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1519 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1520 0 : return false;
1521 : }
1522 :
1523 0 : return true;
1524 : }
1525 :
1526 0 : bool run_smb2_session_reauth(int dummy)
1527 : {
1528 : struct cli_state *cli;
1529 : NTSTATUS status;
1530 : bool ok;
1531 : uint64_t fid_persistent, fid_volatile;
1532 : uint64_t dir_persistent, dir_volatile;
1533 : uint8_t *dir_data;
1534 : uint32_t dir_data_length;
1535 : struct tevent_context *ev;
1536 : struct tevent_req *subreq;
1537 0 : DATA_BLOB in_blob = data_blob_null;
1538 : DATA_BLOB out_blob;
1539 : DATA_BLOB in_input_buffer;
1540 : DATA_BLOB out_output_buffer;
1541 : uint8_t in_file_info_class;
1542 : struct auth_generic_state *auth_generic_state;
1543 : struct iovec *recv_iov;
1544 : uint32_t saved_tid;
1545 : struct smbXcli_tcon *saved_tcon;
1546 :
1547 0 : printf("Starting SMB2-SESSION_REAUTH\n");
1548 :
1549 0 : if (!torture_init_connection(&cli)) {
1550 0 : return false;
1551 : }
1552 :
1553 : /*
1554 : * PROTOCOL_SMB2_22 has a bug in win8pre0
1555 : * it behaves like PROTOCOL_SMB2_02
1556 : * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
1557 : * while it allows it on PROTOCOL_SMB2_10.
1558 : */
1559 0 : status = smbXcli_negprot(cli->conn, cli->timeout,
1560 : PROTOCOL_SMB2_10, PROTOCOL_SMB2_10);
1561 0 : if (!NT_STATUS_IS_OK(status)) {
1562 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1563 0 : return false;
1564 : }
1565 :
1566 0 : status = cli_session_setup_creds(cli, torture_creds);
1567 0 : if (!NT_STATUS_IS_OK(status)) {
1568 0 : printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
1569 0 : return false;
1570 : }
1571 :
1572 0 : status = cli_tree_connect(cli, share, "?????", NULL);
1573 0 : if (!NT_STATUS_IS_OK(status)) {
1574 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
1575 0 : return false;
1576 : }
1577 :
1578 0 : status = smb2cli_create(
1579 0 : cli->conn,
1580 0 : cli->timeout,
1581 0 : cli->smb2.session,
1582 0 : cli->smb2.tcon,
1583 : "session-reauth.txt",
1584 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1585 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1586 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1587 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1588 : FILE_SHARE_READ|
1589 : FILE_SHARE_WRITE|
1590 : FILE_SHARE_DELETE, /* share_access, */
1591 : FILE_CREATE, /* create_disposition, */
1592 : FILE_DELETE_ON_CLOSE, /* create_options, */
1593 : NULL, /* smb2_create_blobs *blobs */
1594 : &fid_persistent,
1595 : &fid_volatile,
1596 : NULL,
1597 : NULL,
1598 : NULL,
1599 : NULL);
1600 0 : if (!NT_STATUS_IS_OK(status)) {
1601 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1602 0 : return false;
1603 : }
1604 :
1605 0 : status = smb2cli_create(
1606 0 : cli->conn,
1607 0 : cli->timeout,
1608 0 : cli->smb2.session,
1609 0 : cli->smb2.tcon,
1610 : "",
1611 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1612 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1613 : SEC_STD_SYNCHRONIZE|
1614 : SEC_DIR_LIST|
1615 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1616 : 0, /* file_attributes, */
1617 : FILE_SHARE_READ|
1618 : FILE_SHARE_WRITE|
1619 : FILE_SHARE_DELETE, /* share_access, */
1620 : FILE_OPEN, /* create_disposition, */
1621 : FILE_SYNCHRONOUS_IO_NONALERT|
1622 : FILE_DIRECTORY_FILE, /* create_options, */
1623 : NULL, /* smb2_create_blobs *blobs */
1624 : &dir_persistent,
1625 : &dir_volatile,
1626 : NULL,
1627 : NULL,
1628 : NULL,
1629 : NULL);
1630 0 : if (!NT_STATUS_IS_OK(status)) {
1631 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
1632 0 : return false;
1633 : }
1634 :
1635 0 : status = smb2cli_query_directory(
1636 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1637 : 1, 0x3, 0, dir_persistent, dir_volatile,
1638 : "session-reauth.txt", 0xffff,
1639 : talloc_tos(), &dir_data, &dir_data_length);
1640 0 : if (!NT_STATUS_IS_OK(status)) {
1641 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1642 0 : return false;
1643 : }
1644 :
1645 0 : status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1646 0 : if (!NT_STATUS_IS_OK(status)) {
1647 0 : printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1648 0 : return false;
1649 : }
1650 :
1651 0 : gensec_want_feature(auth_generic_state->gensec_security,
1652 : GENSEC_FEATURE_SESSION_KEY);
1653 :
1654 0 : status = auth_generic_set_creds(auth_generic_state, torture_creds);
1655 0 : if (!NT_STATUS_IS_OK(status)) {
1656 0 : printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1657 0 : return false;
1658 : }
1659 :
1660 0 : status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1661 0 : if (!NT_STATUS_IS_OK(status)) {
1662 0 : printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1663 0 : return false;
1664 : }
1665 :
1666 0 : ev = samba_tevent_context_init(talloc_tos());
1667 0 : if (ev == NULL) {
1668 0 : printf("samba_tevent_context_init() returned NULL\n");
1669 0 : return false;
1670 : }
1671 :
1672 0 : status = gensec_update(auth_generic_state->gensec_security,
1673 : talloc_tos(), data_blob_null, &in_blob);
1674 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1675 0 : printf("gensec_update returned %s\n", nt_errstr(status));
1676 0 : return false;
1677 : }
1678 :
1679 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1680 0 : cli->conn,
1681 0 : cli->timeout,
1682 0 : cli->smb2.session,
1683 : 0x0, /* in_flags */
1684 : SMB2_CAP_DFS, /* in_capabilities */
1685 : 0, /* in_channel */
1686 : 0, /* in_previous_session_id */
1687 : &in_blob); /* in_security_buffer */
1688 0 : if (subreq == NULL) {
1689 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1690 0 : return false;
1691 : }
1692 :
1693 0 : ok = tevent_req_poll(subreq, ev);
1694 0 : if (!ok) {
1695 0 : printf("tevent_req_poll() returned false\n");
1696 0 : return false;
1697 : }
1698 :
1699 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1700 : NULL, &out_blob);
1701 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1702 0 : printf("smb2cli_session_setup_recv returned %s\n",
1703 : nt_errstr(status));
1704 0 : return false;
1705 : }
1706 :
1707 0 : status = gensec_update(auth_generic_state->gensec_security,
1708 : talloc_tos(), out_blob, &in_blob);
1709 0 : if (!NT_STATUS_IS_OK(status)) {
1710 0 : printf("auth_generic_update returned %s\n", nt_errstr(status));
1711 0 : return false;
1712 : }
1713 :
1714 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1715 0 : cli->smb2.tcon, fid_persistent, fid_volatile);
1716 0 : if (!NT_STATUS_IS_OK(status)) {
1717 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1718 0 : return false;
1719 : }
1720 :
1721 0 : status = smb2cli_query_directory(
1722 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1723 : 1, 0x3, 0, dir_persistent, dir_volatile,
1724 : "session-reauth.txt", 0xffff,
1725 : talloc_tos(), &dir_data, &dir_data_length);
1726 0 : if (!NT_STATUS_IS_OK(status)) {
1727 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1728 0 : return false;
1729 : }
1730 :
1731 : /*
1732 : * query_info seems to be a path based operation on Windows...
1733 : */
1734 0 : status = smb2cli_query_info(cli->conn,
1735 0 : cli->timeout,
1736 0 : cli->smb2.session,
1737 0 : cli->smb2.tcon,
1738 : SMB2_0_INFO_SECURITY,
1739 : 0, /* in_file_info_class */
1740 : 1024, /* in_max_output_length */
1741 : NULL, /* in_input_buffer */
1742 : SECINFO_OWNER, /* in_additional_info */
1743 : 0, /* in_flags */
1744 : fid_persistent,
1745 : fid_volatile,
1746 : talloc_tos(),
1747 : &out_output_buffer);
1748 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1749 0 : printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1750 0 : return false;
1751 : }
1752 :
1753 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1754 0 : status = smb2cli_query_info(cli->conn,
1755 0 : cli->timeout,
1756 0 : cli->smb2.session,
1757 0 : cli->smb2.tcon,
1758 : SMB2_0_INFO_FILE,
1759 : in_file_info_class,
1760 : 1024, /* in_max_output_length */
1761 : NULL, /* in_input_buffer */
1762 : 0, /* in_additional_info */
1763 : 0, /* in_flags */
1764 : fid_persistent,
1765 : fid_volatile,
1766 : talloc_tos(),
1767 : &out_output_buffer);
1768 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1769 0 : printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1770 0 : return false;
1771 : }
1772 :
1773 0 : in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1774 0 : SBVAL(in_input_buffer.data, 0, 512);
1775 :
1776 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1777 0 : status = smb2cli_set_info(cli->conn,
1778 0 : cli->timeout,
1779 0 : cli->smb2.session,
1780 0 : cli->smb2.tcon,
1781 : SMB2_0_INFO_FILE,
1782 : in_file_info_class,
1783 : &in_input_buffer,
1784 : 0, /* in_additional_info */
1785 : fid_persistent,
1786 : fid_volatile);
1787 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1788 0 : printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1789 0 : return false;
1790 : }
1791 :
1792 0 : status = smb2cli_create(
1793 0 : cli->conn,
1794 0 : cli->timeout,
1795 0 : cli->smb2.session,
1796 0 : cli->smb2.tcon,
1797 : "session-reauth-invalid.txt",
1798 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1799 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1800 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1801 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1802 : FILE_SHARE_READ|
1803 : FILE_SHARE_WRITE|
1804 : FILE_SHARE_DELETE, /* share_access, */
1805 : FILE_CREATE, /* create_disposition, */
1806 : FILE_DELETE_ON_CLOSE, /* create_options, */
1807 : NULL, /* smb2_create_blobs *blobs */
1808 : &fid_persistent,
1809 : &fid_volatile,
1810 : NULL,
1811 : NULL,
1812 : NULL,
1813 : NULL);
1814 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1815 0 : printf("smb2cli_create %s\n", nt_errstr(status));
1816 0 : return false;
1817 : }
1818 :
1819 0 : status = smb2cli_create(
1820 0 : cli->conn,
1821 0 : cli->timeout,
1822 0 : cli->smb2.session,
1823 0 : cli->smb2.tcon,
1824 : "",
1825 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1826 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1827 : SEC_STD_SYNCHRONIZE|
1828 : SEC_DIR_LIST|
1829 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1830 : 0, /* file_attributes, */
1831 : FILE_SHARE_READ|
1832 : FILE_SHARE_WRITE|
1833 : FILE_SHARE_DELETE, /* share_access, */
1834 : FILE_OPEN, /* create_disposition, */
1835 : FILE_SYNCHRONOUS_IO_NONALERT|
1836 : FILE_DIRECTORY_FILE, /* create_options, */
1837 : NULL, /* smb2_create_blobs *blobs */
1838 : &dir_persistent,
1839 : &dir_volatile,
1840 : NULL,
1841 : NULL,
1842 : NULL,
1843 : NULL);
1844 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1845 0 : printf("smb2cli_create returned %s\n", nt_errstr(status));
1846 0 : return false;
1847 : }
1848 :
1849 0 : saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
1850 0 : saved_tcon = cli->smb2.tcon;
1851 0 : cli->smb2.tcon = smbXcli_tcon_create(cli);
1852 0 : smb2cli_tcon_set_values(cli->smb2.tcon,
1853 : NULL, /* session */
1854 : saved_tid,
1855 : 0, /* type */
1856 : 0, /* flags */
1857 : 0, /* capabilities */
1858 : 0 /* maximal_access */);
1859 0 : status = cli_tree_connect(cli, share, "?????", NULL);
1860 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1861 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
1862 0 : return false;
1863 : }
1864 0 : talloc_free(cli->smb2.tcon);
1865 0 : cli->smb2.tcon = saved_tcon;
1866 :
1867 0 : subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1868 0 : cli->conn,
1869 0 : cli->timeout,
1870 0 : cli->smb2.session,
1871 : 0x0, /* in_flags */
1872 : SMB2_CAP_DFS, /* in_capabilities */
1873 : 0, /* in_channel */
1874 : 0, /* in_previous_session_id */
1875 : &in_blob); /* in_security_buffer */
1876 0 : if (subreq == NULL) {
1877 0 : printf("smb2cli_session_setup_send() returned NULL\n");
1878 0 : return false;
1879 : }
1880 :
1881 0 : ok = tevent_req_poll(subreq, ev);
1882 0 : if (!ok) {
1883 0 : printf("tevent_req_poll() returned false\n");
1884 0 : return false;
1885 : }
1886 :
1887 0 : status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1888 : &recv_iov, &out_blob);
1889 0 : if (!NT_STATUS_IS_OK(status)) {
1890 0 : printf("smb2cli_session_setup_recv returned %s\n",
1891 : nt_errstr(status));
1892 0 : return false;
1893 : }
1894 :
1895 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1896 0 : cli->smb2.tcon, fid_persistent, fid_volatile);
1897 0 : if (!NT_STATUS_IS_OK(status)) {
1898 0 : printf("smb2cli_flush returned %s\n", nt_errstr(status));
1899 0 : return false;
1900 : }
1901 :
1902 0 : status = smb2cli_query_info(cli->conn,
1903 0 : cli->timeout,
1904 0 : cli->smb2.session,
1905 0 : cli->smb2.tcon,
1906 : SMB2_0_INFO_SECURITY,
1907 : 0, /* in_file_info_class */
1908 : 1024, /* in_max_output_length */
1909 : NULL, /* in_input_buffer */
1910 : SECINFO_OWNER, /* in_additional_info */
1911 : 0, /* in_flags */
1912 : fid_persistent,
1913 : fid_volatile,
1914 : talloc_tos(),
1915 : &out_output_buffer);
1916 0 : if (!NT_STATUS_IS_OK(status)) {
1917 0 : printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1918 0 : return false;
1919 : }
1920 :
1921 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1922 0 : status = smb2cli_query_info(cli->conn,
1923 0 : cli->timeout,
1924 0 : cli->smb2.session,
1925 0 : cli->smb2.tcon,
1926 : SMB2_0_INFO_FILE,
1927 : in_file_info_class,
1928 : 1024, /* in_max_output_length */
1929 : NULL, /* in_input_buffer */
1930 : 0, /* in_additional_info */
1931 : 0, /* in_flags */
1932 : fid_persistent,
1933 : fid_volatile,
1934 : talloc_tos(),
1935 : &out_output_buffer);
1936 0 : if (!NT_STATUS_IS_OK(status)) {
1937 0 : printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1938 0 : return false;
1939 : }
1940 :
1941 0 : in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1942 0 : SBVAL(in_input_buffer.data, 0, 512);
1943 :
1944 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1945 0 : status = smb2cli_set_info(cli->conn,
1946 0 : cli->timeout,
1947 0 : cli->smb2.session,
1948 0 : cli->smb2.tcon,
1949 : SMB2_0_INFO_FILE,
1950 : in_file_info_class,
1951 : &in_input_buffer,
1952 : 0, /* in_additional_info */
1953 : fid_persistent,
1954 : fid_volatile);
1955 0 : if (!NT_STATUS_IS_OK(status)) {
1956 0 : printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1957 0 : return false;
1958 : }
1959 :
1960 0 : in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1961 0 : status = smb2cli_query_info(cli->conn,
1962 0 : cli->timeout,
1963 0 : cli->smb2.session,
1964 0 : cli->smb2.tcon,
1965 : SMB2_0_INFO_FILE,
1966 : in_file_info_class,
1967 : 1024, /* in_max_output_length */
1968 : NULL, /* in_input_buffer */
1969 : 0, /* in_additional_info */
1970 : 0, /* in_flags */
1971 : fid_persistent,
1972 : fid_volatile,
1973 : talloc_tos(),
1974 : &out_output_buffer);
1975 0 : if (!NT_STATUS_IS_OK(status)) {
1976 0 : printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1977 0 : return false;
1978 : }
1979 :
1980 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1981 0 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
1982 0 : if (!NT_STATUS_IS_OK(status)) {
1983 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
1984 0 : return false;
1985 : }
1986 :
1987 0 : status = smb2cli_create(
1988 0 : cli->conn,
1989 0 : cli->timeout,
1990 0 : cli->smb2.session,
1991 0 : cli->smb2.tcon,
1992 : "session-reauth.txt",
1993 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1994 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1995 : SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1996 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1997 : FILE_SHARE_READ|
1998 : FILE_SHARE_WRITE|
1999 : FILE_SHARE_DELETE, /* share_access, */
2000 : FILE_CREATE, /* create_disposition, */
2001 : FILE_DELETE_ON_CLOSE, /* create_options, */
2002 : NULL, /* smb2_create_blobs *blobs */
2003 : &fid_persistent,
2004 : &fid_volatile,
2005 : NULL,
2006 : NULL,
2007 : NULL,
2008 : NULL);
2009 0 : if (!NT_STATUS_IS_OK(status)) {
2010 0 : printf("smb2cli_create %s\n", nt_errstr(status));
2011 0 : return false;
2012 : }
2013 :
2014 0 : status = smb2cli_query_directory(
2015 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2016 : 1, 0x3, 0, dir_persistent, dir_volatile,
2017 : "session-reauth.txt", 0xffff,
2018 : talloc_tos(), &dir_data, &dir_data_length);
2019 0 : if (!NT_STATUS_IS_OK(status)) {
2020 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2021 0 : return false;
2022 : }
2023 :
2024 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2025 0 : cli->smb2.tcon, 0, dir_persistent, dir_volatile);
2026 0 : if (!NT_STATUS_IS_OK(status)) {
2027 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2028 0 : return false;
2029 : }
2030 :
2031 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2032 0 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2033 0 : if (!NT_STATUS_IS_OK(status)) {
2034 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2035 0 : return false;
2036 : }
2037 :
2038 0 : saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
2039 0 : saved_tcon = cli->smb2.tcon;
2040 0 : cli->smb2.tcon = smbXcli_tcon_create(cli);
2041 0 : smb2cli_tcon_set_values(cli->smb2.tcon,
2042 : NULL, /* session */
2043 : saved_tid,
2044 : 0, /* type */
2045 : 0, /* flags */
2046 : 0, /* capabilities */
2047 : 0 /* maximal_access */);
2048 0 : status = cli_tree_connect(cli, share, "?????", NULL);
2049 0 : if (!NT_STATUS_IS_OK(status)) {
2050 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2051 0 : return false;
2052 : }
2053 0 : talloc_free(cli->smb2.tcon);
2054 0 : cli->smb2.tcon = saved_tcon;
2055 :
2056 0 : return true;
2057 : }
2058 :
2059 11 : static NTSTATUS check_size(struct cli_state *cli,
2060 : uint16_t fnum,
2061 : const char *fname,
2062 : size_t size)
2063 : {
2064 11 : off_t size_read = 0;
2065 :
2066 11 : NTSTATUS status = cli_qfileinfo_basic(cli,
2067 : fnum,
2068 : NULL,
2069 : &size_read,
2070 : NULL,
2071 : NULL,
2072 : NULL,
2073 : NULL,
2074 : NULL);
2075 :
2076 11 : if (!NT_STATUS_IS_OK(status)) {
2077 0 : printf("cli_qfileinfo_basic of %s failed (%s)\n",
2078 : fname,
2079 : nt_errstr(status));
2080 0 : return status;
2081 : }
2082 :
2083 11 : if (size != size_read) {
2084 0 : printf("size (%u) != size_read(%u) for %s\n",
2085 : (unsigned int)size,
2086 : (unsigned int)size_read,
2087 : fname);
2088 : /* Use EOF to mean bad size. */
2089 0 : return NT_STATUS_END_OF_FILE;
2090 : }
2091 11 : return NT_STATUS_OK;
2092 : }
2093 :
2094 : /* Ensure cli_ftruncate() works for SMB2. */
2095 :
2096 1 : bool run_smb2_ftruncate(int dummy)
2097 : {
2098 1 : struct cli_state *cli = NULL;
2099 1 : const char *fname = "smb2_ftruncate.txt";
2100 1 : uint16_t fnum = (uint16_t)-1;
2101 1 : bool correct = false;
2102 1 : size_t buflen = 1024*1024;
2103 1 : uint8_t *buf = NULL;
2104 : unsigned int i;
2105 : NTSTATUS status;
2106 :
2107 1 : printf("Starting SMB2-FTRUNCATE\n");
2108 :
2109 1 : if (!torture_init_connection(&cli)) {
2110 0 : goto fail;
2111 : }
2112 :
2113 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
2114 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2115 1 : if (!NT_STATUS_IS_OK(status)) {
2116 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2117 0 : goto fail;
2118 : }
2119 :
2120 1 : status = cli_session_setup_creds(cli, torture_creds);
2121 1 : if (!NT_STATUS_IS_OK(status)) {
2122 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2123 0 : goto fail;
2124 : }
2125 :
2126 1 : status = cli_tree_connect(cli, share, "?????", NULL);
2127 1 : if (!NT_STATUS_IS_OK(status)) {
2128 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2129 0 : goto fail;
2130 : }
2131 :
2132 1 : cli_setatr(cli, fname, 0, 0);
2133 1 : cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2134 :
2135 1 : status = cli_ntcreate(cli,
2136 : fname,
2137 : 0,
2138 : GENERIC_ALL_ACCESS,
2139 : FILE_ATTRIBUTE_NORMAL,
2140 : FILE_SHARE_NONE,
2141 : FILE_CREATE,
2142 : 0,
2143 : 0,
2144 : &fnum,
2145 : NULL);
2146 :
2147 1 : if (!NT_STATUS_IS_OK(status)) {
2148 0 : printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2149 0 : goto fail;
2150 : }
2151 :
2152 1 : buf = talloc_zero_array(cli, uint8_t, buflen);
2153 1 : if (buf == NULL) {
2154 0 : goto fail;
2155 : }
2156 :
2157 : /* Write 1MB. */
2158 1 : status = cli_writeall(cli,
2159 : fnum,
2160 : 0,
2161 : buf,
2162 : 0,
2163 : buflen,
2164 : NULL);
2165 :
2166 1 : if (!NT_STATUS_IS_OK(status)) {
2167 0 : printf("write of %u to %s failed (%s)\n",
2168 : (unsigned int)buflen,
2169 : fname,
2170 : nt_errstr(status));
2171 0 : goto fail;
2172 : }
2173 :
2174 1 : status = check_size(cli, fnum, fname, buflen);
2175 1 : if (!NT_STATUS_IS_OK(status)) {
2176 0 : goto fail;
2177 : }
2178 :
2179 : /* Now ftruncate. */
2180 11 : for ( i = 0; i < 10; i++) {
2181 10 : status = cli_ftruncate(cli, fnum, i*1024);
2182 10 : if (!NT_STATUS_IS_OK(status)) {
2183 0 : printf("cli_ftruncate %u of %s failed (%s)\n",
2184 : (unsigned int)i*1024,
2185 : fname,
2186 : nt_errstr(status));
2187 0 : goto fail;
2188 : }
2189 10 : status = check_size(cli, fnum, fname, i*1024);
2190 10 : if (!NT_STATUS_IS_OK(status)) {
2191 0 : goto fail;
2192 : }
2193 : }
2194 :
2195 1 : correct = true;
2196 :
2197 1 : fail:
2198 :
2199 1 : if (cli == NULL) {
2200 0 : return false;
2201 : }
2202 :
2203 1 : if (fnum != (uint16_t)-1) {
2204 1 : cli_close(cli, fnum);
2205 : }
2206 1 : cli_setatr(cli, fname, 0, 0);
2207 1 : cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2208 :
2209 1 : if (!torture_close_connection(cli)) {
2210 0 : correct = false;
2211 : }
2212 1 : return correct;
2213 : }
2214 :
2215 : /* Ensure SMB2 flush on directories behaves correctly. */
2216 :
2217 1 : static bool test_dir_fsync(struct cli_state *cli, const char *path)
2218 : {
2219 : NTSTATUS status;
2220 : uint64_t fid_persistent, fid_volatile;
2221 1 : uint8_t *dir_data = NULL;
2222 1 : uint32_t dir_data_length = 0;
2223 :
2224 : /* Open directory - no write abilities. */
2225 1 : status = smb2cli_create(
2226 : cli->conn,
2227 1 : cli->timeout,
2228 : cli->smb2.session,
2229 : cli->smb2.tcon,
2230 : path,
2231 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2232 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2233 : SEC_STD_SYNCHRONIZE|
2234 : SEC_DIR_LIST|
2235 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2236 : 0, /* file_attributes, */
2237 : FILE_SHARE_READ|
2238 : FILE_SHARE_WRITE|
2239 : FILE_SHARE_DELETE, /* share_access, */
2240 : FILE_OPEN, /* create_disposition, */
2241 : FILE_SYNCHRONOUS_IO_NONALERT|
2242 : FILE_DIRECTORY_FILE, /* create_options, */
2243 : NULL, /* smb2_create_blobs *blobs */
2244 : &fid_persistent,
2245 : &fid_volatile,
2246 : NULL,
2247 : NULL,
2248 : NULL,
2249 : NULL);
2250 1 : if (!NT_STATUS_IS_OK(status)) {
2251 0 : printf("smb2cli_create '%s' (readonly) returned %s\n",
2252 : path,
2253 : nt_errstr(status));
2254 0 : return false;
2255 : }
2256 :
2257 1 : status = smb2cli_query_directory(
2258 1 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2259 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2260 : talloc_tos(), &dir_data, &dir_data_length);
2261 :
2262 1 : if (!NT_STATUS_IS_OK(status)) {
2263 0 : printf("smb2cli_query_directory returned %s\n",
2264 : nt_errstr(status));
2265 0 : return false;
2266 : }
2267 :
2268 : /* Open directory no write access. Flush should fail. */
2269 :
2270 1 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2271 : cli->smb2.tcon, fid_persistent, fid_volatile);
2272 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2273 1 : printf("smb2cli_flush on a read-only directory returned %s\n",
2274 : nt_errstr(status));
2275 1 : return false;
2276 : }
2277 :
2278 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2279 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2280 0 : if (!NT_STATUS_IS_OK(status)) {
2281 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2282 0 : return false;
2283 : }
2284 :
2285 : /* Open directory write-attributes only. Flush should still fail. */
2286 :
2287 0 : status = smb2cli_create(
2288 : cli->conn,
2289 0 : cli->timeout,
2290 : cli->smb2.session,
2291 : cli->smb2.tcon,
2292 : path,
2293 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2294 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2295 : SEC_STD_SYNCHRONIZE|
2296 : SEC_DIR_LIST|
2297 : SEC_DIR_WRITE_ATTRIBUTE|
2298 : SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2299 : 0, /* file_attributes, */
2300 : FILE_SHARE_READ|
2301 : FILE_SHARE_WRITE|
2302 : FILE_SHARE_DELETE, /* share_access, */
2303 : FILE_OPEN, /* create_disposition, */
2304 : FILE_SYNCHRONOUS_IO_NONALERT|
2305 : FILE_DIRECTORY_FILE, /* create_options, */
2306 : NULL, /* smb2_create_blobs *blobs */
2307 : &fid_persistent,
2308 : &fid_volatile,
2309 : NULL,
2310 : NULL,
2311 : NULL,
2312 : NULL);
2313 0 : if (!NT_STATUS_IS_OK(status)) {
2314 0 : printf("smb2cli_create '%s' (write attr) returned %s\n",
2315 : path,
2316 : nt_errstr(status));
2317 0 : return false;
2318 : }
2319 :
2320 0 : status = smb2cli_query_directory(
2321 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2322 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2323 : talloc_tos(), &dir_data, &dir_data_length);
2324 :
2325 0 : if (!NT_STATUS_IS_OK(status)) {
2326 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2327 0 : return false;
2328 : }
2329 :
2330 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2331 : cli->smb2.tcon, fid_persistent, fid_volatile);
2332 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2333 0 : printf("smb2cli_flush on a write-attributes directory "
2334 : "returned %s\n",
2335 : nt_errstr(status));
2336 0 : return false;
2337 : }
2338 :
2339 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2340 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2341 0 : if (!NT_STATUS_IS_OK(status)) {
2342 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2343 0 : return false;
2344 : }
2345 :
2346 : /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2347 :
2348 0 : status = smb2cli_create(
2349 : cli->conn,
2350 0 : cli->timeout,
2351 : cli->smb2.session,
2352 : cli->smb2.tcon,
2353 : path,
2354 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2355 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2356 : SEC_STD_SYNCHRONIZE|
2357 : SEC_DIR_LIST|
2358 : SEC_DIR_ADD_FILE, /* desired_access, */
2359 : 0, /* file_attributes, */
2360 : FILE_SHARE_READ|
2361 : FILE_SHARE_WRITE|
2362 : FILE_SHARE_DELETE, /* share_access, */
2363 : FILE_OPEN, /* create_disposition, */
2364 : FILE_SYNCHRONOUS_IO_NONALERT|
2365 : FILE_DIRECTORY_FILE, /* create_options, */
2366 : NULL, /* smb2_create_blobs *blobs */
2367 : &fid_persistent,
2368 : &fid_volatile,
2369 : NULL,
2370 : NULL,
2371 : NULL,
2372 : NULL);
2373 0 : if (!NT_STATUS_IS_OK(status)) {
2374 0 : printf("smb2cli_create '%s' (write FILE access) returned %s\n",
2375 : path,
2376 : nt_errstr(status));
2377 0 : return false;
2378 : }
2379 :
2380 0 : status = smb2cli_query_directory(
2381 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2382 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2383 : talloc_tos(), &dir_data, &dir_data_length);
2384 :
2385 0 : if (!NT_STATUS_IS_OK(status)) {
2386 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2387 0 : return false;
2388 : }
2389 :
2390 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2391 : cli->smb2.tcon, fid_persistent, fid_volatile);
2392 0 : if (!NT_STATUS_IS_OK(status)) {
2393 0 : printf("smb2cli_flush on a directory returned %s\n",
2394 : nt_errstr(status));
2395 0 : return false;
2396 : }
2397 :
2398 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2399 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2400 0 : if (!NT_STATUS_IS_OK(status)) {
2401 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2402 0 : return false;
2403 : }
2404 :
2405 : /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2406 :
2407 0 : status = smb2cli_create(
2408 : cli->conn,
2409 0 : cli->timeout,
2410 : cli->smb2.session,
2411 : cli->smb2.tcon,
2412 : path,
2413 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2414 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2415 : SEC_STD_SYNCHRONIZE|
2416 : SEC_DIR_LIST|
2417 : SEC_DIR_ADD_SUBDIR, /* desired_access, */
2418 : 0, /* file_attributes, */
2419 : FILE_SHARE_READ|
2420 : FILE_SHARE_WRITE|
2421 : FILE_SHARE_DELETE, /* share_access, */
2422 : FILE_OPEN, /* create_disposition, */
2423 : FILE_SYNCHRONOUS_IO_NONALERT|
2424 : FILE_DIRECTORY_FILE, /* create_options, */
2425 : NULL, /* smb2_create_blobs *blobs */
2426 : &fid_persistent,
2427 : &fid_volatile,
2428 : NULL,
2429 : NULL,
2430 : NULL,
2431 : NULL);
2432 0 : if (!NT_STATUS_IS_OK(status)) {
2433 0 : printf("smb2cli_create '%s' (write DIR access) returned %s\n",
2434 : path,
2435 : nt_errstr(status));
2436 0 : return false;
2437 : }
2438 :
2439 0 : status = smb2cli_query_directory(
2440 0 : cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2441 : 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2442 : talloc_tos(), &dir_data, &dir_data_length);
2443 :
2444 0 : if (!NT_STATUS_IS_OK(status)) {
2445 0 : printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2446 0 : return false;
2447 : }
2448 :
2449 0 : status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2450 : cli->smb2.tcon, fid_persistent, fid_volatile);
2451 0 : if (!NT_STATUS_IS_OK(status)) {
2452 0 : printf("smb2cli_flush on a directory returned %s\n",
2453 : nt_errstr(status));
2454 0 : return false;
2455 : }
2456 :
2457 0 : status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2458 : cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2459 0 : if (!NT_STATUS_IS_OK(status)) {
2460 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2461 0 : return false;
2462 : }
2463 :
2464 :
2465 0 : return true;
2466 : }
2467 :
2468 1 : bool run_smb2_dir_fsync(int dummy)
2469 : {
2470 1 : struct cli_state *cli = NULL;
2471 : NTSTATUS status;
2472 1 : bool bret = false;
2473 1 : const char *dname = "fsync_test_dir";
2474 :
2475 1 : printf("Starting SMB2-DIR-FSYNC\n");
2476 :
2477 1 : if (!torture_init_connection(&cli)) {
2478 0 : return false;
2479 : }
2480 :
2481 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
2482 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2483 1 : if (!NT_STATUS_IS_OK(status)) {
2484 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2485 0 : return false;
2486 : }
2487 :
2488 1 : status = cli_session_setup_creds(cli, torture_creds);
2489 1 : if (!NT_STATUS_IS_OK(status)) {
2490 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2491 0 : return false;
2492 : }
2493 :
2494 1 : status = cli_tree_connect(cli, share, "?????", NULL);
2495 1 : if (!NT_STATUS_IS_OK(status)) {
2496 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2497 0 : return false;
2498 : }
2499 :
2500 1 : (void)cli_rmdir(cli, dname);
2501 1 : status = cli_mkdir(cli, dname);
2502 1 : if (!NT_STATUS_IS_OK(status)) {
2503 0 : printf("cli_mkdir(%s) returned %s\n",
2504 : dname,
2505 : nt_errstr(status));
2506 0 : return false;
2507 : }
2508 :
2509 : /* Test on a subdirectory. */
2510 1 : bret = test_dir_fsync(cli, dname);
2511 1 : if (bret == false) {
2512 1 : (void)cli_rmdir(cli, dname);
2513 1 : return false;
2514 : }
2515 0 : (void)cli_rmdir(cli, dname);
2516 :
2517 : /* Test on the root handle of a share. */
2518 0 : bret = test_dir_fsync(cli, "");
2519 0 : if (bret == false) {
2520 0 : return false;
2521 : }
2522 0 : return true;
2523 : }
2524 :
2525 1 : bool run_smb2_path_slash(int dummy)
2526 : {
2527 1 : struct cli_state *cli = NULL;
2528 : NTSTATUS status;
2529 : uint64_t fid_persistent;
2530 : uint64_t fid_volatile;
2531 1 : const char *dname_noslash = "smb2_dir_slash";
2532 1 : const char *dname_backslash = "smb2_dir_slash\\";
2533 1 : const char *dname_slash = "smb2_dir_slash/";
2534 1 : const char *fname_noslash = "smb2_file_slash";
2535 1 : const char *fname_backslash = "smb2_file_slash\\";
2536 1 : const char *fname_slash = "smb2_file_slash/";
2537 :
2538 1 : printf("Starting SMB2-PATH-SLASH\n");
2539 :
2540 1 : if (!torture_init_connection(&cli)) {
2541 0 : return false;
2542 : }
2543 :
2544 1 : status = smbXcli_negprot(cli->conn, cli->timeout,
2545 : PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2546 1 : if (!NT_STATUS_IS_OK(status)) {
2547 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2548 0 : return false;
2549 : }
2550 :
2551 1 : status = cli_session_setup_creds(cli, torture_creds);
2552 1 : if (!NT_STATUS_IS_OK(status)) {
2553 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2554 0 : return false;
2555 : }
2556 :
2557 1 : status = cli_tree_connect(cli, share, "?????", NULL);
2558 1 : if (!NT_STATUS_IS_OK(status)) {
2559 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2560 0 : return false;
2561 : }
2562 :
2563 1 : (void)cli_unlink(cli, dname_noslash, 0);
2564 1 : (void)cli_rmdir(cli, dname_noslash);
2565 1 : (void)cli_unlink(cli, fname_noslash, 0);
2566 1 : (void)cli_rmdir(cli, fname_noslash);
2567 :
2568 : /* Try to create a directory with the backslash name. */
2569 1 : status = smb2cli_create(
2570 1 : cli->conn,
2571 1 : cli->timeout,
2572 1 : cli->smb2.session,
2573 1 : cli->smb2.tcon,
2574 : dname_backslash,
2575 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2576 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2577 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2578 : 0, /* file_attributes, */
2579 : FILE_SHARE_READ|
2580 : FILE_SHARE_WRITE|
2581 : FILE_SHARE_DELETE, /* share_access, */
2582 : FILE_CREATE, /* create_disposition, */
2583 : FILE_DIRECTORY_FILE, /* create_options, */
2584 : NULL, /* smb2_create_blobs *blobs */
2585 : &fid_persistent,
2586 : &fid_volatile,
2587 : NULL,
2588 : NULL,
2589 : NULL,
2590 : NULL);
2591 :
2592 : /* directory ending in '\\' should be success. */
2593 :
2594 1 : if (!NT_STATUS_IS_OK(status)) {
2595 0 : printf("smb2cli_create '%s' returned %s - "
2596 : "should be NT_STATUS_OK\n",
2597 : dname_backslash,
2598 : nt_errstr(status));
2599 0 : return false;
2600 : }
2601 1 : status = smb2cli_close(cli->conn,
2602 1 : cli->timeout,
2603 1 : cli->smb2.session,
2604 1 : cli->smb2.tcon,
2605 : 0,
2606 : fid_persistent,
2607 : fid_volatile);
2608 1 : if (!NT_STATUS_IS_OK(status)) {
2609 0 : printf("smb2cli_close returned %s\n", nt_errstr(status));
2610 0 : return false;
2611 : }
2612 :
2613 1 : (void)cli_rmdir(cli, dname_noslash);
2614 :
2615 : /* Try to create a directory with the slash name. */
2616 1 : status = smb2cli_create(
2617 1 : cli->conn,
2618 1 : cli->timeout,
2619 1 : cli->smb2.session,
2620 1 : cli->smb2.tcon,
2621 : dname_slash,
2622 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2623 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2624 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2625 : 0, /* file_attributes, */
2626 : FILE_SHARE_READ|
2627 : FILE_SHARE_WRITE|
2628 : FILE_SHARE_DELETE, /* share_access, */
2629 : FILE_CREATE, /* create_disposition, */
2630 : FILE_DIRECTORY_FILE, /* create_options, */
2631 : NULL, /* smb2_create_blobs *blobs */
2632 : &fid_persistent,
2633 : &fid_volatile,
2634 : NULL,
2635 : NULL,
2636 : NULL,
2637 : NULL);
2638 :
2639 : /* directory ending in '/' is an error. */
2640 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2641 0 : printf("smb2cli_create '%s' returned %s - "
2642 : "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2643 : dname_slash,
2644 : nt_errstr(status));
2645 0 : if (NT_STATUS_IS_OK(status)) {
2646 0 : (void)smb2cli_close(cli->conn,
2647 0 : cli->timeout,
2648 0 : cli->smb2.session,
2649 0 : cli->smb2.tcon,
2650 : 0,
2651 : fid_persistent,
2652 : fid_volatile);
2653 : }
2654 0 : (void)cli_rmdir(cli, dname_noslash);
2655 0 : return false;
2656 : }
2657 :
2658 1 : (void)cli_rmdir(cli, dname_noslash);
2659 :
2660 : /* Try to create a file with the backslash name. */
2661 1 : status = smb2cli_create(
2662 1 : cli->conn,
2663 1 : cli->timeout,
2664 1 : cli->smb2.session,
2665 1 : cli->smb2.tcon,
2666 : fname_backslash,
2667 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2668 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2669 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2670 : 0, /* file_attributes, */
2671 : FILE_SHARE_READ|
2672 : FILE_SHARE_WRITE|
2673 : FILE_SHARE_DELETE, /* share_access, */
2674 : FILE_CREATE, /* create_disposition, */
2675 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2676 : NULL, /* smb2_create_blobs *blobs */
2677 : &fid_persistent,
2678 : &fid_volatile,
2679 : NULL,
2680 : NULL,
2681 : NULL,
2682 : NULL);
2683 :
2684 : /* file ending in '\\' should be error. */
2685 :
2686 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2687 1 : printf("smb2cli_create '%s' returned %s - "
2688 : "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2689 : fname_backslash,
2690 : nt_errstr(status));
2691 1 : if (NT_STATUS_IS_OK(status)) {
2692 1 : (void)smb2cli_close(cli->conn,
2693 1 : cli->timeout,
2694 1 : cli->smb2.session,
2695 1 : cli->smb2.tcon,
2696 : 0,
2697 : fid_persistent,
2698 : fid_volatile);
2699 : }
2700 1 : (void)cli_unlink(cli, fname_noslash, 0);
2701 1 : return false;
2702 : }
2703 :
2704 0 : (void)cli_unlink(cli, fname_noslash, 0);
2705 :
2706 : /* Try to create a file with the slash name. */
2707 0 : status = smb2cli_create(
2708 0 : cli->conn,
2709 0 : cli->timeout,
2710 0 : cli->smb2.session,
2711 0 : cli->smb2.tcon,
2712 : fname_slash,
2713 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2714 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2715 : FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2716 : 0, /* file_attributes, */
2717 : FILE_SHARE_READ|
2718 : FILE_SHARE_WRITE|
2719 : FILE_SHARE_DELETE, /* share_access, */
2720 : FILE_CREATE, /* create_disposition, */
2721 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2722 : NULL, /* smb2_create_blobs *blobs */
2723 : &fid_persistent,
2724 : &fid_volatile,
2725 : NULL,
2726 : NULL,
2727 : NULL,
2728 : NULL);
2729 :
2730 : /* file ending in '/' should be error. */
2731 :
2732 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2733 0 : printf("smb2cli_create '%s' returned %s - "
2734 : "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2735 : fname_slash,
2736 : nt_errstr(status));
2737 0 : if (NT_STATUS_IS_OK(status)) {
2738 0 : (void)smb2cli_close(cli->conn,
2739 0 : cli->timeout,
2740 0 : cli->smb2.session,
2741 0 : cli->smb2.tcon,
2742 : 0,
2743 : fid_persistent,
2744 : fid_volatile);
2745 : }
2746 0 : (void)cli_unlink(cli, fname_noslash, 0);
2747 0 : return false;
2748 : }
2749 :
2750 0 : (void)cli_unlink(cli, fname_noslash, 0);
2751 0 : return true;
2752 : }
2753 :
2754 : /*
2755 : * NB. This can only work against a server where
2756 : * the connecting user has been granted SeSecurityPrivilege.
2757 : *
2758 : * 1). Create a test file.
2759 : * 2). Open with SEC_FLAG_SYSTEM_SECURITY *only*. ACCESS_DENIED -
2760 : * NB. SMB2-only behavior.
2761 : * 3). Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2762 : * 4). Write SACL. Should fail with ACCESS_DENIED (seems to need WRITE_DAC).
2763 : * 5). Close (3).
2764 : * 6). Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2765 : * 7). Write SACL. Success.
2766 : * 8). Close (4).
2767 : * 9). Open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
2768 : * 10). Read SACL. Success.
2769 : * 11). Read DACL. Should fail with ACCESS_DENIED (no READ_CONTROL).
2770 : * 12). Close (9).
2771 : */
2772 :
2773 0 : bool run_smb2_sacl(int dummy)
2774 : {
2775 0 : struct cli_state *cli = NULL;
2776 : NTSTATUS status;
2777 0 : struct security_descriptor *sd_dacl = NULL;
2778 0 : struct security_descriptor *sd_sacl = NULL;
2779 0 : const char *fname = "sacl_test_file";
2780 0 : uint16_t fnum = (uint16_t)-1;
2781 :
2782 0 : printf("Starting SMB2-SACL\n");
2783 :
2784 0 : if (!torture_init_connection(&cli)) {
2785 0 : return false;
2786 : }
2787 :
2788 0 : status = smbXcli_negprot(cli->conn,
2789 0 : cli->timeout,
2790 : PROTOCOL_SMB2_02,
2791 : PROTOCOL_SMB3_11);
2792 0 : if (!NT_STATUS_IS_OK(status)) {
2793 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2794 0 : return false;
2795 : }
2796 :
2797 0 : status = cli_session_setup_creds(cli, torture_creds);
2798 0 : if (!NT_STATUS_IS_OK(status)) {
2799 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
2800 0 : return false;
2801 : }
2802 :
2803 0 : status = cli_tree_connect(cli, share, "?????", NULL);
2804 0 : if (!NT_STATUS_IS_OK(status)) {
2805 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
2806 0 : return false;
2807 : }
2808 :
2809 0 : (void)cli_unlink(cli, fname, 0);
2810 :
2811 : /* First create a file. */
2812 0 : status = cli_ntcreate(cli,
2813 : fname,
2814 : 0,
2815 : GENERIC_ALL_ACCESS,
2816 : FILE_ATTRIBUTE_NORMAL,
2817 : FILE_SHARE_NONE,
2818 : FILE_CREATE,
2819 : 0,
2820 : 0,
2821 : &fnum,
2822 : NULL);
2823 :
2824 0 : if (!NT_STATUS_IS_OK(status)) {
2825 0 : printf("Create of %s failed (%s)\n",
2826 : fname,
2827 : nt_errstr(status));
2828 0 : goto fail;
2829 : }
2830 :
2831 0 : cli_close(cli, fnum);
2832 0 : fnum = (uint16_t)-1;
2833 :
2834 : /*
2835 : * Now try to open with *only* SEC_FLAG_SYSTEM_SECURITY.
2836 : * This should fail with NT_STATUS_ACCESS_DENIED - but
2837 : * only against an SMB2 server. SMB1 allows this as tested
2838 : * in SMB1-SYSTEM-SECURITY.
2839 : */
2840 :
2841 0 : status = cli_smb2_create_fnum(cli,
2842 : fname,
2843 : SMB2_OPLOCK_LEVEL_NONE,
2844 : SMB2_IMPERSONATION_IMPERSONATION,
2845 : SEC_FLAG_SYSTEM_SECURITY, /* desired access */
2846 : 0, /* file_attributes, */
2847 : FILE_SHARE_READ|
2848 : FILE_SHARE_WRITE|
2849 : FILE_SHARE_DELETE, /* share_access, */
2850 : FILE_OPEN, /* create_disposition, */
2851 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2852 : NULL, /* in_cblobs. */
2853 : &fnum, /* fnum */
2854 : NULL, /* smb_create_returns */
2855 : talloc_tos(), /* mem_ctx */
2856 : NULL); /* out_cblobs */
2857 :
2858 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
2859 0 : printf("SMB2-SACL-TEST can only work with a user "
2860 : "who has been granted SeSecurityPrivilege.\n"
2861 : "This is the "
2862 : "\"Manage auditing and security log\""
2863 : "privilege setting on Windows\n");
2864 0 : goto fail;
2865 : }
2866 :
2867 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2868 0 : printf("open file %s with SEC_FLAG_SYSTEM_SECURITY only: "
2869 : "got %s - should fail with ACCESS_DENIED\n",
2870 : fname,
2871 : nt_errstr(status));
2872 0 : goto fail;
2873 : }
2874 :
2875 : /*
2876 : * Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2877 : */
2878 :
2879 0 : status = cli_smb2_create_fnum(cli,
2880 : fname,
2881 : SMB2_OPLOCK_LEVEL_NONE,
2882 : SMB2_IMPERSONATION_IMPERSONATION,
2883 : SEC_FLAG_SYSTEM_SECURITY|
2884 : FILE_WRITE_ATTRIBUTES, /* desired access */
2885 : 0, /* file_attributes, */
2886 : FILE_SHARE_READ|
2887 : FILE_SHARE_WRITE|
2888 : FILE_SHARE_DELETE, /* share_access, */
2889 : FILE_OPEN, /* create_disposition, */
2890 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2891 : NULL, /* in_cblobs. */
2892 : &fnum, /* fnum */
2893 : NULL, /* smb_create_returns */
2894 : talloc_tos(), /* mem_ctx */
2895 : NULL); /* out_cblobs */
2896 :
2897 0 : if (!NT_STATUS_IS_OK(status)) {
2898 0 : printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2899 : "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2900 : fname,
2901 : nt_errstr(status));
2902 0 : goto fail;
2903 : }
2904 :
2905 : /* Create an SD with a SACL. */
2906 0 : sd_sacl = security_descriptor_sacl_create(talloc_tos(),
2907 : 0,
2908 : NULL, /* owner. */
2909 : NULL, /* group. */
2910 : /* first ACE. */
2911 : SID_WORLD,
2912 : SEC_ACE_TYPE_SYSTEM_AUDIT,
2913 : SEC_GENERIC_ALL,
2914 : SEC_ACE_FLAG_FAILED_ACCESS,
2915 : NULL);
2916 :
2917 0 : if (sd_sacl == NULL) {
2918 0 : printf("Out of memory creating SACL\n");
2919 0 : goto fail;
2920 : }
2921 :
2922 : /*
2923 : * Write the SACL SD. This should fail
2924 : * even though we have SEC_FLAG_SYSTEM_SECURITY,
2925 : * as it seems to also need WRITE_DAC access.
2926 : */
2927 0 : status = cli_set_security_descriptor(cli,
2928 : fnum,
2929 : SECINFO_DACL|SECINFO_SACL,
2930 : sd_sacl);
2931 :
2932 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2933 0 : printf("Writing SACL on file %s got (%s) "
2934 : "should have failed with ACCESS_DENIED.\n",
2935 : fname,
2936 : nt_errstr(status));
2937 0 : goto fail;
2938 : }
2939 :
2940 : /* And close. */
2941 0 : cli_smb2_close_fnum(cli, fnum);
2942 0 : fnum = (uint16_t)-1;
2943 :
2944 : /*
2945 : * Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2946 : */
2947 :
2948 0 : status = cli_smb2_create_fnum(cli,
2949 : fname,
2950 : SMB2_OPLOCK_LEVEL_NONE,
2951 : SMB2_IMPERSONATION_IMPERSONATION,
2952 : SEC_FLAG_SYSTEM_SECURITY|
2953 : SEC_STD_WRITE_DAC, /* desired access */
2954 : 0, /* file_attributes, */
2955 : FILE_SHARE_READ|
2956 : FILE_SHARE_WRITE|
2957 : FILE_SHARE_DELETE, /* share_access, */
2958 : FILE_OPEN, /* create_disposition, */
2959 : FILE_NON_DIRECTORY_FILE, /* create_options, */
2960 : NULL, /* in_cblobs. */
2961 : &fnum, /* fnum */
2962 : NULL, /* smb_create_returns */
2963 : talloc_tos(), /* mem_ctx */
2964 : NULL); /* out_cblobs */
2965 :
2966 0 : if (!NT_STATUS_IS_OK(status)) {
2967 0 : printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2968 : "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2969 : fname,
2970 : nt_errstr(status));
2971 0 : goto fail;
2972 : }
2973 :
2974 : /*
2975 : * Write the SACL SD. This should now succeed
2976 : * as we have both SEC_FLAG_SYSTEM_SECURITY
2977 : * and WRITE_DAC access.
2978 : */
2979 0 : status = cli_set_security_descriptor(cli,
2980 : fnum,
2981 : SECINFO_DACL|SECINFO_SACL,
2982 : sd_sacl);
2983 :
2984 0 : if (!NT_STATUS_IS_OK(status)) {
2985 0 : printf("cli_set_security_descriptor SACL "
2986 : "on file %s failed (%s)\n",
2987 : fname,
2988 : nt_errstr(status));
2989 0 : goto fail;
2990 : }
2991 :
2992 : /* And close. */
2993 0 : cli_smb2_close_fnum(cli, fnum);
2994 0 : fnum = (uint16_t)-1;
2995 :
2996 : /* We're done with the sacl we made. */
2997 0 : TALLOC_FREE(sd_sacl);
2998 :
2999 : /*
3000 : * Now try to open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
3001 : * This gives us access to the SACL.
3002 : */
3003 :
3004 0 : status = cli_smb2_create_fnum(cli,
3005 : fname,
3006 : SMB2_OPLOCK_LEVEL_NONE,
3007 : SMB2_IMPERSONATION_IMPERSONATION,
3008 : SEC_FLAG_SYSTEM_SECURITY|
3009 : FILE_READ_ATTRIBUTES, /* desired access */
3010 : 0, /* file_attributes, */
3011 : FILE_SHARE_READ|
3012 : FILE_SHARE_WRITE|
3013 : FILE_SHARE_DELETE, /* share_access, */
3014 : FILE_OPEN, /* create_disposition, */
3015 : FILE_NON_DIRECTORY_FILE, /* create_options, */
3016 : NULL, /* in_cblobs. */
3017 : &fnum, /* fnum */
3018 : NULL, /* smb_create_returns */
3019 : talloc_tos(), /* mem_ctx */
3020 : NULL); /* out_cblobs */
3021 :
3022 0 : if (!NT_STATUS_IS_OK(status)) {
3023 0 : printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
3024 : "FILE_READ_ATTRIBUTES) failed (%s)\n",
3025 : fname,
3026 : nt_errstr(status));
3027 0 : goto fail;
3028 : }
3029 :
3030 : /* Try and read the SACL - should succeed. */
3031 0 : status = cli_query_security_descriptor(
3032 : cli, fnum, SECINFO_SACL, talloc_tos(), &sd_sacl);
3033 :
3034 0 : if (!NT_STATUS_IS_OK(status)) {
3035 0 : printf("Read SACL from file %s failed (%s)\n",
3036 : fname,
3037 : nt_errstr(status));
3038 0 : goto fail;
3039 : }
3040 :
3041 0 : TALLOC_FREE(sd_sacl);
3042 :
3043 : /*
3044 : * Try and read the DACL - should fail as we have
3045 : * no READ_DAC access.
3046 : */
3047 0 : status = cli_query_security_descriptor(
3048 : cli, fnum, SECINFO_DACL, talloc_tos(), &sd_sacl);
3049 :
3050 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3051 0 : printf("Reading DACL on file %s got (%s) "
3052 : "should have failed with ACCESS_DENIED.\n",
3053 : fname,
3054 : nt_errstr(status));
3055 0 : goto fail;
3056 : }
3057 :
3058 0 : if (fnum != (uint16_t)-1) {
3059 0 : cli_smb2_close_fnum(cli, fnum);
3060 0 : fnum = (uint16_t)-1;
3061 : }
3062 :
3063 0 : TALLOC_FREE(sd_dacl);
3064 0 : TALLOC_FREE(sd_sacl);
3065 :
3066 0 : (void)cli_unlink(cli, fname, 0);
3067 0 : return true;
3068 :
3069 0 : fail:
3070 :
3071 0 : TALLOC_FREE(sd_dacl);
3072 0 : TALLOC_FREE(sd_sacl);
3073 :
3074 0 : if (fnum != (uint16_t)-1) {
3075 0 : cli_smb2_close_fnum(cli, fnum);
3076 0 : fnum = (uint16_t)-1;
3077 : }
3078 :
3079 0 : (void)cli_unlink(cli, fname, 0);
3080 0 : return false;
3081 : }
3082 :
3083 1 : bool run_smb2_quota1(int dummy)
3084 : {
3085 1 : struct cli_state *cli = NULL;
3086 : NTSTATUS status;
3087 1 : uint16_t fnum = (uint16_t)-1;
3088 1 : SMB_NTQUOTA_STRUCT qt = {0};
3089 :
3090 1 : printf("Starting SMB2-QUOTA1\n");
3091 :
3092 1 : if (!torture_init_connection(&cli)) {
3093 0 : return false;
3094 : }
3095 :
3096 1 : status = smbXcli_negprot(cli->conn,
3097 1 : cli->timeout,
3098 : PROTOCOL_SMB2_02,
3099 : PROTOCOL_SMB3_11);
3100 1 : if (!NT_STATUS_IS_OK(status)) {
3101 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3102 0 : return false;
3103 : }
3104 :
3105 1 : status = cli_session_setup_creds(cli, torture_creds);
3106 1 : if (!NT_STATUS_IS_OK(status)) {
3107 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3108 0 : return false;
3109 : }
3110 :
3111 1 : status = cli_tree_connect(cli, share, "?????", NULL);
3112 1 : if (!NT_STATUS_IS_OK(status)) {
3113 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3114 0 : return false;
3115 : }
3116 :
3117 1 : status = cli_smb2_create_fnum(
3118 : cli,
3119 : "\\",
3120 : SMB2_OPLOCK_LEVEL_NONE,
3121 : SMB2_IMPERSONATION_IMPERSONATION,
3122 : SEC_GENERIC_READ, /* desired access */
3123 : 0, /* file_attributes, */
3124 : FILE_SHARE_READ|
3125 : FILE_SHARE_WRITE|
3126 : FILE_SHARE_DELETE, /* share_access, */
3127 : FILE_OPEN, /* create_disposition, */
3128 : FILE_DIRECTORY_FILE, /* create_options, */
3129 : NULL, /* in_cblobs. */
3130 : &fnum, /* fnum */
3131 : NULL, /* smb_create_returns */
3132 : NULL, /* mem_ctx */
3133 : NULL); /* out_cblobs */
3134 1 : if (!NT_STATUS_IS_OK(status)) {
3135 0 : printf("cli_smb2_create_fnum failed: %s\n", nt_errstr(status));
3136 0 : return false;
3137 : }
3138 :
3139 1 : status = cli_smb2_get_user_quota(cli, fnum, &qt);
3140 1 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
3141 1 : printf("cli_smb2_get_user_quota returned %s, expected "
3142 : "NT_STATUS_INVALID_HANDLE\n",
3143 : nt_errstr(status));
3144 1 : return false;
3145 : }
3146 :
3147 0 : return true;
3148 : }
3149 :
3150 0 : bool run_smb2_stream_acl(int dummy)
3151 : {
3152 0 : struct cli_state *cli = NULL;
3153 : NTSTATUS status;
3154 0 : uint16_t fnum = (uint16_t)-1;
3155 0 : const char *fname = "stream_acl_test_file";
3156 0 : const char *sname = "stream_acl_test_file:streamname";
3157 0 : struct security_descriptor *sd_dacl = NULL;
3158 0 : bool ret = false;
3159 :
3160 0 : printf("SMB2 stream acl\n");
3161 :
3162 0 : if (!torture_init_connection(&cli)) {
3163 0 : return false;
3164 : }
3165 :
3166 0 : status = smbXcli_negprot(cli->conn,
3167 0 : cli->timeout,
3168 : PROTOCOL_SMB2_02,
3169 : PROTOCOL_SMB3_11);
3170 0 : if (!NT_STATUS_IS_OK(status)) {
3171 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3172 0 : return false;
3173 : }
3174 :
3175 0 : status = cli_session_setup_creds(cli, torture_creds);
3176 0 : if (!NT_STATUS_IS_OK(status)) {
3177 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3178 0 : return false;
3179 : }
3180 :
3181 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3182 0 : if (!NT_STATUS_IS_OK(status)) {
3183 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3184 0 : return false;
3185 : }
3186 :
3187 : /* Ensure file doesn't exist. */
3188 0 : (void)cli_unlink(cli, fname, 0);
3189 :
3190 : /* Create the file. */
3191 0 : status = cli_ntcreate(cli,
3192 : fname,
3193 : 0,
3194 : GENERIC_ALL_ACCESS,
3195 : FILE_ATTRIBUTE_NORMAL,
3196 : FILE_SHARE_NONE,
3197 : FILE_CREATE,
3198 : 0,
3199 : 0,
3200 : &fnum,
3201 : NULL);
3202 :
3203 0 : if (!NT_STATUS_IS_OK(status)) {
3204 0 : printf("Create of %s failed (%s)\n",
3205 : fname,
3206 : nt_errstr(status));
3207 0 : goto fail;
3208 : }
3209 :
3210 : /* Close the handle. */
3211 0 : cli_smb2_close_fnum(cli, fnum);
3212 0 : fnum = (uint16_t)-1;
3213 :
3214 : /* Create the stream. */
3215 0 : status = cli_ntcreate(cli,
3216 : sname,
3217 : 0,
3218 : FILE_READ_DATA|
3219 : SEC_STD_READ_CONTROL|
3220 : SEC_STD_WRITE_DAC,
3221 : FILE_ATTRIBUTE_NORMAL,
3222 : FILE_SHARE_NONE,
3223 : FILE_CREATE,
3224 : 0,
3225 : 0,
3226 : &fnum,
3227 : NULL);
3228 :
3229 0 : if (!NT_STATUS_IS_OK(status)) {
3230 0 : printf("Create of %s failed (%s)\n",
3231 : sname,
3232 : nt_errstr(status));
3233 0 : goto fail;
3234 : }
3235 :
3236 : /* Close the handle. */
3237 0 : cli_smb2_close_fnum(cli, fnum);
3238 0 : fnum = (uint16_t)-1;
3239 :
3240 : /*
3241 : * Open the stream - for Samba this ensures
3242 : * we prove we have a pathref fsp.
3243 : */
3244 0 : status = cli_ntcreate(cli,
3245 : sname,
3246 : 0,
3247 : FILE_READ_DATA|
3248 : SEC_STD_READ_CONTROL|
3249 : SEC_STD_WRITE_DAC,
3250 : FILE_ATTRIBUTE_NORMAL,
3251 : FILE_SHARE_NONE,
3252 : FILE_OPEN,
3253 : 0,
3254 : 0,
3255 : &fnum,
3256 : NULL);
3257 :
3258 0 : if (!NT_STATUS_IS_OK(status)) {
3259 0 : printf("Open of %s failed (%s)\n",
3260 : sname,
3261 : nt_errstr(status));
3262 0 : goto fail;
3263 : }
3264 :
3265 : /* Read the security descriptor off the stream handle. */
3266 0 : status = cli_query_security_descriptor(cli,
3267 : fnum,
3268 : SECINFO_DACL,
3269 : talloc_tos(),
3270 : &sd_dacl);
3271 :
3272 0 : if (!NT_STATUS_IS_OK(status)) {
3273 0 : printf("Reading DACL on stream %s got (%s)\n",
3274 : sname,
3275 : nt_errstr(status));
3276 0 : goto fail;
3277 : }
3278 :
3279 0 : if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3280 0 : sd_dacl->dacl->num_aces < 1) {
3281 0 : printf("Invalid DACL returned on stream %s "
3282 : "(this should not happen)\n",
3283 : sname);
3284 0 : goto fail;
3285 : }
3286 :
3287 : /*
3288 : * Ensure it allows FILE_READ_DATA in the first ace.
3289 : * It always should.
3290 : */
3291 0 : if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) == 0) {
3292 0 : printf("DACL->ace[0] returned on stream %s "
3293 : "doesn't have read access (should not happen)\n",
3294 : sname);
3295 0 : goto fail;
3296 : }
3297 :
3298 : /* Remove FILE_READ_DATA from the first ace and set. */
3299 0 : sd_dacl->dacl->aces[0].access_mask &= ~FILE_READ_DATA;
3300 :
3301 0 : status = cli_set_security_descriptor(cli,
3302 : fnum,
3303 : SECINFO_DACL,
3304 : sd_dacl);
3305 :
3306 0 : if (!NT_STATUS_IS_OK(status)) {
3307 0 : printf("Setting DACL on stream %s got (%s)\n",
3308 : sname,
3309 : nt_errstr(status));
3310 0 : goto fail;
3311 : }
3312 :
3313 0 : TALLOC_FREE(sd_dacl);
3314 :
3315 : /* Read again and check it changed. */
3316 0 : status = cli_query_security_descriptor(cli,
3317 : fnum,
3318 : SECINFO_DACL,
3319 : talloc_tos(),
3320 : &sd_dacl);
3321 :
3322 0 : if (!NT_STATUS_IS_OK(status)) {
3323 0 : printf("Reading DACL on stream %s got (%s)\n",
3324 : sname,
3325 : nt_errstr(status));
3326 0 : goto fail;
3327 : }
3328 :
3329 0 : if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3330 0 : sd_dacl->dacl->num_aces < 1) {
3331 0 : printf("Invalid DACL (1) returned on stream %s "
3332 : "(this should not happen)\n",
3333 : sname);
3334 0 : goto fail;
3335 : }
3336 :
3337 : /* FILE_READ_DATA should be gone from the first ace. */
3338 0 : if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) != 0) {
3339 0 : printf("DACL on stream %s did not change\n",
3340 : sname);
3341 0 : goto fail;
3342 : }
3343 :
3344 0 : ret = true;
3345 :
3346 0 : fail:
3347 :
3348 0 : if (fnum != (uint16_t)-1) {
3349 0 : cli_smb2_close_fnum(cli, fnum);
3350 0 : fnum = (uint16_t)-1;
3351 : }
3352 :
3353 0 : (void)cli_unlink(cli, fname, 0);
3354 0 : return ret;
3355 : }
3356 :
3357 0 : static NTSTATUS list_fn(struct file_info *finfo,
3358 : const char *name,
3359 : void *state)
3360 : {
3361 0 : bool *matched = (bool *)state;
3362 0 : if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
3363 0 : *matched = true;
3364 : }
3365 0 : return NT_STATUS_OK;
3366 : }
3367 :
3368 : /*
3369 : * Must be run against a share with "smbd async dosmode = yes".
3370 : * Checks we can return DOS attriutes other than "N".
3371 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14758
3372 : */
3373 :
3374 0 : bool run_list_dir_async_test(int dummy)
3375 : {
3376 0 : struct cli_state *cli = NULL;
3377 : NTSTATUS status;
3378 0 : const char *dname = "ASYNC_DIR";
3379 0 : bool ret = false;
3380 0 : bool matched = false;
3381 :
3382 0 : printf("SMB2 list dir async\n");
3383 :
3384 0 : if (!torture_init_connection(&cli)) {
3385 0 : return false;
3386 : }
3387 :
3388 0 : status = smbXcli_negprot(cli->conn,
3389 0 : cli->timeout,
3390 : PROTOCOL_SMB2_02,
3391 : PROTOCOL_SMB3_11);
3392 0 : if (!NT_STATUS_IS_OK(status)) {
3393 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3394 0 : return false;
3395 : }
3396 :
3397 0 : status = cli_session_setup_creds(cli, torture_creds);
3398 0 : if (!NT_STATUS_IS_OK(status)) {
3399 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3400 0 : return false;
3401 : }
3402 :
3403 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3404 0 : if (!NT_STATUS_IS_OK(status)) {
3405 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3406 0 : return false;
3407 : }
3408 :
3409 : /* Ensure directory doesn't exist. */
3410 0 : (void)cli_rmdir(cli, dname);
3411 :
3412 0 : status = cli_mkdir(cli, dname);
3413 0 : if (!NT_STATUS_IS_OK(status)) {
3414 0 : printf("cli_mkdir %s returned %s\n", dname, nt_errstr(status));
3415 0 : return false;
3416 : }
3417 :
3418 0 : status = cli_list(cli,
3419 : dname,
3420 : FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_DIRECTORY,
3421 : list_fn,
3422 : &matched);
3423 0 : if (!NT_STATUS_IS_OK(status)) {
3424 0 : printf("cli_list %s returned %s\n", dname, nt_errstr(status));
3425 0 : goto fail;
3426 : }
3427 :
3428 0 : if (!matched) {
3429 0 : printf("Failed to find %s\n", dname);
3430 0 : goto fail;
3431 : }
3432 :
3433 0 : ret = true;
3434 :
3435 0 : fail:
3436 :
3437 0 : (void)cli_rmdir(cli, dname);
3438 0 : return ret;
3439 : }
3440 :
3441 : /*
3442 : * Test delete a directory fails if a file is created
3443 : * in a directory after the delete on close is set.
3444 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
3445 : */
3446 :
3447 0 : bool run_delete_on_close_non_empty(int dummy)
3448 : {
3449 0 : struct cli_state *cli = NULL;
3450 : NTSTATUS status;
3451 0 : const char *dname = "DEL_ON_CLOSE_DIR";
3452 0 : const char *fname = "DEL_ON_CLOSE_DIR\\testfile";
3453 0 : uint16_t fnum = (uint16_t)-1;
3454 0 : uint16_t fnum1 = (uint16_t)-1;
3455 0 : bool ret = false;
3456 :
3457 0 : printf("SMB2 delete on close nonempty\n");
3458 :
3459 0 : if (!torture_init_connection(&cli)) {
3460 0 : return false;
3461 : }
3462 :
3463 0 : status = smbXcli_negprot(cli->conn,
3464 0 : cli->timeout,
3465 : PROTOCOL_SMB2_02,
3466 : PROTOCOL_SMB3_11);
3467 0 : if (!NT_STATUS_IS_OK(status)) {
3468 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3469 0 : return false;
3470 : }
3471 :
3472 0 : status = cli_session_setup_creds(cli, torture_creds);
3473 0 : if (!NT_STATUS_IS_OK(status)) {
3474 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3475 0 : return false;
3476 : }
3477 :
3478 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3479 0 : if (!NT_STATUS_IS_OK(status)) {
3480 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3481 0 : return false;
3482 : }
3483 :
3484 : /* Ensure directory doesn't exist. */
3485 0 : (void)cli_unlink(cli,
3486 : fname,
3487 : FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3488 0 : (void)cli_rmdir(cli, dname);
3489 :
3490 : /* Create target directory. */
3491 0 : status = cli_ntcreate(cli,
3492 : dname,
3493 : 0,
3494 : DELETE_ACCESS|FILE_READ_DATA,
3495 : FILE_ATTRIBUTE_DIRECTORY,
3496 : FILE_SHARE_READ|
3497 : FILE_SHARE_WRITE|
3498 : FILE_SHARE_DELETE,
3499 : FILE_CREATE,
3500 : FILE_DIRECTORY_FILE,
3501 : 0,
3502 : &fnum,
3503 : NULL);
3504 0 : if (!NT_STATUS_IS_OK(status)) {
3505 0 : printf("cli_ntcreate for directory %s returned %s\n",
3506 : dname,
3507 : nt_errstr(status));
3508 0 : goto out;
3509 : }
3510 :
3511 : /* Now set the delete on close bit. */
3512 0 : status = cli_nt_delete_on_close(cli, fnum, 1);
3513 0 : if (!NT_STATUS_IS_OK(status)) {
3514 0 : printf("cli_cli_nt_delete_on_close set for directory "
3515 : "%s returned %s\n",
3516 : dname,
3517 : nt_errstr(status));
3518 0 : goto out;
3519 : }
3520 :
3521 : /* Create file inside target directory. */
3522 : /*
3523 : * NB. On Windows this will return NT_STATUS_DELETE_PENDING. Only on
3524 : * Samba will this succeed by default (the option "check parent
3525 : * directory delete on close" configures behaviour), but we're using
3526 : * this to test a race condition.
3527 : */
3528 0 : status = cli_ntcreate(cli,
3529 : fname,
3530 : 0,
3531 : FILE_READ_DATA,
3532 : FILE_ATTRIBUTE_NORMAL,
3533 : FILE_SHARE_READ|
3534 : FILE_SHARE_WRITE|
3535 : FILE_SHARE_DELETE,
3536 : FILE_CREATE,
3537 : 0,
3538 : 0,
3539 : &fnum1,
3540 : NULL);
3541 0 : if (!NT_STATUS_IS_OK(status)) {
3542 0 : printf("cli_ntcreate for file %s returned %s\n",
3543 : fname,
3544 : nt_errstr(status));
3545 0 : goto out;
3546 : }
3547 0 : cli_close(cli, fnum1);
3548 0 : fnum1 = (uint16_t)-1;
3549 :
3550 : /* Now the close should fail. */
3551 0 : status = cli_close(cli, fnum);
3552 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3553 0 : printf("cli_close for directory %s returned %s\n",
3554 : dname,
3555 : nt_errstr(status));
3556 0 : goto out;
3557 : }
3558 :
3559 0 : ret = true;
3560 :
3561 0 : out:
3562 :
3563 0 : if (fnum1 != (uint16_t)-1) {
3564 0 : cli_close(cli, fnum1);
3565 : }
3566 0 : if (fnum != (uint16_t)-1) {
3567 0 : cli_nt_delete_on_close(cli, fnum, 0);
3568 0 : cli_close(cli, fnum);
3569 : }
3570 0 : (void)cli_unlink(cli,
3571 : fname,
3572 : FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3573 0 : (void)cli_rmdir(cli, dname);
3574 0 : return ret;
3575 : }
3576 :
3577 0 : static NTSTATUS check_empty_fn(struct file_info *finfo,
3578 : const char *mask,
3579 : void *private_data)
3580 : {
3581 0 : unsigned int *pcount = (unsigned int *)private_data;
3582 :
3583 0 : if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
3584 0 : (*pcount)++;
3585 0 : return NT_STATUS_OK;
3586 : }
3587 0 : return NT_STATUS_DIRECTORY_NOT_EMPTY;
3588 : }
3589 :
3590 : /*
3591 : * Test setting the delete on close bit on a directory
3592 : * containing an unwritable file fails or succeeds
3593 : * an a share set with "hide unwritable = yes"
3594 : * depending on the setting of "delete veto files".
3595 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3596 : *
3597 : * First version. With "delete veto files = yes"
3598 : * setting the delete on close should succeed.
3599 : */
3600 :
3601 0 : bool run_delete_on_close_nonwrite_delete_yes_test(int dummy)
3602 : {
3603 0 : struct cli_state *cli = NULL;
3604 : NTSTATUS status;
3605 0 : const char *dname = "delete_veto_yes";
3606 0 : const char *list_dname = "delete_veto_yes\\*";
3607 0 : uint16_t fnum = (uint16_t)-1;
3608 0 : bool ret = false;
3609 0 : unsigned int list_count = 0;
3610 :
3611 0 : printf("SMB2 delete on close nonwrite - delete veto yes\n");
3612 :
3613 0 : if (!torture_init_connection(&cli)) {
3614 0 : return false;
3615 : }
3616 :
3617 0 : status = smbXcli_negprot(cli->conn,
3618 0 : cli->timeout,
3619 : PROTOCOL_SMB2_02,
3620 : PROTOCOL_SMB3_11);
3621 0 : if (!NT_STATUS_IS_OK(status)) {
3622 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3623 0 : return false;
3624 : }
3625 :
3626 0 : status = cli_session_setup_creds(cli, torture_creds);
3627 0 : if (!NT_STATUS_IS_OK(status)) {
3628 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3629 0 : return false;
3630 : }
3631 :
3632 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3633 0 : if (!NT_STATUS_IS_OK(status)) {
3634 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3635 0 : return false;
3636 : }
3637 :
3638 : /* Ensure target directory is seen as empty. */
3639 0 : status = cli_list(cli,
3640 : list_dname,
3641 : FILE_ATTRIBUTE_DIRECTORY |
3642 : FILE_ATTRIBUTE_HIDDEN |
3643 : FILE_ATTRIBUTE_SYSTEM,
3644 : check_empty_fn,
3645 : &list_count);
3646 0 : if (!NT_STATUS_IS_OK(status)) {
3647 0 : printf("cli_list of %s returned %s\n",
3648 : dname,
3649 : nt_errstr(status));
3650 0 : return false;
3651 : }
3652 0 : if (list_count != 2) {
3653 0 : printf("cli_list of %s returned a count of %u\n",
3654 : dname,
3655 : list_count);
3656 0 : return false;
3657 : }
3658 :
3659 : /* Open target directory. */
3660 0 : status = cli_ntcreate(cli,
3661 : dname,
3662 : 0,
3663 : DELETE_ACCESS|FILE_READ_DATA,
3664 : FILE_ATTRIBUTE_DIRECTORY,
3665 : FILE_SHARE_READ|
3666 : FILE_SHARE_WRITE|
3667 : FILE_SHARE_DELETE,
3668 : FILE_OPEN,
3669 : FILE_DIRECTORY_FILE,
3670 : 0,
3671 : &fnum,
3672 : NULL);
3673 0 : if (!NT_STATUS_IS_OK(status)) {
3674 0 : printf("cli_ntcreate for directory %s returned %s\n",
3675 : dname,
3676 : nt_errstr(status));
3677 0 : goto out;
3678 : }
3679 :
3680 : /* Now set the delete on close bit. */
3681 0 : status = cli_nt_delete_on_close(cli, fnum, 1);
3682 0 : if (!NT_STATUS_IS_OK(status)) {
3683 0 : printf("cli_cli_nt_delete_on_close set for directory "
3684 : "%s returned %s (should have succeeded)\n",
3685 : dname,
3686 : nt_errstr(status));
3687 0 : goto out;
3688 : }
3689 :
3690 0 : ret = true;
3691 :
3692 0 : out:
3693 :
3694 0 : if (fnum != (uint16_t)-1) {
3695 0 : (void)cli_nt_delete_on_close(cli, fnum, 0);
3696 0 : (void)cli_close(cli, fnum);
3697 : }
3698 0 : return ret;
3699 : }
3700 :
3701 : /*
3702 : * Test setting the delete on close bit on a directory
3703 : * containing an unwritable file fails or succeeds
3704 : * an a share set with "hide unwritable = yes"
3705 : * depending on the setting of "delete veto files".
3706 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3707 : *
3708 : * Second version. With "delete veto files = no"
3709 : * setting the delete on close should fail.
3710 : */
3711 :
3712 0 : bool run_delete_on_close_nonwrite_delete_no_test(int dummy)
3713 : {
3714 0 : struct cli_state *cli = NULL;
3715 : NTSTATUS status;
3716 0 : const char *dname = "delete_veto_no";
3717 0 : const char *list_dname = "delete_veto_no\\*";
3718 0 : uint16_t fnum = (uint16_t)-1;
3719 0 : bool ret = false;
3720 0 : unsigned int list_count = 0;
3721 :
3722 0 : printf("SMB2 delete on close nonwrite - delete veto yes\n");
3723 :
3724 0 : if (!torture_init_connection(&cli)) {
3725 0 : return false;
3726 : }
3727 :
3728 0 : status = smbXcli_negprot(cli->conn,
3729 0 : cli->timeout,
3730 : PROTOCOL_SMB2_02,
3731 : PROTOCOL_SMB3_11);
3732 0 : if (!NT_STATUS_IS_OK(status)) {
3733 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3734 0 : return false;
3735 : }
3736 :
3737 0 : status = cli_session_setup_creds(cli, torture_creds);
3738 0 : if (!NT_STATUS_IS_OK(status)) {
3739 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
3740 0 : return false;
3741 : }
3742 :
3743 0 : status = cli_tree_connect(cli, share, "?????", NULL);
3744 0 : if (!NT_STATUS_IS_OK(status)) {
3745 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
3746 0 : return false;
3747 : }
3748 :
3749 : /* Ensure target directory is seen as empty. */
3750 0 : status = cli_list(cli,
3751 : list_dname,
3752 : FILE_ATTRIBUTE_DIRECTORY |
3753 : FILE_ATTRIBUTE_HIDDEN |
3754 : FILE_ATTRIBUTE_SYSTEM,
3755 : check_empty_fn,
3756 : &list_count);
3757 0 : if (!NT_STATUS_IS_OK(status)) {
3758 0 : printf("cli_list of %s returned %s\n",
3759 : dname,
3760 : nt_errstr(status));
3761 0 : return false;
3762 : }
3763 0 : if (list_count != 2) {
3764 0 : printf("cli_list of %s returned a count of %u\n",
3765 : dname,
3766 : list_count);
3767 0 : return false;
3768 : }
3769 :
3770 : /* Open target directory. */
3771 0 : status = cli_ntcreate(cli,
3772 : dname,
3773 : 0,
3774 : DELETE_ACCESS|FILE_READ_DATA,
3775 : FILE_ATTRIBUTE_DIRECTORY,
3776 : FILE_SHARE_READ|
3777 : FILE_SHARE_WRITE|
3778 : FILE_SHARE_DELETE,
3779 : FILE_OPEN,
3780 : FILE_DIRECTORY_FILE,
3781 : 0,
3782 : &fnum,
3783 : NULL);
3784 0 : if (!NT_STATUS_IS_OK(status)) {
3785 0 : printf("cli_ntcreate for directory %s returned %s\n",
3786 : dname,
3787 : nt_errstr(status));
3788 0 : goto out;
3789 : }
3790 :
3791 : /* Now set the delete on close bit. */
3792 0 : status = cli_nt_delete_on_close(cli, fnum, 1);
3793 0 : if (NT_STATUS_IS_OK(status)) {
3794 0 : printf("cli_cli_nt_delete_on_close set for directory "
3795 : "%s returned NT_STATUS_OK "
3796 : "(should have failed)\n",
3797 : dname);
3798 0 : goto out;
3799 : }
3800 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3801 0 : printf("cli_cli_nt_delete_on_close set for directory "
3802 : "%s returned %s "
3803 : "(should have returned "
3804 : "NT_STATUS_DIRECTORY_NOT_EMPTY)\n",
3805 : dname,
3806 : nt_errstr(status));
3807 0 : goto out;
3808 : }
3809 :
3810 0 : ret = true;
3811 :
3812 0 : out:
3813 :
3814 0 : if (fnum != (uint16_t)-1) {
3815 0 : (void)cli_nt_delete_on_close(cli, fnum, 0);
3816 0 : (void)cli_close(cli, fnum);
3817 : }
3818 0 : return ret;
3819 : }
3820 :
3821 : /*
3822 : * Open an SMB2 file readonly and return the inode number.
3823 : */
3824 0 : static NTSTATUS get_smb2_inode(struct cli_state *cli,
3825 : const char *pathname,
3826 : uint64_t *ino_ret)
3827 : {
3828 : NTSTATUS status;
3829 0 : uint64_t fid_persistent = 0;
3830 0 : uint64_t fid_volatile = 0;
3831 0 : DATA_BLOB outbuf = data_blob_null;
3832 : /*
3833 : * Open the file.
3834 : */
3835 0 : status = smb2cli_create(cli->conn,
3836 0 : cli->timeout,
3837 : cli->smb2.session,
3838 : cli->smb2.tcon,
3839 : pathname,
3840 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3841 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3842 : SEC_STD_SYNCHRONIZE|
3843 : SEC_FILE_READ_DATA|
3844 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
3845 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3846 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3847 : FILE_OPEN, /* create_disposition, */
3848 : 0, /* create_options, */
3849 : NULL, /* smb2_create_blobs *blobs */
3850 : &fid_persistent,
3851 : &fid_volatile,
3852 : NULL, /* struct smb_create_returns * */
3853 : talloc_tos(), /* mem_ctx. */
3854 : NULL, /* struct smb2_create_blobs * */
3855 : NULL); /* struct symlink_reparse_struct */
3856 0 : if (!NT_STATUS_IS_OK(status)) {
3857 0 : return status;
3858 : }
3859 :
3860 : /*
3861 : * Get the inode.
3862 : */
3863 0 : status = smb2cli_query_info(cli->conn,
3864 0 : cli->timeout,
3865 : cli->smb2.session,
3866 : cli->smb2.tcon,
3867 : SMB2_0_INFO_FILE,
3868 : (SMB_FILE_ALL_INFORMATION - 1000), /* in_file_info_class */
3869 : 1024, /* in_max_output_length */
3870 : NULL, /* in_input_buffer */
3871 : 0, /* in_additional_info */
3872 : 0, /* in_flags */
3873 : fid_persistent,
3874 : fid_volatile,
3875 : talloc_tos(),
3876 : &outbuf);
3877 :
3878 0 : if (NT_STATUS_IS_OK(status)) {
3879 0 : *ino_ret = PULL_LE_U64(outbuf.data, 0x40);
3880 : }
3881 :
3882 0 : (void)smb2cli_close(cli->conn,
3883 0 : cli->timeout,
3884 : cli->smb2.session,
3885 : cli->smb2.tcon,
3886 : 0,
3887 : fid_persistent,
3888 : fid_volatile);
3889 0 : return status;
3890 : }
3891 :
3892 : /*
3893 : * Check an inode matches a given SMB2 path.
3894 : */
3895 0 : static bool smb2_inode_matches(struct cli_state *cli,
3896 : const char *match_pathname,
3897 : uint64_t ino_tomatch,
3898 : const char *test_pathname)
3899 : {
3900 0 : uint64_t test_ino = 0;
3901 : NTSTATUS status;
3902 :
3903 0 : status = get_smb2_inode(cli,
3904 : test_pathname,
3905 : &test_ino);
3906 0 : if (!NT_STATUS_IS_OK(status)) {
3907 0 : printf("%s: Failed to get ino "
3908 : "number for %s, (%s)\n",
3909 : __func__,
3910 : test_pathname,
3911 : nt_errstr(status));
3912 0 : return false;
3913 : }
3914 0 : if (test_ino != ino_tomatch) {
3915 0 : printf("%s: Inode missmatch, ino_tomatch (%s) "
3916 : "ino=%"PRIu64" test (%s) "
3917 : "ino=%"PRIu64"\n",
3918 : __func__,
3919 : match_pathname,
3920 : ino_tomatch,
3921 : test_pathname,
3922 : test_ino);
3923 0 : return false;
3924 : }
3925 0 : return true;
3926 : }
3927 :
3928 : /*
3929 : * Delete an SMB2 file on a DFS share.
3930 : */
3931 0 : static NTSTATUS smb2_dfs_delete(struct cli_state *cli,
3932 : const char *pathname)
3933 : {
3934 : NTSTATUS status;
3935 0 : uint64_t fid_persistent = 0;
3936 0 : uint64_t fid_volatile = 0;
3937 : uint8_t data[1];
3938 : DATA_BLOB inbuf;
3939 :
3940 : /*
3941 : * Open the file.
3942 : */
3943 0 : status = smb2cli_create(cli->conn,
3944 0 : cli->timeout,
3945 : cli->smb2.session,
3946 : cli->smb2.tcon,
3947 : pathname,
3948 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3949 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3950 : SEC_STD_SYNCHRONIZE|
3951 : SEC_STD_DELETE, /* desired_access, */
3952 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3953 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3954 : FILE_OPEN, /* create_disposition, */
3955 : 0, /* create_options, */
3956 : NULL, /* smb2_create_blobs *blobs */
3957 : &fid_persistent,
3958 : &fid_volatile,
3959 : NULL, /* struct smb_create_returns * */
3960 : talloc_tos(), /* mem_ctx. */
3961 : NULL, /* struct smb2_create_blobs * */
3962 : NULL); /* struct symlink_reparse_struct */
3963 0 : if (!NT_STATUS_IS_OK(status)) {
3964 0 : return status;
3965 : }
3966 :
3967 : /*
3968 : * Set delete on close.
3969 : */
3970 0 : PUSH_LE_U8(&data[0], 0, 1);
3971 0 : inbuf.data = &data[0];
3972 0 : inbuf.length = 1;
3973 :
3974 0 : status = smb2cli_set_info(cli->conn,
3975 0 : cli->timeout,
3976 : cli->smb2.session,
3977 : cli->smb2.tcon,
3978 : SMB2_0_INFO_FILE, /* info_type. */
3979 : SMB_FILE_DISPOSITION_INFORMATION - 1000, /* info_class */
3980 : &inbuf,
3981 : 0, /* additional_info. */
3982 : fid_persistent,
3983 : fid_volatile);
3984 0 : if (!NT_STATUS_IS_OK(status)) {
3985 0 : return status;
3986 : }
3987 0 : status = smb2cli_close(cli->conn,
3988 0 : cli->timeout,
3989 : cli->smb2.session,
3990 : cli->smb2.tcon,
3991 : 0,
3992 : fid_persistent,
3993 : fid_volatile);
3994 0 : return status;
3995 : }
3996 :
3997 : /*
3998 : * Rename or hardlink an SMB2 file on a DFS share.
3999 : */
4000 0 : static NTSTATUS smb2_dfs_setinfo_name(struct cli_state *cli,
4001 : uint64_t fid_persistent,
4002 : uint64_t fid_volatile,
4003 : const char *newname,
4004 : bool do_rename)
4005 : {
4006 : NTSTATUS status;
4007 : DATA_BLOB inbuf;
4008 0 : smb_ucs2_t *converted_str = NULL;
4009 0 : size_t converted_size_bytes = 0;
4010 : size_t inbuf_size;
4011 0 : uint8_t info_class = 0;
4012 : bool ok;
4013 :
4014 0 : ok = push_ucs2_talloc(talloc_tos(),
4015 : &converted_str,
4016 : newname,
4017 : &converted_size_bytes);
4018 0 : if (!ok) {
4019 0 : return NT_STATUS_INVALID_PARAMETER;
4020 : }
4021 : /*
4022 : * W2K8 insists the dest name is not null terminated. Remove
4023 : * the last 2 zero bytes and reduce the name length.
4024 : */
4025 0 : if (converted_size_bytes < 2) {
4026 0 : return NT_STATUS_INVALID_PARAMETER;
4027 : }
4028 0 : converted_size_bytes -= 2;
4029 0 : inbuf_size = 20 + converted_size_bytes;
4030 0 : if (inbuf_size < 20) {
4031 : /* Integer wrap check. */
4032 0 : return NT_STATUS_INVALID_PARAMETER;
4033 : }
4034 :
4035 : /*
4036 : * The Windows 10 SMB2 server has a minimum length
4037 : * for a SMB2_FILE_RENAME_INFORMATION buffer of
4038 : * 24 bytes. It returns NT_STATUS_INFO_LENGTH_MISMATCH
4039 : * if the length is less.
4040 : */
4041 0 : inbuf_size = MAX(inbuf_size, 24);
4042 0 : inbuf = data_blob_talloc_zero(talloc_tos(), inbuf_size);
4043 0 : if (inbuf.data == NULL) {
4044 0 : return NT_STATUS_NO_MEMORY;
4045 : }
4046 0 : PUSH_LE_U32(inbuf.data, 16, converted_size_bytes);
4047 0 : memcpy(inbuf.data + 20, converted_str, converted_size_bytes);
4048 0 : TALLOC_FREE(converted_str);
4049 :
4050 0 : if (do_rename == true) {
4051 0 : info_class = SMB_FILE_RENAME_INFORMATION - 1000;
4052 : } else {
4053 : /* Hardlink. */
4054 0 : info_class = SMB_FILE_LINK_INFORMATION - 1000;
4055 : }
4056 :
4057 0 : status = smb2cli_set_info(cli->conn,
4058 0 : cli->timeout,
4059 : cli->smb2.session,
4060 : cli->smb2.tcon,
4061 : SMB2_0_INFO_FILE, /* info_type. */
4062 : info_class, /* info_class */
4063 : &inbuf,
4064 : 0, /* additional_info. */
4065 : fid_persistent,
4066 : fid_volatile);
4067 0 : return status;
4068 : }
4069 :
4070 0 : static NTSTATUS smb2_dfs_rename(struct cli_state *cli,
4071 : uint64_t fid_persistent,
4072 : uint64_t fid_volatile,
4073 : const char *newname)
4074 : {
4075 0 : return smb2_dfs_setinfo_name(cli,
4076 : fid_persistent,
4077 : fid_volatile,
4078 : newname,
4079 : true); /* do_rename */
4080 : }
4081 :
4082 0 : static NTSTATUS smb2_dfs_hlink(struct cli_state *cli,
4083 : uint64_t fid_persistent,
4084 : uint64_t fid_volatile,
4085 : const char *newname)
4086 : {
4087 0 : return smb2_dfs_setinfo_name(cli,
4088 : fid_persistent,
4089 : fid_volatile,
4090 : newname,
4091 : false); /* do_rename */
4092 : }
4093 :
4094 : /*
4095 : * According to:
4096 :
4097 : * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/dc9978d7-6299-4c5a-a22d-a039cdc716ea
4098 : *
4099 : * (Characters " \ / [ ] : | < > + = ; , * ?,
4100 : * and control characters in range 0x00 through
4101 : * 0x1F, inclusive, are illegal in a share name)
4102 : *
4103 : * But Windows server only checks in DFS sharenames ':'. All other
4104 : * share names are allowed.
4105 : */
4106 :
4107 0 : static bool test_smb2_dfs_sharenames(struct cli_state *cli,
4108 : const char *dfs_root_share_name,
4109 : uint64_t root_ino)
4110 : {
4111 : char test_path[9];
4112 0 : const char *test_str = "/[]:|<>+=;,*?";
4113 : const char *p;
4114 : unsigned int i;
4115 0 : bool ino_matched = false;
4116 :
4117 : /* Setup template pathname. */
4118 0 : memcpy(test_path, "SERVER\\X", 9);
4119 :
4120 : /* Test invalid control characters. */
4121 0 : for (i = 1; i < 0x20; i++) {
4122 0 : test_path[7] = i;
4123 0 : ino_matched = smb2_inode_matches(cli,
4124 : dfs_root_share_name,
4125 : root_ino,
4126 : test_path);
4127 0 : if (!ino_matched) {
4128 0 : return false;
4129 : }
4130 : }
4131 :
4132 : /* Test explicit invalid characters. */
4133 0 : for (p = test_str; *p != '\0'; p++) {
4134 0 : test_path[7] = *p;
4135 0 : if (*p == ':') {
4136 : /*
4137 : * Only ':' is treated as an INVALID sharename
4138 : * for a DFS SERVER\\SHARE path.
4139 : */
4140 0 : uint64_t test_ino = 0;
4141 0 : NTSTATUS status = get_smb2_inode(cli,
4142 : test_path,
4143 : &test_ino);
4144 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
4145 0 : printf("%s:%d Open of %s should get "
4146 : "NT_STATUS_OBJECT_NAME_INVALID, got %s\n",
4147 : __FILE__,
4148 : __LINE__,
4149 : test_path,
4150 : nt_errstr(status));
4151 0 : return false;
4152 : }
4153 : } else {
4154 0 : ino_matched = smb2_inode_matches(cli,
4155 : dfs_root_share_name,
4156 : root_ino,
4157 : test_path);
4158 0 : if (!ino_matched) {
4159 0 : return false;
4160 : }
4161 : }
4162 : }
4163 0 : return true;
4164 : }
4165 :
4166 : /*
4167 : * "Raw" test of SMB2 paths to a DFS share.
4168 : * We must use the lower level smb2cli_XXXX() interfaces,
4169 : * not the cli_XXX() ones here as the ultimate goal is to fix our
4170 : * cli_XXX() interfaces to work transparently over DFS.
4171 : *
4172 : * So here, we're testing the server code, not the client code.
4173 : *
4174 : * Passes cleanly against Windows.
4175 : */
4176 :
4177 0 : bool run_smb2_dfs_paths(int dummy)
4178 : {
4179 0 : struct cli_state *cli = NULL;
4180 : NTSTATUS status;
4181 0 : bool dfs_supported = false;
4182 0 : char *dfs_root_share_name = NULL;
4183 0 : uint64_t root_ino = 0;
4184 0 : uint64_t test_ino = 0;
4185 0 : bool ino_matched = false;
4186 0 : uint64_t fid_persistent = 0;
4187 0 : uint64_t fid_volatile = 0;
4188 0 : bool retval = false;
4189 0 : bool ok = false;
4190 :
4191 0 : printf("Starting SMB2-DFS-PATHS\n");
4192 :
4193 0 : if (!torture_init_connection(&cli)) {
4194 0 : return false;
4195 : }
4196 :
4197 0 : status = smbXcli_negprot(cli->conn,
4198 0 : cli->timeout,
4199 : PROTOCOL_SMB2_02,
4200 : PROTOCOL_SMB3_11);
4201 0 : if (!NT_STATUS_IS_OK(status)) {
4202 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4203 0 : return false;
4204 : }
4205 :
4206 0 : status = cli_session_setup_creds(cli, torture_creds);
4207 0 : if (!NT_STATUS_IS_OK(status)) {
4208 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
4209 0 : return false;
4210 : }
4211 :
4212 0 : status = cli_tree_connect(cli, share, "?????", NULL);
4213 0 : if (!NT_STATUS_IS_OK(status)) {
4214 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
4215 0 : return false;
4216 : }
4217 :
4218 : /* Ensure this is a DFS share. */
4219 0 : dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4220 0 : if (!dfs_supported) {
4221 0 : printf("Server %s does not support DFS\n",
4222 0 : smbXcli_conn_remote_name(cli->conn));
4223 0 : return false;
4224 : }
4225 0 : dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4226 0 : if (!dfs_supported) {
4227 0 : printf("Share %s does not support DFS\n",
4228 0 : cli->share);
4229 0 : return false;
4230 : }
4231 : /*
4232 : * Create the "official" DFS share root name.
4233 : * No SMB2 paths can start with '\\'.
4234 : */
4235 0 : dfs_root_share_name = talloc_asprintf(talloc_tos(),
4236 : "%s\\%s",
4237 0 : smbXcli_conn_remote_name(cli->conn),
4238 0 : cli->share);
4239 0 : if (dfs_root_share_name == NULL) {
4240 0 : printf("Out of memory\n");
4241 0 : return false;
4242 : }
4243 :
4244 : /* Get the share root inode number. */
4245 0 : status = get_smb2_inode(cli,
4246 : dfs_root_share_name,
4247 : &root_ino);
4248 0 : if (!NT_STATUS_IS_OK(status)) {
4249 0 : printf("%s:%d Failed to get ino number for share root %s, (%s)\n",
4250 : __FILE__,
4251 : __LINE__,
4252 : dfs_root_share_name,
4253 : nt_errstr(status));
4254 0 : return false;
4255 : }
4256 :
4257 : /*
4258 : * Test the Windows algorithm for parsing DFS names.
4259 : */
4260 : /*
4261 : * A single "SERVER" element should open and match the share root.
4262 : */
4263 0 : ino_matched = smb2_inode_matches(cli,
4264 : dfs_root_share_name,
4265 : root_ino,
4266 0 : smbXcli_conn_remote_name(cli->conn));
4267 0 : if (!ino_matched) {
4268 0 : printf("%s:%d Failed to match ino number for %s\n",
4269 : __FILE__,
4270 : __LINE__,
4271 0 : smbXcli_conn_remote_name(cli->conn));
4272 0 : return false;
4273 : }
4274 :
4275 : /*
4276 : * An "" DFS empty server name should open and match the share root on
4277 : * Windows 2008. Windows 2022 returns NT_STATUS_INVALID_PARAMETER
4278 : * for a DFS empty server name.
4279 : */
4280 0 : status = get_smb2_inode(cli,
4281 : "",
4282 : &test_ino);
4283 0 : if (NT_STATUS_IS_OK(status)) {
4284 : /*
4285 : * Windows 2008 - open succeeded. Proceed to
4286 : * check ino number.
4287 : */
4288 0 : ino_matched = smb2_inode_matches(cli,
4289 : dfs_root_share_name,
4290 : root_ino,
4291 : "");
4292 0 : if (!ino_matched) {
4293 0 : printf("%s:%d Failed to match ino number for %s\n",
4294 : __FILE__,
4295 : __LINE__,
4296 : "");
4297 0 : return false;
4298 : }
4299 : }
4300 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4301 : /*
4302 : * For Windows 2022 we expect to fail with
4303 : * NT_STATUS_INVALID_PARAMETER. Anything else is
4304 : * unexpected.
4305 : */
4306 0 : printf("%s:%d Unexpected error (%s) getting ino number for %s\n",
4307 : __FILE__,
4308 : __LINE__,
4309 : nt_errstr(status),
4310 : "");
4311 0 : return false;
4312 : }
4313 : /* A "BAD" server name should open and match the share root. */
4314 0 : ino_matched = smb2_inode_matches(cli,
4315 : dfs_root_share_name,
4316 : root_ino,
4317 : "BAD");
4318 0 : if (!ino_matched) {
4319 0 : printf("%s:%d Failed to match ino number for %s\n",
4320 : __FILE__,
4321 : __LINE__,
4322 : "BAD");
4323 0 : return false;
4324 : }
4325 : /*
4326 : * A "BAD\\BAD" server and share name should open
4327 : * and match the share root.
4328 : */
4329 0 : ino_matched = smb2_inode_matches(cli,
4330 : dfs_root_share_name,
4331 : root_ino,
4332 : "BAD\\BAD");
4333 0 : if (!ino_matched) {
4334 0 : printf("%s:%d Failed to match ino number for %s\n",
4335 : __FILE__,
4336 : __LINE__,
4337 : "BAD\\BAD");
4338 0 : return false;
4339 : }
4340 : /*
4341 : * Trying to open "BAD\\BAD\\BAD" should get
4342 : * NT_STATUS_OBJECT_NAME_NOT_FOUND.
4343 : */
4344 0 : status = get_smb2_inode(cli,
4345 : "BAD\\BAD\\BAD",
4346 : &test_ino);
4347 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4348 0 : printf("%s:%d Open of %s should get "
4349 : "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
4350 : __FILE__,
4351 : __LINE__,
4352 : "BAD\\BAD\\BAD",
4353 : nt_errstr(status));
4354 0 : return false;
4355 : }
4356 : /*
4357 : * Trying to open "BAD\\BAD\\BAD\\BAD" should get
4358 : * NT_STATUS_OBJECT_PATH_NOT_FOUND.
4359 : */
4360 0 : status = get_smb2_inode(cli,
4361 : "BAD\\BAD\\BAD\\BAD",
4362 : &test_ino);
4363 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4364 0 : printf("%s:%d Open of %s should get "
4365 : "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
4366 : __FILE__,
4367 : __LINE__,
4368 : "BAD\\BAD\\BAD\\BAD",
4369 : nt_errstr(status));
4370 0 : return false;
4371 : }
4372 : /*
4373 : * Test for invalid pathname characters in the servername.
4374 : * They are ignored, and it still opens the share root.
4375 : */
4376 0 : ino_matched = smb2_inode_matches(cli,
4377 : dfs_root_share_name,
4378 : root_ino,
4379 : "::::");
4380 0 : if (!ino_matched) {
4381 0 : printf("%s:%d Failed to match ino number for %s\n",
4382 : __FILE__,
4383 : __LINE__,
4384 : "::::");
4385 0 : return false;
4386 : }
4387 :
4388 : /*
4389 : * Test for invalid pathname characters in the sharename.
4390 : * Invalid sharename characters should still be flagged as
4391 : * NT_STATUS_OBJECT_NAME_INVALID. It turns out only ':'
4392 : * is considered an invalid sharename character.
4393 : */
4394 0 : ok = test_smb2_dfs_sharenames(cli,
4395 : dfs_root_share_name,
4396 : root_ino);
4397 0 : if (!ok) {
4398 0 : return false;
4399 : }
4400 :
4401 : /* Now create a file called "file". */
4402 0 : status = smb2cli_create(cli->conn,
4403 0 : cli->timeout,
4404 0 : cli->smb2.session,
4405 0 : cli->smb2.tcon,
4406 : "BAD\\BAD\\file",
4407 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4408 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4409 : SEC_STD_SYNCHRONIZE|
4410 : SEC_STD_DELETE |
4411 : SEC_FILE_READ_DATA|
4412 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4413 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4414 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4415 : FILE_CREATE, /* create_disposition, */
4416 : 0, /* create_options, */
4417 : NULL, /* smb2_create_blobs *blobs */
4418 : &fid_persistent,
4419 : &fid_volatile,
4420 : NULL, /* struct smb_create_returns * */
4421 : talloc_tos(), /* mem_ctx. */
4422 : NULL, /* struct smb2_create_blobs * */
4423 : NULL); /* struct symlink_reparse_struct */
4424 0 : if (!NT_STATUS_IS_OK(status)) {
4425 0 : printf("%s:%d smb2cli_create on %s returned %s\n",
4426 : __FILE__,
4427 : __LINE__,
4428 : "BAD\\BAD\\file",
4429 : nt_errstr(status));
4430 0 : return false;
4431 : }
4432 :
4433 : /*
4434 : * Trying to open "BAD\\BAD\\file" should now get
4435 : * a valid inode.
4436 : */
4437 0 : status = get_smb2_inode(cli,
4438 : "BAD\\BAD\\file",
4439 : &test_ino);
4440 0 : if (!NT_STATUS_IS_OK(status)) {
4441 0 : printf("%s:%d Open of %s should succeed "
4442 : "got %s\n",
4443 : __FILE__,
4444 : __LINE__,
4445 : "BAD\\BAD\\file",
4446 : nt_errstr(status));
4447 0 : goto err;
4448 : }
4449 :
4450 : /*
4451 : * Now show that renames use relative,
4452 : * not full DFS paths.
4453 : */
4454 :
4455 : /* Full DFS path should fail. */
4456 0 : status = smb2_dfs_rename(cli,
4457 : fid_persistent,
4458 : fid_volatile,
4459 : "ANY\\NAME\\renamed_file");
4460 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4461 0 : printf("%s:%d Rename of %s -> %s should fail "
4462 : "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4463 : __FILE__,
4464 : __LINE__,
4465 : "BAD\\BAD\\file",
4466 : "ANY\\NAME\\renamed_file",
4467 : nt_errstr(status));
4468 0 : goto err;
4469 : }
4470 : /* Relative DFS path should succeed. */
4471 0 : status = smb2_dfs_rename(cli,
4472 : fid_persistent,
4473 : fid_volatile,
4474 : "renamed_file");
4475 0 : if (!NT_STATUS_IS_OK(status)) {
4476 0 : printf("%s:%d: Rename of %s -> %s should succeed. "
4477 : "Got %s\n",
4478 : __FILE__,
4479 : __LINE__,
4480 : "BAD\\BAD\\file",
4481 : "renamed_file",
4482 : nt_errstr(status));
4483 0 : goto err;
4484 : }
4485 :
4486 : /*
4487 : * Trying to open "BAD\\BAD\\renamed_file" should now get
4488 : * a valid inode.
4489 : */
4490 0 : status = get_smb2_inode(cli,
4491 : "BAD\\BAD\\renamed_file",
4492 : &test_ino);
4493 0 : if (!NT_STATUS_IS_OK(status)) {
4494 0 : printf("%s:%d: Open of %s should succeed "
4495 : "got %s\n",
4496 : __FILE__,
4497 : __LINE__,
4498 : "BAD\\BAD\\renamed_file",
4499 : nt_errstr(status));
4500 0 : goto err;
4501 : }
4502 :
4503 : /*
4504 : * Now show that hard links use relative,
4505 : * not full DFS paths.
4506 : */
4507 :
4508 : /* Full DFS path should fail. */
4509 0 : status = smb2_dfs_hlink(cli,
4510 : fid_persistent,
4511 : fid_volatile,
4512 : "ANY\\NAME\\hlink");
4513 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4514 0 : printf("%s:%d Hlink of %s -> %s should fail "
4515 : "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4516 : __FILE__,
4517 : __LINE__,
4518 : "ANY\\NAME\\renamed_file",
4519 : "ANY\\NAME\\hlink",
4520 : nt_errstr(status));
4521 0 : goto err;
4522 : }
4523 : /* Relative DFS path should succeed. */
4524 0 : status = smb2_dfs_hlink(cli,
4525 : fid_persistent,
4526 : fid_volatile,
4527 : "hlink");
4528 0 : if (!NT_STATUS_IS_OK(status)) {
4529 0 : printf("%s:%d: Hlink of %s -> %s should succeed. "
4530 : "Got %s\n",
4531 : __FILE__,
4532 : __LINE__,
4533 : "ANY\\NAME\\renamed_file",
4534 : "hlink",
4535 : nt_errstr(status));
4536 0 : goto err;
4537 : }
4538 :
4539 : /*
4540 : * Trying to open "BAD\\BAD\\hlink" should now get
4541 : * a valid inode.
4542 : */
4543 0 : status = get_smb2_inode(cli,
4544 : "BAD\\BAD\\hlink",
4545 : &test_ino);
4546 0 : if (!NT_STATUS_IS_OK(status)) {
4547 0 : printf("%s:%d Open of %s should succeed "
4548 : "got %s\n",
4549 : __FILE__,
4550 : __LINE__,
4551 : "BAD\\BAD\\hlink",
4552 : nt_errstr(status));
4553 0 : goto err;
4554 : }
4555 :
4556 0 : retval = true;
4557 :
4558 0 : err:
4559 :
4560 0 : if (fid_persistent != 0 || fid_volatile != 0) {
4561 0 : smb2cli_close(cli->conn,
4562 0 : cli->timeout,
4563 0 : cli->smb2.session,
4564 0 : cli->smb2.tcon,
4565 : 0, /* flags */
4566 : fid_persistent,
4567 : fid_volatile);
4568 : }
4569 : /* Delete anything we made. */
4570 0 : (void)smb2_dfs_delete(cli, "BAD\\BAD\\BAD");
4571 0 : (void)smb2_dfs_delete(cli, "BAD\\BAD\\file");
4572 0 : (void)smb2_dfs_delete(cli, "BAD\\BAD\\renamed_file");
4573 0 : (void)smb2_dfs_delete(cli, "BAD\\BAD\\hlink");
4574 0 : return retval;
4575 : }
4576 :
4577 : /*
4578 : * Add a test that sends DFS paths and sets the
4579 : * SMB2 flag FLAGS2_DFS_PATHNAMES, but to a non-DFS
4580 : * share. Windows passes this (it just treats the
4581 : * pathnames as non-DFS and ignores the FLAGS2_DFS_PATHNAMES
4582 : * bit).
4583 : */
4584 :
4585 0 : bool run_smb2_non_dfs_share(int dummy)
4586 : {
4587 0 : struct cli_state *cli = NULL;
4588 : NTSTATUS status;
4589 0 : bool dfs_supported = false;
4590 0 : uint64_t fid_persistent = 0;
4591 0 : uint64_t fid_volatile = 0;
4592 0 : bool retval = false;
4593 0 : char *dfs_filename = NULL;
4594 :
4595 0 : printf("Starting SMB2-DFS-NON-DFS-SHARE\n");
4596 :
4597 0 : if (!torture_init_connection(&cli)) {
4598 0 : return false;
4599 : }
4600 :
4601 0 : status = smbXcli_negprot(cli->conn,
4602 0 : cli->timeout,
4603 : PROTOCOL_SMB2_02,
4604 : PROTOCOL_SMB3_11);
4605 0 : if (!NT_STATUS_IS_OK(status)) {
4606 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4607 0 : return false;
4608 : }
4609 :
4610 0 : status = cli_session_setup_creds(cli, torture_creds);
4611 0 : if (!NT_STATUS_IS_OK(status)) {
4612 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
4613 0 : return false;
4614 : }
4615 :
4616 0 : status = cli_tree_connect(cli, share, "?????", NULL);
4617 0 : if (!NT_STATUS_IS_OK(status)) {
4618 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
4619 0 : return false;
4620 : }
4621 :
4622 0 : dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4623 0 : if (!dfs_supported) {
4624 0 : printf("Server %s does not support DFS\n",
4625 0 : smbXcli_conn_remote_name(cli->conn));
4626 0 : return false;
4627 : }
4628 : /* Ensure this is *NOT* a DFS share. */
4629 0 : dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4630 0 : if (dfs_supported) {
4631 0 : printf("Share %s is a DFS share.\n",
4632 0 : cli->share);
4633 0 : return false;
4634 : }
4635 : /*
4636 : * Force the share to be DFS, as far as the client
4637 : * is concerned.
4638 : */
4639 0 : smb2cli_tcon_set_values(cli->smb2.tcon,
4640 0 : cli->smb2.session,
4641 0 : smb2cli_tcon_current_id(cli->smb2.tcon),
4642 : 0,
4643 0 : smb2cli_tcon_flags(cli->smb2.tcon),
4644 0 : smb2cli_tcon_capabilities(cli->smb2.tcon) |
4645 : SMB2_SHARE_CAP_DFS,
4646 : 0);
4647 :
4648 : /* Come up with a "valid" SMB2 DFS name. */
4649 0 : dfs_filename = talloc_asprintf(talloc_tos(),
4650 : "%s\\%s\\file",
4651 0 : smbXcli_conn_remote_name(cli->conn),
4652 0 : cli->share);
4653 0 : if (dfs_filename == NULL) {
4654 0 : printf("Out of memory\n");
4655 0 : return false;
4656 : }
4657 :
4658 : /* Now try create dfs_filename. */
4659 0 : status = smb2cli_create(cli->conn,
4660 0 : cli->timeout,
4661 0 : cli->smb2.session,
4662 0 : cli->smb2.tcon,
4663 : dfs_filename,
4664 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4665 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4666 : SEC_STD_SYNCHRONIZE|
4667 : SEC_STD_DELETE |
4668 : SEC_FILE_READ_DATA|
4669 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4670 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4671 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4672 : FILE_CREATE, /* create_disposition, */
4673 : 0, /* create_options, */
4674 : NULL, /* smb2_create_blobs *blobs */
4675 : &fid_persistent,
4676 : &fid_volatile,
4677 : NULL, /* struct smb_create_returns * */
4678 : talloc_tos(), /* mem_ctx. */
4679 : NULL, /* struct smb2_create_blobs */
4680 : NULL); /* struct symlink_reparse_struct */
4681 : /*
4682 : * Should fail with NT_STATUS_OBJECT_PATH_NOT_FOUND, as
4683 : * even though we set the FLAGS2_DFS_PATHNAMES the server
4684 : * knows this isn't a DFS share and so treats BAD\\BAD as
4685 : * part of the filename.
4686 : */
4687 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4688 0 : printf("%s:%d create of %s should fail "
4689 : "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4690 : __FILE__,
4691 : __LINE__,
4692 : dfs_filename,
4693 : nt_errstr(status));
4694 0 : goto err;
4695 : }
4696 : /*
4697 : * Prove we can still use non-DFS pathnames, even though
4698 : * we are setting the FLAGS2_DFS_PATHNAMES in the SMB2
4699 : * request.
4700 : */
4701 0 : status = smb2cli_create(cli->conn,
4702 0 : cli->timeout,
4703 0 : cli->smb2.session,
4704 0 : cli->smb2.tcon,
4705 : "file",
4706 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4707 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4708 : SEC_STD_SYNCHRONIZE|
4709 : SEC_STD_DELETE |
4710 : SEC_FILE_READ_DATA|
4711 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4712 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4713 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4714 : FILE_CREATE, /* create_disposition, */
4715 : 0, /* create_options, */
4716 : NULL, /* smb2_create_blobs *blobs */
4717 : &fid_persistent,
4718 : &fid_volatile,
4719 : NULL, /* struct smb_create_returns * */
4720 : talloc_tos(), /* mem_ctx. */
4721 : NULL, /* struct smb2_create_blobs * */
4722 : NULL); /* struct symlink_reparse_struct */
4723 0 : if (!NT_STATUS_IS_OK(status)) {
4724 0 : printf("%s:%d smb2cli_create on %s returned %s\n",
4725 : __FILE__,
4726 : __LINE__,
4727 : "file",
4728 : nt_errstr(status));
4729 0 : return false;
4730 : }
4731 :
4732 0 : retval = true;
4733 :
4734 0 : err:
4735 :
4736 0 : (void)smb2_dfs_delete(cli, dfs_filename);
4737 0 : (void)smb2_dfs_delete(cli, "file");
4738 0 : return retval;
4739 : }
4740 :
4741 : /*
4742 : * Add a test that sends a non-DFS path and does not set the
4743 : * SMB2 flag FLAGS2_DFS_PATHNAMES to a DFS
4744 : * share. Windows passes this (it just treats the
4745 : * pathnames as non-DFS).
4746 : */
4747 :
4748 0 : bool run_smb2_dfs_share_non_dfs_path(int dummy)
4749 : {
4750 0 : struct cli_state *cli = NULL;
4751 : NTSTATUS status;
4752 0 : bool dfs_supported = false;
4753 0 : uint64_t fid_persistent = 0;
4754 0 : uint64_t fid_volatile = 0;
4755 0 : bool retval = false;
4756 0 : char *dfs_filename = NULL;
4757 0 : uint64_t root_ino = (uint64_t)-1;
4758 0 : bool ino_matched = false;
4759 :
4760 0 : printf("Starting SMB2-DFS-SHARE-NON-DFS-PATH\n");
4761 :
4762 0 : if (!torture_init_connection(&cli)) {
4763 0 : return false;
4764 : }
4765 :
4766 0 : status = smbXcli_negprot(cli->conn,
4767 0 : cli->timeout,
4768 : PROTOCOL_SMB2_02,
4769 : PROTOCOL_SMB3_11);
4770 0 : if (!NT_STATUS_IS_OK(status)) {
4771 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4772 0 : return false;
4773 : }
4774 :
4775 0 : status = cli_session_setup_creds(cli, torture_creds);
4776 0 : if (!NT_STATUS_IS_OK(status)) {
4777 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
4778 0 : return false;
4779 : }
4780 :
4781 0 : status = cli_tree_connect(cli, share, "?????", NULL);
4782 0 : if (!NT_STATUS_IS_OK(status)) {
4783 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
4784 0 : return false;
4785 : }
4786 :
4787 0 : dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4788 0 : if (!dfs_supported) {
4789 0 : printf("Server %s does not support DFS\n",
4790 0 : smbXcli_conn_remote_name(cli->conn));
4791 0 : return false;
4792 : }
4793 : /* Ensure this is a DFS share. */
4794 0 : dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4795 0 : if (!dfs_supported) {
4796 0 : printf("Share %s is not a DFS share.\n",
4797 0 : cli->share);
4798 0 : return false;
4799 : }
4800 : /* Come up with a "valid" SMB2 DFS name. */
4801 0 : dfs_filename = talloc_asprintf(talloc_tos(),
4802 : "%s\\%s\\file",
4803 0 : smbXcli_conn_remote_name(cli->conn),
4804 0 : cli->share);
4805 0 : if (dfs_filename == NULL) {
4806 0 : printf("Out of memory\n");
4807 0 : return false;
4808 : }
4809 :
4810 : /* Get the root of the share ino. */
4811 0 : status = get_smb2_inode(cli,
4812 : "SERVER\\SHARE",
4813 : &root_ino);
4814 0 : if (!NT_STATUS_IS_OK(status)) {
4815 0 : printf("%s:%d get_smb2_inode on %s returned %s\n",
4816 : __FILE__,
4817 : __LINE__,
4818 : "SERVER\\SHARE",
4819 : nt_errstr(status));
4820 0 : goto err;
4821 : }
4822 :
4823 : /* Create a dfs_filename. */
4824 0 : status = smb2cli_create(cli->conn,
4825 0 : cli->timeout,
4826 0 : cli->smb2.session,
4827 0 : cli->smb2.tcon,
4828 : dfs_filename,
4829 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4830 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4831 : SEC_STD_SYNCHRONIZE|
4832 : SEC_STD_DELETE |
4833 : SEC_FILE_READ_DATA|
4834 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4835 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4836 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4837 : FILE_CREATE, /* create_disposition, */
4838 : 0, /* create_options, */
4839 : NULL, /* smb2_create_blobs *blobs */
4840 : &fid_persistent,
4841 : &fid_volatile,
4842 : NULL, /* struct smb_create_returns * */
4843 : talloc_tos(), /* mem_ctx. */
4844 : NULL, /* struct smb2_create_blobs * */
4845 : NULL); /* psymlink */
4846 0 : if (!NT_STATUS_IS_OK(status)) {
4847 0 : printf("%s:%d smb2cli_create on %s returned %s\n",
4848 : __FILE__,
4849 : __LINE__,
4850 : dfs_filename,
4851 : nt_errstr(status));
4852 0 : goto err;
4853 : }
4854 :
4855 : /* Close the handle we just opened. */
4856 0 : smb2cli_close(cli->conn,
4857 0 : cli->timeout,
4858 0 : cli->smb2.session,
4859 0 : cli->smb2.tcon,
4860 : 0, /* flags */
4861 : fid_persistent,
4862 : fid_volatile);
4863 :
4864 0 : fid_persistent = 0;
4865 0 : fid_volatile = 0;
4866 :
4867 : /*
4868 : * Force the share to be non-DFS, as far as the client
4869 : * is concerned.
4870 : */
4871 0 : smb2cli_tcon_set_values(cli->smb2.tcon,
4872 0 : cli->smb2.session,
4873 0 : smb2cli_tcon_current_id(cli->smb2.tcon),
4874 : 0,
4875 0 : smb2cli_tcon_flags(cli->smb2.tcon),
4876 0 : smb2cli_tcon_capabilities(cli->smb2.tcon) &
4877 : ~SMB2_SHARE_CAP_DFS,
4878 : 0);
4879 :
4880 : /*
4881 : * Prove we can still use non-DFS pathnames on a DFS
4882 : * share so long as we don't set the FLAGS2_DFS_PATHNAMES
4883 : * in the SMB2 request.
4884 : */
4885 0 : status = smb2cli_create(cli->conn,
4886 0 : cli->timeout,
4887 0 : cli->smb2.session,
4888 0 : cli->smb2.tcon,
4889 : "file",
4890 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4891 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4892 : SEC_STD_SYNCHRONIZE|
4893 : SEC_STD_DELETE |
4894 : SEC_FILE_READ_DATA|
4895 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4896 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4897 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4898 : FILE_OPEN, /* create_disposition, */
4899 : 0, /* create_options, */
4900 : NULL, /* smb2_create_blobs *blobs */
4901 : &fid_persistent,
4902 : &fid_volatile,
4903 : NULL, /* struct smb_create_returns * */
4904 : talloc_tos(), /* mem_ctx. */
4905 : NULL, /* struct smb2_create_blobs * */
4906 : NULL); /* psymlink */
4907 0 : if (!NT_STATUS_IS_OK(status)) {
4908 0 : printf("%s:%d smb2cli_create on %s returned %s\n",
4909 : __FILE__,
4910 : __LINE__,
4911 : "file",
4912 : nt_errstr(status));
4913 0 : goto err;
4914 : }
4915 :
4916 : /*
4917 : * Show that now we're using non-DFS pathnames
4918 : * on a DFS share, "" opens the root of the share.
4919 : */
4920 0 : ino_matched = smb2_inode_matches(cli,
4921 : "SERVER\\SHARE",
4922 : root_ino,
4923 : "");
4924 0 : if (!ino_matched) {
4925 0 : printf("%s:%d Failed to match ino number for %s\n",
4926 : __FILE__,
4927 : __LINE__,
4928 : "");
4929 0 : goto err;
4930 : }
4931 :
4932 0 : retval = true;
4933 :
4934 0 : err:
4935 :
4936 0 : if (fid_volatile != 0) {
4937 0 : smb2cli_close(cli->conn,
4938 0 : cli->timeout,
4939 0 : cli->smb2.session,
4940 0 : cli->smb2.tcon,
4941 : 0, /* flags */
4942 : fid_persistent,
4943 : fid_volatile);
4944 : }
4945 0 : (void)smb2_dfs_delete(cli, "file");
4946 0 : (void)smb2_dfs_delete(cli, dfs_filename);
4947 0 : return retval;
4948 : }
4949 :
4950 : /*
4951 : * "Raw" test of an SMB2 filename with one or more leading
4952 : * backslash characters to a DFS share.
4953 : *
4954 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
4955 : *
4956 : * Once the server passes SMB2-DFS-PATHS we can
4957 : * fold this test into that one.
4958 : *
4959 : * Passes cleanly against Windows.
4960 : */
4961 :
4962 0 : bool run_smb2_dfs_filename_leading_backslash(int dummy)
4963 : {
4964 0 : struct cli_state *cli = NULL;
4965 : NTSTATUS status;
4966 0 : bool dfs_supported = false;
4967 0 : char *dfs_filename_slash = NULL;
4968 0 : char *dfs_filename_slash_multi = NULL;
4969 0 : uint64_t file_ino = 0;
4970 0 : bool ino_matched = false;
4971 0 : uint64_t fid_persistent = 0;
4972 0 : uint64_t fid_volatile = 0;
4973 0 : bool retval = false;
4974 :
4975 0 : printf("Starting SMB2-DFS-FILENAME-LEADING-BACKSLASH\n");
4976 :
4977 0 : if (!torture_init_connection(&cli)) {
4978 0 : return false;
4979 : }
4980 :
4981 0 : status = smbXcli_negprot(cli->conn,
4982 0 : cli->timeout,
4983 : PROTOCOL_SMB2_02,
4984 : PROTOCOL_SMB3_11);
4985 0 : if (!NT_STATUS_IS_OK(status)) {
4986 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4987 0 : return false;
4988 : }
4989 :
4990 0 : status = cli_session_setup_creds(cli, torture_creds);
4991 0 : if (!NT_STATUS_IS_OK(status)) {
4992 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
4993 0 : return false;
4994 : }
4995 :
4996 0 : status = cli_tree_connect(cli, share, "?????", NULL);
4997 0 : if (!NT_STATUS_IS_OK(status)) {
4998 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
4999 0 : return false;
5000 : }
5001 :
5002 : /* Ensure this is a DFS share. */
5003 0 : dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
5004 0 : if (!dfs_supported) {
5005 0 : printf("Server %s does not support DFS\n",
5006 0 : smbXcli_conn_remote_name(cli->conn));
5007 0 : return false;
5008 : }
5009 0 : dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
5010 0 : if (!dfs_supported) {
5011 0 : printf("Share %s does not support DFS\n",
5012 0 : cli->share);
5013 0 : return false;
5014 : }
5015 :
5016 : /*
5017 : * Create the filename with one leading backslash.
5018 : */
5019 0 : dfs_filename_slash = talloc_asprintf(talloc_tos(),
5020 : "\\%s\\%s\\file",
5021 0 : smbXcli_conn_remote_name(cli->conn),
5022 0 : cli->share);
5023 0 : if (dfs_filename_slash == NULL) {
5024 0 : printf("Out of memory\n");
5025 0 : return false;
5026 : }
5027 :
5028 : /*
5029 : * Create the filename with many leading backslashes.
5030 : */
5031 0 : dfs_filename_slash_multi = talloc_asprintf(talloc_tos(),
5032 : "\\\\\\\\%s\\%s\\file",
5033 0 : smbXcli_conn_remote_name(cli->conn),
5034 0 : cli->share);
5035 0 : if (dfs_filename_slash_multi == NULL) {
5036 0 : printf("Out of memory\n");
5037 0 : return false;
5038 : }
5039 :
5040 : /*
5041 : * Trying to open "\\server\\share\\file" should get
5042 : * NT_STATUS_OBJECT_NAME_NOT_FOUND.
5043 : */
5044 0 : status = get_smb2_inode(cli,
5045 : dfs_filename_slash,
5046 : &file_ino);
5047 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5048 0 : printf("%s:%d Open of %s should get "
5049 : "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
5050 : __FILE__,
5051 : __LINE__,
5052 : dfs_filename_slash,
5053 : nt_errstr(status));
5054 0 : return false;
5055 : }
5056 :
5057 : /* Now create a file called "\\server\\share\\file". */
5058 0 : status = smb2cli_create(cli->conn,
5059 0 : cli->timeout,
5060 0 : cli->smb2.session,
5061 0 : cli->smb2.tcon,
5062 : dfs_filename_slash,
5063 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
5064 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
5065 : SEC_STD_SYNCHRONIZE|
5066 : SEC_STD_DELETE |
5067 : SEC_FILE_READ_DATA|
5068 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
5069 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
5070 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
5071 : FILE_CREATE, /* create_disposition, */
5072 : 0, /* create_options, */
5073 : NULL, /* smb2_create_blobs *blobs */
5074 : &fid_persistent,
5075 : &fid_volatile,
5076 : NULL, /* struct smb_create_returns * */
5077 : talloc_tos(), /* mem_ctx. */
5078 : NULL, /* struct smb2_create_blobs * */
5079 : NULL); /* struct symlink_reparse_struct */
5080 0 : if (!NT_STATUS_IS_OK(status)) {
5081 0 : printf("%s:%d smb2cli_create on %s returned %s\n",
5082 : __FILE__,
5083 : __LINE__,
5084 : dfs_filename_slash,
5085 : nt_errstr(status));
5086 0 : return false;
5087 : }
5088 :
5089 : /*
5090 : * Trying to open "\\server\\share\\file" should now get
5091 : * a valid inode.
5092 : */
5093 0 : status = get_smb2_inode(cli,
5094 : dfs_filename_slash,
5095 : &file_ino);
5096 0 : if (!NT_STATUS_IS_OK(status)) {
5097 0 : printf("%s:%d Open of %s should succeed "
5098 : "got %s\n",
5099 : __FILE__,
5100 : __LINE__,
5101 : dfs_filename_slash,
5102 : nt_errstr(status));
5103 0 : goto err;
5104 : }
5105 :
5106 : /*
5107 : * Trying to open "\\\\\\server\\share\\file" should now get
5108 : * a valid inode that matches. MacOSX-style of DFS name test.
5109 : */
5110 0 : ino_matched = smb2_inode_matches(cli,
5111 : dfs_filename_slash,
5112 : file_ino,
5113 : dfs_filename_slash_multi);
5114 0 : if (!ino_matched) {
5115 0 : printf("%s:%d Failed to match ino number for %s\n",
5116 : __FILE__,
5117 : __LINE__,
5118 : dfs_filename_slash_multi);
5119 0 : goto err;
5120 : }
5121 :
5122 0 : retval = true;
5123 :
5124 0 : err:
5125 :
5126 0 : if (fid_persistent != 0 || fid_volatile != 0) {
5127 0 : smb2cli_close(cli->conn,
5128 0 : cli->timeout,
5129 0 : cli->smb2.session,
5130 0 : cli->smb2.tcon,
5131 : 0, /* flags */
5132 : fid_persistent,
5133 : fid_volatile);
5134 : }
5135 : /* Delete anything we made. */
5136 0 : (void)smb2_dfs_delete(cli, dfs_filename_slash);
5137 0 : return retval;
5138 : }
5139 :
5140 : /*
5141 : * Ensure a named pipe async read followed by a disconnect
5142 : * doesn't crash the server (server crash checked for in
5143 : * containing test script:
5144 : * source3/script/tests/test_smbtorture_nocrash_s3.sh)
5145 : * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15423
5146 : */
5147 :
5148 0 : bool run_smb2_pipe_read_async_disconnect(int dummy)
5149 : {
5150 0 : struct cli_state *cli = NULL;
5151 : NTSTATUS status;
5152 0 : uint64_t fid_persistent = 0;
5153 0 : uint64_t fid_volatile = 0;
5154 : struct tevent_context *ev;
5155 : struct tevent_req *req;
5156 0 : bool retval = false;
5157 :
5158 0 : printf("Starting SMB2-PIPE-READ-ASYNC-DISCONNECT\n");
5159 :
5160 0 : if (!torture_init_connection(&cli)) {
5161 0 : return false;
5162 : }
5163 :
5164 0 : status = smbXcli_negprot(cli->conn,
5165 0 : cli->timeout,
5166 : PROTOCOL_SMB2_02,
5167 : PROTOCOL_SMB3_11);
5168 0 : if (!NT_STATUS_IS_OK(status)) {
5169 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
5170 0 : return false;
5171 : }
5172 :
5173 0 : status = cli_session_setup_creds(cli, torture_creds);
5174 0 : if (!NT_STATUS_IS_OK(status)) {
5175 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
5176 0 : return false;
5177 : }
5178 :
5179 0 : status = cli_tree_connect_creds(cli, "IPC$", "IPC", torture_creds);
5180 0 : if (!NT_STATUS_IS_OK(status)) {
5181 0 : printf("cli_tree_connect to IPC$ returned %s\n",
5182 : nt_errstr(status));
5183 0 : return false;
5184 : }
5185 :
5186 : /* Open the SAMR pipe. */
5187 0 : status = smb2cli_create(cli->conn,
5188 0 : cli->timeout,
5189 0 : cli->smb2.session,
5190 0 : cli->smb2.tcon,
5191 : "SAMR",
5192 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
5193 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
5194 : SEC_STD_SYNCHRONIZE|
5195 : SEC_FILE_READ_DATA|
5196 : SEC_FILE_WRITE_DATA, /* desired_access, */
5197 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
5198 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
5199 : FILE_OPEN, /* create_disposition, */
5200 : 0, /* create_options, */
5201 : NULL, /* smb2_create_blobs *blobs */
5202 : &fid_persistent,
5203 : &fid_volatile,
5204 : NULL, /* struct smb_create_returns * */
5205 : talloc_tos(), /* mem_ctx. */
5206 : NULL, /* struct smb2_create_blobs * */
5207 : NULL); /* psymlink */
5208 0 : if (!NT_STATUS_IS_OK(status)) {
5209 0 : printf("%s:%d smb2cli_create on SAMR returned %s\n",
5210 : __FILE__,
5211 : __LINE__,
5212 : nt_errstr(status));
5213 0 : goto err;
5214 : }
5215 :
5216 0 : ev = samba_tevent_context_init(talloc_tos());
5217 0 : if (ev == NULL) {
5218 0 : goto err;
5219 : }
5220 :
5221 : /* Start an async read. */
5222 0 : req = smb2cli_read_send(talloc_tos(),
5223 : ev,
5224 0 : cli->conn,
5225 0 : cli->timeout,
5226 0 : cli->smb2.session,
5227 0 : cli->smb2.tcon,
5228 : 16*1024,
5229 : 0, /* offset */
5230 : fid_persistent,
5231 : fid_volatile,
5232 : 0, /* minimum_count */
5233 : 0); /* remaining_bytes */
5234 0 : if (req == NULL) {
5235 0 : goto err;
5236 : }
5237 :
5238 : /* Force disconnect. */
5239 0 : smbXcli_conn_disconnect(cli->conn, NT_STATUS_LOCAL_DISCONNECT);
5240 0 : fid_volatile = 0;
5241 0 : retval = true;
5242 :
5243 0 : err:
5244 :
5245 0 : if (fid_volatile != 0) {
5246 0 : smb2cli_close(cli->conn,
5247 0 : cli->timeout,
5248 0 : cli->smb2.session,
5249 0 : cli->smb2.tcon,
5250 : 0, /* flags */
5251 : fid_persistent,
5252 : fid_volatile);
5253 : }
5254 0 : return retval;
5255 : }
5256 :
5257 0 : bool run_smb2_invalid_pipename(int dummy)
5258 : {
5259 0 : struct cli_state *cli = NULL;
5260 : NTSTATUS status;
5261 0 : uint64_t fid_persistent = 0;
5262 0 : uint64_t fid_volatile = 0;
5263 0 : const char *unknown_pipe = "badpipe";
5264 0 : const char *invalid_pipe = "../../../../../../../../../badpipe";
5265 :
5266 0 : printf("Starting SMB2-INVALID-PIPENAME\n");
5267 :
5268 0 : if (!torture_init_connection(&cli)) {
5269 0 : return false;
5270 : }
5271 :
5272 0 : status = smbXcli_negprot(cli->conn,
5273 0 : cli->timeout,
5274 : PROTOCOL_SMB2_02,
5275 : PROTOCOL_SMB3_11);
5276 0 : if (!NT_STATUS_IS_OK(status)) {
5277 0 : printf("smbXcli_negprot returned %s\n", nt_errstr(status));
5278 0 : return false;
5279 : }
5280 :
5281 0 : status = cli_session_setup_creds(cli, torture_creds);
5282 0 : if (!NT_STATUS_IS_OK(status)) {
5283 0 : printf("cli_session_setup returned %s\n", nt_errstr(status));
5284 0 : return false;
5285 : }
5286 :
5287 0 : status = cli_tree_connect(cli, "IPC$", "?????", NULL);
5288 0 : if (!NT_STATUS_IS_OK(status)) {
5289 0 : printf("cli_tree_connect returned %s\n", nt_errstr(status));
5290 0 : return false;
5291 : }
5292 :
5293 : /* Try and connect to an unknown pipename. */
5294 0 : status = smb2cli_create(cli->conn,
5295 0 : cli->timeout,
5296 0 : cli->smb2.session,
5297 0 : cli->smb2.tcon,
5298 : unknown_pipe,
5299 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
5300 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
5301 : SEC_STD_SYNCHRONIZE|
5302 : SEC_FILE_READ_DATA|
5303 : SEC_FILE_WRITE_DATA|
5304 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
5305 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
5306 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
5307 : FILE_CREATE, /* create_disposition, */
5308 : 0, /* create_options, */
5309 : NULL, /* smb2_create_blobs *blobs */
5310 : &fid_persistent,
5311 : &fid_volatile,
5312 : NULL, /* struct smb_create_returns * */
5313 : talloc_tos(), /* mem_ctx. */
5314 : NULL, /* struct smb2_create_blobs * */
5315 : NULL); /* struct symlink_reparse_struct */
5316 : /* We should get NT_STATUS_OBJECT_NAME_NOT_FOUND */
5317 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5318 0 : printf("%s:%d smb2cli_create on name %s returned %s\n",
5319 : __FILE__,
5320 : __LINE__,
5321 : unknown_pipe,
5322 : nt_errstr(status));
5323 0 : return false;
5324 : }
5325 :
5326 : /* Try and connect to an invalid pipename containing unix separators. */
5327 0 : status = smb2cli_create(cli->conn,
5328 0 : cli->timeout,
5329 0 : cli->smb2.session,
5330 0 : cli->smb2.tcon,
5331 : invalid_pipe,
5332 : SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
5333 : SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
5334 : SEC_STD_SYNCHRONIZE|
5335 : SEC_FILE_READ_DATA|
5336 : SEC_FILE_WRITE_DATA|
5337 : SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
5338 : FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
5339 : FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
5340 : FILE_CREATE, /* create_disposition, */
5341 : 0, /* create_options, */
5342 : NULL, /* smb2_create_blobs *blobs */
5343 : &fid_persistent,
5344 : &fid_volatile,
5345 : NULL, /* struct smb_create_returns * */
5346 : talloc_tos(), /* mem_ctx. */
5347 : NULL, /* struct smb2_create_blobs * */
5348 : NULL); /* struct symlink_reparse_struct */
5349 : /*
5350 : * We should still get NT_STATUS_OBJECT_NAME_NOT_FOUND
5351 : * (tested against Windows 2022).
5352 : */
5353 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5354 0 : printf("%s:%d smb2cli_create on name %s returned %s\n",
5355 : __FILE__,
5356 : __LINE__,
5357 : invalid_pipe,
5358 : nt_errstr(status));
5359 0 : return false;
5360 : }
5361 0 : return true;
5362 : }
|