coreutils/coreutils-5.2.1-runuser.patch

369 lines
12 KiB
Diff
Raw Normal View History

diff -urNp coreutils-7.0.orig/AUTHORS coreutils-7.0/AUTHORS
--- coreutils-7.0.orig/AUTHORS 2008-08-24 22:58:15.000000000 +0200
+++ coreutils-7.0/AUTHORS 2009-01-28 18:11:00.316247411 +0100
@@ -63,6 +63,7 @@ pwd: Jim Meyering
readlink: Dmitry V. Levin
rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering
rmdir: David MacKenzie
+runuser: David MacKenzie, Dan Walsh
runcon: Russell Coker
seq: Ulrich Drepper
sha1sum: Ulrich Drepper, Scott Miller, David Madore
diff -urNp coreutils-7.0.orig/man/Makefile.am coreutils-7.0/man/Makefile.am
--- coreutils-7.0.orig/man/Makefile.am 2008-09-27 19:28:54.000000000 +0200
+++ coreutils-7.0/man/Makefile.am 2009-01-28 18:11:00.317247417 +0100
@@ -93,6 +93,7 @@ readlink.1: $(common_dep) $(srcdir)/read
rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c
rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c
runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c
+runuser.1: $(common_dep) $(srcdir)/runuser.x ../src/su.c
seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c
sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c
sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c
diff -urNp coreutils-7.0.orig/man/runuser.x coreutils-7.0/man/runuser.x
--- coreutils-7.0.orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-7.0/man/runuser.x 2009-01-28 18:11:00.321247443 +0100
@@ -0,0 +1,12 @@
+[NAME]
+runuser \- run a shell with substitute user and group IDs
+[DESCRIPTION]
+.\" Add any additional description here
+[SEE ALSO]
+.TP
+More detailed Texinfo documentation could be found by command
+.TP
+\t\fBinfo su invocation\fR\t
+.TP
+since the command \fBrunuser\fR is trimmed down version of command \fBrunuser\fR.
+.br
diff -urNp coreutils-7.0.orig/README coreutils-7.0/README
--- coreutils-7.0.orig/README 2008-08-24 22:30:10.000000000 +0200
+++ coreutils-7.0/README 2009-01-28 18:11:00.318247424 +0100
@@ -12,10 +12,10 @@ The programs that can be built with this
factor false fmt fold groups head hostid hostname id install join kill
link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup
od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir
- runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf
- sleep sort split stat stty su sum sync tac tail tee test timeout touch tr
- true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc who
- whoami yes
+ runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum shred
+ shuf sleep sort split stat stty su sum sync tac tail tee test timeout touch
+ tr true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc
+ who whoami yes
See the file NEWS for a list of major changes in the current release.
diff -urNp coreutils-7.0.orig/src/Makefile.am coreutils-7.0/src/Makefile.am
--- coreutils-7.0.orig/src/Makefile.am 2009-01-28 18:10:10.756926000 +0100
+++ coreutils-7.0/src/Makefile.am 2009-01-28 18:11:59.658631933 +0100
@@ -38,7 +38,7 @@ EXTRA_PROGRAMS = \
shuf sort split sum tac tail tr tsort unexpand uniq wc \
basename date dirname echo env expr factor false \
id kill logname pathchk printenv printf pwd \
- runcon seq sleep tee \
+ runcon runuser seq sleep tee \
test timeout true truncate tty whoami yes \
base64
@@ -154,6 +154,10 @@ cp_LDADD += $(LIB_ACL) $(LIB_XATTR)
mv_LDADD += $(LIB_ACL) $(LIB_XATTR)
ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR)
+runuser_SOURCES = su.c
+runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\""
+runuser_LDADD = $(LDADD) $(LIB_CRYPT) @LIB_PAM@
+
stat_LDADD = $(LDADD) $(LIB_SELINUX)
# Append $(LIBICONV) to each program that uses proper_name_utf8.
@@ -173,7 +177,7 @@ RELEASE_YEAR = \
`sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \
$(top_srcdir)/lib/version-etc.c`
-all-local: su$(EXEEXT)
+all-local: su$(EXEEXT) runuser
installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'`
diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c
--- coreutils-7.0.orig/src/su.c 2009-01-28 18:10:10.801926000 +0100
+++ coreutils-7.0/src/su.c 2009-01-28 18:11:00.320247437 +0100
@@ -109,9 +109,15 @@
#include "error.h"
/* The official name of this program (e.g., no `g' prefix). */
+#ifndef RUNUSER
#define PROGRAM_NAME "su"
+#else
+#define PROGRAM_NAME "runuser"
+#endif
+#ifndef AUTHORS
#define AUTHORS proper_name ("David MacKenzie")
+#endif
#if HAVE_PATHS_H
# include <paths.h>
@@ -149,6 +155,10 @@
#ifndef USE_PAM
char *crypt ();
#endif
+#ifndef CHECKPASSWD
+#define CHECKPASSWD 1
+#endif
+
char *getusershell ();
void endusershell ();
void setusershell ();
@@ -156,7 +166,11 @@ void setusershell ();
extern char **environ;
static void run_shell (char const *, char const *, char **, size_t,
- const struct passwd *)
+ const struct passwd *
+#ifdef RUNUSER
+ , gid_t *groups, int num_groups
+#endif
+ )
#ifdef USE_PAM
;
#else
@@ -183,6 +197,10 @@ static struct option const longopts[] =
{"login", no_argument, NULL, 'l'},
{"preserve-environment", no_argument, NULL, 'p'},
{"shell", required_argument, NULL, 's'},
+#ifdef RUNUSER
+ {"group", required_argument, NULL, 'g'},
+ {"supp-group", required_argument, NULL, 'G'},
+#endif
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -284,10 +302,12 @@ correct_password (const struct passwd *p
retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh);
PAM_BAIL_P;
+#ifndef RUNUSER
if (getuid() != 0 && !isatty(0)) {
fprintf(stderr, "standard in must be a tty\n");
exit(1);
}
+#endif
caller = getpwuid(getuid());
if(caller != NULL && caller->pw_name != NULL) {
@@ -304,6 +324,11 @@ correct_password (const struct passwd *p
retval = pam_set_item(pamh, PAM_TTY, tty_name);
PAM_BAIL_P;
}
+#ifdef RUNUSER
+ if (getuid() != geteuid())
+ /* safety net: deny operation if we are suid by accident */
+ error(EXIT_FAILURE, 1, "runuser may not be setuid");
+#else
retval = pam_authenticate(pamh, 0);
PAM_BAIL_P;
retval = pam_acct_mgmt(pamh, 0);
@@ -313,6 +338,7 @@ correct_password (const struct passwd *p
PAM_BAIL_P;
}
PAM_BAIL_P;
+#endif
/* must be authenticated if this point was reached */
return 1;
#else /* !USE_PAM */
@@ -394,11 +420,22 @@ modify_environment (const struct passwd
/* Become the user and group(s) specified by PW. */
static void
-change_identity (const struct passwd *pw)
+change_identity (const struct passwd *pw
+#ifdef RUNUSER
+ , gid_t *groups, int num_groups
+#endif
+ )
{
#ifdef HAVE_INITGROUPS
+ int rc = 0;
errno = 0;
- if (initgroups (pw->pw_name, pw->pw_gid) == -1) {
+#ifdef RUNUSER
+ if (num_groups)
+ rc = setgroups(num_groups, groups);
+ else
+#endif
+ rc = initgroups(pw->pw_name, pw->pw_gid);
+ if (rc == -1) {
#ifdef USE_PAM
pam_close_session(pamh, 0);
pam_end(pamh, PAM_ABORT);
@@ -445,7 +482,11 @@ pam_copyenv (pam_handle_t *pamh)
static void
run_shell (char const *shell, char const *command, char **additional_args,
- size_t n_additional_args, const struct passwd *pw)
+ size_t n_additional_args, const struct passwd *pw
+#ifdef RUNUSER
+ , gid_t *groups, int num_groups
+#endif
+ )
{
size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1;
char const **args = xnmalloc (n_args, sizeof *args);
@@ -476,7 +517,11 @@ run_shell (char const *shell, char const
child = fork();
if (child == 0) { /* child shell */
- change_identity (pw);
+ change_identity (pw
+#ifdef RUNUSER
+ , groups, num_groups
+#endif
+ );
pam_end(pamh, 0);
if (!same_session)
setsid ();
@@ -620,6 +665,26 @@ usage (int status)
else
{
printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
+#ifdef RUNUSER
+ fputs (_("\
+Change the effective user id and group id to that of USER. No PAM hooks\n\
+are run, and there will be no password prompt. This command is useful\n\
+when run as the root user. If run as a non-root user without privilege\n\
+to set user ID, the command will fail.\n\
+\n\
+ -, -l, --login make the shell a login shell, uses runuser-l\n\
+ PAM file instead of default one\n\
+ -g --group=group specify the primary group\n\
+ -G --supp-group=group specify a supplemental group\n\
+ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\
+ and do not create a new session\n\
+ -f, --fast pass -f to the shell (for csh or tcsh)\n\
+ -m, --preserve-environment do not reset environment variables\n\
+ -p same as -m\n\
+ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
+"), stdout);
+#else
fputs (_("\
Change the effective user id and group id to that of USER.\n\
\n\
@@ -632,6 +697,7 @@ Change the effective user id and group i
-p same as -m\n\
-s, --shell=SHELL run SHELL if /etc/shells allows it\n\
"), stdout);
+#endif
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
@@ -653,6 +719,12 @@ main (int argc, char **argv)
char *shell = NULL;
struct passwd *pw;
struct passwd pw_copy;
+#ifdef RUNUSER
+ struct group *gr;
+ gid_t groups[NGROUPS_MAX];
+ int num_supp_groups = 0;
+ int use_gid = 0;
+#endif
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -667,7 +739,11 @@ main (int argc, char **argv)
simulate_login = false;
change_environment = true;
- while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "c:flmps:"
+#ifdef RUNUSER
+ "g:G:"
+#endif
+ , longopts, NULL)) != -1)
{
switch (optc)
{
@@ -697,6 +773,28 @@ main (int argc, char **argv)
shell = optarg;
break;
+#ifdef RUNUSER
+ case 'g':
+ gr = getgrnam(optarg);
+ if (!gr)
+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
+ use_gid = 1;
+ groups[0] = gr->gr_gid;
+ break;
+
+ case 'G':
+ num_supp_groups++;
+ if (num_supp_groups >= NGROUPS_MAX)
+ error (EXIT_FAILURE, 0,
+ _("Can't specify more than %d supplemental groups"),
+ NGROUPS_MAX - 1);
+ gr = getgrnam(optarg);
+ if (!gr)
+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
+ groups[num_supp_groups] = gr->gr_gid;
+ break;
+#endif
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -735,7 +833,20 @@ main (int argc, char **argv)
: DEFAULT_SHELL);
endpwent ();
- if (!correct_password (pw))
+#ifdef RUNUSER
+ if (num_supp_groups && !use_gid)
+ {
+ pw->pw_gid = groups[1];
+ memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups);
+ }
+ else if (use_gid)
+ {
+ pw->pw_gid = groups[0];
+ num_supp_groups++;
+ }
+#endif
+
+ if (CHECKPASSWD && !correct_password (pw))
{
#ifdef SYSLOG_FAILURE
log_su (pw, false);
@@ -767,8 +878,16 @@ main (int argc, char **argv)
modify_environment (pw, shell);
#ifndef USE_PAM
- change_identity (pw);
+ change_identity (pw
+#ifdef RUNUSER
+ , groups, num_supp_groups
+#endif
+ );
#endif
- run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw);
+ run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw
+#ifdef RUNUSER
+ , groups, num_supp_groups
+#endif
+ );
}
diff -urNp coreutils-7.0.orig/tests/misc/help-version coreutils-7.0/tests/misc/help-version
--- coreutils-7.0.orig/tests/misc/help-version 2008-09-27 19:28:54.000000000 +0200
+++ coreutils-7.0/tests/misc/help-version 2009-01-28 18:11:00.321247443 +0100
@@ -148,6 +148,7 @@ printf_args=foo
seq_args=10
sleep_args=0
su_args=--version
+runuser_args=--version
timeout_args=--version
# I'd rather not run sync, since it spins up disks that I've