mirror of
https://github.com/coreutils/coreutils.git
synced 2024-12-24 09:15:12 +08:00
New program, solely for testing (not installed).
This commit is contained in:
parent
477fd9c12e
commit
d743e47970
136
src/setuidgid.c
Normal file
136
src/setuidgid.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* setuidgid - run a command with the UID and GID of a specified user
|
||||
Copyright (C) 2003 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; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Written by Jim Meyering */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "closeout.h"
|
||||
#include "error.h"
|
||||
#include "long-options.h"
|
||||
#include "quote.h"
|
||||
|
||||
#define PROGRAM_NAME "setuidgid"
|
||||
|
||||
/* I wrote this program from scratch, based on the description of
|
||||
D.J. Bernstein's program: http://cr.yp.to/daemontools/setuidgid.html. */
|
||||
#define AUTHORS "Jim Meyering"
|
||||
|
||||
#define FAIL_STATUS 111
|
||||
|
||||
char *program_name;
|
||||
|
||||
void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != 0)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s USERNAME COMMAND [ARGUMENT]...\n\
|
||||
or: %s OPTION\n\
|
||||
"),
|
||||
program_name, program_name);
|
||||
|
||||
fputs (_("\
|
||||
Drop any supplemental groups, assume the user-ID and group-ID of\n\
|
||||
the specified USERNAME, and run COMMAND with any specified ARGUMENTs.\n\
|
||||
Exit with status 111 if unable to assume the required UID and GID.\n\
|
||||
Otherwise, exit with the exit status of COMMAND.\n\
|
||||
This program is useful only when run by root (UID=0).\n\
|
||||
\n\
|
||||
"), stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char const *user_id;
|
||||
struct passwd *pwd;
|
||||
|
||||
initialize_main (&argc, &argv);
|
||||
program_name = argv[0];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
atexit (close_stdout);
|
||||
|
||||
parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
|
||||
AUTHORS, usage);
|
||||
|
||||
/* The above handles --help and --version.
|
||||
Since there is no other invocation of getopt, handle `--' here. */
|
||||
if (argc > 1 && STREQ (argv[1], "--"))
|
||||
{
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
|
||||
if (argc <= 2)
|
||||
{
|
||||
error (0, 0, _("too few arguments"));
|
||||
usage (FAIL_STATUS);
|
||||
}
|
||||
|
||||
user_id = argv[1];
|
||||
pwd = getpwnam (user_id);
|
||||
if (pwd == NULL)
|
||||
{
|
||||
error (0, errno, _("unknown user-ID: %s"), quote (user_id));
|
||||
exit (FAIL_STATUS);
|
||||
}
|
||||
|
||||
if (setgroups (1, &pwd->pw_gid))
|
||||
{
|
||||
error (0, errno, _("cannot set supplemental group"));
|
||||
exit (FAIL_STATUS);
|
||||
}
|
||||
|
||||
if (setgid (pwd->pw_gid))
|
||||
{
|
||||
error (0, errno, _("cannot set group-ID to %ld"), (long) pwd->pw_gid);
|
||||
exit (FAIL_STATUS);
|
||||
}
|
||||
|
||||
if (setuid (pwd->pw_uid))
|
||||
{
|
||||
error (0, errno, _("cannot set user-ID to %ld"), (long) pwd->pw_uid);
|
||||
exit (FAIL_STATUS);
|
||||
}
|
||||
|
||||
{
|
||||
char **cmd = argv + 2;
|
||||
execvp (*cmd, cmd);
|
||||
|
||||
error (0, errno, "could not run command %s", quote (*cmd));
|
||||
exit (FAIL_STATUS);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user