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.
29 #define DBGC_CLASS DBGC_WINBIND
31 /* Prototypes from common.h */
33 NSS_STATUS
winbindd_request(int req_type
,
34 struct winbindd_request
*request
,
35 struct winbindd_response
*response
);
37 static char winbind_separator(void)
39 struct winbindd_response response
;
46 ZERO_STRUCT(response
);
48 /* Send off request */
50 if (winbindd_request(WINBINDD_INFO
, NULL
, &response
) !=
52 d_printf("could not obtain winbind separator!\n");
53 /* HACK: (this module should not call lp_ funtions) */
54 return *lp_winbind_separator();
57 sep
= response
.data
.info
.winbind_separator
;
61 d_printf("winbind separator was NULL!\n");
62 /* HACK: (this module should not call lp_ funtions) */
63 sep
= *lp_winbind_separator();
69 static char *get_winbind_domain(void)
71 struct winbindd_response response
;
72 static fstring winbind_domain
;
74 ZERO_STRUCT(response
);
76 /* Send off request */
78 if (winbindd_request(WINBINDD_DOMAIN_NAME
, NULL
, &response
) !=
80 d_printf("could not obtain winbind domain name!\n");
82 /* HACK: (this module should not call lp_ funtions) */
83 return lp_workgroup();
86 fstrcpy(winbind_domain
, response
.data
.domain_name
);
88 return winbind_domain
;
92 /* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
93 form DOMAIN/user into a domain and a user */
95 static BOOL
parse_wbinfo_domain_user(const char *domuser
, fstring domain
,
99 char *p
= strchr(domuser
,winbind_separator());
102 fstrcpy(user
, domuser
);
103 fstrcpy(domain
, get_winbind_domain());
108 fstrcpy(domain
, domuser
);
109 domain
[PTR_DIFF(p
, domuser
)] = 0;
115 /* List groups a user is a member of */
117 static BOOL
wbinfo_get_usergroups(char *user
)
119 struct winbindd_request request
;
120 struct winbindd_response response
;
124 ZERO_STRUCT(response
);
128 fstrcpy(request
.data
.username
, user
);
130 result
= winbindd_request(WINBINDD_GETGROUPS
, &request
, &response
);
132 if (result
!= NSS_STATUS_SUCCESS
)
135 for (i
= 0; i
< response
.data
.num_entries
; i
++)
136 d_printf("%d\n", (int)((gid_t
*)response
.extra_data
)[i
]);
138 SAFE_FREE(response
.extra_data
);
143 /* Convert NetBIOS name to IP */
145 static BOOL
wbinfo_wins_byname(char *name
)
147 struct winbindd_request request
;
148 struct winbindd_response response
;
150 ZERO_STRUCT(request
);
151 ZERO_STRUCT(response
);
155 fstrcpy(request
.data
.winsreq
, name
);
157 if (winbindd_request(WINBINDD_WINS_BYNAME
, &request
, &response
) !=
158 NSS_STATUS_SUCCESS
) {
162 /* Display response */
164 printf("%s\n", response
.data
.winsresp
);
169 /* Convert IP to NetBIOS name */
171 static BOOL
wbinfo_wins_byip(char *ip
)
173 struct winbindd_request request
;
174 struct winbindd_response response
;
176 ZERO_STRUCT(request
);
177 ZERO_STRUCT(response
);
181 fstrcpy(request
.data
.winsreq
, ip
);
183 if (winbindd_request(WINBINDD_WINS_BYIP
, &request
, &response
) !=
184 NSS_STATUS_SUCCESS
) {
188 /* Display response */
190 printf("%s\n", response
.data
.winsresp
);
195 /* List trusted domains */
197 static BOOL
wbinfo_list_domains(void)
199 struct winbindd_response response
;
202 ZERO_STRUCT(response
);
206 if (winbindd_request(WINBINDD_LIST_TRUSTDOM
, NULL
, &response
) !=
210 /* Display response */
212 if (response
.extra_data
) {
213 char *extra_data
= (char *)response
.extra_data
;
215 while(next_token(&extra_data
, name
, ",", sizeof(fstring
)))
216 d_printf("%s\n", name
);
218 SAFE_FREE(response
.extra_data
);
225 /* show sequence numbers */
226 static BOOL
wbinfo_show_sequence(void)
228 struct winbindd_response response
;
230 ZERO_STRUCT(response
);
234 if (winbindd_request(WINBINDD_SHOW_SEQUENCE
, NULL
, &response
) !=
238 /* Display response */
240 if (response
.extra_data
) {
241 char *extra_data
= (char *)response
.extra_data
;
242 d_printf("%s", extra_data
);
243 SAFE_FREE(response
.extra_data
);
249 /* Check trust account password */
251 static BOOL
wbinfo_check_secret(void)
253 struct winbindd_response response
;
256 ZERO_STRUCT(response
);
258 result
= winbindd_request(WINBINDD_CHECK_MACHACC
, NULL
, &response
);
260 d_printf("checking the trust secret via RPC calls %s\n",
261 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
263 if (result
!= NSS_STATUS_SUCCESS
)
264 d_printf("error code was %s (0x%x)\n",
265 response
.data
.auth
.nt_status_string
,
266 response
.data
.auth
.nt_status
);
268 return result
== NSS_STATUS_SUCCESS
;
271 /* Convert uid to sid */
273 static BOOL
wbinfo_uid_to_sid(uid_t uid
)
275 struct winbindd_request request
;
276 struct winbindd_response response
;
278 ZERO_STRUCT(request
);
279 ZERO_STRUCT(response
);
283 request
.data
.uid
= uid
;
285 if (winbindd_request(WINBINDD_UID_TO_SID
, &request
, &response
) !=
289 /* Display response */
291 d_printf("%s\n", response
.data
.sid
.sid
);
296 /* Convert gid to sid */
298 static BOOL
wbinfo_gid_to_sid(gid_t gid
)
300 struct winbindd_request request
;
301 struct winbindd_response response
;
303 ZERO_STRUCT(request
);
304 ZERO_STRUCT(response
);
308 request
.data
.gid
= gid
;
310 if (winbindd_request(WINBINDD_GID_TO_SID
, &request
, &response
) !=
314 /* Display response */
316 d_printf("%s\n", response
.data
.sid
.sid
);
321 /* Convert sid to uid */
323 static BOOL
wbinfo_sid_to_uid(char *sid
)
325 struct winbindd_request request
;
326 struct winbindd_response response
;
328 ZERO_STRUCT(request
);
329 ZERO_STRUCT(response
);
333 fstrcpy(request
.data
.sid
, sid
);
335 if (winbindd_request(WINBINDD_SID_TO_UID
, &request
, &response
) !=
339 /* Display response */
341 d_printf("%d\n", (int)response
.data
.uid
);
346 static BOOL
wbinfo_sid_to_gid(char *sid
)
348 struct winbindd_request request
;
349 struct winbindd_response response
;
351 ZERO_STRUCT(request
);
352 ZERO_STRUCT(response
);
356 fstrcpy(request
.data
.sid
, sid
);
358 if (winbindd_request(WINBINDD_SID_TO_GID
, &request
, &response
) !=
362 /* Display response */
364 d_printf("%d\n", (int)response
.data
.gid
);
369 /* Convert sid to string */
371 static BOOL
wbinfo_lookupsid(char *sid
)
373 struct winbindd_request request
;
374 struct winbindd_response response
;
376 ZERO_STRUCT(request
);
377 ZERO_STRUCT(response
);
379 /* Send off request */
381 fstrcpy(request
.data
.sid
, sid
);
383 if (winbindd_request(WINBINDD_LOOKUPSID
, &request
, &response
) !=
387 /* Display response */
389 d_printf("%s%c%s %d\n", response
.data
.name
.dom_name
,
390 winbind_separator(), response
.data
.name
.name
,
391 response
.data
.name
.type
);
396 /* Convert string to sid */
398 static BOOL
wbinfo_lookupname(char *name
)
400 struct winbindd_request request
;
401 struct winbindd_response response
;
403 /* Send off request */
405 ZERO_STRUCT(request
);
406 ZERO_STRUCT(response
);
408 parse_wbinfo_domain_user(name
, request
.data
.name
.dom_name
,
409 request
.data
.name
.name
);
411 if (winbindd_request(WINBINDD_LOOKUPNAME
, &request
, &response
) !=
415 /* Display response */
417 d_printf("%s %d\n", response
.data
.sid
.sid
, response
.data
.sid
.type
);
422 /* Authenticate a user with a plaintext password */
424 static BOOL
wbinfo_auth(char *username
)
426 struct winbindd_request request
;
427 struct winbindd_response response
;
431 /* Send off request */
433 ZERO_STRUCT(request
);
434 ZERO_STRUCT(response
);
436 p
= strchr(username
, '%');
440 fstrcpy(request
.data
.auth
.user
, username
);
441 fstrcpy(request
.data
.auth
.pass
, p
+ 1);
444 fstrcpy(request
.data
.auth
.user
, username
);
446 result
= winbindd_request(WINBINDD_PAM_AUTH
, &request
, &response
);
448 /* Display response */
450 d_printf("plaintext password authentication %s\n",
451 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
453 d_printf("error code was %s (0x%x)\n",
454 response
.data
.auth
.nt_status_string
,
455 response
.data
.auth
.nt_status
);
457 return result
== NSS_STATUS_SUCCESS
;
460 /* Authenticate a user with a challenge/response */
462 static BOOL
wbinfo_auth_crap(char *username
)
464 struct winbindd_request request
;
465 struct winbindd_response response
;
472 /* Send off request */
474 ZERO_STRUCT(request
);
475 ZERO_STRUCT(response
);
477 p
= strchr(username
, '%');
481 fstrcpy(pass
, p
+ 1);
484 parse_wbinfo_domain_user(username
, name_domain
, name_user
);
486 fstrcpy(request
.data
.auth_crap
.user
, name_user
);
488 fstrcpy(request
.data
.auth_crap
.domain
, name_domain
);
490 generate_random_buffer(request
.data
.auth_crap
.chal
, 8, False
);
492 SMBencrypt(pass
, request
.data
.auth_crap
.chal
,
493 (uchar
*)request
.data
.auth_crap
.lm_resp
);
494 SMBNTencrypt(pass
, request
.data
.auth_crap
.chal
,
495 (uchar
*)request
.data
.auth_crap
.nt_resp
);
497 request
.data
.auth_crap
.lm_resp_len
= 24;
498 request
.data
.auth_crap
.nt_resp_len
= 24;
500 result
= winbindd_request(WINBINDD_PAM_AUTH_CRAP
, &request
, &response
);
502 /* Display response */
504 d_printf("challenge/response password authentication %s\n",
505 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
507 d_printf("error code was %s (0x%x)\n",
508 response
.data
.auth
.nt_status_string
,
509 response
.data
.auth
.nt_status
);
511 return result
== NSS_STATUS_SUCCESS
;
514 /* Print domain users */
516 static BOOL
print_domain_users(void)
518 struct winbindd_response response
;
522 /* Send request to winbind daemon */
524 ZERO_STRUCT(response
);
526 if (winbindd_request(WINBINDD_LIST_USERS
, NULL
, &response
) !=
530 /* Look through extra data */
532 if (!response
.extra_data
)
535 extra_data
= (char *)response
.extra_data
;
537 while(next_token(&extra_data
, name
, ",", sizeof(fstring
)))
538 d_printf("%s\n", name
);
540 SAFE_FREE(response
.extra_data
);
545 /* Print domain groups */
547 static BOOL
print_domain_groups(void)
549 struct winbindd_response response
;
553 ZERO_STRUCT(response
);
555 if (winbindd_request(WINBINDD_LIST_GROUPS
, NULL
, &response
) !=
559 /* Look through extra data */
561 if (!response
.extra_data
)
564 extra_data
= (char *)response
.extra_data
;
566 while(next_token(&extra_data
, name
, ",", sizeof(fstring
)))
567 d_printf("%s\n", name
);
569 SAFE_FREE(response
.extra_data
);
574 /* Set the authorised user for winbindd access in secrets.tdb */
576 static BOOL
wbinfo_set_auth_user(char *username
)
579 fstring user
, domain
;
581 /* Separate into user and password */
583 parse_wbinfo_domain_user(username
, domain
, user
);
585 password
= strchr(user
, '%');
593 /* Store in secrets.tdb */
595 if (!secrets_store(SECRETS_AUTH_USER
, user
,
597 !secrets_store(SECRETS_AUTH_DOMAIN
, domain
,
598 strlen(domain
) + 1) ||
599 !secrets_store(SECRETS_AUTH_PASSWORD
, password
,
600 strlen(password
) + 1)) {
601 d_fprintf(stderr
, "error storing authenticated user info\n");
608 static BOOL
wbinfo_ping(void)
612 result
= winbindd_request(WINBINDD_PING
, NULL
, NULL
);
614 /* Display response */
616 d_printf("'ping' to winbindd %s\n",
617 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
619 return result
== NSS_STATUS_SUCCESS
;
622 /* Print program usage */
624 static void usage(void)
626 d_printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
627 "| -[aA] user%%password\n");
628 d_printf("\t-u\t\t\tlists all domain users\n");
629 d_printf("\t-g\t\t\tlists all domain groups\n");
630 d_printf("\t-n name\t\t\tconverts name to sid\n");
631 d_printf("\t-s sid\t\t\tconverts sid to name\n");
632 d_printf("\t-N name\t\t\tconverts NetBIOS name to IP (WINS)\n");
633 d_printf("\t-I name\t\t\tconverts IP address to NetBIOS name (WINS)\n");
634 d_printf("\t-U uid\t\t\tconverts uid to sid\n");
635 d_printf("\t-G gid\t\t\tconverts gid to sid\n");
636 d_printf("\t-S sid\t\t\tconverts sid to uid\n");
637 d_printf("\t-Y sid\t\t\tconverts sid to gid\n");
638 d_printf("\t-t\t\t\tcheck shared secret\n");
639 d_printf("\t-m\t\t\tlist trusted domains\n");
640 d_printf("\t-r user\t\t\tget user groups\n");
641 d_printf("\t-a user%%password\tauthenticate user\n");
642 d_printf("\t-A user%%password\tstore user and password used by winbindd (root only)\n");
643 d_printf("\t-p\t\t\t'ping' winbindd to see if it is alive\n");
644 d_printf("\t--sequence\t\tshow sequence numbers of all domains\n");
645 d_printf("\t--set-auth-user DOMAIN\\user%%password\tset password for restrict anonymous\n");
651 OPT_SET_AUTH_USER
= 1000,
655 int main(int argc
, char **argv
)
657 extern pstring global_myname
;
661 static char *string_arg
;
663 BOOL got_command
= False
;
666 struct poptOption long_options
[] = {
668 /* longName, shortName, argInfo, argPtr, value, descrip,
671 { "help", 'h', POPT_ARG_NONE
, 0, 'h' },
672 { "domain-users", 'u', POPT_ARG_NONE
, 0, 'u' },
673 { "domain-groups", 'g', POPT_ARG_NONE
, 0, 'g' },
674 { "WINS-by-name", 'N', POPT_ARG_STRING
, &string_arg
, 'N' },
675 { "WINS-by-ip", 'I', POPT_ARG_STRING
, &string_arg
, 'I' },
676 { "name-to-sid", 'n', POPT_ARG_STRING
, &string_arg
, 'n' },
677 { "sid-to-name", 's', POPT_ARG_STRING
, &string_arg
, 's' },
678 { "uid-to-sid", 'U', POPT_ARG_INT
, &int_arg
, 'U' },
679 { "gid-to-sid", 'G', POPT_ARG_INT
, &int_arg
, 'G' },
680 { "sid-to-uid", 'S', POPT_ARG_STRING
, &string_arg
, 'S' },
681 { "sid-to-gid", 'Y', POPT_ARG_STRING
, &string_arg
, 'Y' },
682 { "check-secret", 't', POPT_ARG_NONE
, 0, 't' },
683 { "trusted-domains", 'm', POPT_ARG_NONE
, 0, 'm' },
684 { "sequence", 0, POPT_ARG_NONE
, 0, OPT_SEQUENCE
},
685 { "user-groups", 'r', POPT_ARG_STRING
, &string_arg
, 'r' },
686 { "authenticate", 'a', POPT_ARG_STRING
, &string_arg
, 'a' },
687 { "set-auth-user", 'A', POPT_ARG_STRING
, &string_arg
, OPT_SET_AUTH_USER
},
688 { "ping", 'p', POPT_ARG_NONE
, 0, 'p' },
692 /* Samba client initialisation */
694 if (!*global_myname
) {
697 fstrcpy(global_myname
, myhostname());
698 p
= strchr(global_myname
, '.');
703 if (!lp_load(dyn_CONFIGFILE
, True
, False
, False
)) {
704 d_fprintf(stderr
, "wbinfo: error opening config file %s. Error was %s\n",
705 dyn_CONFIGFILE
, strerror(errno
));
711 /* Parse command line options */
720 pc
= poptGetContext("wbinfo", argc
, (const char **)argv
, long_options
, 0);
722 while((opt
= poptGetNextOpt(pc
)) != -1) {
724 d_fprintf(stderr
, "No more than one command may be specified at once.\n");
732 pc
= poptGetContext(NULL
, argc
, (const char **)argv
, long_options
,
733 POPT_CONTEXT_KEEP_FIRST
);
735 while((opt
= poptGetNextOpt(pc
)) != -1) {
742 if (!print_domain_users()) {
743 d_printf("Error looking up domain users\n");
748 if (!print_domain_groups()) {
749 d_printf("Error looking up domain groups\n");
754 if (!wbinfo_lookupsid(string_arg
)) {
755 d_printf("Could not lookup sid %s\n", string_arg
);
760 if (!wbinfo_lookupname(string_arg
)) {
761 d_printf("Could not lookup name %s\n", string_arg
);
766 if (!wbinfo_wins_byname(string_arg
)) {
767 d_printf("Could not lookup WINS by name %s\n", string_arg
);
772 if (!wbinfo_wins_byip(string_arg
)) {
773 d_printf("Could not lookup WINS by IP %s\n", string_arg
);
778 if (!wbinfo_uid_to_sid(int_arg
)) {
779 d_printf("Could not convert uid %d to sid\n", int_arg
);
784 if (!wbinfo_gid_to_sid(int_arg
)) {
785 d_printf("Could not convert gid %d to sid\n",
791 if (!wbinfo_sid_to_uid(string_arg
)) {
792 d_printf("Could not convert sid %s to uid\n",
798 if (!wbinfo_sid_to_gid(string_arg
)) {
799 d_printf("Could not convert sid %s to gid\n",
805 if (!wbinfo_check_secret()) {
806 d_printf("Could not check secret\n");
811 if (!wbinfo_list_domains()) {
812 d_printf("Could not list trusted domains\n");
817 if (!wbinfo_show_sequence()) {
818 d_printf("Could not show sequence numbers\n");
823 if (!wbinfo_get_usergroups(string_arg
)) {
824 d_printf("Could not get groups for user %s\n",
830 BOOL got_error
= False
;
832 if (!wbinfo_auth(string_arg
)) {
833 d_printf("Could not authenticate user %s with "
834 "plaintext password\n", string_arg
);
838 if (!wbinfo_auth_crap(string_arg
)) {
839 d_printf("Could not authenticate user %s with "
840 "challenge/response\n", string_arg
);
850 if (!wbinfo_ping()) {
851 d_printf("could not ping winbindd!\n");
856 case OPT_SET_AUTH_USER
:
857 if (!(wbinfo_set_auth_user(string_arg
)))
861 d_fprintf(stderr
, "Invalid option\n");