nsswitch: allow passing the domain name to wbcPingDC[2]()
[obnox/samba/samba-obnox.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 "nsswitch/libwbclient/wbclient.h"
26 #include "torture/smbtorture.h"
27 #include "torture/winbind/proto.h"
28 #include "lib/util/util_net.h"
29 #include "lib/util/charset/charset.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "lib/param/param.h"
32 #include "lib/util/samba_util.h"
33 #include "lib/crypto/arcfour.h"
34 #include "auth/credentials/credentials.h"
35 #include "lib/cmdline/popt_common.h"
36
37 #define WBC_ERROR_EQUAL(x,y) (x == y)
38
39 #define torture_assert_wbc_equal(torture_ctx, got, expected, cmt, cmt_arg)      \
40         do { wbcErr __got = got, __expected = expected; \
41         if (!WBC_ERROR_EQUAL(__got, __expected)) { \
42                 torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: " cmt, wbcErrorString(__got), wbcErrorString(__expected), cmt_arg); \
43                 return false; \
44         } \
45         } while (0)
46
47 #define torture_assert_wbc_ok(torture_ctx,expr,cmt,cmt_arg)                     \
48         torture_assert_wbc_equal(torture_ctx,expr,WBC_ERR_SUCCESS,cmt,cmt_arg)
49
50 static bool test_wbc_ping(struct torture_context *tctx)
51 {
52         torture_assert_wbc_ok(tctx, wbcPing(),
53                 "%s", "wbcPing failed");
54
55         return true;
56 }
57
58 static bool test_wbc_pingdc(struct torture_context *tctx)
59 {
60         struct wbcInterfaceDetails *details;
61
62         torture_assert_wbc_equal(tctx, wbcPingDc("random_string", NULL), WBC_ERR_DOMAIN_NOT_FOUND,
63                                  "%s", "wbcPingDc failed");
64         torture_assert_wbc_ok(tctx, wbcPingDc(NULL, NULL),
65                 "%s", "wbcPingDc failed");
66
67         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
68                 "%s", "wbcInterfaceDetails failed");
69         torture_assert(tctx, details,
70                        "wbcInterfaceDetails returned NULL pointer");
71         torture_assert(tctx, details->netbios_domain,
72                        "wbcInterfaceDetails returned NULL netbios_domain");
73
74         torture_assert_wbc_ok(tctx, wbcPingDc(details->netbios_domain, NULL),
75                 "wbcPingDc(%s) failed", details->netbios_domain);
76
77         torture_assert_wbc_ok(tctx, wbcPingDc("BUILTIN", NULL),
78                 "%s", "wbcPingDc(BUILTIN) failed");
79
80         wbcFreeMemory(details);
81         return true;
82 }
83
84 static bool test_wbc_pingdc2(struct torture_context *tctx)
85 {
86         struct wbcInterfaceDetails *details;
87         char *name = NULL;
88
89         torture_assert_wbc_equal(tctx, wbcPingDc2("random_string", NULL, &name),
90                                  WBC_ERR_DOMAIN_NOT_FOUND, "%s",
91                                  "wbcPingDc2 failed");
92         torture_assert_wbc_ok(tctx, wbcPingDc2(NULL, NULL, &name), "%s",
93                               "wbcPingDc2 failed");
94
95         wbcFreeMemory(name);
96
97         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
98                 "%s", "wbcInterfaceDetails failed");
99         torture_assert(tctx, details,
100                        "wbcInterfaceDetails returned NULL pointer");
101         torture_assert(tctx, details->netbios_domain,
102                        "wbcInterfaceDetails returned NULL netbios_domain");
103
104         torture_assert_wbc_ok(tctx, wbcPingDc2(details->netbios_domain, NULL, &name),
105                 "wbcPingDc2(%s) failed", details->netbios_domain);
106         wbcFreeMemory(name);
107
108         torture_assert_wbc_ok(tctx, wbcPingDc2("BUILTIN", NULL, &name),
109                 "%s", "wbcPingDc2(BUILTIN) failed");
110         wbcFreeMemory(name);
111
112         wbcFreeMemory(details);
113
114         return true;
115 }
116
117 static bool test_wbc_library_details(struct torture_context *tctx)
118 {
119         struct wbcLibraryDetails *details;
120
121         torture_assert_wbc_ok(tctx, wbcLibraryDetails(&details),
122                 "%s", "wbcLibraryDetails failed");
123         torture_assert(tctx, details,
124                 "wbcLibraryDetails returned NULL pointer");
125
126         wbcFreeMemory(details);
127
128         return true;
129 }
130
131 static bool test_wbc_interface_details(struct torture_context *tctx)
132 {
133         struct wbcInterfaceDetails *details;
134
135         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
136                 "%s", "wbcInterfaceDetails failed");
137         torture_assert(tctx, details,
138                        "wbcInterfaceDetails returned NULL pointer");
139
140         wbcFreeMemory(details);
141
142         return true;
143 }
144
145 static bool test_wbc_sidtypestring(struct torture_context *tctx)
146 {
147         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_USE_NONE),
148                                  "SID_NONE", "SID_NONE failed");
149         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_USER),
150                                  "SID_USER", "SID_USER failed");
151         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DOM_GRP),
152                                  "SID_DOM_GROUP", "SID_DOM_GROUP failed");
153         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DOMAIN),
154                                  "SID_DOMAIN", "SID_DOMAIN failed");
155         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_ALIAS),
156                                  "SID_ALIAS", "SID_ALIAS failed");
157         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_WKN_GRP),
158                                  "SID_WKN_GROUP", "SID_WKN_GROUP failed");
159         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_DELETED),
160                                  "SID_DELETED", "SID_DELETED failed");
161         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_INVALID),
162                                  "SID_INVALID", "SID_INVALID failed");
163         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_UNKNOWN),
164                                  "SID_UNKNOWN", "SID_UNKNOWN failed");
165         torture_assert_str_equal(tctx, wbcSidTypeString(WBC_SID_NAME_COMPUTER),
166                                  "SID_COMPUTER",  "SID_COMPUTER failed");
167         return true;
168 }
169
170 static bool test_wbc_sidtostring(struct torture_context *tctx)
171 {
172         struct wbcDomainSid sid;
173         const char *sid_string = "S-1-5-32";
174         char *sid_string2;
175
176         torture_assert_wbc_ok(tctx, wbcStringToSid(sid_string, &sid),
177                               "wbcStringToSid of %s failed", sid_string);
178         torture_assert_wbc_ok(tctx, wbcSidToString(&sid, &sid_string2),
179                               "wbcSidToString of %s failed", sid_string);
180         torture_assert_str_equal(tctx, sid_string, sid_string2,
181                 "sid strings differ");
182         wbcFreeMemory(sid_string2);
183
184         return true;
185 }
186
187 static bool test_wbc_guidtostring(struct torture_context *tctx)
188 {
189         struct wbcGuid guid;
190         const char *guid_string = "f7cf07b4-1487-45c7-824d-8b18cc580811";
191         char *guid_string2;
192
193         torture_assert_wbc_ok(tctx, wbcStringToGuid(guid_string, &guid),
194                               "wbcStringToGuid of %s failed", guid_string);
195         torture_assert_wbc_ok(tctx, wbcGuidToString(&guid, &guid_string2),
196                               "wbcGuidToString of %s failed", guid_string);
197         torture_assert_str_equal(tctx, guid_string, guid_string2,
198                                  "guid strings differ");
199         wbcFreeMemory(guid_string2);
200
201         return true;
202 }
203
204 static bool test_wbc_domain_info(struct torture_context *tctx)
205 {
206         struct wbcDomainInfo *info;
207         struct wbcInterfaceDetails *details;
208
209         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
210                 "%s", "wbcInterfaceDetails failed");
211         torture_assert_wbc_ok(
212                 tctx, wbcDomainInfo(details->netbios_domain, &info),
213                 "%s", "wbcDomainInfo failed");
214         wbcFreeMemory(details);
215
216         torture_assert(tctx, info,
217                 "wbcDomainInfo returned NULL pointer");
218         wbcFreeMemory(info);
219
220         return true;
221 }
222
223 static bool test_wbc_users(struct torture_context *tctx)
224 {
225         const char *domain_name = NULL;
226         uint32_t num_users;
227         const char **users;
228         int i;
229         struct wbcInterfaceDetails *details;
230
231         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
232                 "%s", "wbcInterfaceDetails failed");
233
234         domain_name = talloc_strdup(tctx, details->netbios_domain);
235         wbcFreeMemory(details);
236
237         torture_assert_wbc_ok(tctx, wbcListUsers(domain_name, &num_users, &users),
238                 "%s", "wbcListUsers failed");
239         torture_assert(tctx, !(num_users > 0 && !users),
240                 "wbcListUsers returned invalid results");
241
242         for (i=0; i < MIN(num_users,100); i++) {
243
244                 struct wbcDomainSid sid, *sids;
245                 enum wbcSidType name_type;
246                 char *domain;
247                 char *name;
248                 char *sid_string;
249                 uint32_t num_sids;
250
251                 torture_assert_wbc_ok(tctx, wbcLookupName(domain_name, users[i], &sid, &name_type),
252                                       "wbcLookupName of %s failed", users[i]);
253                 torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_USER,
254                                          "wbcLookupName expected WBC_SID_NAME_USER");
255                 wbcSidToString(&sid, &sid_string);
256                 torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
257                                       "wbcLookupSid of %s failed", sid_string);
258                 torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_USER,
259                                          "wbcLookupSid of expected WBC_SID_NAME_USER");
260                 torture_assert(tctx, name,
261                         "wbcLookupSid returned no name");
262                 wbcFreeMemory(domain);
263                 wbcFreeMemory(name);
264                 torture_assert_wbc_ok(tctx, wbcLookupUserSids(&sid, true, &num_sids, &sids),
265                         "wbcLookupUserSids of %s failed", sid_string);
266                 torture_assert_wbc_ok(
267                         tctx, wbcGetDisplayName(&sid, &domain, &name,
268                                                 &name_type),
269                         "wbcGetDisplayName of %s failed", sid_string);
270                 wbcFreeMemory(domain);
271                 wbcFreeMemory(name);
272                 wbcFreeMemory(sids);
273                 wbcFreeMemory(sid_string);
274         }
275         wbcFreeMemory(users);
276
277         return true;
278 }
279
280 static bool test_wbc_groups(struct torture_context *tctx)
281 {
282         const char *domain_name = NULL;
283         uint32_t num_groups;
284         const char **groups;
285         int i;
286         struct wbcInterfaceDetails *details;
287
288         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
289                               "%s", "wbcInterfaceDetails failed");
290
291         domain_name = talloc_strdup(tctx, details->netbios_domain);
292         wbcFreeMemory(details);
293
294         torture_assert_wbc_ok(tctx, wbcListGroups(domain_name, &num_groups, &groups),
295                               "wbcListGroups in %s failed", domain_name);
296         torture_assert(tctx, !(num_groups > 0 && !groups),
297                        "wbcListGroups returned invalid results");
298
299         for (i=0; i < MIN(num_groups,100); i++) {
300
301                 struct wbcDomainSid sid;
302                 enum wbcSidType name_type;
303                 char *domain;
304                 char *name;
305                 char *sid_string;
306
307                 torture_assert_wbc_ok(tctx, wbcLookupName(domain_name, groups[i], &sid, &name_type),
308                                       "wbcLookupName for %s failed", domain_name);
309                 wbcSidToString(&sid, &sid_string);
310                 torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
311                                       "wbcLookupSid of %s failed", sid_string);
312                 wbcFreeMemory(sid_string);
313                 torture_assert(tctx, name,
314                         "wbcLookupSid returned no name");
315         }
316         wbcFreeMemory(groups);
317
318         return true;
319 }
320
321 static bool test_wbc_trusts(struct torture_context *tctx)
322 {
323         struct wbcDomainInfo *domains;
324         size_t num_domains;
325         int i;
326
327         torture_assert_wbc_ok(tctx, wbcListTrusts(&domains, &num_domains),
328                               "%s", "wbcListTrusts failed");
329         torture_assert(tctx, !(num_domains > 0 && !domains),
330                 "wbcListTrusts returned invalid results");
331
332         for (i=0; i < MIN(num_domains,100); i++) {
333
334                 struct wbcAuthErrorInfo *error;
335                 /*
336                 struct wbcDomainSid sid;
337                 enum wbcSidType name_type;
338                 char *domain;
339                 char *name;
340                 */
341                 torture_assert_wbc_ok(tctx, wbcCheckTrustCredentials(domains[i].short_name, &error),
342                                       "%s", "wbcCheckTrustCredentials failed");
343                 /*
344                 torture_assert_wbc_ok(tctx, wbcLookupName(domains[i].short_name, NULL, &sid, &name_type),
345                         "wbcLookupName failed");
346                 torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
347                         "wbcLookupName expected WBC_SID_NAME_DOMAIN");
348                 torture_assert_wbc_ok(tctx, wbcLookupSid(&sid, &domain, &name, &name_type),
349                         "wbcLookupSid failed");
350                 torture_assert_int_equal(tctx, name_type, WBC_SID_NAME_DOMAIN,
351                         "wbcLookupSid expected WBC_SID_NAME_DOMAIN");
352                 torture_assert(tctx, name,
353                         "wbcLookupSid returned no name");
354                 */
355         }
356         wbcFreeMemory(domains);
357
358         return true;
359 }
360
361 static bool test_wbc_lookupdc(struct torture_context *tctx)
362 {
363         const char *domain_name = NULL;
364         struct wbcInterfaceDetails *details;
365         struct wbcDomainControllerInfo *dc_info;
366
367         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
368                 "%s", "wbcInterfaceDetails failed");
369
370         domain_name = talloc_strdup(tctx, details->netbios_domain);
371         wbcFreeMemory(details);
372
373         torture_assert_wbc_ok(tctx, wbcLookupDomainController(domain_name, 0, &dc_info),
374                               "wbcLookupDomainController for %s failed", domain_name);
375         wbcFreeMemory(dc_info);
376
377         return true;
378 }
379
380 static bool test_wbc_lookupdcex(struct torture_context *tctx)
381 {
382         const char *domain_name = NULL;
383         struct wbcInterfaceDetails *details;
384         struct wbcDomainControllerInfoEx *dc_info;
385
386         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
387                 "%s", "wbcInterfaceDetails failed");
388
389         domain_name = talloc_strdup(tctx, details->netbios_domain);
390         wbcFreeMemory(details);
391
392         torture_assert_wbc_ok(tctx, wbcLookupDomainControllerEx(domain_name, NULL, NULL, 0, &dc_info),
393                 "wbcLookupDomainControllerEx for %s failed", domain_name);
394         wbcFreeMemory(dc_info);
395
396         return true;
397 }
398
399 static bool test_wbc_resolve_winsbyname(struct torture_context *tctx)
400 {
401         const char *name;
402         char *ip;
403         wbcErr ret;
404
405         name = torture_setting_string(tctx, "host", NULL);
406
407         ret = wbcResolveWinsByName(name, &ip);
408
409         if (is_ipaddress(name)) {
410                 torture_assert_wbc_equal(tctx, ret, WBC_ERR_DOMAIN_NOT_FOUND, "wbcResolveWinsByName of %s failed", name);
411         } else {
412                 torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByName for %s failed", name);
413         }
414
415         return true;
416 }
417
418 static bool test_wbc_resolve_winsbyip(struct torture_context *tctx)
419 {
420         const char *ip;
421         char *name;
422         wbcErr ret;
423
424         ip = torture_setting_string(tctx, "host", NULL);
425
426         ret = wbcResolveWinsByIP(ip, &name);
427
428         torture_assert_wbc_ok(tctx, ret, "wbcResolveWinsByIP for %s failed", ip);
429
430         wbcFreeMemory(name);
431
432         return true;
433 }
434
435 static bool test_wbc_lookup_rids(struct torture_context *tctx)
436 {
437         struct wbcDomainSid builtin;
438         uint32_t rids[2] = { 544, 545 };
439         const char *domain_name, **names;
440         enum wbcSidType *types;
441         wbcErr ret;
442
443         wbcStringToSid("S-1-5-32", &builtin);
444
445         ret = wbcLookupRids(&builtin, 2, rids, &domain_name, &names,
446                             &types);
447         torture_assert_wbc_ok(tctx, ret, "%s", "wbcLookupRids for 544 and 545 failed");
448
449         torture_assert_str_equal(
450                 tctx, names[0], "Administrators",
451                 "S-1-5-32-544 not mapped to 'Administrators'");
452         torture_assert_str_equal(
453                 tctx, names[1], "Users", "S-1-5-32-545 not mapped to 'Users'");
454
455         wbcFreeMemory(discard_const_p(char ,domain_name));
456         wbcFreeMemory(names);
457         wbcFreeMemory(types);
458
459         return true;
460 }
461
462 static bool test_wbc_get_sidaliases(struct torture_context *tctx)
463 {
464         struct wbcDomainSid builtin;
465         struct wbcDomainInfo *info;
466         struct wbcInterfaceDetails *details;
467         struct wbcDomainSid sids[2];
468         uint32_t *rids;
469         uint32_t num_rids;
470         wbcErr ret;
471
472         torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details),
473                               "%s", "wbcInterfaceDetails failed");
474         torture_assert_wbc_ok(
475                 tctx, wbcDomainInfo(details->netbios_domain, &info),
476                 "wbcDomainInfo of %s failed", details->netbios_domain);
477         wbcFreeMemory(details);
478
479         sids[0] = info->sid;
480         sids[0].sub_auths[sids[0].num_auths++] = 500;
481         sids[1] = info->sid;
482         sids[1].sub_auths[sids[1].num_auths++] = 512;
483         wbcFreeMemory(info);
484
485         torture_assert_wbc_ok(
486                 tctx, wbcStringToSid("S-1-5-32", &builtin),
487                 "wbcStringToSid of %s failed", "S-1-5-32");
488
489         ret = wbcGetSidAliases(&builtin, sids, 2, &rids, &num_rids);
490         torture_assert_wbc_ok(tctx, ret, "%s", "wbcGetSidAliases failed");
491
492         wbcFreeMemory(rids);
493
494         return true;
495 }
496
497 static bool test_wbc_authenticate_user_int(struct torture_context *tctx,
498                                            const char *correct_password)
499 {
500         struct wbcAuthUserParams params;
501         struct wbcAuthUserInfo *info = NULL;
502         struct wbcAuthErrorInfo *error = NULL;
503         wbcErr ret;
504
505         ret = wbcAuthenticateUser(cli_credentials_get_username(cmdline_credentials), correct_password);
506         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
507                                  "wbcAuthenticateUser of %s failed",
508                                  cli_credentials_get_username(cmdline_credentials));
509
510         ZERO_STRUCT(params);
511         params.account_name             = cli_credentials_get_username(cmdline_credentials);
512         params.level                    = WBC_AUTH_USER_LEVEL_PLAIN;
513         params.password.plaintext       = correct_password;
514
515         ret = wbcAuthenticateUserEx(&params, &info, &error);
516         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
517                                  "wbcAuthenticateUserEx of %s failed", params.account_name);
518         wbcFreeMemory(info);
519         info = NULL;
520
521         wbcFreeMemory(error);
522         error = NULL;
523
524         params.password.plaintext       = "wrong";
525         ret = wbcAuthenticateUserEx(&params, &info, &error);
526         torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
527                                  "wbcAuthenticateUserEx for %s succeeded where it "
528                                  "should have failed", params.account_name);
529         wbcFreeMemory(info);
530         info = NULL;
531
532         wbcFreeMemory(error);
533         error = NULL;
534
535         return true;
536 }
537
538 static bool test_wbc_authenticate_user(struct torture_context *tctx)
539 {
540         return test_wbc_authenticate_user_int(tctx, cli_credentials_get_password(cmdline_credentials));
541 }
542
543 static bool test_wbc_change_password(struct torture_context *tctx)
544 {
545         wbcErr ret;
546         const char *oldpass = cli_credentials_get_password(cmdline_credentials);
547         const char *newpass = "Koo8irei%$";
548
549         struct samr_CryptPassword new_nt_password;
550         struct samr_CryptPassword new_lm_password;
551         struct samr_Password old_nt_hash_enc;
552         struct samr_Password old_lanman_hash_enc;
553
554         uint8_t old_nt_hash[16];
555         uint8_t old_lanman_hash[16];
556         uint8_t new_nt_hash[16];
557         uint8_t new_lanman_hash[16];
558
559         struct wbcChangePasswordParams params;
560
561         if (oldpass == NULL) {
562                 torture_skip(tctx,
563                         "skipping wbcChangeUserPassword test as old password cannot be retrieved\n");
564         }
565
566         ZERO_STRUCT(params);
567
568         E_md4hash(oldpass, old_nt_hash);
569         E_md4hash(newpass, new_nt_hash);
570
571         if (lpcfg_client_lanman_auth(tctx->lp_ctx) &&
572             E_deshash(newpass, new_lanman_hash) &&
573             E_deshash(oldpass, old_lanman_hash)) {
574
575                 /* E_deshash returns false for 'long' passwords (> 14
576                    DOS chars).  This allows us to match Win2k, which
577                    does not store a LM hash for these passwords (which
578                    would reduce the effective password length to 14) */
579
580                 encode_pw_buffer(new_lm_password.data, newpass, STR_UNICODE);
581                 arcfour_crypt(new_lm_password.data, old_nt_hash, 516);
582                 E_old_pw_hash(new_nt_hash, old_lanman_hash,
583                               old_lanman_hash_enc.hash);
584
585                 params.old_password.response.old_lm_hash_enc_length =
586                         sizeof(old_lanman_hash_enc.hash);
587                 params.old_password.response.old_lm_hash_enc_data =
588                         old_lanman_hash_enc.hash;
589                 params.new_password.response.lm_length =
590                         sizeof(new_lm_password.data);
591                 params.new_password.response.lm_data =
592                         new_lm_password.data;
593         } else {
594                 ZERO_STRUCT(new_lm_password);
595                 ZERO_STRUCT(old_lanman_hash_enc);
596         }
597
598         encode_pw_buffer(new_nt_password.data, newpass, STR_UNICODE);
599
600         arcfour_crypt(new_nt_password.data, old_nt_hash, 516);
601         E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
602
603         params.old_password.response.old_nt_hash_enc_length =
604                 sizeof(old_nt_hash_enc.hash);
605         params.old_password.response.old_nt_hash_enc_data =
606                 old_nt_hash_enc.hash;
607         params.new_password.response.nt_length = sizeof(new_nt_password.data);
608         params.new_password.response.nt_data = new_nt_password.data;
609
610         params.level = WBC_CHANGE_PASSWORD_LEVEL_RESPONSE;
611         params.account_name = cli_credentials_get_username(cmdline_credentials);
612         params.domain_name = cli_credentials_get_domain(cmdline_credentials);
613
614         ret = wbcChangeUserPasswordEx(&params, NULL, NULL, NULL);
615         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
616                                  "wbcChangeUserPassword for %s failed", params.account_name);
617
618         if (!test_wbc_authenticate_user_int(tctx, newpass)) {
619                 return false;
620         }
621
622         ret = wbcChangeUserPassword(cli_credentials_get_username(cmdline_credentials), newpass,
623                                     cli_credentials_get_password(cmdline_credentials));
624         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
625                                  "wbcChangeUserPassword for %s failed", params.account_name);
626
627         return test_wbc_authenticate_user_int(tctx, cli_credentials_get_password(cmdline_credentials));
628 }
629
630 static bool test_wbc_logon_user(struct torture_context *tctx)
631 {
632         struct wbcLogonUserParams params;
633         struct wbcLogonUserInfo *info = NULL;
634         struct wbcAuthErrorInfo *error = NULL;
635         struct wbcUserPasswordPolicyInfo *policy = NULL;
636         struct wbcInterfaceDetails *iface;
637         struct wbcDomainSid sid;
638         enum wbcSidType sidtype;
639         char *sidstr;
640         wbcErr ret;
641
642         ZERO_STRUCT(params);
643
644         ret = wbcLogonUser(&params, &info, &error, &policy);
645         torture_assert_wbc_equal(tctx, ret, WBC_ERR_INVALID_PARAM,
646                                  "%s", "wbcLogonUser succeeded for NULL where it should "
647                                  "have failed");
648
649         params.username = cli_credentials_get_username(cmdline_credentials);
650         params.password = cli_credentials_get_password(cmdline_credentials);
651
652         ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
653                               "foo", 0, discard_const_p(uint8_t, "bar"), 4);
654         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
655                                  "%s", "wbcAddNamedBlob failed");
656
657         ret = wbcLogonUser(&params, &info, &error, &policy);
658         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
659                                  "wbcLogonUser for %s failed", params.username);
660         wbcFreeMemory(info); info = NULL;
661         wbcFreeMemory(error); error = NULL;
662         wbcFreeMemory(policy); policy = NULL;
663
664         params.password = "wrong";
665
666         ret = wbcLogonUser(&params, &info, &error, &policy);
667         torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
668                                  "wbcLogonUser for %s should have failed with "
669                                  "WBC_ERR_AUTH_ERROR", params.username);
670         wbcFreeMemory(info); info = NULL;
671         wbcFreeMemory(error); error = NULL;
672         wbcFreeMemory(policy); policy = NULL;
673
674         ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
675                               "membership_of", 0,
676                               discard_const_p(uint8_t, "S-1-2-3-4"),
677                               strlen("S-1-2-3-4")+1);
678         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
679                                  "%s", "wbcAddNamedBlob failed");
680         params.password = cli_credentials_get_password(cmdline_credentials);
681         ret = wbcLogonUser(&params, &info, &error, &policy);
682         torture_assert_wbc_equal(tctx, ret, WBC_ERR_AUTH_ERROR,
683                                  "wbcLogonUser for %s should have failed with "
684                                  "WBC_ERR_AUTH_ERROR", params.username);
685         wbcFreeMemory(info); info = NULL;
686         wbcFreeMemory(error); error = NULL;
687         wbcFreeMemory(policy); policy = NULL;
688         wbcFreeMemory(params.blobs);
689         params.blobs = NULL; params.num_blobs = 0;
690
691         ret = wbcInterfaceDetails(&iface);
692         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
693                                  "%s", "wbcInterfaceDetails failed");
694
695         ret = wbcLookupName(iface->netbios_domain, cli_credentials_get_username(cmdline_credentials), &sid,
696                             &sidtype);
697         wbcFreeMemory(iface);
698         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
699                                  "wbcLookupName for %s failed", cli_credentials_get_username(cmdline_credentials));
700
701         ret = wbcSidToString(&sid, &sidstr);
702         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
703                                  "%s", "wbcSidToString failed");
704
705         ret = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
706                               "membership_of", 0,
707                               (uint8_t *)sidstr, strlen(sidstr)+1);
708         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
709                                  "%s", "wbcAddNamedBlob failed");
710         wbcFreeMemory(sidstr);
711         params.password = cli_credentials_get_password(cmdline_credentials);
712         ret = wbcLogonUser(&params, &info, &error, &policy);
713         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
714                                  "wbcLogonUser for %s failed", params.username);
715         wbcFreeMemory(info); info = NULL;
716         wbcFreeMemory(error); error = NULL;
717         wbcFreeMemory(policy); policy = NULL;
718         wbcFreeMemory(params.blobs);
719         params.blobs = NULL; params.num_blobs = 0;
720
721         return true;
722 }
723
724 static bool test_wbc_getgroups(struct torture_context *tctx)
725 {
726         wbcErr ret;
727         uint32_t num_groups;
728         gid_t *groups;
729
730         ret = wbcGetGroups(cli_credentials_get_username(cmdline_credentials), &num_groups, &groups);
731         torture_assert_wbc_equal(tctx, ret, WBC_ERR_SUCCESS,
732                                  "wbcGetGroups for %s failed", cli_credentials_get_username(cmdline_credentials));
733         wbcFreeMemory(groups);
734         return true;
735 }
736
737 struct torture_suite *torture_wbclient(void)
738 {
739         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "wbclient");
740
741         torture_suite_add_simple_test(suite, "wbcPing", test_wbc_ping);
742         torture_suite_add_simple_test(suite, "wbcPingDc", test_wbc_pingdc);
743         torture_suite_add_simple_test(suite, "wbcPingDc2", test_wbc_pingdc2);
744         torture_suite_add_simple_test(suite, "wbcLibraryDetails", test_wbc_library_details);
745         torture_suite_add_simple_test(suite, "wbcInterfaceDetails", test_wbc_interface_details);
746         torture_suite_add_simple_test(suite, "wbcSidTypeString", test_wbc_sidtypestring);
747         torture_suite_add_simple_test(suite, "wbcSidToString", test_wbc_sidtostring);
748         torture_suite_add_simple_test(suite, "wbcGuidToString", test_wbc_guidtostring);
749         torture_suite_add_simple_test(suite, "wbcDomainInfo", test_wbc_domain_info);
750         torture_suite_add_simple_test(suite, "wbcListUsers", test_wbc_users);
751         torture_suite_add_simple_test(suite, "wbcListGroups", test_wbc_groups);
752         torture_suite_add_simple_test(suite, "wbcListTrusts", test_wbc_trusts);
753         torture_suite_add_simple_test(suite, "wbcLookupDomainController", test_wbc_lookupdc);
754         torture_suite_add_simple_test(suite, "wbcLookupDomainControllerEx", test_wbc_lookupdcex);
755         torture_suite_add_simple_test(suite, "wbcResolveWinsByName", test_wbc_resolve_winsbyname);
756         torture_suite_add_simple_test(suite, "wbcResolveWinsByIP", test_wbc_resolve_winsbyip);
757         torture_suite_add_simple_test(suite, "wbcLookupRids",
758                                       test_wbc_lookup_rids);
759         torture_suite_add_simple_test(suite, "wbcGetSidAliases",
760                                       test_wbc_get_sidaliases);
761         torture_suite_add_simple_test(suite, "wbcAuthenticateUser",
762                                       test_wbc_authenticate_user);
763         torture_suite_add_simple_test(suite, "wbcLogonUser",
764                                       test_wbc_logon_user);
765         torture_suite_add_simple_test(suite, "wbcChangeUserPassword",
766                                       test_wbc_change_password);
767         torture_suite_add_simple_test(suite, "wbcGetGroups",
768                                       test_wbc_getgroups);
769
770         return suite;
771 }