autobuild: fixed clone source for build trees
[samba.git] / nsswitch / wbinfo.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind status program.
5
6    Copyright (C) Tim Potter      2000-2003
7    Copyright (C) Andrew Bartlett 2002-2007
8    Copyright (C) Volker Lendecke 2009
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "popt_common.h"
26 #include "winbind_client.h"
27 #include "libwbclient/wbclient.h"
28 #include "lib/popt/popt.h"
29 #include "../libcli/auth/libcli_auth.h"
30 #if (_SAMBA_BUILD_) >= 4
31 #include "lib/cmdline/popt_common.h"
32 #endif
33
34 #ifdef DBGC_CLASS
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_WINBIND
37 #endif
38
39 static struct wbcInterfaceDetails *init_interface_details(void)
40 {
41         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
42         static struct wbcInterfaceDetails *details;
43
44         if (details) {
45                 return details;
46         }
47
48         wbc_status = wbcInterfaceDetails(&details);
49         if (!WBC_ERROR_IS_OK(wbc_status)) {
50                 d_fprintf(stderr, "could not obtain winbind interface "
51                                   "details: %s\n", wbcErrorString(wbc_status));
52         }
53
54         return details;
55 }
56
57 static char winbind_separator(void)
58 {
59         struct wbcInterfaceDetails *details;
60         static bool got_sep;
61         static char sep;
62
63         if (got_sep)
64                 return sep;
65
66         details = init_interface_details();
67
68         if (!details) {
69                 d_fprintf(stderr, "could not obtain winbind separator!\n");
70                 return 0;
71         }
72
73         sep = details->winbind_separator;
74         got_sep = true;
75
76         if (!sep) {
77                 d_fprintf(stderr, "winbind separator was NULL!\n");
78                 return 0;
79         }
80
81         return sep;
82 }
83
84 static const char *get_winbind_domain(void)
85 {
86         static struct wbcInterfaceDetails *details;
87
88         details = init_interface_details();
89
90         if (!details) {
91                 d_fprintf(stderr, "could not obtain winbind domain name!\n");
92                 return 0;
93         }
94
95         return details->netbios_domain;
96 }
97
98 static const char *get_winbind_netbios_name(void)
99 {
100         static struct wbcInterfaceDetails *details;
101
102         details = init_interface_details();
103
104         if (!details) {
105                 d_fprintf(stderr, "could not obtain winbind netbios name!\n");
106                 return 0;
107         }
108
109         return details->netbios_name;
110 }
111
112 /* Copy of parse_domain_user from winbindd_util.c.  Parse a string of the
113    form DOMAIN/user into a domain and a user */
114
115 static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
116                                      fstring user)
117 {
118
119         char *p = strchr(domuser,winbind_separator());
120
121         if (!p) {
122                 /* Maybe it was a UPN? */
123                 if ((p = strchr(domuser, '@')) != NULL) {
124                         fstrcpy(domain, "");
125                         fstrcpy(user, domuser);
126                         return true;
127                 }
128
129                 fstrcpy(user, domuser);
130                 fstrcpy(domain, get_winbind_domain());
131                 return true;
132         }
133
134         fstrcpy(user, p+1);
135         fstrcpy(domain, domuser);
136         domain[PTR_DIFF(p, domuser)] = 0;
137         strupper_m(domain);
138
139         return true;
140 }
141
142 /* pull pwent info for a given user */
143
144 static bool wbinfo_get_userinfo(char *user)
145 {
146         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
147         struct passwd *pwd = NULL;
148
149         wbc_status = wbcGetpwnam(user, &pwd);
150         if (!WBC_ERROR_IS_OK(wbc_status)) {
151                 d_fprintf(stderr, "failed to call wbcGetpwnam: %s\n",
152                           wbcErrorString(wbc_status));
153                 return false;
154         }
155
156         d_printf("%s:%s:%u:%u:%s:%s:%s\n",
157                  pwd->pw_name,
158                  pwd->pw_passwd,
159                  (unsigned int)pwd->pw_uid,
160                  (unsigned int)pwd->pw_gid,
161                  pwd->pw_gecos,
162                  pwd->pw_dir,
163                  pwd->pw_shell);
164
165         return true;
166 }
167
168 /* pull pwent info for a given uid */
169 static bool wbinfo_get_uidinfo(int uid)
170 {
171         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
172         struct passwd *pwd = NULL;
173
174         wbc_status = wbcGetpwuid(uid, &pwd);
175         if (!WBC_ERROR_IS_OK(wbc_status)) {
176                 d_fprintf(stderr, "failed to call wbcGetpwuid: %s\n",
177                           wbcErrorString(wbc_status));
178                 return false;
179         }
180
181         d_printf("%s:%s:%u:%u:%s:%s:%s\n",
182                  pwd->pw_name,
183                  pwd->pw_passwd,
184                  (unsigned int)pwd->pw_uid,
185                  (unsigned int)pwd->pw_gid,
186                  pwd->pw_gecos,
187                  pwd->pw_dir,
188                  pwd->pw_shell);
189
190         return true;
191 }
192
193 static bool wbinfo_get_user_sidinfo(const char *sid_str)
194 {
195         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
196         struct passwd *pwd = NULL;
197         struct wbcDomainSid sid;
198
199         wbc_status = wbcStringToSid(sid_str, &sid);
200         wbc_status = wbcGetpwsid(&sid, &pwd);
201         if (!WBC_ERROR_IS_OK(wbc_status)) {
202                 d_fprintf(stderr, "failed to call wbcGetpwsid: %s\n",
203                           wbcErrorString(wbc_status));
204                 return false;
205         }
206
207         d_printf("%s:%s:%u:%u:%s:%s:%s\n",
208                  pwd->pw_name,
209                  pwd->pw_passwd,
210                  (unsigned int)pwd->pw_uid,
211                  (unsigned int)pwd->pw_gid,
212                  pwd->pw_gecos,
213                  pwd->pw_dir,
214                  pwd->pw_shell);
215
216         return true;
217 }
218
219
220 /* pull grent for a given group */
221 static bool wbinfo_get_groupinfo(const char *group)
222 {
223         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
224         struct group *grp;
225         char **mem;
226
227         wbc_status = wbcGetgrnam(group, &grp);
228         if (!WBC_ERROR_IS_OK(wbc_status)) {
229                 d_fprintf(stderr, "failed to call wbcGetgrnam: %s\n",
230                           wbcErrorString(wbc_status));
231                 return false;
232         }
233
234         d_printf("%s:%s:%u:",
235                  grp->gr_name,
236                  grp->gr_passwd,
237                  (unsigned int)grp->gr_gid);
238
239         mem = grp->gr_mem;
240         while (*mem != NULL) {
241                 d_printf("%s%s", *mem, *(mem+1) != NULL ? "," : "");
242                 mem += 1;
243         }
244         d_printf("\n");
245
246         wbcFreeMemory(grp);
247
248         return true;
249 }
250
251 /* pull grent for a given gid */
252 static bool wbinfo_get_gidinfo(int gid)
253 {
254         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
255         struct group *grp;
256         char **mem;
257
258         wbc_status = wbcGetgrgid(gid, &grp);
259         if (!WBC_ERROR_IS_OK(wbc_status)) {
260                 d_fprintf(stderr, "failed to call wbcGetgrgid: %s\n",
261                           wbcErrorString(wbc_status));
262                 return false;
263         }
264
265         d_printf("%s:%s:%u:",
266                  grp->gr_name,
267                  grp->gr_passwd,
268                  (unsigned int)grp->gr_gid);
269
270         mem = grp->gr_mem;
271         while (*mem != NULL) {
272                 d_printf("%s%s", *mem, *(mem+1) != NULL ? "," : "");
273                 mem += 1;
274         }
275         d_printf("\n");
276
277         wbcFreeMemory(grp);
278
279         return true;
280 }
281
282 /* List groups a user is a member of */
283
284 static bool wbinfo_get_usergroups(const char *user)
285 {
286         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
287         uint32_t num_groups;
288         uint32_t i;
289         gid_t *groups = NULL;
290
291         /* Send request */
292
293         wbc_status = wbcGetGroups(user, &num_groups, &groups);
294         if (!WBC_ERROR_IS_OK(wbc_status)) {
295                 d_fprintf(stderr, "failed to call wbcGetGroups: %s\n",
296                           wbcErrorString(wbc_status));
297                 return false;
298         }
299
300         for (i = 0; i < num_groups; i++) {
301                 d_printf("%d\n", (int)groups[i]);
302         }
303
304         wbcFreeMemory(groups);
305
306         return true;
307 }
308
309
310 /* List group SIDs a user SID is a member of */
311 static bool wbinfo_get_usersids(const char *user_sid_str)
312 {
313         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
314         uint32_t num_sids;
315         uint32_t i;
316         struct wbcDomainSid user_sid, *sids = NULL;
317
318         /* Send request */
319
320         wbc_status = wbcStringToSid(user_sid_str, &user_sid);
321         if (!WBC_ERROR_IS_OK(wbc_status)) {
322                 d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
323                           wbcErrorString(wbc_status));
324                 return false;
325         }
326
327         wbc_status = wbcLookupUserSids(&user_sid, false, &num_sids, &sids);
328         if (!WBC_ERROR_IS_OK(wbc_status)) {
329                 d_fprintf(stderr, "failed to call wbcLookupUserSids: %s\n",
330                           wbcErrorString(wbc_status));
331                 return false;
332         }
333
334         for (i = 0; i < num_sids; i++) {
335                 char *str = NULL;
336                 wbc_status = wbcSidToString(&sids[i], &str);
337                 if (!WBC_ERROR_IS_OK(wbc_status)) {
338                         d_fprintf(stderr, "failed to call wbcSidToString: "
339                                   "%s\n", wbcErrorString(wbc_status));
340                         wbcFreeMemory(sids);
341                         return false;
342                 }
343                 d_printf("%s\n", str);
344                 wbcFreeMemory(str);
345         }
346
347         wbcFreeMemory(sids);
348
349         return true;
350 }
351
352 static bool wbinfo_get_userdomgroups(const char *user_sid_str)
353 {
354         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
355         uint32_t num_sids;
356         uint32_t i;
357         struct wbcDomainSid user_sid, *sids = NULL;
358
359         /* Send request */
360
361         wbc_status = wbcStringToSid(user_sid_str, &user_sid);
362         if (!WBC_ERROR_IS_OK(wbc_status)) {
363                 d_fprintf(stderr, "failed to call wbcSidToString: %s\n",
364                           wbcErrorString(wbc_status));
365                 return false;
366         }
367
368         wbc_status = wbcLookupUserSids(&user_sid, true, &num_sids, &sids);
369         if (!WBC_ERROR_IS_OK(wbc_status)) {
370                 d_fprintf(stderr, "failed to call wbcLookupUserSids: %s\n",
371                           wbcErrorString(wbc_status));
372                 return false;
373         }
374
375         for (i = 0; i < num_sids; i++) {
376                 char *str = NULL;
377                 wbc_status = wbcSidToString(&sids[i], &str);
378                 if (!WBC_ERROR_IS_OK(wbc_status)) {
379                         d_fprintf(stderr, "failed to call wbcSidToString: "
380                                   "%s\n", wbcErrorString(wbc_status));
381                         wbcFreeMemory(sids);
382                         return false;
383                 }
384                 d_printf("%s\n", str);
385                 wbcFreeMemory(str);
386         }
387
388         wbcFreeMemory(sids);
389
390         return true;
391 }
392
393 static bool wbinfo_get_sidaliases(const char *domain,
394                                   const char *user_sid_str)
395 {
396         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
397         struct wbcDomainInfo *dinfo = NULL;
398         uint32_t i;
399         struct wbcDomainSid user_sid;
400         uint32_t *alias_rids = NULL;
401         uint32_t num_alias_rids;
402         char *domain_sid_str = NULL;
403
404         /* Send request */
405         if ((domain == NULL) || (strequal(domain, ".")) ||
406            (domain[0] == '\0')) {
407                 domain = get_winbind_domain();
408         }
409
410         /* Send request */
411
412         wbc_status = wbcDomainInfo(domain, &dinfo);
413         if (!WBC_ERROR_IS_OK(wbc_status)) {
414                 d_fprintf(stderr, "wbcDomainInfo(%s) failed: %s\n", domain,
415                           wbcErrorString(wbc_status));
416                 goto done;
417         }
418         wbc_status = wbcStringToSid(user_sid_str, &user_sid);
419         if (!WBC_ERROR_IS_OK(wbc_status)) {
420                 goto done;
421         }
422
423         wbc_status = wbcGetSidAliases(&dinfo->sid, &user_sid, 1,
424             &alias_rids, &num_alias_rids);
425         if (!WBC_ERROR_IS_OK(wbc_status)) {
426                 goto done;
427         }
428
429         wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str);
430         if (!WBC_ERROR_IS_OK(wbc_status)) {
431                 goto done;
432         }
433
434         for (i = 0; i < num_alias_rids; i++) {
435                 d_printf("%s-%d\n", domain_sid_str, alias_rids[i]);
436         }
437
438         wbcFreeMemory(alias_rids);
439
440 done:
441         if (domain_sid_str) {
442                 wbcFreeMemory(domain_sid_str);
443         }
444         if (dinfo) {
445                 wbcFreeMemory(dinfo);
446         }
447         return (WBC_ERR_SUCCESS == wbc_status);
448 }
449
450
451 /* Convert NetBIOS name to IP */
452
453 static bool wbinfo_wins_byname(const char *name)
454 {
455         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
456         char *ip = NULL;
457
458         wbc_status = wbcResolveWinsByName(name, &ip);
459         if (!WBC_ERROR_IS_OK(wbc_status)) {
460                 d_fprintf(stderr, "failed to call wbcResolveWinsByName: %s\n",
461                           wbcErrorString(wbc_status));
462                 return false;
463         }
464
465         /* Display response */
466
467         d_printf("%s\n", ip);
468
469         wbcFreeMemory(ip);
470
471         return true;
472 }
473
474 /* Convert IP to NetBIOS name */
475
476 static bool wbinfo_wins_byip(const char *ip)
477 {
478         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
479         char *name = NULL;
480
481         wbc_status = wbcResolveWinsByIP(ip, &name);
482         if (!WBC_ERROR_IS_OK(wbc_status)) {
483                 d_fprintf(stderr, "failed to call wbcResolveWinsByIP: %s\n",
484                           wbcErrorString(wbc_status));
485                 return false;
486         }
487
488         /* Display response */
489
490         d_printf("%s\n", name);
491
492         wbcFreeMemory(name);
493
494         return true;
495 }
496
497 /* List all/trusted domains */
498
499 static bool wbinfo_list_domains(bool list_all_domains, bool verbose)
500 {
501         struct wbcDomainInfo *domain_list = NULL;
502         size_t num_domains;
503         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
504         bool print_all = !list_all_domains && verbose;
505         int i;
506
507         wbc_status = wbcListTrusts(&domain_list, &num_domains);
508         if (!WBC_ERROR_IS_OK(wbc_status)) {
509                 d_fprintf(stderr, "failed to call wbcListTrusts: %s\n",
510                           wbcErrorString(wbc_status));
511                 return false;
512         }
513
514         if (print_all) {
515                 d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n",
516                          "Domain Name", "DNS Domain", "Trust Type",
517                          "Transitive", "In", "Out");
518         }
519
520         for (i=0; i<num_domains; i++) {
521                 if (print_all) {
522                         d_printf("%-16s", domain_list[i].short_name);
523                 } else {
524                         d_printf("%s", domain_list[i].short_name);
525                         d_printf("\n");
526                         continue;
527                 }
528
529                 d_printf("%-24s", domain_list[i].dns_name);
530
531                 switch(domain_list[i].trust_type) {
532                 case WBC_DOMINFO_TRUSTTYPE_NONE:
533                         d_printf("None        ");
534                         break;
535                 case WBC_DOMINFO_TRUSTTYPE_FOREST:
536                         d_printf("Forest      ");
537                         break;
538                 case WBC_DOMINFO_TRUSTTYPE_EXTERNAL:
539                         d_printf("External    ");
540                         break;
541                 case WBC_DOMINFO_TRUSTTYPE_IN_FOREST:
542                         d_printf("In-Forest   ");
543                         break;
544                 }
545
546                 if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_TRANSITIVE) {
547                         d_printf("Yes         ");
548                 } else {
549                         d_printf("No          ");
550                 }
551
552                 if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_INCOMING) {
553                         d_printf("Yes  ");
554                 } else {
555                         d_printf("No   ");
556                 }
557
558                 if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_OUTGOING) {
559                         d_printf("Yes  ");
560                 } else {
561                         d_printf("No   ");
562                 }
563
564                 d_printf("\n");
565         }
566
567         return true;
568 }
569
570 /* List own domain */
571
572 static bool wbinfo_list_own_domain(void)
573 {
574         d_printf("%s\n", get_winbind_domain());
575
576         return true;
577 }
578
579 /* show sequence numbers */
580 static bool wbinfo_show_sequence(const char *domain)
581 {
582         d_printf("This command has been deprecated.  Please use the "
583                  "--online-status option instead.\n");
584         return false;
585 }
586
587 /* show sequence numbers */
588 static bool wbinfo_show_onlinestatus(const char *domain)
589 {
590         struct wbcDomainInfo *domain_list = NULL;
591         size_t num_domains;
592         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
593         int i;
594
595         wbc_status = wbcListTrusts(&domain_list, &num_domains);
596         if (!WBC_ERROR_IS_OK(wbc_status)) {
597                 d_fprintf(stderr, "failed to call wbcListTrusts: %s\n",
598                           wbcErrorString(wbc_status));
599                 return false;
600         }
601
602         for (i=0; i<num_domains; i++) {
603                 bool is_offline;
604
605                 if (domain) {
606                         if (!strequal(domain_list[i].short_name, domain)) {
607                                 continue;
608                         }
609                 }
610
611                 is_offline = (domain_list[i].domain_flags &
612                               WBC_DOMINFO_DOMAIN_OFFLINE);
613
614                 d_printf("%s : %s\n",
615                          domain_list[i].short_name,
616                          is_offline ? "offline" : "online" );
617         }
618
619         return true;
620 }
621
622
623 /* Show domain info */
624
625 static bool wbinfo_domain_info(const char *domain)
626 {
627         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
628         struct wbcDomainInfo *dinfo = NULL;
629         char *sid_str = NULL;
630
631         if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')){
632                 domain = get_winbind_domain();
633         }
634
635         /* Send request */
636
637         wbc_status = wbcDomainInfo(domain, &dinfo);
638         if (!WBC_ERROR_IS_OK(wbc_status)) {
639                 d_fprintf(stderr, "failed to call wbcDomainInfo: %s\n",
640                           wbcErrorString(wbc_status));
641                 return false;
642         }
643
644         wbc_status = wbcSidToString(&dinfo->sid, &sid_str);
645         if (!WBC_ERROR_IS_OK(wbc_status)) {
646                 d_fprintf(stderr, "failed to call wbcSidToString: %s\n",
647                           wbcErrorString(wbc_status));
648                 wbcFreeMemory(dinfo);
649                 return false;
650         }
651
652         /* Display response */
653
654         d_printf("Name              : %s\n", dinfo->short_name);
655         d_printf("Alt_Name          : %s\n", dinfo->dns_name);
656
657         d_printf("SID               : %s\n", sid_str);
658
659         d_printf("Active Directory  : %s\n",
660                  (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_AD) ? "Yes" : "No");
661         d_printf("Native            : %s\n",
662                  (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_NATIVE) ?
663                  "Yes" : "No");
664
665         d_printf("Primary           : %s\n",
666                  (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_PRIMARY) ?
667                  "Yes" : "No");
668
669         wbcFreeMemory(sid_str);
670         wbcFreeMemory(dinfo);
671
672         return true;
673 }
674
675 /* Get a foreign DC's name */
676 static bool wbinfo_getdcname(const char *domain_name)
677 {
678         struct winbindd_request request;
679         struct winbindd_response response;
680
681         ZERO_STRUCT(request);
682         ZERO_STRUCT(response);
683
684         fstrcpy(request.domain_name, domain_name);
685
686         /* Send request */
687
688         if (winbindd_request_response(WINBINDD_GETDCNAME, &request,
689                                       &response) != NSS_STATUS_SUCCESS) {
690                 d_fprintf(stderr, "Could not get dc name for %s\n",domain_name);
691                 return false;
692         }
693
694         /* Display response */
695
696         d_printf("%s\n", response.data.dc_name);
697
698         return true;
699 }
700
701 /* Find a DC */
702 static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags)
703 {
704         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
705         struct wbcDomainControllerInfoEx *dc_info;
706         char *str = NULL;
707
708         wbc_status = wbcLookupDomainControllerEx(domain_name, NULL, NULL,
709                                                  flags | DS_DIRECTORY_SERVICE_REQUIRED,
710                                                  &dc_info);
711         if (!WBC_ERROR_IS_OK(wbc_status)) {
712                 printf("Could not find dc for %s\n", domain_name);
713                 return false;
714         }
715
716         wbcGuidToString(dc_info->domain_guid, &str);
717
718         d_printf("%s\n", dc_info->dc_unc);
719         d_printf("%s\n", dc_info->dc_address);
720         d_printf("%d\n", dc_info->dc_address_type);
721         d_printf("%s\n", str);
722         d_printf("%s\n", dc_info->domain_name);
723         d_printf("%s\n", dc_info->forest_name);
724         d_printf("0x%08x\n", dc_info->dc_flags);
725         d_printf("%s\n", dc_info->dc_site_name);
726         d_printf("%s\n", dc_info->client_site_name);
727
728         return true;
729 }
730
731 /* Check trust account password */
732
733 static bool wbinfo_check_secret(const char *domain)
734 {
735         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
736         struct wbcAuthErrorInfo *error = NULL;
737         const char *domain_name;
738
739         if (domain) {
740                 domain_name = domain;
741         } else {
742                 domain_name = get_winbind_domain();
743         }
744
745         wbc_status = wbcCheckTrustCredentials(domain_name, &error);
746
747         d_printf("checking the trust secret for domain %s via RPC calls %s\n",
748                 domain_name,
749                 WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
750
751         if (wbc_status == WBC_ERR_AUTH_ERROR) {
752                 d_fprintf(stderr, "error code was %s (0x%x)\n",
753                           error->nt_string, error->nt_status);
754                 wbcFreeMemory(error);
755         }
756         if (!WBC_ERROR_IS_OK(wbc_status)) {
757                 d_fprintf(stderr, "failed to call wbcCheckTrustCredentials: "
758                           "%s\n", wbcErrorString(wbc_status));
759                 return false;
760         }
761
762         return true;
763 }
764
765 /* Find the currently connected DCs */
766
767 static bool wbinfo_dc_info(const char *domain_name)
768 {
769         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
770         size_t i, num_dcs;
771         const char **dc_names, **dc_ips;
772
773         wbc_status = wbcDcInfo(domain_name, &num_dcs,
774                                &dc_names, &dc_ips);
775         if (!WBC_ERROR_IS_OK(wbc_status)) {
776                 printf("Could not find dc info %s\n",
777                        domain_name ? domain_name : "our domain");
778                 return false;
779         }
780
781         for (i=0; i<num_dcs; i++) {
782                 printf("%s (%s)\n", dc_names[i], dc_ips[i]);
783         }
784         wbcFreeMemory(dc_names);
785         wbcFreeMemory(dc_ips);
786
787         return true;
788 }
789
790 /* Change trust account password */
791
792 static bool wbinfo_change_secret(const char *domain)
793 {
794         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
795         struct wbcAuthErrorInfo *error = NULL;
796         const char *domain_name;
797
798         if (domain) {
799                 domain_name = domain;
800         } else {
801                 domain_name = get_winbind_domain();
802         }
803
804         wbc_status = wbcChangeTrustCredentials(domain_name, &error);
805
806         d_printf("changing the trust secret for domain %s via RPC calls %s\n",
807                 domain_name,
808                 WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
809
810         if (wbc_status == WBC_ERR_AUTH_ERROR) {
811                 d_fprintf(stderr, "error code was %s (0x%x)\n",
812                           error->nt_string, error->nt_status);
813                 wbcFreeMemory(error);
814         }
815         if (!WBC_ERROR_IS_OK(wbc_status)) {
816                 d_fprintf(stderr, "failed to call wbcChangeTrustCredentials: "
817                           "%s\n", wbcErrorString(wbc_status));
818                 return false;
819         }
820
821         return true;
822 }
823
824 /* Check DC connection */
825
826 static bool wbinfo_ping_dc(void)
827 {
828         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
829         struct wbcAuthErrorInfo *error = NULL;
830
831         wbc_status = wbcPingDc(NULL, &error);
832
833         d_printf("checking the NETLOGON dc connection %s\n",
834                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
835
836         if (wbc_status == WBC_ERR_AUTH_ERROR) {
837                 d_fprintf(stderr, "error code was %s (0x%x)\n",
838                           error->nt_string, error->nt_status);
839                 wbcFreeMemory(error);
840         }
841         if (!WBC_ERROR_IS_OK(wbc_status)) {
842                 d_fprintf(stderr, "failed to call wbcPingDc: %s\n",
843                           wbcErrorString(wbc_status));
844                 return false;
845         }
846
847         return true;
848 }
849
850 /* Convert uid to sid */
851
852 static bool wbinfo_uid_to_sid(uid_t uid)
853 {
854         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
855         struct wbcDomainSid sid;
856         char *sid_str = NULL;
857
858         /* Send request */
859
860         wbc_status = wbcUidToSid(uid, &sid);
861         if (!WBC_ERROR_IS_OK(wbc_status)) {
862                 d_fprintf(stderr, "failed to call wbcUidToSid: %s\n",
863                           wbcErrorString(wbc_status));
864                 return false;
865         }
866
867         wbc_status = wbcSidToString(&sid, &sid_str);
868         if (!WBC_ERROR_IS_OK(wbc_status)) {
869                 d_fprintf(stderr, "failed to call wbcSidToString: %s\n",
870                           wbcErrorString(wbc_status));
871                 return false;
872         }
873
874         /* Display response */
875
876         d_printf("%s\n", sid_str);
877
878         wbcFreeMemory(sid_str);
879
880         return true;
881 }
882
883 /* Convert gid to sid */
884
885 static bool wbinfo_gid_to_sid(gid_t gid)
886 {
887         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
888         struct wbcDomainSid sid;
889         char *sid_str = NULL;
890
891         /* Send request */
892
893         wbc_status = wbcGidToSid(gid, &sid);
894         if (!WBC_ERROR_IS_OK(wbc_status)) {
895                 d_fprintf(stderr, "failed to call wbcGidToSid: %s\n",
896                           wbcErrorString(wbc_status));
897                 return false;
898         }
899
900         wbc_status = wbcSidToString(&sid, &sid_str);
901         if (!WBC_ERROR_IS_OK(wbc_status)) {
902                 d_fprintf(stderr, "failed to call wbcSidToString: %s\n",
903                           wbcErrorString(wbc_status));
904                 return false;
905         }
906
907         /* Display response */
908
909         d_printf("%s\n", sid_str);
910
911         wbcFreeMemory(sid_str);
912
913         return true;
914 }
915
916 /* Convert sid to uid */
917
918 static bool wbinfo_sid_to_uid(const char *sid_str)
919 {
920         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
921         struct wbcDomainSid sid;
922         uid_t uid;
923
924         /* Send request */
925
926         wbc_status = wbcStringToSid(sid_str, &sid);
927         if (!WBC_ERROR_IS_OK(wbc_status)) {
928                 d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
929                           wbcErrorString(wbc_status));
930                 return false;
931         }
932
933         wbc_status = wbcSidToUid(&sid, &uid);
934         if (!WBC_ERROR_IS_OK(wbc_status)) {
935                 d_fprintf(stderr, "failed to call wbcSidToUid: %s\n",
936                           wbcErrorString(wbc_status));
937                 return false;
938         }
939
940         /* Display response */
941
942         d_printf("%d\n", (int)uid);
943
944         return true;
945 }
946
947 static bool wbinfo_sid_to_gid(const char *sid_str)
948 {
949         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
950         struct wbcDomainSid sid;
951         gid_t gid;
952
953         /* Send request */
954
955         wbc_status = wbcStringToSid(sid_str, &sid);
956         if (!WBC_ERROR_IS_OK(wbc_status)) {
957                 d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
958                           wbcErrorString(wbc_status));
959                 return false;
960         }
961
962         wbc_status = wbcSidToGid(&sid, &gid);
963         if (!WBC_ERROR_IS_OK(wbc_status)) {
964                 d_fprintf(stderr, "failed to call wbcSidToGid: %s\n",
965                           wbcErrorString(wbc_status));
966                 return false;
967         }
968
969         /* Display response */
970
971         d_printf("%d\n", (int)gid);
972
973         return true;
974 }
975
976 static bool wbinfo_allocate_uid(void)
977 {
978         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
979         uid_t uid;
980
981         /* Send request */
982
983         wbc_status = wbcAllocateUid(&uid);
984         if (!WBC_ERROR_IS_OK(wbc_status)) {
985                 d_fprintf(stderr, "failed to call wbcAllocateUid: %s\n",
986                           wbcErrorString(wbc_status));
987                 return false;
988         }
989
990         /* Display response */
991
992         d_printf("New uid: %u\n", (unsigned int)uid);
993
994         return true;
995 }
996
997 static bool wbinfo_allocate_gid(void)
998 {
999         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1000         gid_t gid;
1001
1002         /* Send request */
1003
1004         wbc_status = wbcAllocateGid(&gid);
1005         if (!WBC_ERROR_IS_OK(wbc_status)) {
1006                 d_fprintf(stderr, "failed to call wbcAllocateGid: %s\n",
1007                           wbcErrorString(wbc_status));
1008                 return false;
1009         }
1010
1011         /* Display response */
1012
1013         d_printf("New gid: %u\n", (unsigned int)gid);
1014
1015         return true;
1016 }
1017
1018 /* Convert sid to string */
1019
1020 static bool wbinfo_lookupsid(const char *sid_str)
1021 {
1022         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1023         struct wbcDomainSid sid;
1024         char *domain;
1025         char *name;
1026         enum wbcSidType type;
1027
1028         /* Send off request */
1029
1030         wbc_status = wbcStringToSid(sid_str, &sid);
1031         if (!WBC_ERROR_IS_OK(wbc_status)) {
1032                 d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
1033                           wbcErrorString(wbc_status));
1034                 return false;
1035         }
1036
1037         wbc_status = wbcLookupSid(&sid, &domain, &name, &type);
1038         if (!WBC_ERROR_IS_OK(wbc_status)) {
1039                 d_fprintf(stderr, "failed to call wbcLookupSid: %s\n",
1040                           wbcErrorString(wbc_status));
1041                 return false;
1042         }
1043
1044         /* Display response */
1045
1046         d_printf("%s%c%s %d\n",
1047                  domain, winbind_separator(), name, type);
1048
1049         return true;
1050 }
1051
1052 /* Convert sid to fullname */
1053
1054 static bool wbinfo_lookupsid_fullname(const char *sid_str)
1055 {
1056         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1057         struct wbcDomainSid sid;
1058         char *domain;
1059         char *name;
1060         enum wbcSidType type;
1061
1062         /* Send off request */
1063
1064         wbc_status = wbcStringToSid(sid_str, &sid);
1065         if (!WBC_ERROR_IS_OK(wbc_status)) {
1066                 d_fprintf(stderr, "failed to call wbcStringToSid: %s\n",
1067                           wbcErrorString(wbc_status));
1068                 return false;
1069         }
1070
1071         wbc_status = wbcGetDisplayName(&sid, &domain, &name, &type);
1072         if (!WBC_ERROR_IS_OK(wbc_status)) {
1073                 d_fprintf(stderr, "failed to call wbcGetDisplayName: %s\n",
1074                           wbcErrorString(wbc_status));
1075                 return false;
1076         }
1077
1078         /* Display response */
1079
1080         d_printf("%s%c%s %d\n",
1081                  domain, winbind_separator(), name, type);
1082
1083         return true;
1084 }
1085
1086 /* Lookup a list of RIDs */
1087
1088 static bool wbinfo_lookuprids(const char *domain, const char *arg)
1089 {
1090         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1091         struct wbcDomainInfo *dinfo = NULL;
1092         char *domain_name = NULL;
1093         const char **names = NULL;
1094         enum wbcSidType *types = NULL;
1095         size_t i;
1096         int num_rids;
1097         uint32_t *rids = NULL;
1098         const char *p;
1099         char *ridstr;
1100         TALLOC_CTX *mem_ctx = NULL;
1101         bool ret = false;
1102
1103         if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')){
1104                 domain = get_winbind_domain();
1105         }
1106
1107         /* Send request */
1108
1109         wbc_status = wbcDomainInfo(domain, &dinfo);
1110         if (!WBC_ERROR_IS_OK(wbc_status)) {
1111                 d_printf("wbcDomainInfo(%s) failed: %s\n", domain,
1112                          wbcErrorString(wbc_status));
1113                 goto done;
1114         }
1115
1116         mem_ctx = talloc_new(NULL);
1117         if (mem_ctx == NULL) {
1118                 d_printf("talloc_new failed\n");
1119                 goto done;
1120         }
1121
1122         num_rids = 0;
1123         rids = NULL;
1124         p = arg;
1125
1126         while (next_token_talloc(mem_ctx, &p, &ridstr, " ,\n")) {
1127                 uint32_t rid = strtoul(ridstr, NULL, 10);
1128                 rids = talloc_realloc(mem_ctx, rids, uint32_t, num_rids + 1);
1129                 if (rids == NULL) {
1130                         d_printf("talloc_realloc failed\n");
1131                 }
1132                 rids[num_rids] = rid;
1133                 num_rids += 1;
1134         }
1135
1136         if (rids == NULL) {
1137                 d_printf("no rids\n");
1138                 goto done;
1139         }
1140
1141         wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids,
1142                                    (const char **)&domain_name, &names, &types);
1143         if (!WBC_ERROR_IS_OK(wbc_status)) {
1144                 d_printf("winbind_lookup_rids failed: %s\n",
1145                          wbcErrorString(wbc_status));
1146                 goto done;
1147         }
1148
1149         d_printf("Domain: %s\n", domain_name);
1150
1151         for (i=0; i<num_rids; i++) {
1152                 d_printf("%8d: %s (%s)\n", rids[i], names[i],
1153                          wbcSidTypeString(types[i]));
1154         }
1155
1156         ret = true;
1157 done:
1158         if (dinfo) {
1159                 wbcFreeMemory(dinfo);
1160         }
1161         if (domain_name) {
1162                 wbcFreeMemory(domain_name);
1163         }
1164         if (names) {
1165                 wbcFreeMemory(names);
1166         }
1167         if (types) {
1168                 wbcFreeMemory(types);
1169         }
1170         TALLOC_FREE(mem_ctx);
1171         return ret;
1172 }
1173
1174 /* Convert string to sid */
1175
1176 static bool wbinfo_lookupname(const char *full_name)
1177 {
1178         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1179         struct wbcDomainSid sid;
1180         char *sid_str;
1181         enum wbcSidType type;
1182         fstring domain_name;
1183         fstring account_name;
1184
1185         /* Send off request */
1186
1187         parse_wbinfo_domain_user(full_name, domain_name,
1188                                  account_name);
1189
1190         wbc_status = wbcLookupName(domain_name, account_name,
1191                                    &sid, &type);
1192         if (!WBC_ERROR_IS_OK(wbc_status)) {
1193                 d_fprintf(stderr, "failed to call wbcLookupName: %s\n",
1194                           wbcErrorString(wbc_status));
1195                 return false;
1196         }
1197
1198         wbc_status = wbcSidToString(&sid, &sid_str);
1199         if (!WBC_ERROR_IS_OK(wbc_status)) {
1200                 d_fprintf(stderr, "failed to call wbcSidToString: %s\n",
1201                           wbcErrorString(wbc_status));
1202                 return false;
1203         }
1204
1205         /* Display response */
1206
1207         d_printf("%s %s (%d)\n", sid_str, wbcSidTypeString(type), type);
1208
1209         wbcFreeMemory(sid_str);
1210
1211         return true;
1212 }
1213
1214 static char *wbinfo_prompt_pass(TALLOC_CTX *mem_ctx,
1215                                 const char *prefix,
1216                                 const char *username)
1217 {
1218         char *prompt;
1219         const char *ret = NULL;
1220
1221         prompt = talloc_asprintf(mem_ctx, "Enter %s's ", username);
1222         if (!prompt) {
1223                 return NULL;
1224         }
1225         if (prefix) {
1226                 prompt = talloc_asprintf_append(prompt, "%s ", prefix);
1227                 if (!prompt) {
1228                         return NULL;
1229                 }
1230         }
1231         prompt = talloc_asprintf_append(prompt, "password: ");
1232         if (!prompt) {
1233                 return NULL;
1234         }
1235
1236         ret = getpass(prompt);
1237         TALLOC_FREE(prompt);
1238
1239         return talloc_strdup(mem_ctx, ret);
1240 }
1241
1242 /* Authenticate a user with a plaintext password */
1243
1244 static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32_t flags)
1245 {
1246         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1247         char *s = NULL;
1248         char *p = NULL;
1249         char *password = NULL;
1250         char *name = NULL;
1251         char *local_cctype = NULL;
1252         uid_t uid;
1253         struct wbcLogonUserParams params;
1254         struct wbcLogonUserInfo *info;
1255         struct wbcAuthErrorInfo *error;
1256         struct wbcUserPasswordPolicyInfo *policy;
1257         TALLOC_CTX *frame = talloc_tos();
1258
1259         if ((s = talloc_strdup(frame, username)) == NULL) {
1260                 return false;
1261         }
1262
1263         if ((p = strchr(s, '%')) != NULL) {
1264                 *p = 0;
1265                 p++;
1266                 password = talloc_strdup(frame, p);
1267         } else {
1268                 password = wbinfo_prompt_pass(frame, NULL, username);
1269         }
1270
1271         local_cctype = talloc_strdup(frame, cctype);
1272
1273         name = s;
1274
1275         uid = geteuid();
1276
1277         params.username = name;
1278         params.password = password;
1279         params.num_blobs = 0;
1280         params.blobs = NULL;
1281
1282         wbc_status = wbcAddNamedBlob(&params.num_blobs,
1283                                      &params.blobs,
1284                                      "flags",
1285                                      0,
1286                                      (uint8_t *)&flags,
1287                                      sizeof(flags));
1288         if (!WBC_ERROR_IS_OK(wbc_status)) {
1289                 d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n",
1290                           wbcErrorString(wbc_status));
1291                 goto done;
1292         }
1293
1294         wbc_status = wbcAddNamedBlob(&params.num_blobs,
1295                                      &params.blobs,
1296                                      "user_uid",
1297                                      0,
1298                                      (uint8_t *)&uid,
1299                                      sizeof(uid));
1300         if (!WBC_ERROR_IS_OK(wbc_status)) {
1301                 d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n",
1302                           wbcErrorString(wbc_status));
1303                 goto done;
1304         }
1305
1306         wbc_status = wbcAddNamedBlob(&params.num_blobs,
1307                                      &params.blobs,
1308                                      "krb5_cc_type",
1309                                      0,
1310                                      (uint8_t *)local_cctype,
1311                                      strlen(cctype)+1);
1312         if (!WBC_ERROR_IS_OK(wbc_status)) {
1313                 d_fprintf(stderr, "failed to call wbcAddNamedBlob: %s\n",
1314                           wbcErrorString(wbc_status));
1315                 goto done;
1316         }
1317
1318         wbc_status = wbcLogonUser(&params, &info, &error, &policy);
1319
1320         d_printf("plaintext kerberos password authentication for [%s] %s "
1321                  "(requesting cctype: %s)\n",
1322                  username, WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed",
1323                  cctype);
1324
1325         if (error) {
1326                 d_fprintf(stderr,
1327                          "error code was %s (0x%x)\nerror message was: %s\n",
1328                          error->nt_string,
1329                          error->nt_status,
1330                          error->display_string);
1331         }
1332
1333         if (WBC_ERROR_IS_OK(wbc_status)) {
1334                 if (flags & WBFLAG_PAM_INFO3_TEXT) {
1335                         if (info && info->info && info->info->user_flags &
1336                             NETLOGON_CACHED_ACCOUNT) {
1337                                 d_printf("user_flgs: "
1338                                          "NETLOGON_CACHED_ACCOUNT\n");
1339                         }
1340                 }
1341
1342                 if (info) {
1343                         int i;
1344                         for (i=0; i < info->num_blobs; i++) {
1345                                 if (strequal(info->blobs[i].name,
1346                                              "krb5ccname")) {
1347                                         d_printf("credentials were put "
1348                                                  "in: %s\n",
1349                                                 (const char *)
1350                                                       info->blobs[i].blob.data);
1351                                         break;
1352                                 }
1353                         }
1354                 } else {
1355                         d_printf("no credentials cached\n");
1356                 }
1357         }
1358  done:
1359
1360         wbcFreeMemory(params.blobs);
1361
1362         return WBC_ERROR_IS_OK(wbc_status);
1363 }
1364
1365 /* Authenticate a user with a plaintext password */
1366
1367 static bool wbinfo_auth(char *username)
1368 {
1369         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1370         char *s = NULL;
1371         char *p = NULL;
1372         char *password = NULL;
1373         char *name = NULL;
1374         TALLOC_CTX *frame = talloc_tos();
1375
1376         if ((s = talloc_strdup(frame, username)) == NULL) {
1377                 return false;
1378         }
1379
1380         if ((p = strchr(s, '%')) != NULL) {
1381                 *p = 0;
1382                 p++;
1383                 password = talloc_strdup(frame, p);
1384         } else {
1385                 password = wbinfo_prompt_pass(frame, NULL, username);
1386         }
1387
1388         name = s;
1389
1390         wbc_status = wbcAuthenticateUser(name, password);
1391
1392         d_printf("plaintext password authentication %s\n",
1393                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1394
1395 #if 0
1396         if (response.data.auth.nt_status)
1397                 d_fprintf(stderr,
1398                          "error code was %s (0x%x)\nerror message was: %s\n",
1399                          response.data.auth.nt_status_string,
1400                          response.data.auth.nt_status,
1401                          response.data.auth.error_string);
1402 #endif
1403
1404         return WBC_ERROR_IS_OK(wbc_status);
1405 }
1406
1407 /* Authenticate a user with a challenge/response */
1408
1409 static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman)
1410 {
1411         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1412         struct wbcAuthUserParams params;
1413         struct wbcAuthUserInfo *info = NULL;
1414         struct wbcAuthErrorInfo *err = NULL;
1415         DATA_BLOB lm = data_blob_null;
1416         DATA_BLOB nt = data_blob_null;
1417         fstring name_user;
1418         fstring name_domain;
1419         char *pass;
1420         char *p;
1421         TALLOC_CTX *frame = talloc_tos();
1422
1423         p = strchr(username, '%');
1424
1425         if (p) {
1426                 *p = 0;
1427                 pass = talloc_strdup(frame, p + 1);
1428         } else {
1429                 pass = wbinfo_prompt_pass(frame, NULL, username);
1430         }
1431
1432         parse_wbinfo_domain_user(username, name_domain, name_user);
1433
1434         params.account_name     = name_user;
1435         params.domain_name      = name_domain;
1436         params.workstation_name = NULL;
1437
1438         params.flags            = 0;
1439         params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT |
1440                                   WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
1441
1442         params.level            = WBC_AUTH_USER_LEVEL_RESPONSE;
1443
1444         generate_random_buffer(params.password.response.challenge, 8);
1445
1446         if (use_ntlmv2) {
1447                 DATA_BLOB server_chal;
1448                 DATA_BLOB names_blob;
1449
1450                 server_chal = data_blob(params.password.response.challenge, 8);
1451
1452                 /* Pretend this is a login to 'us', for blob purposes */
1453                 names_blob = NTLMv2_generate_names_blob(NULL,
1454                                                 get_winbind_netbios_name(),
1455                                                 get_winbind_domain());
1456
1457                 if (!SMBNTLMv2encrypt(NULL, name_user, name_domain, pass,
1458                                       &server_chal,
1459                                       &names_blob,
1460                                       &lm, &nt, NULL, NULL)) {
1461                         data_blob_free(&names_blob);
1462                         data_blob_free(&server_chal);
1463                         TALLOC_FREE(pass);
1464                         return false;
1465                 }
1466                 data_blob_free(&names_blob);
1467                 data_blob_free(&server_chal);
1468
1469         } else {
1470                 if (use_lanman) {
1471                         bool ok;
1472                         lm = data_blob(NULL, 24);
1473                         ok = SMBencrypt(pass,
1474                                         params.password.response.challenge,
1475                                         lm.data);
1476                         if (!ok) {
1477                                 data_blob_free(&lm);
1478                         }
1479                 }
1480                 nt = data_blob(NULL, 24);
1481                 SMBNTencrypt(pass, params.password.response.challenge,
1482                              nt.data);
1483         }
1484
1485         params.password.response.nt_length      = nt.length;
1486         params.password.response.nt_data        = nt.data;
1487         params.password.response.lm_length      = lm.length;
1488         params.password.response.lm_data        = lm.data;
1489
1490         wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
1491
1492         /* Display response */
1493
1494         d_printf("challenge/response password authentication %s\n",
1495                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1496
1497         if (wbc_status == WBC_ERR_AUTH_ERROR) {
1498                 d_fprintf(stderr,
1499                          "error code was %s (0x%x)\nerror message was: %s\n",
1500                          err->nt_string,
1501                          err->nt_status,
1502                          err->display_string);
1503                 wbcFreeMemory(err);
1504         } else if (WBC_ERROR_IS_OK(wbc_status)) {
1505                 wbcFreeMemory(info);
1506         }
1507
1508         data_blob_free(&nt);
1509         data_blob_free(&lm);
1510
1511         return WBC_ERROR_IS_OK(wbc_status);
1512 }
1513
1514 /* Authenticate a user with a plaintext password */
1515
1516 static bool wbinfo_pam_logon(char *username)
1517 {
1518         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1519         struct wbcLogonUserParams params;
1520         struct wbcAuthErrorInfo *error;
1521         char *s = NULL;
1522         char *p = NULL;
1523         TALLOC_CTX *frame = talloc_tos();
1524         uint32_t flags;
1525         uint32_t uid;
1526
1527         ZERO_STRUCT(params);
1528
1529         if ((s = talloc_strdup(frame, username)) == NULL) {
1530                 return false;
1531         }
1532
1533         if ((p = strchr(s, '%')) != NULL) {
1534                 *p = 0;
1535                 p++;
1536                 params.password = talloc_strdup(frame, p);
1537         } else {
1538                 params.password = wbinfo_prompt_pass(frame, NULL, username);
1539         }
1540         params.username = s;
1541
1542         flags = WBFLAG_PAM_CACHED_LOGIN;
1543
1544         wbc_status = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
1545                                      "flags", 0,
1546                                      (uint8_t *)&flags, sizeof(flags));
1547         if (!WBC_ERROR_IS_OK(wbc_status)) {
1548                 d_printf("wbcAddNamedBlob failed: %s\n",
1549                          wbcErrorString(wbc_status));
1550                 return false;
1551         }
1552
1553         uid = getuid();
1554
1555         wbc_status = wbcAddNamedBlob(&params.num_blobs, &params.blobs,
1556                                      "user_uid", 0,
1557                                      (uint8_t *)&uid, sizeof(uid));
1558         if (!WBC_ERROR_IS_OK(wbc_status)) {
1559                 d_printf("wbcAddNamedBlob failed: %s\n",
1560                          wbcErrorString(wbc_status));
1561                 return false;
1562         }
1563
1564         wbc_status = wbcLogonUser(&params, NULL, &error, NULL);
1565
1566         wbcFreeMemory(params.blobs);
1567
1568         d_printf("plaintext password authentication %s\n",
1569                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1570
1571         if (!WBC_ERROR_IS_OK(wbc_status)) {
1572                 d_fprintf(stderr,
1573                           "error code was %s (0x%x)\nerror message was: %s\n",
1574                           error->nt_string,
1575                           (int)error->nt_status,
1576                           error->display_string);
1577                 wbcFreeMemory(error);
1578                 return false;
1579         }
1580         return true;
1581 }
1582
1583 /* Save creds with winbind */
1584
1585 static bool wbinfo_ccache_save(char *username)
1586 {
1587         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1588         char *s = NULL;
1589         char *p = NULL;
1590         char *password = NULL;
1591         char *name = NULL;
1592         TALLOC_CTX *frame = talloc_stackframe();
1593
1594         s = talloc_strdup(frame, username);
1595         if (s == NULL) {
1596                 return false;
1597         }
1598
1599         p = strchr(s, '%');
1600         if (p != NULL) {
1601                 *p = 0;
1602                 p++;
1603                 password = talloc_strdup(frame, p);
1604         } else {
1605                 password = wbinfo_prompt_pass(frame, NULL, username);
1606         }
1607
1608         name = s;
1609
1610         wbc_status = wbcCredentialSave(name, password);
1611
1612         d_printf("saving creds %s\n",
1613                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1614
1615         TALLOC_FREE(frame);
1616
1617         return WBC_ERROR_IS_OK(wbc_status);
1618 }
1619
1620 #ifdef WITH_FAKE_KASERVER
1621 /* Authenticate a user with a plaintext password and set a token */
1622
1623 static bool wbinfo_klog(char *username)
1624 {
1625         struct winbindd_request request;
1626         struct winbindd_response response;
1627         NSS_STATUS result;
1628         char *p;
1629
1630         /* Send off request */
1631
1632         ZERO_STRUCT(request);
1633         ZERO_STRUCT(response);
1634
1635         p = strchr(username, '%');
1636
1637         if (p) {
1638                 *p = 0;
1639                 fstrcpy(request.data.auth.user, username);
1640                 fstrcpy(request.data.auth.pass, p + 1);
1641                 *p = '%';
1642         } else {
1643                 fstrcpy(request.data.auth.user, username);
1644                 fstrcpy(request.data.auth.pass, getpass("Password: "));
1645         }
1646
1647         request.flags |= WBFLAG_PAM_AFS_TOKEN;
1648
1649         result = winbindd_request_response(WINBINDD_PAM_AUTH, &request,
1650                                            &response);
1651
1652         /* Display response */
1653
1654         d_printf("plaintext password authentication %s\n",
1655                  (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
1656
1657         if (response.data.auth.nt_status)
1658                 d_fprintf(stderr,
1659                          "error code was %s (0x%x)\nerror message was: %s\n",
1660                          response.data.auth.nt_status_string,
1661                          response.data.auth.nt_status,
1662                          response.data.auth.error_string);
1663
1664         if (result != NSS_STATUS_SUCCESS)
1665                 return false;
1666
1667         if (response.extra_data.data == NULL) {
1668                 d_fprintf(stderr, "Did not get token data\n");
1669                 return false;
1670         }
1671
1672         if (!afs_settoken_str((char *)response.extra_data.data)) {
1673                 d_fprintf(stderr, "Could not set token\n");
1674                 return false;
1675         }
1676
1677         d_printf("Successfully created AFS token\n");
1678         return true;
1679 }
1680 #else
1681 static bool wbinfo_klog(char *username)
1682 {
1683         d_fprintf(stderr, "No AFS support compiled in.\n");
1684         return false;
1685 }
1686 #endif
1687
1688 /* Print domain users */
1689
1690 static bool print_domain_users(const char *domain)
1691 {
1692         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1693         uint32_t i;
1694         uint32_t num_users = 0;
1695         const char **users = NULL;
1696
1697         /* Send request to winbind daemon */
1698
1699         /* '.' is the special sign for our own domain */
1700         if (domain && strcmp(domain, ".") == 0) {
1701                 domain = get_winbind_domain();
1702         }
1703
1704         wbc_status = wbcListUsers(domain, &num_users, &users);
1705         if (!WBC_ERROR_IS_OK(wbc_status)) {
1706                 return false;
1707         }
1708
1709         for (i=0; i < num_users; i++) {
1710                 d_printf("%s\n", users[i]);
1711         }
1712
1713         wbcFreeMemory(users);
1714
1715         return true;
1716 }
1717
1718 /* Print domain groups */
1719
1720 static bool print_domain_groups(const char *domain)
1721 {
1722         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1723         uint32_t i;
1724         uint32_t num_groups = 0;
1725         const char **groups = NULL;
1726
1727         /* Send request to winbind daemon */
1728
1729         /* '.' is the special sign for our own domain */
1730         if (domain && strcmp(domain, ".") == 0) {
1731                 domain = get_winbind_domain();
1732         }
1733
1734         wbc_status = wbcListGroups(domain, &num_groups, &groups);
1735         if (!WBC_ERROR_IS_OK(wbc_status)) {
1736                 d_fprintf(stderr, "failed to call wbcListGroups: %s\n",
1737                           wbcErrorString(wbc_status));
1738                 return false;
1739         }
1740
1741         for (i=0; i < num_groups; i++) {
1742                 d_printf("%s\n", groups[i]);
1743         }
1744
1745         wbcFreeMemory(groups);
1746
1747         return true;
1748 }
1749
1750 /* Set the authorised user for winbindd access in secrets.tdb */
1751
1752 static bool wbinfo_set_auth_user(char *username)
1753 {
1754         d_fprintf(stderr, "This functionality was moved to the 'net' utility.\n"
1755                           "See 'net help setauthuser' for details.\n");
1756         return false;
1757 }
1758
1759 static void wbinfo_get_auth_user(void)
1760 {
1761         d_fprintf(stderr, "This functionality was moved to the 'net' utility.\n"
1762                           "See 'net help getauthuser' for details.\n");
1763 }
1764
1765 static bool wbinfo_ping(void)
1766 {
1767         wbcErr wbc_status;
1768
1769         wbc_status = wbcPing();
1770
1771         /* Display response */
1772
1773         d_printf("Ping to winbindd %s\n",
1774                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1775
1776         return WBC_ERROR_IS_OK(wbc_status);
1777 }
1778
1779 static bool wbinfo_change_user_password(const char *username)
1780 {
1781         wbcErr wbc_status;
1782         char *old_password = NULL;
1783         char *new_password = NULL;
1784         TALLOC_CTX *frame = talloc_tos();
1785
1786         old_password = wbinfo_prompt_pass(frame, "old", username);
1787         new_password = wbinfo_prompt_pass(frame, "new", username);
1788
1789         wbc_status = wbcChangeUserPassword(username, old_password,new_password);
1790
1791         /* Display response */
1792
1793         d_printf("Password change for user %s %s\n", username,
1794                 WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1795
1796         return WBC_ERROR_IS_OK(wbc_status);
1797 }
1798
1799 /* Main program */
1800
1801 enum {
1802         OPT_SET_AUTH_USER = 1000,
1803         OPT_GET_AUTH_USER,
1804         OPT_DOMAIN_NAME,
1805         OPT_SEQUENCE,
1806         OPT_GETDCNAME,
1807         OPT_DSGETDCNAME,
1808         OPT_DC_INFO,
1809         OPT_USERDOMGROUPS,
1810         OPT_SIDALIASES,
1811         OPT_USERSIDS,
1812         OPT_ALLOCATE_UID,
1813         OPT_ALLOCATE_GID,
1814         OPT_SEPARATOR,
1815         OPT_LIST_ALL_DOMAINS,
1816         OPT_LIST_OWN_DOMAIN,
1817         OPT_UID_INFO,
1818         OPT_USER_SIDINFO,
1819         OPT_GROUP_INFO,
1820         OPT_GID_INFO,
1821         OPT_VERBOSE,
1822         OPT_ONLINESTATUS,
1823         OPT_CHANGE_USER_PASSWORD,
1824         OPT_CCACHE_SAVE,
1825         OPT_SID_TO_FULLNAME,
1826         OPT_NTLMV2,
1827         OPT_PAM_LOGON,
1828         OPT_LOGOFF,
1829         OPT_LOGOFF_USER,
1830         OPT_LOGOFF_UID,
1831         OPT_LANMAN
1832 };
1833
1834 int main(int argc, char **argv, char **envp)
1835 {
1836         int opt;
1837         TALLOC_CTX *frame = talloc_stackframe();
1838         poptContext pc;
1839         static char *string_arg;
1840         static char *opt_domain_name;
1841         static int int_arg;
1842         int result = 1;
1843         bool verbose = false;
1844         bool use_ntlmv2 = false;
1845         bool use_lanman = false;
1846         char *logoff_user = getenv("USER");
1847         int logoff_uid = geteuid();
1848
1849         struct poptOption long_options[] = {
1850                 POPT_AUTOHELP
1851
1852                 /* longName, shortName, argInfo, argPtr, value, descrip,
1853                    argDesc */
1854
1855                 { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"},
1856                 { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups", "domain" },
1857                 { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP", "NETBIOS-NAME" },
1858                 { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" },
1859                 { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" },
1860                 { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" },
1861                 { "sid-to-fullname", 0, POPT_ARG_STRING, &string_arg,
1862                   OPT_SID_TO_FULLNAME, "Converts sid to fullname", "SID" },
1863                 { "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" },
1864                 { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" },
1865                 { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" },
1866                 { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
1867                 { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" },
1868                 { "allocate-uid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_UID,
1869                   "Get a new UID out of idmap" },
1870                 { "allocate-gid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_GID,
1871                   "Get a new GID out of idmap" },
1872                 { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
1873                 { "change-secret", 'c', POPT_ARG_NONE, 0, 'c', "Change shared secret" },
1874                 { "ping-dc", 'P', POPT_ARG_NONE, 0, 'P',
1875                   "Check the NETLOGON connection" },
1876                 { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
1877                 { "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" },
1878                 { "own-domain", 0, POPT_ARG_NONE, 0, OPT_LIST_OWN_DOMAIN, "List own domain" },
1879                 { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Deprecated command, see --online-status" },
1880                 { "online-status", 0, POPT_ARG_NONE, 0, OPT_ONLINESTATUS, "Show whether domains are marked as online or offline"},
1881                 { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" },
1882                 { "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" },
1883                 { "uid-info", 0, POPT_ARG_INT, &int_arg, OPT_UID_INFO, "Get user info from uid", "UID" },
1884                 { "group-info", 0, POPT_ARG_STRING, &string_arg, OPT_GROUP_INFO, "Get group info", "GROUP" },
1885                 { "user-sidinfo", 0, POPT_ARG_STRING, &string_arg, OPT_USER_SIDINFO, "Get user info from sid", "SID" },
1886                 { "gid-info", 0, POPT_ARG_INT, &int_arg, OPT_GID_INFO, "Get group info from gid", "GID" },
1887                 { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
1888                 { "user-domgroups", 0, POPT_ARG_STRING, &string_arg,
1889                   OPT_USERDOMGROUPS, "Get user domain groups", "SID" },
1890                 { "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" },
1891                 { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
1892                 { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
1893                 { "pam-logon", 0, POPT_ARG_STRING, &string_arg, OPT_PAM_LOGON,
1894                   "do a pam logon equivalent", "user%password" },
1895                 { "logoff", 0, POPT_ARG_NONE, NULL, OPT_LOGOFF,
1896                   "log off user", "uid" },
1897                 { "logoff-user", 0, POPT_ARG_STRING, &logoff_user,
1898                   OPT_LOGOFF_USER, "username to log off" },
1899                 { "logoff-uid", 0, POPT_ARG_INT, &logoff_uid,
1900                   OPT_LOGOFF_UID, "uid to log off" },
1901                 { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
1902                 { "ccache-save", 0, POPT_ARG_STRING, &string_arg,
1903                   OPT_CCACHE_SAVE, "Store user and password for ccache "
1904                   "operation", "user%password" },
1905                 { "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME,
1906                   "Get a DC name for a foreign domain", "domainname" },
1907                 { "dsgetdcname", 0, POPT_ARG_STRING, &string_arg, OPT_DSGETDCNAME, "Find a DC for a domain", "domainname" },
1908                 { "dc-info", 0, POPT_ARG_STRING, &string_arg, OPT_DC_INFO,
1909                   "Find the currently known DCs", "domainname" },
1910                 { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
1911                 { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
1912                 { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" },
1913 #ifdef WITH_FAKE_KASERVER
1914                 { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
1915 #endif
1916 #ifdef HAVE_KRB5
1917                 { "krb5auth", 'K', POPT_ARG_STRING, &string_arg, 'K', "authenticate user using Kerberos", "user%password" },
1918                         /* destroys wbinfo --help output */
1919                         /* "user%password,DOM\\user%password,user@EXAMPLE.COM,EXAMPLE.COM\\user%password" }, */
1920 #endif
1921                 { "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL },
1922                 { "verbose", 0, POPT_ARG_NONE, 0, OPT_VERBOSE, "Print additional information per command", NULL },
1923                 { "change-user-password", 0, POPT_ARG_STRING, &string_arg, OPT_CHANGE_USER_PASSWORD, "Change the password for a user", NULL },
1924                 { "ntlmv2", 0, POPT_ARG_NONE, 0, OPT_NTLMV2, "Use NTLMv2 cryptography for user authentication", NULL},
1925                 { "lanman", 0, POPT_ARG_NONE, 0, OPT_LANMAN, "Use lanman cryptography for user authentication", NULL},
1926                 POPT_COMMON_VERSION
1927                 POPT_TABLEEND
1928         };
1929
1930         /* Samba client initialisation */
1931         load_case_tables();
1932
1933
1934         /* Parse options */
1935
1936         pc = poptGetContext("wbinfo", argc, (const char **)argv,
1937                             long_options, 0);
1938
1939         /* Parse command line options */
1940
1941         if (argc == 1) {
1942                 poptPrintHelp(pc, stderr, 0);
1943                 return 1;
1944         }
1945
1946         while((opt = poptGetNextOpt(pc)) != -1) {
1947                 /* get the generic configuration parameters like --domain */
1948                 switch (opt) {
1949                 case OPT_VERBOSE:
1950                         verbose = true;
1951                         break;
1952                 case OPT_NTLMV2:
1953                         use_ntlmv2 = true;
1954                         break;
1955                 case OPT_LANMAN:
1956                         use_lanman = true;
1957                         break;
1958                 }
1959         }
1960
1961         poptFreeContext(pc);
1962
1963         pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
1964                             POPT_CONTEXT_KEEP_FIRST);
1965
1966         while((opt = poptGetNextOpt(pc)) != -1) {
1967                 switch (opt) {
1968                 case 'u':
1969                         if (!print_domain_users(opt_domain_name)) {
1970                                 d_fprintf(stderr,
1971                                           "Error looking up domain users\n");
1972                                 goto done;
1973                         }
1974                         break;
1975                 case 'g':
1976                         if (!print_domain_groups(opt_domain_name)) {
1977                                 d_fprintf(stderr,
1978                                           "Error looking up domain groups\n");
1979                                 goto done;
1980                         }
1981                         break;
1982                 case 's':
1983                         if (!wbinfo_lookupsid(string_arg)) {
1984                                 d_fprintf(stderr,
1985                                           "Could not lookup sid %s\n",
1986                                           string_arg);
1987                                 goto done;
1988                         }
1989                         break;
1990                 case OPT_SID_TO_FULLNAME:
1991                         if (!wbinfo_lookupsid_fullname(string_arg)) {
1992                                 d_fprintf(stderr, "Could not lookup sid %s\n",
1993                                           string_arg);
1994                                 goto done;
1995                         }
1996                         break;
1997                 case 'R':
1998                         if (!wbinfo_lookuprids(opt_domain_name, string_arg)) {
1999                                 d_fprintf(stderr, "Could not lookup RIDs %s\n",
2000                                           string_arg);
2001                                 goto done;
2002                         }
2003                         break;
2004                 case 'n':
2005                         if (!wbinfo_lookupname(string_arg)) {
2006                                 d_fprintf(stderr, "Could not lookup name %s\n",
2007                                           string_arg);
2008                                 goto done;
2009                         }
2010                         break;
2011                 case 'N':
2012                         if (!wbinfo_wins_byname(string_arg)) {
2013                                 d_fprintf(stderr,
2014                                           "Could not lookup WINS by name %s\n",
2015                                           string_arg);
2016                                 goto done;
2017                         }
2018                         break;
2019                 case 'I':
2020                         if (!wbinfo_wins_byip(string_arg)) {
2021                                 d_fprintf(stderr,
2022                                           "Could not lookup WINS by IP %s\n",
2023                                           string_arg);
2024                                 goto done;
2025                         }
2026                         break;
2027                 case 'U':
2028                         if (!wbinfo_uid_to_sid(int_arg)) {
2029                                 d_fprintf(stderr,
2030                                           "Could not convert uid %d to sid\n",
2031                                           int_arg);
2032                                 goto done;
2033                         }
2034                         break;
2035                 case 'G':
2036                         if (!wbinfo_gid_to_sid(int_arg)) {
2037                                 d_fprintf(stderr,
2038                                           "Could not convert gid %d to sid\n",
2039                                           int_arg);
2040                                 goto done;
2041                         }
2042                         break;
2043                 case 'S':
2044                         if (!wbinfo_sid_to_uid(string_arg)) {
2045                                 d_fprintf(stderr,
2046                                           "Could not convert sid %s to uid\n",
2047                                           string_arg);
2048                                 goto done;
2049                         }
2050                         break;
2051                 case 'Y':
2052                         if (!wbinfo_sid_to_gid(string_arg)) {
2053                                 d_fprintf(stderr,
2054                                           "Could not convert sid %s to gid\n",
2055                                           string_arg);
2056                                 goto done;
2057                         }
2058                         break;
2059                 case OPT_ALLOCATE_UID:
2060                         if (!wbinfo_allocate_uid()) {
2061                                 d_fprintf(stderr, "Could not allocate a uid\n");
2062                                 goto done;
2063                         }
2064                         break;
2065                 case OPT_ALLOCATE_GID:
2066                         if (!wbinfo_allocate_gid()) {
2067                                 d_fprintf(stderr, "Could not allocate a gid\n");
2068                                 goto done;
2069                         }
2070                         break;
2071                 case 't':
2072                         if (!wbinfo_check_secret(opt_domain_name)) {
2073                                 d_fprintf(stderr, "Could not check secret\n");
2074                                 goto done;
2075                         }
2076                         break;
2077                 case 'c':
2078                         if (!wbinfo_change_secret(opt_domain_name)) {
2079                                 d_fprintf(stderr, "Could not change secret\n");
2080                                 goto done;
2081                         }
2082                         break;
2083                 case 'P':
2084                         if (!wbinfo_ping_dc()) {
2085                                 d_fprintf(stderr, "Could not ping our DC\n");
2086                                 goto done;
2087                         }
2088                         break;
2089                 case 'm':
2090                         if (!wbinfo_list_domains(false, verbose)) {
2091                                 d_fprintf(stderr,
2092                                           "Could not list trusted domains\n");
2093                                 goto done;
2094                         }
2095                         break;
2096                 case OPT_SEQUENCE:
2097                         if (!wbinfo_show_sequence(opt_domain_name)) {
2098                                 d_fprintf(stderr,
2099                                           "Could not show sequence numbers\n");
2100                                 goto done;
2101                         }
2102                         break;
2103                 case OPT_ONLINESTATUS:
2104                         if (!wbinfo_show_onlinestatus(opt_domain_name)) {
2105                                 d_fprintf(stderr,
2106                                           "Could not show online-status\n");
2107                                 goto done;
2108                         }
2109                         break;
2110                 case 'D':
2111                         if (!wbinfo_domain_info(string_arg)) {
2112                                 d_fprintf(stderr,
2113                                           "Could not get domain info\n");
2114                                 goto done;
2115                         }
2116                         break;
2117                 case 'i':
2118                         if (!wbinfo_get_userinfo(string_arg)) {
2119                                 d_fprintf(stderr,
2120                                           "Could not get info for user %s\n",
2121                                           string_arg);
2122                                 goto done;
2123                         }
2124                         break;
2125                 case OPT_USER_SIDINFO:
2126                         if ( !wbinfo_get_user_sidinfo(string_arg)) {
2127                                 d_fprintf(stderr,
2128                                           "Could not get info for user "
2129                                           "sid %s\n", string_arg);
2130                                 goto done;
2131                         }
2132                         break;
2133                 case OPT_UID_INFO:
2134                         if ( !wbinfo_get_uidinfo(int_arg)) {
2135                                 d_fprintf(stderr, "Could not get info for uid "
2136                                                 "%d\n", int_arg);
2137                                 goto done;
2138                         }
2139                         break;
2140                 case OPT_GROUP_INFO:
2141                         if ( !wbinfo_get_groupinfo(string_arg)) {
2142                                 d_fprintf(stderr, "Could not get info for "
2143                                           "group %s\n", string_arg);
2144                                 goto done;
2145                         }
2146                         break;
2147                 case OPT_GID_INFO:
2148                         if ( !wbinfo_get_gidinfo(int_arg)) {
2149                                 d_fprintf(stderr, "Could not get info for gid "
2150                                                 "%d\n", int_arg);
2151                                 goto done;
2152                         }
2153                         break;
2154                 case 'r':
2155                         if (!wbinfo_get_usergroups(string_arg)) {
2156                                 d_fprintf(stderr,
2157                                           "Could not get groups for user %s\n",
2158                                           string_arg);
2159                                 goto done;
2160                         }
2161                         break;
2162                 case OPT_USERSIDS:
2163                         if (!wbinfo_get_usersids(string_arg)) {
2164                                 d_fprintf(stderr, "Could not get group SIDs "
2165                                           "for user SID %s\n",
2166                                           string_arg);
2167                                 goto done;
2168                         }
2169                         break;
2170                 case OPT_USERDOMGROUPS:
2171                         if (!wbinfo_get_userdomgroups(string_arg)) {
2172                                 d_fprintf(stderr, "Could not get user's domain "
2173                                          "groups for user SID %s\n",
2174                                          string_arg);
2175                                 goto done;
2176                         }
2177                         break;
2178                 case OPT_SIDALIASES:
2179                         if (!wbinfo_get_sidaliases(opt_domain_name,
2180                                                    string_arg)) {
2181                                 d_fprintf(stderr, "Could not get sid aliases "
2182                                          "for user SID %s\n", string_arg);
2183                                 goto done;
2184                         }
2185                         break;
2186                 case 'a': {
2187                                 bool got_error = false;
2188
2189                                 if (!wbinfo_auth(string_arg)) {
2190                                         d_fprintf(stderr,
2191                                                   "Could not authenticate user "
2192                                                   "%s with plaintext "
2193                                                   "password\n", string_arg);
2194                                         got_error = true;
2195                                 }
2196
2197                                 if (!wbinfo_auth_crap(string_arg, use_ntlmv2,
2198                                                       use_lanman)) {
2199                                         d_fprintf(stderr,
2200                                                 "Could not authenticate user "
2201                                                 "%s with challenge/response\n",
2202                                                 string_arg);
2203                                         got_error = true;
2204                                 }
2205
2206                                 if (got_error)
2207                                         goto done;
2208                                 break;
2209                         }
2210                 case OPT_PAM_LOGON:
2211                         if (!wbinfo_pam_logon(string_arg)) {
2212                                 d_fprintf(stderr, "pam_logon failed for %s\n",
2213                                           string_arg);
2214                                 goto done;
2215                         }
2216                         break;
2217                 case OPT_LOGOFF:
2218                 {
2219                         wbcErr wbc_status;
2220
2221                         wbc_status = wbcLogoffUser(logoff_user, logoff_uid,
2222                                                    "");
2223                         d_printf("Logoff %s (%d): %s\n", logoff_user,
2224                                  logoff_uid, wbcErrorString(wbc_status));
2225                         break;
2226                 }
2227                 case 'K': {
2228                                 uint32_t flags = WBFLAG_PAM_KRB5 |
2229                                                  WBFLAG_PAM_CACHED_LOGIN |
2230                                                 WBFLAG_PAM_FALLBACK_AFTER_KRB5 |
2231                                                  WBFLAG_PAM_INFO3_TEXT |
2232                                                  WBFLAG_PAM_CONTACT_TRUSTDOM;
2233
2234                                 if (!wbinfo_auth_krb5(string_arg, "FILE",
2235                                                       flags)) {
2236                                         d_fprintf(stderr,
2237                                                 "Could not authenticate user "
2238                                                 "[%s] with Kerberos "
2239                                                 "(ccache: %s)\n", string_arg,
2240                                                 "FILE");
2241                                         goto done;
2242                                 }
2243                                 break;
2244                         }
2245                 case 'k':
2246                         if (!wbinfo_klog(string_arg)) {
2247                                 d_fprintf(stderr, "Could not klog user\n");
2248                                 goto done;
2249                         }
2250                         break;
2251                 case 'p':
2252                         if (!wbinfo_ping()) {
2253                                 d_fprintf(stderr, "could not ping winbindd!\n");
2254                                 goto done;
2255                         }
2256                         break;
2257                 case OPT_SET_AUTH_USER:
2258                         if (!wbinfo_set_auth_user(string_arg)) {
2259                                 goto done;
2260                         }
2261                         break;
2262                 case OPT_GET_AUTH_USER:
2263                         wbinfo_get_auth_user();
2264                         goto done;
2265                         break;
2266                 case OPT_CCACHE_SAVE:
2267                         if (!wbinfo_ccache_save(string_arg)) {
2268                                 goto done;
2269                         }
2270                         break;
2271                 case OPT_GETDCNAME:
2272                         if (!wbinfo_getdcname(string_arg)) {
2273                                 goto done;
2274                         }
2275                         break;
2276                 case OPT_DSGETDCNAME:
2277                         if (!wbinfo_dsgetdcname(string_arg, 0)) {
2278                                 goto done;
2279                         }
2280                         break;
2281                 case OPT_DC_INFO:
2282                         if (!wbinfo_dc_info(string_arg)) {
2283                                 goto done;
2284                         }
2285                         break;
2286                 case OPT_SEPARATOR: {
2287                         const char sep = winbind_separator();
2288                         if ( !sep ) {
2289                                 goto done;
2290                         }
2291                         d_printf("%c\n", sep);
2292                         break;
2293                 }
2294                 case OPT_LIST_ALL_DOMAINS:
2295                         if (!wbinfo_list_domains(true, verbose)) {
2296                                 goto done;
2297                         }
2298                         break;
2299                 case OPT_LIST_OWN_DOMAIN:
2300                         if (!wbinfo_list_own_domain()) {
2301                                 goto done;
2302                         }
2303                         break;
2304                 case OPT_CHANGE_USER_PASSWORD:
2305                         if (!wbinfo_change_user_password(string_arg)) {
2306                                 d_fprintf(stderr,
2307                                         "Could not change user password "
2308                                          "for user %s\n", string_arg);
2309                                 goto done;
2310                         }
2311                         break;
2312
2313                 /* generic configuration options */
2314                 case OPT_DOMAIN_NAME:
2315                 case OPT_VERBOSE:
2316                 case OPT_NTLMV2:
2317                 case OPT_LANMAN:
2318                 case OPT_LOGOFF_USER:
2319                 case OPT_LOGOFF_UID:
2320                         break;
2321                 default:
2322                         d_fprintf(stderr, "Invalid option\n");
2323                         poptPrintHelp(pc, stderr, 0);
2324                         goto done;
2325                 }
2326         }
2327
2328         result = 0;
2329
2330         /* Exit code */
2331
2332  done:
2333         talloc_free(frame);
2334
2335         poptFreeContext(pc);
2336         return result;
2337 }