nsswitch: Fix memory leak in test_wbc_users()
[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         return true;
220 }
221
222 static bool test_wbc_sidtostring(struct torture_context *tctx)
223 {
224         struct wbcDomainSid sid;
225         const char *sid_string = "S-1-5-32";
226         char *sid_string2;
227
228         torture_assert_wbc_ok(tctx, wbcStringToSid(sid_string, &sid),
229                               "wbcStringToSid of %s failed", sid_string);
230         torture_assert_wbc_ok(tctx, wbcSidToString(&sid, &sid_string2),
231                               "wbcSidToString of %s failed", sid_string);
232         torture_assert_str_equal(tctx, sid_string, sid_string2,
233                 "sid strings differ");
234         wbcFreeMemory(sid_string2);
235
236         return true;
237 }
238
239 static bool test_wbc_guidtostring(struct torture_context *tctx)
240 {
241         struct wbcGuid guid;
242         const char *guid_string = "f7cf07b4-1487-45c7-824d-8b18cc580811";
243         char *guid_string2;
244
245         torture_assert_wbc_ok(tctx, wbcStringToGuid(guid_string, &guid),
246                               "wbcStringToGuid of %s failed", guid_string);
247         torture_assert_wbc_ok(tctx, wbcGuidToString(&guid, &guid_string2),
248                               "wbcGuidToString of %s failed", guid_string);
249         torture_assert_str_equal(tctx, guid_string, guid_string2,
250                                  "guid strings differ");
251         wbcFreeMemory(guid_string2);
252
253         return true;
254 }
255
256 static bool test_wbc_domain_info(struct torture_context *tctx)
257 {
258         struct wbcDomainInfo *info = NULL;
259         struct wbcInterfaceDetails *details = NULL;
260         wbcErr ret = false;
261
262         torture_assert_wbc_ok_goto_fail(tctx,
263                                         wbcInterfaceDetails(&details),
264                                         "%s",
265                                         "wbcInterfaceDetails failed");
266         torture_assert_wbc_ok_goto_fail(tctx,
267                                         wbcDomainInfo(details->netbios_domain, &info),
268                                         "%s",
269                                         "wbcDomainInfo failed");
270
271         torture_assert_goto(tctx,
272                             info,
273                             ret,
274                             fail,
275                             "wbcDomainInfo returned NULL pointer");
276
277         ret = true;
278 fail:
279         wbcFreeMemory(details);
280         wbcFreeMemory(info);
281
282         return ret;
283 }
284
285 static bool test_wbc_users(struct torture_context *tctx)
286 {
287         const char *domain_name = NULL;
288         uint32_t num_users;
289         const char **users = NULL;
290         uint32_t i;
291         struct wbcInterfaceDetails *details = NULL;
292         struct wbcDomainSid *sids = NULL;
293         char *domain = NULL;
294         char *name = NULL;
295         char *sid_string = NULL;
296         wbcErr ret = false;
297
298         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
299                 "%s", "wbcInterfaceDetails failed");
300
301         domain_name = talloc_strdup(tctx, details->netbios_domain);
302         torture_assert_goto(tctx,
303                             domain_name != NULL,
304                             ret,
305                             fail,
306                             "Failed to allocate domain_name");
307         wbcFreeMemory(details);
308         details = NULL;
309
310         torture_assert_wbc_ok_goto_fail(tctx,
311                                         wbcListUsers(domain_name, &num_users, &users),
312                                         "%s",
313                                         "wbcListUsers failed");
314         torture_assert_goto(tctx,
315                             !(num_users > 0 && !users),
316                             ret,
317                             fail,
318                             "wbcListUsers returned invalid results");
319
320         for (i = 0; i < MIN(num_users, 100); i++) {
321                 struct wbcDomainSid sid;
322                 enum wbcSidType name_type;
323                 uint32_t num_sids;
324
325                 torture_assert_wbc_ok_goto_fail(tctx,
326                                                 wbcLookupName(domain_name, users[i], &sid, &name_type),
327                                                 "wbcLookupName of %s failed",
328                                                 users[i]);
329                 torture_assert_int_equal_goto(tctx,
330                                               name_type, WBC_SID_NAME_USER,
331                                               ret,
332                                               fail,
333                                               "wbcLookupName expected WBC_SID_NAME_USER");
334                 wbcSidToString(&sid, &sid_string);
335                 torture_assert_wbc_ok_goto_fail(tctx,
336                                                 wbcLookupSid(&sid,
337                                                              &domain,
338                                                              &name,
339                                                              &name_type),
340                                                 "wbcLookupSid of %s failed",
341                                                 sid_string);
342                 torture_assert_int_equal_goto(tctx,
343                                               name_type, WBC_SID_NAME_USER,
344                                               ret,
345                                               fail,
346                                               "wbcLookupSid of expected WBC_SID_NAME_USER");
347                 torture_assert_goto(tctx,
348                                     name,
349                                     ret,
350                                     fail,
351                                     "wbcLookupSid returned no name");
352                 wbcFreeMemory(domain);
353                 domain = NULL;
354                 wbcFreeMemory(name);
355                 name = NULL;
356
357                 torture_assert_wbc_ok_goto_fail(tctx,
358                                                 wbcLookupUserSids(&sid, true, &num_sids, &sids),
359                                                 "wbcLookupUserSids of %s failed", sid_string);
360                 torture_assert_wbc_ok_goto_fail(tctx,
361                                                 wbcGetDisplayName(&sid,
362                                                                   &domain,
363                                                                   &name,
364                                                                   &name_type),
365                                                 "wbcGetDisplayName of %s failed",
366                                                 sid_string);
367                 wbcFreeMemory(domain);
368                 domain = NULL;
369                 wbcFreeMemory(name);
370                 name = NULL;
371                 wbcFreeMemory(sids);
372                 sids = NULL;
373                 wbcFreeMemory(sid_string);
374                 sid_string = NULL;
375         }
376
377         ret = true;
378 fail:
379         wbcFreeMemory(details);
380         wbcFreeMemory(users);
381         wbcFreeMemory(domain);
382         wbcFreeMemory(name);
383         wbcFreeMemory(sids);
384         wbcFreeMemory(sid_string);
385
386         return ret;
387 }
388
389 static bool test_wbc_groups(struct torture_context *tctx)
390 {
391         const char *domain_name = NULL;
392         uint32_t num_groups;
393         const char **groups;
394         int i;
395         struct wbcInterfaceDetails *details;
396
397         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
398                               "%s", "wbcInterfaceDetails failed");
399
400         domain_name = talloc_strdup(tctx, details->netbios_domain);
401         wbcFreeMemory(details);
402
403         torture_assert_wbc_ok(tctx, wbcListGroups(domain_name, &num_groups, &groups),
404                               "wbcListGroups in %s failed", domain_name);
405         torture_assert(tctx, !(num_groups > 0 && !groups),
406                        "wbcListGroups returned invalid results");
407
408         for (i=0; i < MIN(num_groups,100); i++) {
409
410                 struct wbcDomainSid sid;
411                 enum wbcSidType name_type;
412                 char *domain;
413                 char *name;
414                 char *sid_string;
415
416                 torture_assert_wbc_ok(tctx, wbcLookupName(domain_name, groups[i], &sid, &name_type),
417                                       "wbcLookupName for %s failed", domain_name);
418                 wbcSidToString(&sid, &sid_string);
419                 torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
420                                       "wbcLookupSid of %s failed", sid_string);
421                 wbcFreeMemory(sid_string);
422                 torture_assert(tctx, name,
423                         "wbcLookupSid returned no name");
424         }
425         wbcFreeMemory(groups);
426
427         return true;
428 }
429
430 static bool test_wbc_trusts(struct torture_context *tctx)
431 {
432         struct wbcDomainInfo *domains;
433         size_t num_domains;
434         int i;
435
436         torture_assert_wbc_ok(tctx, wbcListTrusts(&domains, &num_domains),
437                               "%s", "wbcListTrusts failed");
438         torture_assert(tctx, !(num_domains > 0 && !domains),
439                 "wbcListTrusts returned invalid results");
440
441         for (i=0; i < MIN(num_domains,100); i++) {
442
443                 struct wbcAuthErrorInfo *error;
444                 /*
445                 struct wbcDomainSid sid;
446                 enum wbcSidType name_type;
447                 char *domain;
448                 char *name;
449                 */
450                 torture_assert_wbc_ok(tctx, wbcCheckTrustCredentials(domains[i].short_name, &error),
451                                       "%s", "wbcCheckTrustCredentials failed");
452                 /*
453                 torture_assert_wbc_ok(tctx, wbcLookupName(domains[i].short_name, NULL, &sid, &name_type),
454                         "wbcLookupName failed");
455                 torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
456                         "wbcLookupName expected WBC_SID_NAME_DOMAIN");
457                 torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
458                         "wbcLookupSid failed");
459                 torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
460                         "wbcLookupSid expected WBC_SID_NAME_DOMAIN");
461                 torture_assert(tctx, name,
462                         "wbcLookupSid returned no name");
463                 */
464         }
465         wbcFreeMemory(domains);
466
467         return true;
468 }
469
470 static bool test_wbc_lookupdc(struct torture_context *tctx)
471 {
472         const char *domain_name = NULL;
473         struct wbcInterfaceDetails *details;
474         struct wbcDomainControllerInfo *dc_info;
475
476         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
477                 "%s", "wbcInterfaceDetails failed");
478
479         domain_name = talloc_strdup(tctx, details->netbios_domain);
480         wbcFreeMemory(details);
481
482         torture_assert_wbc_ok(tctx, wbcLookupDomainController(domain_name, 0, &dc_info),
483                               "wbcLookupDomainController for %s failed", domain_name);
484         wbcFreeMemory(dc_info);
485
486         return true;
487 }
488
489 static bool test_wbc_lookupdcex(struct torture_context *tctx)
490 {
491         const char *domain_name = NULL;
492         struct wbcInterfaceDetails *details;
493         struct wbcDomainControllerInfoEx *dc_info;
494
495         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
496                 "%s", "wbcInterfaceDetails failed");
497
498         domain_name = talloc_strdup(tctx, details->netbios_domain);
499         wbcFreeMemory(details);
500
501         torture_assert_wbc_ok(tctx, wbcLookupDomainControllerEx(domain_name, NULL, NULL, 0, &dc_info),
502                 "wbcLookupDomainControllerEx for %s failed", domain_name);
503         wbcFreeMemory(dc_info);
504
505         return true;
506 }
507
508 static bool test_wbc_resolve_winsbyname(struct torture_context *tctx)
509 {
510         const char *name;
511         char *ip;
512         wbcErr ret;
513
514         name = torture_setting_string(tctx, "host", NULL);
515
516         torture_comment(tctx, "test-WinsByName: host='%s'\n", name);
517
518         ret = wbcResolveWinsByName(name, &ip);
519
520         if (is_ipaddress(name)) {
521                 torture_assert_wbc_equal(tctx, ret, WBC_ERR_DOMAIN_NOT_FOUND, "wbcResolveWinsByName of %s failed", name);
522         } else {
523                 torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByName for %s failed", name);
524         }
525
526         return true;
527 }
528
529 static bool test_wbc_resolve_winsbyip(struct torture_context *tctx)
530 {
531         const char *ip;
532         const char *host;
533         struct nbt_name nbt_name;
534         char *name;
535         wbcErr ret;
536         NTSTATUS status;
537
538         host = torture_setting_string(tctx, "host", NULL);
539
540         torture_comment(tctx, "test-WinsByIp: host='%s'\n", host);
541
542         make_nbt_name_server(&nbt_name, host);
543
544         status = resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
545                                  0, 0, &nbt_name, tctx, &ip, tctx->ev);
546         torture_assert_ntstatus_ok(tctx, status,
547                         talloc_asprintf(tctx,"Failed to resolve %s: %s",
548                                         nbt_name.name, nt_errstr(status)));
549
550         torture_comment(tctx, "test-WinsByIp: ip='%s'\n", ip);
551
552         ret = wbcResolveWinsByIP(ip, &name);
553
554         torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByIP for %s failed", ip);
555
556         wbcFreeMemory(name);
557
558         return true;
559 }
560
561 static bool test_wbc_lookup_rids(struct torture_context *tctx)
562 {
563         struct wbcDomainSid builtin;
564         uint32_t rids[2] = { 544, 545 };
565         const char *domain_name = NULL;
566         const char **names = NULL;
567         enum wbcSidType *types;
568         wbcErr ret = false;
569
570         wbcStringToSid("S-1-5-32", &builtin);
571
572         ret = wbcLookupRids(&builtin, 2, rids, &domain_name, &names,
573                             &types);
574         torture_assert_wbc_ok_goto_fail(
575                 tctx, ret, "%s", "wbcLookupRids for 544 and 545 failed");
576
577         torture_assert_str_equal(
578                 tctx, names[0], "Administrators",
579                 "S-1-5-32-544 not mapped to 'Administrators'");
580         torture_assert_str_equal_goto_fail(
581                 tctx, names[1], "Users", "S-1-5-32-545 not mapped to 'Users'");
582
583         ret = true;
584 fail:
585         wbcFreeMemory(discard_const_p(char ,domain_name));
586         wbcFreeMemory(names);
587         wbcFreeMemory(types);
588         return ret;
589 }
590
591 static bool test_wbc_get_sidaliases(struct torture_context *tctx)
592 {
593         struct wbcDomainSid builtin;
594         struct wbcDomainInfo *info = NULL;
595         struct wbcInterfaceDetails *details = NULL;
596         struct wbcDomainSid sids[2];
597         uint32_t *rids = NULL;
598         uint32_t num_rids;
599         wbcErr ret = false;
600
601         torture_assert_wbc_ok_goto_fail(tctx,
602                                         wbcInterfaceDetails(&details),
603                                         "%s",
604                                         "wbcInterfaceDetails failed");
605         torture_assert_wbc_ok_goto_fail(tctx,
606                                         wbcDomainInfo(details->netbios_domain, &info),
607                                         "wbcDomainInfo of %s failed",
608                                         details->netbios_domain);
609
610         sids[0] = info->sid;
611         sids[0].sub_auths[sids[0].num_auths++] = 500;
612         sids[1] = info->sid;
613         sids[1].sub_auths[sids[1].num_auths++] = 512;
614
615         torture_assert_wbc_ok_goto_fail(tctx,
616                                         wbcStringToSid("S-1-5-32", &builtin),
617                                         "wbcStringToSid of %s failed",
618                                         "S-1-5-32");
619
620         ret = wbcGetSidAliases(&builtin, sids, 2, &rids, &num_rids);
621         torture_assert_wbc_ok_goto_fail(tctx,
622                                         ret,
623                                         "%s",
624                                         "wbcGetSidAliases failed");
625
626         ret = true;
627 fail:
628         wbcFreeMemory(details);
629         wbcFreeMemory(info);
630         wbcFreeMemory(rids);
631         return ret;
632 }
633
634 static bool test_wbc_authenticate_user_int(struct torture_context *tctx,
635                                            const char *correct_password)
636 {
637         struct wbcAuthUserParams params;
638         struct wbcAuthUserInfo *info = NULL;
639         struct wbcAuthErrorInfo *error = NULL;
640         wbcErr ret;
641
642         ret = wbcAuthenticateUser(cli_credentials_get_username(cmdline_credentials), correct_password);
643         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
644                                  "wbcAuthenticateUser of %s failed",
645                                  cli_credentials_get_username(cmdline_credentials));
646
647         ZERO_STRUCT(params);
648         params.account_name             = cli_credentials_get_username(cmdline_credentials);
649         params.level                    = WBC_AUTH_USER_LEVEL_PLAIN;
650         params.password.plaintext       = correct_password;
651
652         ret = wbcAuthenticateUserEx(&params, &info, &error);
653         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
654                                  "wbcAuthenticateUserEx of %s failed", params.account_name);
655         wbcFreeMemory(info);
656         info = NULL;
657
658         wbcFreeMemory(error);
659         error = NULL;
660
661         params.password.plaintext       = "wrong";
662         ret = wbcAuthenticateUserEx(&params, &info, &error);
663         torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
664                                  "wbcAuthenticateUserEx for %s succeeded where it "
665                                  "should have failed", params.account_name);
666         wbcFreeMemory(info);
667         info = NULL;
668
669         wbcFreeMemory(error);
670         error = NULL;
671
672         return true;
673 }
674
675 static bool test_wbc_authenticate_user(struct torture_context *tctx)
676 {
677         return test_wbc_authenticate_user_int(tctx, cli_credentials_get_password(cmdline_credentials));
678 }
679
680 static bool test_wbc_change_password(struct torture_context *tctx)
681 {
682         wbcErr ret;
683         const char *oldpass = cli_credentials_get_password(cmdline_credentials);
684         const char *newpass = "Koo8irei%$";
685
686         struct samr_CryptPassword new_nt_password;
687         struct samr_CryptPassword new_lm_password;
688         struct samr_Password old_nt_hash_enc;
689         struct samr_Password old_lanman_hash_enc;
690
691         uint8_t old_nt_hash[16];
692         uint8_t old_lanman_hash[16];
693         uint8_t new_nt_hash[16];
694         uint8_t new_lanman_hash[16];
695
696         struct wbcChangePasswordParams params;
697
698         if (oldpass == NULL) {
699                 torture_skip(tctx,
700                         "skipping wbcChangeUserPassword test as old password cannot be retrieved\n");
701         }
702
703         ZERO_STRUCT(params);
704
705         E_md4hash(oldpass, old_nt_hash);
706         E_md4hash(newpass, new_nt_hash);
707
708         if (lpcfg_client_lanman_auth(tctx->lp_ctx) &&
709             E_deshash(newpass, new_lanman_hash) &&
710             E_deshash(oldpass, old_lanman_hash)) {
711
712                 /* E_deshash returns false for 'long' passwords (> 14
713                    DOS chars).  This allows us to match Win2k, which
714                    does not store a LM hash for these passwords (which
715                    would reduce the effective password length to 14) */
716
717                 encode_pw_buffer(new_lm_password.data, newpass, STR_UNICODE);
718                 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
719                 E_old_pw_hash(new_nt_hash, old_lanman_hash,
720                               old_lanman_hash_enc.hash);
721
722                 params.old_password.response.old_lm_hash_enc_length =
723                         sizeof(old_lanman_hash_enc.hash);
724                 params.old_password.response.old_lm_hash_enc_data =
725                         old_lanman_hash_enc.hash;
726                 params.new_password.response.lm_length =
727                         sizeof(new_lm_password.data);
728                 params.new_password.response.lm_data =
729                         new_lm_password.data;
730         } else {
731                 ZERO_STRUCT(new_lm_password);
732                 ZERO_STRUCT(old_lanman_hash_enc);
733         }
734
735         encode_pw_buffer(new_nt_password.data, newpass, STR_UNICODE);
736
737         arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
738         E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
739
740         params.old_password.response.old_nt_hash_enc_length =
741                 sizeof(old_nt_hash_enc.hash);
742         params.old_password.response.old_nt_hash_enc_data =
743                 old_nt_hash_enc.hash;
744         params.new_password.response.nt_length = sizeof(new_nt_password.data);
745         params.new_password.response.nt_data = new_nt_password.data;
746
747         params.level = WBC_CHANGE_PASSWORD_LEVEL_RESPONSE;
748         params.account_name = cli_credentials_get_username(cmdline_credentials);
749         params.domain_name = cli_credentials_get_domain(cmdline_credentials);
750
751         ret = wbcChangeUserPasswordEx(&params, NULL, NULL, NULL);
752         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
753                                  "wbcChangeUserPassword for %s failed", params.account_name);
754
755         if (!test_wbc_authenticate_user_int(tctx, newpass)) {
756                 return false;
757         }
758
759         ret = wbcChangeUserPassword(cli_credentials_get_username(cmdline_credentials), newpass,
760                                     cli_credentials_get_password(cmdline_credentials));
761         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
762                                  "wbcChangeUserPassword for %s failed", params.account_name);
763
764         return test_wbc_authenticate_user_int(tctx, cli_credentials_get_password(cmdline_credentials));
765 }
766
767 static bool test_wbc_logon_user(struct torture_context *tctx)
768 {
769         struct wbcLogonUserParams params;
770         struct wbcLogonUserInfo *info = NULL;
771         struct wbcAuthErrorInfo *error = NULL;
772         struct wbcUserPasswordPolicyInfo *policy = NULL;
773         struct wbcInterfaceDetails *iface;
774         struct wbcDomainSid sid;
775         enum wbcSidType sidtype;
776         char *sidstr;
777         wbcErr ret;
778
779         ZERO_STRUCT(params);
780
781         ret = wbcLogonUser(&params, &info, &error, &policy);
782         torture_assert_wbc_equal(tctx, ret, WBC_ERR_INVALID_PARAM,
783                                  "%s", "wbcLogonUser succeeded for NULL where it should "
784                                  "have failed");
785
786         params.username = cli_credentials_get_username(cmdline_credentials);
787         params.password = cli_credentials_get_password(cmdline_credentials);
788
789         ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
790                               "foo", 0, discard_const_p(uint8_t, "bar"), 4);
791         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
792                                  "%s", "wbcAddNamedBlob failed");
793
794         ret = wbcLogonUser(&params, &info, &error, &policy);
795         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
796                                  "wbcLogonUser for %s failed", params.username);
797         wbcFreeMemory(info); info = NULL;
798         wbcFreeMemory(error); error = NULL;
799         wbcFreeMemory(policy); policy = NULL;
800
801         params.password = "wrong";
802
803         ret = wbcLogonUser(&params, &info, &error, &policy);
804         torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
805                                  "wbcLogonUser for %s should have failed with "
806                                  "WBC_ERR_AUTH_ERROR", params.username);
807         wbcFreeMemory(info); info = NULL;
808         wbcFreeMemory(error); error = NULL;
809         wbcFreeMemory(policy); policy = NULL;
810
811         ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
812                               "membership_of", 0,
813                               discard_const_p(uint8_t, "S-1-2-3-4"),
814                               strlen("S-1-2-3-4")+1);
815         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
816                                  "%s", "wbcAddNamedBlob failed");
817         params.password = cli_credentials_get_password(cmdline_credentials);
818         ret = wbcLogonUser(&params, &info, &error, &policy);
819         torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
820                                  "wbcLogonUser for %s should have failed with "
821                                  "WBC_ERR_AUTH_ERROR", params.username);
822         wbcFreeMemory(info); info = NULL;
823         wbcFreeMemory(error); error = NULL;
824         wbcFreeMemory(policy); policy = NULL;
825         wbcFreeMemory(params.blobs);
826         params.blobs = NULL; params.num_blobs = 0;
827
828         ret = wbcInterfaceDetails(&iface);
829         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
830                                  "%s", "wbcInterfaceDetails failed");
831
832         ret = wbcLookupName(iface->netbios_domain, cli_credentials_get_username(cmdline_credentials), &sid,
833                             &sidtype);
834         wbcFreeMemory(iface);
835         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
836                                  "wbcLookupName for %s failed", cli_credentials_get_username(cmdline_credentials));
837
838         ret = wbcSidToString(&sid, &sidstr);
839         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
840                                  "%s", "wbcSidToString failed");
841
842         ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
843                               "membership_of", 0,
844                               (uint8_t *)sidstr, strlen(sidstr)+1);
845         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
846                                  "%s", "wbcAddNamedBlob failed");
847         wbcFreeMemory(sidstr);
848         params.password = cli_credentials_get_password(cmdline_credentials);
849         ret = wbcLogonUser(&params, &info, &error, &policy);
850         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
851                                  "wbcLogonUser for %s failed", params.username);
852         wbcFreeMemory(info); info = NULL;
853         wbcFreeMemory(error); error = NULL;
854         wbcFreeMemory(policy); policy = NULL;
855         wbcFreeMemory(params.blobs);
856         params.blobs = NULL; params.num_blobs = 0;
857
858         return true;
859 }
860
861 static bool test_wbc_getgroups(struct torture_context *tctx)
862 {
863         wbcErr ret;
864         uint32_t num_groups;
865         gid_t *groups;
866
867         ret = wbcGetGroups(cli_credentials_get_username(cmdline_credentials), &num_groups, &groups);
868         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
869                                  "wbcGetGroups for %s failed", cli_credentials_get_username(cmdline_credentials));
870         wbcFreeMemory(groups);
871         return true;
872 }
873
874 struct torture_suite *torture_wbclient(void)
875 {
876         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "wbclient");
877
878         torture_suite_add_simple_test(suite, "wbcPing", test_wbc_ping);
879         torture_suite_add_simple_test(suite, "wbcPingDc", test_wbc_pingdc);
880         torture_suite_add_simple_test(suite, "wbcPingDc2", test_wbc_pingdc2);
881         torture_suite_add_simple_test(suite, "wbcLibraryDetails", test_wbc_library_details);
882         torture_suite_add_simple_test(suite, "wbcInterfaceDetails", test_wbc_interface_details);
883         torture_suite_add_simple_test(suite, "wbcSidTypeString", test_wbc_sidtypestring);
884         torture_suite_add_simple_test(suite, "wbcSidToString", test_wbc_sidtostring);
885         torture_suite_add_simple_test(suite, "wbcGuidToString", test_wbc_guidtostring);
886         torture_suite_add_simple_test(suite, "wbcDomainInfo", test_wbc_domain_info);
887         torture_suite_add_simple_test(suite, "wbcListUsers", test_wbc_users);
888         torture_suite_add_simple_test(suite, "wbcListGroups", test_wbc_groups);
889         torture_suite_add_simple_test(suite, "wbcListTrusts", test_wbc_trusts);
890         torture_suite_add_simple_test(suite, "wbcLookupDomainController", test_wbc_lookupdc);
891         torture_suite_add_simple_test(suite, "wbcLookupDomainControllerEx", test_wbc_lookupdcex);
892         torture_suite_add_simple_test(suite, "wbcResolveWinsByName", test_wbc_resolve_winsbyname);
893         torture_suite_add_simple_test(suite, "wbcResolveWinsByIP", test_wbc_resolve_winsbyip);
894         torture_suite_add_simple_test(suite, "wbcLookupRids",
895                                       test_wbc_lookup_rids);
896         torture_suite_add_simple_test(suite, "wbcGetSidAliases",
897                                       test_wbc_get_sidaliases);
898         torture_suite_add_simple_test(suite, "wbcAuthenticateUser",
899                                       test_wbc_authenticate_user);
900         torture_suite_add_simple_test(suite, "wbcLogonUser",
901                                       test_wbc_logon_user);
902         torture_suite_add_simple_test(suite, "wbcChangeUserPassword",
903                                       test_wbc_change_password);
904         torture_suite_add_simple_test(suite, "wbcGetGroups",
905                                       test_wbc_getgroups);
906
907         return suite;
908 }