diff options
author | Eric Blake <ebb9@byu.net> | 2009-11-12 10:19:39 -0700 |
---|---|---|
committer | Eric Blake <ebb9@byu.net> | 2009-11-13 07:39:56 -0700 |
commit | 6e4b15b5ee28b52b4a03c74fe8a9ac9bc8a976ea (patch) | |
tree | 60e9911fe45923bfaa4a562268ab26a0979f3ee9 | |
parent | 61b3a42219dc8f575923346b59162f81186b7425 (diff) | |
download | gnulib-6e4b15b5ee28b52b4a03c74fe8a9ac9bc8a976ea.tar.gz |
getgroups: don't expose GETGROUPS_T to user
These days, most systems already declare getgroups with gid_t*.
But in the rare case that GETGROUPS_T is still int but gid_t
is short, the user should not have to uglify their code; let
the replacement hide all the magic.
Tested by configuring with ac_cv_type_getgroups=uint64_t on a
platform with 32-bit gid_t, and ignoring compiler warnings.
However, since we don't replace setgroups, the GETGROUPS_T
workaround is still needed there for now.
* lib/getgroups.c (rpl_getgroups): Change signature. Copy array
an element at a time if GETGROUPS_T is wrong size.
* lib/getugroups.h (getugroups): Change signature.
* lib/unistd.in.h (getgroups): Likewise.
* m4/getgroups.m4 (gl_FUNC_GETGROUPS): Use replacement if
signature needs fixing.
* m4/getugroups.m4 (gl_GETUGROUPS): No longer need
AC_TYPE_GETGROUPS.
* modules/group-member (Depends-on): Add getgroups.
* lib/group-member.c (group_info, get_group_info): Use gid_t.
(group_member): Rely on getgroups replacement.
* lib/getugroups.c (getugroups): Use gid_t.
* tests/test-getgroups.c (main): Likewise.
* NEWS: Mention the signature change.
* doc/posix-functions/getgroups.texi (getgroups): Mention the
problem with signature.
* doc/glibc-functions/setgroups.texi (setgroups): Mention that
GETGROUPS_T is still useful for setgroups.
Signed-off-by: Eric Blake <ebb9@byu.net>
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | doc/glibc-functions/setgroups.texi | 6 | ||||
-rw-r--r-- | doc/posix-functions/getgroups.texi | 3 | ||||
-rw-r--r-- | lib/getgroups.c | 34 | ||||
-rw-r--r-- | lib/getugroups.c | 2 | ||||
-rw-r--r-- | lib/getugroups.h | 6 | ||||
-rw-r--r-- | lib/group-member.c | 29 | ||||
-rw-r--r-- | lib/unistd.in.h | 2 | ||||
-rw-r--r-- | m4/getgroups.m4 | 5 | ||||
-rw-r--r-- | m4/getugroups.m4 | 5 | ||||
-rw-r--r-- | modules/group-member | 1 | ||||
-rw-r--r-- | tests/test-getgroups.c | 2 |
13 files changed, 87 insertions, 32 deletions
@@ -1,5 +1,25 @@ 2009-11-13 Eric Blake <ebb9@byu.net> + getgroups: don't expose GETGROUPS_T to user + * lib/getgroups.c (rpl_getgroups): Change signature. Copy array + an element at a time if GETGROUPS_T is wrong size. + * lib/getugroups.h (getugroups): Change signature. + * lib/unistd.in.h (getgroups): Likewise. + * m4/getgroups.m4 (gl_FUNC_GETGROUPS): Use replacement if + signature needs fixing. + * m4/getugroups.m4 (gl_GETUGROUPS): No longer need + AC_TYPE_GETGROUPS. + * modules/group-member (Depends-on): Add getgroups. + * lib/group-member.c (group_info, get_group_info): Use gid_t. + (group_member): Rely on getgroups replacement. + * lib/getugroups.c (getugroups): Use gid_t. + * tests/test-getgroups.c (main): Likewise. + * NEWS: Mention the signature change. + * doc/posix-functions/getgroups.texi (getgroups): Mention the + problem with signature. + * doc/glibc-functions/setgroups.texi (setgroups): Mention that + GETGROUPS_T is still useful for setgroups. + getgroups, getugroups: provide stubs for mingw * lib/getgroups.c (getgroups): Provide ENOSYS stub for mingw. * lib/getugroups.c (getugroups): Likewise. @@ -6,6 +6,10 @@ User visible incompatible changes Date Modules Changes +2009-11-12 getgroups These functions now use a signature of gid_t, + getugroups rather than GETGROUPS_T. This probably has no + effect except on very old platforms. + 2009-11-04 tempname The gen_tempname function takes an additional 'suffixlen' argument. You can safely pass 0. diff --git a/doc/glibc-functions/setgroups.texi b/doc/glibc-functions/setgroups.texi index 1b3e6fed9a..bcbd841577 100644 --- a/doc/glibc-functions/setgroups.texi +++ b/doc/glibc-functions/setgroups.texi @@ -13,4 +13,10 @@ Portability problems not fixed by Gnulib: @item This function is missing on some platforms: AIX 5.1, mingw, Interix 3.5, BeOS. +@item +On very old systems, this function operated on an array of @samp{int}, +even though that was a different size than an array of @samp{gid_t}; +you can use autoconf's AC_TYPE_GETGROUPS to set @code{GETGROUPS_T} to +the appropriate size (since @code{getgroups} and @code{setgroups} +share the same bug). @end itemize diff --git a/doc/posix-functions/getgroups.texi b/doc/posix-functions/getgroups.texi index 951705e8a5..745210e854 100644 --- a/doc/posix-functions/getgroups.texi +++ b/doc/posix-functions/getgroups.texi @@ -14,6 +14,9 @@ mingw. @item On Ultrix 4.3, @code{getgroups (0, 0)} always fails. See macro @samp{AC_FUNC_GETGROUPS}. +@item +On very old systems, this function operated on an array of @samp{int}, +even though that was a different size than an array of @samp{gid_t}. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/getgroups.c b/lib/getgroups.c index bad676ea5e..e4540fe9b7 100644 --- a/lib/getgroups.c +++ b/lib/getgroups.c @@ -48,14 +48,44 @@ getgroups (int n _UNUSED_PARAMETER_, GETGROUPS_T *groups _UNUSED_PARAMETER_) whether the effective group id is included in the list. */ int -rpl_getgroups (int n, GETGROUPS_T *group) +rpl_getgroups (int n, gid_t *group) { int n_groups; GETGROUPS_T *gbuf; int saved_errno; if (n != 0) - return getgroups (n, group); + { + int result; + int saved_errno; + if (sizeof *group == sizeof *gbuf) + return getgroups (n, (GETGROUPS_T *) group); + + if (n < 0) + { + errno = EINVAL; + return -1; + } + if (SIZE_MAX / sizeof *gbuf <= n) + { + errno = ENOMEM; + return -1; + } + gbuf = malloc (n * sizeof *gbuf); + if (!gbuf) + return -1; + result = getgroups (n, gbuf); + if (0 <= result) + { + n = result; + while (n--) + group[n] = gbuf[n]; + } + saved_errno = errno; + free (gbuf); + errno == saved_errno; + return result; + } n = 20; while (1) diff --git a/lib/getugroups.c b/lib/getugroups.c index a614ec7be3..8605ab1a1b 100644 --- a/lib/getugroups.c +++ b/lib/getugroups.c @@ -55,7 +55,7 @@ getugroups (int maxcount _UNUSED_PARAMETER_, Otherwise, return the number of IDs we've written into GROUPLIST. */ int -getugroups (int maxcount, GETGROUPS_T *grouplist, char const *username, +getugroups (int maxcount, gid_t *grouplist, char const *username, gid_t gid) { int count = 0; diff --git a/lib/getugroups.h b/lib/getugroups.h index f2914add7f..cbaa6640aa 100644 --- a/lib/getugroups.h +++ b/lib/getugroups.h @@ -1,5 +1,5 @@ /* Get a list of group IDs associated with a specified user ID. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,5 +15,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <sys/types.h> -int getugroups (int maxcount, GETGROUPS_T *grouplist, char const *username, - gid_t gid); +int getugroups (int maxcount, gid_t *grouplist, char const *username, + gid_t gid); diff --git a/lib/group-member.c b/lib/group-member.c index a34efc04af..7934c0a33d 100644 --- a/lib/group-member.c +++ b/lib/group-member.c @@ -1,6 +1,6 @@ /* group-member.c -- determine whether group id is in calling user's group list - Copyright (C) 1994, 1997, 1998, 2003, 2005, 2006 Free Software + Copyright (C) 1994, 1997, 1998, 2003, 2005, 2006, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -32,11 +32,9 @@ struct group_info { int n_groups; - GETGROUPS_T *group; + gid_t *group; }; -#if HAVE_GETGROUPS - static void free_group_info (struct group_info const *g) { @@ -48,7 +46,7 @@ get_group_info (struct group_info *gi) { int n_groups; int n_group_slots = getgroups (0, NULL); - GETGROUPS_T *group; + gid_t *group; if (n_group_slots < 0) return false; @@ -72,18 +70,14 @@ get_group_info (struct group_info *gi) return true; } -#endif /* not HAVE_GETGROUPS */ - /* Return non-zero if GID is one that we have in our groups list. - If there is no getgroups function, return non-zero if GID matches - either of the current or effective group IDs. */ + Note that the groups list is not guaranteed to contain the current + or effective group ID, so they should generally be checked + separately. */ int group_member (gid_t gid) { -#ifndef HAVE_GETGROUPS - return ((gid == getgid ()) || (gid == getegid ())); -#else int i; int found; struct group_info gi; @@ -96,16 +90,15 @@ group_member (gid_t gid) for (i = 0; i < gi.n_groups; i++) { if (gid == gi.group[i]) - { - found = 1; - break; - } + { + found = 1; + break; + } } free_group_info (&gi); return found; -#endif /* HAVE_GETGROUPS */ } #ifdef TEST @@ -119,7 +112,7 @@ main (int argc, char **argv) program_name = argv[0]; - for (i=1; i<argc; i++) + for (i = 1; i < argc; i++) { gid_t gid; diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 90494e4d1d..c3219872d8 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -417,7 +417,7 @@ extern int getdtablesize (void); If N is 0, return the group count; otherwise, N describes how many entries are available in GROUPS. Return -1 and set errno if N is not 0 and not large enough. Fails with ENOSYS on some systems. */ -int getgroups (int n, GETGROUPS_T *groups); +int getgroups (int n, gid_t *groups); # endif #elif defined GNULIB_POSIXCHECK # undef getgroups diff --git a/m4/getgroups.m4 b/m4/getgroups.m4 index 1dd39eacce..4d9671247f 100644 --- a/m4/getgroups.m4 +++ b/m4/getgroups.m4 @@ -1,4 +1,4 @@ -# serial 13 +# serial 14 dnl From Jim Meyering. dnl A wrapper around AC_FUNC_GETGROUPS. @@ -17,7 +17,8 @@ AC_DEFUN([gl_FUNC_GETGROUPS], if test "$ac_cv_func_getgroups" != yes; then AC_LIBOBJ([getgroups]) HAVE_GETGROUPS=0 - elif test "$ac_cv_func_getgroups_works" != yes; then + elif test "$ac_cv_func_getgroups_works.$ac_cv_type_getgroups" != yes.gid_t + then AC_LIBOBJ([getgroups]) REPLACE_GETGROUPS=1 fi diff --git a/m4/getugroups.m4 b/m4/getugroups.m4 index e437e1ba3a..d311f77f69 100644 --- a/m4/getugroups.m4 +++ b/m4/getugroups.m4 @@ -1,4 +1,4 @@ -# getugroups.m4 serial 7 +# getugroups.m4 serial 8 dnl Copyright (C) 2002, 2003, 2005, 2006, 2009 Free Software dnl Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -9,7 +9,4 @@ AC_DEFUN([gl_GETUGROUPS], [ AC_LIBOBJ([getugroups]) AC_CHECK_HEADERS_ONCE([grp.h]) - - dnl Prerequisites of lib/getugroups.c. - AC_TYPE_GETGROUPS ]) diff --git a/modules/group-member b/modules/group-member index 45c8bd5607..20075dd6d4 100644 --- a/modules/group-member +++ b/modules/group-member @@ -8,6 +8,7 @@ m4/group-member.m4 Depends-on: extensions +getgroups xalloc stdbool diff --git a/tests/test-getgroups.c b/tests/test-getgroups.c index 5324df1150..ffa873f2e2 100644 --- a/tests/test-getgroups.c +++ b/tests/test-getgroups.c @@ -40,7 +40,7 @@ int main (int argc, char **argv _UNUSED_PARAMETER_) { int result; - GETGROUPS_T *groups; + gid_t *groups; errno = 0; result = getgroups (0, NULL); |