2 Unix SMB/Netbios implementation.
5 Winbind status program.
7 Copyright (C) Tim Potter 2000
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 /* List groups a user is a member of */
36 static BOOL
wbinfo_get_usergroups(char *user
)
38 struct winbindd_request request
;
39 struct winbindd_response response
;
43 ZERO_STRUCT(response
);
47 fstrcpy(request
.data
.username
, user
);
49 result
= winbindd_request(WINBINDD_GETGROUPS
, &request
, &response
);
51 if (result
!= NSS_STATUS_SUCCESS
) {
55 for (i
= 0; i
< response
.data
.num_entries
; i
++) {
56 printf("%d\n", (int)((gid_t
*)response
.extra_data
)[i
]);
62 /* List trusted domains */
64 static BOOL
wbinfo_list_domains(void)
66 struct winbindd_response response
;
69 ZERO_STRUCT(response
);
73 if (winbindd_request(WINBINDD_LIST_TRUSTDOM
, NULL
, &response
) !=
78 /* Display response */
80 if (response
.extra_data
) {
81 while(next_token((char **)&response
.extra_data
, name
, ",",
90 /* Check trust account password */
92 static BOOL
wbinfo_check_secret(void)
94 struct winbindd_response response
;
97 ZERO_STRUCT(response
);
99 result
= winbindd_request(WINBINDD_CHECK_MACHACC
, NULL
, &response
) ==
104 if (response
.data
.num_entries
== 0) {
105 printf("Secret is good\n");
107 printf("Secret is bad\n0x%08x\n",
108 response
.data
.num_entries
);
117 /* Convert uid to sid */
119 static BOOL
wbinfo_uid_to_sid(uid_t uid
)
121 struct winbindd_request request
;
122 struct winbindd_response response
;
124 ZERO_STRUCT(request
);
125 ZERO_STRUCT(response
);
129 request
.data
.uid
= uid
;
130 if (winbindd_request(WINBINDD_UID_TO_SID
, &request
, &response
) !=
131 NSS_STATUS_SUCCESS
) {
135 /* Display response */
137 printf("%s\n", response
.data
.sid
.sid
);
142 /* Convert gid to sid */
144 static BOOL
wbinfo_gid_to_sid(gid_t gid
)
146 struct winbindd_request request
;
147 struct winbindd_response response
;
149 ZERO_STRUCT(request
);
150 ZERO_STRUCT(response
);
154 request
.data
.gid
= gid
;
155 if (winbindd_request(WINBINDD_GID_TO_SID
, &request
, &response
) !=
156 NSS_STATUS_SUCCESS
) {
160 /* Display response */
162 printf("%s\n", response
.data
.sid
.sid
);
167 /* Convert sid to uid */
169 static BOOL
wbinfo_sid_to_uid(char *sid
)
171 struct winbindd_request request
;
172 struct winbindd_response response
;
174 ZERO_STRUCT(request
);
175 ZERO_STRUCT(response
);
179 fstrcpy(request
.data
.sid
, sid
);
180 if (winbindd_request(WINBINDD_SID_TO_UID
, &request
, &response
) !=
181 NSS_STATUS_SUCCESS
) {
185 /* Display response */
187 printf("%d\n", (int)response
.data
.uid
);
192 static BOOL
wbinfo_sid_to_gid(char *sid
)
194 struct winbindd_request request
;
195 struct winbindd_response response
;
197 ZERO_STRUCT(request
);
198 ZERO_STRUCT(response
);
202 fstrcpy(request
.data
.sid
, sid
);
203 if (winbindd_request(WINBINDD_SID_TO_GID
, &request
, &response
) !=
204 NSS_STATUS_SUCCESS
) {
208 /* Display response */
210 printf("%d\n", (int)response
.data
.gid
);
215 /* Convert sid to string */
217 static BOOL
wbinfo_lookupsid(char *sid
)
219 struct winbindd_request request
;
220 struct winbindd_response response
;
222 ZERO_STRUCT(request
);
223 ZERO_STRUCT(response
);
225 /* Send off request */
227 fstrcpy(request
.data
.sid
, sid
);
228 if (winbindd_request(WINBINDD_LOOKUPSID
, &request
, &response
) !=
229 NSS_STATUS_SUCCESS
) {
233 /* Display response */
235 printf("%s %d\n", response
.data
.name
.name
, response
.data
.name
.type
);
240 /* Convert string to sid */
242 static BOOL
wbinfo_lookupname(char *name
)
244 struct winbindd_request request
;
245 struct winbindd_response response
;
248 * Don't do the lookup if the name has no separator.
251 if (!strchr(name
, *lp_winbind_separator()))
254 /* Send off request */
256 ZERO_STRUCT(request
);
257 ZERO_STRUCT(response
);
259 fstrcpy(request
.data
.name
, name
);
260 if (winbindd_request(WINBINDD_LOOKUPNAME
, &request
, &response
) !=
261 NSS_STATUS_SUCCESS
) {
265 /* Display response */
267 printf("%s %d\n", response
.data
.sid
.sid
, response
.data
.sid
.type
);
272 /* Authenticate a user with a plaintext password */
274 static BOOL
wbinfo_auth(char *username
)
276 struct winbindd_request request
;
277 struct winbindd_response response
;
282 * Don't do the lookup if the name has no separator.
285 if (!strchr(username
, *lp_winbind_separator()))
288 /* Send off request */
290 ZERO_STRUCT(request
);
291 ZERO_STRUCT(response
);
293 p
= strchr(username
, '%');
297 fstrcpy(request
.data
.auth
.user
, username
);
298 fstrcpy(request
.data
.auth
.pass
, p
+ 1);
301 fstrcpy(request
.data
.auth
.user
, username
);
303 result
= winbindd_request(WINBINDD_PAM_AUTH
, &request
, &response
);
305 /* Display response */
307 printf("plaintext password authentication %s\n",
308 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
310 return result
== NSS_STATUS_SUCCESS
;
313 /* Authenticate a user with a challenge/response */
315 static BOOL
wbinfo_auth_crap(char *username
)
317 struct winbindd_request request
;
318 struct winbindd_response response
;
324 * Don't do the lookup if the name has no separator.
327 if (!strchr(username
, *lp_winbind_separator()))
330 /* Send off request */
332 ZERO_STRUCT(request
);
333 ZERO_STRUCT(response
);
335 p
= strchr(username
, '%');
339 fstrcpy(request
.data
.auth_crap
.user
, username
);
340 fstrcpy(pass
, p
+ 1);
343 fstrcpy(request
.data
.auth_crap
.user
, username
);
345 generate_random_buffer(request
.data
.auth_crap
.chal
, 8, False
);
347 SMBencrypt((uchar
*)pass
, request
.data
.auth_crap
.chal
,
348 (uchar
*)request
.data
.auth_crap
.lm_resp
);
349 SMBNTencrypt((uchar
*)pass
, request
.data
.auth_crap
.chal
,
350 (uchar
*)request
.data
.auth_crap
.nt_resp
);
352 request
.data
.auth_crap
.lm_resp_len
= 24;
353 request
.data
.auth_crap
.nt_resp_len
= 24;
355 result
= winbindd_request(WINBINDD_PAM_AUTH_CRAP
, &request
, &response
);
357 /* Display response */
359 printf("challenge/response password authentication %s\n",
360 (result
== NSS_STATUS_SUCCESS
) ? "succeeded" : "failed");
362 return result
== NSS_STATUS_SUCCESS
;
365 /* Print domain users */
367 static BOOL
print_domain_users(void)
369 struct winbindd_response response
;
372 /* Send request to winbind daemon */
374 ZERO_STRUCT(response
);
376 if (winbindd_request(WINBINDD_LIST_USERS
, NULL
, &response
) !=
377 NSS_STATUS_SUCCESS
) {
381 /* Look through extra data */
383 if (!response
.extra_data
) {
387 while(next_token((char **)&response
.extra_data
, name
, ",",
389 printf("%s\n", name
);
395 /* Print domain groups */
397 static BOOL
print_domain_groups(void)
399 struct winbindd_response response
;
402 ZERO_STRUCT(response
);
404 if (winbindd_request(WINBINDD_LIST_GROUPS
, NULL
, &response
) !=
405 NSS_STATUS_SUCCESS
) {
409 /* Look through extra data */
411 if (!response
.extra_data
) {
415 while(next_token((char **)&response
.extra_data
, name
, ",",
417 printf("%s\n", name
);
423 /* Set the authorised user for winbindd access in secrets.tdb */
425 static BOOL
wbinfo_set_auth_user(char *username
)
429 /* Separate into user and password */
431 password
= strchr(username
, '%');
439 /* Store in secrets.tdb */
441 if (!secrets_store(SECRETS_AUTH_USER
, username
, strlen(username
) + 1) ||
442 !secrets_store(SECRETS_AUTH_PASSWORD
, password
, strlen(password
) + 1)) {
443 fprintf(stderr
, "error storing authenticated user info\n");
450 /* Print program usage */
452 static void usage(void)
454 printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
455 "| -a user%%password\n");
456 printf("\t-u\t\t\tlists all domain users\n");
457 printf("\t-g\t\t\tlists all domain groups\n");
458 printf("\t-n name\t\t\tconverts name to sid\n");
459 printf("\t-s sid\t\t\tconverts sid to name\n");
460 printf("\t-U uid\t\t\tconverts uid to sid\n");
461 printf("\t-G gid\t\t\tconverts gid to sid\n");
462 printf("\t-S sid\t\t\tconverts sid to uid\n");
463 printf("\t-Y sid\t\t\tconverts sid to gid\n");
464 printf("\t-t\t\t\tcheck shared secret\n");
465 printf("\t-m\t\t\tlist trusted domains\n");
466 printf("\t-r user\t\t\tget user groups\n");
467 printf("\t-a user%%password\tauthenticate user\n");
473 OPT_SET_AUTH_USER
= 1000
476 int main(int argc
, char **argv
)
478 extern pstring global_myname
;
482 static char *string_arg
;
484 BOOL got_command
= False
;
486 struct poptOption long_options
[] = {
488 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
489 { "help", 'h', POPT_ARG_NONE
, 0, 'h' },
490 { "domain-users", 'u', POPT_ARG_NONE
, 0, 'u' },
491 { "domain-groups", 'g', POPT_ARG_NONE
, 0, 'g' },
492 { "name-to-sid", 'n', POPT_ARG_STRING
, &string_arg
, 'n' },
493 { "sid-to-name", 's', POPT_ARG_STRING
, &string_arg
, 's' },
494 { "uid-to-sid", 'U', POPT_ARG_INT
, &int_arg
, 'U' },
495 { "gid-to-sid", 'G', POPT_ARG_INT
, &int_arg
, 'G' },
496 { "sid-to-uid", 'S', POPT_ARG_STRING
, &string_arg
, 'S' },
497 { "sid-to-gid", 'Y', POPT_ARG_STRING
, &string_arg
, 'Y' },
498 { "check-secret", 't', POPT_ARG_NONE
, 0, 't' },
499 { "trusted-domains", 'm', POPT_ARG_NONE
, 0, 'm' },
500 { "user-groups", 'r', POPT_ARG_STRING
, &string_arg
, 'r' },
501 { "authenticate", 'a', POPT_ARG_STRING
, &string_arg
, 'a' },
502 { "set-auth-user", 0, POPT_ARG_STRING
, &string_arg
, OPT_SET_AUTH_USER
},
506 /* Samba client initialisation */
508 if (!*global_myname
) {
511 fstrcpy(global_myname
, myhostname());
512 p
= strchr(global_myname
, '.');
518 if (!lp_load(dyn_CONFIGFILE
, True
, False
, False
)) {
519 fprintf(stderr
, "wbinfo: error opening config file %s. Error was %s\n",
520 dyn_CONFIGFILE
, strerror(errno
));
526 /* Parse command line options */
535 pc
= poptGetContext("wbinfo", argc
, (const char **)argv
, long_options
, 0);
537 while((opt
= poptGetNextOpt(pc
)) != -1) {
539 fprintf(stderr
, "No more than one command may be specified "
546 pc
= poptGetContext(NULL
, argc
, (const char **)argv
, long_options
,
547 POPT_CONTEXT_KEEP_FIRST
);
549 while((opt
= poptGetNextOpt(pc
)) != -1) {
555 if (!print_domain_users()) {
556 printf("Error looking up domain users\n");
561 if (!print_domain_groups()) {
562 printf("Error looking up domain groups\n");
567 if (!wbinfo_lookupsid(string_arg
)) {
568 printf("Could not lookup sid %s\n", string_arg
);
573 if (!wbinfo_lookupname(string_arg
)) {
574 printf("Could not lookup name %s\n", string_arg
);
579 if (!wbinfo_uid_to_sid(int_arg
)) {
580 printf("Could not convert uid %d to sid\n", int_arg
);
585 if (!wbinfo_gid_to_sid(int_arg
)) {
586 printf("Could not convert gid %d to sid\n",
592 if (!wbinfo_sid_to_uid(string_arg
)) {
593 printf("Could not convert sid %s to uid\n",
599 if (!wbinfo_sid_to_gid(string_arg
)) {
600 printf("Could not convert sid %s to gid\n",
606 if (!wbinfo_check_secret()) {
607 printf("Could not check secret\n");
612 if (!wbinfo_list_domains()) {
613 printf("Could not list trusted domains\n");
618 if (!wbinfo_get_usergroups(string_arg
)) {
619 printf("Could not get groups for user %s\n",
625 BOOL got_error
= False
;
627 if (!wbinfo_auth(string_arg
)) {
628 printf("Could not authenticate user %s with "
629 "plaintext password\n", string_arg
);
633 if (!wbinfo_auth_crap(string_arg
)) {
634 printf("Could not authenticate user %s with "
635 "challenge/response\n", string_arg
);
643 case OPT_SET_AUTH_USER
:
644 if (!(wbinfo_set_auth_user(string_arg
))) {
649 fprintf(stderr
, "Invalid option\n");