2 Unix SMB/CIFS implementation.
4 Copyright (C) Guenther Deschner 2010
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 "system/dir.h"
22 #include "torture/smbtorture.h"
23 #include "auth/credentials/credentials.h"
24 #include "lib/cmdline/cmdline.h"
25 #include <libsmbclient.h>
26 #include "torture/libsmbclient/proto.h"
27 #include "lib/param/loadparm.h"
28 #include "lib/param/param_global.h"
29 #include "libcli/smb/smb_constants.h"
30 #include "dynconfig.h"
31 #include "lib/util/time.h"
33 /* test string to compare with when debug_callback is called */
34 #define TEST_STRING "smbc_setLogCallback test"
36 /* Dummy log callback function */
37 static void debug_callback(void *private_ptr
, int level
, const char *msg
)
39 bool *found
= private_ptr
;
40 if (strstr(msg
, TEST_STRING
) != NULL
) {
46 static void auth_callback(const char *srv
,
52 const char *workgroup
=
53 cli_credentials_get_domain(samba_cmdline_get_creds());
54 const char *username
=
55 cli_credentials_get_username(samba_cmdline_get_creds());
56 const char *password
=
57 cli_credentials_get_password(samba_cmdline_get_creds());
60 if (workgroup
!= NULL
) {
61 ret
= strlcpy(wg
, workgroup
, wglen
);
67 if (username
!= NULL
) {
68 ret
= strlcpy(un
, username
, unlen
);
74 if (password
!= NULL
) {
75 ret
= strlcpy(pw
, password
, pwlen
);
82 bool torture_libsmbclient_init_context(struct torture_context
*tctx
,
85 const char *workgroup
=
86 cli_credentials_get_domain(samba_cmdline_get_creds());
87 const char *username
=
88 cli_credentials_get_username(samba_cmdline_get_creds());
89 const char *client_proto
=
90 torture_setting_string(tctx
, "clientprotocol", NULL
);
94 int dbglevel
= DEBUGLEVEL
;
96 ctx
= smbc_new_context();
97 torture_assert_not_null_goto(tctx
,
101 "Failed to create new context");
103 p
= smbc_init_context(ctx
);
104 torture_assert_not_null_goto(tctx
,
108 "Failed to initialize context");
110 smbc_setDebug(ctx
, dbglevel
);
111 smbc_setOptionDebugToStderr(ctx
, 1);
113 if (workgroup
!= NULL
) {
114 smbc_setWorkgroup(ctx
, workgroup
);
116 if (username
!= NULL
) {
117 smbc_setUser(ctx
, username
);
120 smbc_setFunctionAuthData(ctx
, auth_callback
);
122 if (client_proto
!= NULL
) {
123 smbc_setOptionProtocols(ctx
, client_proto
, client_proto
);
130 smbc_free_context(ctx
, 1);
136 static bool torture_libsmbclient_version(struct torture_context
*tctx
)
138 torture_comment(tctx
, "Testing smbc_version\n");
140 torture_assert(tctx
, smbc_version(), "failed to get version");
145 static bool torture_libsmbclient_initialize(struct torture_context
*tctx
)
150 torture_comment(tctx
, "Testing smbc_new_context\n");
152 ctx
= smbc_new_context();
153 torture_assert(tctx
, ctx
, "failed to get new context");
155 torture_comment(tctx
, "Testing smbc_init_context\n");
157 torture_assert(tctx
, smbc_init_context(ctx
), "failed to init context");
159 smbc_setLogCallback(ctx
, &ret
, debug_callback
);
160 DEBUG(0, (TEST_STRING
"\n"));
161 torture_assert(tctx
, ret
, "Failed debug_callback not called");
163 smbc_setLogCallback(ctx
, NULL
, NULL
);
164 DEBUG(0, (TEST_STRING
"\n"));
165 torture_assert(tctx
, !ret
, "Failed debug_callback called");
167 smbc_free_context(ctx
, 1);
172 static bool torture_libsmbclient_setConfiguration(struct torture_context
*tctx
)
175 struct loadparm_global
*global_config
= NULL
;
176 const char *new_smb_conf
= torture_setting_string(tctx
,
180 ctx
= smbc_new_context();
181 torture_assert_not_null(tctx
, ctx
, "failed to get new context");
183 torture_assert_not_null(
184 tctx
, smbc_init_context(ctx
), "failed to init context");
186 torture_comment(tctx
, "Testing smbc_setConfiguration - new file %s\n",
189 global_config
= get_globals();
190 torture_assert(tctx
, global_config
, "Global Config is NULL");
192 /* check configuration before smbc_setConfiguration call */
193 torture_comment(tctx
, "'workgroup' before setConfiguration %s\n",
194 global_config
->workgroup
);
195 torture_comment(tctx
, "'client min protocol' before "
196 "setConfiguration %d\n",
197 global_config
->client_min_protocol
);
198 torture_comment(tctx
, "'client max protocol' before "
199 "setConfiguration %d\n",
200 global_config
->_client_max_protocol
);
201 torture_comment(tctx
, "'client signing' before setConfiguration %d\n",
202 global_config
->client_signing
);
203 torture_comment(tctx
, "'deadtime' before setConfiguration %d\n",
204 global_config
->deadtime
);
206 torture_assert_int_equal(tctx
, smbc_setConfiguration(ctx
, new_smb_conf
),
207 0, "setConfiguration conf file not found");
209 /* verify configuration */
210 torture_assert_str_equal(tctx
, global_config
->workgroup
,
212 "smbc_setConfiguration failed, "
213 "'workgroup' not updated");
214 torture_assert_int_equal(tctx
, global_config
->client_min_protocol
, PROTOCOL_NT1
,
215 "smbc_setConfiguration failed, 'client min protocol' "
217 torture_assert_int_equal(tctx
, global_config
->_client_max_protocol
, PROTOCOL_SMB3_00
,
218 "smbc_setConfiguration failed, 'client max protocol' "
220 torture_assert_int_equal(tctx
, global_config
->client_signing
, 1,
221 "smbc_setConfiguration failed, 'client signing' "
223 torture_assert_int_equal(tctx
, global_config
->deadtime
, 5,
224 "smbc_setConfiguration failed, 'deadtime' not updated");
226 /* Restore configuration to default */
227 smbc_setConfiguration(ctx
, get_dyn_CONFIGFILE());
229 smbc_free_context(ctx
, 1);
234 static bool test_opendir(struct torture_context
*tctx
,
241 torture_comment(tctx
, "Testing smbc_opendir(%s)\n", fname
);
243 handle
= smbc_opendir(fname
);
244 if (!expect_success
) {
248 torture_fail(tctx
, talloc_asprintf(tctx
, "failed to obain file handle for '%s'", fname
));
251 ret
= smbc_closedir(handle
);
252 torture_assert_int_equal(tctx
, ret
, 0,
253 talloc_asprintf(tctx
, "failed to close file handle for '%s'", fname
));
258 static bool torture_libsmbclient_opendir(struct torture_context
*tctx
)
263 const char *bad_urls
[] = {
279 const char *good_urls
[] = {
285 torture_assert(tctx
, torture_libsmbclient_init_context(tctx
, &ctx
), "");
286 smbc_set_context(ctx
);
288 for (i
=0; i
< ARRAY_SIZE(bad_urls
); i
++) {
289 ret
&= test_opendir(tctx
, ctx
, bad_urls
[i
], false);
291 for (i
=0; i
< ARRAY_SIZE(good_urls
); i
++) {
292 ret
&= test_opendir(tctx
, ctx
, good_urls
[i
], true);
295 smbc_free_context(ctx
, 1);
300 static bool torture_libsmbclient_readdirplus(struct torture_context
*tctx
)
307 const char *filename
= NULL
;
308 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
310 if (smburl
== NULL
) {
312 "option --option=torture:smburl="
313 "smb://user:password@server/share missing\n");
316 torture_assert(tctx
, torture_libsmbclient_init_context(tctx
, &ctx
), "");
317 smbc_set_context(ctx
);
319 filename
= talloc_asprintf(tctx
,
320 "%s/test_readdirplus.txt",
322 if (filename
== NULL
) {
326 /* Ensure the file doesn't exist. */
327 smbc_unlink(filename
);
330 fhandle
= smbc_creat(filename
, 0666);
333 talloc_asprintf(tctx
,
334 "failed to create file '%s': %s",
338 ret
= smbc_close(fhandle
);
339 torture_assert_int_equal(tctx
,
342 talloc_asprintf(tctx
,
343 "failed to close handle for '%s'",
346 dhandle
= smbc_opendir(smburl
);
348 int saved_errno
= errno
;
349 smbc_unlink(filename
);
351 talloc_asprintf(tctx
,
353 "directory handle for '%s' : %s",
355 strerror(saved_errno
)));
358 /* Readdirplus to ensure we see the new file. */
360 const struct libsmb_file_info
*exstat
=
361 smbc_readdirplus(dhandle
);
362 if (exstat
== NULL
) {
365 if (strcmp(exstat
->name
, "test_readdirplus.txt") == 0) {
371 /* Remove it again. */
372 smbc_unlink(filename
);
373 ret
= smbc_closedir(dhandle
);
374 torture_assert_int_equal(tctx
,
377 talloc_asprintf(tctx
,
378 "failed to close directory handle for '%s'",
381 smbc_free_context(ctx
, 1);
385 talloc_asprintf(tctx
,
386 "failed to find file '%s'",
393 static bool torture_libsmbclient_readdirplus_seek(struct torture_context
*tctx
)
399 const char *dname
= NULL
;
400 const char *full_filename
[100] = {0};
401 const char *filename
[100] = {0};
402 const struct libsmb_file_info
*direntries
[102] = {0};
404 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
405 bool success
= false;
406 off_t telldir_50
= (off_t
)-1;
407 off_t telldir_20
= (off_t
)-1;
408 size_t getdentries_size
= 0;
409 struct smbc_dirent
*getdentries
= NULL
;
410 struct smbc_dirent
*dirent_20
= NULL
;
411 const struct libsmb_file_info
*direntries_20
= NULL
;
412 const struct libsmb_file_info
*direntriesplus_20
= NULL
;
413 const char *plus2_stat_path
= NULL
;
414 struct stat st
= {0};
415 struct stat st2
= {0};
417 torture_assert_not_null(
420 "option --option=torture:smburl="
421 "smb://user:password@server/share missing\n");
423 DEBUG(0,("torture_libsmbclient_readdirplus_seek start\n"));
425 torture_assert(tctx
, torture_libsmbclient_init_context(tctx
, &ctx
), "");
426 smbc_set_context(ctx
);
428 dname
= talloc_asprintf(tctx
,
431 torture_assert_not_null_goto(
432 tctx
, dname
, success
, done
, "talloc fail\n");
434 /* Ensure the files don't exist. */
435 for (i
= 0; i
< 100; i
++) {
436 filename
[i
] = talloc_asprintf(tctx
,
437 "test_readdirplus_%u.txt",
439 torture_assert_not_null_goto(
440 tctx
, filename
[i
], success
, done
, "talloc fail");
441 full_filename
[i
] = talloc_asprintf(tctx
,
445 torture_assert_not_null_goto(
446 tctx
, full_filename
[i
], success
, done
, "talloc fail");
447 (void)smbc_unlink(full_filename
[i
]);
449 /* Ensure the directory doesn't exist. */
450 (void)smbc_rmdir(dname
);
452 /* Create containing directory. */
453 ret
= smbc_mkdir(dname
, 0777);
459 talloc_asprintf(tctx
,
460 "failed to create directory '%s': %s",
464 DEBUG(0,("torture_libsmbclient_readdirplus_seek create\n"));
467 for (i
= 0; i
< 100; i
++) {
468 fhandle
= smbc_creat(full_filename
[i
], 0666);
470 torture_fail_goto(tctx
,
472 talloc_asprintf(tctx
,
473 "failed to create file '%s': %s",
477 ret
= smbc_close(fhandle
);
478 torture_assert_int_equal_goto(tctx
,
483 talloc_asprintf(tctx
,
484 "failed to close handle for '%s'",
488 DEBUG(0,("torture_libsmbclient_readdirplus_seek enum\n"));
490 /* Now enumerate the directory. */
491 dhandle
= smbc_opendir(dname
);
497 talloc_asprintf(tctx
,
499 "directory handle for '%s' : %s",
503 /* Read all the files. 100 we created plus . and .. */
504 for (i
= 0; i
< 102; i
++) {
508 direntries
[i
] = smbc_readdirplus(dhandle
);
509 if (direntries
[i
] == NULL
) {
513 /* Store at offset 50. */
515 telldir_50
= smbc_telldir(dhandle
);
518 telldir_50
!= (off_t
)-1,
521 talloc_asprintf(tctx
,
522 "telldir failed file %s\n",
523 direntries
[i
]->name
));
526 if (ISDOT(direntries
[i
]->name
)) {
529 if (ISDOTDOT(direntries
[i
]->name
)) {
533 /* Ensure all our files exist. */
534 for (j
= 0; j
< 100; j
++) {
535 if (strcmp(direntries
[i
]->name
,
545 talloc_asprintf(tctx
,
546 "failed to find file %s\n",
547 direntries
[i
]->name
));
551 * We're seeking on in-memory lists here, so
552 * whilst the handle is open we really should
553 * get the same files back in the same order.
556 ret
= smbc_lseekdir(dhandle
, telldir_50
);
557 torture_assert_int_equal_goto(tctx
,
562 talloc_asprintf(tctx
,
563 "failed to seek (50) directory handle for '%s'",
566 DEBUG(0,("torture_libsmbclient_readdirplus_seek seek\n"));
568 for (i
= 51; i
< 102; i
++) {
569 const struct libsmb_file_info
*entry
=
570 smbc_readdirplus(dhandle
);
573 entry
== direntries
[i
],
576 talloc_asprintf(tctx
,
577 "after seek - failed to find "
578 "file %s - got %s\n",
583 /* Seek back to the start. */
584 ret
= smbc_lseekdir(dhandle
, 0);
585 torture_assert_int_equal_goto(tctx
,
590 talloc_asprintf(tctx
,
591 "failed to seek directory handle to start for '%s'",
595 * Mix getdents/readdir/readdirplus with lseek to ensure
596 * we get the same result.
599 /* Allocate the space for 20 entries.
600 * Tricky as we need to allocate 20 struct smbc_dirent's + space
601 * for the name lengths.
603 getdentries_size
= 20 * (sizeof(struct smbc_dirent
) +
604 strlen("test_readdirplus_1000.txt") + 1);
606 getdentries
= (struct smbc_dirent
*)talloc_array_size(tctx
,
609 torture_assert_not_null_goto(
616 ret
= smbc_getdents(dhandle
, getdentries
, getdentries_size
);
617 torture_assert_goto(tctx
,
621 talloc_asprintf(tctx
,
622 "smbd_getdents(1) for '%s' failed\n",
625 telldir_20
= smbc_telldir(dhandle
);
628 telldir_20
!= (off_t
)-1,
631 "telldir (20) failed\n");
633 /* Read another 20. */
634 ret
= smbc_getdents(dhandle
, getdentries
, getdentries_size
);
635 torture_assert_goto(tctx
,
639 talloc_asprintf(tctx
,
640 "smbd_getdents(2) for '%s' failed\n",
643 /* Seek back to 20. */
644 ret
= smbc_lseekdir(dhandle
, telldir_20
);
645 torture_assert_int_equal_goto(tctx
,
650 talloc_asprintf(tctx
,
651 "failed to seek (20) directory handle for '%s'",
654 /* Read with readdir. */
655 dirent_20
= smbc_readdir(dhandle
);
656 torture_assert_not_null_goto(
661 "smbc_readdir (20) failed\n");
663 /* Ensure the getdents and readdir names are the same. */
664 ret
= strcmp(dirent_20
->name
, getdentries
[0].name
);
670 talloc_asprintf(tctx
,
671 "after seek (20) readdir name mismatch "
672 "file %s - got %s\n",
674 getdentries
[0].name
));
676 /* Seek back to 20. */
677 ret
= smbc_lseekdir(dhandle
, telldir_20
);
678 torture_assert_int_equal_goto(tctx
,
683 talloc_asprintf(tctx
,
684 "failed to seek (20) directory handle for '%s'",
686 /* Read with readdirplus. */
687 direntries_20
= smbc_readdirplus(dhandle
);
688 torture_assert_not_null_goto(
693 "smbc_readdirplus (20) failed\n");
695 /* Ensure the readdirplus and readdir names are the same. */
696 ret
= strcmp(dirent_20
->name
, direntries_20
->name
);
702 talloc_asprintf(tctx
,
703 "after seek (20) readdirplus name mismatch "
704 "file %s - got %s\n",
706 direntries_20
->name
));
708 /* Seek back to 20. */
709 ret
= smbc_lseekdir(dhandle
, telldir_20
);
710 torture_assert_int_equal_goto(tctx
,
715 talloc_asprintf(tctx
,
716 "failed to seek (20) directory handle for '%s'",
719 /* Read with readdirplus2. */
720 direntriesplus_20
= smbc_readdirplus2(dhandle
, &st2
);
721 torture_assert_not_null_goto(
726 "smbc_readdirplus2 (20) failed\n");
728 /* Ensure the readdirplus2 and readdirplus names are the same. */
729 ret
= strcmp(direntries_20
->name
, direntriesplus_20
->name
);
735 talloc_asprintf(tctx
,
736 "after seek (20) readdirplus2 name mismatch "
737 "file %s - got %s\n",
739 direntries_20
->name
));
741 /* Ensure doing stat gets the same data. */
742 plus2_stat_path
= talloc_asprintf(tctx
,
745 direntriesplus_20
->name
);
746 torture_assert_not_null_goto(
753 ret
= smbc_stat(plus2_stat_path
, &st
);
754 torture_assert_int_equal_goto(tctx
,
759 talloc_asprintf(tctx
,
760 "failed to stat file '%s'",
763 torture_assert_int_equal(tctx
,
766 talloc_asprintf(tctx
,
767 "file %s mismatched ino value "
768 "stat got %"PRIx64
" readdirplus2 got %"PRIx64
"" ,
771 (uint64_t)st2
.st_ino
));
773 torture_assert_int_equal(tctx
,
776 talloc_asprintf(tctx
,
777 "file %s mismatched dev value "
778 "stat got %"PRIx64
" readdirplus2 got %"PRIx64
"" ,
781 (uint64_t)st2
.st_dev
));
783 ret
= smbc_closedir(dhandle
);
784 torture_assert_int_equal(tctx
,
787 talloc_asprintf(tctx
,
788 "failed to close directory handle for '%s'",
798 smbc_closedir(dhandle
);
800 for (i
= 0; i
< 100; i
++) {
801 if (full_filename
[i
] != NULL
) {
802 smbc_unlink(full_filename
[i
]);
809 smbc_free_context(ctx
, 1);
814 #ifndef SMBC_FILE_MODE
815 #define SMBC_FILE_MODE (S_IFREG | 0444)
818 static bool torture_libsmbclient_readdirplus2(struct torture_context
*tctx
)
824 bool success
= false;
825 const char *filename
= NULL
;
826 struct stat st2
= {0};
827 struct stat st
= {0};
829 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
831 if (smburl
== NULL
) {
833 "option --option=torture:smburl="
834 "smb://user:password@server/share missing\n");
837 torture_assert_goto(tctx
, torture_libsmbclient_init_context(tctx
, &ctx
), success
, done
, "");
838 smbc_set_context(ctx
);
840 filename
= talloc_asprintf(tctx
,
841 "%s/test_readdirplus.txt",
843 if (filename
== NULL
) {
844 torture_fail_goto(tctx
, done
, "talloc fail\n");
847 /* Ensure the file doesn't exist. */
848 smbc_unlink(filename
);
851 fhandle
= smbc_creat(filename
, 0666);
853 torture_fail_goto(tctx
,
855 talloc_asprintf(tctx
,
856 "failed to create file '%s': %s",
860 ret
= smbc_close(fhandle
);
861 torture_assert_int_equal_goto(tctx
,
866 talloc_asprintf(tctx
,
867 "failed to close handle for '%s'",
870 dhandle
= smbc_opendir(smburl
);
872 int saved_errno
= errno
;
873 smbc_unlink(filename
);
874 torture_fail_goto(tctx
,
876 talloc_asprintf(tctx
,
878 "directory handle for '%s' : %s",
880 strerror(saved_errno
)));
883 /* readdirplus2 to ensure we see the new file. */
885 const struct libsmb_file_info
*exstat
=
886 smbc_readdirplus2(dhandle
, &st2
);
887 if (exstat
== NULL
) {
891 if (strcmp(exstat
->name
, "test_readdirplus.txt") == 0) {
898 smbc_unlink(filename
);
899 torture_fail_goto(tctx
,
901 talloc_asprintf(tctx
,
902 "failed to find file '%s'",
906 /* Ensure mode is as expected. */
908 * New file gets SMBC_FILE_MODE plus
909 * archive bit -> S_IXUSR
910 * !READONLY -> S_IWUSR.
912 torture_assert_int_equal_goto(tctx
,
914 SMBC_FILE_MODE
|S_IXUSR
|S_IWUSR
,
917 talloc_asprintf(tctx
,
918 "file %s st_mode should be 0%o, got 0%o'",
920 SMBC_FILE_MODE
|S_IXUSR
|S_IWUSR
,
921 (unsigned int)st2
.st_mode
));
923 /* Ensure smbc_stat() gets the same data. */
924 ret
= smbc_stat(filename
, &st
);
925 torture_assert_int_equal_goto(tctx
,
930 talloc_asprintf(tctx
,
931 "failed to stat file '%s'",
934 torture_assert_int_equal_goto(tctx
,
939 talloc_asprintf(tctx
,
940 "filename '%s' ino mismatch. "
941 "From smbc_readdirplus2 = %"PRIx64
" "
942 "From smbc_stat = %"PRIx64
"",
944 (uint64_t)st2
.st_ino
,
945 (uint64_t)st
.st_ino
));
948 /* Remove it again. */
949 smbc_unlink(filename
);
950 ret
= smbc_closedir(dhandle
);
951 torture_assert_int_equal_goto(tctx
,
956 talloc_asprintf(tctx
,
957 "failed to close directory handle for '%s'",
962 smbc_free_context(ctx
, 1);
966 bool torture_libsmbclient_configuration(struct torture_context
*tctx
)
971 ctx
= smbc_new_context();
972 torture_assert(tctx
, ctx
, "failed to get new context");
973 torture_assert(tctx
, smbc_init_context(ctx
), "failed to init context");
975 torture_comment(tctx
, "Testing smbc_(set|get)Debug\n");
976 smbc_setDebug(ctx
, DEBUGLEVEL
);
977 torture_assert_int_equal_goto(tctx
,
982 "failed to set DEBUGLEVEL");
984 torture_comment(tctx
, "Testing smbc_(set|get)NetbiosName\n");
985 smbc_setNetbiosName(ctx
, discard_const("torture_netbios"));
986 torture_assert_str_equal_goto(tctx
,
987 smbc_getNetbiosName(ctx
),
991 "failed to set NetbiosName");
993 torture_comment(tctx
, "Testing smbc_(set|get)Workgroup\n");
994 smbc_setWorkgroup(ctx
, discard_const("torture_workgroup"));
995 torture_assert_str_equal_goto(tctx
,
996 smbc_getWorkgroup(ctx
),
1000 "failed to set Workgroup");
1002 torture_comment(tctx
, "Testing smbc_(set|get)User\n");
1003 smbc_setUser(ctx
, "torture_user");
1004 torture_assert_str_equal_goto(tctx
,
1009 "failed to set User");
1011 torture_comment(tctx
, "Testing smbc_(set|get)Timeout\n");
1012 smbc_setTimeout(ctx
, 12345);
1013 torture_assert_int_equal_goto(tctx
,
1014 smbc_getTimeout(ctx
),
1018 "failed to set Timeout");
1021 smbc_free_context(ctx
, 1);
1026 bool torture_libsmbclient_options(struct torture_context
*tctx
)
1031 ctx
= smbc_new_context();
1032 torture_assert(tctx
, ctx
, "failed to get new context");
1033 torture_assert(tctx
, smbc_init_context(ctx
), "failed to init context");
1035 torture_comment(tctx
, "Testing smbc_(set|get)OptionDebugToStderr\n");
1036 smbc_setOptionDebugToStderr(ctx
, true);
1037 torture_assert_goto(tctx
,
1038 smbc_getOptionDebugToStderr(ctx
),
1041 "failed to set OptionDebugToStderr");
1043 torture_comment(tctx
, "Testing smbc_(set|get)OptionFullTimeNames\n");
1044 smbc_setOptionFullTimeNames(ctx
, true);
1045 torture_assert_goto(tctx
,
1046 smbc_getOptionFullTimeNames(ctx
),
1049 "failed to set OptionFullTimeNames");
1051 torture_comment(tctx
, "Testing smbc_(set|get)OptionOpenShareMode\n");
1052 smbc_setOptionOpenShareMode(ctx
, SMBC_SHAREMODE_DENY_ALL
);
1053 torture_assert_int_equal_goto(tctx
,
1054 smbc_getOptionOpenShareMode(ctx
),
1055 SMBC_SHAREMODE_DENY_ALL
,
1058 "failed to set OptionOpenShareMode");
1060 torture_comment(tctx
, "Testing smbc_(set|get)OptionUserData\n");
1061 smbc_setOptionUserData(ctx
, (void *)discard_const("torture_user_data"));
1062 torture_assert_str_equal_goto(tctx
,
1063 (const char*)smbc_getOptionUserData(ctx
),
1064 "torture_user_data",
1067 "failed to set OptionUserData");
1069 torture_comment(tctx
,
1070 "Testing smbc_(set|get)OptionSmbEncryptionLevel\n");
1071 smbc_setOptionSmbEncryptionLevel(ctx
, SMBC_ENCRYPTLEVEL_REQUEST
);
1072 torture_assert_int_equal_goto(tctx
,
1073 smbc_getOptionSmbEncryptionLevel(ctx
),
1074 SMBC_ENCRYPTLEVEL_REQUEST
,
1077 "failed to set OptionSmbEncryptionLevel");
1079 torture_comment(tctx
, "Testing smbc_(set|get)OptionCaseSensitive\n");
1080 smbc_setOptionCaseSensitive(ctx
, false);
1081 torture_assert_goto(tctx
,
1082 !smbc_getOptionCaseSensitive(ctx
),
1085 "failed to set OptionCaseSensitive");
1087 torture_comment(tctx
,
1088 "Testing smbc_(set|get)OptionBrowseMaxLmbCount\n");
1089 smbc_setOptionBrowseMaxLmbCount(ctx
, 2);
1090 torture_assert_int_equal_goto(tctx
,
1091 smbc_getOptionBrowseMaxLmbCount(ctx
),
1095 "failed to set OptionBrowseMaxLmbCount");
1097 torture_comment(tctx
,
1098 "Testing smbc_(set|get)OptionUrlEncodeReaddirEntries\n");
1099 smbc_setOptionUrlEncodeReaddirEntries(ctx
, true);
1100 torture_assert_goto(tctx
,
1101 smbc_getOptionUrlEncodeReaddirEntries(ctx
),
1104 "failed to set OptionUrlEncodeReaddirEntries");
1106 torture_comment(tctx
,
1107 "Testing smbc_(set|get)OptionOneSharePerServer\n");
1108 smbc_setOptionOneSharePerServer(ctx
, true);
1109 torture_assert_goto(tctx
,
1110 smbc_getOptionOneSharePerServer(ctx
),
1113 "failed to set OptionOneSharePerServer");
1115 torture_comment(tctx
, "Testing smbc_(set|get)OptionUseKerberos\n");
1116 smbc_setOptionUseKerberos(ctx
, false);
1117 torture_assert_goto(tctx
,
1118 !smbc_getOptionUseKerberos(ctx
),
1121 "failed to set OptionUseKerberos");
1123 torture_comment(tctx
,
1124 "Testing smbc_(set|get)OptionFallbackAfterKerberos\n");
1125 smbc_setOptionFallbackAfterKerberos(ctx
, false);
1126 torture_assert_goto(tctx
,
1127 !smbc_getOptionFallbackAfterKerberos(ctx
),
1130 "failed to set OptionFallbackAfterKerberos");
1132 torture_comment(tctx
,
1133 "Testing smbc_(set|get)OptionNoAutoAnonymousLogin\n");
1134 smbc_setOptionNoAutoAnonymousLogin(ctx
, true);
1135 torture_assert_goto(tctx
,
1136 smbc_getOptionNoAutoAnonymousLogin(ctx
),
1139 "failed to set OptionNoAutoAnonymousLogin");
1141 torture_comment(tctx
, "Testing smbc_(set|get)OptionUseCCache\n");
1142 smbc_setOptionUseCCache(ctx
, true);
1143 torture_assert_goto(tctx
,
1144 smbc_getOptionUseCCache(ctx
),
1147 "failed to set OptionUseCCache");
1150 smbc_free_context(ctx
, 1);
1155 static bool torture_libsmbclient_list_shares(struct torture_context
*tctx
)
1157 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
1158 struct smbc_dirent
*dirent
= NULL
;
1159 SMBCCTX
*ctx
= NULL
;
1161 bool ipc_share_found
= false;
1164 if (smburl
== NULL
) {
1166 "option --option=torture:smburl="
1167 "smb://user:password@server missing\n");
1170 ok
= torture_libsmbclient_init_context(tctx
, &ctx
);
1171 torture_assert_goto(tctx
,
1175 "Failed to init context");
1176 smbc_set_context(ctx
);
1178 torture_comment(tctx
, "Listing: %s\n", smburl
);
1179 dhandle
= smbc_opendir(smburl
);
1180 torture_assert_int_not_equal_goto(tctx
,
1185 "Failed to open smburl");
1187 while((dirent
= smbc_readdir(dhandle
)) != NULL
) {
1188 torture_comment(tctx
, "DIR: %s\n", dirent
->name
);
1189 torture_assert_not_null_goto(tctx
,
1193 "Failed to read name");
1195 if (strequal(dirent
->name
, "IPC$")) {
1196 ipc_share_found
= true;
1200 torture_assert_goto(tctx
,
1204 "Failed to list IPC$ share");
1207 smbc_closedir(dhandle
);
1211 static bool torture_libsmbclient_utimes(struct torture_context
*tctx
)
1213 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
1214 SMBCCTX
*ctx
= NULL
;
1217 struct timeval tbuf
[2];
1220 if (smburl
== NULL
) {
1222 "option --option=torture:smburl="
1223 "smb://user:password@server missing\n");
1226 ok
= torture_libsmbclient_init_context(tctx
, &ctx
);
1227 torture_assert(tctx
, ok
, "Failed to init context");
1228 smbc_set_context(ctx
);
1230 fhandle
= smbc_open(smburl
, O_RDWR
|O_CREAT
, 0644);
1231 torture_assert_int_not_equal(tctx
, fhandle
, -1, "smbc_open failed");
1233 ret
= smbc_fstat(fhandle
, &st
);
1234 torture_assert_int_not_equal(tctx
, ret
, -1, "smbc_fstat failed");
1236 tbuf
[0] = convert_timespec_to_timeval(get_atimespec(&st
));
1237 tbuf
[1] = convert_timespec_to_timeval(get_mtimespec(&st
));
1239 tbuf
[1] = timeval_add(&tbuf
[1], 0, 100000); /* 100 msec */
1241 ret
= smbc_utimes(smburl
, tbuf
);
1242 torture_assert_int_not_equal(tctx
, ret
, -1, "smbc_utimes failed");
1244 ret
= smbc_fstat(fhandle
, &st
);
1245 torture_assert_int_not_equal(tctx
, ret
, -1, "smbc_fstat failed");
1247 torture_assert_int_equal(
1249 get_mtimensec(&st
) / 1000,
1251 "smbc_utimes did not update msec");
1253 smbc_close(fhandle
);
1254 smbc_unlink(smburl
);
1258 static bool torture_libsmbclient_noanon_list(struct torture_context
*tctx
)
1260 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
1261 struct smbc_dirent
*dirent
= NULL
;
1262 SMBCCTX
*ctx
= NULL
;
1266 if (smburl
== NULL
) {
1268 "option --option=torture:smburl="
1269 "smb://user:password@server missing\n");
1272 ok
= torture_libsmbclient_init_context(tctx
, &ctx
);
1273 torture_assert_goto(tctx
,
1277 "Failed to init context");
1278 torture_comment(tctx
,
1279 "Testing smbc_setOptionNoAutoAnonymousLogin\n");
1280 smbc_setOptionNoAutoAnonymousLogin(ctx
, true);
1281 smbc_set_context(ctx
);
1283 torture_comment(tctx
, "Listing: %s\n", smburl
);
1284 dhandle
= smbc_opendir(smburl
);
1285 torture_assert_int_not_equal_goto(tctx
,
1290 "Failed to open smburl");
1292 while((dirent
= smbc_readdir(dhandle
)) != NULL
) {
1293 torture_comment(tctx
, "DIR: %s\n", dirent
->name
);
1294 torture_assert_not_null_goto(tctx
,
1298 "Failed to read name");
1302 smbc_closedir(dhandle
);
1306 static bool torture_libsmbclient_rename(struct torture_context
*tctx
)
1308 SMBCCTX
*ctx
= NULL
;
1310 bool success
= false;
1311 const char *filename_src
= NULL
;
1312 const char *filename_dst
= NULL
;
1314 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
1316 if (smburl
== NULL
) {
1318 "option --option=torture:smburl="
1319 "smb://user:password@server/share missing\n");
1322 torture_assert_goto(tctx
,
1323 torture_libsmbclient_init_context(tctx
, &ctx
),
1328 smbc_set_context(ctx
);
1330 filename_src
= talloc_asprintf(tctx
,
1333 if (filename_src
== NULL
) {
1334 torture_fail_goto(tctx
, done
, "talloc fail\n");
1337 filename_dst
= talloc_asprintf(tctx
,
1340 if (filename_dst
== NULL
) {
1341 torture_fail_goto(tctx
, done
, "talloc fail\n");
1344 /* Ensure the files don't exist. */
1345 smbc_unlink(filename_src
);
1346 smbc_unlink(filename_dst
);
1349 fhandle
= smbc_creat(filename_src
, 0666);
1351 torture_fail_goto(tctx
,
1353 talloc_asprintf(tctx
,
1354 "failed to create file '%s': %s",
1358 ret
= smbc_close(fhandle
);
1359 torture_assert_int_equal_goto(tctx
,
1364 talloc_asprintf(tctx
,
1365 "failed to close handle for '%s'",
1368 fhandle
= smbc_creat(filename_dst
, 0666);
1370 torture_fail_goto(tctx
,
1372 talloc_asprintf(tctx
,
1373 "failed to create file '%s': %s",
1377 ret
= smbc_close(fhandle
);
1378 torture_assert_int_equal_goto(tctx
,
1383 talloc_asprintf(tctx
,
1384 "failed to close handle for '%s'",
1387 ret
= smbc_rename(filename_src
, filename_dst
);
1390 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14938
1391 * gives ret == -1, but errno = 0 for overwrite renames
1394 torture_assert_int_equal_goto(tctx
,
1399 talloc_asprintf(tctx
,
1400 "smbc_rename '%s' -> '%s' failed with %s\n",
1405 /* Remove them again. */
1406 smbc_unlink(filename_src
);
1407 smbc_unlink(filename_dst
);
1411 smbc_free_context(ctx
, 1);
1415 static bool torture_libsmbclient_getatr(struct torture_context
*tctx
)
1417 const char *smburl
= torture_setting_string(tctx
, "smburl", NULL
);
1418 SMBCCTX
*ctx
= NULL
;
1419 char *getatr_name
= NULL
;
1420 struct stat st
= {0};
1425 if (smburl
== NULL
) {
1427 "option --option=torture:smburl="
1428 "smb://user:password@server missing\n");
1431 ok
= torture_libsmbclient_init_context(tctx
, &ctx
);
1432 torture_assert(tctx
, ok
, "Failed to init context");
1433 smbc_set_context(ctx
);
1435 getatr_name
= talloc_asprintf(tctx
,
1438 if (getatr_name
== NULL
) {
1439 torture_result(tctx
,
1445 /* Ensure the file doesn't exist. */
1446 smbc_unlink(getatr_name
);
1448 * smbc_stat() internally uses SMBC_getatr().
1449 * Make sure doing getatr on a non-existent file gives
1450 * an error of -1, errno = ENOENT.
1453 ret
= smbc_stat(getatr_name
, &st
);
1457 torture_assert_int_equal(tctx
,
1460 talloc_asprintf(tctx
,
1461 "smbc_stat on '%s' should "
1465 torture_assert_int_equal(tctx
,
1468 talloc_asprintf(tctx
,
1469 "smbc_stat on '%s' should "
1470 "get errno = ENOENT, got %s\n",
1476 NTSTATUS
torture_libsmbclient_init(TALLOC_CTX
*ctx
)
1478 struct torture_suite
*suite
;
1480 suite
= torture_suite_create(ctx
, "libsmbclient");
1482 torture_suite_add_simple_test(suite
, "version", torture_libsmbclient_version
);
1483 torture_suite_add_simple_test(suite
, "initialize", torture_libsmbclient_initialize
);
1484 torture_suite_add_simple_test(suite
, "configuration", torture_libsmbclient_configuration
);
1485 torture_suite_add_simple_test(suite
, "setConfiguration", torture_libsmbclient_setConfiguration
);
1486 torture_suite_add_simple_test(suite
, "options", torture_libsmbclient_options
);
1487 torture_suite_add_simple_test(suite
, "opendir", torture_libsmbclient_opendir
);
1488 torture_suite_add_simple_test(suite
, "list_shares", torture_libsmbclient_list_shares
);
1489 torture_suite_add_simple_test(suite
, "readdirplus",
1490 torture_libsmbclient_readdirplus
);
1491 torture_suite_add_simple_test(suite
, "readdirplus_seek",
1492 torture_libsmbclient_readdirplus_seek
);
1493 torture_suite_add_simple_test(suite
, "readdirplus2",
1494 torture_libsmbclient_readdirplus2
);
1495 torture_suite_add_simple_test(
1496 suite
, "utimes", torture_libsmbclient_utimes
);
1497 torture_suite_add_simple_test(
1498 suite
, "noanon_list", torture_libsmbclient_noanon_list
);
1499 torture_suite_add_simple_test(suite
,
1501 torture_libsmbclient_rename
);
1502 torture_suite_add_simple_test(suite
, "getatr",
1503 torture_libsmbclient_getatr
);
1505 suite
->description
= talloc_strdup(suite
, "libsmbclient interface tests");
1507 torture_register_suite(ctx
, suite
);
1509 return NT_STATUS_OK
;