up io error count if not exiting
[tridge/junkcode.git] / getgrouplist2.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
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
54 int main(int argc, char *argv[])
55 {
56         char *user = argv[1];
57         struct passwd *pwd;
58         gid_t gids[NGROUPS_MAX + 1];
59         int count, ret, i;
60
61         pwd = getpwnam(user);
62
63         count = NGROUPS_MAX;
64
65         ret = getgrouplist(user, pwd->pw_gid, gids, &count);
66
67         printf("Got %d groups\n", ret);
68         if (ret != -1) {
69                 for (i=0;i<count;i++) {
70                         printf("%u ", (unsigned)gids[i]);
71                 }
72                 printf("\n");
73         }
74         
75         return 0;
76 }