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