s3 wbinfo: remove --get-auth-user and --set-auth-user functionality
[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 *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 rid = strtoul(ridstr, NULL, 10);
1079                 ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids);
1080         }
1081
1082         if (rids == NULL) {
1083                 d_printf("no rids\n");
1084                 goto done;
1085         }
1086
1087         wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids,
1088                                    (const char **)&domain_name, &names, &types);
1089         if (!WBC_ERROR_IS_OK(wbc_status)) {
1090                 d_printf("winbind_lookup_rids failed: %s\n",
1091                          wbcErrorString(wbc_status));
1092                 goto done;
1093         }
1094
1095         d_printf("Domain: %s\n", domain_name);
1096
1097         for (i=0; i<num_rids; i++) {
1098                 d_printf("%8d: %s (%s)\n", rids[i], names[i],
1099                          sid_type_lookup(types[i]));
1100         }
1101
1102         ret = true;
1103 done:
1104         if (dinfo) {
1105                 wbcFreeMemory(dinfo);
1106         }
1107         if (domain_name) {
1108                 wbcFreeMemory(domain_name);
1109         }
1110         if (names) {
1111                 wbcFreeMemory(names);
1112         }
1113         if (types) {
1114                 wbcFreeMemory(types);
1115         }
1116         TALLOC_FREE(mem_ctx);
1117         return ret;
1118 }
1119
1120 /* Convert string to sid */
1121
1122 static bool wbinfo_lookupname(const char *full_name)
1123 {
1124         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1125         struct wbcDomainSid sid;
1126         char *sid_str;
1127         enum wbcSidType type;
1128         fstring domain_name;
1129         fstring account_name;
1130
1131         /* Send off request */
1132
1133         parse_wbinfo_domain_user(full_name, domain_name,
1134                                  account_name);
1135
1136         wbc_status = wbcLookupName(domain_name, account_name,
1137                                    &sid, &type);
1138         if (!WBC_ERROR_IS_OK(wbc_status)) {
1139                 return false;
1140         }
1141
1142         wbc_status = wbcSidToString(&sid, &sid_str);
1143         if (!WBC_ERROR_IS_OK(wbc_status)) {
1144                 return false;
1145         }
1146
1147         /* Display response */
1148
1149         d_printf("%s %s (%d)\n", sid_str, sid_type_lookup(type), type);
1150
1151         wbcFreeMemory(sid_str);
1152
1153         return true;
1154 }
1155
1156 static char *wbinfo_prompt_pass(const char *prefix,
1157                                 const char *username)
1158 {
1159         char *prompt;
1160         const char *ret = NULL;
1161
1162         prompt = talloc_asprintf(talloc_tos(), "Enter %s's ", username);
1163         if (!prompt) {
1164                 return NULL;
1165         }
1166         if (prefix) {
1167                 prompt = talloc_asprintf_append(prompt, "%s ", prefix);
1168                 if (!prompt) {
1169                         return NULL;
1170                 }
1171         }
1172         prompt = talloc_asprintf_append(prompt, "password: ");
1173         if (!prompt) {
1174                 return NULL;
1175         }
1176
1177         ret = getpass(prompt);
1178         TALLOC_FREE(prompt);
1179
1180         return SMB_STRDUP(ret);
1181 }
1182
1183 /* Authenticate a user with a plaintext password */
1184
1185 static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
1186 {
1187         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1188         char *s = NULL;
1189         char *p = NULL;
1190         char *password = NULL;
1191         char *name = NULL;
1192         uid_t uid;
1193         struct wbcLogonUserParams params;
1194         struct wbcLogonUserInfo *info;
1195         struct wbcAuthErrorInfo *error;
1196         struct wbcUserPasswordPolicyInfo *policy;
1197
1198         if ((s = SMB_STRDUP(username)) == NULL) {
1199                 return false;
1200         }
1201
1202         if ((p = strchr(s, '%')) != NULL) {
1203                 *p = 0;
1204                 p++;
1205                 password = SMB_STRDUP(p);
1206         } else {
1207                 password = wbinfo_prompt_pass(NULL, username);
1208         }
1209
1210         name = s;
1211
1212         uid = geteuid();
1213
1214         params.username = name;
1215         params.password = password;
1216         params.num_blobs = 0;
1217         params.blobs = NULL;
1218
1219         wbc_status = wbcAddNamedBlob(&params.num_blobs,
1220                                      &params.blobs,
1221                                      "flags",
1222                                      0,
1223                                      (uint8_t *)&flags,
1224                                      sizeof(flags));
1225         if (!WBC_ERROR_IS_OK(wbc_status)) {
1226                 goto done;
1227         }
1228
1229         wbc_status = wbcAddNamedBlob(&params.num_blobs,
1230                                      &params.blobs,
1231                                      "user_uid",
1232                                      0,
1233                                      (uint8_t *)&uid,
1234                                      sizeof(uid));
1235         if (!WBC_ERROR_IS_OK(wbc_status)) {
1236                 goto done;
1237         }
1238
1239         wbc_status = wbcAddNamedBlob(&params.num_blobs,
1240                                      &params.blobs,
1241                                      "krb5_cc_type",
1242                                      0,
1243                                      (uint8_t *)cctype,
1244                                      strlen(cctype)+1);
1245         if (!WBC_ERROR_IS_OK(wbc_status)) {
1246                 goto done;
1247         }
1248
1249         wbc_status = wbcLogonUser(&params, &info, &error, &policy);
1250
1251         d_printf("plaintext kerberos password authentication for [%s] %s "
1252                  "(requesting cctype: %s)\n",
1253                  username, WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed",
1254                  cctype);
1255
1256         if (error) {
1257                 d_fprintf(stderr,
1258                          "error code was %s (0x%x)\nerror messsage was: %s\n",
1259                          error->nt_string,
1260                          error->nt_status,
1261                          error->display_string);
1262         }
1263
1264         if (WBC_ERROR_IS_OK(wbc_status)) {
1265                 if (flags & WBFLAG_PAM_INFO3_TEXT) {
1266                         if (info && info->info && info->info->user_flags &
1267                             NETLOGON_CACHED_ACCOUNT) {
1268                                 d_printf("user_flgs: "
1269                                          "NETLOGON_CACHED_ACCOUNT\n");
1270                         }
1271                 }
1272
1273                 if (info) {
1274                         int i;
1275                         for (i=0; i < info->num_blobs; i++) {
1276                                 if (strequal(info->blobs[i].name,
1277                                              "krb5ccname")) {
1278                                         d_printf("credentials were put "
1279                                                  "in: %s\n",
1280                                                 (const char *)
1281                                                       info->blobs[i].blob.data);
1282                                         break;
1283                                 }
1284                         }
1285                 } else {
1286                         d_printf("no credentials cached\n");
1287                 }
1288         }
1289  done:
1290
1291         SAFE_FREE(s);
1292         SAFE_FREE(password);
1293         wbcFreeMemory(params.blobs);
1294
1295         return WBC_ERROR_IS_OK(wbc_status);
1296 }
1297
1298 /* Authenticate a user with a plaintext password */
1299
1300 static bool wbinfo_auth(char *username)
1301 {
1302         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1303         char *s = NULL;
1304         char *p = NULL;
1305         char *password = NULL;
1306         char *name = NULL;
1307
1308         if ((s = SMB_STRDUP(username)) == NULL) {
1309                 return false;
1310         }
1311
1312         if ((p = strchr(s, '%')) != NULL) {
1313                 *p = 0;
1314                 p++;
1315                 password = SMB_STRDUP(p);
1316         } else {
1317                 password = wbinfo_prompt_pass(NULL, username);
1318         }
1319
1320         name = s;
1321
1322         wbc_status = wbcAuthenticateUser(name, password);
1323
1324         d_printf("plaintext password authentication %s\n",
1325                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1326
1327 #if 0
1328         if (response.data.auth.nt_status)
1329                 d_fprintf(stderr,
1330                          "error code was %s (0x%x)\nerror messsage was: %s\n",
1331                          response.data.auth.nt_status_string,
1332                          response.data.auth.nt_status,
1333                          response.data.auth.error_string);
1334 #endif
1335
1336         SAFE_FREE(s);
1337         SAFE_FREE(password);
1338
1339         return WBC_ERROR_IS_OK(wbc_status);
1340 }
1341
1342 /* Authenticate a user with a challenge/response */
1343
1344 static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman)
1345 {
1346         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1347         struct wbcAuthUserParams params;
1348         struct wbcAuthUserInfo *info = NULL;
1349         struct wbcAuthErrorInfo *err = NULL;
1350         DATA_BLOB lm = data_blob_null;
1351         DATA_BLOB nt = data_blob_null;
1352         fstring name_user;
1353         fstring name_domain;
1354         char *pass;
1355         char *p;
1356
1357         p = strchr(username, '%');
1358
1359         if (p) {
1360                 *p = 0;
1361                 pass = SMB_STRDUP(p + 1);
1362         } else {
1363                 pass = wbinfo_prompt_pass(NULL, username);
1364         }
1365
1366         parse_wbinfo_domain_user(username, name_domain, name_user);
1367
1368         params.account_name     = name_user;
1369         params.domain_name      = name_domain;
1370         params.workstation_name = NULL;
1371
1372         params.flags            = 0;
1373         params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT |
1374                                   WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
1375
1376         params.level            = WBC_AUTH_USER_LEVEL_RESPONSE;
1377
1378         generate_random_buffer(params.password.response.challenge, 8);
1379
1380         if (use_ntlmv2) {
1381                 DATA_BLOB server_chal;
1382                 DATA_BLOB names_blob;
1383
1384                 server_chal = data_blob(params.password.response.challenge, 8);
1385
1386                 /* Pretend this is a login to 'us', for blob purposes */
1387                 names_blob = NTLMv2_generate_names_blob(NULL, global_myname(),
1388                                                         get_winbind_domain());
1389
1390                 if (!SMBNTLMv2encrypt(NULL, name_user, name_domain, pass,
1391                                       &server_chal,
1392                                       &names_blob,
1393                                       &lm, &nt, NULL, NULL)) {
1394                         data_blob_free(&names_blob);
1395                         data_blob_free(&server_chal);
1396                         SAFE_FREE(pass);
1397                         return false;
1398                 }
1399                 data_blob_free(&names_blob);
1400                 data_blob_free(&server_chal);
1401
1402         } else {
1403                 if (use_lanman) {
1404                         bool ok;
1405                         lm = data_blob(NULL, 24);
1406                         ok = SMBencrypt(pass,
1407                                         params.password.response.challenge,
1408                                         lm.data);
1409                         if (!ok) {
1410                                 data_blob_free(&lm);
1411                         }
1412                 }
1413                 nt = data_blob(NULL, 24);
1414                 SMBNTencrypt(pass, params.password.response.challenge,
1415                              nt.data);
1416         }
1417
1418         params.password.response.nt_length      = nt.length;
1419         params.password.response.nt_data        = nt.data;
1420         params.password.response.lm_length      = lm.length;
1421         params.password.response.lm_data        = lm.data;
1422
1423         wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
1424
1425         /* Display response */
1426
1427         d_printf("challenge/response password authentication %s\n",
1428                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1429
1430         if (wbc_status == WBC_ERR_AUTH_ERROR) {
1431                 d_fprintf(stderr,
1432                          "error code was %s (0x%x)\nerror messsage was: %s\n",
1433                          err->nt_string,
1434                          err->nt_status,
1435                          err->display_string);
1436                 wbcFreeMemory(err);
1437         } else if (WBC_ERROR_IS_OK(wbc_status)) {
1438                 wbcFreeMemory(info);
1439         }
1440
1441         data_blob_free(&nt);
1442         data_blob_free(&lm);
1443         SAFE_FREE(pass);
1444
1445         return WBC_ERROR_IS_OK(wbc_status);
1446 }
1447
1448 /* Authenticate a user with a plaintext password and set a token */
1449
1450 static bool wbinfo_klog(char *username)
1451 {
1452         struct winbindd_request request;
1453         struct winbindd_response response;
1454         NSS_STATUS result;
1455         char *p;
1456
1457         /* Send off request */
1458
1459         ZERO_STRUCT(request);
1460         ZERO_STRUCT(response);
1461
1462         p = strchr(username, '%');
1463
1464         if (p) {
1465                 *p = 0;
1466                 fstrcpy(request.data.auth.user, username);
1467                 fstrcpy(request.data.auth.pass, p + 1);
1468                 *p = '%';
1469         } else {
1470                 fstrcpy(request.data.auth.user, username);
1471                 fstrcpy(request.data.auth.pass, getpass("Password: "));
1472         }
1473
1474         request.flags |= WBFLAG_PAM_AFS_TOKEN;
1475
1476         result = winbindd_request_response(WINBINDD_PAM_AUTH, &request,
1477                                            &response);
1478
1479         /* Display response */
1480
1481         d_printf("plaintext password authentication %s\n",
1482                  (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
1483
1484         if (response.data.auth.nt_status)
1485                 d_fprintf(stderr,
1486                          "error code was %s (0x%x)\nerror messsage was: %s\n",
1487                          response.data.auth.nt_status_string,
1488                          response.data.auth.nt_status,
1489                          response.data.auth.error_string);
1490
1491         if (result != NSS_STATUS_SUCCESS)
1492                 return false;
1493
1494         if (response.extra_data.data == NULL) {
1495                 d_fprintf(stderr, "Did not get token data\n");
1496                 return false;
1497         }
1498
1499         if (!afs_settoken_str((char *)response.extra_data.data)) {
1500                 d_fprintf(stderr, "Could not set token\n");
1501                 return false;
1502         }
1503
1504         d_printf("Successfully created AFS token\n");
1505         return true;
1506 }
1507
1508 /* Print domain users */
1509
1510 static bool print_domain_users(const char *domain)
1511 {
1512         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1513         uint32_t i;
1514         uint32_t num_users = 0;
1515         const char **users = NULL;
1516
1517         /* Send request to winbind daemon */
1518
1519         /* '.' is the special sign for our own domain */
1520         if (domain && strcmp(domain, ".") == 0) {
1521                 domain = get_winbind_domain();
1522         }
1523
1524         wbc_status = wbcListUsers(domain, &num_users, &users);
1525         if (!WBC_ERROR_IS_OK(wbc_status)) {
1526                 return false;
1527         }
1528
1529         for (i=0; i < num_users; i++) {
1530                 d_printf("%s\n", users[i]);
1531         }
1532
1533         wbcFreeMemory(users);
1534
1535         return true;
1536 }
1537
1538 /* Print domain groups */
1539
1540 static bool print_domain_groups(const char *domain)
1541 {
1542         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
1543         uint32_t i;
1544         uint32_t num_groups = 0;
1545         const char **groups = NULL;
1546
1547         /* Send request to winbind daemon */
1548
1549         /* '.' is the special sign for our own domain */
1550         if (domain && strcmp(domain, ".") == 0) {
1551                 domain = get_winbind_domain();
1552         }
1553
1554         wbc_status = wbcListGroups(domain, &num_groups, &groups);
1555         if (!WBC_ERROR_IS_OK(wbc_status)) {
1556                 return false;
1557         }
1558
1559         for (i=0; i < num_groups; i++) {
1560                 d_printf("%s\n", groups[i]);
1561         }
1562
1563         wbcFreeMemory(groups);
1564
1565         return true;
1566 }
1567
1568 /* Set the authorised user for winbindd access in secrets.tdb */
1569
1570 static bool wbinfo_set_auth_user(char *username)
1571 {
1572         d_fprintf(stderr, "This functionality was moved to the 'net' utility.\n"
1573                           "See 'net help setauthuser' for details.\n");
1574         return false;
1575 }
1576
1577 static void wbinfo_get_auth_user(void)
1578 {
1579         d_fprintf(stderr, "This functionality was moved to the 'net' utility.\n"
1580                           "See 'net help getauthuser' for details.\n");
1581 }
1582
1583 static bool wbinfo_ping(void)
1584 {
1585         wbcErr wbc_status;
1586
1587         wbc_status = wbcPing();
1588
1589         /* Display response */
1590
1591         d_printf("Ping to winbindd %s\n",
1592                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1593
1594         return WBC_ERROR_IS_OK(wbc_status);
1595 }
1596
1597 static bool wbinfo_change_user_password(const char *username)
1598 {
1599         wbcErr wbc_status;
1600         char *old_password = NULL;
1601         char *new_password = NULL;
1602
1603         old_password = wbinfo_prompt_pass("old", username);
1604         new_password = wbinfo_prompt_pass("new", username);
1605
1606         wbc_status = wbcChangeUserPassword(username, old_password,new_password);
1607
1608         /* Display response */
1609
1610         d_printf("Password change for user %s %s\n", username,
1611                 WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1612
1613         SAFE_FREE(old_password);
1614         SAFE_FREE(new_password);
1615
1616         return WBC_ERROR_IS_OK(wbc_status);
1617 }
1618
1619 /* Main program */
1620
1621 enum {
1622         OPT_SET_AUTH_USER = 1000,
1623         OPT_GET_AUTH_USER,
1624         OPT_DOMAIN_NAME,
1625         OPT_SEQUENCE,
1626         OPT_GETDCNAME,
1627         OPT_DSGETDCNAME,
1628         OPT_USERDOMGROUPS,
1629         OPT_SIDALIASES,
1630         OPT_USERSIDS,
1631         OPT_ALLOCATE_UID,
1632         OPT_ALLOCATE_GID,
1633         OPT_SET_UID_MAPPING,
1634         OPT_SET_GID_MAPPING,
1635         OPT_REMOVE_UID_MAPPING,
1636         OPT_REMOVE_GID_MAPPING,
1637         OPT_SEPARATOR,
1638         OPT_LIST_ALL_DOMAINS,
1639         OPT_LIST_OWN_DOMAIN,
1640         OPT_UID_INFO,
1641         OPT_USER_SIDINFO,
1642         OPT_GROUP_INFO,
1643         OPT_GID_INFO,
1644         OPT_VERBOSE,
1645         OPT_ONLINESTATUS,
1646         OPT_CHANGE_USER_PASSWORD,
1647         OPT_SID_TO_FULLNAME,
1648         OPT_NTLMV2,
1649         OPT_LANMAN
1650 };
1651
1652 int main(int argc, char **argv, char **envp)
1653 {
1654         int opt;
1655         TALLOC_CTX *frame = talloc_stackframe();
1656         poptContext pc;
1657         static char *string_arg;
1658         char *string_subarg = NULL;
1659         static char *opt_domain_name;
1660         static int int_arg;
1661         int int_subarg = -1;
1662         int result = 1;
1663         bool verbose = false;
1664         bool use_ntlmv2 = false;
1665         bool use_lanman = false;
1666
1667         struct poptOption long_options[] = {
1668                 POPT_AUTOHELP
1669
1670                 /* longName, shortName, argInfo, argPtr, value, descrip,
1671                    argDesc */
1672
1673                 { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"},
1674                 { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups", "domain" },
1675                 { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP", "NETBIOS-NAME" },
1676                 { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" },
1677                 { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" },
1678                 { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" },
1679                 { "sid-to-fullname", 0, POPT_ARG_STRING, &string_arg,
1680                   OPT_SID_TO_FULLNAME, "Converts sid to fullname", "SID" },
1681                 { "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" },
1682                 { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" },
1683                 { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" },
1684                 { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
1685                 { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" },
1686                 { "allocate-uid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_UID,
1687                   "Get a new UID out of idmap" },
1688                 { "allocate-gid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_GID,
1689                   "Get a new GID out of idmap" },
1690                 { "set-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_UID_MAPPING, "Create or modify uid to sid mapping in idmap", "UID,SID" },
1691                 { "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" },
1692                 { "remove-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_UID_MAPPING, "Remove uid to sid mapping in idmap", "UID,SID" },
1693                 { "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" },
1694                 { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
1695                 { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
1696                 { "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" },
1697                 { "own-domain", 0, POPT_ARG_NONE, 0, OPT_LIST_OWN_DOMAIN, "List own domain" },
1698                 { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
1699                 { "online-status", 0, POPT_ARG_NONE, 0, OPT_ONLINESTATUS, "Show whether domains are marked as online or offline"},
1700                 { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" },
1701                 { "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" },
1702                 { "uid-info", 0, POPT_ARG_INT, &int_arg, OPT_UID_INFO, "Get user info from uid", "UID" },
1703                 { "group-info", 0, POPT_ARG_STRING, &string_arg, OPT_GROUP_INFO, "Get group info", "GROUP" },
1704                 { "user-sidinfo", 0, POPT_ARG_STRING, &string_arg, OPT_USER_SIDINFO, "Get user info from sid", "SID" },
1705                 { "gid-info", 0, POPT_ARG_INT, &int_arg, OPT_GID_INFO, "Get group info from gid", "GID" },
1706                 { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
1707                 { "user-domgroups", 0, POPT_ARG_STRING, &string_arg,
1708                   OPT_USERDOMGROUPS, "Get user domain groups", "SID" },
1709                 { "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" },
1710                 { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
1711                 { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
1712                 { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
1713                 { "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME,
1714                   "Get a DC name for a foreign domain", "domainname" },
1715                 { "dsgetdcname", 0, POPT_ARG_STRING, &string_arg, OPT_DSGETDCNAME, "Find a DC for a domain", "domainname" },
1716                 { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
1717                 { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
1718                 { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" },
1719 #ifdef WITH_FAKE_KASERVER
1720                 { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
1721 #endif
1722 #ifdef HAVE_KRB5
1723                 { "krb5auth", 'K', POPT_ARG_STRING, &string_arg, 'K', "authenticate user using Kerberos", "user%password" },
1724                         /* destroys wbinfo --help output */
1725                         /* "user%password,DOM\\user%password,user@EXAMPLE.COM,EXAMPLE.COM\\user%password" }, */
1726 #endif
1727                 { "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL },
1728                 { "verbose", 0, POPT_ARG_NONE, 0, OPT_VERBOSE, "Print additional information per command", NULL },
1729                 { "change-user-password", 0, POPT_ARG_STRING, &string_arg, OPT_CHANGE_USER_PASSWORD, "Change the password for a user", NULL },
1730                 { "ntlmv2", 0, POPT_ARG_NONE, 0, OPT_NTLMV2, "Use NTLMv2 cryptography for user authentication", NULL},
1731                 { "lanman", 0, POPT_ARG_NONE, 0, OPT_LANMAN, "Use lanman cryptography for user authentication", NULL},
1732                 POPT_COMMON_CONFIGFILE
1733                 POPT_COMMON_VERSION
1734                 POPT_TABLEEND
1735         };
1736
1737         /* Samba client initialisation */
1738         load_case_tables();
1739
1740
1741         /* Parse options */
1742
1743         pc = poptGetContext("wbinfo", argc, (const char **)argv,
1744                             long_options, 0);
1745
1746         /* Parse command line options */
1747
1748         if (argc == 1) {
1749                 poptPrintHelp(pc, stderr, 0);
1750                 return 1;
1751         }
1752
1753         while((opt = poptGetNextOpt(pc)) != -1) {
1754                 /* get the generic configuration parameters like --domain */
1755                 switch (opt) {
1756                 case OPT_VERBOSE:
1757                         verbose = True;
1758                         break;
1759                 case OPT_NTLMV2:
1760                         use_ntlmv2 = true;
1761                         break;
1762                 case OPT_LANMAN:
1763                         use_lanman = true;
1764                         break;
1765                 }
1766         }
1767
1768         poptFreeContext(pc);
1769
1770         if (!init_names())
1771                 return 1;
1772
1773         load_interfaces();
1774
1775         pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
1776                             POPT_CONTEXT_KEEP_FIRST);
1777
1778         while((opt = poptGetNextOpt(pc)) != -1) {
1779                 switch (opt) {
1780                 case 'u':
1781                         if (!print_domain_users(opt_domain_name)) {
1782                                 d_fprintf(stderr,
1783                                           "Error looking up domain users\n");
1784                                 goto done;
1785                         }
1786                         break;
1787                 case 'g':
1788                         if (!print_domain_groups(opt_domain_name)) {
1789                                 d_fprintf(stderr,
1790                                           "Error looking up domain groups\n");
1791                                 goto done;
1792                         }
1793                         break;
1794                 case 's':
1795                         if (!wbinfo_lookupsid(string_arg)) {
1796                                 d_fprintf(stderr,
1797                                           "Could not lookup sid %s\n",
1798                                           string_arg);
1799                                 goto done;
1800                         }
1801                         break;
1802                 case OPT_SID_TO_FULLNAME:
1803                         if (!wbinfo_lookupsid_fullname(string_arg)) {
1804                                 d_fprintf(stderr, "Could not lookup sid %s\n",
1805                                           string_arg);
1806                                 goto done;
1807                         }
1808                         break;
1809                 case 'R':
1810                         if (!wbinfo_lookuprids(opt_domain_name, string_arg)) {
1811                                 d_fprintf(stderr, "Could not lookup RIDs %s\n",
1812                                           string_arg);
1813                                 goto done;
1814                         }
1815                         break;
1816                 case 'n':
1817                         if (!wbinfo_lookupname(string_arg)) {
1818                                 d_fprintf(stderr, "Could not lookup name %s\n",
1819                                           string_arg);
1820                                 goto done;
1821                         }
1822                         break;
1823                 case 'N':
1824                         if (!wbinfo_wins_byname(string_arg)) {
1825                                 d_fprintf(stderr,
1826                                           "Could not lookup WINS by name %s\n",
1827                                           string_arg);
1828                                 goto done;
1829                         }
1830                         break;
1831                 case 'I':
1832                         if (!wbinfo_wins_byip(string_arg)) {
1833                                 d_fprintf(stderr,
1834                                           "Could not lookup WINS by IP %s\n",
1835                                           string_arg);
1836                                 goto done;
1837                         }
1838                         break;
1839                 case 'U':
1840                         if (!wbinfo_uid_to_sid(int_arg)) {
1841                                 d_fprintf(stderr,
1842                                           "Could not convert uid %d to sid\n",
1843                                           int_arg);
1844                                 goto done;
1845                         }
1846                         break;
1847                 case 'G':
1848                         if (!wbinfo_gid_to_sid(int_arg)) {
1849                                 d_fprintf(stderr,
1850                                           "Could not convert gid %d to sid\n",
1851                                           int_arg);
1852                                 goto done;
1853                         }
1854                         break;
1855                 case 'S':
1856                         if (!wbinfo_sid_to_uid(string_arg)) {
1857                                 d_fprintf(stderr,
1858                                           "Could not convert sid %s to uid\n",
1859                                           string_arg);
1860                                 goto done;
1861                         }
1862                         break;
1863                 case 'Y':
1864                         if (!wbinfo_sid_to_gid(string_arg)) {
1865                                 d_fprintf(stderr,
1866                                           "Could not convert sid %s to gid\n",
1867                                           string_arg);
1868                                 goto done;
1869                         }
1870                         break;
1871                 case OPT_ALLOCATE_UID:
1872                         if (!wbinfo_allocate_uid()) {
1873                                 d_fprintf(stderr, "Could not allocate a uid\n");
1874                                 goto done;
1875                         }
1876                         break;
1877                 case OPT_ALLOCATE_GID:
1878                         if (!wbinfo_allocate_gid()) {
1879                                 d_fprintf(stderr, "Could not allocate a gid\n");
1880                                 goto done;
1881                         }
1882                         break;
1883                 case OPT_SET_UID_MAPPING:
1884                         if (!parse_mapping_arg(string_arg, &int_subarg,
1885                                 &string_subarg) ||
1886                             !wbinfo_set_uid_mapping(int_subarg, string_subarg))
1887                         {
1888                                 d_fprintf(stderr, "Could not create or modify "
1889                                           "uid to sid mapping\n");
1890                                 goto done;
1891                         }
1892                         break;
1893                 case OPT_SET_GID_MAPPING:
1894                         if (!parse_mapping_arg(string_arg, &int_subarg,
1895                                 &string_subarg) ||
1896                             !wbinfo_set_gid_mapping(int_subarg, string_subarg))
1897                         {
1898                                 d_fprintf(stderr, "Could not create or modify "
1899                                           "gid to sid mapping\n");
1900                                 goto done;
1901                         }
1902                         break;
1903                 case OPT_REMOVE_UID_MAPPING:
1904                         if (!parse_mapping_arg(string_arg, &int_subarg,
1905                                 &string_subarg) ||
1906                             !wbinfo_remove_uid_mapping(int_subarg,
1907                                 string_subarg))
1908                         {
1909                                 d_fprintf(stderr, "Could not remove uid to sid "
1910                                     "mapping\n");
1911                                 goto done;
1912                         }
1913                         break;
1914                 case OPT_REMOVE_GID_MAPPING:
1915                         if (!parse_mapping_arg(string_arg, &int_subarg,
1916                                 &string_subarg) ||
1917                             !wbinfo_remove_gid_mapping(int_subarg,
1918                                 string_subarg))
1919                         {
1920                                 d_fprintf(stderr, "Could not remove gid to sid "
1921                                     "mapping\n");
1922                                 goto done;
1923                         }
1924                         break;
1925                 case 't':
1926                         if (!wbinfo_check_secret()) {
1927                                 d_fprintf(stderr, "Could not check secret\n");
1928                                 goto done;
1929                         }
1930                         break;
1931                 case 'm':
1932                         if (!wbinfo_list_domains(false, verbose)) {
1933                                 d_fprintf(stderr,
1934                                           "Could not list trusted domains\n");
1935                                 goto done;
1936                         }
1937                         break;
1938                 case OPT_SEQUENCE:
1939                         if (!wbinfo_show_sequence(opt_domain_name)) {
1940                                 d_fprintf(stderr,
1941                                           "Could not show sequence numbers\n");
1942                                 goto done;
1943                         }
1944                         break;
1945                 case OPT_ONLINESTATUS:
1946                         if (!wbinfo_show_onlinestatus(opt_domain_name)) {
1947                                 d_fprintf(stderr,
1948                                           "Could not show online-status\n");
1949                                 goto done;
1950                         }
1951                         break;
1952                 case 'D':
1953                         if (!wbinfo_domain_info(string_arg)) {
1954                                 d_fprintf(stderr,
1955                                           "Could not get domain info\n");
1956                                 goto done;
1957                         }
1958                         break;
1959                 case 'i':
1960                         if (!wbinfo_get_userinfo(string_arg)) {
1961                                 d_fprintf(stderr,
1962                                           "Could not get info for user %s\n",
1963                                           string_arg);
1964                                 goto done;
1965                         }
1966                         break;
1967                 case OPT_USER_SIDINFO:
1968                         if ( !wbinfo_get_user_sidinfo(string_arg)) {
1969                                 d_fprintf(stderr,
1970                                           "Could not get info for user "
1971                                           "sid %s\n", string_arg);
1972                                 goto done;
1973                         }
1974                         break;
1975                 case OPT_UID_INFO:
1976                         if ( !wbinfo_get_uidinfo(int_arg)) {
1977                                 d_fprintf(stderr, "Could not get info for uid "
1978                                                 "%d\n", int_arg);
1979                                 goto done;
1980                         }
1981                         break;
1982                 case OPT_GROUP_INFO:
1983                         if ( !wbinfo_get_groupinfo(string_arg)) {
1984                                 d_fprintf(stderr, "Could not get info for "
1985                                           "group %s\n", string_arg);
1986                                 goto done;
1987                         }
1988                         break;
1989                 case OPT_GID_INFO:
1990                         if ( !wbinfo_get_gidinfo(int_arg)) {
1991                                 d_fprintf(stderr, "Could not get info for gid "
1992                                                 "%d\n", int_arg);
1993                                 goto done;
1994                         }
1995                         break;
1996                 case 'r':
1997                         if (!wbinfo_get_usergroups(string_arg)) {
1998                                 d_fprintf(stderr,
1999                                           "Could not get groups for user %s\n",
2000                                           string_arg);
2001                                 goto done;
2002                         }
2003                         break;
2004                 case OPT_USERSIDS:
2005                         if (!wbinfo_get_usersids(string_arg)) {
2006                                 d_fprintf(stderr, "Could not get group SIDs "
2007                                           "for user SID %s\n",
2008                                           string_arg);
2009                                 goto done;
2010                         }
2011                         break;
2012                 case OPT_USERDOMGROUPS:
2013                         if (!wbinfo_get_userdomgroups(string_arg)) {
2014                                 d_fprintf(stderr, "Could not get user's domain "
2015                                          "groups for user SID %s\n",
2016                                          string_arg);
2017                                 goto done;
2018                         }
2019                         break;
2020                 case OPT_SIDALIASES:
2021                         if (!wbinfo_get_sidaliases(opt_domain_name,
2022                                                    string_arg)) {
2023                                 d_fprintf(stderr, "Could not get sid aliases "
2024                                          "for user SID %s\n", string_arg);
2025                                 goto done;
2026                         }
2027                         break;
2028                 case 'a': {
2029                                 bool got_error = false;
2030
2031                                 if (!wbinfo_auth(string_arg)) {
2032                                         d_fprintf(stderr,
2033                                                   "Could not authenticate user "
2034                                                   "%s with plaintext "
2035                                                   "password\n", string_arg);
2036                                         got_error = true;
2037                                 }
2038
2039                                 if (!wbinfo_auth_crap(string_arg, use_ntlmv2,
2040                                                       use_lanman)) {
2041                                         d_fprintf(stderr,
2042                                                 "Could not authenticate user "
2043                                                 "%s with challenge/response\n",
2044                                                 string_arg);
2045                                         got_error = true;
2046                                 }
2047
2048                                 if (got_error)
2049                                         goto done;
2050                                 break;
2051                         }
2052                 case 'K': {
2053                                 uint32 flags =  WBFLAG_PAM_KRB5 |
2054                                                 WBFLAG_PAM_CACHED_LOGIN |
2055                                                 WBFLAG_PAM_FALLBACK_AFTER_KRB5 |
2056                                                 WBFLAG_PAM_INFO3_TEXT |
2057                                                 WBFLAG_PAM_CONTACT_TRUSTDOM;
2058
2059                                 if (!wbinfo_auth_krb5(string_arg, "FILE",
2060                                                       flags)) {
2061                                         d_fprintf(stderr,
2062                                                 "Could not authenticate user "
2063                                                 "[%s] with Kerberos "
2064                                                 "(ccache: %s)\n", string_arg,
2065                                                 "FILE");
2066                                         goto done;
2067                                 }
2068                                 break;
2069                         }
2070                 case 'k':
2071                         if (!wbinfo_klog(string_arg)) {
2072                                 d_fprintf(stderr, "Could not klog user\n");
2073                                 goto done;
2074                         }
2075                         break;
2076                 case 'p':
2077                         if (!wbinfo_ping()) {
2078                                 d_fprintf(stderr, "could not ping winbindd!\n");
2079                                 goto done;
2080                         }
2081                         break;
2082                 case OPT_SET_AUTH_USER:
2083                         if (!wbinfo_set_auth_user(string_arg)) {
2084                                 goto done;
2085                         }
2086                         break;
2087                 case OPT_GET_AUTH_USER:
2088                         wbinfo_get_auth_user();
2089                         goto done;
2090                         break;
2091                 case OPT_GETDCNAME:
2092                         if (!wbinfo_getdcname(string_arg)) {
2093                                 goto done;
2094                         }
2095                         break;
2096                 case OPT_DSGETDCNAME:
2097                         if (!wbinfo_dsgetdcname(string_arg, 0)) {
2098                                 goto done;
2099                         }
2100                         break;
2101                 case OPT_SEPARATOR: {
2102                         const char sep = winbind_separator();
2103                         if ( !sep ) {
2104                                 goto done;
2105                         }
2106                         d_printf("%c\n", sep);
2107                         break;
2108                 }
2109                 case OPT_LIST_ALL_DOMAINS:
2110                         if (!wbinfo_list_domains(true, verbose)) {
2111                                 goto done;
2112                         }
2113                         break;
2114                 case OPT_LIST_OWN_DOMAIN:
2115                         if (!wbinfo_list_own_domain()) {
2116                                 goto done;
2117                         }
2118                         break;
2119                 case OPT_CHANGE_USER_PASSWORD:
2120                         if (!wbinfo_change_user_password(string_arg)) {
2121                                 d_fprintf(stderr,
2122                                         "Could not change user password "
2123                                          "for user %s\n", string_arg);
2124                                 goto done;
2125                         }
2126                         break;
2127
2128                 /* generic configuration options */
2129                 case OPT_DOMAIN_NAME:
2130                         break;
2131                 case OPT_VERBOSE:
2132                         break;
2133                 case OPT_NTLMV2:
2134                         break;
2135                 case OPT_LANMAN:
2136                         break;
2137                 default:
2138                         d_fprintf(stderr, "Invalid option\n");
2139                         poptPrintHelp(pc, stderr, 0);
2140                         goto done;
2141                 }
2142         }
2143
2144         result = 0;
2145
2146         /* Exit code */
2147
2148  done:
2149         talloc_destroy(frame);
2150
2151         poptFreeContext(pc);
2152         return result;
2153 }