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