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