strchr and strrchr are macros when compiling with optimisation in gcc, so we can...
[tprouty/samba.git] / source / nsswitch / wbinfo.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.0
4
5    Winbind status program.
6
7    Copyright (C) Tim Potter 2000
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 2 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, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "winbindd.h"
26 #include "debug.h"
27
28 /* Prototypes from common.h */
29
30 int winbindd_request(int req_type, struct winbindd_request *request,
31                      struct winbindd_response *response);
32
33 /* List groups a user is a member of */
34
35 static BOOL wbinfo_get_usergroups(char *user)
36 {
37         struct winbindd_request request;
38         struct winbindd_response response;
39         int result, i;
40         
41         ZERO_STRUCT(response);
42
43         /* Send request */
44
45         fstrcpy(request.data.username, user);
46
47         result = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
48
49         if (result != NSS_STATUS_SUCCESS) {
50                 return False;
51         }
52
53         for (i = 0; i < response.data.num_entries; i++) {
54                 printf("%d\n", (int)((gid_t *)response.extra_data)[i]);
55         }
56
57         return True;
58 }
59
60 /* List trusted domains */
61
62 static BOOL wbinfo_list_domains(void)
63 {
64         struct winbindd_response response;
65         fstring name;
66
67         ZERO_STRUCT(response);
68
69         /* Send request */
70
71         if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) ==
72             WINBINDD_ERROR) {
73                 return False;
74         }
75
76         /* Display response */
77
78         if (response.extra_data) {
79                 while(next_token((char **)&response.extra_data, name, ",", 
80                                  sizeof(fstring))) {
81                         printf("%s\n", name);
82                 }
83         }
84
85         return True;
86 }
87
88 /* Check trust account password */
89
90 static BOOL wbinfo_check_secret(void)
91 {
92         struct winbindd_response response;
93         BOOL result;
94
95         ZERO_STRUCT(response);
96
97         result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response) ==
98                 NSS_STATUS_SUCCESS;
99
100         if (result) {
101
102                 if (response.data.num_entries == 0) {
103                         printf("Secret is good\n");
104                 } else {
105                         printf("Secret is bad\n0x%08x\n", 
106                                response.data.num_entries);
107                 }
108
109                 return True;
110         }
111
112         return False;
113 }
114
115 /* Convert uid to sid */
116
117 static BOOL wbinfo_uid_to_sid(uid_t uid)
118 {
119         struct winbindd_request request;
120         struct winbindd_response response;
121
122         ZERO_STRUCT(request);
123         ZERO_STRUCT(response);
124
125         /* Send request */
126
127         request.data.uid = uid;
128         if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) ==
129             WINBINDD_ERROR) {
130                 return False;
131         }
132
133         /* Display response */
134
135         printf("%s\n", response.data.sid.sid);
136
137         return True;
138 }
139
140 /* Convert gid to sid */
141
142 static BOOL wbinfo_gid_to_sid(gid_t gid)
143 {
144         struct winbindd_request request;
145         struct winbindd_response response;
146
147         ZERO_STRUCT(request);
148         ZERO_STRUCT(response);
149
150         /* Send request */
151
152         request.data.gid = gid;
153         if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) ==
154             WINBINDD_ERROR) {
155                 return False;
156         }
157
158         /* Display response */
159
160         printf("%s\n", response.data.sid.sid);
161
162         return True;
163 }
164
165 /* Convert sid to uid */
166
167 static BOOL wbinfo_sid_to_uid(char *sid)
168 {
169         struct winbindd_request request;
170         struct winbindd_response response;
171
172         ZERO_STRUCT(request);
173         ZERO_STRUCT(response);
174
175         /* Send request */
176
177         fstrcpy(request.data.sid, sid);
178         if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) ==
179             WINBINDD_ERROR) {
180                 return False;
181         }
182
183         /* Display response */
184
185         printf("%d\n", (int)response.data.uid);
186
187         return True;
188 }
189
190 static BOOL wbinfo_sid_to_gid(char *sid)
191 {
192         struct winbindd_request request;
193         struct winbindd_response response;
194
195         ZERO_STRUCT(request);
196         ZERO_STRUCT(response);
197
198         /* Send request */
199
200         fstrcpy(request.data.sid, sid);
201         if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) ==
202             WINBINDD_ERROR) {
203                 return False;
204         }
205
206         /* Display response */
207
208         printf("%d\n", (int)response.data.gid);
209
210         return True;
211 }
212
213 /* Convert sid to string */
214
215 static BOOL wbinfo_lookupsid(char *sid)
216 {
217         struct winbindd_request request;
218         struct winbindd_response response;
219
220         ZERO_STRUCT(request);
221         ZERO_STRUCT(response);
222
223         /* Send off request */
224
225         fstrcpy(request.data.sid, sid);
226         if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) ==
227             WINBINDD_ERROR) {
228                 return False;
229         }
230
231         /* Display response */
232
233         printf("%s %d\n", response.data.name.name, response.data.name.type);
234
235         return True;
236 }
237
238 /* Convert string to sid */
239
240 static BOOL wbinfo_lookupname(char *name)
241 {
242         struct winbindd_request request;
243         struct winbindd_response response;
244
245         /* Send off request */
246
247         ZERO_STRUCT(request);
248         ZERO_STRUCT(response);
249
250         fstrcpy(request.data.name, name);
251         if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) ==
252             WINBINDD_ERROR) {
253                 return False;
254         }
255
256         /* Display response */
257
258         printf("%s %d\n", response.data.sid.sid, response.data.sid.type);
259
260         return True;
261 }
262
263 /* Print domain users */
264
265 static BOOL print_domain_users(void)
266 {
267         struct winbindd_response response;
268         fstring name;
269
270         /* Send request to winbind daemon */
271
272         ZERO_STRUCT(response);
273
274         if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) ==
275             WINBINDD_ERROR) {
276                 return False;
277         }
278
279         /* Look through extra data */
280
281         if (!response.extra_data) {
282                 return False;
283         }
284
285         while(next_token((char **)&response.extra_data, name, ",", 
286                          sizeof(fstring))) {
287                 printf("%s\n", name);
288         }
289         
290         return True;
291 }
292
293 /* Print domain groups */
294
295 static BOOL print_domain_groups(void)
296 {
297         struct winbindd_response response;
298         fstring name;
299
300         ZERO_STRUCT(response);
301
302         if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) ==
303             WINBINDD_ERROR) {
304                 return False;
305         }
306
307         /* Look through extra data */
308
309         if (!response.extra_data) {
310                 return False;
311         }
312
313         while(next_token((char **)&response.extra_data, name, ",", 
314                          sizeof(fstring))) {
315                 printf("%s\n", name);
316         }
317         
318         return True;
319 }
320
321 /* Print program usage */
322
323 static void usage(void)
324 {
325         printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm\n");
326         printf("\t-u\tlists all domain users\n");
327         printf("\t-g\tlists all domain groups\n");
328         printf("\t-n name\tconverts name to sid\n");
329         printf("\t-s sid\tconverts sid to name\n");
330         printf("\t-U uid\tconverts uid to sid\n");
331         printf("\t-G gid\tconverts gid to sid\n");
332         printf("\t-S sid\tconverts sid to uid\n");
333         printf("\t-Y sid\tconverts sid to gid\n");
334         printf("\t-t\tcheck shared secret\n");
335         printf("\t-m\tlist trusted domains\n");
336         printf("\t-r user\tget user groups\n");
337 }
338
339 /* Main program */
340
341 int main(int argc, char **argv)
342 {
343         extern pstring global_myname;
344         int opt;
345
346         /* Samba client initialisation */
347
348         if (!*global_myname) {
349                 char *p;
350
351                 fstrcpy(global_myname, myhostname());
352                 p = strchr_m(global_myname, '.');
353                 if (p) {
354                         *p = 0;
355                 }
356         }
357
358         TimeInit();
359
360         if (!lp_load(CONFIGFILE, True, False, False)) {
361                 DEBUG(0, ("error opening config file\n"));
362                 exit(1);
363         }
364         
365         load_interfaces();
366
367         /* Parse command line options */
368
369         if (argc == 1) {
370                 usage();
371                 return 1;
372         }
373
374         while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:")) != EOF) {
375                 switch (opt) {
376                 case 'u':
377                         if (!print_domain_users()) {
378                                 printf("Error looking up domain users\n");
379                                 return 1;
380                         }
381                         break;
382                 case 'g':
383                         if (!print_domain_groups()) {
384                                 printf("Error looking up domain groups\n");
385                                 return 1;
386                         }
387                         break;
388                 case 's':
389                         if (!wbinfo_lookupsid(optarg)) {
390                                 printf("Could not lookup sid %s\n", optarg);
391                                 return 1;
392                         }
393                         break;
394                 case 'n':
395                         if (!wbinfo_lookupname(optarg)) {
396                                 printf("Could not lookup name %s\n", optarg);
397                                 return 1;
398                         }
399                         break;
400                 case 'U':
401                         if (!wbinfo_uid_to_sid(atoi(optarg))) {
402                                 printf("Could not convert uid %s to sid\n",
403                                        optarg);
404                                 return 1;
405                         }
406                         break;
407                 case 'G':
408                         if (!wbinfo_gid_to_sid(atoi(optarg))) {
409                                 printf("Could not convert gid %s to sid\n",
410                                        optarg);
411                                 return 1;
412                         }
413                         break;
414                 case 'S':
415                         if (!wbinfo_sid_to_uid(optarg)) {
416                                 printf("Could not convert sid %s to uid\n",
417                                        optarg);
418                                 return 1;
419                         }
420                         break;
421                 case 'Y':
422                         if (!wbinfo_sid_to_gid(optarg)) {
423                                 printf("Could not convert sid %s to gid\n",
424                                        optarg);
425                                 return 1;
426                         }
427                         break;
428                 case 't':
429                         if (!wbinfo_check_secret()) {
430                                 printf("Could not check secret\n");
431                                 return 1;
432                         }
433                         break;
434                 case 'm':
435                         if (!wbinfo_list_domains()) {
436                                 printf("Could not list trusted domains\n");
437                                 return 1;
438                         }
439                         break;
440                 case 'r':
441                         if (!wbinfo_get_usergroups(optarg)) {
442                                 printf("Could not get groups for user %s\n", 
443                                        optarg);
444                                 return 1;
445                         }
446                         break;
447                                 
448                       /* Invalid option */
449
450                 default:
451                         usage();
452                         return 1;
453                 }
454         }
455         
456         /* Clean exit */
457
458         return 0;
459 }