mirror of
https://https.git.savannah.gnu.org/git/coreutils.git
synced 2026-01-27 01:44:21 +00:00
setuidgid: set all groups, not just the primary one; mgetgroups: new module
I wanted to use the xgetgroups function from id.c, so factored it out and made it into a non-exiting function (hence the "m" prefix rather than "x"). * src/setuidgid.c (main): Use mgetgroups. Include "mgetgroups.h". * src/id.c (xgetgroups): Remove function. Include "mgetgroups.h". (print_group_list): Use mgetgroups, not xgetgroups. * gl/modules/mgetgroups: New module. * gl/lib/mgetgroups.c: New file. mgetgroups is derived from id.c's xgetgroups function. * bootstrap.conf (gnulib_modules): Add mgetgroups. * gl/m4/mgetgroups.m4: New file. * gl/lib/mgetgroups.h: New file.
This commit is contained in:
parent
b8031ff7c7
commit
e0066f36c2
18
ChangeLog
18
ChangeLog
@ -1,5 +1,23 @@
|
||||
2007-07-05 Jim Meyering <jim@meyering.net>
|
||||
|
||||
setuidgid: set all groups, not just the primary one.
|
||||
I wanted to use the xgetgroups function from id.c, so factored
|
||||
it out and made it into a non-exiting function (hence the "m"
|
||||
prefix rather than "x").
|
||||
* src/setuidgid.c (main): Use mgetgroups.
|
||||
Include "mgetgroups.h".
|
||||
|
||||
* src/id.c (xgetgroups): Remove function.
|
||||
Include "mgetgroups.h".
|
||||
(print_group_list): Use mgetgroups, not xgetgroups.
|
||||
|
||||
* gl/modules/mgetgroups: New module.
|
||||
* gl/lib/mgetgroups.c: New file. mgetgroups is derived from
|
||||
id.c's xgetgroups function.
|
||||
* bootstrap.conf (gnulib_modules): Add mgetgroups.
|
||||
* gl/m4/mgetgroups.m4: New file.
|
||||
* gl/lib/mgetgroups.h: New file.
|
||||
|
||||
* bootstrap: Merge in changes from gnulib.
|
||||
|
||||
* src/id.c: Include "getugroups.h" rather than declaring manually.
|
||||
|
||||
@ -60,7 +60,8 @@ gnulib_modules="
|
||||
inttostr inttypes isapipe
|
||||
lchmod lchown lib-ignore linebuffer link-follow
|
||||
long-options lstat malloc mbswidth memcasecmp mempcpy
|
||||
memrchr mkancesdirs mkdir mkdir-p mkstemp mktime modechange
|
||||
memrchr mgetgroups
|
||||
mkancesdirs mkdir mkdir-p mkstemp mktime modechange
|
||||
mountlist mpsort obstack pathmax perl physmem posixtm posixver putenv
|
||||
quote quotearg raise readlink mreadlink-with-size readtokens
|
||||
readtokens0 readutmp
|
||||
|
||||
80
gl/lib/mgetgroups.c
Normal file
80
gl/lib/mgetgroups.c
Normal file
@ -0,0 +1,80 @@
|
||||
/* getugroups.c -- return a list of the groups a user is in
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation.
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Extracted from coreutils' src/id.c. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "mgetgroups.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "getugroups.h"
|
||||
#include "xalloc.h"
|
||||
|
||||
/* Like getugroups, but store the result in malloc'd storage.
|
||||
Set *GROUPS to the malloc'd list of all group IDs of which USERNAME
|
||||
is a member. If GID is not -1, store it first. GID should be the
|
||||
group ID (pw_gid) obtained from getpwuid, in case USERNAME is not
|
||||
listed in the groups database (e.g., /etc/groups). Upon failure,
|
||||
don't modify *GROUPS, set errno, and return -1. Otherwise, return
|
||||
the number of groups. */
|
||||
|
||||
int
|
||||
mgetgroups (const char *username, gid_t gid, GETGROUPS_T **groups)
|
||||
{
|
||||
int max_n_groups;
|
||||
int ng;
|
||||
GETGROUPS_T *g;
|
||||
|
||||
max_n_groups = (username
|
||||
? getugroups (0, NULL, username, gid)
|
||||
: getgroups (0, NULL));
|
||||
|
||||
/* If we failed to count groups with NULL for a buffer,
|
||||
try again with a non-NULL one, just in case. */
|
||||
if (max_n_groups < 0)
|
||||
max_n_groups = 5;
|
||||
|
||||
if (xalloc_oversized (max_n_groups, sizeof *g))
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
g = malloc (max_n_groups * sizeof *g);
|
||||
if (g == NULL)
|
||||
return -1;
|
||||
|
||||
ng = (username
|
||||
? getugroups (max_n_groups, g, username, gid)
|
||||
: getgroups (max_n_groups, g));
|
||||
|
||||
if (ng < 0)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
free (g);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*groups = g;
|
||||
return ng;
|
||||
}
|
||||
21
gl/lib/mgetgroups.h
Normal file
21
gl/lib/mgetgroups.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* Get a list of all group IDs associated with a specified user ID.
|
||||
Copyright (C) 2007 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
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int mgetgroups (const char *username, gid_t gid, GETGROUPS_T **groups);
|
||||
10
gl/m4/mgetgroups.m4
Normal file
10
gl/m4/mgetgroups.m4
Normal file
@ -0,0 +1,10 @@
|
||||
#serial 1
|
||||
dnl Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
AC_DEFUN([gl_MGETGROUPS],
|
||||
[
|
||||
AC_LIBOBJ([mgetgroups])
|
||||
])
|
||||
25
gl/modules/mgetgroups
Normal file
25
gl/modules/mgetgroups
Normal file
@ -0,0 +1,25 @@
|
||||
Description:
|
||||
Return the group IDs of a user in malloc'd storage.
|
||||
|
||||
Files:
|
||||
lib/mgetgroups.c
|
||||
lib/mgetgroups.h
|
||||
m4/mgetgroups.m4
|
||||
|
||||
Depends-on:
|
||||
free
|
||||
getugroups
|
||||
xalloc
|
||||
|
||||
configure.ac:
|
||||
gl_MGETGROUPS
|
||||
|
||||
Makefile.am:
|
||||
|
||||
Include:
|
||||
|
||||
License:
|
||||
LGPL
|
||||
|
||||
Maintainer:
|
||||
Jim Meyering
|
||||
@ -151,6 +151,7 @@ gettext.h
|
||||
gettime.c
|
||||
gettimeofday.c
|
||||
getugroups.c
|
||||
getugroups.h
|
||||
getusershell.c
|
||||
gnulib.mk
|
||||
group-member.c
|
||||
@ -218,6 +219,8 @@ memmove.c
|
||||
mempcpy.c
|
||||
memrchr.c
|
||||
memset.c
|
||||
mgetgroups.c
|
||||
mgetgroups.h
|
||||
mkancesdirs.c
|
||||
mkancesdirs.h
|
||||
mkdir-p.c
|
||||
|
||||
3
lib/.gitignore
vendored
3
lib/.gitignore
vendored
@ -144,6 +144,7 @@ gettext.h
|
||||
gettime.c
|
||||
gettimeofday.c
|
||||
getugroups.c
|
||||
getugroups.h
|
||||
getusershell.c
|
||||
gnulib.mk
|
||||
group-member.c
|
||||
@ -212,6 +213,8 @@ memmove.c
|
||||
mempcpy.c
|
||||
memrchr.c
|
||||
memset.c
|
||||
mgetgroups.c
|
||||
mgetgroups.h
|
||||
mkancesdirs.c
|
||||
mkancesdirs.h
|
||||
mkdir-p.c
|
||||
|
||||
@ -144,6 +144,7 @@ memmove.m4
|
||||
mempcpy.m4
|
||||
memrchr.m4
|
||||
memset.m4
|
||||
mgetgroups.m4
|
||||
mkancesdirs.m4
|
||||
mkdir-p.m4
|
||||
mkdir-slash.m4
|
||||
|
||||
2
m4/.gitignore
vendored
2
m4/.gitignore
vendored
@ -92,6 +92,7 @@ iconv.m4
|
||||
iconv_h.m4
|
||||
iconv_open.m4
|
||||
idcache.m4
|
||||
include_next.m4
|
||||
inet_ntop.m4
|
||||
inline.m4
|
||||
intl.m4
|
||||
@ -138,6 +139,7 @@ memmove.m4
|
||||
mempcpy.m4
|
||||
memrchr.m4
|
||||
memset.m4
|
||||
mgetgroups.m4
|
||||
mkancesdirs.m4
|
||||
mkdir-p.m4
|
||||
mkdir-slash.m4
|
||||
|
||||
65
src/id.c
65
src/id.c
@ -30,6 +30,7 @@
|
||||
#include "system.h"
|
||||
#include "error.h"
|
||||
#include "getugroups.h"
|
||||
#include "mgetgroups.h"
|
||||
#include "quote.h"
|
||||
|
||||
/* The official name of this program (e.g., no `g' prefix). */
|
||||
@ -278,50 +279,6 @@ print_group (gid_t gid)
|
||||
printf ("%s", grp->gr_name);
|
||||
}
|
||||
|
||||
#if HAVE_GETGROUPS
|
||||
|
||||
/* FIXME: document */
|
||||
|
||||
static bool
|
||||
xgetgroups (const char *username, gid_t gid, int *n_groups,
|
||||
GETGROUPS_T **groups)
|
||||
{
|
||||
int max_n_groups;
|
||||
int ng;
|
||||
GETGROUPS_T *g = NULL;
|
||||
|
||||
if (!username)
|
||||
max_n_groups = getgroups (0, NULL);
|
||||
else
|
||||
max_n_groups = getugroups (0, NULL, username, gid);
|
||||
|
||||
if (max_n_groups < 0)
|
||||
ng = -1;
|
||||
else
|
||||
{
|
||||
g = xnmalloc (max_n_groups, sizeof *g);
|
||||
if (!username)
|
||||
ng = getgroups (max_n_groups, g);
|
||||
else
|
||||
ng = getugroups (max_n_groups, g, username, gid);
|
||||
}
|
||||
|
||||
if (ng < 0)
|
||||
{
|
||||
error (0, errno, _("cannot get supplemental group list"));
|
||||
free (g);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*n_groups = ng;
|
||||
*groups = g;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_GETGROUPS */
|
||||
|
||||
/* Print all of the distinct groups the user is in. */
|
||||
|
||||
static void
|
||||
@ -342,13 +299,15 @@ print_group_list (const char *username)
|
||||
|
||||
#if HAVE_GETGROUPS
|
||||
{
|
||||
int n_groups;
|
||||
GETGROUPS_T *groups;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
if (! xgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
|
||||
&n_groups, &groups))
|
||||
int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
|
||||
&groups);
|
||||
if (n_groups < 0)
|
||||
{
|
||||
error (0, errno, _("failed to get groups for user %s"),
|
||||
quote (username));
|
||||
ok = false;
|
||||
return;
|
||||
}
|
||||
@ -400,13 +359,15 @@ print_full_info (const char *username)
|
||||
|
||||
#if HAVE_GETGROUPS
|
||||
{
|
||||
int n_groups;
|
||||
GETGROUPS_T *groups;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
if (! xgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
|
||||
&n_groups, &groups))
|
||||
int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
|
||||
&groups);
|
||||
if (n_groups < 0)
|
||||
{
|
||||
error (0, errno, _("failed to get groups for user %s"),
|
||||
quote (username));
|
||||
ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* setuidgid - run a command with the UID and GID of a specified user
|
||||
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003-2007 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
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
#include "error.h"
|
||||
#include "long-options.h"
|
||||
#include "mgetgroups.h"
|
||||
#include "quote.h"
|
||||
|
||||
#define PROGRAM_NAME "setuidgid"
|
||||
@ -105,8 +106,21 @@ main (int argc, char **argv)
|
||||
_("unknown user-ID: %s"), quote (user_id));
|
||||
|
||||
#if HAVE_SETGROUPS
|
||||
if (setgroups (1, &pwd->pw_gid))
|
||||
error (SETUIDGID_FAILURE, errno, _("cannot set supplemental group"));
|
||||
{
|
||||
GETGROUPS_T *groups;
|
||||
int n_groups = mgetgroups (user_id, pwd->pw_gid, &groups);
|
||||
if (n_groups < 0)
|
||||
{
|
||||
n_groups = 1;
|
||||
groups = xmalloc (sizeof *groups);
|
||||
*groups = pwd->pw_gid;
|
||||
}
|
||||
|
||||
if (0 < n_groups && setgroups (n_groups, groups))
|
||||
error (SETUIDGID_FAILURE, errno, _("cannot set supplemental group(s)"));
|
||||
|
||||
free (groups);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setgid (pwd->pw_gid))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user