s3 wbinfo: Get rid of lp_ functions
[samba.git] / nsswitch / wbinfo.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind status program.
5
6    Copyright (C) Tim Potter      2000-2003
7    Copyright (C) Andrew Bartlett 2002
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "winbind_client.h"
25 #include "libwbclient/wbclient.h"
26 #include "../libcli/auth/libcli_auth.h"
27
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_WINBIND
30
31 static struct wbcInterfaceDetails *init_interface_details(void)
32 {
33         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
34         static struct wbcInterfaceDetails *details;
35
36         if (details) {
37                 return details;
38         }
39
40         wbc_status = wbcInterfaceDetails(&details);
41         if (!WBC_ERROR_IS_OK(wbc_status)) {
42                 d_fprintf(stderr, "could not obtain winbind interface "
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         const char *password;
1573         char *p;
1574         fstring user, domain;
1575
1576         /* Separate into user and password */
1577
1578         parse_wbinfo_domain_user(username, domain, user);
1579
1580         p = strchr(user, '%');
1581
1582         if (p != NULL) {
1583                 *p = 0;
1584                 password = p+1;
1585         } else {
1586                 char *thepass = getpass("Password: ");
1587                 if (thepass) {
1588                         password = thepass;
1589                 } else
1590                         password = "";
1591         }
1592
1593         /* Store or remove DOMAIN\username%password in secrets.tdb */
1594
1595         secrets_init();
1596
1597         if (user[0]) {
1598
1599                 if (!secrets_store(SECRETS_AUTH_USER, user,
1600                                    strlen(user) + 1)) {
1601                         d_fprintf(stderr, "error storing username\n");
1602                         return false;
1603                 }
1604
1605                 /* We always have a domain name added by the
1606                    parse_wbinfo_domain_user() function. */
1607
1608                 if (!secrets_store(SECRETS_AUTH_DOMAIN, domain,
1609                                    strlen(domain) + 1)) {
1610                         d_fprintf(stderr, "error storing domain name\n");
1611                         return false;
1612                 }
1613
1614         } else {
1615                 secrets_delete(SECRETS_AUTH_USER);
1616                 secrets_delete(SECRETS_AUTH_DOMAIN);
1617         }
1618
1619         if (password[0]) {
1620
1621                 if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
1622                                    strlen(password) + 1)) {
1623                         d_fprintf(stderr, "error storing password\n");
1624                         return false;
1625                 }
1626
1627         } else
1628                 secrets_delete(SECRETS_AUTH_PASSWORD);
1629
1630         return true;
1631 }
1632
1633 static void wbinfo_get_auth_user(void)
1634 {
1635         char *user, *domain, *password;
1636         char separator[] = {'\0', '\0'};
1637
1638         /* Lift data from secrets file */
1639
1640         secrets_fetch_ipc_userpass(&user, &domain, &password);
1641
1642         if ((!user || !*user) && (!domain || !*domain ) &&
1643             (!password || !*password)){
1644
1645                 SAFE_FREE(user);
1646                 SAFE_FREE(domain);
1647                 SAFE_FREE(password);
1648                 d_printf("No authorised user configured\n");
1649                 return;
1650         }
1651
1652         /* Pretty print authorised user info */
1653
1654         if (domain) {
1655                 separator[0] = winbind_separator();
1656         }
1657
1658         d_printf("%s%s%s%s%s\n", domain ? domain : "",
1659                  separator, user,
1660                  password ? "%" : "", password ? password : "");
1661
1662         SAFE_FREE(user);
1663         SAFE_FREE(domain);
1664         SAFE_FREE(password);
1665 }
1666
1667 static bool wbinfo_ping(void)
1668 {
1669         wbcErr wbc_status;
1670
1671         wbc_status = wbcPing();
1672
1673         /* Display response */
1674
1675         d_printf("Ping to winbindd %s\n",
1676                  WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1677
1678         return WBC_ERROR_IS_OK(wbc_status);
1679 }
1680
1681 static bool wbinfo_change_user_password(const char *username)
1682 {
1683         wbcErr wbc_status;
1684         char *old_password = NULL;
1685         char *new_password = NULL;
1686
1687         old_password = wbinfo_prompt_pass("old", username);
1688         new_password = wbinfo_prompt_pass("new", username);
1689
1690         wbc_status = wbcChangeUserPassword(username, old_password,new_password);
1691
1692         /* Display response */
1693
1694         d_printf("Password change for user %s %s\n", username,
1695                 WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
1696
1697         SAFE_FREE(old_password);
1698         SAFE_FREE(new_password);
1699
1700         return WBC_ERROR_IS_OK(wbc_status);
1701 }
1702
1703 /* Main program */
1704
1705 enum {
1706         OPT_SET_AUTH_USER = 1000,
1707         OPT_GET_AUTH_USER,
1708         OPT_DOMAIN_NAME,
1709         OPT_SEQUENCE,
1710         OPT_GETDCNAME,
1711         OPT_DSGETDCNAME,
1712         OPT_USERDOMGROUPS,
1713         OPT_SIDALIASES,
1714         OPT_USERSIDS,
1715         OPT_ALLOCATE_UID,
1716         OPT_ALLOCATE_GID,
1717         OPT_SET_UID_MAPPING,
1718         OPT_SET_GID_MAPPING,
1719         OPT_REMOVE_UID_MAPPING,
1720         OPT_REMOVE_GID_MAPPING,
1721         OPT_SEPARATOR,
1722         OPT_LIST_ALL_DOMAINS,
1723         OPT_LIST_OWN_DOMAIN,
1724         OPT_UID_INFO,
1725         OPT_USER_SIDINFO,
1726         OPT_GROUP_INFO,
1727         OPT_GID_INFO,
1728         OPT_VERBOSE,
1729         OPT_ONLINESTATUS,
1730         OPT_CHANGE_USER_PASSWORD,
1731         OPT_SID_TO_FULLNAME,
1732         OPT_NTLMV2,
1733         OPT_LANMAN
1734 };
1735
1736 int main(int argc, char **argv, char **envp)
1737 {
1738         int opt;
1739         TALLOC_CTX *frame = talloc_stackframe();
1740         poptContext pc;
1741         static char *string_arg;
1742         char *string_subarg = NULL;
1743         static char *opt_domain_name;
1744         static int int_arg;
1745         int int_subarg = -1;
1746         int result = 1;
1747         bool verbose = false;
1748         bool use_ntlmv2 = false;
1749         bool use_lanman = false;
1750
1751         struct poptOption long_options[] = {
1752                 POPT_AUTOHELP
1753
1754                 /* longName, shortName, argInfo, argPtr, value, descrip,
1755                    argDesc */
1756
1757                 { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"},
1758                 { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups", "domain" },
1759                 { "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP", "NETBIOS-NAME" },
1760                 { "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" },
1761                 { "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" },
1762                 { "sid-to-name", 's', POPT_ARG_STRING, &string_arg, 's', "Converts sid to name", "SID" },
1763                 { "sid-to-fullname", 0, POPT_ARG_STRING, &string_arg,
1764                   OPT_SID_TO_FULLNAME, "Converts sid to fullname", "SID" },
1765                 { "lookup-rids", 'R', POPT_ARG_STRING, &string_arg, 'R', "Converts RIDs to names", "RIDs" },
1766                 { "uid-to-sid", 'U', POPT_ARG_INT, &int_arg, 'U', "Converts uid to sid" , "UID" },
1767                 { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" },
1768                 { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" },
1769                 { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" },
1770                 { "allocate-uid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_UID,
1771                   "Get a new UID out of idmap" },
1772                 { "allocate-gid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_GID,
1773                   "Get a new GID out of idmap" },
1774                 { "set-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_UID_MAPPING, "Create or modify uid to sid mapping in idmap", "UID,SID" },
1775                 { "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" },
1776                 { "remove-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_UID_MAPPING, "Remove uid to sid mapping in idmap", "UID,SID" },
1777                 { "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" },
1778                 { "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
1779                 { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
1780                 { "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" },
1781                 { "own-domain", 0, POPT_ARG_NONE, 0, OPT_LIST_OWN_DOMAIN, "List own domain" },
1782                 { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
1783                 { "online-status", 0, POPT_ARG_NONE, 0, OPT_ONLINESTATUS, "Show whether domains are marked as online or offline"},
1784                 { "domain-info", 'D', POPT_ARG_STRING, &string_arg, 'D', "Show most of the info we have about the domain" },
1785                 { "user-info", 'i', POPT_ARG_STRING, &string_arg, 'i', "Get user info", "USER" },
1786                 { "uid-info", 0, POPT_ARG_INT, &int_arg, OPT_UID_INFO, "Get user info from uid", "UID" },
1787                 { "group-info", 0, POPT_ARG_STRING, &string_arg, OPT_GROUP_INFO, "Get group info", "GROUP" },
1788                 { "user-sidinfo", 0, POPT_ARG_STRING, &string_arg, OPT_USER_SIDINFO, "Get user info from sid", "SID" },
1789                 { "gid-info", 0, POPT_ARG_INT, &int_arg, OPT_GID_INFO, "Get group info from gid", "GID" },
1790                 { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
1791                 { "user-domgroups", 0, POPT_ARG_STRING, &string_arg,
1792                   OPT_USERDOMGROUPS, "Get user domain groups", "SID" },
1793                 { "sid-aliases", 0, POPT_ARG_STRING, &string_arg, OPT_SIDALIASES, "Get sid aliases", "SID" },
1794                 { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
1795                 { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
1796                 { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
1797                 { "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME,
1798                   "Get a DC name for a foreign domain", "domainname" },
1799                 { "dsgetdcname", 0, POPT_ARG_STRING, &string_arg, OPT_DSGETDCNAME, "Find a DC for a domain", "domainname" },
1800                 { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
1801                 { "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
1802                 { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" },
1803 #ifdef WITH_FAKE_KASERVER
1804                 { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
1805 #endif
1806 #ifdef HAVE_KRB5
1807                 { "krb5auth", 'K', POPT_ARG_STRING, &string_arg, 'K', "authenticate user using Kerberos", "user%password" },
1808                         /* destroys wbinfo --help output */
1809                         /* "user%password,DOM\\user%password,user@EXAMPLE.COM,EXAMPLE.COM\\user%password" }, */
1810 #endif
1811                 { "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL },
1812                 { "verbose", 0, POPT_ARG_NONE, 0, OPT_VERBOSE, "Print additional information per command", NULL },
1813                 { "change-user-password", 0, POPT_ARG_STRING, &string_arg, OPT_CHANGE_USER_PASSWORD, "Change the password for a user", NULL },
1814                 { "ntlmv2", 0, POPT_ARG_NONE, 0, OPT_NTLMV2, "Use NTLMv2 cryptography for user authentication", NULL},
1815                 { "lanman", 0, POPT_ARG_NONE, 0, OPT_LANMAN, "Use lanman cryptography for user authentication", NULL},
1816                 POPT_COMMON_CONFIGFILE
1817                 POPT_COMMON_VERSION
1818                 POPT_TABLEEND
1819         };
1820
1821         /* Samba client initialisation */
1822         load_case_tables();
1823
1824
1825         /* Parse options */
1826
1827         pc = poptGetContext("wbinfo", argc, (const char **)argv,
1828                             long_options, 0);
1829
1830         /* Parse command line options */
1831
1832         if (argc == 1) {
1833                 poptPrintHelp(pc, stderr, 0);
1834                 return 1;
1835         }
1836
1837         while((opt = poptGetNextOpt(pc)) != -1) {
1838                 /* get the generic configuration parameters like --domain */
1839                 switch (opt) {
1840                 case OPT_VERBOSE:
1841                         verbose = True;
1842                         break;
1843                 case OPT_NTLMV2:
1844                         use_ntlmv2 = true;
1845                         break;
1846                 case OPT_LANMAN:
1847                         use_lanman = true;
1848                         break;
1849                 }
1850         }
1851
1852         poptFreeContext(pc);
1853
1854         if (!init_names())
1855                 return 1;
1856
1857         load_interfaces();
1858
1859         pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
1860                             POPT_CONTEXT_KEEP_FIRST);
1861
1862         while((opt = poptGetNextOpt(pc)) != -1) {
1863                 switch (opt) {
1864                 case 'u':
1865                         if (!print_domain_users(opt_domain_name)) {
1866                                 d_fprintf(stderr,
1867                                           "Error looking up domain users\n");
1868                                 goto done;
1869                         }
1870                         break;
1871                 case 'g':
1872                         if (!print_domain_groups(opt_domain_name)) {
1873                                 d_fprintf(stderr,
1874                                           "Error looking up domain groups\n");
1875                                 goto done;
1876                         }
1877                         break;
1878                 case 's':
1879                         if (!wbinfo_lookupsid(string_arg)) {
1880                                 d_fprintf(stderr,
1881                                           "Could not lookup sid %s\n",
1882                                           string_arg);
1883                                 goto done;
1884                         }
1885                         break;
1886                 case OPT_SID_TO_FULLNAME:
1887                         if (!wbinfo_lookupsid_fullname(string_arg)) {
1888                                 d_fprintf(stderr, "Could not lookup sid %s\n",
1889                                           string_arg);
1890                                 goto done;
1891                         }
1892                         break;
1893                 case 'R':
1894                         if (!wbinfo_lookuprids(opt_domain_name, string_arg)) {
1895                                 d_fprintf(stderr, "Could not lookup RIDs %s\n",
1896                                           string_arg);
1897                                 goto done;
1898                         }
1899                         break;
1900                 case 'n':
1901                         if (!wbinfo_lookupname(string_arg)) {
1902                                 d_fprintf(stderr, "Could not lookup name %s\n",
1903                                           string_arg);
1904                                 goto done;
1905                         }
1906                         break;
1907                 case 'N':
1908                         if (!wbinfo_wins_byname(string_arg)) {
1909                                 d_fprintf(stderr,
1910                                           "Could not lookup WINS by name %s\n",
1911                                           string_arg);
1912                                 goto done;
1913                         }
1914                         break;
1915                 case 'I':
1916                         if (!wbinfo_wins_byip(string_arg)) {
1917                                 d_fprintf(stderr,
1918                                           "Could not lookup WINS by IP %s\n",
1919                                           string_arg);
1920                                 goto done;
1921                         }
1922                         break;
1923                 case 'U':
1924                         if (!wbinfo_uid_to_sid(int_arg)) {
1925                                 d_fprintf(stderr,
1926                                           "Could not convert uid %d to sid\n",
1927                                           int_arg);
1928                                 goto done;
1929                         }
1930                         break;
1931                 case 'G':
1932                         if (!wbinfo_gid_to_sid(int_arg)) {
1933                                 d_fprintf(stderr,
1934                                           "Could not convert gid %d to sid\n",
1935                                           int_arg);
1936                                 goto done;
1937                         }
1938                         break;
1939                 case 'S':
1940                         if (!wbinfo_sid_to_uid(string_arg)) {
1941                                 d_fprintf(stderr,
1942                                           "Could not convert sid %s to uid\n",
1943                                           string_arg);
1944                                 goto done;
1945                         }
1946                         break;
1947                 case 'Y':
1948                         if (!wbinfo_sid_to_gid(string_arg)) {
1949                                 d_fprintf(stderr,
1950                                           "Could not convert sid %s to gid\n",
1951                                           string_arg);
1952                                 goto done;
1953                         }
1954                         break;
1955                 case OPT_ALLOCATE_UID:
1956                         if (!wbinfo_allocate_uid()) {
1957                                 d_fprintf(stderr, "Could not allocate a uid\n");
1958                                 goto done;
1959                         }
1960                         break;
1961                 case OPT_ALLOCATE_GID:
1962                         if (!wbinfo_allocate_gid()) {
1963                                 d_fprintf(stderr, "Could not allocate a gid\n");
1964                                 goto done;
1965                         }
1966                         break;
1967                 case OPT_SET_UID_MAPPING:
1968                         if (!parse_mapping_arg(string_arg, &int_subarg,
1969                                 &string_subarg) ||
1970                             !wbinfo_set_uid_mapping(int_subarg, string_subarg))
1971                         {
1972                                 d_fprintf(stderr, "Could not create or modify "
1973                                           "uid to sid mapping\n");
1974                                 goto done;
1975                         }
1976                         break;
1977                 case OPT_SET_GID_MAPPING:
1978                         if (!parse_mapping_arg(string_arg, &int_subarg,
1979                                 &string_subarg) ||
1980                             !wbinfo_set_gid_mapping(int_subarg, string_subarg))
1981                         {
1982                                 d_fprintf(stderr, "Could not create or modify "
1983                                           "gid to sid mapping\n");
1984                                 goto done;
1985                         }
1986                         break;
1987                 case OPT_REMOVE_UID_MAPPING:
1988                         if (!parse_mapping_arg(string_arg, &int_subarg,
1989                                 &string_subarg) ||
1990                             !wbinfo_remove_uid_mapping(int_subarg,
1991                                 string_subarg))
1992                         {
1993                                 d_fprintf(stderr, "Could not remove uid to sid "
1994                                     "mapping\n");
1995                                 goto done;
1996                         }
1997                         break;
1998                 case OPT_REMOVE_GID_MAPPING:
1999                         if (!parse_mapping_arg(string_arg, &int_subarg,
2000                                 &string_subarg) ||
2001                             !wbinfo_remove_gid_mapping(int_subarg,
2002                                 string_subarg))
2003                         {
2004                                 d_fprintf(stderr, "Could not remove gid to sid "
2005                                     "mapping\n");
2006                                 goto done;
2007                         }
2008                         break;
2009                 case 't':
2010                         if (!wbinfo_check_secret()) {
2011                                 d_fprintf(stderr, "Could not check secret\n");
2012                                 goto done;
2013                         }
2014                         break;
2015                 case 'm':
2016                         if (!wbinfo_list_domains(false, verbose)) {
2017                                 d_fprintf(stderr,
2018                                           "Could not list trusted domains\n");
2019                                 goto done;
2020                         }
2021                         break;
2022                 case OPT_SEQUENCE:
2023                         if (!wbinfo_show_sequence(opt_domain_name)) {
2024                                 d_fprintf(stderr,
2025                                           "Could not show sequence numbers\n");
2026                                 goto done;
2027                         }
2028                         break;
2029                 case OPT_ONLINESTATUS:
2030                         if (!wbinfo_show_onlinestatus(opt_domain_name)) {
2031                                 d_fprintf(stderr,
2032                                           "Could not show online-status\n");
2033                                 goto done;
2034                         }
2035                         break;
2036                 case 'D':
2037                         if (!wbinfo_domain_info(string_arg)) {
2038                                 d_fprintf(stderr,
2039                                           "Could not get domain info\n");
2040                                 goto done;
2041                         }
2042                         break;
2043                 case 'i':
2044                         if (!wbinfo_get_userinfo(string_arg)) {
2045                                 d_fprintf(stderr,
2046                                           "Could not get info for user %s\n",
2047                                           string_arg);
2048                                 goto done;
2049                         }
2050                         break;
2051                 case OPT_USER_SIDINFO:
2052                         if ( !wbinfo_get_user_sidinfo(string_arg)) {
2053                                 d_fprintf(stderr,
2054                                           "Could not get info for user "
2055                                           "sid %s\n", string_arg);
2056                                 goto done;
2057                         }
2058                         break;
2059                 case OPT_UID_INFO:
2060                         if ( !wbinfo_get_uidinfo(int_arg)) {
2061                                 d_fprintf(stderr, "Could not get info for uid "
2062                                                 "%d\n", int_arg);
2063                                 goto done;
2064                         }
2065                         break;
2066                 case OPT_GROUP_INFO:
2067                         if ( !wbinfo_get_groupinfo(string_arg)) {
2068                                 d_fprintf(stderr, "Could not get info for "
2069                                           "group %s\n", string_arg);
2070                                 goto done;
2071                         }
2072                         break;
2073                 case OPT_GID_INFO:
2074                         if ( !wbinfo_get_gidinfo(int_arg)) {
2075                                 d_fprintf(stderr, "Could not get info for gid "
2076                                                 "%d\n", int_arg);
2077                                 goto done;
2078                         }
2079                         break;
2080                 case 'r':
2081                         if (!wbinfo_get_usergroups(string_arg)) {
2082                                 d_fprintf(stderr,
2083                                           "Could not get groups for user %s\n",
2084                                           string_arg);
2085                                 goto done;
2086                         }
2087                         break;
2088                 case OPT_USERSIDS:
2089                         if (!wbinfo_get_usersids(string_arg)) {
2090                                 d_fprintf(stderr, "Could not get group SIDs "
2091                                           "for user SID %s\n",
2092                                           string_arg);
2093                                 goto done;
2094                         }
2095                         break;
2096                 case OPT_USERDOMGROUPS:
2097                         if (!wbinfo_get_userdomgroups(string_arg)) {
2098                                 d_fprintf(stderr, "Could not get user's domain "
2099                                          "groups for user SID %s\n",
2100                                          string_arg);
2101                                 goto done;
2102                         }
2103                         break;
2104                 case OPT_SIDALIASES:
2105                         if (!wbinfo_get_sidaliases(opt_domain_name,
2106                                                    string_arg)) {
2107                                 d_fprintf(stderr, "Could not get sid aliases "
2108                                          "for user SID %s\n", string_arg);
2109                                 goto done;
2110                         }
2111                         break;
2112                 case 'a': {
2113                                 bool got_error = false;
2114
2115                                 if (!wbinfo_auth(string_arg)) {
2116                                         d_fprintf(stderr,
2117                                                   "Could not authenticate user "
2118                                                   "%s with plaintext "
2119                                                   "password\n", string_arg);
2120                                         got_error = true;
2121                                 }
2122
2123                                 if (!wbinfo_auth_crap(string_arg, use_ntlmv2,
2124                                                       use_lanman)) {
2125                                         d_fprintf(stderr,
2126                                                 "Could not authenticate user "
2127                                                 "%s with challenge/response\n",
2128                                                 string_arg);
2129                                         got_error = true;
2130                                 }
2131
2132                                 if (got_error)
2133                                         goto done;
2134                                 break;
2135                         }
2136                 case 'K': {
2137                                 uint32 flags =  WBFLAG_PAM_KRB5 |
2138                                                 WBFLAG_PAM_CACHED_LOGIN |
2139                                                 WBFLAG_PAM_FALLBACK_AFTER_KRB5 |
2140                                                 WBFLAG_PAM_INFO3_TEXT |
2141                                                 WBFLAG_PAM_CONTACT_TRUSTDOM;
2142
2143                                 if (!wbinfo_auth_krb5(string_arg, "FILE",
2144                                                       flags)) {
2145                                         d_fprintf(stderr,
2146                                                 "Could not authenticate user "
2147                                                 "[%s] with Kerberos "
2148                                                 "(ccache: %s)\n", string_arg,
2149                                                 "FILE");
2150                                         goto done;
2151                                 }
2152                                 break;
2153                         }
2154                 case 'k':
2155                         if (!wbinfo_klog(string_arg)) {
2156                                 d_fprintf(stderr, "Could not klog user\n");
2157                                 goto done;
2158                         }
2159                         break;
2160                 case 'p':
2161                         if (!wbinfo_ping()) {
2162                                 d_fprintf(stderr, "could not ping winbindd!\n");
2163                                 goto done;
2164                         }
2165                         break;
2166                 case OPT_SET_AUTH_USER:
2167                         if (!wbinfo_set_auth_user(string_arg)) {
2168                                 goto done;
2169                         }
2170                         break;
2171                 case OPT_GET_AUTH_USER:
2172                         wbinfo_get_auth_user();
2173                         break;
2174                 case OPT_GETDCNAME:
2175                         if (!wbinfo_getdcname(string_arg)) {
2176                                 goto done;
2177                         }
2178                         break;
2179                 case OPT_DSGETDCNAME:
2180                         if (!wbinfo_dsgetdcname(string_arg, 0)) {
2181                                 goto done;
2182                         }
2183                         break;
2184                 case OPT_SEPARATOR: {
2185                         const char sep = winbind_separator();
2186                         if ( !sep ) {
2187                                 goto done;
2188                         }
2189                         d_printf("%c\n", sep);
2190                         break;
2191                 }
2192                 case OPT_LIST_ALL_DOMAINS:
2193                         if (!wbinfo_list_domains(true, verbose)) {
2194                                 goto done;
2195                         }
2196                         break;
2197                 case OPT_LIST_OWN_DOMAIN:
2198                         if (!wbinfo_list_own_domain()) {
2199                                 goto done;
2200                         }
2201                         break;
2202                 case OPT_CHANGE_USER_PASSWORD:
2203                         if (!wbinfo_change_user_password(string_arg)) {
2204                                 d_fprintf(stderr,
2205                                         "Could not change user password "
2206                                          "for user %s\n", string_arg);
2207                                 goto done;
2208                         }
2209                         break;
2210
2211                 /* generic configuration options */
2212                 case OPT_DOMAIN_NAME:
2213                         break;
2214                 case OPT_VERBOSE:
2215                         break;
2216                 case OPT_NTLMV2:
2217                         break;
2218                 case OPT_LANMAN:
2219                         break;
2220                 default:
2221                         d_fprintf(stderr, "Invalid option\n");
2222                         poptPrintHelp(pc, stderr, 0);
2223                         goto done;
2224                 }
2225         }
2226
2227         result = 0;
2228
2229         /* Exit code */
2230
2231  done:
2232         talloc_destroy(frame);
2233
2234         poptFreeContext(pc);
2235         return result;
2236 }