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