2 Unix SMB/CIFS implementation.
4 Winbind status program.
6 Copyright (C) Tim Potter 2000-2002
7 Copyright (C) Andrew Bartlett 2002
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 2 of the License, or
12 (at your option) any later version.
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.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 /* Prototypes from common.h */
30 NSS_STATUS
winbindd_request(int req_type
,
31 struct winbindd_request
*request
,
32 struct winbindd_response
*response
);
34 static char winbind_separator(void)
36 struct winbindd_response response
;
43 ZERO_STRUCT(response
);
45 /* Send off request */
47 if (winbindd_request(WINBINDD_INFO
, NULL
, &response
) !=
49 printf("could not obtain winbind separator!\n");
50 /* HACK: (this module should not call lp_ funtions) */
51 return *lp_winbind_separator();
54 sep
= response
.data
.info
.winbind_separator
;
58 printf("winbind separator was NULL!\n");
59 /* HACK: (this module should not call lp_ funtions) */
60 sep
= *lp_winbind_separator();
66 static char *get_winbind_domain(void)
68 struct winbindd_response response
;
69 static fstring winbind_domain
;
71 ZERO_STRUCT(response
);
73 /* Send off request */
75 if (winbindd_request(WINBINDD_DOMAIN_NAME
, NULL
, &response
) !=
77 printf("could not obtain winbind domain name!\n");
79 /* HACK: (this module should not call lp_ funtions) */
80 return lp_workgroup();
83 fstrcpy(winbind_domain
, response
.data
.domain_name
);
85 return winbind_domain
;
89 /* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
90 form DOMAIN/user into a domain and a user */
92 static BOOL
parse_wbinfo_domain_user(const char *domuser
, fstring domain
,
96 char *p
= strchr(domuser
,winbind_separator());
99 fstrcpy(user
, domuser
);
100 fstrcpy(domain
, get_winbind_domain());
105 fstrcpy(domain
, domuser
);
106 domain
[PTR_DIFF(p
, domuser
)] = 0;
112 /* List groups a user is a member of */
114 static BOOL
wbinfo_get_usergroups(char *user
)
116 struct winbindd_request request
;
117 struct winbindd_response response
;
121 ZERO_STRUCT(response
);
125 fstrcpy(request
.data
.username
, user
);
127 result
= winbindd_request(WINBINDD_GETGROUPS
, &request
, &response
);
129 if (result
!= NSS_STATUS_SUCCESS
)
132 for (i
= 0; i
< response
.data
.num_entries
; i
++)
133 printf("%d\n", (int)((gid_t
*)response
.extra_data
)[i
]);
135 SAFE_FREE(response
.extra_data
);
140 /* Convert NetBIOS name to IP */
142 static BOOL
wbinfo_wins_byname(char *name
)
144 struct winbindd_request request
;
145 struct winbindd_response response
;
147 ZERO_STRUCT(request
);
148 ZERO_STRUCT(response
);
152 fstrcpy(request
.data
.winsreq
, name
);
154 if (winbindd_request(WINBINDD_WINS_BYNAME
, &request
, &response
) !=
155 NSS_STATUS_SUCCESS
) {
159 /* Display response */
161 printf("%s\n", response
.data
.winsresp
);
166 /* Convert IP to NetBIOS name */
168 static BOOL
wbinfo_wins_byip(char *ip
)
170 struct winbindd_request request
;
171 struct winbindd_response response
;
173 ZERO_STRUCT(request
);
174 ZERO_STRUCT(response
);
178 fstrcpy(request
.data
.winsreq
, ip
);
180 if (winbindd_request(WINBINDD_WINS_BYIP
, &request
, &response
) !=
181 NSS_STATUS_SUCCESS
) {
185 /* Display response */
187 printf("%s\n", response
.data
.winsresp
);
192 /* List trusted domains */
194 static BOOL
wbinfo_list_domains(void)
196 struct winbindd_response response
;
199 ZERO_STRUCT(response
);
203 if (winbindd_request(WINBINDD_LIST_TRUSTDOM
, NULL
, &response
) !=
207 /* Display response */
209 if (response
.extra_data
) {
210 char *extra_data
= (char *)response
.extra_data
;
212 while(next_token(&extra_data
, name
, ",", sizeof(fstring
)))
213 printf("%s\n", name
);
215 SAFE_FREE(response
.extra_data
);
222 /* show sequence numbers */
223 static BOOL
wbinfo_show_sequence(void)
225 struct winbindd_response response
;
227 ZERO_STRUCT(response
);
231 if (winbindd_request(WINBINDD_SHOW_SEQUENCE
, NULL
, &response
) !=
235 /* Display response */
237 if (response
.extra_data
) {
238 char *extra_data
= (char *)response
.extra_data
;
239 printf("%s", extra_data
);
240 SAFE_FREE(response
.extra_data
);
246 /* Check trust account password */
248 static BOOL
wbinfo_check_secret(void)
250 struct winbindd_response response
;
253 ZERO_STRUCT(response
);
255 result
= winbindd_request(WINBINDD_CHECK_MACHACC
, NULL
, &response
) ==
260 if (response
.data
.auth
.nt_status
== 0)
261 printf("Secret is good\n");
263 printf("Secret is bad\n0x%08x\n",
264 response
.data
.auth
.nt_status
);
272 /* Convert uid to sid */
274 static BOOL
wbinfo_uid_to_sid(uid_t uid
)
276 struct winbindd_request request
;
277 struct winbindd_response response
;
279 ZERO_STRUCT(request
);
280 ZERO_STRUCT(response
);
284 request
.data
.uid
= uid
;
286 if (winbindd_request(WINBINDD_UID_TO_SID
, &request
, &response
) !=
290 /* Display response */
292 printf("%s\n", response
.data
.sid
.sid
);
297 /* Convert gid to sid */
299 static BOOL
wbinfo_gid_to_sid(gid_t gid
)
301 struct winbindd_request request
;
302 struct winbindd_response response
;
304 ZERO_STRUCT(request
);
305 ZERO_STRUCT(response
);
309 request
.data
.gid
= gid
;
311 if (winbindd_request(WINBINDD_GID_TO_SID
, &request
, &response
) !=
315 /* Display response */
317 printf("%s\n", response
.data
.sid
.sid
);
322 /* Convert sid to uid */
324 static BOOL
wbinfo_sid_to_uid(char *sid
)
326 struct winbindd_request request
;
327 struct winbindd_response response
;
329 ZERO_STRUCT(request
);
330 ZERO_STRUCT(response
);
334 fstrcpy(request
.data
.sid
, sid
);
336 if (winbindd_request(WINBINDD_SID_TO_UID
, &request
, &response
) !=
340 /* Display response */
342 printf("%d\n", (int)response
.data
.uid
);
347 static BOOL
wbinfo_sid_to_gid(char *sid
)
349 struct winbindd_request request
;
350 struct winbindd_response response
;
352 ZERO_STRUCT(request
);
353 ZERO_STRUCT(response
);
357 fstrcpy(request
.data
.sid
, sid
);
359 if (winbindd_request(WINBINDD_SID_TO_GID
, &request
, &response
) !=
363 /* Display response */
365 printf("%d\n", (int)response
.data
.gid
);
370 /* Convert sid to string */
372 static BOOL
wbinfo_lookupsid(char *sid
)
374 struct winbindd_request request
;
375 struct winbindd_response response
;
377 ZERO_STRUCT(request
);
378 ZERO_STRUCT(response
);
380 /* Send off request */
382 fstrcpy(request
.data
.sid
, sid
);
384 if (winbindd_request(WINBINDD_LOOKUPSID
, &request
, &response
) !=
388 /* Display response */
390 printf("%s%c%s %d\n", response
.data
.name
.dom_name
,
391 winbind_separator(), response
.data
.name
.name
,
392 response
.data
.name
.type
);
397 /* Convert string to sid */
399 static BOOL
wbinfo_lookupname(char *name
)
401 struct winbindd_request request
;
402 struct winbindd_response response
;
404 /* Send off request */
406 ZERO_STRUCT(request
);
407 ZERO_STRUCT(response
);
409 parse_wbinfo_domain_user(name
, request
.data
.name
.dom_name
,
410 request
.data
.name
.name
);
412 if (winbindd_request(WINBINDD_LOOKUPNAME
, &request
, &response
) !=
416 /* Display response */
418 printf("%s %d\n", response
.data
.sid
.sid
, response
.data
.sid
.type
);
423 /* Authenticate a user with a plaintext password */
425 static BOOL
wbinfo_auth(char *username
)
427 struct winbindd_request request
;
428 struct winbindd_response response
;
432 /* Send off request */
434 ZERO_STRUCT(request
);
435 ZERO_STRUCT(response
);
437 p
= strchr(username
, '%');
441 fstrcpy(request
.data
.auth
.user
, username
);
442 fstrcpy(request
.data
.auth
.pass
, p
+ 1);
445 fstrcpy(request
.data
.auth
.user
, username
);
447 result
= winbindd_request(WINBINDD_PAM_AUTH
, &request
, &response
);
449 /* Display response */
451 printf("plaintext password authentication %s\n",
452 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
454 if (response
.data
.auth
.nt_status
)
455 printf("error code was %s (0x%x)\n",
456 response
.data
.auth
.nt_status_string
,
457 response
.data
.auth
.nt_status
);
459 return result
== NSS_STATUS_SUCCESS
;
462 #ifdef WITH_WINBIND_AUTH_CRAP
464 /* Authenticate a user with a challenge/response */
466 static BOOL
wbinfo_auth_crap(char *username
)
468 struct winbindd_request request
;
469 struct winbindd_response response
;
476 /* Send off request */
478 ZERO_STRUCT(request
);
479 ZERO_STRUCT(response
);
481 p
= strchr(username
, '%');
485 fstrcpy(pass
, p
+ 1);
488 parse_wbinfo_domain_user(username
, name_domain
, name_user
);
490 fstrcpy(request
.data
.auth_crap
.user
, name_user
);
492 fstrcpy(request
.data
.auth_crap
.domain
, name_domain
);
494 generate_random_buffer(request
.data
.auth_crap
.chal
, 8, False
);
496 SMBencrypt((uchar
*)pass
, request
.data
.auth_crap
.chal
,
497 (uchar
*)request
.data
.auth_crap
.lm_resp
);
498 SMBNTencrypt((uchar
*)pass
, request
.data
.auth_crap
.chal
,
499 (uchar
*)request
.data
.auth_crap
.nt_resp
);
501 request
.data
.auth_crap
.lm_resp_len
= 24;
502 request
.data
.auth_crap
.nt_resp_len
= 24;
504 result
= winbindd_request(WINBINDD_PAM_AUTH_CRAP
, &request
, &response
);
506 /* Display response */
508 printf("challenge/response password authentication %s\n",
509 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
511 if (response
.data
.auth
.nt_status
)
512 printf("error code was %s (0x%x)\n",
513 response
.data
.auth
.nt_status_string
,
514 response
.data
.auth
.nt_status
);
516 return result
== NSS_STATUS_SUCCESS
;
519 #endif /* WITH_WINBIND_AUTH_CRAP */
521 /* Print domain users */
523 static BOOL
print_domain_users(void)
525 struct winbindd_response response
;
529 /* Send request to winbind daemon */
531 ZERO_STRUCT(response
);
533 if (winbindd_request(WINBINDD_LIST_USERS
, NULL
, &response
) !=
537 /* Look through extra data */
539 if (!response
.extra_data
)
542 extra_data
= (char *)response
.extra_data
;
544 while(next_token(&extra_data
, name
, ",", sizeof(fstring
)))
545 printf("%s\n", name
);
547 SAFE_FREE(response
.extra_data
);
550 if (response
.nt_status
)
551 printf("0x%08x\n", response
.nt_status
);
556 /* Print domain groups */
558 static BOOL
print_domain_groups(void)
560 struct winbindd_response response
;
564 ZERO_STRUCT(response
);
566 if (winbindd_request(WINBINDD_LIST_GROUPS
, NULL
, &response
) !=
570 /* Look through extra data */
572 if (!response
.extra_data
)
575 extra_data
= (char *)response
.extra_data
;
577 while(next_token(&extra_data
, name
, ",", sizeof(fstring
)))
578 printf("%s\n", name
);
580 SAFE_FREE(response
.extra_data
);
583 if (response
.nt_status
)
584 printf("0x%08x\n", response
.nt_status
);
589 /* Set the authorised user for winbindd access in secrets.tdb */
591 static BOOL
wbinfo_set_auth_user(char *username
)
594 fstring user
, domain
;
596 /* Separate into user and password */
598 parse_wbinfo_domain_user(username
, domain
, user
);
600 password
= strchr(user
, '%');
608 /* Store in secrets.tdb */
612 if (!secrets_store(SECRETS_AUTH_USER
, user
,
614 !secrets_store(SECRETS_AUTH_DOMAIN
, domain
,
615 strlen(domain
) + 1) ||
616 !secrets_store(SECRETS_AUTH_PASSWORD
, password
,
617 strlen(password
) + 1)) {
618 fprintf(stderr
, "error storing authenticated user info\n");
625 static BOOL
wbinfo_ping(void)
629 result
= winbindd_request(WINBINDD_PING
, NULL
, NULL
);
631 /* Display response */
633 printf("'ping' to winbindd %s\n",
634 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
636 return result
== NSS_STATUS_SUCCESS
;
639 /* Print program usage */
641 static void usage(void)
643 printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
644 "| -[aA] user%%password\n");
645 printf("Version: %s\n", VERSION
);
646 printf("\t-u\t\t\tlists all domain users\n");
647 printf("\t-g\t\t\tlists all domain groups\n");
648 printf("\t-n name\t\t\tconverts name to sid\n");
649 printf("\t-s sid\t\t\tconverts sid to name\n");
650 printf("\t-N name\t\t\tconverts NetBIOS name to IP (WINS)\n");
651 printf("\t-I IP\t\t\tconverts IP address to NetBIOS name (WINS)\n");
652 printf("\t-U uid\t\t\tconverts uid to sid\n");
653 printf("\t-G gid\t\t\tconverts gid to sid\n");
654 printf("\t-S sid\t\t\tconverts sid to uid\n");
655 printf("\t-Y sid\t\t\tconverts sid to gid\n");
656 printf("\t-t\t\t\tcheck shared secret\n");
657 printf("\t-m\t\t\tlist trusted domains\n");
658 printf("\t-r user\t\t\tget user groups\n");
659 printf("\t-a user%%password\tauthenticate user\n");
660 printf("\t-A user%%password\tstore user and password used by winbindd (root only)\n");
661 printf("\t-p\t\t\t'ping' winbindd to see if it is alive\n");
662 printf("\t--sequence\t\tshow sequence numbers of all domains\n");
663 printf("\t--set-auth-user DOMAIN\\user%%password\tset password for restrict anonymous\n");
669 OPT_SET_AUTH_USER
= 1000,
673 int main(int argc
, char **argv
)
675 extern pstring global_myname
;
679 static char *string_arg
;
681 BOOL got_command
= False
;
684 struct poptOption long_options
[] = {
686 /* longName, shortName, argInfo, argPtr, value, descrip,
689 { "help", 'h', POPT_ARG_NONE
, 0, 'h' },
690 { "domain-users", 'u', POPT_ARG_NONE
, 0, 'u' },
691 { "domain-groups", 'g', POPT_ARG_NONE
, 0, 'g' },
692 { "WINS-by-name", 'N', POPT_ARG_STRING
, &string_arg
, 'N' },
693 { "WINS-by-ip", 'I', POPT_ARG_STRING
, &string_arg
, 'I' },
694 { "name-to-sid", 'n', POPT_ARG_STRING
, &string_arg
, 'n' },
695 { "sid-to-name", 's', POPT_ARG_STRING
, &string_arg
, 's' },
696 { "uid-to-sid", 'U', POPT_ARG_INT
, &int_arg
, 'U' },
697 { "gid-to-sid", 'G', POPT_ARG_INT
, &int_arg
, 'G' },
698 { "sid-to-uid", 'S', POPT_ARG_STRING
, &string_arg
, 'S' },
699 { "sid-to-gid", 'Y', POPT_ARG_STRING
, &string_arg
, 'Y' },
700 { "check-secret", 't', POPT_ARG_NONE
, 0, 't' },
701 { "trusted-domains", 'm', POPT_ARG_NONE
, 0, 'm' },
702 { "sequence", 0, POPT_ARG_NONE
, 0, OPT_SEQUENCE
},
703 { "user-groups", 'r', POPT_ARG_STRING
, &string_arg
, 'r' },
704 { "authenticate", 'a', POPT_ARG_STRING
, &string_arg
, 'a' },
705 { "set-auth-user", 'A', POPT_ARG_STRING
, &string_arg
, OPT_SET_AUTH_USER
},
706 { "ping", 'p', POPT_ARG_NONE
, 0, 'p' },
710 /* Samba client initialisation */
712 if (!*global_myname
) {
715 fstrcpy(global_myname
, myhostname());
716 p
= strchr(global_myname
, '.');
723 codepage_initialise(lp_client_code_page());
724 charset_initialise();
726 if (!lp_load(CONFIGFILE
, True
, False
, False
)) {
727 fprintf(stderr
, "wbinfo: error opening config file %s. Error was %s\n",
728 CONFIGFILE
, strerror(errno
));
734 /* Parse command line options */
743 pc
= poptGetContext("wbinfo", argc
, (const char **)argv
, long_options
, 0);
745 while((opt
= poptGetNextOpt(pc
)) != -1) {
747 fprintf(stderr
, "No more than one command may be specified at once.\n");
755 pc
= poptGetContext(NULL
, argc
, (const char **)argv
, long_options
,
756 POPT_CONTEXT_KEEP_FIRST
);
758 while((opt
= poptGetNextOpt(pc
)) != -1) {
765 if (!print_domain_users()) {
766 printf("Error looking up domain users\n");
771 if (!print_domain_groups()) {
772 printf("Error looking up domain groups\n");
777 if (!wbinfo_lookupsid(string_arg
)) {
778 printf("Could not lookup sid %s\n", string_arg
);
783 if (!wbinfo_lookupname(string_arg
)) {
784 printf("Could not lookup name %s\n", string_arg
);
789 if (!wbinfo_wins_byname(string_arg
)) {
790 printf("Could not lookup WINS by name %s\n", string_arg
);
795 if (!wbinfo_wins_byip(string_arg
)) {
796 printf("Could not lookup WINS by IP %s\n", string_arg
);
801 if (!wbinfo_uid_to_sid(int_arg
)) {
802 printf("Could not convert uid %d to sid\n", int_arg
);
807 if (!wbinfo_gid_to_sid(int_arg
)) {
808 printf("Could not convert gid %d to sid\n",
814 if (!wbinfo_sid_to_uid(string_arg
)) {
815 printf("Could not convert sid %s to uid\n",
821 if (!wbinfo_sid_to_gid(string_arg
)) {
822 printf("Could not convert sid %s to gid\n",
828 if (!wbinfo_check_secret()) {
829 printf("Could not check secret\n");
834 if (!wbinfo_list_domains()) {
835 printf("Could not list trusted domains\n");
840 if (!wbinfo_show_sequence()) {
841 printf("Could not show sequence numbers\n");
846 if (!wbinfo_get_usergroups(string_arg
)) {
847 printf("Could not get groups for user %s\n",
853 BOOL got_error
= False
;
855 if (!wbinfo_auth(string_arg
)) {
856 printf("Could not authenticate user %s with "
857 "plaintext password\n", string_arg
);
860 #ifdef WITH_WINBIND_AUTH_CRAP
861 if (!wbinfo_auth_crap(string_arg
)) {
862 printf("Could not authenticate user %s with "
863 "challenge/response\n", string_arg
);
873 if (!wbinfo_ping()) {
874 printf("could not ping winbindd!\n");
879 case OPT_SET_AUTH_USER
:
880 if (!(wbinfo_set_auth_user(string_arg
)))
884 fprintf(stderr
, "Invalid option\n");