Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : SMB torture tester
4 : Copyright (C) Guenther Deschner 2009-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 "lib/replace/replace.h"
21 : #include "libcli/util/ntstatus.h"
22 : #include "libcli/util/werror.h"
23 : #include "lib/util/data_blob.h"
24 : #include "lib/util/time.h"
25 : #include "libcli/resolve/resolve.h"
26 : #include "nsswitch/libwbclient/wbclient.h"
27 : #include "torture/smbtorture.h"
28 : #include "torture/winbind/proto.h"
29 : #include "lib/util/util_net.h"
30 : #include "lib/util/charset/charset.h"
31 : #include "libcli/auth/libcli_auth.h"
32 : #include "lib/param/param.h"
33 : #include "lib/util/samba_util.h"
34 : #include "auth/credentials/credentials.h"
35 : #include "lib/cmdline/cmdline.h"
36 :
37 : #include <gnutls/gnutls.h>
38 : #include <gnutls/crypto.h>
39 :
40 : #define WBC_ERROR_EQUAL(x,y) (x == y)
41 :
42 : #define torture_assert_wbc_equal(torture_ctx, got, expected, cmt, cmt_arg) \
43 : do { wbcErr __got = got, __expected = expected; \
44 : if (!WBC_ERROR_EQUAL(__got, __expected)) { \
45 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: " cmt, wbcErrorString(__got), wbcErrorString(__expected), cmt_arg); \
46 : return false; \
47 : } \
48 : } while (0)
49 :
50 : #define torture_assert_wbc_ok(torture_ctx,expr,cmt,cmt_arg) \
51 : torture_assert_wbc_equal(torture_ctx,expr,WBC_ERR_SUCCESS,cmt,cmt_arg)
52 :
53 : #define torture_assert_wbc_equal_goto_fail(torture_ctx, got, expected, cmt, cmt_arg) \
54 : do { wbcErr __got = got, __expected = expected; \
55 : if (!WBC_ERROR_EQUAL(__got, __expected)) { \
56 : torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: " cmt, wbcErrorString(__got), wbcErrorString(__expected), cmt_arg); \
57 : goto fail; \
58 : } \
59 : } while (0)
60 :
61 : #define torture_assert_wbc_ok_goto_fail(torture_ctx,expr,cmt,cmt_arg) \
62 : torture_assert_wbc_equal_goto_fail(torture_ctx,expr,WBC_ERR_SUCCESS,cmt,cmt_arg)
63 :
64 : #define torture_assert_str_equal_goto_fail(torture_ctx,got,expected,cmt)\
65 : do { const char *__got = (got), *__expected = (expected); \
66 : if (strcmp(__got, __expected) != 0) { \
67 : torture_result(torture_ctx, TORTURE_FAIL, \
68 : __location__": "#got" was %s, expected %s: %s", \
69 : __got, __expected, cmt); \
70 : goto fail;; \
71 : } \
72 : } while(0)
73 :
74 4 : static bool test_wbc_ping(struct torture_context *tctx)
75 : {
76 4 : torture_assert_wbc_ok(tctx, wbcPing(),
77 : "%s", "wbcPing failed");
78 :
79 4 : return true;
80 : }
81 :
82 4 : static bool test_wbc_pingdc(struct torture_context *tctx)
83 : {
84 4 : struct wbcInterfaceDetails *details = NULL;
85 4 : wbcErr ret = false;
86 :
87 4 : torture_assert_wbc_equal_goto_fail(tctx,
88 : wbcPingDc("random_string", NULL),
89 : WBC_ERR_DOMAIN_NOT_FOUND,
90 : "%s",
91 : "wbcPingDc failed");
92 4 : torture_assert_wbc_ok_goto_fail(tctx, wbcPingDc(NULL, NULL),
93 : "%s", "wbcPingDc failed");
94 :
95 4 : torture_assert_wbc_ok_goto_fail(tctx, wbcInterfaceDetails(&details),
96 : "%s", "wbcInterfaceDetails failed");
97 4 : torture_assert_goto(tctx, details, ret, fail,
98 : "wbcInterfaceDetails returned NULL pointer");
99 4 : torture_assert_goto(tctx, details->netbios_domain, ret, fail,
100 : "wbcInterfaceDetails returned NULL netbios_domain");
101 :
102 4 : torture_assert_wbc_ok_goto_fail(tctx,
103 : wbcPingDc(details->netbios_domain, NULL),
104 : "wbcPingDc(%s) failed",
105 : details->netbios_domain);
106 :
107 4 : torture_assert_wbc_ok_goto_fail(tctx,
108 : wbcPingDc("BUILTIN", NULL),
109 : "%s",
110 : "wbcPingDc(BUILTIN) failed");
111 :
112 4 : ret = true;
113 4 : fail:
114 4 : wbcFreeMemory(details);
115 4 : return ret;
116 : }
117 :
118 4 : static bool test_wbc_pingdc2(struct torture_context *tctx)
119 : {
120 4 : struct wbcInterfaceDetails *details = NULL;
121 4 : char *name = NULL;
122 4 : wbcErr ret = false;
123 :
124 4 : torture_assert_wbc_equal_goto_fail(tctx,
125 : wbcPingDc2("random_string", NULL, &name),
126 : WBC_ERR_DOMAIN_NOT_FOUND,
127 : "%s",
128 : "wbcPingDc2 failed");
129 4 : torture_assert_wbc_ok_goto_fail(tctx,
130 : wbcPingDc2(NULL, NULL, &name),
131 : "%s",
132 : "wbcPingDc2 failed");
133 4 : wbcFreeMemory(name);
134 4 : name = NULL;
135 :
136 4 : torture_assert_wbc_ok_goto_fail(tctx,
137 : wbcInterfaceDetails(&details),
138 : "%s",
139 : "wbcInterfaceDetails failed");
140 4 : torture_assert_goto(tctx,
141 : details,
142 : ret,
143 : fail,
144 : "wbcInterfaceDetails returned NULL pointer");
145 4 : torture_assert_goto(tctx,
146 : details->netbios_domain,
147 : ret,
148 : fail,
149 : "wbcInterfaceDetails returned NULL netbios_domain");
150 :
151 4 : torture_assert_wbc_ok_goto_fail(tctx,
152 : wbcPingDc2(details->netbios_domain, NULL, &name),
153 : "wbcPingDc2(%s) failed",
154 : details->netbios_domain);
155 4 : wbcFreeMemory(name);
156 4 : name = NULL;
157 :
158 4 : torture_assert_wbc_ok_goto_fail(tctx,
159 : wbcPingDc2("BUILTIN", NULL, &name),
160 : "%s",
161 : "wbcPingDc2(BUILTIN) failed");
162 :
163 4 : ret = true;
164 4 : fail:
165 4 : wbcFreeMemory(name);
166 4 : wbcFreeMemory(details);
167 :
168 4 : return ret;
169 : }
170 :
171 4 : static bool test_wbc_library_details(struct torture_context *tctx)
172 : {
173 : struct wbcLibraryDetails *details;
174 :
175 4 : torture_assert_wbc_ok(tctx, wbcLibraryDetails(&details),
176 : "%s", "wbcLibraryDetails failed");
177 4 : torture_assert(tctx, details,
178 : "wbcLibraryDetails returned NULL pointer");
179 :
180 4 : wbcFreeMemory(details);
181 :
182 4 : return true;
183 : }
184 :
185 4 : static bool test_wbc_interface_details(struct torture_context *tctx)
186 : {
187 : struct wbcInterfaceDetails *details;
188 :
189 4 : torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
190 : "%s", "wbcInterfaceDetails failed");
191 4 : torture_assert(tctx, details,
192 : "wbcInterfaceDetails returned NULL pointer");
193 :
194 4 : wbcFreeMemory(details);
195 :
196 4 : return true;
197 : }
198 :
199 4 : static bool test_wbc_sidtypestring(struct torture_context *tctx)
200 : {
201 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_USE_NONE),
202 : "SID_NONE", "SID_NONE failed");
203 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_USER),
204 : "SID_USER", "SID_USER failed");
205 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DOM_GRP),
206 : "SID_DOM_GROUP", "SID_DOM_GROUP failed");
207 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DOMAIN),
208 : "SID_DOMAIN", "SID_DOMAIN failed");
209 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_ALIAS),
210 : "SID_ALIAS", "SID_ALIAS failed");
211 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_WKN_GRP),
212 : "SID_WKN_GROUP", "SID_WKN_GROUP failed");
213 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DELETED),
214 : "SID_DELETED", "SID_DELETED failed");
215 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_INVALID),
216 : "SID_INVALID", "SID_INVALID failed");
217 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_UNKNOWN),
218 : "SID_UNKNOWN", "SID_UNKNOWN failed");
219 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_COMPUTER),
220 : "SID_COMPUTER", "SID_COMPUTER failed");
221 4 : torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_LABEL),
222 : "SID_LABEL", "SID_LABEL failed");
223 4 : return true;
224 : }
225 :
226 4 : static bool test_wbc_sidtostring(struct torture_context *tctx)
227 : {
228 : struct wbcDomainSid sid;
229 4 : const char *sid_string = "S-1-5-32";
230 : char *sid_string2;
231 :
232 4 : torture_assert_wbc_ok(tctx, wbcStringToSid(sid_string, &sid),
233 : "wbcStringToSid of %s failed", sid_string);
234 4 : torture_assert_wbc_ok(tctx, wbcSidToString(&sid, &sid_string2),
235 : "wbcSidToString of %s failed", sid_string);
236 4 : torture_assert_str_equal(tctx, sid_string, sid_string2,
237 : "sid strings differ");
238 4 : wbcFreeMemory(sid_string2);
239 :
240 4 : return true;
241 : }
242 :
243 4 : static bool test_wbc_guidtostring(struct torture_context *tctx)
244 : {
245 : struct wbcGuid guid;
246 4 : const char *guid_string = "f7cf07b4-1487-45c7-824d-8b18cc580811";
247 : char *guid_string2;
248 :
249 4 : torture_assert_wbc_ok(tctx, wbcStringToGuid(guid_string, &guid),
250 : "wbcStringToGuid of %s failed", guid_string);
251 4 : torture_assert_wbc_ok(tctx, wbcGuidToString(&guid, &guid_string2),
252 : "wbcGuidToString of %s failed", guid_string);
253 4 : torture_assert_str_equal(tctx, guid_string, guid_string2,
254 : "guid strings differ");
255 4 : wbcFreeMemory(guid_string2);
256 :
257 4 : return true;
258 : }
259 :
260 4 : static bool test_wbc_domain_info(struct torture_context *tctx)
261 : {
262 4 : struct wbcDomainInfo *info = NULL;
263 4 : struct wbcInterfaceDetails *details = NULL;
264 4 : wbcErr ret = false;
265 :
266 4 : torture_assert_wbc_ok_goto_fail(tctx,
267 : wbcInterfaceDetails(&details),
268 : "%s",
269 : "wbcInterfaceDetails failed");
270 4 : torture_assert_wbc_ok_goto_fail(tctx,
271 : wbcDomainInfo(details->netbios_domain, &info),
272 : "%s",
273 : "wbcDomainInfo failed");
274 :
275 4 : torture_assert_goto(tctx,
276 : info,
277 : ret,
278 : fail,
279 : "wbcDomainInfo returned NULL pointer");
280 :
281 4 : ret = true;
282 4 : fail:
283 4 : wbcFreeMemory(details);
284 4 : wbcFreeMemory(info);
285 :
286 4 : return ret;
287 : }
288 :
289 4 : static bool test_wbc_users(struct torture_context *tctx)
290 : {
291 4 : const char *domain_name = NULL;
292 : uint32_t num_users;
293 4 : const char **users = NULL;
294 : uint32_t i;
295 4 : struct wbcInterfaceDetails *details = NULL;
296 4 : struct wbcDomainSid *sids = NULL;
297 4 : char *domain = NULL;
298 4 : char *name = NULL;
299 4 : char *sid_string = NULL;
300 4 : wbcErr ret = false;
301 : char separator;
302 :
303 4 : torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
304 : "%s", "wbcInterfaceDetails failed");
305 :
306 4 : domain_name = talloc_strdup(tctx, details->netbios_domain);
307 4 : torture_assert_goto(tctx,
308 : domain_name != NULL,
309 : ret,
310 : fail,
311 : "Failed to allocate domain_name");
312 4 : separator = details->winbind_separator;
313 4 : wbcFreeMemory(details);
314 4 : details = NULL;
315 :
316 4 : torture_assert_wbc_ok_goto_fail(tctx,
317 : wbcListUsers(domain_name, &num_users, &users),
318 : "%s",
319 : "wbcListUsers failed");
320 4 : torture_assert_goto(tctx,
321 : !(num_users > 0 && !users),
322 : ret,
323 : fail,
324 : "wbcListUsers returned invalid results");
325 :
326 440 : for (i = 0; i < MIN(num_users, 100); i++) {
327 : struct wbcDomainSid sid;
328 : enum wbcSidType name_type;
329 : uint32_t num_sids;
330 : const char *user;
331 : char *c;
332 :
333 222 : c = strchr(users[i], separator);
334 :
335 222 : if (c == NULL) {
336 : /*
337 : * NT4 DC
338 : * user name does not contain DOMAIN SEPARATOR prefix.
339 : */
340 :
341 200 : user = users[i];
342 : } else {
343 : /*
344 : * AD DC
345 : * user name starts with DOMAIN SEPARATOR prefix.
346 : */
347 : const char *dom;
348 :
349 22 : *c = '\0';
350 22 : dom = users[i];
351 22 : user = c + 1;
352 :
353 22 : torture_assert_str_equal_goto(tctx, dom, domain_name,
354 : ret, fail, "Domain part "
355 : "of user name does not "
356 : "match domain name.\n");
357 : }
358 :
359 222 : torture_assert_wbc_ok_goto_fail(tctx,
360 : wbcLookupName(domain_name, user,
361 : &sid, &name_type),
362 : "wbcLookupName of %s failed",
363 : users[i]);
364 222 : torture_assert_int_equal_goto(tctx,
365 : name_type, WBC_SID_NAME_USER,
366 : ret,
367 : fail,
368 : "wbcLookupName expected WBC_SID_NAME_USER");
369 222 : wbcSidToString(&sid, &sid_string);
370 222 : torture_assert_wbc_ok_goto_fail(tctx,
371 : wbcLookupSid(&sid,
372 : &domain,
373 : &name,
374 : &name_type),
375 : "wbcLookupSid of %s failed",
376 : sid_string);
377 222 : torture_assert_int_equal_goto(tctx,
378 : name_type, WBC_SID_NAME_USER,
379 : ret,
380 : fail,
381 : "wbcLookupSid of expected WBC_SID_NAME_USER");
382 222 : torture_assert_goto(tctx,
383 : name,
384 : ret,
385 : fail,
386 : "wbcLookupSid returned no name");
387 222 : wbcFreeMemory(domain);
388 222 : domain = NULL;
389 222 : wbcFreeMemory(name);
390 222 : name = NULL;
391 :
392 222 : torture_assert_wbc_ok_goto_fail(tctx,
393 : wbcLookupUserSids(&sid, true, &num_sids, &sids),
394 : "wbcLookupUserSids of %s failed", sid_string);
395 222 : torture_assert_wbc_ok_goto_fail(tctx,
396 : wbcGetDisplayName(&sid,
397 : &domain,
398 : &name,
399 : &name_type),
400 : "wbcGetDisplayName of %s failed",
401 : sid_string);
402 222 : wbcFreeMemory(domain);
403 222 : domain = NULL;
404 222 : wbcFreeMemory(name);
405 222 : name = NULL;
406 222 : wbcFreeMemory(sids);
407 222 : sids = NULL;
408 222 : wbcFreeMemory(sid_string);
409 222 : sid_string = NULL;
410 : }
411 :
412 4 : ret = true;
413 4 : fail:
414 4 : wbcFreeMemory(details);
415 4 : wbcFreeMemory(users);
416 4 : wbcFreeMemory(domain);
417 4 : wbcFreeMemory(name);
418 4 : wbcFreeMemory(sids);
419 4 : wbcFreeMemory(sid_string);
420 :
421 4 : return ret;
422 : }
423 :
424 4 : static bool test_wbc_groups(struct torture_context *tctx)
425 : {
426 4 : wbcErr ret = false;
427 4 : const char *domain_name = NULL;
428 : uint32_t num_groups;
429 4 : const char **groups = NULL;
430 : uint32_t i;
431 4 : struct wbcInterfaceDetails *details = NULL;
432 4 : char *domain = NULL;
433 4 : char *name = NULL;
434 4 : char *sid_string = NULL;
435 : char separator;
436 :
437 4 : torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
438 : "%s", "wbcInterfaceDetails failed");
439 :
440 4 : domain_name = talloc_strdup(tctx, details->netbios_domain);
441 4 : torture_assert_goto(tctx,
442 : domain_name != NULL,
443 : ret,
444 : fail,
445 : "Failed to allocate domain_name");
446 4 : separator = details->winbind_separator;
447 4 : wbcFreeMemory(details);
448 4 : details = NULL;
449 :
450 4 : torture_assert_wbc_ok_goto_fail(tctx,
451 : wbcListGroups(domain_name, &num_groups, &groups),
452 : "wbcListGroups in %s failed",
453 : domain_name);
454 4 : torture_assert_goto(tctx,
455 : !(num_groups > 0 && !groups),
456 : ret,
457 : fail,
458 : "wbcListGroups returned invalid results");
459 :
460 461 : for (i=0; i < MIN(num_groups,100); i++) {
461 : struct wbcDomainSid sid;
462 : enum wbcSidType name_type;
463 : const char *group;
464 : char *c;
465 :
466 236 : c = strchr(groups[i], separator);
467 :
468 236 : if (c == NULL) {
469 : /*
470 : * NT4 DC
471 : * group name does not contain DOMAIN SEPARATOR prefix.
472 : */
473 :
474 200 : group = groups[i];
475 : } else {
476 : /*
477 : * AD DC
478 : * group name starts with DOMAIN SEPARATOR prefix.
479 : */
480 : const char *dom;
481 :
482 :
483 36 : *c = '\0';
484 36 : dom = groups[i];
485 36 : group = c + 1;
486 :
487 36 : torture_assert_str_equal_goto(tctx, dom, domain_name,
488 : ret, fail, "Domain part "
489 : "of group name does not "
490 : "match domain name.\n");
491 : }
492 :
493 236 : torture_assert_wbc_ok_goto_fail(tctx,
494 : wbcLookupName(domain_name,
495 : group,
496 : &sid,
497 : &name_type),
498 : "wbcLookupName for %s failed",
499 : domain_name);
500 236 : wbcSidToString(&sid, &sid_string);
501 236 : torture_assert_wbc_ok_goto_fail(tctx,
502 : wbcLookupSid(&sid,
503 : &domain,
504 : &name,
505 : &name_type),
506 : "wbcLookupSid of %s failed",
507 : sid_string);
508 236 : torture_assert_goto(tctx,
509 : name,
510 : ret,
511 : fail,
512 : "wbcLookupSid returned no name");
513 :
514 236 : wbcFreeMemory(domain);
515 236 : domain = NULL;
516 236 : wbcFreeMemory(name);
517 236 : name = NULL;
518 236 : wbcFreeMemory(sid_string);
519 236 : sid_string = NULL;
520 : }
521 :
522 4 : ret = true;
523 4 : fail:
524 4 : wbcFreeMemory(details);
525 4 : wbcFreeMemory(groups);
526 4 : wbcFreeMemory(domain);
527 4 : wbcFreeMemory(name);
528 4 : wbcFreeMemory(sid_string);
529 :
530 4 : return ret;
531 : }
532 :
533 4 : static bool test_wbc_trusts(struct torture_context *tctx)
534 : {
535 4 : struct wbcDomainInfo *domains = NULL;
536 4 : struct wbcAuthErrorInfo *error = NULL;
537 : size_t num_domains;
538 : uint32_t i;
539 4 : wbcErr ret = false;
540 :
541 4 : torture_assert_wbc_ok_goto_fail(tctx,
542 : wbcListTrusts(&domains, &num_domains),
543 : "%s",
544 : "wbcListTrusts failed");
545 4 : torture_assert_goto(tctx,
546 : !(num_domains > 0 && !domains),
547 : ret,
548 : fail,
549 : "wbcListTrusts returned invalid results");
550 :
551 14 : for (i=0; i < MIN(num_domains,100); i++) {
552 :
553 : /*
554 : struct wbcDomainSid sid;
555 : enum wbcSidType name_type;
556 : char *domain;
557 : char *name;
558 : */
559 10 : torture_assert_wbc_ok_goto_fail(tctx,
560 : wbcCheckTrustCredentials(domains[i].short_name,
561 : &error),
562 : "%s",
563 : "wbcCheckTrustCredentials failed");
564 : /*
565 : torture_assert_wbc_ok(tctx, wbcLookupName(domains[i].short_name, NULL, &sid, &name_type),
566 : "wbcLookupName failed");
567 : torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
568 : "wbcLookupName expected WBC_SID_NAME_DOMAIN");
569 : torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
570 : "wbcLookupSid failed");
571 : torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
572 : "wbcLookupSid expected WBC_SID_NAME_DOMAIN");
573 : torture_assert(tctx, name,
574 : "wbcLookupSid returned no name");
575 : */
576 10 : wbcFreeMemory(error);
577 10 : error = NULL;
578 : }
579 :
580 4 : ret = true;
581 4 : fail:
582 4 : wbcFreeMemory(domains);
583 4 : wbcFreeMemory(error);
584 :
585 4 : return ret;
586 : }
587 :
588 4 : static bool test_wbc_lookupdc(struct torture_context *tctx)
589 : {
590 4 : const char *domain_name = NULL;
591 : struct wbcInterfaceDetails *details;
592 : struct wbcDomainControllerInfo *dc_info;
593 :
594 4 : torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
595 : "%s", "wbcInterfaceDetails failed");
596 :
597 4 : domain_name = talloc_strdup(tctx, details->netbios_domain);
598 4 : wbcFreeMemory(details);
599 :
600 4 : torture_assert_wbc_ok(tctx, wbcLookupDomainController(domain_name, 0, &dc_info),
601 : "wbcLookupDomainController for %s failed", domain_name);
602 4 : wbcFreeMemory(dc_info);
603 :
604 4 : return true;
605 : }
606 :
607 4 : static bool test_wbc_lookupdcex(struct torture_context *tctx)
608 : {
609 4 : const char *domain_name = NULL;
610 : struct wbcInterfaceDetails *details;
611 : struct wbcDomainControllerInfoEx *dc_info;
612 :
613 4 : torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
614 : "%s", "wbcInterfaceDetails failed");
615 :
616 4 : domain_name = talloc_strdup(tctx, details->netbios_domain);
617 4 : wbcFreeMemory(details);
618 :
619 4 : torture_assert_wbc_ok(tctx, wbcLookupDomainControllerEx(domain_name, NULL, NULL, 0, &dc_info),
620 : "wbcLookupDomainControllerEx for %s failed", domain_name);
621 4 : wbcFreeMemory(dc_info);
622 :
623 4 : return true;
624 : }
625 :
626 4 : static bool test_wbc_resolve_winsbyname(struct torture_context *tctx)
627 : {
628 : const char *name;
629 : char *ip;
630 : wbcErr ret;
631 :
632 4 : name = torture_setting_string(tctx, "host", NULL);
633 :
634 4 : torture_comment(tctx, "test-WinsByName: host='%s'\n", name);
635 :
636 4 : ret = wbcResolveWinsByName(name, &ip);
637 :
638 4 : if (is_ipaddress(name)) {
639 0 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_DOMAIN_NOT_FOUND, "wbcResolveWinsByName of %s failed", name);
640 : } else {
641 4 : torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByName for %s failed", name);
642 : }
643 :
644 4 : return true;
645 : }
646 :
647 4 : static bool test_wbc_resolve_winsbyip(struct torture_context *tctx)
648 : {
649 : const char *ip;
650 : const char *host;
651 : struct nbt_name nbt_name;
652 : char *name;
653 : wbcErr ret;
654 : NTSTATUS status;
655 :
656 4 : host = torture_setting_string(tctx, "host", NULL);
657 :
658 4 : torture_comment(tctx, "test-WinsByIp: host='%s'\n", host);
659 :
660 4 : make_nbt_name_server(&nbt_name, host);
661 :
662 4 : status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
663 : 0, 0, &nbt_name, tctx, &ip, tctx->ev);
664 4 : torture_assert_ntstatus_ok(tctx, status,
665 : talloc_asprintf(tctx,"Failed to resolve %s: %s",
666 : nbt_name.name, nt_errstr(status)));
667 :
668 4 : torture_comment(tctx, "test-WinsByIp: ip='%s'\n", ip);
669 :
670 4 : ret = wbcResolveWinsByIP(ip, &name);
671 :
672 4 : torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByIP for %s failed", ip);
673 :
674 4 : wbcFreeMemory(name);
675 :
676 4 : return true;
677 : }
678 :
679 4 : static bool test_wbc_lookup_rids(struct torture_context *tctx)
680 : {
681 : struct wbcDomainSid builtin;
682 4 : uint32_t rids[2] = { 544, 545 };
683 4 : const char *domain_name = NULL;
684 4 : const char **names = NULL;
685 : enum wbcSidType *types;
686 4 : wbcErr ret = false;
687 :
688 4 : wbcStringToSid("S-1-5-32", &builtin);
689 :
690 4 : ret = wbcLookupRids(&builtin, 2, rids, &domain_name, &names,
691 : &types);
692 4 : torture_assert_wbc_ok_goto_fail(
693 : tctx, ret, "%s", "wbcLookupRids for 544 and 545 failed");
694 :
695 4 : torture_assert_str_equal(
696 : tctx, names[0], "Administrators",
697 : "S-1-5-32-544 not mapped to 'Administrators'");
698 4 : torture_assert_str_equal_goto_fail(
699 : tctx, names[1], "Users", "S-1-5-32-545 not mapped to 'Users'");
700 :
701 4 : ret = true;
702 4 : fail:
703 4 : wbcFreeMemory(discard_const_p(char ,domain_name));
704 4 : wbcFreeMemory(names);
705 4 : wbcFreeMemory(types);
706 4 : return ret;
707 : }
708 :
709 4 : static bool test_wbc_get_sidaliases(struct torture_context *tctx)
710 : {
711 : struct wbcDomainSid builtin;
712 4 : struct wbcDomainInfo *info = NULL;
713 4 : struct wbcInterfaceDetails *details = NULL;
714 : struct wbcDomainSid sids[2];
715 4 : uint32_t *rids = NULL;
716 : uint32_t num_rids;
717 4 : wbcErr ret = false;
718 :
719 4 : torture_assert_wbc_ok_goto_fail(tctx,
720 : wbcInterfaceDetails(&details),
721 : "%s",
722 : "wbcInterfaceDetails failed");
723 4 : torture_assert_wbc_ok_goto_fail(tctx,
724 : wbcDomainInfo(details->netbios_domain, &info),
725 : "wbcDomainInfo of %s failed",
726 : details->netbios_domain);
727 :
728 4 : sids[0] = info->sid;
729 4 : sids[0].sub_auths[sids[0].num_auths++] = 500;
730 4 : sids[1] = info->sid;
731 4 : sids[1].sub_auths[sids[1].num_auths++] = 512;
732 :
733 4 : torture_assert_wbc_ok_goto_fail(tctx,
734 : wbcStringToSid("S-1-5-32", &builtin),
735 : "wbcStringToSid of %s failed",
736 : "S-1-5-32");
737 :
738 4 : ret = wbcGetSidAliases(&builtin, sids, 2, &rids, &num_rids);
739 4 : torture_assert_wbc_ok_goto_fail(tctx,
740 : ret,
741 : "%s",
742 : "wbcGetSidAliases failed");
743 :
744 4 : ret = true;
745 4 : fail:
746 4 : wbcFreeMemory(details);
747 4 : wbcFreeMemory(info);
748 4 : wbcFreeMemory(rids);
749 4 : return ret;
750 : }
751 :
752 12 : static bool test_wbc_authenticate_user_int(struct torture_context *tctx,
753 : const char *correct_password)
754 : {
755 : struct wbcAuthUserParams params;
756 12 : struct wbcAuthUserInfo *info = NULL;
757 12 : struct wbcAuthErrorInfo *error = NULL;
758 : wbcErr ret;
759 12 : struct cli_credentials *creds = samba_cmdline_get_creds();
760 :
761 12 : ret = wbcAuthenticateUser(cli_credentials_get_username(
762 : creds), correct_password);
763 12 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
764 : "wbcAuthenticateUser of %s failed",
765 : cli_credentials_get_username(creds));
766 :
767 12 : ZERO_STRUCT(params);
768 12 : params.account_name =
769 12 : cli_credentials_get_username(creds);
770 12 : params.level = WBC_AUTH_USER_LEVEL_PLAIN;
771 12 : params.password.plaintext = correct_password;
772 :
773 12 : ret = wbcAuthenticateUserEx(¶ms, &info, &error);
774 12 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
775 : "wbcAuthenticateUserEx of %s failed", params.account_name);
776 12 : wbcFreeMemory(info);
777 12 : info = NULL;
778 :
779 12 : wbcFreeMemory(error);
780 12 : error = NULL;
781 :
782 12 : params.password.plaintext = "wrong";
783 12 : ret = wbcAuthenticateUserEx(¶ms, &info, &error);
784 12 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
785 : "wbcAuthenticateUserEx for %s succeeded where it "
786 : "should have failed", params.account_name);
787 12 : wbcFreeMemory(info);
788 12 : info = NULL;
789 :
790 12 : wbcFreeMemory(error);
791 12 : error = NULL;
792 :
793 12 : return true;
794 : }
795 :
796 4 : static bool test_wbc_authenticate_user(struct torture_context *tctx)
797 : {
798 4 : struct cli_credentials *creds = samba_cmdline_get_creds();
799 :
800 4 : return test_wbc_authenticate_user_int(tctx,
801 : cli_credentials_get_password(creds));
802 : }
803 :
804 4 : static bool test_wbc_change_password(struct torture_context *tctx)
805 : {
806 : wbcErr ret;
807 4 : struct cli_credentials *creds = samba_cmdline_get_creds();
808 3 : const char *oldpass =
809 1 : cli_credentials_get_password(creds);
810 4 : const char *newpass = "Koo8irei%$";
811 :
812 : struct samr_CryptPassword new_nt_password;
813 : struct samr_CryptPassword new_lm_password;
814 : struct samr_Password old_nt_hash_enc;
815 : struct samr_Password old_lanman_hash_enc;
816 :
817 4 : gnutls_cipher_hd_t cipher_hnd = NULL;
818 :
819 : uint8_t old_nt_hash[16];
820 : uint8_t old_lanman_hash[16];
821 : uint8_t new_nt_hash[16];
822 : uint8_t new_lanman_hash[16];
823 4 : gnutls_datum_t old_nt_key = {
824 : .data = old_nt_hash,
825 : .size = sizeof(old_nt_hash),
826 : };
827 :
828 : struct wbcChangePasswordParams params;
829 :
830 4 : if (oldpass == NULL) {
831 0 : torture_skip(tctx,
832 : "skipping wbcChangeUserPassword test as old password cannot be retrieved\n");
833 : }
834 :
835 4 : ZERO_STRUCT(params);
836 :
837 4 : E_md4hash(oldpass, old_nt_hash);
838 4 : E_md4hash(newpass, new_nt_hash);
839 :
840 4 : if (lpcfg_client_lanman_auth(tctx->lp_ctx) &&
841 0 : E_deshash(newpass, new_lanman_hash) &&
842 0 : E_deshash(oldpass, old_lanman_hash)) {
843 :
844 : /* E_deshash returns false for 'long' passwords (> 14
845 : DOS chars). This allows us to match Win2k, which
846 : does not store a LM hash for these passwords (which
847 : would reduce the effective password length to 14) */
848 :
849 0 : encode_pw_buffer(new_lm_password.data, newpass, STR_UNICODE);
850 :
851 0 : gnutls_cipher_init(&cipher_hnd,
852 : GNUTLS_CIPHER_ARCFOUR_128,
853 : &old_nt_key,
854 : NULL);
855 0 : gnutls_cipher_encrypt(cipher_hnd,
856 : new_lm_password.data,
857 : 516);
858 0 : gnutls_cipher_deinit(cipher_hnd);
859 :
860 0 : E_old_pw_hash(new_nt_hash, old_lanman_hash,
861 : old_lanman_hash_enc.hash);
862 :
863 0 : params.old_password.response.old_lm_hash_enc_length =
864 : sizeof(old_lanman_hash_enc.hash);
865 0 : params.old_password.response.old_lm_hash_enc_data =
866 : old_lanman_hash_enc.hash;
867 0 : params.new_password.response.lm_length =
868 : sizeof(new_lm_password.data);
869 0 : params.new_password.response.lm_data =
870 : new_lm_password.data;
871 : } else {
872 4 : ZERO_STRUCT(new_lm_password);
873 4 : ZERO_STRUCT(old_lanman_hash_enc);
874 : }
875 :
876 4 : encode_pw_buffer(new_nt_password.data, newpass, STR_UNICODE);
877 :
878 4 : gnutls_cipher_init(&cipher_hnd,
879 : GNUTLS_CIPHER_ARCFOUR_128,
880 : &old_nt_key,
881 : NULL);
882 4 : gnutls_cipher_encrypt(cipher_hnd,
883 : new_nt_password.data,
884 : 516);
885 4 : gnutls_cipher_deinit(cipher_hnd);
886 :
887 4 : E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
888 :
889 4 : params.old_password.response.old_nt_hash_enc_length =
890 : sizeof(old_nt_hash_enc.hash);
891 4 : params.old_password.response.old_nt_hash_enc_data =
892 : old_nt_hash_enc.hash;
893 4 : params.new_password.response.nt_length = sizeof(new_nt_password.data);
894 4 : params.new_password.response.nt_data = new_nt_password.data;
895 :
896 4 : params.level = WBC_CHANGE_PASSWORD_LEVEL_RESPONSE;
897 4 : params.account_name =
898 4 : cli_credentials_get_username(creds);
899 4 : params.domain_name =
900 4 : cli_credentials_get_domain(creds);
901 :
902 4 : ret = wbcChangeUserPasswordEx(¶ms, NULL, NULL, NULL);
903 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
904 : "wbcChangeUserPassword for %s failed", params.account_name);
905 :
906 4 : if (!test_wbc_authenticate_user_int(tctx, newpass)) {
907 0 : return false;
908 : }
909 :
910 4 : ret = wbcChangeUserPassword(
911 : cli_credentials_get_username(creds),
912 : newpass,
913 : cli_credentials_get_password(creds));
914 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
915 : "wbcChangeUserPassword for %s failed", params.account_name);
916 :
917 4 : return test_wbc_authenticate_user_int(tctx,
918 : cli_credentials_get_password(creds));
919 : }
920 :
921 4 : static bool test_wbc_logon_user(struct torture_context *tctx)
922 : {
923 : struct wbcLogonUserParams params;
924 4 : struct wbcLogonUserInfo *info = NULL;
925 4 : struct wbcAuthErrorInfo *error = NULL;
926 4 : struct wbcUserPasswordPolicyInfo *policy = NULL;
927 : struct wbcInterfaceDetails *iface;
928 : struct wbcDomainSid sid;
929 : enum wbcSidType sidtype;
930 : char *sidstr;
931 : wbcErr ret;
932 4 : struct cli_credentials *creds = samba_cmdline_get_creds();
933 :
934 4 : ZERO_STRUCT(params);
935 :
936 4 : ret = wbcLogonUser(¶ms, &info, &error, &policy);
937 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_INVALID_PARAM,
938 : "%s", "wbcLogonUser succeeded for NULL where it should "
939 : "have failed");
940 :
941 4 : params.username =
942 4 : cli_credentials_get_username(creds);
943 4 : params.password =
944 4 : cli_credentials_get_password(creds);
945 :
946 4 : ret = wbcAddNamedBlob(¶ms.num_blobs, ¶ms.blobs,
947 : "foo", 0, discard_const_p(uint8_t, "bar"), 4);
948 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
949 : "%s", "wbcAddNamedBlob failed");
950 :
951 4 : ret = wbcLogonUser(¶ms, &info, &error, &policy);
952 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
953 : "wbcLogonUser for %s failed", params.username);
954 4 : wbcFreeMemory(info); info = NULL;
955 4 : wbcFreeMemory(error); error = NULL;
956 4 : wbcFreeMemory(policy); policy = NULL;
957 :
958 4 : params.password = "wrong";
959 :
960 4 : ret = wbcLogonUser(¶ms, &info, &error, &policy);
961 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
962 : "wbcLogonUser for %s should have failed with "
963 : "WBC_ERR_AUTH_ERROR", params.username);
964 4 : wbcFreeMemory(info); info = NULL;
965 4 : wbcFreeMemory(error); error = NULL;
966 4 : wbcFreeMemory(policy); policy = NULL;
967 :
968 4 : ret = wbcAddNamedBlob(¶ms.num_blobs, ¶ms.blobs,
969 : "membership_of", 0,
970 : discard_const_p(uint8_t, "S-1-2-3-4"),
971 : strlen("S-1-2-3-4")+1);
972 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
973 : "%s", "wbcAddNamedBlob failed");
974 4 : params.password =
975 4 : cli_credentials_get_password(creds);
976 4 : ret = wbcLogonUser(¶ms, &info, &error, &policy);
977 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
978 : "wbcLogonUser for %s should have failed with "
979 : "WBC_ERR_AUTH_ERROR", params.username);
980 4 : wbcFreeMemory(info); info = NULL;
981 4 : wbcFreeMemory(error); error = NULL;
982 4 : wbcFreeMemory(policy); policy = NULL;
983 4 : wbcFreeMemory(params.blobs);
984 4 : params.blobs = NULL; params.num_blobs = 0;
985 :
986 4 : ret = wbcInterfaceDetails(&iface);
987 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
988 : "%s", "wbcInterfaceDetails failed");
989 :
990 4 : ret = wbcLookupName(iface->netbios_domain,
991 : cli_credentials_get_username(creds),
992 : &sid,
993 : &sidtype);
994 4 : wbcFreeMemory(iface);
995 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
996 : "wbcLookupName for %s failed",
997 : cli_credentials_get_username(creds));
998 :
999 4 : ret = wbcSidToString(&sid, &sidstr);
1000 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
1001 : "%s", "wbcSidToString failed");
1002 :
1003 4 : ret = wbcAddNamedBlob(¶ms.num_blobs, ¶ms.blobs,
1004 : "membership_of", 0,
1005 4 : (uint8_t *)sidstr, strlen(sidstr)+1);
1006 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
1007 : "%s", "wbcAddNamedBlob failed");
1008 4 : wbcFreeMemory(sidstr);
1009 4 : params.password =
1010 4 : cli_credentials_get_password(creds);
1011 4 : ret = wbcLogonUser(¶ms, &info, &error, &policy);
1012 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
1013 : "wbcLogonUser for %s failed", params.username);
1014 4 : wbcFreeMemory(info); info = NULL;
1015 4 : wbcFreeMemory(error); error = NULL;
1016 4 : wbcFreeMemory(policy); policy = NULL;
1017 4 : wbcFreeMemory(params.blobs);
1018 4 : params.blobs = NULL; params.num_blobs = 0;
1019 :
1020 4 : return true;
1021 : }
1022 :
1023 4 : static bool test_wbc_getgroups(struct torture_context *tctx)
1024 : {
1025 : wbcErr ret;
1026 : uint32_t num_groups;
1027 : gid_t *groups;
1028 4 : struct cli_credentials *creds = samba_cmdline_get_creds();
1029 :
1030 4 : ret = wbcGetGroups(
1031 : cli_credentials_get_username(creds),
1032 : &num_groups,
1033 : &groups);
1034 4 : torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
1035 : "wbcGetGroups for %s failed",
1036 : cli_credentials_get_username(creds));
1037 4 : wbcFreeMemory(groups);
1038 4 : return true;
1039 : }
1040 :
1041 2355 : struct torture_suite *torture_wbclient(TALLOC_CTX *ctx)
1042 : {
1043 2355 : struct torture_suite *suite = torture_suite_create(ctx, "wbclient");
1044 :
1045 2355 : torture_suite_add_simple_test(suite, "wbcPing", test_wbc_ping);
1046 2355 : torture_suite_add_simple_test(suite, "wbcPingDc", test_wbc_pingdc);
1047 2355 : torture_suite_add_simple_test(suite, "wbcPingDc2", test_wbc_pingdc2);
1048 2355 : torture_suite_add_simple_test(suite, "wbcLibraryDetails", test_wbc_library_details);
1049 2355 : torture_suite_add_simple_test(suite, "wbcInterfaceDetails", test_wbc_interface_details);
1050 2355 : torture_suite_add_simple_test(suite, "wbcSidTypeString", test_wbc_sidtypestring);
1051 2355 : torture_suite_add_simple_test(suite, "wbcSidToString", test_wbc_sidtostring);
1052 2355 : torture_suite_add_simple_test(suite, "wbcGuidToString", test_wbc_guidtostring);
1053 2355 : torture_suite_add_simple_test(suite, "wbcDomainInfo", test_wbc_domain_info);
1054 2355 : torture_suite_add_simple_test(suite, "wbcListUsers", test_wbc_users);
1055 2355 : torture_suite_add_simple_test(suite, "wbcListGroups", test_wbc_groups);
1056 2355 : torture_suite_add_simple_test(suite, "wbcListTrusts", test_wbc_trusts);
1057 2355 : torture_suite_add_simple_test(suite, "wbcLookupDomainController", test_wbc_lookupdc);
1058 2355 : torture_suite_add_simple_test(suite, "wbcLookupDomainControllerEx", test_wbc_lookupdcex);
1059 2355 : torture_suite_add_simple_test(suite, "wbcResolveWinsByName", test_wbc_resolve_winsbyname);
1060 2355 : torture_suite_add_simple_test(suite, "wbcResolveWinsByIP", test_wbc_resolve_winsbyip);
1061 2355 : torture_suite_add_simple_test(suite, "wbcLookupRids",
1062 : test_wbc_lookup_rids);
1063 2355 : torture_suite_add_simple_test(suite, "wbcGetSidAliases",
1064 : test_wbc_get_sidaliases);
1065 2355 : torture_suite_add_simple_test(suite, "wbcAuthenticateUser",
1066 : test_wbc_authenticate_user);
1067 2355 : torture_suite_add_simple_test(suite, "wbcLogonUser",
1068 : test_wbc_logon_user);
1069 2355 : torture_suite_add_simple_test(suite, "wbcChangeUserPassword",
1070 : test_wbc_change_password);
1071 2355 : torture_suite_add_simple_test(suite, "wbcGetGroups",
1072 : test_wbc_getgroups);
1073 :
1074 2355 : return suite;
1075 : }
|