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