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(
83 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
84 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
85 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
86 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
89 FILE_SHARE_DELETE, /* share_access, */
90 FILE_CREATE, /* create_disposition, */
91 FILE_DELETE_ON_CLOSE, /* create_options, */
92 NULL, /* smb2_create_blobs *blobs */
99 if (!NT_STATUS_IS_OK(status)) {
100 printf("smb2cli_create returned %s\n", nt_errstr(status));
104 status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
105 cli->smb2.tcon, strlen(hello), 0, fid_persistent,
106 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
107 if (!NT_STATUS_IS_OK(status)) {
108 printf("smb2cli_write returned %s\n", nt_errstr(status));
112 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
113 cli->smb2.tcon, fid_persistent, fid_volatile);
114 if (!NT_STATUS_IS_OK(status)) {
115 printf("smb2cli_flush returned %s\n", nt_errstr(status));
119 status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
120 cli->smb2.tcon, 0x10000, 0, fid_persistent,
122 talloc_tos(), &result, &nread);
123 if (!NT_STATUS_IS_OK(status)) {
124 printf("smb2cli_read returned %s\n", nt_errstr(status));
128 if (nread != strlen(hello)) {
129 printf("smb2cli_read returned %d bytes, expected %d\n",
130 (int)nread, (int)strlen(hello));
134 if (memcmp(hello, result, nread) != 0) {
135 printf("smb2cli_read returned '%s', expected '%s'\n",
140 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
141 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
142 if (!NT_STATUS_IS_OK(status)) {
143 printf("smb2cli_close returned %s\n", nt_errstr(status));
147 status = smb2cli_create(
153 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
154 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
157 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
158 0, /* file_attributes, */
161 FILE_SHARE_DELETE, /* share_access, */
162 FILE_OPEN, /* create_disposition, */
163 FILE_SYNCHRONOUS_IO_NONALERT|
164 FILE_DIRECTORY_FILE, /* create_options, */
165 NULL, /* smb2_create_blobs *blobs */
172 if (!NT_STATUS_IS_OK(status)) {
173 printf("smb2cli_create returned %s\n", nt_errstr(status));
177 status = smb2cli_query_directory(
178 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
179 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
180 talloc_tos(), &dir_data, &dir_data_length);
182 if (!NT_STATUS_IS_OK(status)) {
183 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
187 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
188 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
189 if (!NT_STATUS_IS_OK(status)) {
190 printf("smb2cli_close returned %s\n", nt_errstr(status));
194 saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
195 cli_state_save_tcon_share(cli, &saved_tcon, &saved_share);
196 cli->smb2.tcon = smbXcli_tcon_create(cli);
197 smb2cli_tcon_set_values(cli->smb2.tcon,
202 0, /* capabilities */
203 0 /* maximal_access */);
204 status = smb2cli_tdis(cli->conn,
208 cli_state_restore_tcon_share(cli, saved_tcon, saved_share);
209 if (!NT_STATUS_IS_OK(status)) {
210 printf("smb2cli_tdis returned %s\n", nt_errstr(status));
214 status = smb2cli_tdis(cli->conn,
218 if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
219 printf("2nd smb2cli_tdis returned %s\n", nt_errstr(status));
223 saved_uid = smb2cli_session_current_id(cli->smb2.session);
224 status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
225 if (!NT_STATUS_IS_OK(status)) {
226 printf("smb2cli_logoff returned %s\n", nt_errstr(status));
230 cli->smb2.session = smbXcli_session_create(cli, cli->conn);
231 if (cli->smb2.session == NULL) {
232 printf("smbXcli_session_create() returned NULL\n");
236 smb2cli_session_set_id_and_flags(cli->smb2.session, saved_uid, 0);
238 status = smb2cli_logoff(cli->conn, cli->timeout, cli->smb2.session);
239 if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
240 printf("2nd smb2cli_logoff returned %s\n", nt_errstr(status));
247 bool run_smb2_negprot(int dummy)
249 struct cli_state *cli;
251 enum protocol_types protocol;
252 const char *name = NULL;
254 printf("Starting SMB2-NEGPROT\n");
256 if (!torture_init_connection(&cli)) {
260 status = smbXcli_negprot(cli->conn, cli->timeout,
261 PROTOCOL_CORE, PROTOCOL_LATEST);
262 if (!NT_STATUS_IS_OK(status)) {
263 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
267 protocol = smbXcli_conn_protocol(cli->conn);
268 name = smb_protocol_types_string(protocol);
270 if (protocol >= PROTOCOL_SMB2_02) {
271 printf("Server supports %s\n", name);
273 printf("Server DOES NOT support SMB2, only %s\n", name);
277 status = smbXcli_negprot(cli->conn, cli->timeout,
279 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET) &&
280 !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED) &&
281 !NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_ABORTED)) {
282 printf("2nd smbXcli_negprot should disconnect - returned %s\n",
287 if (smbXcli_conn_is_connected(cli->conn)) {
288 printf("2nd smbXcli_negprot should disconnect "
289 "- still connected\n");
296 bool run_smb2_anonymous(int dummy)
298 struct cli_state *cli = NULL;
300 struct cli_credentials *anon_creds = NULL;
303 printf("Starting SMB2-ANONYMOUS\n");
305 if (!torture_init_connection(&cli)) {
309 status = smbXcli_negprot(cli->conn, cli->timeout,
310 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
311 if (!NT_STATUS_IS_OK(status)) {
312 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
316 anon_creds = cli_credentials_init_anon(talloc_tos());
317 if (anon_creds == NULL) {
318 printf("cli_credentials_init_anon failed\n");
322 status = cli_session_setup_creds(cli, anon_creds);
323 if (!NT_STATUS_IS_OK(status)) {
324 printf("cli_session_setup returned %s\n", nt_errstr(status));
328 guest = smbXcli_session_is_guest(cli->smb2.session);
330 printf("anonymous session should not have guest authentication\n");
337 bool run_smb2_session_reconnect(int dummy)
339 struct cli_state *cli1;
340 struct cli_state *cli2;
343 uint64_t fid_persistent, fid_volatile;
344 struct tevent_context *ev;
345 struct tevent_req *subreq;
346 DATA_BLOB in_blob = data_blob_null;
348 DATA_BLOB session_key;
349 struct auth_generic_state *auth_generic_state;
350 struct iovec *recv_iov;
351 const char *hello = "Hello, world\n";
355 printf("Starting SMB2-SESSION-RECONNECT\n");
357 if (!torture_init_connection(&cli1)) {
361 status = smbXcli_negprot(cli1->conn, cli1->timeout,
362 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
363 if (!NT_STATUS_IS_OK(status)) {
364 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
368 status = cli_session_setup_creds(cli1, torture_creds);
369 if (!NT_STATUS_IS_OK(status)) {
370 printf("cli_session_setup returned %s\n", nt_errstr(status));
374 status = cli_tree_connect(cli1, share, "?????", NULL);
375 if (!NT_STATUS_IS_OK(status)) {
376 printf("cli_tree_connect returned %s\n", nt_errstr(status));
380 status = smb2cli_create(
385 "session-reconnect.txt",
386 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
387 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
388 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
389 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
392 FILE_SHARE_DELETE, /* share_access, */
393 FILE_CREATE, /* create_disposition, */
394 FILE_DELETE_ON_CLOSE, /* create_options, */
395 NULL, /* smb2_create_blobs *blobs */
402 if (!NT_STATUS_IS_OK(status)) {
403 printf("smb2cli_create on cli1 %s\n", nt_errstr(status));
407 status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
408 cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
409 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
410 if (!NT_STATUS_IS_OK(status)) {
411 printf("smb2cli_write returned %s\n", nt_errstr(status));
415 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
416 cli1->smb2.tcon, fid_persistent, fid_volatile);
417 if (!NT_STATUS_IS_OK(status)) {
418 printf("smb2cli_flush returned %s\n", nt_errstr(status));
422 status = smb2cli_read(cli1->conn, cli1->timeout, cli1->smb2.session,
423 cli1->smb2.tcon, 0x10000, 0, fid_persistent,
425 talloc_tos(), &result, &nread);
426 if (!NT_STATUS_IS_OK(status)) {
427 printf("smb2cli_read returned %s\n", nt_errstr(status));
431 if (nread != strlen(hello)) {
432 printf("smb2cli_read returned %d bytes, expected %d\n",
433 (int)nread, (int)strlen(hello));
437 if (memcmp(hello, result, nread) != 0) {
438 printf("smb2cli_read returned '%s', expected '%s'\n",
443 /* prepare second session */
445 if (!torture_init_connection(&cli2)) {
449 status = smbXcli_negprot(cli2->conn, cli2->timeout,
450 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
451 if (!NT_STATUS_IS_OK(status)) {
452 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
456 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
457 if (!NT_STATUS_IS_OK(status)) {
458 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
462 gensec_want_feature(auth_generic_state->gensec_security,
463 GENSEC_FEATURE_SESSION_KEY);
465 status = auth_generic_set_creds(auth_generic_state, torture_creds);
466 if (!NT_STATUS_IS_OK(status)) {
467 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
471 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
472 if (!NT_STATUS_IS_OK(status)) {
473 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
477 ev = samba_tevent_context_init(talloc_tos());
479 printf("samba_tevent_context_init() returned NULL\n");
483 status = gensec_update(auth_generic_state->gensec_security,
484 talloc_tos(), data_blob_null, &in_blob);
485 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
486 printf("gensec_update returned %s\n", nt_errstr(status));
490 cli2->smb2.session = smbXcli_session_create(cli2, cli2->conn);
492 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
497 SMB2_CAP_DFS, /* in_capabilities */
499 /* in_previous_session_id: */
500 smb2cli_session_current_id(cli1->smb2.session),
501 &in_blob); /* in_security_buffer */
502 if (subreq == NULL) {
503 printf("smb2cli_session_setup_send() returned NULL\n");
507 ok = tevent_req_poll(subreq, ev);
509 printf("tevent_req_poll() returned false\n");
513 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
515 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
516 printf("smb2cli_session_setup_recv returned %s\n",
521 status = gensec_update(auth_generic_state->gensec_security,
522 talloc_tos(), out_blob, &in_blob);
523 if (!NT_STATUS_IS_OK(status)) {
524 printf("auth_generic_update returned %s\n", nt_errstr(status));
528 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
533 SMB2_CAP_DFS, /* in_capabilities */
535 /* in_previous_session_id: */
536 smb2cli_session_current_id(cli1->smb2.session),
537 &in_blob); /* in_security_buffer */
538 if (subreq == NULL) {
539 printf("smb2cli_session_setup_send() returned NULL\n");
543 ok = tevent_req_poll(subreq, ev);
545 printf("tevent_req_poll() returned false\n");
549 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
550 &recv_iov, &out_blob);
551 if (!NT_STATUS_IS_OK(status)) {
552 printf("smb2cli_session_setup_recv returned %s\n",
557 status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
559 if (!NT_STATUS_IS_OK(status)) {
560 printf("gensec_session_key returned %s\n",
565 /* check file operation on the old client */
567 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
568 cli1->smb2.tcon, fid_persistent, fid_volatile);
569 if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
570 printf("smb2cli_flush returned %s\n", nt_errstr(status));
574 status = cli_tree_connect(cli1, share, "?????", NULL);
575 if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
576 printf("cli_tree_connect returned %s\n", nt_errstr(status));
581 * checking file operations without signing.
582 * on w2k8r2 at least, flush, read and write also work the same way,
583 * while create gives ACCESS_DENIED without signing
585 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
586 cli2->smb2.tcon, fid_persistent, fid_volatile);
587 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
588 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
590 printf("smb2cli_flush returned %s\n", nt_errstr(status));
594 status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
595 cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
596 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
597 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
598 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
600 printf("smb2cli_write returned %s\n", nt_errstr(status));
604 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
605 cli2->smb2.tcon, 0x10000, 0, fid_persistent,
607 talloc_tos(), &result, &nread);
608 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
609 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
611 printf("smb2cli_read returned %s\n", nt_errstr(status));
615 status = smb2cli_create(
620 "session-reconnect.txt",
621 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
622 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
623 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
624 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
627 FILE_SHARE_DELETE, /* share_access, */
628 FILE_CREATE, /* create_disposition, */
629 FILE_DELETE_ON_CLOSE, /* create_options, */
630 NULL, /* smb2_create_blobs *blobs */
637 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
638 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
639 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
643 /* now grab the session key and try with signing */
645 status = smb2cli_session_set_session_key(cli2->smb2.session,
648 if (!NT_STATUS_IS_OK(status)) {
649 printf("smb2cli_session_set_session_key %s\n", nt_errstr(status));
653 /* the tid seems to be irrelevant at this stage */
655 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
656 cli1->smb2.tcon, fid_persistent, fid_volatile);
657 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
658 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
660 printf("smb2cli_flush returned %s\n", nt_errstr(status));
664 status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
665 cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
666 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
667 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
668 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
670 printf("smb2cli_write returned %s\n", nt_errstr(status));
674 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
675 cli1->smb2.tcon, 0x10000, 0, fid_persistent,
677 talloc_tos(), &result, &nread);
678 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) &&
679 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
681 printf("smb2cli_read returned %s\n", nt_errstr(status));
685 status = smb2cli_create(
690 "session-reconnect.txt",
691 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
692 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
693 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
694 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
697 FILE_SHARE_DELETE, /* share_access, */
698 FILE_CREATE, /* create_disposition, */
699 FILE_DELETE_ON_CLOSE, /* create_options, */
700 NULL, /* smb2_create_blobs *blobs */
707 if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) &&
708 !NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED))
710 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
714 /* now do a new tcon and test file calls again */
716 status = cli_tree_connect(cli2, share, "?????", NULL);
717 if (!NT_STATUS_IS_OK(status)) {
718 printf("cli_tree_connect returned %s\n", nt_errstr(status));
722 status = smb2cli_create(
727 "session-reconnect.txt",
728 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
729 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
730 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
731 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
734 FILE_SHARE_DELETE, /* share_access, */
735 FILE_CREATE, /* create_disposition, */
736 FILE_DELETE_ON_CLOSE, /* create_options, */
737 NULL, /* smb2_create_blobs *blobs */
744 if (!NT_STATUS_IS_OK(status)) {
745 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
749 status = smb2cli_write(cli2->conn, cli2->timeout, cli2->smb2.session,
750 cli2->smb2.tcon, strlen(hello), 0, fid_persistent,
751 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
752 if (!NT_STATUS_IS_OK(status)) {
753 printf("smb2cli_write returned %s\n", nt_errstr(status));
757 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
758 cli2->smb2.tcon, fid_persistent, fid_volatile);
759 if (!NT_STATUS_IS_OK(status)) {
760 printf("smb2cli_flush returned %s\n", nt_errstr(status));
764 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
765 cli2->smb2.tcon, 0x10000, 0, fid_persistent,
767 talloc_tos(), &result, &nread);
768 if (!NT_STATUS_IS_OK(status)) {
769 printf("smb2cli_read returned %s\n", nt_errstr(status));
773 if (nread != strlen(hello)) {
774 printf("smb2cli_read returned %d bytes, expected %d\n",
775 (int)nread, (int)strlen(hello));
779 if (memcmp(hello, result, nread) != 0) {
780 printf("smb2cli_read returned '%s', expected '%s'\n",
788 bool run_smb2_tcon_dependence(int dummy)
790 struct cli_state *cli;
792 uint64_t fid_persistent, fid_volatile;
793 const char *hello = "Hello, world\n";
796 struct smbXcli_tcon *tcon2;
799 printf("Starting SMB2-TCON-DEPENDENCE\n");
801 if (!torture_init_connection(&cli)) {
805 status = smbXcli_negprot(cli->conn, cli->timeout,
806 PROTOCOL_SMB2_02, PROTOCOL_LATEST);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
812 status = cli_session_setup_creds(cli, torture_creds);
813 if (!NT_STATUS_IS_OK(status)) {
814 printf("cli_session_setup returned %s\n", nt_errstr(status));
818 status = cli_tree_connect(cli, share, "?????", NULL);
819 if (!NT_STATUS_IS_OK(status)) {
820 printf("cli_tree_connect returned %s\n", nt_errstr(status));
824 status = smb2cli_create(
829 "tcon_depedence.txt",
830 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
831 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
832 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
833 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
836 FILE_SHARE_DELETE, /* share_access, */
837 FILE_CREATE, /* create_disposition, */
838 FILE_DELETE_ON_CLOSE, /* create_options, */
839 NULL, /* smb2_create_blobs *blobs */
846 if (!NT_STATUS_IS_OK(status)) {
847 printf("smb2cli_create on cli %s\n", nt_errstr(status));
851 status = smb2cli_write(cli->conn, cli->timeout, cli->smb2.session,
852 cli->smb2.tcon, strlen(hello), 0, fid_persistent,
853 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
854 if (!NT_STATUS_IS_OK(status)) {
855 printf("smb2cli_write returned %s\n", nt_errstr(status));
859 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
860 cli->smb2.tcon, fid_persistent, fid_volatile);
861 if (!NT_STATUS_IS_OK(status)) {
862 printf("smb2cli_flush returned %s\n", nt_errstr(status));
866 status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
867 cli->smb2.tcon, 0x10000, 0, fid_persistent,
869 talloc_tos(), &result, &nread);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("smb2cli_read returned %s\n", nt_errstr(status));
875 if (nread != strlen(hello)) {
876 printf("smb2cli_read returned %d bytes, expected %d\n",
877 (int)nread, (int)strlen(hello));
881 if (memcmp(hello, result, nread) != 0) {
882 printf("smb2cli_read returned '%s', expected '%s'\n",
887 /* check behaviour with wrong tid... */
889 tcon2 = smbXcli_tcon_create(cli);
890 tcon2_id = smb2cli_tcon_current_id(cli->smb2.tcon);
892 smb2cli_tcon_set_values(tcon2,
897 0, /* capabilities */
898 0 /* maximal_access */);
900 status = smb2cli_read(cli->conn, cli->timeout, cli->smb2.session,
901 tcon2, 0x10000, 0, fid_persistent,
903 talloc_tos(), &result, &nread);
904 if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
905 printf("smb2cli_read returned %s\n", nt_errstr(status));
914 bool run_smb2_multi_channel(int dummy)
916 struct cli_state *cli1;
917 struct cli_state *cli2;
918 struct cli_state *cli3;
921 uint64_t fid_persistent, fid_volatile;
922 struct tevent_context *ev;
923 struct tevent_req *subreq;
924 DATA_BLOB in_blob = data_blob_null;
926 DATA_BLOB channel_session_key;
927 struct auth_generic_state *auth_generic_state;
928 struct iovec *recv_iov;
929 const char *hello = "Hello, world\n";
932 struct GUID saved_guid = cli_state_client_guid;
934 printf("Starting SMB2-MULTI-CHANNEL\n");
936 cli_state_client_guid = GUID_random();
938 if (!torture_init_connection(&cli1)) {
942 if (!torture_init_connection(&cli2)) {
946 if (!torture_init_connection(&cli3)) {
950 cli_state_client_guid = saved_guid;
952 status = smbXcli_negprot(cli1->conn, cli1->timeout,
953 PROTOCOL_SMB3_00, PROTOCOL_LATEST);
954 if (!NT_STATUS_IS_OK(status)) {
955 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
959 status = smbXcli_negprot(cli2->conn, cli2->timeout,
960 PROTOCOL_SMB3_00, PROTOCOL_LATEST);
961 if (!NT_STATUS_IS_OK(status)) {
962 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
966 status = smbXcli_negprot(cli3->conn, cli3->timeout,
967 PROTOCOL_SMB3_00, PROTOCOL_LATEST);
968 if (!NT_STATUS_IS_OK(status)) {
969 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
973 status = cli_session_setup_creds(cli1, torture_creds);
974 if (!NT_STATUS_IS_OK(status)) {
975 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
979 status = cli_tree_connect(cli1, share, "?????", NULL);
980 if (!NT_STATUS_IS_OK(status)) {
981 printf("cli_tree_connect returned %s\n", nt_errstr(status));
985 status = smb2cli_session_create_channel(cli2,
988 &cli2->smb2.session);
989 if (!NT_STATUS_IS_OK(status)) {
990 printf("smb2cli_session_create_channel returned %s\n",
995 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
996 if (!NT_STATUS_IS_OK(status)) {
997 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1001 gensec_want_feature(auth_generic_state->gensec_security,
1002 GENSEC_FEATURE_SESSION_KEY);
1004 status = auth_generic_set_creds(auth_generic_state, torture_creds);
1005 if (!NT_STATUS_IS_OK(status)) {
1006 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1010 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1016 ev = samba_tevent_context_init(talloc_tos());
1018 printf("samba_tevent_context_init() returned NULL\n");
1022 status = gensec_update(auth_generic_state->gensec_security,
1023 talloc_tos(), data_blob_null, &in_blob);
1024 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1025 printf("gensec_update returned %s\n", nt_errstr(status));
1029 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1033 0x01, /* in_flags */
1034 SMB2_CAP_DFS, /* in_capabilities */
1036 0, /* in_previous_session_id */
1037 &in_blob); /* in_security_buffer */
1038 if (subreq == NULL) {
1039 printf("smb2cli_session_setup_send() returned NULL\n");
1043 ok = tevent_req_poll(subreq, ev);
1045 printf("tevent_req_poll() returned false\n");
1049 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1051 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1052 printf("smb2cli_session_setup_recv returned %s\n",
1057 status = gensec_update(auth_generic_state->gensec_security,
1058 talloc_tos(), out_blob, &in_blob);
1059 if (!NT_STATUS_IS_OK(status)) {
1060 printf("auth_generic_update returned %s\n", nt_errstr(status));
1064 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1068 0x01, /* in_flags */
1069 SMB2_CAP_DFS, /* in_capabilities */
1071 0, /* in_previous_session_id */
1072 &in_blob); /* in_security_buffer */
1073 if (subreq == NULL) {
1074 printf("smb2cli_session_setup_send() returned NULL\n");
1078 ok = tevent_req_poll(subreq, ev);
1080 printf("tevent_req_poll() returned false\n");
1084 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1085 &recv_iov, &out_blob);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 printf("smb2cli_session_setup_recv returned %s\n",
1092 status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1093 &channel_session_key);
1094 if (!NT_STATUS_IS_OK(status)) {
1095 printf("gensec_session_key returned %s\n",
1100 status = smb2cli_session_set_channel_key(cli2->smb2.session,
1101 channel_session_key,
1103 if (!NT_STATUS_IS_OK(status)) {
1104 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1108 status = smb2cli_session_create_channel(cli3,
1111 &cli3->smb2.session);
1112 if (!NT_STATUS_IS_OK(status)) {
1113 printf("smb2cli_session_create_channel returned %s\n",
1118 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1119 if (!NT_STATUS_IS_OK(status)) {
1120 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1124 gensec_want_feature(auth_generic_state->gensec_security,
1125 GENSEC_FEATURE_SESSION_KEY);
1127 status = auth_generic_set_creds(auth_generic_state, torture_creds);
1128 if (!NT_STATUS_IS_OK(status)) {
1129 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1133 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1134 if (!NT_STATUS_IS_OK(status)) {
1135 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1139 status = gensec_update(auth_generic_state->gensec_security,
1140 talloc_tos(), data_blob_null, &in_blob);
1141 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1142 printf("gensec_update returned %s\n", nt_errstr(status));
1146 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1150 0x01, /* in_flags */
1151 SMB2_CAP_DFS, /* in_capabilities */
1153 0, /* in_previous_session_id */
1154 &in_blob); /* in_security_buffer */
1155 if (subreq == NULL) {
1156 printf("smb2cli_session_setup_send() returned NULL\n");
1160 ok = tevent_req_poll(subreq, ev);
1162 printf("tevent_req_poll() returned false\n");
1166 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1168 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1169 printf("smb2cli_session_setup_recv returned %s\n",
1174 status = gensec_update(auth_generic_state->gensec_security,
1175 talloc_tos(), out_blob, &in_blob);
1176 if (!NT_STATUS_IS_OK(status)) {
1177 printf("auth_generic_update returned %s\n", nt_errstr(status));
1181 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1185 0x01, /* in_flags */
1186 SMB2_CAP_DFS, /* in_capabilities */
1188 0, /* in_previous_session_id */
1189 &in_blob); /* in_security_buffer */
1190 if (subreq == NULL) {
1191 printf("smb2cli_session_setup_send() returned NULL\n");
1195 ok = tevent_req_poll(subreq, ev);
1197 printf("tevent_req_poll() returned false\n");
1201 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1202 &recv_iov, &out_blob);
1203 if (!NT_STATUS_IS_OK(status)) {
1204 printf("smb2cli_session_setup_recv returned %s\n",
1209 status = gensec_session_key(auth_generic_state->gensec_security, talloc_tos(),
1210 &channel_session_key);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 printf("gensec_session_key returned %s\n",
1217 status = smb2cli_session_set_channel_key(cli3->smb2.session,
1218 channel_session_key,
1220 if (!NT_STATUS_IS_OK(status)) {
1221 printf("smb2cli_session_set_channel_key %s\n", nt_errstr(status));
1225 status = smb2cli_create(
1230 "multi-channel.txt",
1231 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1232 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1233 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1234 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1237 FILE_SHARE_DELETE, /* share_access, */
1238 FILE_CREATE, /* create_disposition, */
1239 FILE_DELETE_ON_CLOSE, /* create_options, */
1240 NULL, /* smb2_create_blobs *blobs */
1247 if (!NT_STATUS_IS_OK(status)) {
1248 printf("smb2cli_create on cli2 %s\n", nt_errstr(status));
1252 status = smb2cli_write(cli1->conn, cli1->timeout, cli1->smb2.session,
1253 cli1->smb2.tcon, strlen(hello), 0, fid_persistent,
1254 fid_volatile, 0, 0, (const uint8_t *)hello, NULL);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 printf("smb2cli_write returned %s\n", nt_errstr(status));
1260 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1261 cli1->smb2.tcon, fid_persistent, fid_volatile);
1262 if (!NT_STATUS_IS_OK(status)) {
1263 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1267 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1268 cli1->smb2.tcon, fid_persistent, fid_volatile);
1269 if (!NT_STATUS_IS_OK(status)) {
1270 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1274 status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1275 cli1->smb2.tcon, fid_persistent, fid_volatile);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1281 status = smb2cli_read(cli2->conn, cli2->timeout, cli2->smb2.session,
1282 cli1->smb2.tcon, 0x10000, 0, fid_persistent,
1284 talloc_tos(), &result, &nread);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 printf("smb2cli_read returned %s\n", nt_errstr(status));
1290 if (nread != strlen(hello)) {
1291 printf("smb2cli_read returned %d bytes, expected %d\n",
1292 (int)nread, (int)strlen(hello));
1296 if (memcmp(hello, result, nread) != 0) {
1297 printf("smb2cli_read returned '%s', expected '%s'\n",
1302 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1303 if (!NT_STATUS_IS_OK(status)) {
1304 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1308 gensec_want_feature(auth_generic_state->gensec_security,
1309 GENSEC_FEATURE_SESSION_KEY);
1311 status = auth_generic_set_creds(auth_generic_state, torture_creds);
1312 if (!NT_STATUS_IS_OK(status)) {
1313 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1317 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1323 status = gensec_update(auth_generic_state->gensec_security,
1324 talloc_tos(), data_blob_null, &in_blob);
1325 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1326 printf("gensec_update returned %s\n", nt_errstr(status));
1330 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1335 SMB2_CAP_DFS, /* in_capabilities */
1337 0, /* in_previous_session_id */
1338 &in_blob); /* in_security_buffer */
1339 if (subreq == NULL) {
1340 printf("smb2cli_session_setup_send() returned NULL\n");
1344 ok = tevent_req_poll(subreq, ev);
1346 printf("tevent_req_poll() returned false\n");
1350 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1352 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1353 printf("smb2cli_session_setup_recv returned %s\n",
1358 status = gensec_update(auth_generic_state->gensec_security,
1359 talloc_tos(), out_blob, &in_blob);
1360 if (!NT_STATUS_IS_OK(status)) {
1361 printf("auth_generic_update returned %s\n", nt_errstr(status));
1365 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1366 cli1->smb2.tcon, fid_persistent, fid_volatile);
1367 if (!NT_STATUS_IS_OK(status)) {
1368 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1372 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1373 cli1->smb2.tcon, fid_persistent, fid_volatile);
1374 if (!NT_STATUS_IS_OK(status)) {
1375 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1379 status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1380 cli1->smb2.tcon, fid_persistent, fid_volatile);
1381 if (!NT_STATUS_IS_OK(status)) {
1382 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1386 status = smb2cli_create(
1391 "multi-channel-invalid.txt",
1392 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1393 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1394 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1395 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1398 FILE_SHARE_DELETE, /* share_access, */
1399 FILE_CREATE, /* create_disposition, */
1400 FILE_DELETE_ON_CLOSE, /* create_options, */
1401 NULL, /* smb2_create_blobs *blobs */
1408 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1409 printf("smb2cli_create %s\n", nt_errstr(status));
1413 status = smb2cli_create(
1418 "multi-channel-invalid.txt",
1419 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1420 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1421 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1422 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1425 FILE_SHARE_DELETE, /* share_access, */
1426 FILE_CREATE, /* create_disposition, */
1427 FILE_DELETE_ON_CLOSE, /* create_options, */
1428 NULL, /* smb2_create_blobs *blobs */
1435 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1436 printf("smb2cli_create %s\n", nt_errstr(status));
1440 status = smb2cli_create(
1445 "multi-channel-invalid.txt",
1446 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1447 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1448 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1449 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1452 FILE_SHARE_DELETE, /* share_access, */
1453 FILE_CREATE, /* create_disposition, */
1454 FILE_DELETE_ON_CLOSE, /* create_options, */
1455 NULL, /* smb2_create_blobs *blobs */
1462 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1463 printf("smb2cli_create %s\n", nt_errstr(status));
1467 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1472 SMB2_CAP_DFS, /* in_capabilities */
1474 0, /* in_previous_session_id */
1475 &in_blob); /* in_security_buffer */
1476 if (subreq == NULL) {
1477 printf("smb2cli_session_setup_send() returned NULL\n");
1481 ok = tevent_req_poll(subreq, ev);
1483 printf("tevent_req_poll() returned false\n");
1487 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1488 &recv_iov, &out_blob);
1489 if (!NT_STATUS_IS_OK(status)) {
1490 printf("smb2cli_session_setup_recv returned %s\n",
1495 status = smb2cli_close(cli3->conn, cli3->timeout, cli3->smb2.session,
1496 cli1->smb2.tcon, 0, fid_persistent, fid_volatile);
1497 if (!NT_STATUS_IS_OK(status)) {
1498 printf("smb2cli_close returned %s\n", nt_errstr(status));
1502 status = smb2cli_flush(cli3->conn, cli3->timeout, cli3->smb2.session,
1503 cli1->smb2.tcon, fid_persistent, fid_volatile);
1504 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1505 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1509 status = smb2cli_flush(cli2->conn, cli2->timeout, cli2->smb2.session,
1510 cli1->smb2.tcon, fid_persistent, fid_volatile);
1511 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1512 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1516 status = smb2cli_flush(cli1->conn, cli1->timeout, cli1->smb2.session,
1517 cli1->smb2.tcon, fid_persistent, fid_volatile);
1518 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
1519 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1526 bool run_smb2_session_reauth(int dummy)
1528 struct cli_state *cli;
1531 uint64_t fid_persistent, fid_volatile;
1532 uint64_t dir_persistent, dir_volatile;
1534 uint32_t dir_data_length;
1535 struct tevent_context *ev;
1536 struct tevent_req *subreq;
1537 DATA_BLOB in_blob = data_blob_null;
1539 DATA_BLOB in_input_buffer;
1540 DATA_BLOB out_output_buffer;
1541 uint8_t in_file_info_class;
1542 struct auth_generic_state *auth_generic_state;
1543 struct iovec *recv_iov;
1545 struct smbXcli_tcon *saved_tcon;
1547 printf("Starting SMB2-SESSION_REAUTH\n");
1549 if (!torture_init_connection(&cli)) {
1554 * PROTOCOL_SMB2_22 has a bug in win8pre0
1555 * it behaves like PROTOCOL_SMB2_02
1556 * and returns NT_STATUS_REQUEST_NOT_ACCEPTED,
1557 * while it allows it on PROTOCOL_SMB2_10.
1559 status = smbXcli_negprot(cli->conn, cli->timeout,
1560 PROTOCOL_SMB2_10, PROTOCOL_SMB2_10);
1561 if (!NT_STATUS_IS_OK(status)) {
1562 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
1566 status = cli_session_setup_creds(cli, torture_creds);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
1572 status = cli_tree_connect(cli, share, "?????", NULL);
1573 if (!NT_STATUS_IS_OK(status)) {
1574 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1578 status = smb2cli_create(
1583 "session-reauth.txt",
1584 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1585 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1586 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1587 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1590 FILE_SHARE_DELETE, /* share_access, */
1591 FILE_CREATE, /* create_disposition, */
1592 FILE_DELETE_ON_CLOSE, /* create_options, */
1593 NULL, /* smb2_create_blobs *blobs */
1600 if (!NT_STATUS_IS_OK(status)) {
1601 printf("smb2cli_create %s\n", nt_errstr(status));
1605 status = smb2cli_create(
1611 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1612 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1613 SEC_STD_SYNCHRONIZE|
1615 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1616 0, /* file_attributes, */
1619 FILE_SHARE_DELETE, /* share_access, */
1620 FILE_OPEN, /* create_disposition, */
1621 FILE_SYNCHRONOUS_IO_NONALERT|
1622 FILE_DIRECTORY_FILE, /* create_options, */
1623 NULL, /* smb2_create_blobs *blobs */
1630 if (!NT_STATUS_IS_OK(status)) {
1631 printf("smb2cli_create returned %s\n", nt_errstr(status));
1635 status = smb2cli_query_directory(
1636 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1637 1, 0x3, 0, dir_persistent, dir_volatile,
1638 "session-reauth.txt", 0xffff,
1639 talloc_tos(), &dir_data, &dir_data_length);
1640 if (!NT_STATUS_IS_OK(status)) {
1641 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1645 status = auth_generic_client_prepare(talloc_tos(), &auth_generic_state);
1646 if (!NT_STATUS_IS_OK(status)) {
1647 printf("auth_generic_client_prepare returned %s\n", nt_errstr(status));
1651 gensec_want_feature(auth_generic_state->gensec_security,
1652 GENSEC_FEATURE_SESSION_KEY);
1654 status = auth_generic_set_creds(auth_generic_state, torture_creds);
1655 if (!NT_STATUS_IS_OK(status)) {
1656 printf("auth_generic_set_creds returned %s\n", nt_errstr(status));
1660 status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
1661 if (!NT_STATUS_IS_OK(status)) {
1662 printf("auth_generic_client_start returned %s\n", nt_errstr(status));
1666 ev = samba_tevent_context_init(talloc_tos());
1668 printf("samba_tevent_context_init() returned NULL\n");
1672 status = gensec_update(auth_generic_state->gensec_security,
1673 talloc_tos(), data_blob_null, &in_blob);
1674 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1675 printf("gensec_update returned %s\n", nt_errstr(status));
1679 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1684 SMB2_CAP_DFS, /* in_capabilities */
1686 0, /* in_previous_session_id */
1687 &in_blob); /* in_security_buffer */
1688 if (subreq == NULL) {
1689 printf("smb2cli_session_setup_send() returned NULL\n");
1693 ok = tevent_req_poll(subreq, ev);
1695 printf("tevent_req_poll() returned false\n");
1699 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1701 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1702 printf("smb2cli_session_setup_recv returned %s\n",
1707 status = gensec_update(auth_generic_state->gensec_security,
1708 talloc_tos(), out_blob, &in_blob);
1709 if (!NT_STATUS_IS_OK(status)) {
1710 printf("auth_generic_update returned %s\n", nt_errstr(status));
1714 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1715 cli->smb2.tcon, fid_persistent, fid_volatile);
1716 if (!NT_STATUS_IS_OK(status)) {
1717 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1721 status = smb2cli_query_directory(
1722 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
1723 1, 0x3, 0, dir_persistent, dir_volatile,
1724 "session-reauth.txt", 0xffff,
1725 talloc_tos(), &dir_data, &dir_data_length);
1726 if (!NT_STATUS_IS_OK(status)) {
1727 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
1732 * query_info seems to be a path based operation on Windows...
1734 status = smb2cli_query_info(cli->conn,
1738 SMB2_0_INFO_SECURITY,
1739 0, /* in_file_info_class */
1740 1024, /* in_max_output_length */
1741 NULL, /* in_input_buffer */
1742 SECINFO_OWNER, /* in_additional_info */
1747 &out_output_buffer);
1748 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1749 printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1753 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1754 status = smb2cli_query_info(cli->conn,
1760 1024, /* in_max_output_length */
1761 NULL, /* in_input_buffer */
1762 0, /* in_additional_info */
1767 &out_output_buffer);
1768 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1769 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1773 in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1774 SBVAL(in_input_buffer.data, 0, 512);
1776 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1777 status = smb2cli_set_info(cli->conn,
1784 0, /* in_additional_info */
1787 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1788 printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1792 status = smb2cli_create(
1797 "session-reauth-invalid.txt",
1798 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1799 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1800 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1801 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1804 FILE_SHARE_DELETE, /* share_access, */
1805 FILE_CREATE, /* create_disposition, */
1806 FILE_DELETE_ON_CLOSE, /* create_options, */
1807 NULL, /* smb2_create_blobs *blobs */
1814 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1815 printf("smb2cli_create %s\n", nt_errstr(status));
1819 status = smb2cli_create(
1825 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1826 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1827 SEC_STD_SYNCHRONIZE|
1829 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
1830 0, /* file_attributes, */
1833 FILE_SHARE_DELETE, /* share_access, */
1834 FILE_OPEN, /* create_disposition, */
1835 FILE_SYNCHRONOUS_IO_NONALERT|
1836 FILE_DIRECTORY_FILE, /* create_options, */
1837 NULL, /* smb2_create_blobs *blobs */
1844 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1845 printf("smb2cli_create returned %s\n", nt_errstr(status));
1849 saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
1850 saved_tcon = cli->smb2.tcon;
1851 cli->smb2.tcon = smbXcli_tcon_create(cli);
1852 smb2cli_tcon_set_values(cli->smb2.tcon,
1857 0, /* capabilities */
1858 0 /* maximal_access */);
1859 status = cli_tree_connect(cli, share, "?????", NULL);
1860 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1861 printf("cli_tree_connect returned %s\n", nt_errstr(status));
1864 talloc_free(cli->smb2.tcon);
1865 cli->smb2.tcon = saved_tcon;
1867 subreq = smb2cli_session_setup_send(talloc_tos(), ev,
1872 SMB2_CAP_DFS, /* in_capabilities */
1874 0, /* in_previous_session_id */
1875 &in_blob); /* in_security_buffer */
1876 if (subreq == NULL) {
1877 printf("smb2cli_session_setup_send() returned NULL\n");
1881 ok = tevent_req_poll(subreq, ev);
1883 printf("tevent_req_poll() returned false\n");
1887 status = smb2cli_session_setup_recv(subreq, talloc_tos(),
1888 &recv_iov, &out_blob);
1889 if (!NT_STATUS_IS_OK(status)) {
1890 printf("smb2cli_session_setup_recv returned %s\n",
1895 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
1896 cli->smb2.tcon, fid_persistent, fid_volatile);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 printf("smb2cli_flush returned %s\n", nt_errstr(status));
1902 status = smb2cli_query_info(cli->conn,
1906 SMB2_0_INFO_SECURITY,
1907 0, /* in_file_info_class */
1908 1024, /* in_max_output_length */
1909 NULL, /* in_input_buffer */
1910 SECINFO_OWNER, /* in_additional_info */
1915 &out_output_buffer);
1916 if (!NT_STATUS_IS_OK(status)) {
1917 printf("smb2cli_query_info (security) returned %s\n", nt_errstr(status));
1921 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1922 status = smb2cli_query_info(cli->conn,
1928 1024, /* in_max_output_length */
1929 NULL, /* in_input_buffer */
1930 0, /* in_additional_info */
1935 &out_output_buffer);
1936 if (!NT_STATUS_IS_OK(status)) {
1937 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1941 in_input_buffer = data_blob_talloc(talloc_tos(), NULL, 8);
1942 SBVAL(in_input_buffer.data, 0, 512);
1944 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1945 status = smb2cli_set_info(cli->conn,
1952 0, /* in_additional_info */
1955 if (!NT_STATUS_IS_OK(status)) {
1956 printf("smb2cli_set_info (position) returned %s\n", nt_errstr(status));
1960 in_file_info_class = SMB_FILE_POSITION_INFORMATION - 1000;
1961 status = smb2cli_query_info(cli->conn,
1967 1024, /* in_max_output_length */
1968 NULL, /* in_input_buffer */
1969 0, /* in_additional_info */
1974 &out_output_buffer);
1975 if (!NT_STATUS_IS_OK(status)) {
1976 printf("smb2cli_query_info (position) returned %s\n", nt_errstr(status));
1980 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
1981 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
1982 if (!NT_STATUS_IS_OK(status)) {
1983 printf("smb2cli_close returned %s\n", nt_errstr(status));
1987 status = smb2cli_create(
1992 "session-reauth.txt",
1993 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
1994 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
1995 SEC_STD_ALL | SEC_FILE_ALL, /* desired_access, */
1996 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
1999 FILE_SHARE_DELETE, /* share_access, */
2000 FILE_CREATE, /* create_disposition, */
2001 FILE_DELETE_ON_CLOSE, /* create_options, */
2002 NULL, /* smb2_create_blobs *blobs */
2009 if (!NT_STATUS_IS_OK(status)) {
2010 printf("smb2cli_create %s\n", nt_errstr(status));
2014 status = smb2cli_query_directory(
2015 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2016 1, 0x3, 0, dir_persistent, dir_volatile,
2017 "session-reauth.txt", 0xffff,
2018 talloc_tos(), &dir_data, &dir_data_length);
2019 if (!NT_STATUS_IS_OK(status)) {
2020 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2024 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2025 cli->smb2.tcon, 0, dir_persistent, dir_volatile);
2026 if (!NT_STATUS_IS_OK(status)) {
2027 printf("smb2cli_close returned %s\n", nt_errstr(status));
2031 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2032 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2033 if (!NT_STATUS_IS_OK(status)) {
2034 printf("smb2cli_close returned %s\n", nt_errstr(status));
2038 saved_tid = smb2cli_tcon_current_id(cli->smb2.tcon);
2039 saved_tcon = cli->smb2.tcon;
2040 cli->smb2.tcon = smbXcli_tcon_create(cli);
2041 smb2cli_tcon_set_values(cli->smb2.tcon,
2046 0, /* capabilities */
2047 0 /* maximal_access */);
2048 status = cli_tree_connect(cli, share, "?????", NULL);
2049 if (!NT_STATUS_IS_OK(status)) {
2050 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2053 talloc_free(cli->smb2.tcon);
2054 cli->smb2.tcon = saved_tcon;
2059 static NTSTATUS check_size(struct cli_state *cli,
2064 off_t size_read = 0;
2066 NTSTATUS status = cli_qfileinfo_basic(cli,
2076 if (!NT_STATUS_IS_OK(status)) {
2077 printf("cli_qfileinfo_basic of %s failed (%s)\n",
2083 if (size != size_read) {
2084 printf("size (%u) != size_read(%u) for %s\n",
2086 (unsigned int)size_read,
2088 /* Use EOF to mean bad size. */
2089 return NT_STATUS_END_OF_FILE;
2091 return NT_STATUS_OK;
2094 /* Ensure cli_ftruncate() works for SMB2. */
2096 bool run_smb2_ftruncate(int dummy)
2098 struct cli_state *cli = NULL;
2099 const char *fname = "smb2_ftruncate.txt";
2100 uint16_t fnum = (uint16_t)-1;
2101 bool correct = false;
2102 size_t buflen = 1024*1024;
2103 uint8_t *buf = NULL;
2107 printf("Starting SMB2-FTRUNCATE\n");
2109 if (!torture_init_connection(&cli)) {
2113 status = smbXcli_negprot(cli->conn, cli->timeout,
2114 PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2115 if (!NT_STATUS_IS_OK(status)) {
2116 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2120 status = cli_session_setup_creds(cli, torture_creds);
2121 if (!NT_STATUS_IS_OK(status)) {
2122 printf("cli_session_setup returned %s\n", nt_errstr(status));
2126 status = cli_tree_connect(cli, share, "?????", NULL);
2127 if (!NT_STATUS_IS_OK(status)) {
2128 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2132 cli_setatr(cli, fname, 0, 0);
2133 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2135 status = cli_ntcreate(cli,
2139 FILE_ATTRIBUTE_NORMAL,
2147 if (!NT_STATUS_IS_OK(status)) {
2148 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2152 buf = talloc_zero_array(cli, uint8_t, buflen);
2158 status = cli_writeall(cli,
2166 if (!NT_STATUS_IS_OK(status)) {
2167 printf("write of %u to %s failed (%s)\n",
2168 (unsigned int)buflen,
2174 status = check_size(cli, fnum, fname, buflen);
2175 if (!NT_STATUS_IS_OK(status)) {
2179 /* Now ftruncate. */
2180 for ( i = 0; i < 10; i++) {
2181 status = cli_ftruncate(cli, fnum, i*1024);
2182 if (!NT_STATUS_IS_OK(status)) {
2183 printf("cli_ftruncate %u of %s failed (%s)\n",
2184 (unsigned int)i*1024,
2189 status = check_size(cli, fnum, fname, i*1024);
2190 if (!NT_STATUS_IS_OK(status)) {
2203 if (fnum != (uint16_t)-1) {
2204 cli_close(cli, fnum);
2206 cli_setatr(cli, fname, 0, 0);
2207 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2209 if (!torture_close_connection(cli)) {
2215 /* Ensure SMB2 flush on directories behaves correctly. */
2217 static bool test_dir_fsync(struct cli_state *cli, const char *path)
2220 uint64_t fid_persistent, fid_volatile;
2221 uint8_t *dir_data = NULL;
2222 uint32_t dir_data_length = 0;
2224 /* Open directory - no write abilities. */
2225 status = smb2cli_create(
2231 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2232 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2233 SEC_STD_SYNCHRONIZE|
2235 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2236 0, /* file_attributes, */
2239 FILE_SHARE_DELETE, /* share_access, */
2240 FILE_OPEN, /* create_disposition, */
2241 FILE_SYNCHRONOUS_IO_NONALERT|
2242 FILE_DIRECTORY_FILE, /* create_options, */
2243 NULL, /* smb2_create_blobs *blobs */
2250 if (!NT_STATUS_IS_OK(status)) {
2251 printf("smb2cli_create '%s' (readonly) returned %s\n",
2257 status = smb2cli_query_directory(
2258 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2259 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2260 talloc_tos(), &dir_data, &dir_data_length);
2262 if (!NT_STATUS_IS_OK(status)) {
2263 printf("smb2cli_query_directory returned %s\n",
2268 /* Open directory no write access. Flush should fail. */
2270 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2271 cli->smb2.tcon, fid_persistent, fid_volatile);
2272 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2273 printf("smb2cli_flush on a read-only directory returned %s\n",
2278 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2279 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2280 if (!NT_STATUS_IS_OK(status)) {
2281 printf("smb2cli_close returned %s\n", nt_errstr(status));
2285 /* Open directory write-attributes only. Flush should still fail. */
2287 status = smb2cli_create(
2293 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2294 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2295 SEC_STD_SYNCHRONIZE|
2297 SEC_DIR_WRITE_ATTRIBUTE|
2298 SEC_DIR_READ_ATTRIBUTE, /* desired_access, */
2299 0, /* file_attributes, */
2302 FILE_SHARE_DELETE, /* share_access, */
2303 FILE_OPEN, /* create_disposition, */
2304 FILE_SYNCHRONOUS_IO_NONALERT|
2305 FILE_DIRECTORY_FILE, /* create_options, */
2306 NULL, /* smb2_create_blobs *blobs */
2313 if (!NT_STATUS_IS_OK(status)) {
2314 printf("smb2cli_create '%s' (write attr) returned %s\n",
2320 status = smb2cli_query_directory(
2321 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2322 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2323 talloc_tos(), &dir_data, &dir_data_length);
2325 if (!NT_STATUS_IS_OK(status)) {
2326 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2330 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2331 cli->smb2.tcon, fid_persistent, fid_volatile);
2332 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2333 printf("smb2cli_flush on a write-attributes directory "
2339 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2340 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 printf("smb2cli_close returned %s\n", nt_errstr(status));
2346 /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2348 status = smb2cli_create(
2354 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2355 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2356 SEC_STD_SYNCHRONIZE|
2358 SEC_DIR_ADD_FILE, /* desired_access, */
2359 0, /* file_attributes, */
2362 FILE_SHARE_DELETE, /* share_access, */
2363 FILE_OPEN, /* create_disposition, */
2364 FILE_SYNCHRONOUS_IO_NONALERT|
2365 FILE_DIRECTORY_FILE, /* create_options, */
2366 NULL, /* smb2_create_blobs *blobs */
2373 if (!NT_STATUS_IS_OK(status)) {
2374 printf("smb2cli_create '%s' (write FILE access) returned %s\n",
2380 status = smb2cli_query_directory(
2381 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2382 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2383 talloc_tos(), &dir_data, &dir_data_length);
2385 if (!NT_STATUS_IS_OK(status)) {
2386 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2390 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2391 cli->smb2.tcon, fid_persistent, fid_volatile);
2392 if (!NT_STATUS_IS_OK(status)) {
2393 printf("smb2cli_flush on a directory returned %s\n",
2398 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2399 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2400 if (!NT_STATUS_IS_OK(status)) {
2401 printf("smb2cli_close returned %s\n", nt_errstr(status));
2405 /* Open directory with SEC_DIR_ADD_FILE access. Flush should now succeed. */
2407 status = smb2cli_create(
2413 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2414 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2415 SEC_STD_SYNCHRONIZE|
2417 SEC_DIR_ADD_SUBDIR, /* desired_access, */
2418 0, /* file_attributes, */
2421 FILE_SHARE_DELETE, /* share_access, */
2422 FILE_OPEN, /* create_disposition, */
2423 FILE_SYNCHRONOUS_IO_NONALERT|
2424 FILE_DIRECTORY_FILE, /* create_options, */
2425 NULL, /* smb2_create_blobs *blobs */
2432 if (!NT_STATUS_IS_OK(status)) {
2433 printf("smb2cli_create '%s' (write DIR access) returned %s\n",
2439 status = smb2cli_query_directory(
2440 cli->conn, cli->timeout, cli->smb2.session, cli->smb2.tcon,
2441 1, 0, 0, fid_persistent, fid_volatile, "*", 0xffff,
2442 talloc_tos(), &dir_data, &dir_data_length);
2444 if (!NT_STATUS_IS_OK(status)) {
2445 printf("smb2cli_query_directory returned %s\n", nt_errstr(status));
2449 status = smb2cli_flush(cli->conn, cli->timeout, cli->smb2.session,
2450 cli->smb2.tcon, fid_persistent, fid_volatile);
2451 if (!NT_STATUS_IS_OK(status)) {
2452 printf("smb2cli_flush on a directory returned %s\n",
2457 status = smb2cli_close(cli->conn, cli->timeout, cli->smb2.session,
2458 cli->smb2.tcon, 0, fid_persistent, fid_volatile);
2459 if (!NT_STATUS_IS_OK(status)) {
2460 printf("smb2cli_close returned %s\n", nt_errstr(status));
2468 bool run_smb2_dir_fsync(int dummy)
2470 struct cli_state *cli = NULL;
2473 const char *dname = "fsync_test_dir";
2475 printf("Starting SMB2-DIR-FSYNC\n");
2477 if (!torture_init_connection(&cli)) {
2481 status = smbXcli_negprot(cli->conn, cli->timeout,
2482 PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2483 if (!NT_STATUS_IS_OK(status)) {
2484 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2488 status = cli_session_setup_creds(cli, torture_creds);
2489 if (!NT_STATUS_IS_OK(status)) {
2490 printf("cli_session_setup returned %s\n", nt_errstr(status));
2494 status = cli_tree_connect(cli, share, "?????", NULL);
2495 if (!NT_STATUS_IS_OK(status)) {
2496 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2500 (void)cli_rmdir(cli, dname);
2501 status = cli_mkdir(cli, dname);
2502 if (!NT_STATUS_IS_OK(status)) {
2503 printf("cli_mkdir(%s) returned %s\n",
2509 /* Test on a subdirectory. */
2510 bret = test_dir_fsync(cli, dname);
2511 if (bret == false) {
2512 (void)cli_rmdir(cli, dname);
2515 (void)cli_rmdir(cli, dname);
2517 /* Test on the root handle of a share. */
2518 bret = test_dir_fsync(cli, "");
2519 if (bret == false) {
2525 bool run_smb2_path_slash(int dummy)
2527 struct cli_state *cli = NULL;
2529 uint64_t fid_persistent;
2530 uint64_t fid_volatile;
2531 const char *dname_noslash = "smb2_dir_slash";
2532 const char *dname_backslash = "smb2_dir_slash\\";
2533 const char *dname_slash = "smb2_dir_slash/";
2534 const char *fname_noslash = "smb2_file_slash";
2535 const char *fname_backslash = "smb2_file_slash\\";
2536 const char *fname_slash = "smb2_file_slash/";
2538 printf("Starting SMB2-PATH-SLASH\n");
2540 if (!torture_init_connection(&cli)) {
2544 status = smbXcli_negprot(cli->conn, cli->timeout,
2545 PROTOCOL_SMB2_02, PROTOCOL_SMB2_02);
2546 if (!NT_STATUS_IS_OK(status)) {
2547 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2551 status = cli_session_setup_creds(cli, torture_creds);
2552 if (!NT_STATUS_IS_OK(status)) {
2553 printf("cli_session_setup returned %s\n", nt_errstr(status));
2557 status = cli_tree_connect(cli, share, "?????", NULL);
2558 if (!NT_STATUS_IS_OK(status)) {
2559 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2563 (void)cli_unlink(cli, dname_noslash, 0);
2564 (void)cli_rmdir(cli, dname_noslash);
2565 (void)cli_unlink(cli, fname_noslash, 0);
2566 (void)cli_rmdir(cli, fname_noslash);
2568 /* Try to create a directory with the backslash name. */
2569 status = smb2cli_create(
2575 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2576 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2577 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2578 0, /* file_attributes, */
2581 FILE_SHARE_DELETE, /* share_access, */
2582 FILE_CREATE, /* create_disposition, */
2583 FILE_DIRECTORY_FILE, /* create_options, */
2584 NULL, /* smb2_create_blobs *blobs */
2592 /* directory ending in '\\' should be success. */
2594 if (!NT_STATUS_IS_OK(status)) {
2595 printf("smb2cli_create '%s' returned %s - "
2596 "should be NT_STATUS_OK\n",
2601 status = smb2cli_close(cli->conn,
2608 if (!NT_STATUS_IS_OK(status)) {
2609 printf("smb2cli_close returned %s\n", nt_errstr(status));
2613 (void)cli_rmdir(cli, dname_noslash);
2615 /* Try to create a directory with the slash name. */
2616 status = smb2cli_create(
2622 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2623 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2624 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2625 0, /* file_attributes, */
2628 FILE_SHARE_DELETE, /* share_access, */
2629 FILE_CREATE, /* create_disposition, */
2630 FILE_DIRECTORY_FILE, /* create_options, */
2631 NULL, /* smb2_create_blobs *blobs */
2639 /* directory ending in '/' is an error. */
2640 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2641 printf("smb2cli_create '%s' returned %s - "
2642 "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2645 if (NT_STATUS_IS_OK(status)) {
2646 (void)smb2cli_close(cli->conn,
2654 (void)cli_rmdir(cli, dname_noslash);
2658 (void)cli_rmdir(cli, dname_noslash);
2660 /* Try to create a file with the backslash name. */
2661 status = smb2cli_create(
2667 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2668 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2669 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2670 0, /* file_attributes, */
2673 FILE_SHARE_DELETE, /* share_access, */
2674 FILE_CREATE, /* create_disposition, */
2675 FILE_NON_DIRECTORY_FILE, /* create_options, */
2676 NULL, /* smb2_create_blobs *blobs */
2684 /* file ending in '\\' should be error. */
2686 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2687 printf("smb2cli_create '%s' returned %s - "
2688 "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2691 if (NT_STATUS_IS_OK(status)) {
2692 (void)smb2cli_close(cli->conn,
2700 (void)cli_unlink(cli, fname_noslash, 0);
2704 (void)cli_unlink(cli, fname_noslash, 0);
2706 /* Try to create a file with the slash name. */
2707 status = smb2cli_create(
2713 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
2714 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
2715 FILE_READ_DATA|FILE_READ_ATTRIBUTES, /* desired_access, */
2716 0, /* file_attributes, */
2719 FILE_SHARE_DELETE, /* share_access, */
2720 FILE_CREATE, /* create_disposition, */
2721 FILE_NON_DIRECTORY_FILE, /* create_options, */
2722 NULL, /* smb2_create_blobs *blobs */
2730 /* file ending in '/' should be error. */
2732 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
2733 printf("smb2cli_create '%s' returned %s - "
2734 "should be NT_STATUS_OBJECT_NAME_INVALID\n",
2737 if (NT_STATUS_IS_OK(status)) {
2738 (void)smb2cli_close(cli->conn,
2746 (void)cli_unlink(cli, fname_noslash, 0);
2750 (void)cli_unlink(cli, fname_noslash, 0);
2755 * NB. This can only work against a server where
2756 * the connecting user has been granted SeSecurityPrivilege.
2758 * 1). Create a test file.
2759 * 2). Open with SEC_FLAG_SYSTEM_SECURITY *only*. ACCESS_DENIED -
2760 * NB. SMB2-only behavior.
2761 * 3). Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2762 * 4). Write SACL. Should fail with ACCESS_DENIED (seems to need WRITE_DAC).
2764 * 6). Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2765 * 7). Write SACL. Success.
2767 * 9). Open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
2768 * 10). Read SACL. Success.
2769 * 11). Read DACL. Should fail with ACCESS_DENIED (no READ_CONTROL).
2773 bool run_smb2_sacl(int dummy)
2775 struct cli_state *cli = NULL;
2777 struct security_descriptor *sd_dacl = NULL;
2778 struct security_descriptor *sd_sacl = NULL;
2779 const char *fname = "sacl_test_file";
2780 uint16_t fnum = (uint16_t)-1;
2782 printf("Starting SMB2-SACL\n");
2784 if (!torture_init_connection(&cli)) {
2788 status = smbXcli_negprot(cli->conn,
2792 if (!NT_STATUS_IS_OK(status)) {
2793 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
2797 status = cli_session_setup_creds(cli, torture_creds);
2798 if (!NT_STATUS_IS_OK(status)) {
2799 printf("cli_session_setup returned %s\n", nt_errstr(status));
2803 status = cli_tree_connect(cli, share, "?????", NULL);
2804 if (!NT_STATUS_IS_OK(status)) {
2805 printf("cli_tree_connect returned %s\n", nt_errstr(status));
2809 (void)cli_unlink(cli, fname, 0);
2811 /* First create a file. */
2812 status = cli_ntcreate(cli,
2816 FILE_ATTRIBUTE_NORMAL,
2824 if (!NT_STATUS_IS_OK(status)) {
2825 printf("Create of %s failed (%s)\n",
2831 cli_close(cli, fnum);
2832 fnum = (uint16_t)-1;
2835 * Now try to open with *only* SEC_FLAG_SYSTEM_SECURITY.
2836 * This should fail with NT_STATUS_ACCESS_DENIED - but
2837 * only against an SMB2 server. SMB1 allows this as tested
2838 * in SMB1-SYSTEM-SECURITY.
2841 status = cli_smb2_create_fnum(cli,
2843 SMB2_OPLOCK_LEVEL_NONE,
2844 SMB2_IMPERSONATION_IMPERSONATION,
2845 SEC_FLAG_SYSTEM_SECURITY, /* desired access */
2846 0, /* file_attributes, */
2849 FILE_SHARE_DELETE, /* share_access, */
2850 FILE_OPEN, /* create_disposition, */
2851 FILE_NON_DIRECTORY_FILE, /* create_options, */
2852 NULL, /* in_cblobs. */
2854 NULL, /* smb_create_returns */
2855 talloc_tos(), /* mem_ctx */
2856 NULL); /* out_cblobs */
2858 if (NT_STATUS_EQUAL(status, NT_STATUS_PRIVILEGE_NOT_HELD)) {
2859 printf("SMB2-SACL-TEST can only work with a user "
2860 "who has been granted SeSecurityPrivilege.\n"
2862 "\"Manage auditing and security log\""
2863 "privilege setting on Windows\n");
2867 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2868 printf("open file %s with SEC_FLAG_SYSTEM_SECURITY only: "
2869 "got %s - should fail with ACCESS_DENIED\n",
2876 * Open with SEC_FLAG_SYSTEM_SECURITY|FILE_WRITE_ATTRIBUTES.
2879 status = cli_smb2_create_fnum(cli,
2881 SMB2_OPLOCK_LEVEL_NONE,
2882 SMB2_IMPERSONATION_IMPERSONATION,
2883 SEC_FLAG_SYSTEM_SECURITY|
2884 FILE_WRITE_ATTRIBUTES, /* desired access */
2885 0, /* file_attributes, */
2888 FILE_SHARE_DELETE, /* share_access, */
2889 FILE_OPEN, /* create_disposition, */
2890 FILE_NON_DIRECTORY_FILE, /* create_options, */
2891 NULL, /* in_cblobs. */
2893 NULL, /* smb_create_returns */
2894 talloc_tos(), /* mem_ctx */
2895 NULL); /* out_cblobs */
2897 if (!NT_STATUS_IS_OK(status)) {
2898 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2899 "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2905 /* Create an SD with a SACL. */
2906 sd_sacl = security_descriptor_sacl_create(talloc_tos(),
2912 SEC_ACE_TYPE_SYSTEM_AUDIT,
2914 SEC_ACE_FLAG_FAILED_ACCESS,
2917 if (sd_sacl == NULL) {
2918 printf("Out of memory creating SACL\n");
2923 * Write the SACL SD. This should fail
2924 * even though we have SEC_FLAG_SYSTEM_SECURITY,
2925 * as it seems to also need WRITE_DAC access.
2927 status = cli_set_security_descriptor(cli,
2929 SECINFO_DACL|SECINFO_SACL,
2932 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2933 printf("Writing SACL on file %s got (%s) "
2934 "should have failed with ACCESS_DENIED.\n",
2941 cli_smb2_close_fnum(cli, fnum);
2942 fnum = (uint16_t)-1;
2945 * Open with SEC_FLAG_SYSTEM_SECURITY|SEC_STD_WRITE_DAC.
2948 status = cli_smb2_create_fnum(cli,
2950 SMB2_OPLOCK_LEVEL_NONE,
2951 SMB2_IMPERSONATION_IMPERSONATION,
2952 SEC_FLAG_SYSTEM_SECURITY|
2953 SEC_STD_WRITE_DAC, /* desired access */
2954 0, /* file_attributes, */
2957 FILE_SHARE_DELETE, /* share_access, */
2958 FILE_OPEN, /* create_disposition, */
2959 FILE_NON_DIRECTORY_FILE, /* create_options, */
2960 NULL, /* in_cblobs. */
2962 NULL, /* smb_create_returns */
2963 talloc_tos(), /* mem_ctx */
2964 NULL); /* out_cblobs */
2966 if (!NT_STATUS_IS_OK(status)) {
2967 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
2968 "FILE_WRITE_ATTRIBUTES) failed (%s)\n",
2975 * Write the SACL SD. This should now succeed
2976 * as we have both SEC_FLAG_SYSTEM_SECURITY
2977 * and WRITE_DAC access.
2979 status = cli_set_security_descriptor(cli,
2981 SECINFO_DACL|SECINFO_SACL,
2984 if (!NT_STATUS_IS_OK(status)) {
2985 printf("cli_set_security_descriptor SACL "
2986 "on file %s failed (%s)\n",
2993 cli_smb2_close_fnum(cli, fnum);
2994 fnum = (uint16_t)-1;
2996 /* We're done with the sacl we made. */
2997 TALLOC_FREE(sd_sacl);
3000 * Now try to open with SEC_FLAG_SYSTEM_SECURITY|READ_ATTRIBUTES.
3001 * This gives us access to the SACL.
3004 status = cli_smb2_create_fnum(cli,
3006 SMB2_OPLOCK_LEVEL_NONE,
3007 SMB2_IMPERSONATION_IMPERSONATION,
3008 SEC_FLAG_SYSTEM_SECURITY|
3009 FILE_READ_ATTRIBUTES, /* desired access */
3010 0, /* file_attributes, */
3013 FILE_SHARE_DELETE, /* share_access, */
3014 FILE_OPEN, /* create_disposition, */
3015 FILE_NON_DIRECTORY_FILE, /* create_options, */
3016 NULL, /* in_cblobs. */
3018 NULL, /* smb_create_returns */
3019 talloc_tos(), /* mem_ctx */
3020 NULL); /* out_cblobs */
3022 if (!NT_STATUS_IS_OK(status)) {
3023 printf("Open of %s with (SEC_FLAG_SYSTEM_SECURITY|"
3024 "FILE_READ_ATTRIBUTES) failed (%s)\n",
3030 /* Try and read the SACL - should succeed. */
3031 status = cli_query_security_descriptor(
3032 cli, fnum, SECINFO_SACL, talloc_tos(), &sd_sacl);
3034 if (!NT_STATUS_IS_OK(status)) {
3035 printf("Read SACL from file %s failed (%s)\n",
3041 TALLOC_FREE(sd_sacl);
3044 * Try and read the DACL - should fail as we have
3045 * no READ_DAC access.
3047 status = cli_query_security_descriptor(
3048 cli, fnum, SECINFO_DACL, talloc_tos(), &sd_sacl);
3050 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
3051 printf("Reading DACL on file %s got (%s) "
3052 "should have failed with ACCESS_DENIED.\n",
3058 if (fnum != (uint16_t)-1) {
3059 cli_smb2_close_fnum(cli, fnum);
3060 fnum = (uint16_t)-1;
3063 TALLOC_FREE(sd_dacl);
3064 TALLOC_FREE(sd_sacl);
3066 (void)cli_unlink(cli, fname, 0);
3071 TALLOC_FREE(sd_dacl);
3072 TALLOC_FREE(sd_sacl);
3074 if (fnum != (uint16_t)-1) {
3075 cli_smb2_close_fnum(cli, fnum);
3076 fnum = (uint16_t)-1;
3079 (void)cli_unlink(cli, fname, 0);
3083 bool run_smb2_quota1(int dummy)
3085 struct cli_state *cli = NULL;
3087 uint16_t fnum = (uint16_t)-1;
3088 SMB_NTQUOTA_STRUCT qt = {0};
3090 printf("Starting SMB2-QUOTA1\n");
3092 if (!torture_init_connection(&cli)) {
3096 status = smbXcli_negprot(cli->conn,
3100 if (!NT_STATUS_IS_OK(status)) {
3101 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3105 status = cli_session_setup_creds(cli, torture_creds);
3106 if (!NT_STATUS_IS_OK(status)) {
3107 printf("cli_session_setup returned %s\n", nt_errstr(status));
3111 status = cli_tree_connect(cli, share, "?????", NULL);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3117 status = cli_smb2_create_fnum(
3120 SMB2_OPLOCK_LEVEL_NONE,
3121 SMB2_IMPERSONATION_IMPERSONATION,
3122 SEC_GENERIC_READ, /* desired access */
3123 0, /* file_attributes, */
3126 FILE_SHARE_DELETE, /* share_access, */
3127 FILE_OPEN, /* create_disposition, */
3128 FILE_DIRECTORY_FILE, /* create_options, */
3129 NULL, /* in_cblobs. */
3131 NULL, /* smb_create_returns */
3133 NULL); /* out_cblobs */
3134 if (!NT_STATUS_IS_OK(status)) {
3135 printf("cli_smb2_create_fnum failed: %s\n", nt_errstr(status));
3139 status = cli_smb2_get_user_quota(cli, fnum, &qt);
3140 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
3141 printf("cli_smb2_get_user_quota returned %s, expected "
3142 "NT_STATUS_INVALID_HANDLE\n",
3150 bool run_smb2_stream_acl(int dummy)
3152 struct cli_state *cli = NULL;
3154 uint16_t fnum = (uint16_t)-1;
3155 const char *fname = "stream_acl_test_file";
3156 const char *sname = "stream_acl_test_file:streamname";
3157 struct security_descriptor *sd_dacl = NULL;
3160 printf("SMB2 stream acl\n");
3162 if (!torture_init_connection(&cli)) {
3166 status = smbXcli_negprot(cli->conn,
3170 if (!NT_STATUS_IS_OK(status)) {
3171 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3175 status = cli_session_setup_creds(cli, torture_creds);
3176 if (!NT_STATUS_IS_OK(status)) {
3177 printf("cli_session_setup returned %s\n", nt_errstr(status));
3181 status = cli_tree_connect(cli, share, "?????", NULL);
3182 if (!NT_STATUS_IS_OK(status)) {
3183 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3187 /* Ensure file doesn't exist. */
3188 (void)cli_unlink(cli, fname, 0);
3190 /* Create the file. */
3191 status = cli_ntcreate(cli,
3195 FILE_ATTRIBUTE_NORMAL,
3203 if (!NT_STATUS_IS_OK(status)) {
3204 printf("Create of %s failed (%s)\n",
3210 /* Close the handle. */
3211 cli_smb2_close_fnum(cli, fnum);
3212 fnum = (uint16_t)-1;
3214 /* Create the stream. */
3215 status = cli_ntcreate(cli,
3219 SEC_STD_READ_CONTROL|
3221 FILE_ATTRIBUTE_NORMAL,
3229 if (!NT_STATUS_IS_OK(status)) {
3230 printf("Create of %s failed (%s)\n",
3236 /* Close the handle. */
3237 cli_smb2_close_fnum(cli, fnum);
3238 fnum = (uint16_t)-1;
3241 * Open the stream - for Samba this ensures
3242 * we prove we have a pathref fsp.
3244 status = cli_ntcreate(cli,
3248 SEC_STD_READ_CONTROL|
3250 FILE_ATTRIBUTE_NORMAL,
3258 if (!NT_STATUS_IS_OK(status)) {
3259 printf("Open of %s failed (%s)\n",
3265 /* Read the security descriptor off the stream handle. */
3266 status = cli_query_security_descriptor(cli,
3272 if (!NT_STATUS_IS_OK(status)) {
3273 printf("Reading DACL on stream %s got (%s)\n",
3279 if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3280 sd_dacl->dacl->num_aces < 1) {
3281 printf("Invalid DACL returned on stream %s "
3282 "(this should not happen)\n",
3288 * Ensure it allows FILE_READ_DATA in the first ace.
3291 if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) == 0) {
3292 printf("DACL->ace[0] returned on stream %s "
3293 "doesn't have read access (should not happen)\n",
3298 /* Remove FILE_READ_DATA from the first ace and set. */
3299 sd_dacl->dacl->aces[0].access_mask &= ~FILE_READ_DATA;
3301 status = cli_set_security_descriptor(cli,
3306 if (!NT_STATUS_IS_OK(status)) {
3307 printf("Setting DACL on stream %s got (%s)\n",
3313 TALLOC_FREE(sd_dacl);
3315 /* Read again and check it changed. */
3316 status = cli_query_security_descriptor(cli,
3322 if (!NT_STATUS_IS_OK(status)) {
3323 printf("Reading DACL on stream %s got (%s)\n",
3329 if (sd_dacl == NULL || sd_dacl->dacl == NULL ||
3330 sd_dacl->dacl->num_aces < 1) {
3331 printf("Invalid DACL (1) returned on stream %s "
3332 "(this should not happen)\n",
3337 /* FILE_READ_DATA should be gone from the first ace. */
3338 if ((sd_dacl->dacl->aces[0].access_mask & FILE_READ_DATA) != 0) {
3339 printf("DACL on stream %s did not change\n",
3348 if (fnum != (uint16_t)-1) {
3349 cli_smb2_close_fnum(cli, fnum);
3350 fnum = (uint16_t)-1;
3353 (void)cli_unlink(cli, fname, 0);
3357 static NTSTATUS list_fn(struct file_info *finfo,
3361 bool *matched = (bool *)state;
3362 if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
3365 return NT_STATUS_OK;
3369 * Must be run against a share with "smbd async dosmode = yes".
3370 * Checks we can return DOS attriutes other than "N".
3371 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14758
3374 bool run_list_dir_async_test(int dummy)
3376 struct cli_state *cli = NULL;
3378 const char *dname = "ASYNC_DIR";
3380 bool matched = false;
3382 printf("SMB2 list dir async\n");
3384 if (!torture_init_connection(&cli)) {
3388 status = smbXcli_negprot(cli->conn,
3392 if (!NT_STATUS_IS_OK(status)) {
3393 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3397 status = cli_session_setup_creds(cli, torture_creds);
3398 if (!NT_STATUS_IS_OK(status)) {
3399 printf("cli_session_setup returned %s\n", nt_errstr(status));
3403 status = cli_tree_connect(cli, share, "?????", NULL);
3404 if (!NT_STATUS_IS_OK(status)) {
3405 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3409 /* Ensure directory doesn't exist. */
3410 (void)cli_rmdir(cli, dname);
3412 status = cli_mkdir(cli, dname);
3413 if (!NT_STATUS_IS_OK(status)) {
3414 printf("cli_mkdir %s returned %s\n", dname, nt_errstr(status));
3418 status = cli_list(cli,
3420 FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_DIRECTORY,
3423 if (!NT_STATUS_IS_OK(status)) {
3424 printf("cli_list %s returned %s\n", dname, nt_errstr(status));
3429 printf("Failed to find %s\n", dname);
3437 (void)cli_rmdir(cli, dname);
3442 * Test delete a directory fails if a file is created
3443 * in a directory after the delete on close is set.
3444 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
3447 bool run_delete_on_close_non_empty(int dummy)
3449 struct cli_state *cli = NULL;
3451 const char *dname = "DEL_ON_CLOSE_DIR";
3452 const char *fname = "DEL_ON_CLOSE_DIR\\testfile";
3453 uint16_t fnum = (uint16_t)-1;
3454 uint16_t fnum1 = (uint16_t)-1;
3457 printf("SMB2 delete on close nonempty\n");
3459 if (!torture_init_connection(&cli)) {
3463 status = smbXcli_negprot(cli->conn,
3467 if (!NT_STATUS_IS_OK(status)) {
3468 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3472 status = cli_session_setup_creds(cli, torture_creds);
3473 if (!NT_STATUS_IS_OK(status)) {
3474 printf("cli_session_setup returned %s\n", nt_errstr(status));
3478 status = cli_tree_connect(cli, share, "?????", NULL);
3479 if (!NT_STATUS_IS_OK(status)) {
3480 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3484 /* Ensure directory doesn't exist. */
3485 (void)cli_unlink(cli,
3487 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3488 (void)cli_rmdir(cli, dname);
3490 /* Create target directory. */
3491 status = cli_ntcreate(cli,
3494 DELETE_ACCESS|FILE_READ_DATA,
3495 FILE_ATTRIBUTE_DIRECTORY,
3500 FILE_DIRECTORY_FILE,
3504 if (!NT_STATUS_IS_OK(status)) {
3505 printf("cli_ntcreate for directory %s returned %s\n",
3511 /* Now set the delete on close bit. */
3512 status = cli_nt_delete_on_close(cli, fnum, 1);
3513 if (!NT_STATUS_IS_OK(status)) {
3514 printf("cli_cli_nt_delete_on_close set for directory "
3521 /* Create file inside target directory. */
3523 * NB. On Windows this will return NT_STATUS_DELETE_PENDING. Only on
3524 * Samba will this succeed by default (the option "check parent
3525 * directory delete on close" configures behaviour), but we're using
3526 * this to test a race condition.
3528 status = cli_ntcreate(cli,
3532 FILE_ATTRIBUTE_NORMAL,
3541 if (!NT_STATUS_IS_OK(status)) {
3542 printf("cli_ntcreate for file %s returned %s\n",
3547 cli_close(cli, fnum1);
3548 fnum1 = (uint16_t)-1;
3550 /* Now the close should fail. */
3551 status = cli_close(cli, fnum);
3552 if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3553 printf("cli_close for directory %s returned %s\n",
3563 if (fnum1 != (uint16_t)-1) {
3564 cli_close(cli, fnum1);
3566 if (fnum != (uint16_t)-1) {
3567 cli_nt_delete_on_close(cli, fnum, 0);
3568 cli_close(cli, fnum);
3570 (void)cli_unlink(cli,
3572 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3573 (void)cli_rmdir(cli, dname);
3577 static NTSTATUS check_empty_fn(struct file_info *finfo,
3581 unsigned int *pcount = (unsigned int *)private_data;
3583 if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) {
3585 return NT_STATUS_OK;
3587 return NT_STATUS_DIRECTORY_NOT_EMPTY;
3591 * Test setting the delete on close bit on a directory
3592 * containing an unwritable file fails or succeeds
3593 * an a share set with "hide unwritable = yes"
3594 * depending on the setting of "delete veto files".
3595 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3597 * First version. With "delete veto files = yes"
3598 * setting the delete on close should succeed.
3601 bool run_delete_on_close_nonwrite_delete_yes_test(int dummy)
3603 struct cli_state *cli = NULL;
3605 const char *dname = "delete_veto_yes";
3606 const char *list_dname = "delete_veto_yes\\*";
3607 uint16_t fnum = (uint16_t)-1;
3609 unsigned int list_count = 0;
3611 printf("SMB2 delete on close nonwrite - delete veto yes\n");
3613 if (!torture_init_connection(&cli)) {
3617 status = smbXcli_negprot(cli->conn,
3621 if (!NT_STATUS_IS_OK(status)) {
3622 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3626 status = cli_session_setup_creds(cli, torture_creds);
3627 if (!NT_STATUS_IS_OK(status)) {
3628 printf("cli_session_setup returned %s\n", nt_errstr(status));
3632 status = cli_tree_connect(cli, share, "?????", NULL);
3633 if (!NT_STATUS_IS_OK(status)) {
3634 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3638 /* Ensure target directory is seen as empty. */
3639 status = cli_list(cli,
3641 FILE_ATTRIBUTE_DIRECTORY |
3642 FILE_ATTRIBUTE_HIDDEN |
3643 FILE_ATTRIBUTE_SYSTEM,
3646 if (!NT_STATUS_IS_OK(status)) {
3647 printf("cli_list of %s returned %s\n",
3652 if (list_count != 2) {
3653 printf("cli_list of %s returned a count of %u\n",
3659 /* Open target directory. */
3660 status = cli_ntcreate(cli,
3663 DELETE_ACCESS|FILE_READ_DATA,
3664 FILE_ATTRIBUTE_DIRECTORY,
3669 FILE_DIRECTORY_FILE,
3673 if (!NT_STATUS_IS_OK(status)) {
3674 printf("cli_ntcreate for directory %s returned %s\n",
3680 /* Now set the delete on close bit. */
3681 status = cli_nt_delete_on_close(cli, fnum, 1);
3682 if (!NT_STATUS_IS_OK(status)) {
3683 printf("cli_cli_nt_delete_on_close set for directory "
3684 "%s returned %s (should have succeeded)\n",
3694 if (fnum != (uint16_t)-1) {
3695 (void)cli_nt_delete_on_close(cli, fnum, 0);
3696 (void)cli_close(cli, fnum);
3702 * Test setting the delete on close bit on a directory
3703 * containing an unwritable file fails or succeeds
3704 * an a share set with "hide unwritable = yes"
3705 * depending on the setting of "delete veto files".
3706 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15023
3708 * Second version. With "delete veto files = no"
3709 * setting the delete on close should fail.
3712 bool run_delete_on_close_nonwrite_delete_no_test(int dummy)
3714 struct cli_state *cli = NULL;
3716 const char *dname = "delete_veto_no";
3717 const char *list_dname = "delete_veto_no\\*";
3718 uint16_t fnum = (uint16_t)-1;
3720 unsigned int list_count = 0;
3722 printf("SMB2 delete on close nonwrite - delete veto yes\n");
3724 if (!torture_init_connection(&cli)) {
3728 status = smbXcli_negprot(cli->conn,
3732 if (!NT_STATUS_IS_OK(status)) {
3733 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
3737 status = cli_session_setup_creds(cli, torture_creds);
3738 if (!NT_STATUS_IS_OK(status)) {
3739 printf("cli_session_setup returned %s\n", nt_errstr(status));
3743 status = cli_tree_connect(cli, share, "?????", NULL);
3744 if (!NT_STATUS_IS_OK(status)) {
3745 printf("cli_tree_connect returned %s\n", nt_errstr(status));
3749 /* Ensure target directory is seen as empty. */
3750 status = cli_list(cli,
3752 FILE_ATTRIBUTE_DIRECTORY |
3753 FILE_ATTRIBUTE_HIDDEN |
3754 FILE_ATTRIBUTE_SYSTEM,
3757 if (!NT_STATUS_IS_OK(status)) {
3758 printf("cli_list of %s returned %s\n",
3763 if (list_count != 2) {
3764 printf("cli_list of %s returned a count of %u\n",
3770 /* Open target directory. */
3771 status = cli_ntcreate(cli,
3774 DELETE_ACCESS|FILE_READ_DATA,
3775 FILE_ATTRIBUTE_DIRECTORY,
3780 FILE_DIRECTORY_FILE,
3784 if (!NT_STATUS_IS_OK(status)) {
3785 printf("cli_ntcreate for directory %s returned %s\n",
3791 /* Now set the delete on close bit. */
3792 status = cli_nt_delete_on_close(cli, fnum, 1);
3793 if (NT_STATUS_IS_OK(status)) {
3794 printf("cli_cli_nt_delete_on_close set for directory "
3795 "%s returned NT_STATUS_OK "
3796 "(should have failed)\n",
3800 if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3801 printf("cli_cli_nt_delete_on_close set for directory "
3803 "(should have returned "
3804 "NT_STATUS_DIRECTORY_NOT_EMPTY)\n",
3814 if (fnum != (uint16_t)-1) {
3815 (void)cli_nt_delete_on_close(cli, fnum, 0);
3816 (void)cli_close(cli, fnum);
3822 * Open an SMB2 file readonly and return the inode number.
3824 static NTSTATUS get_smb2_inode(struct cli_state *cli,
3825 const char *pathname,
3829 uint64_t fid_persistent = 0;
3830 uint64_t fid_volatile = 0;
3831 DATA_BLOB outbuf = data_blob_null;
3835 status = smb2cli_create(cli->conn,
3840 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3841 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3842 SEC_STD_SYNCHRONIZE|
3844 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
3845 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3846 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3847 FILE_OPEN, /* create_disposition, */
3848 0, /* create_options, */
3849 NULL, /* smb2_create_blobs *blobs */
3852 NULL, /* struct smb_create_returns * */
3853 talloc_tos(), /* mem_ctx. */
3854 NULL, /* struct smb2_create_blobs * */
3855 NULL); /* struct symlink_reparse_struct */
3856 if (!NT_STATUS_IS_OK(status)) {
3863 status = smb2cli_query_info(cli->conn,
3868 (SMB_FILE_ALL_INFORMATION - 1000), /* in_file_info_class */
3869 1024, /* in_max_output_length */
3870 NULL, /* in_input_buffer */
3871 0, /* in_additional_info */
3878 if (NT_STATUS_IS_OK(status)) {
3879 *ino_ret = PULL_LE_U64(outbuf.data, 0x40);
3882 (void)smb2cli_close(cli->conn,
3893 * Check an inode matches a given SMB2 path.
3895 static bool smb2_inode_matches(struct cli_state *cli,
3896 const char *match_pathname,
3897 uint64_t ino_tomatch,
3898 const char *test_pathname)
3900 uint64_t test_ino = 0;
3903 status = get_smb2_inode(cli,
3906 if (!NT_STATUS_IS_OK(status)) {
3907 printf("%s: Failed to get ino "
3908 "number for %s, (%s)\n",
3914 if (test_ino != ino_tomatch) {
3915 printf("%s: Inode missmatch, ino_tomatch (%s) "
3916 "ino=%"PRIu64" test (%s) "
3929 * Delete an SMB2 file on a DFS share.
3931 static NTSTATUS smb2_dfs_delete(struct cli_state *cli,
3932 const char *pathname)
3935 uint64_t fid_persistent = 0;
3936 uint64_t fid_volatile = 0;
3943 status = smb2cli_create(cli->conn,
3948 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
3949 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
3950 SEC_STD_SYNCHRONIZE|
3951 SEC_STD_DELETE, /* desired_access, */
3952 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
3953 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
3954 FILE_OPEN, /* create_disposition, */
3955 0, /* create_options, */
3956 NULL, /* smb2_create_blobs *blobs */
3959 NULL, /* struct smb_create_returns * */
3960 talloc_tos(), /* mem_ctx. */
3961 NULL, /* struct smb2_create_blobs * */
3962 NULL); /* struct symlink_reparse_struct */
3963 if (!NT_STATUS_IS_OK(status)) {
3968 * Set delete on close.
3970 PUSH_LE_U8(&data[0], 0, 1);
3971 inbuf.data = &data[0];
3974 status = smb2cli_set_info(cli->conn,
3978 SMB2_0_INFO_FILE, /* info_type. */
3979 SMB_FILE_DISPOSITION_INFORMATION - 1000, /* info_class */
3981 0, /* additional_info. */
3984 if (!NT_STATUS_IS_OK(status)) {
3987 status = smb2cli_close(cli->conn,
3998 * Rename or hardlink an SMB2 file on a DFS share.
4000 static NTSTATUS smb2_dfs_setinfo_name(struct cli_state *cli,
4001 uint64_t fid_persistent,
4002 uint64_t fid_volatile,
4003 const char *newname,
4008 smb_ucs2_t *converted_str = NULL;
4009 size_t converted_size_bytes = 0;
4011 uint8_t info_class = 0;
4014 ok = push_ucs2_talloc(talloc_tos(),
4017 &converted_size_bytes);
4019 return NT_STATUS_INVALID_PARAMETER;
4022 * W2K8 insists the dest name is not null terminated. Remove
4023 * the last 2 zero bytes and reduce the name length.
4025 if (converted_size_bytes < 2) {
4026 return NT_STATUS_INVALID_PARAMETER;
4028 converted_size_bytes -= 2;
4029 inbuf_size = 20 + converted_size_bytes;
4030 if (inbuf_size < 20) {
4031 /* Integer wrap check. */
4032 return NT_STATUS_INVALID_PARAMETER;
4036 * The Windows 10 SMB2 server has a minimum length
4037 * for a SMB2_FILE_RENAME_INFORMATION buffer of
4038 * 24 bytes. It returns NT_STATUS_INFO_LENGTH_MISMATCH
4039 * if the length is less.
4041 inbuf_size = MAX(inbuf_size, 24);
4042 inbuf = data_blob_talloc_zero(talloc_tos(), inbuf_size);
4043 if (inbuf.data == NULL) {
4044 return NT_STATUS_NO_MEMORY;
4046 PUSH_LE_U32(inbuf.data, 16, converted_size_bytes);
4047 memcpy(inbuf.data + 20, converted_str, converted_size_bytes);
4048 TALLOC_FREE(converted_str);
4050 if (do_rename == true) {
4051 info_class = SMB_FILE_RENAME_INFORMATION - 1000;
4054 info_class = SMB_FILE_LINK_INFORMATION - 1000;
4057 status = smb2cli_set_info(cli->conn,
4061 SMB2_0_INFO_FILE, /* info_type. */
4062 info_class, /* info_class */
4064 0, /* additional_info. */
4070 static NTSTATUS smb2_dfs_rename(struct cli_state *cli,
4071 uint64_t fid_persistent,
4072 uint64_t fid_volatile,
4073 const char *newname)
4075 return smb2_dfs_setinfo_name(cli,
4079 true); /* do_rename */
4082 static NTSTATUS smb2_dfs_hlink(struct cli_state *cli,
4083 uint64_t fid_persistent,
4084 uint64_t fid_volatile,
4085 const char *newname)
4087 return smb2_dfs_setinfo_name(cli,
4091 false); /* do_rename */
4097 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/dc9978d7-6299-4c5a-a22d-a039cdc716ea
4099 * (Characters " \ / [ ] : | < > + = ; , * ?,
4100 * and control characters in range 0x00 through
4101 * 0x1F, inclusive, are illegal in a share name)
4103 * But Windows server only checks in DFS sharenames ':'. All other
4104 * share names are allowed.
4107 static bool test_smb2_dfs_sharenames(struct cli_state *cli,
4108 const char *dfs_root_share_name,
4112 const char *test_str = "/[]:|<>+=;,*?";
4115 bool ino_matched = false;
4117 /* Setup template pathname. */
4118 memcpy(test_path, "SERVER\\X", 9);
4120 /* Test invalid control characters. */
4121 for (i = 1; i < 0x20; i++) {
4123 ino_matched = smb2_inode_matches(cli,
4124 dfs_root_share_name,
4132 /* Test explicit invalid characters. */
4133 for (p = test_str; *p != '\0'; p++) {
4137 * Only ':' is treated as an INVALID sharename
4138 * for a DFS SERVER\\SHARE path.
4140 uint64_t test_ino = 0;
4141 NTSTATUS status = get_smb2_inode(cli,
4144 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_INVALID)) {
4145 printf("%s:%d Open of %s should get "
4146 "NT_STATUS_OBJECT_NAME_INVALID, got %s\n",
4154 ino_matched = smb2_inode_matches(cli,
4155 dfs_root_share_name,
4167 * "Raw" test of SMB2 paths to a DFS share.
4168 * We must use the lower level smb2cli_XXXX() interfaces,
4169 * not the cli_XXX() ones here as the ultimate goal is to fix our
4170 * cli_XXX() interfaces to work transparently over DFS.
4172 * So here, we're testing the server code, not the client code.
4174 * Passes cleanly against Windows.
4177 bool run_smb2_dfs_paths(int dummy)
4179 struct cli_state *cli = NULL;
4181 bool dfs_supported = false;
4182 char *dfs_root_share_name = NULL;
4183 uint64_t root_ino = 0;
4184 uint64_t test_ino = 0;
4185 bool ino_matched = false;
4186 uint64_t fid_persistent = 0;
4187 uint64_t fid_volatile = 0;
4188 bool retval = false;
4191 printf("Starting SMB2-DFS-PATHS\n");
4193 if (!torture_init_connection(&cli)) {
4197 status = smbXcli_negprot(cli->conn,
4201 if (!NT_STATUS_IS_OK(status)) {
4202 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4206 status = cli_session_setup_creds(cli, torture_creds);
4207 if (!NT_STATUS_IS_OK(status)) {
4208 printf("cli_session_setup returned %s\n", nt_errstr(status));
4212 status = cli_tree_connect(cli, share, "?????", NULL);
4213 if (!NT_STATUS_IS_OK(status)) {
4214 printf("cli_tree_connect returned %s\n", nt_errstr(status));
4218 /* Ensure this is a DFS share. */
4219 dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4220 if (!dfs_supported) {
4221 printf("Server %s does not support DFS\n",
4222 smbXcli_conn_remote_name(cli->conn));
4225 dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4226 if (!dfs_supported) {
4227 printf("Share %s does not support DFS\n",
4232 * Create the "official" DFS share root name.
4233 * No SMB2 paths can start with '\\'.
4235 dfs_root_share_name = talloc_asprintf(talloc_tos(),
4237 smbXcli_conn_remote_name(cli->conn),
4239 if (dfs_root_share_name == NULL) {
4240 printf("Out of memory\n");
4244 /* Get the share root inode number. */
4245 status = get_smb2_inode(cli,
4246 dfs_root_share_name,
4248 if (!NT_STATUS_IS_OK(status)) {
4249 printf("%s:%d Failed to get ino number for share root %s, (%s)\n",
4252 dfs_root_share_name,
4258 * Test the Windows algorithm for parsing DFS names.
4261 * A single "SERVER" element should open and match the share root.
4263 ino_matched = smb2_inode_matches(cli,
4264 dfs_root_share_name,
4266 smbXcli_conn_remote_name(cli->conn));
4268 printf("%s:%d Failed to match ino number for %s\n",
4271 smbXcli_conn_remote_name(cli->conn));
4276 * An "" DFS empty server name should open and match the share root on
4277 * Windows 2008. Windows 2022 returns NT_STATUS_INVALID_PARAMETER
4278 * for a DFS empty server name.
4280 status = get_smb2_inode(cli,
4283 if (NT_STATUS_IS_OK(status)) {
4285 * Windows 2008 - open succeeded. Proceed to
4288 ino_matched = smb2_inode_matches(cli,
4289 dfs_root_share_name,
4293 printf("%s:%d Failed to match ino number for %s\n",
4300 if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4302 * For Windows 2022 we expect to fail with
4303 * NT_STATUS_INVALID_PARAMETER. Anything else is
4306 printf("%s:%d Unexpected error (%s) getting ino number for %s\n",
4313 /* A "BAD" server name should open and match the share root. */
4314 ino_matched = smb2_inode_matches(cli,
4315 dfs_root_share_name,
4319 printf("%s:%d Failed to match ino number for %s\n",
4326 * A "BAD\\BAD" server and share name should open
4327 * and match the share root.
4329 ino_matched = smb2_inode_matches(cli,
4330 dfs_root_share_name,
4334 printf("%s:%d Failed to match ino number for %s\n",
4341 * Trying to open "BAD\\BAD\\BAD" should get
4342 * NT_STATUS_OBJECT_NAME_NOT_FOUND.
4344 status = get_smb2_inode(cli,
4347 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4348 printf("%s:%d Open of %s should get "
4349 "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
4357 * Trying to open "BAD\\BAD\\BAD\\BAD" should get
4358 * NT_STATUS_OBJECT_PATH_NOT_FOUND.
4360 status = get_smb2_inode(cli,
4361 "BAD\\BAD\\BAD\\BAD",
4363 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4364 printf("%s:%d Open of %s should get "
4365 "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
4368 "BAD\\BAD\\BAD\\BAD",
4373 * Test for invalid pathname characters in the servername.
4374 * They are ignored, and it still opens the share root.
4376 ino_matched = smb2_inode_matches(cli,
4377 dfs_root_share_name,
4381 printf("%s:%d Failed to match ino number for %s\n",
4389 * Test for invalid pathname characters in the sharename.
4390 * Invalid sharename characters should still be flagged as
4391 * NT_STATUS_OBJECT_NAME_INVALID. It turns out only ':'
4392 * is considered an invalid sharename character.
4394 ok = test_smb2_dfs_sharenames(cli,
4395 dfs_root_share_name,
4401 /* Now create a file called "file". */
4402 status = smb2cli_create(cli->conn,
4407 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4408 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4409 SEC_STD_SYNCHRONIZE|
4412 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4413 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4414 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4415 FILE_CREATE, /* create_disposition, */
4416 0, /* create_options, */
4417 NULL, /* smb2_create_blobs *blobs */
4420 NULL, /* struct smb_create_returns * */
4421 talloc_tos(), /* mem_ctx. */
4422 NULL, /* struct smb2_create_blobs * */
4423 NULL); /* struct symlink_reparse_struct */
4424 if (!NT_STATUS_IS_OK(status)) {
4425 printf("%s:%d smb2cli_create on %s returned %s\n",
4434 * Trying to open "BAD\\BAD\\file" should now get
4437 status = get_smb2_inode(cli,
4440 if (!NT_STATUS_IS_OK(status)) {
4441 printf("%s:%d Open of %s should succeed "
4451 * Now show that renames use relative,
4452 * not full DFS paths.
4455 /* Full DFS path should fail. */
4456 status = smb2_dfs_rename(cli,
4459 "ANY\\NAME\\renamed_file");
4460 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4461 printf("%s:%d Rename of %s -> %s should fail "
4462 "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4466 "ANY\\NAME\\renamed_file",
4470 /* Relative DFS path should succeed. */
4471 status = smb2_dfs_rename(cli,
4475 if (!NT_STATUS_IS_OK(status)) {
4476 printf("%s:%d: Rename of %s -> %s should succeed. "
4487 * Trying to open "BAD\\BAD\\renamed_file" should now get
4490 status = get_smb2_inode(cli,
4491 "BAD\\BAD\\renamed_file",
4493 if (!NT_STATUS_IS_OK(status)) {
4494 printf("%s:%d: Open of %s should succeed "
4498 "BAD\\BAD\\renamed_file",
4504 * Now show that hard links use relative,
4505 * not full DFS paths.
4508 /* Full DFS path should fail. */
4509 status = smb2_dfs_hlink(cli,
4512 "ANY\\NAME\\hlink");
4513 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4514 printf("%s:%d Hlink of %s -> %s should fail "
4515 "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4518 "ANY\\NAME\\renamed_file",
4523 /* Relative DFS path should succeed. */
4524 status = smb2_dfs_hlink(cli,
4528 if (!NT_STATUS_IS_OK(status)) {
4529 printf("%s:%d: Hlink of %s -> %s should succeed. "
4533 "ANY\\NAME\\renamed_file",
4540 * Trying to open "BAD\\BAD\\hlink" should now get
4543 status = get_smb2_inode(cli,
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("%s:%d Open of %s should succeed "
4560 if (fid_persistent != 0 || fid_volatile != 0) {
4561 smb2cli_close(cli->conn,
4569 /* Delete anything we made. */
4570 (void)smb2_dfs_delete(cli, "BAD\\BAD\\BAD");
4571 (void)smb2_dfs_delete(cli, "BAD\\BAD\\file");
4572 (void)smb2_dfs_delete(cli, "BAD\\BAD\\renamed_file");
4573 (void)smb2_dfs_delete(cli, "BAD\\BAD\\hlink");
4578 * Add a test that sends DFS paths and sets the
4579 * SMB2 flag FLAGS2_DFS_PATHNAMES, but to a non-DFS
4580 * share. Windows passes this (it just treats the
4581 * pathnames as non-DFS and ignores the FLAGS2_DFS_PATHNAMES
4585 bool run_smb2_non_dfs_share(int dummy)
4587 struct cli_state *cli = NULL;
4589 bool dfs_supported = false;
4590 uint64_t fid_persistent = 0;
4591 uint64_t fid_volatile = 0;
4592 bool retval = false;
4593 char *dfs_filename = NULL;
4595 printf("Starting SMB2-DFS-NON-DFS-SHARE\n");
4597 if (!torture_init_connection(&cli)) {
4601 status = smbXcli_negprot(cli->conn,
4605 if (!NT_STATUS_IS_OK(status)) {
4606 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4610 status = cli_session_setup_creds(cli, torture_creds);
4611 if (!NT_STATUS_IS_OK(status)) {
4612 printf("cli_session_setup returned %s\n", nt_errstr(status));
4616 status = cli_tree_connect(cli, share, "?????", NULL);
4617 if (!NT_STATUS_IS_OK(status)) {
4618 printf("cli_tree_connect returned %s\n", nt_errstr(status));
4622 dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4623 if (!dfs_supported) {
4624 printf("Server %s does not support DFS\n",
4625 smbXcli_conn_remote_name(cli->conn));
4628 /* Ensure this is *NOT* a DFS share. */
4629 dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4630 if (dfs_supported) {
4631 printf("Share %s is a DFS share.\n",
4636 * Force the share to be DFS, as far as the client
4639 smb2cli_tcon_set_values(cli->smb2.tcon,
4641 smb2cli_tcon_current_id(cli->smb2.tcon),
4643 smb2cli_tcon_flags(cli->smb2.tcon),
4644 smb2cli_tcon_capabilities(cli->smb2.tcon) |
4648 /* Come up with a "valid" SMB2 DFS name. */
4649 dfs_filename = talloc_asprintf(talloc_tos(),
4651 smbXcli_conn_remote_name(cli->conn),
4653 if (dfs_filename == NULL) {
4654 printf("Out of memory\n");
4658 /* Now try create dfs_filename. */
4659 status = smb2cli_create(cli->conn,
4664 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4665 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4666 SEC_STD_SYNCHRONIZE|
4669 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4670 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4671 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4672 FILE_CREATE, /* create_disposition, */
4673 0, /* create_options, */
4674 NULL, /* smb2_create_blobs *blobs */
4677 NULL, /* struct smb_create_returns * */
4678 talloc_tos(), /* mem_ctx. */
4679 NULL, /* struct smb2_create_blobs */
4680 NULL); /* struct symlink_reparse_struct */
4682 * Should fail with NT_STATUS_OBJECT_PATH_NOT_FOUND, as
4683 * even though we set the FLAGS2_DFS_PATHNAMES the server
4684 * knows this isn't a DFS share and so treats BAD\\BAD as
4685 * part of the filename.
4687 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4688 printf("%s:%d create of %s should fail "
4689 "with NT_STATUS_OBJECT_PATH_NOT_FOUND. Got %s\n",
4697 * Prove we can still use non-DFS pathnames, even though
4698 * we are setting the FLAGS2_DFS_PATHNAMES in the SMB2
4701 status = smb2cli_create(cli->conn,
4706 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4707 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4708 SEC_STD_SYNCHRONIZE|
4711 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4712 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4713 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4714 FILE_CREATE, /* create_disposition, */
4715 0, /* create_options, */
4716 NULL, /* smb2_create_blobs *blobs */
4719 NULL, /* struct smb_create_returns * */
4720 talloc_tos(), /* mem_ctx. */
4721 NULL, /* struct smb2_create_blobs * */
4722 NULL); /* struct symlink_reparse_struct */
4723 if (!NT_STATUS_IS_OK(status)) {
4724 printf("%s:%d smb2cli_create on %s returned %s\n",
4736 (void)smb2_dfs_delete(cli, dfs_filename);
4737 (void)smb2_dfs_delete(cli, "file");
4742 * Add a test that sends a non-DFS path and does not set the
4743 * SMB2 flag FLAGS2_DFS_PATHNAMES to a DFS
4744 * share. Windows passes this (it just treats the
4745 * pathnames as non-DFS).
4748 bool run_smb2_dfs_share_non_dfs_path(int dummy)
4750 struct cli_state *cli = NULL;
4752 bool dfs_supported = false;
4753 uint64_t fid_persistent = 0;
4754 uint64_t fid_volatile = 0;
4755 bool retval = false;
4756 char *dfs_filename = NULL;
4757 uint64_t root_ino = (uint64_t)-1;
4758 bool ino_matched = false;
4760 printf("Starting SMB2-DFS-SHARE-NON-DFS-PATH\n");
4762 if (!torture_init_connection(&cli)) {
4766 status = smbXcli_negprot(cli->conn,
4770 if (!NT_STATUS_IS_OK(status)) {
4771 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
4775 status = cli_session_setup_creds(cli, torture_creds);
4776 if (!NT_STATUS_IS_OK(status)) {
4777 printf("cli_session_setup returned %s\n", nt_errstr(status));
4781 status = cli_tree_connect(cli, share, "?????", NULL);
4782 if (!NT_STATUS_IS_OK(status)) {
4783 printf("cli_tree_connect returned %s\n", nt_errstr(status));
4787 dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
4788 if (!dfs_supported) {
4789 printf("Server %s does not support DFS\n",
4790 smbXcli_conn_remote_name(cli->conn));
4793 /* Ensure this is a DFS share. */
4794 dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
4795 if (!dfs_supported) {
4796 printf("Share %s is not a DFS share.\n",
4800 /* Come up with a "valid" SMB2 DFS name. */
4801 dfs_filename = talloc_asprintf(talloc_tos(),
4803 smbXcli_conn_remote_name(cli->conn),
4805 if (dfs_filename == NULL) {
4806 printf("Out of memory\n");
4810 /* Get the root of the share ino. */
4811 status = get_smb2_inode(cli,
4814 if (!NT_STATUS_IS_OK(status)) {
4815 printf("%s:%d get_smb2_inode on %s returned %s\n",
4823 /* Create a dfs_filename. */
4824 status = smb2cli_create(cli->conn,
4829 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4830 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4831 SEC_STD_SYNCHRONIZE|
4834 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4835 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4836 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4837 FILE_CREATE, /* create_disposition, */
4838 0, /* create_options, */
4839 NULL, /* smb2_create_blobs *blobs */
4842 NULL, /* struct smb_create_returns * */
4843 talloc_tos(), /* mem_ctx. */
4844 NULL, /* struct smb2_create_blobs * */
4845 NULL); /* psymlink */
4846 if (!NT_STATUS_IS_OK(status)) {
4847 printf("%s:%d smb2cli_create on %s returned %s\n",
4855 /* Close the handle we just opened. */
4856 smb2cli_close(cli->conn,
4868 * Force the share to be non-DFS, as far as the client
4871 smb2cli_tcon_set_values(cli->smb2.tcon,
4873 smb2cli_tcon_current_id(cli->smb2.tcon),
4875 smb2cli_tcon_flags(cli->smb2.tcon),
4876 smb2cli_tcon_capabilities(cli->smb2.tcon) &
4877 ~SMB2_SHARE_CAP_DFS,
4881 * Prove we can still use non-DFS pathnames on a DFS
4882 * share so long as we don't set the FLAGS2_DFS_PATHNAMES
4883 * in the SMB2 request.
4885 status = smb2cli_create(cli->conn,
4890 SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
4891 SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
4892 SEC_STD_SYNCHRONIZE|
4895 SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
4896 FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
4897 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
4898 FILE_OPEN, /* create_disposition, */
4899 0, /* create_options, */
4900 NULL, /* smb2_create_blobs *blobs */
4903 NULL, /* struct smb_create_returns * */
4904 talloc_tos(), /* mem_ctx. */
4905 NULL, /* struct smb2_create_blobs * */
4906 NULL); /* psymlink */
4907 if (!NT_STATUS_IS_OK(status)) {
4908 printf("%s:%d smb2cli_create on %s returned %s\n",
4917 * Show that now we're using non-DFS pathnames
4918 * on a DFS share, "" opens the root of the share.
4920 ino_matched = smb2_inode_matches(cli,
4925 printf("%s:%d Failed to match ino number for %s\n",
4936 if (fid_volatile != 0) {
4937 smb2cli_close(cli->conn,
4945 (void)smb2_dfs_delete(cli, "file");
4946 (void)smb2_dfs_delete(cli, dfs_filename);