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