00e766c488a66e9944a1385d1b14f8f3f4888e69
[metze/samba/wip.git] / source4 / torture / libsmbclient / libsmbclient.c
1 /*
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Guenther Deschner 2010
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "torture/smbtorture.h"
22 #include "auth/credentials/credentials.h"
23 #include "lib/cmdline/popt_common.h"
24 #include <libsmbclient.h>
25 #include "torture/libsmbclient/proto.h"
26 #include "lib/param/loadparm.h"
27 #include "lib/param/param_global.h"
28 #include "dynconfig.h"
29
30 /* test string to compare with when debug_callback is called */
31 #define TEST_STRING "smbc_setLogCallback test"
32
33 /* Dummy log callback function */
34 static void debug_callback(void *private_ptr, int level, const char *msg)
35 {
36         bool *found = private_ptr;
37         if (strstr(msg, TEST_STRING) != NULL) {
38                 *found = true;
39         }
40         return;
41 }
42
43 bool torture_libsmbclient_init_context(struct torture_context *tctx,
44                                        SMBCCTX **ctx_p)
45 {
46         SMBCCTX *ctx;
47
48         ctx = smbc_new_context();
49         torture_assert(tctx, ctx, "failed to get new context");
50         torture_assert(tctx, smbc_init_context(ctx), "failed to init context");
51
52         smbc_setDebug(ctx, DEBUGLEVEL);
53         smbc_setOptionDebugToStderr(ctx, 1);
54
55         smbc_setUser(ctx,
56                      cli_credentials_get_username(popt_get_cmdline_credentials()));
57
58         *ctx_p = ctx;
59
60         return true;
61 }
62
63 static bool torture_libsmbclient_version(struct torture_context *tctx)
64 {
65         torture_comment(tctx, "Testing smbc_version\n");
66
67         torture_assert(tctx, smbc_version(), "failed to get version");
68
69         return true;
70 }
71
72 static bool torture_libsmbclient_initialize(struct torture_context *tctx)
73 {
74         SMBCCTX *ctx;
75         bool ret = false;
76
77         torture_comment(tctx, "Testing smbc_new_context\n");
78
79         ctx = smbc_new_context();
80         torture_assert(tctx, ctx, "failed to get new context");
81
82         torture_comment(tctx, "Testing smbc_init_context\n");
83
84         torture_assert(tctx, smbc_init_context(ctx), "failed to init context");
85
86         smbc_setLogCallback(ctx, &ret, debug_callback);
87         DEBUG(0, (TEST_STRING"\n"));
88         torture_assert(tctx, ret, "Failed debug_callback not called");
89         ret = false;
90         smbc_setLogCallback(ctx, NULL, NULL);
91         DEBUG(0, (TEST_STRING"\n"));
92         torture_assert(tctx, !ret, "Failed debug_callback called");
93
94         smbc_free_context(ctx, 1);
95
96         return true;
97 }
98
99 static bool torture_libsmbclient_setConfiguration(struct torture_context *tctx)
100 {
101         SMBCCTX *ctx;
102         struct loadparm_global *global_config = NULL;
103         const char *new_smb_conf = torture_setting_string(tctx,
104                                 "replace_smbconf",
105                                 "");
106
107         ctx = smbc_new_context();
108         torture_assert(tctx, ctx, "failed to get new context");
109
110         torture_assert(tctx, smbc_init_context(ctx), "failed to init context");
111
112         torture_comment(tctx, "Testing smbc_setConfiguration - new file %s\n",
113                 new_smb_conf);
114
115         global_config = get_globals();
116         torture_assert(tctx, global_config, "Global Config is NULL");
117
118         /* check configuration before smbc_setConfiguration call */
119         torture_comment(tctx, "'workgroup' before setConfiguration %s\n",
120                         global_config->workgroup);
121         torture_comment(tctx, "'client min protocol' before "
122                         "setConfiguration %d\n",
123                         global_config->client_min_protocol);
124         torture_comment(tctx, "'client max protocol' before "
125                         "setConfiguration %d\n",
126                         global_config->_client_max_protocol);
127         torture_comment(tctx, "'client signing' before setConfiguration %d\n",
128                         global_config->client_signing);
129         torture_comment(tctx, "'deadtime' before setConfiguration %d\n",
130                         global_config->deadtime);
131
132         torture_assert_int_equal(tctx, smbc_setConfiguration(ctx, new_smb_conf),
133                         0, "setConfiguration conf file not found");
134
135         /* verify configuration */
136         torture_assert_str_equal(tctx, global_config->workgroup,
137                         "NEW_WORKGROUP",
138                         "smbc_setConfiguration failed, "
139                         "'workgroup' not updated");
140         torture_assert_int_equal(tctx, global_config->client_min_protocol, 7,
141                         "smbc_setConfiguration failed, 'client min protocol' "
142                         "not updated");
143         torture_assert_int_equal(tctx, global_config->_client_max_protocol, 13,
144                         "smbc_setConfiguration failed, 'client max protocol' "
145                         "not updated");
146         torture_assert_int_equal(tctx, global_config->client_signing, 1,
147                         "smbc_setConfiguration failed, 'client signing' "
148                         "not updated");
149         torture_assert_int_equal(tctx, global_config->deadtime, 5,
150                         "smbc_setConfiguration failed, 'deadtime' not updated");
151
152         /* Restore configuration to default */
153         smbc_setConfiguration(ctx, get_dyn_CONFIGFILE());
154
155         smbc_free_context(ctx, 1);
156
157         return true;
158 }
159
160 static bool test_opendir(struct torture_context *tctx,
161                          SMBCCTX *ctx,
162                          const char *fname,
163                          bool expect_success)
164 {
165         int handle, ret;
166
167         torture_comment(tctx, "Testing smbc_opendir(%s)\n", fname);
168
169         handle = smbc_opendir(fname);
170         if (!expect_success) {
171                 return true;
172         }
173         if (handle < 0) {
174                 torture_fail(tctx, talloc_asprintf(tctx, "failed to obain file handle for '%s'", fname));
175         }
176
177         ret = smbc_closedir(handle);
178         torture_assert_int_equal(tctx, ret, 0,
179                 talloc_asprintf(tctx, "failed to close file handle for '%s'", fname));
180
181         return true;
182 }
183
184 static bool torture_libsmbclient_opendir(struct torture_context *tctx)
185 {
186         int i;
187         SMBCCTX *ctx;
188         bool ret = true;
189         const char *bad_urls[] = {
190                 "",
191                 NULL,
192                 "smb",
193                 "smb:",
194                 "smb:/",
195                 "smb:///",
196                 "bms://",
197                 ":",
198                 ":/",
199                 "://",
200                 ":///",
201                 "/",
202                 "//",
203                 "///"
204         };
205         const char *good_urls[] = {
206                 "smb://",
207                 "smb://WORKGROUP",
208                 "smb://WORKGROUP/"
209         };
210
211         torture_assert(tctx, torture_libsmbclient_init_context(tctx, &ctx), "");
212         smbc_set_context(ctx);
213
214         for (i=0; i < ARRAY_SIZE(bad_urls); i++) {
215                 ret &= test_opendir(tctx, ctx, bad_urls[i], false);
216         }
217         for (i=0; i < ARRAY_SIZE(good_urls); i++) {
218                 ret &= test_opendir(tctx, ctx, good_urls[i], true);
219         }
220
221         smbc_free_context(ctx, 1);
222
223         return ret;
224 }
225
226 /* note the strdup for string options on smbc_set calls. I think libsmbclient is
227  * really doing something wrong here: in smbc_free_context libsmbclient just
228  * calls free() on the string options so it assumes the callers have malloced
229  * them before setting them via smbc_set calls. */
230
231 #define TEST_OPTION_INT(option, val) \
232         torture_comment(tctx, "Testing smbc_set" #option "\n");\
233         smbc_set ##option(ctx, val);\
234         torture_comment(tctx, "Testing smbc_get" #option "\n");\
235         torture_assert_int_equal(tctx, smbc_get ##option(ctx), val, "failed " #option);
236
237 #define TEST_OPTION_STRING(option, val) \
238         torture_comment(tctx, "Testing smbc_set" #option "\n");\
239         smbc_set ##option(ctx, strdup(val));\
240         torture_comment(tctx, "Testing smbc_get" #option "\n");\
241         torture_assert_str_equal(tctx, smbc_get ##option(ctx), val, "failed " #option);
242
243 bool torture_libsmbclient_configuration(struct torture_context *tctx)
244 {
245         SMBCCTX *ctx;
246
247         ctx = smbc_new_context();
248         torture_assert(tctx, ctx, "failed to get new context");
249         torture_assert(tctx, smbc_init_context(ctx), "failed to init context");
250
251         TEST_OPTION_INT(Debug, DEBUGLEVEL);
252         TEST_OPTION_STRING(NetbiosName, "torture_netbios");
253         TEST_OPTION_STRING(Workgroup, "torture_workgroup");
254         TEST_OPTION_STRING(User, "torture_user");
255         TEST_OPTION_INT(Timeout, 12345);
256
257         smbc_free_context(ctx, 1);
258
259         return true;
260 }
261
262 bool torture_libsmbclient_options(struct torture_context *tctx)
263 {
264         SMBCCTX *ctx;
265
266         ctx = smbc_new_context();
267         torture_assert(tctx, ctx, "failed to get new context");
268         torture_assert(tctx, smbc_init_context(ctx), "failed to init context");
269
270         TEST_OPTION_INT(OptionDebugToStderr, true);
271         TEST_OPTION_INT(OptionFullTimeNames, true);
272         TEST_OPTION_INT(OptionOpenShareMode, SMBC_SHAREMODE_DENY_ALL);
273         /* FIXME: OptionUserData */
274         TEST_OPTION_INT(OptionSmbEncryptionLevel, SMBC_ENCRYPTLEVEL_REQUEST);
275         TEST_OPTION_INT(OptionCaseSensitive, false);
276         TEST_OPTION_INT(OptionBrowseMaxLmbCount, 2);
277         TEST_OPTION_INT(OptionUrlEncodeReaddirEntries, true);
278         TEST_OPTION_INT(OptionOneSharePerServer, true);
279         TEST_OPTION_INT(OptionUseKerberos, false);
280         TEST_OPTION_INT(OptionFallbackAfterKerberos, false);
281         TEST_OPTION_INT(OptionNoAutoAnonymousLogin, true);
282         TEST_OPTION_INT(OptionUseCCache, true);
283
284         smbc_free_context(ctx, 1);
285
286         return true;
287 }
288
289 NTSTATUS torture_libsmbclient_init(TALLOC_CTX *ctx)
290 {
291         struct torture_suite *suite;
292
293         suite = torture_suite_create(ctx, "libsmbclient");
294
295         torture_suite_add_simple_test(suite, "version", torture_libsmbclient_version);
296         torture_suite_add_simple_test(suite, "initialize", torture_libsmbclient_initialize);
297         torture_suite_add_simple_test(suite, "configuration", torture_libsmbclient_configuration);
298         torture_suite_add_simple_test(suite, "setConfiguration", torture_libsmbclient_setConfiguration);
299         torture_suite_add_simple_test(suite, "options", torture_libsmbclient_options);
300         torture_suite_add_simple_test(suite, "opendir", torture_libsmbclient_opendir);
301
302         suite->description = talloc_strdup(suite, "libsmbclient interface tests");
303
304         torture_register_suite(ctx, suite);
305
306         return NT_STATUS_OK;
307 }