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