2008-01-25 16:05:52 +00:00
|
|
|
/* groups -- print the groups a user is in
|
2021-01-01 16:36:09 +00:00
|
|
|
Copyright (C) 1989-2021 Free Software Foundation, Inc.
|
2008-01-25 16:05:52 +00:00
|
|
|
|
|
|
|
|
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 3 of the License, 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
|
2017-09-19 01:13:23 -07:00
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
2008-01-25 16:05:52 +00:00
|
|
|
|
|
|
|
|
/* Written by James Youngman based on id.c and groups.sh,
|
|
|
|
|
which were written by Arnold Robbins and David MacKenzie. */
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <pwd.h>
|
|
|
|
|
#include <grp.h>
|
|
|
|
|
#include <getopt.h>
|
|
|
|
|
|
|
|
|
|
#include "system.h"
|
2016-10-15 23:10:35 +01:00
|
|
|
#include "die.h"
|
2008-01-25 16:05:52 +00:00
|
|
|
#include "group-list.h"
|
2015-10-27 13:13:59 +00:00
|
|
|
#include "quote.h"
|
2008-01-25 16:05:52 +00:00
|
|
|
|
2012-01-08 15:08:30 +01:00
|
|
|
/* The official name of this program (e.g., no 'g' prefix). */
|
2008-01-25 16:05:52 +00:00
|
|
|
#define PROGRAM_NAME "groups"
|
|
|
|
|
|
2008-05-19 16:26:25 +02:00
|
|
|
#define AUTHORS \
|
|
|
|
|
proper_name ("David MacKenzie"), \
|
|
|
|
|
proper_name ("James Youngman")
|
2008-01-25 16:05:52 +00:00
|
|
|
|
|
|
|
|
|
remove redundant const directives
In 1463824d8e7f72c31f1d803d7cfe2b608ccafc5c, I added some
missing "const" directives, as well as some new, redundant ones.
This removes the redundant ones. Pointed out by Eric Blake.
* base64.c, cat.c, chcon.c, chgrp.c, chmod.c, chown.c, comm.c:
* cp.c, csplit.c, cut.c, date.c, dd.c, df.c, dircolors.c, du.c:
* env.c, expand.c, fmt.c, fold.c, groups.c, head.c, id.c:
* install.c, join.c, kill.c, ln.c, ls.c, md5sum.c, mkdir.c:
* mkfifo.c, mknod.c, mktemp.c, mv.c, nice.c, nl.c, od.c:
* paste.c, pathchk.c, pinky.c, pr.c, ptx.c, readlink.c, rm.c:
* rmdir.c, runcon.c, seq.c, shred.c, shuf.c, sort.c, split.c:
* stat.c, stty.c, su.c, sum.c, tac.c, tail.c, tee.c, timeout.c:
* touch.c, tr.c, truncate.c, tty.c, uname.c, unexpand.c, uniq.c:
* wc.c, who.c: Remove redundant const directives.
* maint.mk (sc_const_long_option): Don't require redundant "const".
2008-06-16 14:55:06 +02:00
|
|
|
static struct option const longopts[] =
|
2008-01-25 16:05:52 +00:00
|
|
|
{
|
|
|
|
|
{GETOPT_HELP_OPTION_DECL},
|
|
|
|
|
{GETOPT_VERSION_OPTION_DECL},
|
|
|
|
|
{NULL, 0, NULL, 0}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
usage (int status)
|
|
|
|
|
{
|
|
|
|
|
if (status != EXIT_SUCCESS)
|
2012-01-07 16:54:26 +01:00
|
|
|
emit_try_help ();
|
2008-01-25 16:05:52 +00:00
|
|
|
else
|
|
|
|
|
{
|
2008-08-10 19:39:38 +02:00
|
|
|
printf (_("Usage: %s [OPTION]... [USERNAME]...\n"), program_name);
|
2008-01-25 16:05:52 +00:00
|
|
|
fputs (_("\
|
coreutils: keep lines within 80-column limits
* cfg.mk (LINE_LEN_MAX, FILTER_LONG_LINES): New macros.
(sc_long_lines): New rule.
* HACKING: Use shorter URLs to the same material.
* doc/Makefile.am, doc/coreutils.texi, m4/boottime.m4:
* man/help2man, man/stdbuf.x, src/Makefile.am, src/cat.c, src/copy.c:
* src/cp.c, src/dd.c, src/df.c, src/du.c, src/groups.c, src/install.c:
* src/ls.c, src/md5sum.c, src/mv.c, src/od.c, src/pinky.c, src/ptx.c:
* src/readlink.c, src/remove.c, src/rmdir.c, src/setuidgid.c:
* src/sort.c, src/tail.c, src/touch.c, tests/Coreutils.pm:
* tests/cp/existing-perm-race, tests/cp/perm, tests/cp/preserve-gid:
* tests/du/2g, tests/du/long-from-unreadable, tests/init.sh:
* tests/install/basic-1, tests/ls/nameless-uid:
* tests/ls/readdir-mountpoint-inode, tests/misc/chroot-credentials:
* tests/misc/cut, tests/misc/date, tests/misc/join, tests/misc/md5sum:
* tests/misc/sha1sum, tests/misc/sha224sum, tests/misc/sort:
* tests/misc/sort-continue, tests/misc/sort-files0-from:
* tests/misc/sort-rand, tests/misc/stdbuf, tests/misc/tr:
* tests/misc/uniq, tests/mv/atomic, tests/mv/part-fail:
* tests/mv/part-symlink, tests/mv/sticky-to-xpart, tests/pr/pr-tests:
* tests/rm/fail-2eperm, tests/rm/interactive-always:
Reformat to fit within 80 columns.
* doc/Makefile.am (BAD_POSIX_PERL): New macro.
* doc/coreutils.texi: Reword slightly, to make menus and
index lines shorter.
* src/md5sum.c: Redo --help output so that it fits within 79
columns, since that's a bit more portable and all the other --help
strings fit in 79 columns.
2010-12-28 12:28:48 -08:00
|
|
|
Print group memberships for each USERNAME or, if no USERNAME is specified, for\
|
|
|
|
|
\n\
|
2008-08-10 19:39:38 +02:00
|
|
|
the current process (which may differ if the groups database has changed).\n"),
|
2008-01-25 16:05:52 +00:00
|
|
|
stdout);
|
|
|
|
|
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
|
|
|
|
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
2014-09-18 14:50:47 +01:00
|
|
|
emit_ancillary_info (PROGRAM_NAME);
|
2008-01-25 16:05:52 +00:00
|
|
|
}
|
|
|
|
|
exit (status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
main (int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
int optc;
|
|
|
|
|
bool ok = true;
|
|
|
|
|
gid_t rgid, egid;
|
|
|
|
|
uid_t ruid;
|
|
|
|
|
|
|
|
|
|
initialize_main (&argc, &argv);
|
2008-06-03 08:34:09 +02:00
|
|
|
set_program_name (argv[0]);
|
2008-01-25 16:05:52 +00:00
|
|
|
setlocale (LC_ALL, "");
|
|
|
|
|
bindtextdomain (PACKAGE, LOCALEDIR);
|
|
|
|
|
textdomain (PACKAGE);
|
|
|
|
|
|
|
|
|
|
atexit (close_stdout);
|
|
|
|
|
|
|
|
|
|
/* Processing the arguments this way makes groups.c behave differently to
|
|
|
|
|
* groups.sh if one of the arguments is "--".
|
|
|
|
|
*/
|
|
|
|
|
while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1)
|
|
|
|
|
{
|
|
|
|
|
switch (optc)
|
|
|
|
|
{
|
|
|
|
|
case_GETOPT_HELP_CHAR;
|
|
|
|
|
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
|
|
|
|
default:
|
|
|
|
|
usage (EXIT_FAILURE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optind == argc)
|
|
|
|
|
{
|
|
|
|
|
/* No arguments. Divulge the details of the current process. */
|
2011-11-20 14:08:33 -08:00
|
|
|
uid_t NO_UID = -1;
|
|
|
|
|
gid_t NO_GID = -1;
|
|
|
|
|
|
|
|
|
|
errno = 0;
|
2008-01-25 16:05:52 +00:00
|
|
|
ruid = getuid ();
|
2011-11-20 14:08:33 -08:00
|
|
|
if (ruid == NO_UID && errno)
|
2016-10-15 23:10:35 +01:00
|
|
|
die (EXIT_FAILURE, errno, _("cannot get real UID"));
|
2011-11-20 14:08:33 -08:00
|
|
|
|
|
|
|
|
errno = 0;
|
2008-01-25 16:05:52 +00:00
|
|
|
egid = getegid ();
|
2011-11-20 14:08:33 -08:00
|
|
|
if (egid == NO_GID && errno)
|
2016-10-15 23:10:35 +01:00
|
|
|
die (EXIT_FAILURE, errno, _("cannot get effective GID"));
|
2011-11-20 14:08:33 -08:00
|
|
|
|
|
|
|
|
errno = 0;
|
2008-01-25 16:05:52 +00:00
|
|
|
rgid = getgid ();
|
2011-11-20 14:08:33 -08:00
|
|
|
if (rgid == NO_GID && errno)
|
2016-10-15 23:10:35 +01:00
|
|
|
die (EXIT_FAILURE, errno, _("cannot get real GID"));
|
2008-01-25 16:05:52 +00:00
|
|
|
|
2013-09-21 14:15:45 +02:00
|
|
|
if (!print_group_list (NULL, ruid, rgid, egid, true, ' '))
|
2008-01-25 16:05:52 +00:00
|
|
|
ok = false;
|
2008-01-28 00:08:32 +01:00
|
|
|
putchar ('\n');
|
2008-01-25 16:05:52 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-09-21 14:15:45 +02:00
|
|
|
/* At least one argument. Divulge the details of the specified users. */
|
2017-07-08 13:01:55 +02:00
|
|
|
for ( ; optind < argc; optind++)
|
2008-01-25 16:05:52 +00:00
|
|
|
{
|
|
|
|
|
struct passwd *pwd = getpwnam (argv[optind]);
|
|
|
|
|
if (pwd == NULL)
|
2017-07-08 13:01:55 +02:00
|
|
|
{
|
|
|
|
|
error (0, 0, _("%s: no such user"), quote (argv[optind]));
|
|
|
|
|
ok = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2008-01-25 16:05:52 +00:00
|
|
|
ruid = pwd->pw_uid;
|
|
|
|
|
rgid = egid = pwd->pw_gid;
|
|
|
|
|
|
2008-01-28 00:08:32 +01:00
|
|
|
printf ("%s : ", argv[optind]);
|
2017-07-08 13:01:55 +02:00
|
|
|
if (!print_group_list (argv[optind], ruid, rgid, egid, true, ' '))
|
2008-01-25 16:05:52 +00:00
|
|
|
ok = false;
|
2008-01-28 00:08:32 +01:00
|
|
|
putchar ('\n');
|
2008-01-25 16:05:52 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
maint: prefer 'return status;' to 'exit (status);' in 'main'
* build-aux/gen-single-binary.sh: Don't use ATTRIBUTE_NORETURN
for main functions.
* src/base64.c, src/basename.c, src/cat.c, src/chcon.c, src/chgrp.c:
* src/chmod.c, src/chown.c, src/chroot.c, src/cksum.c, src/comm.c:
* src/cp.c, src/csplit.c, src/cut.c, src/date.c, src/dd.c, src/df.c:
* src/dircolors.c, src/dirname.c, src/du.c, src/echo.c, src/env.c:
* src/expand.c, src/expr.c, src/factor.c, src/fmt.c, src/fold.c:
* src/getlimits.c, src/groups.c, src/head.c, src/hostid.c:
* src/hostname.c, src/id.c, src/install.c, src/join.c, src/kill.c:
* src/link.c, src/ln.c, src/logname.c, src/ls.c, src/make-prime-list.c:
* src/md5sum.c, src/mkdir.c, src/mkfifo.c, src/mknod.c, src/mktemp.c:
* src/mv.c, src/nice.c, src/nl.c, src/nohup.c, src/nproc.c:
* src/numfmt.c, src/od.c, src/paste.c, src/pathchk.c, src/pinky.c:
* src/pr.c, src/printenv.c, src/printf.c, src/ptx.c, src/pwd.c:
* src/readlink.c, src/realpath.c, src/rm.c, src/rmdir.c, src/runcon.c:
* src/seq.c, src/shred.c, src/shuf.c, src/sleep.c, src/sort.c:
* src/split.c, src/stat.c, src/stdbuf.c, src/stty.c, src/sum.c:
* src/sync.c, src/tac.c, src/tail.c, src/tee.c, src/timeout.c:
* src/touch.c, src/tr.c, src/true.c, src/truncate.c, src/tsort.c:
* src/tty.c, src/uname.c, src/unexpand.c, src/uniq.c, src/unlink.c:
* src/uptime.c, src/users.c, src/wc.c, src/who.c, src/whoami.c:
In 'main' functions, Prefer 'return status;' to 'exit (status);'.
* src/coreutils-arch.c (_single_binary_main_uname)
(_single_binary_main_arch):
* src/coreutils-dir.c, src/coreutils-vdir.c (_single_binary_main_ls)
(_single_binary_main_dir, _single_binary_main_vdir):
Omit ATTRIBUTE_NORETURN. Return a value.
* src/coreutils.c (SINGLE_BINARY_PROGRAM): Omit ATTRIBUTE_NORETURN.
(launch_program): Now static.
* src/dd.c (finish_up): New function.
(quit, main): Use it.
* src/getlimits.c (main): Return a proper exit status.
* src/test.c (test_main_return): New macro.
(main): Use it.
* src/logname.c, src/nohup.c, src/whoami.c:
Use 'error' to simplify exit status in 'main' function.
* src/yes.c (main): Use 'return' rather than 'error' to exit,
so that GCC doesn't suggest ATTRIBUTE_NORETURN.
2014-09-08 16:31:14 -07:00
|
|
|
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
2008-01-25 16:05:52 +00:00
|
|
|
}
|