2 Unix SMB/CIFS implementation.
3 Copyright (C) Ralph Boehme 2020
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "torture/proto.h"
21 #include "libcli/security/security.h"
22 #include "libsmb/libsmb.h"
23 #include "libsmb/clirap.h"
24 #include "libsmb/proto.h"
25 #include "../libcli/smb/smbXcli_base.h"
27 extern struct cli_credentials *torture_creds;
28 extern fstring host, workgroup, share, password, username, myname;
30 struct posix_test_entry {
34 uint64_t returned_size;
38 static NTSTATUS posix_ls_fn(struct file_info *finfo,
42 struct posix_test_entry *state =
43 (struct posix_test_entry *)_state;
45 for (; state->name != NULL; state++) {
46 if (strequal(finfo->name, state->expected)) {
48 state->returned_size = finfo->size;
56 static void posix_test_entries_reset(struct posix_test_entry *state)
58 for (; state->name != NULL; state++) {
63 static bool posix_test_entry_check(struct posix_test_entry *state,
66 uint64_t expected_size)
70 for (; state->name != NULL; state++) {
71 if (strequal(name, state->name)) {
76 if (state->name == NULL) {
77 printf("test failed, unknown name: %s\n", name);
81 if (expected == result) {
85 printf("test failed, %s: %s\n",
86 expected ? "missing" : "unexpected",
93 Test non-POSIX vs POSIX ls * of symlinks
95 bool run_posix_ls_wildcard_test(int dummy)
97 TALLOC_CTX *frame = NULL;
98 struct cli_state *cli_unix = NULL;
99 struct cli_state *cli_win = NULL;
100 uint16_t fnum = (uint16_t)-1;
102 const char *file = "file";
103 const char *symlnk_dangling = "dangling";
104 const char *symlnk_dst_dangling = "xxxxxxx";
105 const char *symlnk_in_share = "symlnk_in_share";
106 const char *symlnk_dst_in_share = file;
107 const char *symlnk_outside_share = "symlnk_outside_share";
108 const char *symlnk_dst_outside_share = "/etc/passwd";
109 struct posix_test_entry state[] = {
111 .name = symlnk_dangling,
112 .target = symlnk_dst_dangling,
113 .expected = symlnk_dangling,
115 .name = symlnk_in_share,
116 .target = symlnk_dst_in_share,
117 .expected = symlnk_in_share,
119 .name = symlnk_outside_share,
120 .target = symlnk_dst_outside_share,
121 .expected = symlnk_outside_share,
127 bool correct = false;
129 frame = talloc_stackframe();
131 printf("Starting POSIX-LS-WILDCARD test\n");
133 if (!torture_open_connection(&cli_unix, 0)) {
138 if (!torture_open_connection(&cli_win, 0)) {
143 torture_conn_set_sockopt(cli_unix);
144 torture_conn_set_sockopt(cli_win);
146 status = torture_setup_unix_extensions(cli_unix);
147 if (!NT_STATUS_IS_OK(status)) {
152 cli_posix_unlink(cli_unix, file);
153 cli_posix_unlink(cli_unix, symlnk_dangling);
154 cli_posix_unlink(cli_unix, symlnk_in_share);
155 cli_posix_unlink(cli_unix, symlnk_outside_share);
157 status = cli_posix_open(cli_unix,
162 if (!NT_STATUS_IS_OK(status)) {
163 printf("cli_posix_open of %s failed error %s\n",
169 status = cli_close(cli_unix, fnum);
170 if (!NT_STATUS_IS_OK(status)) {
171 printf("cli_close failed %s\n", nt_errstr(status));
176 for (i = 0; state[i].name != NULL; i++) {
177 status = cli_posix_symlink(cli_unix,
180 if (!NT_STATUS_IS_OK(status)) {
181 printf("POSIX symlink of %s failed (%s)\n",
182 symlnk_dangling, nt_errstr(status));
187 printf("Doing Windows ls *\n");
189 status = cli_list(cli_win, "*", 0, posix_ls_fn, state);
190 if (!NT_STATUS_IS_OK(status)) {
191 printf("cli_close failed %s\n", nt_errstr(status));
195 if (!posix_test_entry_check(state, symlnk_dangling, false, 0)) {
198 if (!posix_test_entry_check(state, symlnk_outside_share, false, 0)) {
201 if (!posix_test_entry_check(state, symlnk_in_share, true, 0)) {
205 posix_test_entries_reset(state);
207 printf("Doing POSIX ls *\n");
209 status = cli_list(cli_unix, "*", 0, posix_ls_fn, state);
210 if (!NT_STATUS_IS_OK(status)) {
211 printf("cli_close failed %s\n", nt_errstr(status));
215 if (!posix_test_entry_check(state,
218 strlen(symlnk_dst_dangling)))
222 if (!posix_test_entry_check(state,
223 symlnk_outside_share,
225 strlen(symlnk_dst_outside_share)))
229 if (!posix_test_entry_check(state,
232 strlen(symlnk_dst_in_share))) {
236 printf("POSIX-LS-WILDCARD test passed\n");
240 cli_posix_unlink(cli_unix, file);
241 cli_posix_unlink(cli_unix, symlnk_dangling);
242 cli_posix_unlink(cli_unix, symlnk_in_share);
243 cli_posix_unlink(cli_unix, symlnk_outside_share);
245 if (!torture_close_connection(cli_unix)) {
248 if (!torture_close_connection(cli_win)) {
257 Test non-POSIX vs POSIX ls single of symlinks
259 bool run_posix_ls_single_test(int dummy)
261 TALLOC_CTX *frame = NULL;
262 struct cli_state *cli_unix = NULL;
263 struct cli_state *cli_win = NULL;
264 uint16_t fnum = (uint16_t)-1;
266 const char *file = "file";
267 const char *symlnk_dangling = "dangling";
268 const char *symlnk_dst_dangling = "xxxxxxx";
269 const char *symlnk_in_share = "symlnk_in_share";
270 const char *symlnk_dst_in_share = file;
271 const char *symlnk_outside_share = "symlnk_outside_share";
272 const char *symlnk_dst_outside_share = "/etc/passwd";
273 struct posix_test_entry state[] = {
275 .name = symlnk_dangling,
276 .target = symlnk_dst_dangling,
277 .expected = symlnk_dangling,
279 .name = symlnk_in_share,
280 .target = symlnk_dst_in_share,
281 .expected = symlnk_in_share,
283 .name = symlnk_outside_share,
284 .target = symlnk_dst_outside_share,
285 .expected = symlnk_outside_share,
291 bool correct = false;
293 frame = talloc_stackframe();
295 printf("Starting POSIX-LS-SINGLE test\n");
297 if (!torture_open_connection(&cli_unix, 0)) {
302 if (!torture_init_connection(&cli_win)) {
307 status = smbXcli_negprot(cli_win->conn,
309 lp_client_min_protocol(),
310 lp_client_max_protocol());
311 if (!NT_STATUS_IS_OK(status)) {
312 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
317 status = cli_session_setup_creds(cli_win, torture_creds);
318 if (!NT_STATUS_IS_OK(status)) {
319 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
324 status = cli_tree_connect(cli_win, share, "?????", NULL);
325 if (!NT_STATUS_IS_OK(status)) {
326 printf("cli_tree_connect returned %s\n", nt_errstr(status));
330 torture_conn_set_sockopt(cli_unix);
331 torture_conn_set_sockopt(cli_win);
333 status = torture_setup_unix_extensions(cli_unix);
334 if (!NT_STATUS_IS_OK(status)) {
339 cli_posix_unlink(cli_unix, file);
340 cli_posix_unlink(cli_unix, symlnk_dangling);
341 cli_posix_unlink(cli_unix, symlnk_in_share);
342 cli_posix_unlink(cli_unix, symlnk_outside_share);
344 status = cli_posix_open(cli_unix,
349 if (!NT_STATUS_IS_OK(status)) {
350 printf("cli_posix_open of %s failed error %s\n",
356 status = cli_close(cli_unix, fnum);
357 if (!NT_STATUS_IS_OK(status)) {
358 printf("cli_close failed %s\n", nt_errstr(status));
363 for (i = 0; state[i].name != NULL; i++) {
364 status = cli_posix_symlink(cli_unix,
367 if (!NT_STATUS_IS_OK(status)) {
368 printf("POSIX symlink of %s failed (%s)\n",
369 symlnk_dangling, nt_errstr(status));
374 printf("Doing Windows ls single\n");
376 cli_list(cli_win, symlnk_dangling, 0, posix_ls_fn, state);
377 cli_list(cli_win, symlnk_outside_share, 0, posix_ls_fn, state);
378 cli_list(cli_win, symlnk_in_share, 0, posix_ls_fn, state);
380 if (!posix_test_entry_check(state, symlnk_dangling, false, 0)) {
383 if (!posix_test_entry_check(state, symlnk_outside_share, false, 0)) {
386 if (!posix_test_entry_check(state, symlnk_in_share, true, 0)) {
390 posix_test_entries_reset(state);
392 printf("Doing POSIX ls single\n");
394 cli_list(cli_unix, symlnk_dangling, 0, posix_ls_fn, state);
395 cli_list(cli_unix, symlnk_outside_share, 0, posix_ls_fn, state);
396 cli_list(cli_unix, symlnk_in_share, 0, posix_ls_fn, state);
398 if (!posix_test_entry_check(state,
401 strlen(symlnk_dst_dangling)))
405 if (!posix_test_entry_check(state,
406 symlnk_outside_share,
408 strlen(symlnk_dst_outside_share)))
412 if (!posix_test_entry_check(state,
415 strlen(symlnk_dst_in_share))) {
419 printf("POSIX-LS-SINGLE test passed\n");
423 cli_posix_unlink(cli_unix, file);
424 cli_posix_unlink(cli_unix, symlnk_dangling);
425 cli_posix_unlink(cli_unix, symlnk_in_share);
426 cli_posix_unlink(cli_unix, symlnk_outside_share);
428 if (!torture_close_connection(cli_unix)) {
431 if (!torture_close_connection(cli_win)) {
440 Test POSIX readlink of symlinks
442 bool run_posix_readlink_test(int dummy)
444 TALLOC_CTX *frame = NULL;
445 struct cli_state *cli_unix = NULL;
446 uint16_t fnum = (uint16_t)-1;
448 const char *file = "file";
449 const char *symlnk_dangling = "dangling";
450 const char *symlnk_dst_dangling = "xxxxxxx";
451 const char *symlnk_in_share = "symlnk_in_share";
452 const char *symlnk_dst_in_share = file;
453 const char *symlnk_outside_share = "symlnk_outside_share";
454 const char *symlnk_dst_outside_share = "/etc/passwd";
455 struct posix_test_entry state[] = {
457 .name = symlnk_dangling,
458 .target = symlnk_dst_dangling,
459 .expected = symlnk_dangling,
461 .name = symlnk_in_share,
462 .target = symlnk_dst_in_share,
463 .expected = symlnk_in_share,
465 .name = symlnk_outside_share,
466 .target = symlnk_dst_outside_share,
467 .expected = symlnk_outside_share,
473 bool correct = false;
475 frame = talloc_stackframe();
477 printf("Starting POSIX-READLINK test\n");
479 if (!torture_open_connection(&cli_unix, 0)) {
484 torture_conn_set_sockopt(cli_unix);
486 status = torture_setup_unix_extensions(cli_unix);
487 if (!NT_STATUS_IS_OK(status)) {
492 cli_posix_unlink(cli_unix, file);
493 cli_posix_unlink(cli_unix, symlnk_dangling);
494 cli_posix_unlink(cli_unix, symlnk_in_share);
495 cli_posix_unlink(cli_unix, symlnk_outside_share);
497 status = cli_posix_open(cli_unix,
502 if (!NT_STATUS_IS_OK(status)) {
503 printf("cli_posix_open of %s failed error %s\n",
509 status = cli_close(cli_unix, fnum);
510 if (!NT_STATUS_IS_OK(status)) {
511 printf("cli_close failed %s\n", nt_errstr(status));
516 for (i = 0; state[i].name != NULL; i++) {
517 status = cli_posix_symlink(cli_unix,
520 if (!NT_STATUS_IS_OK(status)) {
521 printf("POSIX symlink of %s failed (%s)\n",
522 symlnk_dangling, nt_errstr(status));
527 for (i = 0; state[i].name != NULL; i++) {
530 status = cli_posix_readlink(cli_unix,
534 if (!NT_STATUS_IS_OK(status)) {
535 printf("POSIX readlink on %s failed (%s)\n",
536 state[i].name, nt_errstr(status));
539 if (strequal(target, state[i].target)) {
541 state[i].returned_size = strlen(target);
545 if (!posix_test_entry_check(state,
548 strlen(symlnk_dst_dangling)))
552 if (!posix_test_entry_check(state,
553 symlnk_outside_share,
555 strlen(symlnk_dst_outside_share)))
559 if (!posix_test_entry_check(state,
562 strlen(symlnk_dst_in_share))) {
566 printf("POSIX-READLINK test passed\n");
570 cli_posix_unlink(cli_unix, file);
571 cli_posix_unlink(cli_unix, symlnk_dangling);
572 cli_posix_unlink(cli_unix, symlnk_in_share);
573 cli_posix_unlink(cli_unix, symlnk_outside_share);
575 if (!torture_close_connection(cli_unix)) {