1 |
diff --git a/lib/getugroups.c b/lib/getugroups.c |
2 |
index 299bae6..8ece29b 100644 |
3 |
--- a/lib/getugroups.c |
4 |
+++ b/lib/getugroups.c |
5 |
@@ -19,6 +19,9 @@ |
6 |
|
7 |
#include <config.h> |
8 |
|
9 |
+/* We do not need this code if getgrouplist(3) is available. */ |
10 |
+#ifndef HAVE_GETGROUPLIST |
11 |
+ |
12 |
#include "getugroups.h" |
13 |
|
14 |
#include <errno.h> |
15 |
@@ -123,3 +126,4 @@ getugroups (int maxcount, gid_t *grouplist, char const *username, |
16 |
} |
17 |
|
18 |
#endif /* HAVE_GRP_H */ |
19 |
+#endif /* have getgrouplist */ |
20 |
diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c |
21 |
index 76474c2..0a9d221 100644 |
22 |
--- a/lib/mgetgroups.c |
23 |
+++ b/lib/mgetgroups.c |
24 |
@@ -115,9 +115,17 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) |
25 |
/* else no username, so fall through and use getgroups. */ |
26 |
#endif |
27 |
|
28 |
- max_n_groups = (username |
29 |
- ? getugroups (0, NULL, username, gid) |
30 |
- : getgroups (0, NULL)); |
31 |
+ if (!username) |
32 |
+ max_n_groups = getgroups(0, NULL); |
33 |
+ else |
34 |
+ { |
35 |
+#ifdef HAVE_GETGROUPLIST |
36 |
+ max_n_groups = 0; |
37 |
+ getgrouplist (username, gid, NULL, &max_n_groups); |
38 |
+#else |
39 |
+ max_n_groups = getugroups (0, NULL, username, gid); |
40 |
+#endif |
41 |
+ } |
42 |
|
43 |
/* If we failed to count groups because there is no supplemental |
44 |
group support, then return an array containing just GID. |
45 |
@@ -139,10 +147,25 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) |
46 |
if (g == NULL) |
47 |
return -1; |
48 |
|
49 |
- ng = (username |
50 |
- ? getugroups (max_n_groups, g, username, gid) |
51 |
- : getgroups (max_n_groups - (gid != (gid_t) -1), |
52 |
- g + (gid != (gid_t) -1))); |
53 |
+ if (!username) |
54 |
+ ng = getgroups (max_n_groups - (gid != (gid_t)-1), g + (gid != (gid_t)-1)); |
55 |
+ else |
56 |
+ { |
57 |
+#ifdef HAVE_GETGROUPLIST |
58 |
+ int e; |
59 |
+ ng = max_n_groups; |
60 |
+ while ((e = getgrouplist (username, gid, g, &ng)) == -1 |
61 |
+ && ng > max_n_groups) |
62 |
+ { |
63 |
+ max_n_groups = ng; |
64 |
+ g = xrealloc (g, max_n_groups * sizeof (GETGROUPS_T)); |
65 |
+ } |
66 |
+ if (e == -1) |
67 |
+ ng = -1; |
68 |
+#else |
69 |
+ ng = getugroups (max_n_groups, g, username, gid); |
70 |
+#endif |
71 |
+ } |
72 |
|
73 |
if (ng < 0) |
74 |
{ |
75 |
diff --git a/m4/jm-macros.m4 b/m4/jm-macros.m4 |
76 |
index 62777c7..5180243 100644 |
77 |
--- a/m4/jm-macros.m4 |
78 |
+++ b/m4/jm-macros.m4 |
79 |
@@ -78,6 +78,7 @@ AC_DEFUN([coreutils_MACROS], |
80 |
fchown \ |
81 |
fchmod \ |
82 |
ftruncate \ |
83 |
+ getgrouplist \ |
84 |
iswspace \ |
85 |
mkfifo \ |
86 |
mbrlen \ |