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