make tsmread.c more robust
[tridge/junkcode.git] / getgrouplist.c
1 #define NGROUPS_MAX 1000
2
3 #include <stdio.h>
4 #include <unistd.h>
5
6 #include <sys/types.h>
7 #include <string.h>
8 #include <grp.h>
9 #include <pwd.h>
10
11 #ifndef HAVE_GETGROUPLIST
12 /*
13   This is a *much* faster way of getting the list of groups for a user
14   without changing the current supplemenrary group list. The old
15   method user getgrent() which could take 20 minutes on a really big
16   network with hundeds of thousands of groups and users. The new method
17   takes a couple of seconds. (tridge@samba.org)
18
19   unfortunately it only works if we are root!
20   */
21 int
22 getgrouplist(uname, agroup, groups, grpcnt)
23         const char *uname;
24         gid_t agroup;
25         register gid_t *groups;
26         int *grpcnt;
27 {
28         gid_t gids_saved[NGROUPS_MAX + 1];
29         int ret, ngrp_saved;
30         
31         ngrp_saved = getgroups(NGROUPS_MAX, gids_saved);
32         if (ngrp_saved == -1) {
33                 return -1;
34         }
35
36         if (initgroups(uname, agroup) != 0) {
37                 return -1;
38         }
39
40         ret = getgroups(*grpcnt, groups);
41         if (ret >= 0) {
42                 *grpcnt = ret;
43         }
44
45         if (setgroups(ngrp_saved, gids_saved) != 0) {
46                 /* yikes! */
47                 fprintf(stderr,"getgrouplist: failed to reset group list!\n");
48                 exit(1);
49         }
50
51         return ret;
52 }
53 #endif
54
55 int main(int argc, char *argv[])
56 {
57         char *user = argv[1];
58         struct passwd *pwd;
59         gid_t gids[NGROUPS_MAX + 1];
60         int count, ret, i;
61
62         pwd = getpwnam(user);
63
64         if (!pwd) {
65                 printf("Unknown user '%s'\n", user);
66                 exit(1);
67         }
68
69         count = 11;
70
71         ret = getgrouplist(user, pwd->pw_gid, gids, &count);
72
73         printf("ret=%d\n", ret);
74
75         if (ret == -1) {
76                 printf("getgrouplist failed\n");
77                 return -1;
78         }
79
80         printf("Got %d groups\n", ret);
81         if (ret != -1) {
82                 for (i=0;i<count;i++) {
83                         printf("%u ", (unsigned)gids[i]);
84                 }
85                 printf("\n");
86         }
87         
88         return 0;
89 }