2 Unix SMB/CIFS implementation.
3 Initial test for the smb2 client lib
4 Copyright (C) Volker Lendecke 2011
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.
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.
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/>.
21 #include "torture/proto.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"
34 extern fstring host, workgroup, share, password, username, myname;
35 extern struct cli_credentials *torture_creds;
37 bool run_smb2_basic(int dummy)
39 struct cli_state *cli;
41 uint64_t fid_persistent, fid_volatile;
42 const char *hello = "Hello, world\n";
46 uint32_t dir_data_length;
47 uint32_t saved_tid = 0;
48 struct smbXcli_tcon *saved_tcon = NULL;
49 char *saved_share = NULL;
50 uint64_t saved_uid = 0;
52 printf("Starting SMB2-BASIC\n");
54 if (!torture_init_connection(&cli)) {
58 status = smbXcli_negprot(cli->conn, cli->timeout,
59 PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
60 if (!NT_STATUS_IS_OK(status)) {
61 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
65 status = cli_session_setup_creds(cli, torture_creds);
66 if (!NT_STATUS_IS_OK(status)) {
67 printf("cli_session_setup returned %s\n", nt_errstr(status));
71 status = cli_tree_connect(cli, share, "?????", NULL);
72 if (!NT_STATUS_IS_OK(status)) {
73 printf("cli_tree_connect returned %s\n", nt_errstr(status));
77 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
78 cli->smb2.tcon, "smb2-basic.txt",
79 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
80 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
81 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
82 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
83 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
84 FILE_CREATE, /* create_disposition, */
85 FILE_DELETE_ON_CLOSE, /* create_options, */
86 NULL, /* smb2_create_blobs *blobs */
90 if (!NT_STATUS_IS_OK(status)) {
91 printf("smb2cli_create returned %s\n", nt_errstr(status));
95 status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
96 cli->smb2.tcon, strlen(hello), 0, fid_persistent,
97 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
98 if (!NT_STATUS_IS_OK(status)) {
99 printf("smb2cli_write returned %s\n", nt_errstr(status));
103 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
104 cli->smb2.tcon, fid_persistent, fid_volatile);
105 if (!NT_STATUS_IS_OK(status)) {
106 printf("smb2cli_flush returned %s\n", nt_errstr(status));
110 status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
111 cli->smb2.tcon, 0x10000, 0, fid_persistent,
113 talloc_tos(), &result, &nread);
114 if (!NT_STATUS_IS_OK(status)) {
115 printf("smb2cli_read returned %s\n", nt_errstr(status));
119 if (nread != strlen(hello)) {
120 printf("smb2cli_read returned %d bytes, expected %d\n",
121 (int)nread, (int)strlen(hello));
125 if (memcmp(hello, result, nread) != 0) {
126 printf("smb2cli_read returned '%s', expected '%s'\n",
131 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
132 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
133 if (!NT_STATUS_IS_OK(status)) {
134 printf("smb2cli_close returned %s\n", nt_errstr(status));
138 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
140 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
141 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
144 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
145 0, /* file_attributes, */
146 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
147 FILE_OPEN, /* create_disposition, */
148 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
149 NULL, /* smb2_create_blobs *blobs */
153 if (!NT_STATUS_IS_OK(status)) {
154 printf("smb2cli_create returned %s\n", nt_errstr(status));
158 status = smb2cli_query_directory(
159 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
160 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
161 talloc_tos(), &dir_data, &dir_data_length);
163 if (!NT_STATUS_IS_OK(status)) {
164 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
168 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
169 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
170 if (!NT_STATUS_IS_OK(status)) {
171 printf("smb2cli_close returned %s\n", nt_errstr(status));
175 saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
176 cli_state_save_tcon_share(cli, &saved_tcon, &saved_share);
177 cli->smb2.tcon = smbXcli_tcon_create(cli);
178 smb2cli_tcon_set_values(cli->smb2.tcon,
183 0, /* capabilities */
184 0 /* maximal_access */);
185 status = smb2cli_tdis(cli->conn,
189 cli_state_restore_tcon_share(cli, saved_tcon, saved_share);
190 if (!NT_STATUS_IS_OK(status)) {
191 printf("smb2cli_tdis returned %s\n", nt_errstr(status));
195 status = smb2cli_tdis(cli->conn,
199 if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
200 printf("2nd smb2cli_tdis returned %s\n", nt_errstr(status));
204 saved_uid = smb2cli_session_current_id(cli->smb2.session);
205 status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
206 if (!NT_STATUS_IS_OK(status)) {
207 printf("smb2cli_logoff returned %s\n", nt_errstr(status));
211 cli->smb2.session = smbXcli_session_create(cli, cli->conn);
212 if (cli->smb2.session == NULL) {
213 printf("smbXcli_session_create() returned NULL\n");
217 smb2cli_session_set_id_and_flags(cli->smb2.session, saved_uid, 0);
219 status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
220 if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
221 printf("2nd smb2cli_logoff returned %s\n", nt_errstr(status));
228 bool run_smb2_negprot(int dummy)
230 struct cli_state *cli;
232 enum protocol_types protocol;
233 const char *name = NULL;
235 printf("Starting SMB2-NEGPROT\n");
237 if (!torture_init_connection(&cli)) {
241 status = smbXcli_negprot(cli->conn, cli->timeout,
242 PROTOCOL_CORE, PROTOCOL_LATEST);
243 if (!NT_STATUS_IS_OK(status)) {
244 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
248 protocol = smbXcli_conn_protocol(cli->conn);
249 name = smb_protocol_types_string(protocol);
251 if (protocol >= PROTOCOL_SMB2_02) {
252 printf("Server supports %s\n", name);
254 printf("Server DOES NOT support SMB2, only %s\n", name);
258 status = smbXcli_negprot(cli->conn, cli->timeout,
260 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
261 !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
262 !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
263 printf("2nd smbXcli_negprot should disconnect - returned %s\n",
268 if (smbXcli_conn_is_connected(cli->conn)) {
269 printf("2nd smbXcli_negprot should disconnect "
270 "- still connected\n");
277 bool run_smb2_anonymous(int dummy)
279 struct cli_state *cli = NULL;
281 struct cli_credentials *anon_creds = NULL;
284 printf("Starting SMB2-ANONYMOUS\n");
286 if (!torture_init_connection(&cli)) {
290 status = smbXcli_negprot(cli->conn, cli->timeout,
291 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
292 if (!NT_STATUS_IS_OK(status)) {
293 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
297 anon_creds = cli_credentials_init_anon(talloc_tos());
298 if (anon_creds == NULL) {
299 printf("cli_credentials_init_anon failed\n");
303 status = cli_session_setup_creds(cli, anon_creds);
304 if (!NT_STATUS_IS_OK(status)) {
305 printf("cli_session_setup returned %s\n", nt_errstr(status));
309 guest = smbXcli_session_is_guest(cli->smb2.session);
311 printf("anonymous session should not have guest authentication\n");
318 bool run_smb2_session_reconnect(int dummy)
320 struct cli_state *cli1;
321 struct cli_state *cli2;
324 uint64_t fid_persistent, fid_volatile;
325 struct tevent_context *ev;
326 struct tevent_req *subreq;
327 DATA_BLOB in_blob = data_blob_null;
329 DATA_BLOB session_key;
330 struct auth_generic_state *auth_generic_state;
331 struct iovec *recv_iov;
332 const char *hello = "Hello, world\n";
336 printf("Starting SMB2-SESSION-RECONNECT\n");
338 if (!torture_init_connection(&cli1)) {
342 status = smbXcli_negprot(cli1->conn, cli1->timeout,
343 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
344 if (!NT_STATUS_IS_OK(status)) {
345 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
349 status = cli_session_setup_creds(cli1, torture_creds);
350 if (!NT_STATUS_IS_OK(status)) {
351 printf("cli_session_setup returned %s\n", nt_errstr(status));
355 status = cli_tree_connect(cli1, share, "?????", NULL);
356 if (!NT_STATUS_IS_OK(status)) {
357 printf("cli_tree_connect returned %s\n", nt_errstr(status));
361 status = smb2cli_create(cli1->conn, cli1->timeout, cli1->smb2.session,
362 cli1->smb2.tcon, "session-reconnect.txt",
363 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
364 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
365 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
366 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
367 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
368 FILE_CREATE, /* create_disposition, */
369 FILE_DELETE_ON_CLOSE, /* create_options, */
370 NULL, /* smb2_create_blobs *blobs */
374 if (!NT_STATUS_IS_OK(status)) {
375 printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
379 status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
380 cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
381 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
382 if (!NT_STATUS_IS_OK(status)) {
383 printf("smb2cli_write returned %s\n", nt_errstr(status));
387 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
388 cli1->smb2.tcon, fid_persistent, fid_volatile);
389 if (!NT_STATUS_IS_OK(status)) {
390 printf("smb2cli_flush returned %s\n", nt_errstr(status));
394 status = smb2cli_read(cli1->conn, cli1->timeout, cli1->smb2.session,
395 cli1->smb2.tcon, 0x10000, 0, fid_persistent,
397 talloc_tos(), &result, &nread);
398 if (!NT_STATUS_IS_OK(status)) {
399 printf("smb2cli_read returned %s\n", nt_errstr(status));
403 if (nread != strlen(hello)) {
404 printf("smb2cli_read returned %d bytes, expected %d\n",
405 (int)nread, (int)strlen(hello));
409 if (memcmp(hello, result, nread) != 0) {
410 printf("smb2cli_read returned '%s', expected '%s'\n",
415 /* prepare second session */
417 if (!torture_init_connection(&cli2)) {
421 status = smbXcli_negprot(cli2->conn, cli2->timeout,
422 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
423 if (!NT_STATUS_IS_OK(status)) {
424 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
428 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
429 if (!NT_STATUS_IS_OK(status)) {
430 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
434 gensec_want_feature(auth_generic_state->gensec_security,
435 GENSEC_FEATURE_SESSION_KEY);
437 status = auth_generic_set_creds(auth_generic_state, torture_creds);
438 if (!NT_STATUS_IS_OK(status)) {
439 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
443 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
444 if (!NT_STATUS_IS_OK(status)) {
445 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
449 ev = samba_tevent_context_init(talloc_tos());
451 printf("samba_tevent_context_init() returned NULL\n");
455 status = gensec_update(auth_generic_state->gensec_security,
456 talloc_tos(), data_blob_null, &in_blob);
457 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
458 printf("gensec_update returned %s\n", nt_errstr(status));
462 cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
464 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
469 SMB2_CAP_DFS, /* in_capabilities */
471 /* in_previous_session_id: */
472 smb2cli_session_current_id(cli1->smb2.session),
473 &in_blob); /* in_security_buffer */
474 if (subreq == NULL) {
475 printf("smb2cli_session_setup_send() returned NULL\n");
479 ok = tevent_req_poll(subreq, ev);
481 printf("tevent_req_poll() returned false\n");
485 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
487 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
488 printf("smb2cli_session_setup_recv returned %s\n",
493 status = gensec_update(auth_generic_state->gensec_security,
494 talloc_tos(), out_blob, &in_blob);
495 if (!NT_STATUS_IS_OK(status)) {
496 printf("auth_generic_update returned %s\n", nt_errstr(status));
500 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
505 SMB2_CAP_DFS, /* in_capabilities */
507 /* in_previous_session_id: */
508 smb2cli_session_current_id(cli1->smb2.session),
509 &in_blob); /* in_security_buffer */
510 if (subreq == NULL) {
511 printf("smb2cli_session_setup_send() returned NULL\n");
515 ok = tevent_req_poll(subreq, ev);
517 printf("tevent_req_poll() returned false\n");
521 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
522 &recv_iov, &out_blob);
523 if (!NT_STATUS_IS_OK(status)) {
524 printf("smb2cli_session_setup_recv returned %s\n",
529 status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
531 if (!NT_STATUS_IS_OK(status)) {
532 printf("gensec_session_key returned %s\n",
537 /* check file operation on the old client */
539 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
540 cli1->smb2.tcon, fid_persistent, fid_volatile);
541 if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
542 printf("smb2cli_flush returned %s\n", nt_errstr(status));
546 status = cli_tree_connect(cli1, share, "?????", NULL);
547 if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
548 printf("cli_tree_connect returned %s\n", nt_errstr(status));
553 * checking file operations without signing.
554 * on w2k8r2 at least, flush, read and write also work the same way,
555 * while create gives ACCESS_DENIED without signing
557 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
558 cli2->smb2.tcon, fid_persistent, fid_volatile);
559 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
560 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
562 printf("smb2cli_flush returned %s\n", nt_errstr(status));
566 status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
567 cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
568 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
569 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
570 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
572 printf("smb2cli_write returned %s\n", nt_errstr(status));
576 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
577 cli2->smb2.tcon, 0x10000, 0, fid_persistent,
579 talloc_tos(), &result, &nread);
580 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
581 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
583 printf("smb2cli_read returned %s\n", nt_errstr(status));
587 status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
588 cli2->smb2.tcon, "session-reconnect.txt",
589 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
590 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
591 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
592 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
593 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
594 FILE_CREATE, /* create_disposition, */
595 FILE_DELETE_ON_CLOSE, /* create_options, */
596 NULL, /* smb2_create_blobs *blobs */
600 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
601 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
602 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
606 /* now grab the session key and try with signing */
608 status = smb2cli_session_set_session_key(cli2->smb2.session,
611 if (!NT_STATUS_IS_OK(status)) {
612 printf("smb2cli_session_set_session_key %s\n", nt_errstr(status));
616 /* the tid seems to be irrelevant at this stage */
618 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
619 cli1->smb2.tcon, fid_persistent, fid_volatile);
620 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
621 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
623 printf("smb2cli_flush returned %s\n", nt_errstr(status));
627 status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
628 cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
629 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
630 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
631 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
633 printf("smb2cli_write returned %s\n", nt_errstr(status));
637 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
638 cli1->smb2.tcon, 0x10000, 0, fid_persistent,
640 talloc_tos(), &result, &nread);
641 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
642 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
644 printf("smb2cli_read returned %s\n", nt_errstr(status));
648 status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
649 cli1->smb2.tcon, "session-reconnect.txt",
650 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
651 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
652 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
653 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
654 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
655 FILE_CREATE, /* create_disposition, */
656 FILE_DELETE_ON_CLOSE, /* create_options, */
657 NULL, /* smb2_create_blobs *blobs */
661 if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) &&
662 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
664 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
668 /* now do a new tcon and test file calls again */
670 status = cli_tree_connect(cli2, share, "?????", NULL);
671 if (!NT_STATUS_IS_OK(status)) {
672 printf("cli_tree_connect returned %s\n", nt_errstr(status));
676 status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
677 cli2->smb2.tcon, "session-reconnect.txt",
678 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
679 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
680 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
681 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
682 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
683 FILE_CREATE, /* create_disposition, */
684 FILE_DELETE_ON_CLOSE, /* create_options, */
685 NULL, /* smb2_create_blobs *blobs */
689 if (!NT_STATUS_IS_OK(status)) {
690 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
694 status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
695 cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
696 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
697 if (!NT_STATUS_IS_OK(status)) {
698 printf("smb2cli_write returned %s\n", nt_errstr(status));
702 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
703 cli2->smb2.tcon, fid_persistent, fid_volatile);
704 if (!NT_STATUS_IS_OK(status)) {
705 printf("smb2cli_flush returned %s\n", nt_errstr(status));
709 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
710 cli2->smb2.tcon, 0x10000, 0, fid_persistent,
712 talloc_tos(), &result, &nread);
713 if (!NT_STATUS_IS_OK(status)) {
714 printf("smb2cli_read returned %s\n", nt_errstr(status));
718 if (nread != strlen(hello)) {
719 printf("smb2cli_read returned %d bytes, expected %d\n",
720 (int)nread, (int)strlen(hello));
724 if (memcmp(hello, result, nread) != 0) {
725 printf("smb2cli_read returned '%s', expected '%s'\n",
733 bool run_smb2_tcon_dependence(int dummy)
735 struct cli_state *cli;
737 uint64_t fid_persistent, fid_volatile;
738 const char *hello = "Hello, world\n";
741 struct smbXcli_tcon *tcon2;
744 printf("Starting SMB2-TCON-DEPENDENCE\n");
746 if (!torture_init_connection(&cli)) {
750 status = smbXcli_negprot(cli->conn, cli->timeout,
751 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
752 if (!NT_STATUS_IS_OK(status)) {
753 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
757 status = cli_session_setup_creds(cli, torture_creds);
758 if (!NT_STATUS_IS_OK(status)) {
759 printf("cli_session_setup returned %s\n", nt_errstr(status));
763 status = cli_tree_connect(cli, share, "?????", NULL);
764 if (!NT_STATUS_IS_OK(status)) {
765 printf("cli_tree_connect returned %s\n", nt_errstr(status));
769 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
770 cli->smb2.tcon, "tcon_depedence.txt",
771 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
772 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
773 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
774 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
775 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
776 FILE_CREATE, /* create_disposition, */
777 FILE_DELETE_ON_CLOSE, /* create_options, */
778 NULL, /* smb2_create_blobs *blobs */
782 if (!NT_STATUS_IS_OK(status)) {
783 printf("smb2cli_create on cli %s\n", nt_errstr(status));
787 status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
788 cli->smb2.tcon, strlen(hello), 0, fid_persistent,
789 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
790 if (!NT_STATUS_IS_OK(status)) {
791 printf("smb2cli_write returned %s\n", nt_errstr(status));
795 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
796 cli->smb2.tcon, fid_persistent, fid_volatile);
797 if (!NT_STATUS_IS_OK(status)) {
798 printf("smb2cli_flush returned %s\n", nt_errstr(status));
802 status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
803 cli->smb2.tcon, 0x10000, 0, fid_persistent,
805 talloc_tos(), &result, &nread);
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("smb2cli_read returned %s\n", nt_errstr(status));
811 if (nread != strlen(hello)) {
812 printf("smb2cli_read returned %d bytes, expected %d\n",
813 (int)nread, (int)strlen(hello));
817 if (memcmp(hello, result, nread) != 0) {
818 printf("smb2cli_read returned '%s', expected '%s'\n",
823 /* check behaviour with wrong tid... */
825 tcon2 = smbXcli_tcon_create(cli);
826 tcon2_id = smb2cli_tcon_current_id(cli->smb2.tcon);
828 smb2cli_tcon_set_values(tcon2,
833 0, /* capabilities */
834 0 /* maximal_access */);
836 status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
837 tcon2, 0x10000, 0, fid_persistent,
839 talloc_tos(), &result, &nread);
840 if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
841 printf("smb2cli_read returned %s\n", nt_errstr(status));
850 bool run_smb2_multi_channel(int dummy)
852 struct cli_state *cli1;
853 struct cli_state *cli2;
854 struct cli_state *cli3;
857 uint64_t fid_persistent, fid_volatile;
858 struct tevent_context *ev;
859 struct tevent_req *subreq;
860 DATA_BLOB in_blob = data_blob_null;
862 DATA_BLOB channel_session_key;
863 struct auth_generic_state *auth_generic_state;
864 struct iovec *recv_iov;
865 const char *hello = "Hello, world\n";
868 struct GUID saved_guid = cli_state_client_guid;
870 printf("Starting SMB2-MULTI-CHANNEL\n");
872 cli_state_client_guid = GUID_random();
874 if (!torture_init_connection(&cli1)) {
878 if (!torture_init_connection(&cli2)) {
882 if (!torture_init_connection(&cli3)) {
886 cli_state_client_guid = saved_guid;
888 status = smbXcli_negprot(cli1->conn, cli1->timeout,
889 PROTOCOL_SMB3_00, PROTOCOL_LATEST);
890 if (!NT_STATUS_IS_OK(status)) {
891 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
895 status = smbXcli_negprot(cli2->conn, cli2->timeout,
896 PROTOCOL_SMB3_00, PROTOCOL_LATEST);
897 if (!NT_STATUS_IS_OK(status)) {
898 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
902 status = smbXcli_negprot(cli3->conn, cli3->timeout,
903 PROTOCOL_SMB3_00, PROTOCOL_LATEST);
904 if (!NT_STATUS_IS_OK(status)) {
905 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
909 status = cli_session_setup_creds(cli1, torture_creds);
910 if (!NT_STATUS_IS_OK(status)) {
911 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
915 status = cli_tree_connect(cli1, share, "?????", NULL);
916 if (!NT_STATUS_IS_OK(status)) {
917 printf("cli_tree_connect returned %s\n", nt_errstr(status));
921 status = smb2cli_session_create_channel(cli2,
924 &cli2->smb2.session);
925 if (!NT_STATUS_IS_OK(status)) {
926 printf("smb2cli_session_create_channel returned %s\n",
931 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
932 if (!NT_STATUS_IS_OK(status)) {
933 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
937 gensec_want_feature(auth_generic_state->gensec_security,
938 GENSEC_FEATURE_SESSION_KEY);
940 status = auth_generic_set_creds(auth_generic_state, torture_creds);
941 if (!NT_STATUS_IS_OK(status)) {
942 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
946 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
947 if (!NT_STATUS_IS_OK(status)) {
948 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
952 ev = samba_tevent_context_init(talloc_tos());
954 printf("samba_tevent_context_init() returned NULL\n");
958 status = gensec_update(auth_generic_state->gensec_security,
959 talloc_tos(), data_blob_null, &in_blob);
960 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
961 printf("gensec_update returned %s\n", nt_errstr(status));
965 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
970 SMB2_CAP_DFS, /* in_capabilities */
972 0, /* in_previous_session_id */
973 &in_blob); /* in_security_buffer */
974 if (subreq == NULL) {
975 printf("smb2cli_session_setup_send() returned NULL\n");
979 ok = tevent_req_poll(subreq, ev);
981 printf("tevent_req_poll() returned false\n");
985 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
987 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
988 printf("smb2cli_session_setup_recv returned %s\n",
993 status = gensec_update(auth_generic_state->gensec_security,
994 talloc_tos(), out_blob, &in_blob);
995 if (!NT_STATUS_IS_OK(status)) {
996 printf("auth_generic_update returned %s\n", nt_errstr(status));
1000 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1004 0x01, /* in_flags */
1005 SMB2_CAP_DFS, /* in_capabilities */
1007 0, /* in_previous_session_id */
1008 &in_blob); /* in_security_buffer */
1009 if (subreq == NULL) {
1010 printf("smb2cli_session_setup_send() returned NULL\n");
1014 ok = tevent_req_poll(subreq, ev);
1016 printf("tevent_req_poll() returned false\n");
1020 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1021 &recv_iov, &out_blob);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("smb2cli_session_setup_recv returned %s\n",
1028 status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1029 &channel_session_key);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 printf("gensec_session_key returned %s\n",
1036 status = smb2cli_session_set_channel_key(cli2->smb2.session,
1037 channel_session_key,
1039 if (!NT_STATUS_IS_OK(status)) {
1040 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1044 status = smb2cli_session_create_channel(cli3,
1047 &cli3->smb2.session);
1048 if (!NT_STATUS_IS_OK(status)) {
1049 printf("smb2cli_session_create_channel returned %s\n",
1054 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1055 if (!NT_STATUS_IS_OK(status)) {
1056 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1060 gensec_want_feature(auth_generic_state->gensec_security,
1061 GENSEC_FEATURE_SESSION_KEY);
1063 status = auth_generic_set_creds(auth_generic_state, torture_creds);
1064 if (!NT_STATUS_IS_OK(status)) {
1065 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1069 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1070 if (!NT_STATUS_IS_OK(status)) {
1071 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1075 status = gensec_update(auth_generic_state->gensec_security,
1076 talloc_tos(), data_blob_null, &in_blob);
1077 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1078 printf("gensec_update returned %s\n", nt_errstr(status));
1082 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1086 0x01, /* in_flags */
1087 SMB2_CAP_DFS, /* in_capabilities */
1089 0, /* in_previous_session_id */
1090 &in_blob); /* in_security_buffer */
1091 if (subreq == NULL) {
1092 printf("smb2cli_session_setup_send() returned NULL\n");
1096 ok = tevent_req_poll(subreq, ev);
1098 printf("tevent_req_poll() returned false\n");
1102 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1104 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1105 printf("smb2cli_session_setup_recv returned %s\n",
1110 status = gensec_update(auth_generic_state->gensec_security,
1111 talloc_tos(), out_blob, &in_blob);
1112 if (!NT_STATUS_IS_OK(status)) {
1113 printf("auth_generic_update returned %s\n", nt_errstr(status));
1117 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1121 0x01, /* in_flags */
1122 SMB2_CAP_DFS, /* in_capabilities */
1124 0, /* in_previous_session_id */
1125 &in_blob); /* in_security_buffer */
1126 if (subreq == NULL) {
1127 printf("smb2cli_session_setup_send() returned NULL\n");
1131 ok = tevent_req_poll(subreq, ev);
1133 printf("tevent_req_poll() returned false\n");
1137 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1138 &recv_iov, &out_blob);
1139 if (!NT_STATUS_IS_OK(status)) {
1140 printf("smb2cli_session_setup_recv returned %s\n",
1145 status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1146 &channel_session_key);
1147 if (!NT_STATUS_IS_OK(status)) {
1148 printf("gensec_session_key returned %s\n",
1153 status = smb2cli_session_set_channel_key(cli3->smb2.session,
1154 channel_session_key,
1156 if (!NT_STATUS_IS_OK(status)) {
1157 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1161 status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
1162 cli1->smb2.tcon, "multi-channel.txt",
1163 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1164 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1165 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1166 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1167 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1168 FILE_CREATE, /* create_disposition, */
1169 FILE_DELETE_ON_CLOSE, /* create_options, */
1170 NULL, /* smb2_create_blobs *blobs */
1174 if (!NT_STATUS_IS_OK(status)) {
1175 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
1179 status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
1180 cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
1181 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 printf("smb2cli_write returned %s\n", nt_errstr(status));
1187 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1188 cli1->smb2.tcon, fid_persistent, fid_volatile);
1189 if (!NT_STATUS_IS_OK(status)) {
1190 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1194 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1195 cli1->smb2.tcon, fid_persistent, fid_volatile);
1196 if (!NT_STATUS_IS_OK(status)) {
1197 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1201 status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1202 cli1->smb2.tcon, fid_persistent, fid_volatile);
1203 if (!NT_STATUS_IS_OK(status)) {
1204 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1208 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
1209 cli1->smb2.tcon, 0x10000, 0, fid_persistent,
1211 talloc_tos(), &result, &nread);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 printf("smb2cli_read returned %s\n", nt_errstr(status));
1217 if (nread != strlen(hello)) {
1218 printf("smb2cli_read returned %d bytes, expected %d\n",
1219 (int)nread, (int)strlen(hello));
1223 if (memcmp(hello, result, nread) != 0) {
1224 printf("smb2cli_read returned '%s', expected '%s'\n",
1229 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1235 gensec_want_feature(auth_generic_state->gensec_security,
1236 GENSEC_FEATURE_SESSION_KEY);
1238 status = auth_generic_set_creds(auth_generic_state, torture_creds);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1244 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1245 if (!NT_STATUS_IS_OK(status)) {
1246 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1250 status = gensec_update(auth_generic_state->gensec_security,
1251 talloc_tos(), data_blob_null, &in_blob);
1252 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1253 printf("gensec_update returned %s\n", nt_errstr(status));
1257 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1262 SMB2_CAP_DFS, /* in_capabilities */
1264 0, /* in_previous_session_id */
1265 &in_blob); /* in_security_buffer */
1266 if (subreq == NULL) {
1267 printf("smb2cli_session_setup_send() returned NULL\n");
1271 ok = tevent_req_poll(subreq, ev);
1273 printf("tevent_req_poll() returned false\n");
1277 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1279 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1280 printf("smb2cli_session_setup_recv returned %s\n",
1285 status = gensec_update(auth_generic_state->gensec_security,
1286 talloc_tos(), out_blob, &in_blob);
1287 if (!NT_STATUS_IS_OK(status)) {
1288 printf("auth_generic_update returned %s\n", nt_errstr(status));
1292 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1293 cli1->smb2.tcon, fid_persistent, fid_volatile);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1299 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1300 cli1->smb2.tcon, fid_persistent, fid_volatile);
1301 if (!NT_STATUS_IS_OK(status)) {
1302 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1306 status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1307 cli1->smb2.tcon, fid_persistent, fid_volatile);
1308 if (!NT_STATUS_IS_OK(status)) {
1309 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1313 status = smb2cli_create(cli1->conn, cli1->timeout, cli1->smb2.session,
1314 cli1->smb2.tcon, "multi-channel-invalid.txt",
1315 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1316 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1317 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1318 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1319 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1320 FILE_CREATE, /* create_disposition, */
1321 FILE_DELETE_ON_CLOSE, /* create_options, */
1322 NULL, /* smb2_create_blobs *blobs */
1326 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1327 printf("smb2cli_create %s\n", nt_errstr(status));
1331 status = smb2cli_create(cli2->conn, cli2->timeout, cli2->smb2.session,
1332 cli1->smb2.tcon, "multi-channel-invalid.txt",
1333 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1334 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1335 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1336 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1337 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1338 FILE_CREATE, /* create_disposition, */
1339 FILE_DELETE_ON_CLOSE, /* create_options, */
1340 NULL, /* smb2_create_blobs *blobs */
1344 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1345 printf("smb2cli_create %s\n", nt_errstr(status));
1349 status = smb2cli_create(cli3->conn, cli3->timeout, cli3->smb2.session,
1350 cli1->smb2.tcon, "multi-channel-invalid.txt",
1351 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1352 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1353 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1354 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1355 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1356 FILE_CREATE, /* create_disposition, */
1357 FILE_DELETE_ON_CLOSE, /* create_options, */
1358 NULL, /* smb2_create_blobs *blobs */
1362 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1363 printf("smb2cli_create %s\n", nt_errstr(status));
1367 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1372 SMB2_CAP_DFS, /* in_capabilities */
1374 0, /* in_previous_session_id */
1375 &in_blob); /* in_security_buffer */
1376 if (subreq == NULL) {
1377 printf("smb2cli_session_setup_send() returned NULL\n");
1381 ok = tevent_req_poll(subreq, ev);
1383 printf("tevent_req_poll() returned false\n");
1387 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1388 &recv_iov, &out_blob);
1389 if (!NT_STATUS_IS_OK(status)) {
1390 printf("smb2cli_session_setup_recv returned %s\n",
1395 status = smb2cli_close(cli3->conn, cli3->timeout, cli3->smb2.session,
1396 cli1->smb2.tcon, 0, fid_persistent, fid_volatile);
1397 if (!NT_STATUS_IS_OK(status)) {
1398 printf("smb2cli_close returned %s\n", nt_errstr(status));
1402 status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1403 cli1->smb2.tcon, fid_persistent, fid_volatile);
1404 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1405 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1409 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1410 cli1->smb2.tcon, fid_persistent, fid_volatile);
1411 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1412 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1416 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1417 cli1->smb2.tcon, fid_persistent, fid_volatile);
1418 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1419 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1426 bool run_smb2_session_reauth(int dummy)
1428 struct cli_state *cli;
1431 uint64_t fid_persistent, fid_volatile;
1432 uint64_t dir_persistent, dir_volatile;
1434 uint32_t dir_data_length;
1435 struct tevent_context *ev;
1436 struct tevent_req *subreq;
1437 DATA_BLOB in_blob = data_blob_null;
1439 DATA_BLOB in_input_buffer;
1440 DATA_BLOB out_output_buffer;
1441 uint8_t in_file_info_class;
1442 struct auth_generic_state *auth_generic_state;
1443 struct iovec *recv_iov;
1445 struct smbXcli_tcon *saved_tcon;
1447 printf("Starting SMB2-SESSION_REAUTH\n");
1449 if (!torture_init_connection(&cli)) {
1454 * PROTOCOL_SMB2_22 has a bug in win8pre0
1455 * it behaves like PROTOCOL_SMB2_02
1456 * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
1457 * while it allows it on PROTOCOL_SMB2_10.
1459 status = smbXcli_negprot(cli->conn, cli->timeout,
1460 PROTOCOL_SMB2_10, PROTOCOL_SMB2_10);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1466 status = cli_session_setup_creds(cli, torture_creds);
1467 if (!NT_STATUS_IS_OK(status)) {
1468 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
1472 status = cli_tree_connect(cli, share, "?????", NULL);
1473 if (!NT_STATUS_IS_OK(status)) {
1474 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1478 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1479 cli->smb2.tcon, "session-reauth.txt",
1480 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1481 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1482 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1483 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1484 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1485 FILE_CREATE, /* create_disposition, */
1486 FILE_DELETE_ON_CLOSE, /* create_options, */
1487 NULL, /* smb2_create_blobs *blobs */
1491 if (!NT_STATUS_IS_OK(status)) {
1492 printf("smb2cli_create %s\n", nt_errstr(status));
1496 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1498 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1499 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1500 SEC_STD_SYNCHRONIZE|
1502 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1503 0, /* file_attributes, */
1504 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1505 FILE_OPEN, /* create_disposition, */
1506 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
1507 NULL, /* smb2_create_blobs *blobs */
1511 if (!NT_STATUS_IS_OK(status)) {
1512 printf("smb2cli_create returned %s\n", nt_errstr(status));
1516 status = smb2cli_query_directory(
1517 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1518 1, 0x3, 0, dir_persistent, dir_volatile,
1519 "session-reauth.txt", 0xffff,
1520 talloc_tos(), &dir_data, &dir_data_length);
1521 if (!NT_STATUS_IS_OK(status)) {
1522 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1526 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1527 if (!NT_STATUS_IS_OK(status)) {
1528 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1532 gensec_want_feature(auth_generic_state->gensec_security,
1533 GENSEC_FEATURE_SESSION_KEY);
1535 status = auth_generic_set_creds(auth_generic_state, torture_creds);
1536 if (!NT_STATUS_IS_OK(status)) {
1537 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1541 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1542 if (!NT_STATUS_IS_OK(status)) {
1543 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1547 ev = samba_tevent_context_init(talloc_tos());
1549 printf("samba_tevent_context_init() returned NULL\n");
1553 status = gensec_update(auth_generic_state->gensec_security,
1554 talloc_tos(), data_blob_null, &in_blob);
1555 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1556 printf("gensec_update returned %s\n", nt_errstr(status));
1560 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1565 SMB2_CAP_DFS, /* in_capabilities */
1567 0, /* in_previous_session_id */
1568 &in_blob); /* in_security_buffer */
1569 if (subreq == NULL) {
1570 printf("smb2cli_session_setup_send() returned NULL\n");
1574 ok = tevent_req_poll(subreq, ev);
1576 printf("tevent_req_poll() returned false\n");
1580 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1582 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1583 printf("smb2cli_session_setup_recv returned %s\n",
1588 status = gensec_update(auth_generic_state->gensec_security,
1589 talloc_tos(), out_blob, &in_blob);
1590 if (!NT_STATUS_IS_OK(status)) {
1591 printf("auth_generic_update returned %s\n", nt_errstr(status));
1595 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1596 cli->smb2.tcon, fid_persistent, fid_volatile);
1597 if (!NT_STATUS_IS_OK(status)) {
1598 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1602 status = smb2cli_query_directory(
1603 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1604 1, 0x3, 0, dir_persistent, dir_volatile,
1605 "session-reauth.txt", 0xffff,
1606 talloc_tos(), &dir_data, &dir_data_length);
1607 if (!NT_STATUS_IS_OK(status)) {
1608 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1613 * query_info seems to be a path based operation on Windows...
1615 status = smb2cli_query_info(cli->conn,
1619 SMB2_0_INFO_SECURITY,
1620 0, /* in_file_info_class */
1621 1024, /* in_max_output_length */
1622 NULL, /* in_input_buffer */
1623 SECINFO_OWNER, /* in_additional_info */
1628 &out_output_buffer);
1629 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1630 printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1634 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1635 status = smb2cli_query_info(cli->conn,
1641 1024, /* in_max_output_length */
1642 NULL, /* in_input_buffer */
1643 0, /* in_additional_info */
1648 &out_output_buffer);
1649 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1650 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1654 in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1655 SBVAL(in_input_buffer.data, 0, 512);
1657 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1658 status = smb2cli_set_info(cli->conn,
1665 0, /* in_additional_info */
1668 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1669 printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1673 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1674 cli->smb2.tcon, "session-reauth-invalid.txt",
1675 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1676 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1677 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1678 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1679 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1680 FILE_CREATE, /* create_disposition, */
1681 FILE_DELETE_ON_CLOSE, /* create_options, */
1682 NULL, /* smb2_create_blobs *blobs */
1686 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1687 printf("smb2cli_create %s\n", nt_errstr(status));
1691 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1693 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1694 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1695 SEC_STD_SYNCHRONIZE|
1697 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1698 0, /* file_attributes, */
1699 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1700 FILE_OPEN, /* create_disposition, */
1701 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
1702 NULL, /* smb2_create_blobs *blobs */
1706 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1707 printf("smb2cli_create returned %s\n", nt_errstr(status));
1711 saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
1712 saved_tcon = cli->smb2.tcon;
1713 cli->smb2.tcon = smbXcli_tcon_create(cli);
1714 smb2cli_tcon_set_values(cli->smb2.tcon,
1719 0, /* capabilities */
1720 0 /* maximal_access */);
1721 status = cli_tree_connect(cli, share, "?????", NULL);
1722 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1723 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1726 talloc_free(cli->smb2.tcon);
1727 cli->smb2.tcon = saved_tcon;
1729 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1734 SMB2_CAP_DFS, /* in_capabilities */
1736 0, /* in_previous_session_id */
1737 &in_blob); /* in_security_buffer */
1738 if (subreq == NULL) {
1739 printf("smb2cli_session_setup_send() returned NULL\n");
1743 ok = tevent_req_poll(subreq, ev);
1745 printf("tevent_req_poll() returned false\n");
1749 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1750 &recv_iov, &out_blob);
1751 if (!NT_STATUS_IS_OK(status)) {
1752 printf("smb2cli_session_setup_recv returned %s\n",
1757 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1758 cli->smb2.tcon, fid_persistent, fid_volatile);
1759 if (!NT_STATUS_IS_OK(status)) {
1760 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1764 status = smb2cli_query_info(cli->conn,
1768 SMB2_0_INFO_SECURITY,
1769 0, /* in_file_info_class */
1770 1024, /* in_max_output_length */
1771 NULL, /* in_input_buffer */
1772 SECINFO_OWNER, /* in_additional_info */
1777 &out_output_buffer);
1778 if (!NT_STATUS_IS_OK(status)) {
1779 printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1783 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1784 status = smb2cli_query_info(cli->conn,
1790 1024, /* in_max_output_length */
1791 NULL, /* in_input_buffer */
1792 0, /* in_additional_info */
1797 &out_output_buffer);
1798 if (!NT_STATUS_IS_OK(status)) {
1799 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1803 in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1804 SBVAL(in_input_buffer.data, 0, 512);
1806 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1807 status = smb2cli_set_info(cli->conn,
1814 0, /* in_additional_info */
1817 if (!NT_STATUS_IS_OK(status)) {
1818 printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1822 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1823 status = smb2cli_query_info(cli->conn,
1829 1024, /* in_max_output_length */
1830 NULL, /* in_input_buffer */
1831 0, /* in_additional_info */
1836 &out_output_buffer);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1842 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1843 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
1844 if (!NT_STATUS_IS_OK(status)) {
1845 printf("smb2cli_close returned %s\n", nt_errstr(status));
1849 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
1850 cli->smb2.tcon, "session-reauth.txt",
1851 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1852 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1853 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1854 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1855 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
1856 FILE_CREATE, /* create_disposition, */
1857 FILE_DELETE_ON_CLOSE, /* create_options, */
1858 NULL, /* smb2_create_blobs *blobs */
1862 if (!NT_STATUS_IS_OK(status)) {
1863 printf("smb2cli_create %s\n", nt_errstr(status));
1867 status = smb2cli_query_directory(
1868 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1869 1, 0x3, 0, dir_persistent, dir_volatile,
1870 "session-reauth.txt", 0xffff,
1871 talloc_tos(), &dir_data, &dir_data_length);
1872 if (!NT_STATUS_IS_OK(status)) {
1873 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1877 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1878 cli->smb2.tcon, 0, dir_persistent, dir_volatile);
1879 if (!NT_STATUS_IS_OK(status)) {
1880 printf("smb2cli_close returned %s\n", nt_errstr(status));
1884 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1885 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
1886 if (!NT_STATUS_IS_OK(status)) {
1887 printf("smb2cli_close returned %s\n", nt_errstr(status));
1891 saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
1892 saved_tcon = cli->smb2.tcon;
1893 cli->smb2.tcon = smbXcli_tcon_create(cli);
1894 smb2cli_tcon_set_values(cli->smb2.tcon,
1899 0, /* capabilities */
1900 0 /* maximal_access */);
1901 status = cli_tree_connect(cli, share, "?????", NULL);
1902 if (!NT_STATUS_IS_OK(status)) {
1903 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1906 talloc_free(cli->smb2.tcon);
1907 cli->smb2.tcon = saved_tcon;
1912 static NTSTATUS check_size(struct cli_state *cli,
1917 off_t size_read = 0;
1919 NTSTATUS status = cli_qfileinfo_basic(cli,
1929 if (!NT_STATUS_IS_OK(status)) {
1930 printf("cli_qfileinfo_basic of %s failed (%s)\n",
1936 if (size != size_read) {
1937 printf("size (%u) != size_read(%u) for %s\n",
1939 (unsigned int)size_read,
1941 /* Use EOF to mean bad size. */
1942 return NT_STATUS_END_OF_FILE;
1944 return NT_STATUS_OK;
1947 /* Ensure cli_ftruncate() works for SMB2. */
1949 bool run_smb2_ftruncate(int dummy)
1951 struct cli_state *cli = NULL;
1952 const char *fname = "smb2_ftruncate.txt";
1953 uint16_t fnum = (uint16_t)-1;
1954 bool correct = false;
1955 size_t buflen = 1024*1024;
1956 uint8_t *buf = NULL;
1960 printf("Starting SMB2-FTRUNCATE\n");
1962 if (!torture_init_connection(&cli)) {
1966 status = smbXcli_negprot(cli->conn, cli->timeout,
1967 PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
1968 if (!NT_STATUS_IS_OK(status)) {
1969 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1973 status = cli_session_setup_creds(cli, torture_creds);
1974 if (!NT_STATUS_IS_OK(status)) {
1975 printf("cli_session_setup returned %s\n", nt_errstr(status));
1979 status = cli_tree_connect(cli, share, "?????", NULL);
1980 if (!NT_STATUS_IS_OK(status)) {
1981 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1985 cli_setatr(cli, fname, 0, 0);
1986 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1988 status = cli_ntcreate(cli,
1992 FILE_ATTRIBUTE_NORMAL,
2000 if (!NT_STATUS_IS_OK(status)) {
2001 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2005 buf = talloc_zero_array(cli, uint8_t, buflen);
2011 status = cli_writeall(cli,
2019 if (!NT_STATUS_IS_OK(status)) {
2020 printf("write of %u to %s failed (%s)\n",
2021 (unsigned int)buflen,
2027 status = check_size(cli, fnum, fname, buflen);
2028 if (!NT_STATUS_IS_OK(status)) {
2032 /* Now ftruncate. */
2033 for ( i = 0; i < 10; i++) {
2034 status = cli_ftruncate(cli, fnum, i*1024);
2035 if (!NT_STATUS_IS_OK(status)) {
2036 printf("cli_ftruncate %u of %s failed (%s)\n",
2037 (unsigned int)i*1024,
2042 status = check_size(cli, fnum, fname, i*1024);
2043 if (!NT_STATUS_IS_OK(status)) {
2056 if (fnum != (uint16_t)-1) {
2057 cli_close(cli, fnum);
2059 cli_setatr(cli, fname, 0, 0);
2060 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2062 if (!torture_close_connection(cli)) {
2068 /* Ensure SMB2 flush on directories behaves correctly. */
2070 static bool test_dir_fsync(struct cli_state *cli, const char *path)
2073 uint64_t fid_persistent, fid_volatile;
2074 uint8_t *dir_data = NULL;
2075 uint32_t dir_data_length = 0;
2077 /* Open directory - no write abilities. */
2078 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2079 cli->smb2.tcon, path,
2080 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2081 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2082 SEC_STD_SYNCHRONIZE|
2084 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2085 0, /* file_attributes, */
2086 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2087 FILE_OPEN, /* create_disposition, */
2088 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2089 NULL, /* smb2_create_blobs *blobs */
2093 if (!NT_STATUS_IS_OK(status)) {
2094 printf("smb2cli_create '%s' (readonly) returned %s\n",
2100 status = smb2cli_query_directory(
2101 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2102 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2103 talloc_tos(), &dir_data, &dir_data_length);
2105 if (!NT_STATUS_IS_OK(status)) {
2106 printf("smb2cli_query_directory returned %s\n",
2111 /* Open directory no write access. Flush should fail. */
2113 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2114 cli->smb2.tcon, fid_persistent, fid_volatile);
2115 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2116 printf("smb2cli_flush on a read-only directory returned %s\n",
2121 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2122 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2123 if (!NT_STATUS_IS_OK(status)) {
2124 printf("smb2cli_close returned %s\n", nt_errstr(status));
2128 /* Open directory write-attributes only. Flush should still fail. */
2130 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2131 cli->smb2.tcon, path,
2132 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2133 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2134 SEC_STD_SYNCHRONIZE|
2136 SEC_DIR_WRITE_ATTRIBUTE|
2137 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2138 0, /* file_attributes, */
2139 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2140 FILE_OPEN, /* create_disposition, */
2141 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2142 NULL, /* smb2_create_blobs *blobs */
2146 if (!NT_STATUS_IS_OK(status)) {
2147 printf("smb2cli_create '%s' (write attr) returned %s\n",
2153 status = smb2cli_query_directory(
2154 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2155 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2156 talloc_tos(), &dir_data, &dir_data_length);
2158 if (!NT_STATUS_IS_OK(status)) {
2159 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2163 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2164 cli->smb2.tcon, fid_persistent, fid_volatile);
2165 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2166 printf("smb2cli_flush on a write-attributes directory "
2172 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2173 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2174 if (!NT_STATUS_IS_OK(status)) {
2175 printf("smb2cli_close returned %s\n", nt_errstr(status));
2179 /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2181 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2182 cli->smb2.tcon, path,
2183 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2184 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2185 SEC_STD_SYNCHRONIZE|
2187 SEC_DIR_ADD_FILE, /* desired_access, */
2188 0, /* file_attributes, */
2189 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2190 FILE_OPEN, /* create_disposition, */
2191 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2192 NULL, /* smb2_create_blobs *blobs */
2196 if (!NT_STATUS_IS_OK(status)) {
2197 printf("smb2cli_create '%s' (write FILE access) returned %s\n",
2203 status = smb2cli_query_directory(
2204 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2205 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2206 talloc_tos(), &dir_data, &dir_data_length);
2208 if (!NT_STATUS_IS_OK(status)) {
2209 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2213 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2214 cli->smb2.tcon, fid_persistent, fid_volatile);
2215 if (!NT_STATUS_IS_OK(status)) {
2216 printf("smb2cli_flush on a directory returned %s\n",
2221 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2222 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2223 if (!NT_STATUS_IS_OK(status)) {
2224 printf("smb2cli_close returned %s\n", nt_errstr(status));
2228 /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2230 status = smb2cli_create(cli->conn, cli->timeout, cli->smb2.session,
2231 cli->smb2.tcon, path,
2232 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2233 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2234 SEC_STD_SYNCHRONIZE|
2236 SEC_DIR_ADD_SUBDIR, /* desired_access, */
2237 0, /* file_attributes, */
2238 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2239 FILE_OPEN, /* create_disposition, */
2240 FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE, /* create_options, */
2241 NULL, /* smb2_create_blobs *blobs */
2245 if (!NT_STATUS_IS_OK(status)) {
2246 printf("smb2cli_create '%s' (write DIR access) returned %s\n",
2252 status = smb2cli_query_directory(
2253 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2254 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2255 talloc_tos(), &dir_data, &dir_data_length);
2257 if (!NT_STATUS_IS_OK(status)) {
2258 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2262 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2263 cli->smb2.tcon, fid_persistent, fid_volatile);
2264 if (!NT_STATUS_IS_OK(status)) {
2265 printf("smb2cli_flush on a directory returned %s\n",
2270 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2271 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2272 if (!NT_STATUS_IS_OK(status)) {
2273 printf("smb2cli_close returned %s\n", nt_errstr(status));
2281 bool run_smb2_dir_fsync(int dummy)
2283 struct cli_state *cli = NULL;
2286 const char *dname = "fsync_test_dir";
2288 printf("Starting SMB2-DIR-FSYNC\n");
2290 if (!torture_init_connection(&cli)) {
2294 status = smbXcli_negprot(cli->conn, cli->timeout,
2295 PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2296 if (!NT_STATUS_IS_OK(status)) {
2297 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2301 status = cli_session_setup_creds(cli, torture_creds);
2302 if (!NT_STATUS_IS_OK(status)) {
2303 printf("cli_session_setup returned %s\n", nt_errstr(status));
2307 status = cli_tree_connect(cli, share, "?????", NULL);
2308 if (!NT_STATUS_IS_OK(status)) {
2309 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2313 (void)cli_rmdir(cli, dname);
2314 status = cli_mkdir(cli, dname);
2315 if (!NT_STATUS_IS_OK(status)) {
2316 printf("cli_mkdir(%s) returned %s\n",
2322 /* Test on a subdirectory. */
2323 bret = test_dir_fsync(cli, dname);
2324 if (bret == false) {
2325 (void)cli_rmdir(cli, dname);
2328 (void)cli_rmdir(cli, dname);
2330 /* Test on the root handle of a share. */
2331 bret = test_dir_fsync(cli, "");
2332 if (bret == false) {
2338 bool run_smb2_path_slash(int dummy)
2340 struct cli_state *cli = NULL;
2342 uint64_t fid_persistent;
2343 uint64_t fid_volatile;
2344 const char *dname_noslash = "smb2_dir_slash";
2345 const char *dname_backslash = "smb2_dir_slash\\";
2346 const char *dname_slash = "smb2_dir_slash/";
2347 const char *fname_noslash = "smb2_file_slash";
2348 const char *fname_backslash = "smb2_file_slash\\";
2349 const char *fname_slash = "smb2_file_slash/";
2351 printf("Starting SMB2-PATH-SLASH\n");
2353 if (!torture_init_connection(&cli)) {
2357 status = smbXcli_negprot(cli->conn, cli->timeout,
2358 PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2359 if (!NT_STATUS_IS_OK(status)) {
2360 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2364 status = cli_session_setup_creds(cli, torture_creds);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 printf("cli_session_setup returned %s\n", nt_errstr(status));
2370 status = cli_tree_connect(cli, share, "?????", NULL);
2371 if (!NT_STATUS_IS_OK(status)) {
2372 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2376 (void)cli_unlink(cli, dname_noslash, 0);
2377 (void)cli_rmdir(cli, dname_noslash);
2378 (void)cli_unlink(cli, fname_noslash, 0);
2379 (void)cli_rmdir(cli, fname_noslash);
2381 /* Try to create a directory with the backslash name. */
2382 status = smb2cli_create(cli->conn,
2387 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2388 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2389 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2390 0, /* file_attributes, */
2391 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2392 FILE_CREATE, /* create_disposition, */
2393 FILE_DIRECTORY_FILE, /* create_options, */
2394 NULL, /* smb2_create_blobs *blobs */
2399 /* directory ending in '\\' should be success. */
2401 if (!NT_STATUS_IS_OK(status)) {
2402 printf("smb2cli_create '%s' returned %s - "
2403 "should be NT_STATUS_OK\n",
2408 status = smb2cli_close(cli->conn,
2415 if (!NT_STATUS_IS_OK(status)) {
2416 printf("smb2cli_close returned %s\n", nt_errstr(status));
2420 (void)cli_rmdir(cli, dname_noslash);
2422 /* Try to create a directory with the slash name. */
2423 status = smb2cli_create(cli->conn,
2428 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2429 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2430 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2431 0, /* file_attributes, */
2432 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2433 FILE_CREATE, /* create_disposition, */
2434 FILE_DIRECTORY_FILE, /* create_options, */
2435 NULL, /* smb2_create_blobs *blobs */
2440 /* directory ending in '/' is an error. */
2441 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2442 printf("smb2cli_create '%s' returned %s - "
2443 "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2446 if (NT_STATUS_IS_OK(status)) {
2447 (void)smb2cli_close(cli->conn,
2455 (void)cli_rmdir(cli, dname_noslash);
2459 (void)cli_rmdir(cli, dname_noslash);
2461 /* Try to create a file with the backslash name. */
2462 status = smb2cli_create(cli->conn,
2467 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2468 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2469 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2470 0, /* file_attributes, */
2471 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2472 FILE_CREATE, /* create_disposition, */
2473 FILE_NON_DIRECTORY_FILE, /* create_options, */
2474 NULL, /* smb2_create_blobs *blobs */
2479 /* file ending in '\\' should be error. */
2481 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2482 printf("smb2cli_create '%s' returned %s - "
2483 "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2486 if (NT_STATUS_IS_OK(status)) {
2487 (void)smb2cli_close(cli->conn,
2495 (void)cli_unlink(cli, fname_noslash, 0);
2499 (void)cli_unlink(cli, fname_noslash, 0);
2501 /* Try to create a file with the slash name. */
2502 status = smb2cli_create(cli->conn,
2507 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2508 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2509 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2510 0, /* file_attributes, */
2511 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
2512 FILE_CREATE, /* create_disposition, */
2513 FILE_NON_DIRECTORY_FILE, /* create_options, */
2514 NULL, /* smb2_create_blobs *blobs */
2519 /* file ending in '/' should be error. */
2521 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2522 printf("smb2cli_create '%s' returned %s - "
2523 "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2526 if (NT_STATUS_IS_OK(status)) {
2527 (void)smb2cli_close(cli->conn,
2535 (void)cli_unlink(cli, fname_noslash, 0);
2539 (void)cli_unlink(cli, fname_noslash, 0);
2544 * NB. This can only work against a server where
2545 * the connecting user has been granted SeSecurityPrivilege.
2547 * 1). Create a test file.
2548 * 2). Open with SEC_FLAG_SYSTEM_SECURITY *only*. ACCESS_DENIED -
2549 * NB. SMB2-only behavior.
2550 * 3). Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2551 * 4). Write SACL. Should fail with ACCESS_DENIED (seems to need WRITE_DAC).
2553 * 6). Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2554 * 7). Write SACL. Success.
2556 * 9). Open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
2557 * 10). Read SACL. Success.
2558 * 11). Read DACL. Should fail with ACCESS_DENIED (no READ_CONTROL).
2562 bool run_smb2_sacl(int dummy)
2564 struct cli_state *cli = NULL;
2566 struct security_descriptor *sd_dacl = NULL;
2567 struct security_descriptor *sd_sacl = NULL;
2568 const char *fname = "sacl_test_file";
2569 uint16_t fnum = (uint16_t)-1;
2571 printf("Starting SMB2-SACL\n");
2573 if (!torture_init_connection(&cli)) {
2577 status = smbXcli_negprot(cli->conn,
2581 if (!NT_STATUS_IS_OK(status)) {
2582 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2586 status = cli_session_setup_creds(cli, torture_creds);
2587 if (!NT_STATUS_IS_OK(status)) {
2588 printf("cli_session_setup returned %s\n", nt_errstr(status));
2592 status = cli_tree_connect(cli, share, "?????", NULL);
2593 if (!NT_STATUS_IS_OK(status)) {
2594 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2598 (void)cli_unlink(cli, fname, 0);
2600 /* First create a file. */
2601 status = cli_ntcreate(cli,
2605 FILE_ATTRIBUTE_NORMAL,
2613 if (!NT_STATUS_IS_OK(status)) {
2614 printf("Create of %s failed (%s)\n",
2620 cli_close(cli, fnum);
2621 fnum = (uint16_t)-1;
2624 * Now try to open with *only* SEC_FLAG_SYSTEM_SECURITY.
2625 * This should fail with NT_STATUS_ACCESS_DENIED - but
2626 * only against an SMB2 server. SMB1 allows this as tested
2627 * in SMB1-SYSTEM-SECURITY.
2630 status = cli_smb2_create_fnum(cli,
2632 SMB2_OPLOCK_LEVEL_NONE,
2633 SMB2_IMPERSONATION_IMPERSONATION,
2634 SEC_FLAG_SYSTEM_SECURITY, /* desired access */
2635 0, /* file_attributes, */
2638 FILE_SHARE_DELETE, /* share_access, */
2639 FILE_OPEN, /* create_disposition, */
2640 FILE_NON_DIRECTORY_FILE, /* create_options, */
2641 NULL, /* in_cblobs. */
2643 NULL, /* smb_create_returns */
2644 talloc_tos(), /* mem_ctx */
2645 NULL); /* out_cblobs */
2647 if (NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
2648 printf("SMB2-SACL-TEST can only work with a user "
2649 "who has been granted SeSecurityPrivilege.\n"
2651 "\"Manage auditing and security log\""
2652 "privilege setting on Windows\n");
2656 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2657 printf("open file %s with SEC_FLAG_SYSTEM_SECURITY only: "
2658 "got %s - should fail with ACCESS_DENIED\n",
2665 * Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2668 status = cli_smb2_create_fnum(cli,
2670 SMB2_OPLOCK_LEVEL_NONE,
2671 SMB2_IMPERSONATION_IMPERSONATION,
2672 SEC_FLAG_SYSTEM_SECURITY|
2673 FILE_WRITE_ATTRIBUTES, /* desired access */
2674 0, /* file_attributes, */
2677 FILE_SHARE_DELETE, /* share_access, */
2678 FILE_OPEN, /* create_disposition, */
2679 FILE_NON_DIRECTORY_FILE, /* create_options, */
2680 NULL, /* in_cblobs. */
2682 NULL, /* smb_create_returns */
2683 talloc_tos(), /* mem_ctx */
2684 NULL); /* out_cblobs */
2686 if (!NT_STATUS_IS_OK(status)) {
2687 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2688 "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2694 /* Create an SD with a SACL. */
2695 sd_sacl = security_descriptor_sacl_create(talloc_tos(),
2701 SEC_ACE_TYPE_SYSTEM_AUDIT,
2703 SEC_ACE_FLAG_FAILED_ACCESS,
2706 if (sd_sacl == NULL) {
2707 printf("Out of memory creating SACL\n");
2712 * Write the SACL SD. This should fail
2713 * even though we have SEC_FLAG_SYSTEM_SECURITY,
2714 * as it seems to also need WRITE_DAC access.
2716 status = cli_set_security_descriptor(cli,
2718 SECINFO_DACL|SECINFO_SACL,
2721 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2722 printf("Writing SACL on file %s got (%s) "
2723 "should have failed with ACCESS_DENIED.\n",
2730 cli_smb2_close_fnum(cli, fnum);
2731 fnum = (uint16_t)-1;
2734 * Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2737 status = cli_smb2_create_fnum(cli,
2739 SMB2_OPLOCK_LEVEL_NONE,
2740 SMB2_IMPERSONATION_IMPERSONATION,
2741 SEC_FLAG_SYSTEM_SECURITY|
2742 SEC_STD_WRITE_DAC, /* desired access */
2743 0, /* file_attributes, */
2746 FILE_SHARE_DELETE, /* share_access, */
2747 FILE_OPEN, /* create_disposition, */
2748 FILE_NON_DIRECTORY_FILE, /* create_options, */
2749 NULL, /* in_cblobs. */
2751 NULL, /* smb_create_returns */
2752 talloc_tos(), /* mem_ctx */
2753 NULL); /* out_cblobs */
2755 if (!NT_STATUS_IS_OK(status)) {
2756 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2757 "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2764 * Write the SACL SD. This should now succeed
2765 * as we have both SEC_FLAG_SYSTEM_SECURITY
2766 * and WRITE_DAC access.
2768 status = cli_set_security_descriptor(cli,
2770 SECINFO_DACL|SECINFO_SACL,
2773 if (!NT_STATUS_IS_OK(status)) {
2774 printf("cli_set_security_descriptor SACL "
2775 "on file %s failed (%s)\n",
2782 cli_smb2_close_fnum(cli, fnum);
2783 fnum = (uint16_t)-1;
2785 /* We're done with the sacl we made. */
2786 TALLOC_FREE(sd_sacl);
2789 * Now try to open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
2790 * This gives us access to the SACL.
2793 status = cli_smb2_create_fnum(cli,
2795 SMB2_OPLOCK_LEVEL_NONE,
2796 SMB2_IMPERSONATION_IMPERSONATION,
2797 SEC_FLAG_SYSTEM_SECURITY|
2798 FILE_READ_ATTRIBUTES, /* desired access */
2799 0, /* file_attributes, */
2802 FILE_SHARE_DELETE, /* share_access, */
2803 FILE_OPEN, /* create_disposition, */
2804 FILE_NON_DIRECTORY_FILE, /* create_options, */
2805 NULL, /* in_cblobs. */
2807 NULL, /* smb_create_returns */
2808 talloc_tos(), /* mem_ctx */
2809 NULL); /* out_cblobs */
2811 if (!NT_STATUS_IS_OK(status)) {
2812 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2813 "FILE_READ_ATTRIBUTES) failed (%s)\n",
2819 /* Try and read the SACL - should succeed. */
2820 status = cli_query_security_descriptor(
2821 cli, fnum, SECINFO_SACL, talloc_tos(), &sd_sacl);
2823 if (!NT_STATUS_IS_OK(status)) {
2824 printf("Read SACL from file %s failed (%s)\n",
2830 TALLOC_FREE(sd_sacl);
2833 * Try and read the DACL - should fail as we have
2834 * no READ_DAC access.
2836 status = cli_query_security_descriptor(
2837 cli, fnum, SECINFO_DACL, talloc_tos(), &sd_sacl);
2839 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2840 printf("Reading DACL on file %s got (%s) "
2841 "should have failed with ACCESS_DENIED.\n",
2847 if (fnum != (uint16_t)-1) {
2848 cli_smb2_close_fnum(cli, fnum);
2849 fnum = (uint16_t)-1;
2852 TALLOC_FREE(sd_dacl);
2853 TALLOC_FREE(sd_sacl);
2855 (void)cli_unlink(cli, fname, 0);
2860 TALLOC_FREE(sd_dacl);
2861 TALLOC_FREE(sd_sacl);
2863 if (fnum != (uint16_t)-1) {
2864 cli_smb2_close_fnum(cli, fnum);
2865 fnum = (uint16_t)-1;
2868 (void)cli_unlink(cli, fname, 0);
2872 bool run_smb2_quota1(int dummy)
2874 struct cli_state *cli = NULL;
2876 uint16_t fnum = (uint16_t)-1;
2877 SMB_NTQUOTA_STRUCT qt = {0};
2879 printf("Starting SMB2-QUOTA1\n");
2881 if (!torture_init_connection(&cli)) {
2885 status = smbXcli_negprot(cli->conn,
2889 if (!NT_STATUS_IS_OK(status)) {
2890 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2894 status = cli_session_setup_creds(cli, torture_creds);
2895 if (!NT_STATUS_IS_OK(status)) {
2896 printf("cli_session_setup returned %s\n", nt_errstr(status));
2900 status = cli_tree_connect(cli, share, "?????", NULL);
2901 if (!NT_STATUS_IS_OK(status)) {
2902 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2906 status = cli_smb2_create_fnum(
2909 SMB2_OPLOCK_LEVEL_NONE,
2910 SMB2_IMPERSONATION_IMPERSONATION,
2911 SEC_GENERIC_READ, /* desired access */
2912 0, /* file_attributes, */
2915 FILE_SHARE_DELETE, /* share_access, */
2916 FILE_OPEN, /* create_disposition, */
2917 FILE_DIRECTORY_FILE, /* create_options, */
2918 NULL, /* in_cblobs. */
2920 NULL, /* smb_create_returns */
2922 NULL); /* out_cblobs */
2923 if (!NT_STATUS_IS_OK(status)) {
2924 printf("cli_smb2_create_fnum failed: %s\n", nt_errstr(status));
2928 status = cli_smb2_get_user_quota(cli, fnum, &qt);
2929 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
2930 printf("cli_smb2_get_user_quota returned %s, expected "
2931 "NT_STATUS_INVALID_HANDLE\n",
2939 bool run_smb2_stream_acl(int dummy)
2941 struct cli_state *cli = NULL;
2943 uint16_t fnum = (uint16_t)-1;
2944 const char *fname = "stream_acl_test_file";
2945 const char *sname = "stream_acl_test_file:streamname";
2946 struct security_descriptor *sd_dacl = NULL;
2949 printf("SMB2 stream acl\n");
2951 if (!torture_init_connection(&cli)) {
2955 status = smbXcli_negprot(cli->conn,
2959 if (!NT_STATUS_IS_OK(status)) {
2960 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2964 status = cli_session_setup_creds(cli, torture_creds);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 printf("cli_session_setup returned %s\n", nt_errstr(status));
2970 status = cli_tree_connect(cli, share, "?????", NULL);
2971 if (!NT_STATUS_IS_OK(status)) {
2972 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2976 /* Ensure file doesn't exist. */
2977 (void)cli_unlink(cli, fname, 0);
2979 /* Create the file. */
2980 status = cli_ntcreate(cli,
2984 FILE_ATTRIBUTE_NORMAL,
2992 if (!NT_STATUS_IS_OK(status)) {
2993 printf("Create of %s failed (%s)\n",
2999 /* Close the handle. */
3000 cli_smb2_close_fnum(cli, fnum);
3001 fnum = (uint16_t)-1;
3003 /* Create the stream. */
3004 status = cli_ntcreate(cli,
3008 SEC_STD_READ_CONTROL|
3010 FILE_ATTRIBUTE_NORMAL,
3018 if (!NT_STATUS_IS_OK(status)) {
3019 printf("Create of %s failed (%s)\n",
3025 /* Close the handle. */
3026 cli_smb2_close_fnum(cli, fnum);
3027 fnum = (uint16_t)-1;
3030 * Open the stream - for Samba this ensures
3031 * we prove we have a pathref fsp.
3033 status = cli_ntcreate(cli,
3037 SEC_STD_READ_CONTROL|
3039 FILE_ATTRIBUTE_NORMAL,
3047 if (!NT_STATUS_IS_OK(status)) {
3048 printf("Open of %s failed (%s)\n",
3054 /* Read the security descriptor off the stream handle. */
3055 status = cli_query_security_descriptor(cli,
3061 if (!NT_STATUS_IS_OK(status)) {
3062 printf("Reading DACL on stream %s got (%s)\n",
3068 if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3069 sd_dacl->dacl->num_aces < 1) {
3070 printf("Invalid DACL returned on stream %s "
3071 "(this should not happen)\n",
3077 * Ensure it allows FILE_READ_DATA in the first ace.
3080 if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) == 0) {
3081 printf("DACL->ace[0] returned on stream %s "
3082 "doesn't have read access (should not happen)\n",
3087 /* Remove FILE_READ_DATA from the first ace and set. */
3088 sd_dacl->dacl->aces[0].access_mask &= ~FILE_READ_DATA;
3090 status = cli_set_security_descriptor(cli,
3095 if (!NT_STATUS_IS_OK(status)) {
3096 printf("Setting DACL on stream %s got (%s)\n",
3102 TALLOC_FREE(sd_dacl);
3104 /* Read again and check it changed. */
3105 status = cli_query_security_descriptor(cli,
3111 if (!NT_STATUS_IS_OK(status)) {
3112 printf("Reading DACL on stream %s got (%s)\n",
3118 if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3119 sd_dacl->dacl->num_aces < 1) {
3120 printf("Invalid DACL (1) returned on stream %s "
3121 "(this should not happen)\n",
3126 /* FILE_READ_DATA should be gone from the first ace. */
3127 if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) != 0) {
3128 printf("DACL on stream %s did not change\n",
3137 if (fnum != (uint16_t)-1) {
3138 cli_smb2_close_fnum(cli, fnum);
3139 fnum = (uint16_t)-1;
3142 (void)cli_unlink(cli, fname, 0);
3146 static NTSTATUS list_fn(struct file_info *finfo,
3150 bool *matched = (bool *)state;
3151 if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
3154 return NT_STATUS_OK;
3158 * Must be run against a share with "smbd async dosmode = yes".
3159 * Checks we can return DOS attriutes other than "N".
3160 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14758
3163 bool run_list_dir_async_test(int dummy)
3165 struct cli_state *cli = NULL;
3167 const char *dname = "ASYNC_DIR";
3169 bool matched = false;
3171 printf("SMB2 list dir async\n");
3173 if (!torture_init_connection(&cli)) {
3177 status = smbXcli_negprot(cli->conn,
3181 if (!NT_STATUS_IS_OK(status)) {
3182 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3186 status = cli_session_setup_creds(cli, torture_creds);
3187 if (!NT_STATUS_IS_OK(status)) {
3188 printf("cli_session_setup returned %s\n", nt_errstr(status));
3192 status = cli_tree_connect(cli, share, "?????", NULL);
3193 if (!NT_STATUS_IS_OK(status)) {
3194 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3198 /* Ensure directory doesn't exist. */
3199 (void)cli_rmdir(cli, dname);
3201 status = cli_mkdir(cli, dname);
3202 if (!NT_STATUS_IS_OK(status)) {
3203 printf("cli_mkdir %s returned %s\n", dname, nt_errstr(status));
3207 status = cli_list(cli,
3209 FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_DIRECTORY,
3212 if (!NT_STATUS_IS_OK(status)) {
3213 printf("cli_list %s returned %s\n", dname, nt_errstr(status));
3218 printf("Failed to find %s\n", dname);
3226 (void)cli_rmdir(cli, dname);
3231 * Test delete a directory fails if a file is created
3232 * in a directory after the delete on close is set.
3233 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
3236 bool run_delete_on_close_non_empty(int dummy)
3238 struct cli_state *cli = NULL;
3240 const char *dname = "DEL_ON_CLOSE_DIR";
3241 const char *fname = "DEL_ON_CLOSE_DIR\\testfile";
3242 uint16_t fnum = (uint16_t)-1;
3243 uint16_t fnum1 = (uint16_t)-1;
3246 printf("SMB2 delete on close nonempty\n");
3248 if (!torture_init_connection(&cli)) {
3252 status = smbXcli_negprot(cli->conn,
3256 if (!NT_STATUS_IS_OK(status)) {
3257 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3261 status = cli_session_setup_creds(cli, torture_creds);
3262 if (!NT_STATUS_IS_OK(status)) {
3263 printf("cli_session_setup returned %s\n", nt_errstr(status));
3267 status = cli_tree_connect(cli, share, "?????", NULL);
3268 if (!NT_STATUS_IS_OK(status)) {
3269 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3273 /* Ensure directory doesn't exist. */
3274 (void)cli_unlink(cli,
3276 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3277 (void)cli_rmdir(cli, dname);
3279 /* Create target directory. */
3280 status = cli_ntcreate(cli,
3283 DELETE_ACCESS|FILE_READ_DATA,
3284 FILE_ATTRIBUTE_DIRECTORY,
3289 FILE_DIRECTORY_FILE,
3293 if (!NT_STATUS_IS_OK(status)) {
3294 printf("cli_ntcreate for directory %s returned %s\n",
3300 /* Now set the delete on close bit. */
3301 status = cli_nt_delete_on_close(cli, fnum, 1);
3302 if (!NT_STATUS_IS_OK(status)) {
3303 printf("cli_cli_nt_delete_on_close set for directory "
3310 /* Create file inside target directory. */
3312 * NB. On Windows this will return NT_STATUS_DELETE_PENDING. Only on
3313 * Samba will this succeed by default (the option "check parent
3314 * directory delete on close" configures behaviour), but we're using
3315 * this to test a race condition.
3317 status = cli_ntcreate(cli,
3321 FILE_ATTRIBUTE_NORMAL,
3330 if (!NT_STATUS_IS_OK(status)) {
3331 printf("cli_ntcreate for file %s returned %s\n",
3336 cli_close(cli, fnum1);
3337 fnum1 = (uint16_t)-1;
3339 /* Now the close should fail. */
3340 status = cli_close(cli, fnum);
3341 if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3342 printf("cli_close for directory %s returned %s\n",
3352 if (fnum1 != (uint16_t)-1) {
3353 cli_close(cli, fnum1);
3355 if (fnum != (uint16_t)-1) {
3356 cli_nt_delete_on_close(cli, fnum, 0);
3357 cli_close(cli, fnum);
3359 (void)cli_unlink(cli,
3361 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3362 (void)cli_rmdir(cli, dname);
3366 static NTSTATUS check_empty_fn(struct file_info *finfo,
3370 unsigned int *pcount = (unsigned int *)private_data;
3372 if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
3374 return NT_STATUS_OK;
3376 return NT_STATUS_DIRECTORY_NOT_EMPTY;
3380 * Test setting the delete on close bit on a directory
3381 * containing an unwritable file fails or succeeds
3382 * an a share set with "hide unwritable = yes"
3383 * depending on the setting of "delete veto files".
3384 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3386 * First version. With "delete veto files = yes"
3387 * setting the delete on close should succeed.
3390 bool run_delete_on_close_nonwrite_delete_yes_test(int dummy)
3392 struct cli_state *cli = NULL;
3394 const char *dname = "delete_veto_yes";
3395 const char *list_dname = "delete_veto_yes\\*";
3396 uint16_t fnum = (uint16_t)-1;
3398 unsigned int list_count = 0;
3400 printf("SMB2 delete on close nonwrite - delete veto yes\n");
3402 if (!torture_init_connection(&cli)) {
3406 status = smbXcli_negprot(cli->conn,
3410 if (!NT_STATUS_IS_OK(status)) {
3411 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3415 status = cli_session_setup_creds(cli, torture_creds);
3416 if (!NT_STATUS_IS_OK(status)) {
3417 printf("cli_session_setup returned %s\n", nt_errstr(status));
3421 status = cli_tree_connect(cli, share, "?????", NULL);
3422 if (!NT_STATUS_IS_OK(status)) {
3423 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3427 /* Ensure target directory is seen as empty. */
3428 status = cli_list(cli,
3430 FILE_ATTRIBUTE_DIRECTORY |
3431 FILE_ATTRIBUTE_HIDDEN |
3432 FILE_ATTRIBUTE_SYSTEM,
3435 if (!NT_STATUS_IS_OK(status)) {
3436 printf("cli_list of %s returned %s\n",
3441 if (list_count != 2) {
3442 printf("cli_list of %s returned a count of %u\n",
3448 /* Open target directory. */
3449 status = cli_ntcreate(cli,
3452 DELETE_ACCESS|FILE_READ_DATA,
3453 FILE_ATTRIBUTE_DIRECTORY,
3458 FILE_DIRECTORY_FILE,
3462 if (!NT_STATUS_IS_OK(status)) {
3463 printf("cli_ntcreate for directory %s returned %s\n",
3469 /* Now set the delete on close bit. */
3470 status = cli_nt_delete_on_close(cli, fnum, 1);
3471 if (!NT_STATUS_IS_OK(status)) {
3472 printf("cli_cli_nt_delete_on_close set for directory "
3473 "%s returned %s (should have succeeded)\n",
3483 if (fnum != (uint16_t)-1) {
3484 (void)cli_nt_delete_on_close(cli, fnum, 0);
3485 (void)cli_close(cli, fnum);
3491 * Test setting the delete on close bit on a directory
3492 * containing an unwritable file fails or succeeds
3493 * an a share set with "hide unwritable = yes"
3494 * depending on the setting of "delete veto files".
3495 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3497 * Second version. With "delete veto files = no"
3498 * setting the delete on close should fail.
3501 bool run_delete_on_close_nonwrite_delete_no_test(int dummy)
3503 struct cli_state *cli = NULL;
3505 const char *dname = "delete_veto_no";
3506 const char *list_dname = "delete_veto_no\\*";
3507 uint16_t fnum = (uint16_t)-1;
3509 unsigned int list_count = 0;
3511 printf("SMB2 delete on close nonwrite - delete veto yes\n");
3513 if (!torture_init_connection(&cli)) {
3517 status = smbXcli_negprot(cli->conn,
3521 if (!NT_STATUS_IS_OK(status)) {
3522 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3526 status = cli_session_setup_creds(cli, torture_creds);
3527 if (!NT_STATUS_IS_OK(status)) {
3528 printf("cli_session_setup returned %s\n", nt_errstr(status));
3532 status = cli_tree_connect(cli, share, "?????", NULL);
3533 if (!NT_STATUS_IS_OK(status)) {
3534 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3538 /* Ensure target directory is seen as empty. */
3539 status = cli_list(cli,
3541 FILE_ATTRIBUTE_DIRECTORY |
3542 FILE_ATTRIBUTE_HIDDEN |
3543 FILE_ATTRIBUTE_SYSTEM,
3546 if (!NT_STATUS_IS_OK(status)) {
3547 printf("cli_list of %s returned %s\n",
3552 if (list_count != 2) {
3553 printf("cli_list of %s returned a count of %u\n",
3559 /* Open target directory. */
3560 status = cli_ntcreate(cli,
3563 DELETE_ACCESS|FILE_READ_DATA,
3564 FILE_ATTRIBUTE_DIRECTORY,
3569 FILE_DIRECTORY_FILE,
3573 if (!NT_STATUS_IS_OK(status)) {
3574 printf("cli_ntcreate for directory %s returned %s\n",
3580 /* Now set the delete on close bit. */
3581 status = cli_nt_delete_on_close(cli, fnum, 1);
3582 if (NT_STATUS_IS_OK(status)) {
3583 printf("cli_cli_nt_delete_on_close set for directory "
3584 "%s returned NT_STATUS_OK "
3585 "(should have failed)\n",
3589 if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3590 printf("cli_cli_nt_delete_on_close set for directory "
3592 "(should have returned "
3593 "NT_STATUS_DIRECTORY_NOT_EMPTY)\n",
3603 if (fnum != (uint16_t)-1) {
3604 (void)cli_nt_delete_on_close(cli, fnum, 0);
3605 (void)cli_close(cli, fnum);
3611 * Open an SMB2 file readonly and return the inode number.
3613 static NTSTATUS get_smb2_inode(struct cli_state *cli,
3614 const char *pathname,
3618 uint64_t fid_persistent = 0;
3619 uint64_t fid_volatile = 0;
3620 DATA_BLOB outbuf = data_blob_null;
3624 status = smb2cli_create(cli->conn,
3629 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3630 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3631 SEC_STD_SYNCHRONIZE|
3633 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
3634 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3635 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3636 FILE_OPEN, /* create_disposition, */
3637 0, /* create_options, */
3638 NULL, /* smb2_create_blobs *blobs */
3641 NULL, /* struct smb_create_returns * */
3642 talloc_tos(), /* mem_ctx. */
3643 NULL); /* struct smb2_create_blobs * */
3644 if (!NT_STATUS_IS_OK(status)) {
3651 status = smb2cli_query_info(cli->conn,
3656 (SMB_FILE_ALL_INFORMATION - 1000), /* in_file_info_class */
3657 1024, /* in_max_output_length */
3658 NULL, /* in_input_buffer */
3659 0, /* in_additional_info */
3666 if (NT_STATUS_IS_OK(status)) {
3667 *ino_ret = PULL_LE_U64(outbuf.data, 0x40);
3670 (void)smb2cli_close(cli->conn,
3681 * Check an inode matches a given SMB2 path.
3683 static bool smb2_inode_matches(struct cli_state *cli,
3684 const char *match_pathname,
3685 uint64_t ino_tomatch,
3686 const char *test_pathname)
3688 uint64_t test_ino = 0;
3691 status = get_smb2_inode(cli,
3694 if (!NT_STATUS_IS_OK(status)) {
3695 printf("%s: Failed to get ino "
3696 "number for %s, (%s)\n",
3702 if (test_ino != ino_tomatch) {
3703 printf("%s: Inode missmatch, ino_tomatch (%s) "
3704 "ino=%"PRIu64" test (%s) "
3717 * Delete an SMB2 file on a DFS share.
3719 static NTSTATUS smb2_dfs_delete(struct cli_state *cli,
3720 const char *pathname)
3723 uint64_t fid_persistent = 0;
3724 uint64_t fid_volatile = 0;
3731 status = smb2cli_create(cli->conn,
3736 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3737 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3738 SEC_STD_SYNCHRONIZE|
3739 SEC_STD_DELETE, /* desired_access, */
3740 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3741 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3742 FILE_OPEN, /* create_disposition, */
3743 0, /* create_options, */
3744 NULL, /* smb2_create_blobs *blobs */
3747 NULL, /* struct smb_create_returns * */
3748 talloc_tos(), /* mem_ctx. */
3749 NULL); /* struct smb2_create_blobs * */
3750 if (!NT_STATUS_IS_OK(status)) {
3755 * Set delete on close.
3757 PUSH_LE_U8(&data[0], 0, 1);
3758 inbuf.data = &data[0];
3761 status = smb2cli_set_info(cli->conn,
3765 SMB2_0_INFO_FILE, /* info_type. */
3766 SMB_FILE_DISPOSITION_INFORMATION - 1000, /* info_class */
3768 0, /* additional_info. */
3771 if (!NT_STATUS_IS_OK(status)) {
3774 status = smb2cli_close(cli->conn,
3785 * Rename or hardlink an SMB2 file on a DFS share.
3787 static NTSTATUS smb2_dfs_setinfo_name(struct cli_state *cli,
3788 uint64_t fid_persistent,
3789 uint64_t fid_volatile,
3790 const char *newname,
3795 smb_ucs2_t *converted_str = NULL;
3796 size_t converted_size_bytes = 0;
3798 uint8_t info_class = 0;
3801 ok = push_ucs2_talloc(talloc_tos(),
3804 &converted_size_bytes);
3806 return NT_STATUS_INVALID_PARAMETER;
3809 * W2K8 insists the dest name is not null terminated. Remove
3810 * the last 2 zero bytes and reduce the name length.
3812 if (converted_size_bytes < 2) {
3813 return NT_STATUS_INVALID_PARAMETER;
3815 converted_size_bytes -= 2;
3816 inbuf_size = 20 + converted_size_bytes;
3817 if (inbuf_size < 20) {
3818 /* Integer wrap check. */
3819 return NT_STATUS_INVALID_PARAMETER;
3823 * The Windows 10 SMB2 server has a minimum length
3824 * for a SMB2_FILE_RENAME_INFORMATION buffer of
3825 * 24 bytes. It returns NT_STATUS_INFO_LENGTH_MISMATCH
3826 * if the length is less.
3828 inbuf_size = MAX(inbuf_size, 24);
3829 inbuf = data_blob_talloc_zero(talloc_tos(), inbuf_size);
3830 if (inbuf.data == NULL) {
3831 return NT_STATUS_NO_MEMORY;
3833 PUSH_LE_U32(inbuf.data, 16, converted_size_bytes);
3834 memcpy(inbuf.data + 20, converted_str, converted_size_bytes);
3835 TALLOC_FREE(converted_str);
3837 if (do_rename == true) {
3838 info_class = SMB_FILE_RENAME_INFORMATION - 1000;
3841 info_class = SMB_FILE_LINK_INFORMATION - 1000;
3844 status = smb2cli_set_info(cli->conn,
3848 SMB2_0_INFO_FILE, /* info_type. */
3849 info_class, /* info_class */
3851 0, /* additional_info. */
3857 static NTSTATUS smb2_dfs_rename(struct cli_state *cli,
3858 uint64_t fid_persistent,
3859 uint64_t fid_volatile,
3860 const char *newname)
3862 return smb2_dfs_setinfo_name(cli,
3866 true); /* do_rename */
3869 static NTSTATUS smb2_dfs_hlink(struct cli_state *cli,
3870 uint64_t fid_persistent,
3871 uint64_t fid_volatile,
3872 const char *newname)
3874 return smb2_dfs_setinfo_name(cli,
3878 false); /* do_rename */
3884 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/dc9978d7-6299-4c5a-a22d-a039cdc716ea
3886 * (Characters " \ / [ ] : | < > + = ; , * ?,
3887 * and control characters in range 0x00 through
3888 * 0x1F, inclusive, are illegal in a share name)
3890 * But Windows server only checks in DFS sharenames ':'. All other
3891 * share names are allowed.
3894 static bool test_smb2_dfs_sharenames(struct cli_state *cli,
3895 const char *dfs_root_share_name,
3899 const char *test_str = "/[]:|<>+=;,*?";
3902 bool ino_matched = false;
3904 /* Setup template pathname. */
3905 memcpy(test_path, "SERVER\\X", 9);
3907 /* Test invalid control characters. */
3908 for (i = 1; i < 0x20; i++) {
3910 ino_matched = smb2_inode_matches(cli,
3911 dfs_root_share_name,
3919 /* Test explicit invalid characters. */
3920 for (p = test_str; *p != '\0'; p++) {
3924 * Only ':' is treated as an INVALID sharename
3925 * for a DFS SERVER\\SHARE path.
3927 uint64_t test_ino = 0;
3928 NTSTATUS status = get_smb2_inode(cli,
3931 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
3932 printf("%s:%d Open of %s should get "
3933 "NT_STATUS_OBJECT_NAME_INVALID, got %s\n",
3941 ino_matched = smb2_inode_matches(cli,
3942 dfs_root_share_name,
3954 * "Raw" test of SMB2 paths to a DFS share.
3955 * We must use the lower level smb2cli_XXXX() interfaces,
3956 * not the cli_XXX() ones here as the ultimate goal is to fix our
3957 * cli_XXX() interfaces to work transparently over DFS.
3959 * So here, we're testing the server code, not the client code.
3961 * Passes cleanly against Windows.
3964 bool run_smb2_dfs_paths(int dummy)
3966 struct cli_state *cli = NULL;
3968 bool dfs_supported = false;
3969 char *dfs_root_share_name = NULL;
3970 uint64_t root_ino = 0;
3971 uint64_t test_ino = 0;
3972 bool ino_matched = false;
3973 uint64_t fid_persistent = 0;
3974 uint64_t fid_volatile = 0;
3975 bool retval = false;
3978 printf("Starting SMB2-DFS-PATHS\n");
3980 if (!torture_init_connection(&cli)) {
3984 status = smbXcli_negprot(cli->conn,
3988 if (!NT_STATUS_IS_OK(status)) {
3989 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3993 status = cli_session_setup_creds(cli, torture_creds);
3994 if (!NT_STATUS_IS_OK(status)) {
3995 printf("cli_session_setup returned %s\n", nt_errstr(status));
3999 status = cli_tree_connect(cli, share, "?????", NULL);
4000 if (!NT_STATUS_IS_OK(status)) {
4001 printf("cli_tree_connect returned %s\n", nt_errstr(status));
4005 /* Ensure this is a DFS share. */
4006 dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4007 if (!dfs_supported) {
4008 printf("Server %s does not support DFS\n",
4009 smbXcli_conn_remote_name(cli->conn));
4012 dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4013 if (!dfs_supported) {
4014 printf("Share %s does not support DFS\n",
4019 * Create the "official" DFS share root name.
4020 * No SMB2 paths can start with '\\'.
4022 dfs_root_share_name = talloc_asprintf(talloc_tos(),
4024 smbXcli_conn_remote_name(cli->conn),
4026 if (dfs_root_share_name == NULL) {
4027 printf("Out of memory\n");
4031 /* Get the share root inode number. */
4032 status = get_smb2_inode(cli,
4033 dfs_root_share_name,
4035 if (!NT_STATUS_IS_OK(status)) {
4036 printf("%s:%d Failed to get ino number for share root %s, (%s)\n",
4039 dfs_root_share_name,
4045 * Test the Windows algorithm for parsing DFS names.
4048 * A single "SERVER" element should open and match the share root.
4050 ino_matched = smb2_inode_matches(cli,
4051 dfs_root_share_name,
4053 smbXcli_conn_remote_name(cli->conn));
4055 printf("%s:%d Failed to match ino number for %s\n",
4058 smbXcli_conn_remote_name(cli->conn));
4063 * An "" DFS empty server name should open and match the share root on
4064 * Windows 2008. Windows 2022 returns NT_STATUS_INVALID_PARAMETER
4065 * for a DFS empty server name.
4067 status = get_smb2_inode(cli,
4070 if (NT_STATUS_IS_OK(status)) {
4072 * Windows 2008 - open succeeded. Proceed to
4075 ino_matched = smb2_inode_matches(cli,
4076 dfs_root_share_name,
4080 printf("%s:%d Failed to match ino number for %s\n",
4087 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4089 * For Windows 2022 we expect to fail with
4090 * NT_STATUS_INVALID_PARAMETER. Anything else is
4093 printf("%s:%d Unexpected error (%s) getting ino number for %s\n",
4100 /* A "BAD" server name should open and match the share root. */
4101 ino_matched = smb2_inode_matches(cli,
4102 dfs_root_share_name,
4106 printf("%s:%d Failed to match ino number for %s\n",
4113 * A "BAD\\BAD" server and share name should open
4114 * and match the share root.
4116 ino_matched = smb2_inode_matches(cli,
4117 dfs_root_share_name,
4121 printf("%s:%d Failed to match ino number for %s\n",
4128 * Trying to open "BAD\\BAD\\BAD" should get
4129 * NT_STATUS_OBJECT_NAME_NOT_FOUND.
4131 status = get_smb2_inode(cli,
4134 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4135 printf("%s:%d Open of %s should get "
4136 "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
4144 * Trying to open "BAD\\BAD\\BAD\\BAD" should get
4145 * NT_STATUS_OBJECT_PATH_NOT_FOUND.
4147 status = get_smb2_inode(cli,
4148 "BAD\\BAD\\BAD\\BAD",
4150 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4151 printf("%s:%d Open of %s should get "
4152 "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
4155 "BAD\\BAD\\BAD\\BAD",
4160 * Test for invalid pathname characters in the servername.
4161 * They are ignored, and it still opens the share root.
4163 ino_matched = smb2_inode_matches(cli,
4164 dfs_root_share_name,
4168 printf("%s:%d Failed to match ino number for %s\n",
4176 * Test for invalid pathname characters in the sharename.
4177 * Invalid sharename characters should still be flagged as
4178 * NT_STATUS_OBJECT_NAME_INVALID. It turns out only ':'
4179 * is considered an invalid sharename character.
4181 ok = test_smb2_dfs_sharenames(cli,
4182 dfs_root_share_name,
4188 /* Now create a file called "file". */
4189 status = smb2cli_create(cli->conn,
4194 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4195 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4196 SEC_STD_SYNCHRONIZE|
4199 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4200 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4201 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4202 FILE_CREATE, /* create_disposition, */
4203 0, /* create_options, */
4204 NULL, /* smb2_create_blobs *blobs */
4207 NULL, /* struct smb_create_returns * */
4208 talloc_tos(), /* mem_ctx. */
4209 NULL); /* struct smb2_create_blobs * */
4210 if (!NT_STATUS_IS_OK(status)) {
4211 printf("%s:%d smb2cli_create on %s returned %s\n",
4220 * Trying to open "BAD\\BAD\\file" should now get
4223 status = get_smb2_inode(cli,
4226 if (!NT_STATUS_IS_OK(status)) {
4227 printf("%s:%d Open of %s should succeed "
4237 * Now show that renames use relative,
4238 * not full DFS paths.
4241 /* Full DFS path should fail. */
4242 status = smb2_dfs_rename(cli,
4245 "ANY\\NAME\\renamed_file");
4246 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4247 printf("%s:%d Rename of %s -> %s should fail "
4248 "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4252 "ANY\\NAME\\renamed_file",
4256 /* Relative DFS path should succeed. */
4257 status = smb2_dfs_rename(cli,
4261 if (!NT_STATUS_IS_OK(status)) {
4262 printf("%s:%d: Rename of %s -> %s should succeed. "
4273 * Trying to open "BAD\\BAD\\renamed_file" should now get
4276 status = get_smb2_inode(cli,
4277 "BAD\\BAD\\renamed_file",
4279 if (!NT_STATUS_IS_OK(status)) {
4280 printf("%s:%d: Open of %s should succeed "
4284 "BAD\\BAD\\renamed_file",
4290 * Now show that hard links use relative,
4291 * not full DFS paths.
4294 /* Full DFS path should fail. */
4295 status = smb2_dfs_hlink(cli,
4298 "ANY\\NAME\\hlink");
4299 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4300 printf("%s:%d Hlink of %s -> %s should fail "
4301 "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4304 "ANY\\NAME\\renamed_file",
4309 /* Relative DFS path should succeed. */
4310 status = smb2_dfs_hlink(cli,
4314 if (!NT_STATUS_IS_OK(status)) {
4315 printf("%s:%d: Hlink of %s -> %s should succeed. "
4319 "ANY\\NAME\\renamed_file",
4326 * Trying to open "BAD\\BAD\\hlink" should now get
4329 status = get_smb2_inode(cli,
4332 if (!NT_STATUS_IS_OK(status)) {
4333 printf("%s:%d Open of %s should succeed "
4346 if (fid_persistent != 0 || fid_volatile != 0) {
4347 smb2cli_close(cli->conn,
4355 /* Delete anything we made. */
4356 (void)smb2_dfs_delete(cli, "BAD\\BAD\\BAD");
4357 (void)smb2_dfs_delete(cli, "BAD\\BAD\\file");
4358 (void)smb2_dfs_delete(cli, "BAD\\BAD\\renamed_file");
4359 (void)smb2_dfs_delete(cli, "BAD\\BAD\\hlink");
4364 * Add a test that sends DFS paths and sets the
4365 * SMB2 flag FLAGS2_DFS_PATHNAMES, but to a non-DFS
4366 * share. Windows passes this (it just treats the
4367 * pathnames as non-DFS and ignores the FLAGS2_DFS_PATHNAMES
4371 bool run_smb2_non_dfs_share(int dummy)
4373 struct cli_state *cli = NULL;
4375 bool dfs_supported = false;
4376 uint64_t fid_persistent = 0;
4377 uint64_t fid_volatile = 0;
4378 bool retval = false;
4379 char *dfs_filename = NULL;
4381 printf("Starting SMB2-DFS-NON-DFS-SHARE\n");
4383 if (!torture_init_connection(&cli)) {
4387 status = smbXcli_negprot(cli->conn,
4391 if (!NT_STATUS_IS_OK(status)) {
4392 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4396 status = cli_session_setup_creds(cli, torture_creds);
4397 if (!NT_STATUS_IS_OK(status)) {
4398 printf("cli_session_setup returned %s\n", nt_errstr(status));
4402 status = cli_tree_connect(cli, share, "?????", NULL);
4403 if (!NT_STATUS_IS_OK(status)) {
4404 printf("cli_tree_connect returned %s\n", nt_errstr(status));
4408 dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4409 if (!dfs_supported) {
4410 printf("Server %s does not support DFS\n",
4411 smbXcli_conn_remote_name(cli->conn));
4414 /* Ensure this is *NOT* a DFS share. */
4415 dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4416 if (dfs_supported) {
4417 printf("Share %s is a DFS share.\n",
4422 * Force the share to be DFS, as far as the client
4425 smb2cli_tcon_set_values(cli->smb2.tcon,
4427 smb2cli_tcon_current_id(cli->smb2.tcon),
4429 smb2cli_tcon_flags(cli->smb2.tcon),
4430 smb2cli_tcon_capabilities(cli->smb2.tcon) |
4434 /* Come up with a "valid" SMB2 DFS name. */
4435 dfs_filename = talloc_asprintf(talloc_tos(),
4437 smbXcli_conn_remote_name(cli->conn),
4439 if (dfs_filename == NULL) {
4440 printf("Out of memory\n");
4444 /* Now try create dfs_filename. */
4445 status = smb2cli_create(cli->conn,
4450 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4451 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4452 SEC_STD_SYNCHRONIZE|
4455 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4456 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4457 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4458 FILE_CREATE, /* create_disposition, */
4459 0, /* create_options, */
4460 NULL, /* smb2_create_blobs *blobs */
4463 NULL, /* struct smb_create_returns * */
4464 talloc_tos(), /* mem_ctx. */
4465 NULL); /* struct smb2_create_blobs * */
4467 * Should fail with NT_STATUS_OBJECT_PATH_NOT_FOUND, as
4468 * even though we set the FLAGS2_DFS_PATHNAMES the server
4469 * knows this isn't a DFS share and so treats BAD\\BAD as
4470 * part of the filename.
4472 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4473 printf("%s:%d create of %s should fail "
4474 "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4482 * Prove we can still use non-DFS pathnames, even though
4483 * we are setting the FLAGS2_DFS_PATHNAMES in the SMB2
4486 status = smb2cli_create(cli->conn,
4491 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4492 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4493 SEC_STD_SYNCHRONIZE|
4496 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4497 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4498 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4499 FILE_CREATE, /* create_disposition, */
4500 0, /* create_options, */
4501 NULL, /* smb2_create_blobs *blobs */
4504 NULL, /* struct smb_create_returns * */
4505 talloc_tos(), /* mem_ctx. */
4506 NULL); /* struct smb2_create_blobs * */
4507 if (!NT_STATUS_IS_OK(status)) {
4508 printf("%s:%d smb2cli_create on %s returned %s\n",
4520 (void)smb2_dfs_delete(cli, dfs_filename);
4521 (void)smb2_dfs_delete(cli, "file");
4526 * Add a test that sends a non-DFS path and does not set the
4527 * SMB2 flag FLAGS2_DFS_PATHNAMES to a DFS
4528 * share. Windows passes this (it just treats the
4529 * pathnames as non-DFS).
4532 bool run_smb2_dfs_share_non_dfs_path(int dummy)
4534 struct cli_state *cli = NULL;
4536 bool dfs_supported = false;
4537 uint64_t fid_persistent = 0;
4538 uint64_t fid_volatile = 0;
4539 bool retval = false;
4540 char *dfs_filename = NULL;
4541 uint64_t root_ino = (uint64_t)-1;
4542 bool ino_matched = false;
4544 printf("Starting SMB2-DFS-SHARE-NON-DFS-PATH\n");
4546 if (!torture_init_connection(&cli)) {
4550 status = smbXcli_negprot(cli->conn,
4554 if (!NT_STATUS_IS_OK(status)) {
4555 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4559 status = cli_session_setup_creds(cli, torture_creds);
4560 if (!NT_STATUS_IS_OK(status)) {
4561 printf("cli_session_setup returned %s\n", nt_errstr(status));
4565 status = cli_tree_connect(cli, share, "?????", NULL);
4566 if (!NT_STATUS_IS_OK(status)) {
4567 printf("cli_tree_connect returned %s\n", nt_errstr(status));
4571 dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4572 if (!dfs_supported) {
4573 printf("Server %s does not support DFS\n",
4574 smbXcli_conn_remote_name(cli->conn));
4577 /* Ensure this is a DFS share. */
4578 dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4579 if (!dfs_supported) {
4580 printf("Share %s is not a DFS share.\n",
4584 /* Come up with a "valid" SMB2 DFS name. */
4585 dfs_filename = talloc_asprintf(talloc_tos(),
4587 smbXcli_conn_remote_name(cli->conn),
4589 if (dfs_filename == NULL) {
4590 printf("Out of memory\n");
4594 /* Get the root of the share ino. */
4595 status = get_smb2_inode(cli,
4598 if (!NT_STATUS_IS_OK(status)) {
4599 printf("%s:%d get_smb2_inode on %s returned %s\n",
4607 /* Create a dfs_filename. */
4608 status = smb2cli_create(cli->conn,
4613 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4614 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4615 SEC_STD_SYNCHRONIZE|
4618 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4619 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4620 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4621 FILE_CREATE, /* create_disposition, */
4622 0, /* create_options, */
4623 NULL, /* smb2_create_blobs *blobs */
4626 NULL, /* struct smb_create_returns * */
4627 talloc_tos(), /* mem_ctx. */
4628 NULL); /* struct smb2_create_blobs * */
4629 if (!NT_STATUS_IS_OK(status)) {
4630 printf("%s:%d smb2cli_create on %s returned %s\n",
4638 /* Close the handle we just opened. */
4639 smb2cli_close(cli->conn,
4651 * Force the share to be non-DFS, as far as the client
4654 smb2cli_tcon_set_values(cli->smb2.tcon,
4656 smb2cli_tcon_current_id(cli->smb2.tcon),
4658 smb2cli_tcon_flags(cli->smb2.tcon),
4659 smb2cli_tcon_capabilities(cli->smb2.tcon) &
4660 ~SMB2_SHARE_CAP_DFS,
4664 * Prove we can still use non-DFS pathnames on a DFS
4665 * share so long as we don't set the FLAGS2_DFS_PATHNAMES
4666 * in the SMB2 request.
4668 status = smb2cli_create(cli->conn,
4673 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4674 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4675 SEC_STD_SYNCHRONIZE|
4678 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4679 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4680 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4681 FILE_OPEN, /* create_disposition, */
4682 0, /* create_options, */
4683 NULL, /* smb2_create_blobs *blobs */
4686 NULL, /* struct smb_create_returns * */
4687 talloc_tos(), /* mem_ctx. */
4688 NULL); /* struct smb2_create_blobs * */
4689 if (!NT_STATUS_IS_OK(status)) {
4690 printf("%s:%d smb2cli_create on %s returned %s\n",
4699 * Show that now we're using non-DFS pathnames
4700 * on a DFS share, "" opens the root of the share.
4702 ino_matched = smb2_inode_matches(cli,
4707 printf("%s:%d Failed to match ino number for %s\n",
4718 if (fid_volatile != 0) {
4719 smb2cli_close(cli->conn,
4727 (void)smb2_dfs_delete(cli, "file");
4728 (void)smb2_dfs_delete(cli, dfs_filename);