diff -urNp coreutils-8.7-orig/README coreutils-8.7/README --- coreutils-8.7-orig/README 2010-10-11 19:35:11.000000000 +0200 +++ coreutils-8.7/README 2010-11-15 10:10:43.002922253 +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 nproc od paste pathchk pinky pr printenv printf ptx pwd readlink realpath - rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred - shuf sleep sort split stat stdbuf 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 + rm rmdir runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum + shred shuf sleep sort split stat stdbuf 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-8.7-orig/AUTHORS coreutils-8.7/AUTHORS --- coreutils-8.7-orig/AUTHORS 2010-10-11 19:35:11.000000000 +0200 +++ coreutils-8.7/AUTHORS 2010-11-15 10:08:04.222078001 +0100 @@ -65,6 +65,7 @@ readlink: Dmitry V. Levin rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering rmdir: David MacKenzie runcon: Russell Coker +runuser: David MacKenzie, Dan Walsh seq: Ulrich Drepper sha1sum: Ulrich Drepper, Scott Miller, David Madore sha224sum: Ulrich Drepper, Scott Miller, David Madore diff -urNp coreutils-8.7-orig/man/help2man coreutils-8.7/man/help2man --- coreutils-8.7-orig/man/help2man 2010-10-11 19:35:11.000000000 +0200 +++ coreutils-8.7/man/help2man 2010-11-15 10:08:51.331054884 +0100 @@ -555,6 +555,9 @@ while (length) $include{$sect} .= $content; } +# There is no info documentation for runuser (shared with su). +$opt_no_info = 1 if $program eq 'runuser'; + # Refer to the real documentation. unless ($opt_no_info) { --- coreutils-6.7/src/su.c.runuser 2007-01-09 17:27:56.000000000 +0000 +++ coreutils-6.7/src/su.c 2007-01-09 17:30:12.000000000 +0000 @@ -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 @@ -149,6 +149,10 @@ char *crypt (char const *key, char const *salt); #endif +#ifndef CHECKPASSWD +#define CHECKPASSWD 1 +#endif + static void run_shell (char const *, char const *, char **, size_t, const struct passwd *) #ifdef USE_PAM @@ -154,7 +154,11 @@ #endif 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 @@ -187,6 +201,10 @@ {"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} @@ -288,10 +306,12 @@ 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) { @@ -308,6 +328,11 @@ 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); @@ -317,6 +342,7 @@ PAM_BAIL_P; } PAM_BAIL_P; +#endif /* must be authenticated if this point was reached */ return 1; #else /* !USE_PAM */ @@ -398,11 +424,22 @@ /* 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); @@ -449,7 +486,11 @@ 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); @@ -480,7 +521,11 @@ 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 (); @@ -657,6 +702,12 @@ 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); program_name = argv[0]; @@ -671,7 +722,11 @@ 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) { @@ -701,6 +756,28 @@ 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); @@ -739,7 +816,20 @@ : 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); @@ -814,7 +814,11 @@ modify_environment (pw, shell); #ifndef USE_PAM - change_identity (pw); + change_identity (pw +#ifdef RUNUSER + , groups, num_supp_groups +#endif + ); #endif /* error() flushes stderr, but does not check for write failure. @@ -825,5 +829,9 @@ if (ferror (stderr)) exit (EXIT_CANCELED); - 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-8.7-orig/src/Makefile.am coreutils-8.7/src/Makefile.am --- coreutils-8.7-orig/src/Makefile.am 2010-11-15 10:07:07.339171659 +0100 +++ coreutils-8.7/src/Makefile.am 2010-11-15 10:12:14.847094550 +0100 @@ -100,6 +100,7 @@ EXTRA_PROGRAMS = \ rm \ rmdir \ runcon \ + runuser \ seq \ sha1sum \ sha224sum \ @@ -300,6 +301,10 @@ cp_LDADD += $(copy_LDADD) ginstall_LDADD += $(copy_LDADD) mv_LDADD += $(copy_LDADD) +runuser_SOURCES = su.c +runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\"" +runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(LIB_PAM) + remove_LDADD = mv_LDADD += $(remove_LDADD) rm_LDADD += $(remove_LDADD) @@ -395,7 +400,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$(EXEEXT) installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` diff -urNp coreutils-8.7-orig/man/Makefile.am coreutils-8.7/man/Makefile.am --- coreutils-8.7-orig/man/Makefile.am 2010-10-11 19:35:11.000000000 +0200 +++ coreutils-8.7/man/Makefile.am 2010-11-15 10:09:21.768922182 +0100 @@ -94,6 +94,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-8.7-orig/man/runuser.x coreutils-8.7/man/runuser.x --- coreutils-8.7-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100 +++ coreutils-8.7/man/runuser.x 2010-11-15 10:09:57.437939015 +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 coreutils \(aqsu invocation\(aq\fR\t +.TP +since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR. +.br --- /dev/null 2007-01-09 09:38:07.860075128 +0000 +++ coreutils-6.7/man/runuser.1 2007-01-09 17:27:56.000000000 +0000 @@ -0,0 +1,68 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33. +.TH RUNUSER "1" "September 2004" "runuser (coreutils) 5.2.1" "User Commands" +.SH NAME +runuser \- run a shell with substitute user and group IDs, similar to su, but will not run PAM hooks +.SH SYNOPSIS +.B runuser +[\fIOPTION\fR]... [\fI-\fR] [\fIUSER \fR[\fIARG\fR]...] +.SH DESCRIPTION +.\" Add any additional description here +.PP +Change the effective user id and group id to that of USER. No PAM hooks +are run, and there will be no password prompt. This command is useful +when run as the root user. If run as a non-root user without privilege +to set user ID, the command will fail. +.TP +-, \fB\-l\fR, \fB\-\-login\fR +make the shell a login shell +.TP +\fB\-c\fR, \fB\-\-commmand\fR=\fICOMMAND\fR +pass a single COMMAND to the shell with \fB\-c\fR +.TP +\fB\-f\fR, \fB\-\-fast\fR +pass \fB\-f\fR to the shell (for csh or tcsh) +.TP +\fB\-g\fR, \fB\-\-group\fR=\fIGROUP\fR +specify the primary group +.TP +\fB\-G\fR, \fB\-\-supp-group\fR=\fIGROUP\fR +specify a supplemental group +.TP +\fB\-m\fR, \fB\-\-preserve\-environment\fR +do not reset environment variables +.TP +\fB\-p\fR +same as \fB\-m\fR +.TP +\fB\-s\fR, \fB\-\-shell\fR=\fISHELL\fR +run SHELL if /etc/shells allows it +.TP +\fB\-\-help\fR +display this help and exit +.TP +\fB\-\-version\fR +output version information and exit +.PP +A mere - implies \fB\-l\fR. If USER not given, assume root. +.SH AUTHOR +Written by David MacKenzie, Dan Walsh. +.SH "REPORTING BUGS" +Report bugs to . +.SH COPYRIGHT +Copyright \(co 2004 Free Software Foundation, Inc. +.br +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +.SH "SEE ALSO" +Since this command is trimmed down version of su use you can use the su manual. +The full documentation for +.B su +is maintained as a Texinfo manual. If the +.B info +and +.B su +programs are properly installed at your site, the command +.IP +.B info coreutils su +.PP +should give you access to the complete manual. --- coreutils-6.10/po/pl.po.orig 2008-03-02 14:22:54.123486386 +0100 +++ coreutils-6.10/po/pl.po 2008-03-02 14:28:35.858960780 +0100 @@ -8986,6 +8986,16 @@ msgid "warning: cannot change directory to %s" msgstr "uwaga: nie można zmienić katalogu na %s" +#: src/su.c:runuser +#, c-format +msgid "group %s does not exist" +msgstr "grupa %s nie istnieje" + +#: src/su.c:runuser +#, c-format +msgid "Can't specify more than %d supplemental groups" +msgstr "Nie można określić więcej niż %d grup dodatkowych" + #. This is a proper name. See the gettext manual, section Names. #: src/sum.c:36 msgid "Kayvan Aghaiepour" diff -urNp coreutils-8.7-orig/tests/misc/help-version coreutils-8.7/tests/misc/help-version --- coreutils-8.7-orig/tests/misc/help-version 2010-10-11 19:35:11.000000000 +0200 +++ coreutils-8.7/tests/misc/help-version 2010-11-15 10:45:18.473682325 +0100 @@ -32,6 +32,7 @@ expected_failure_status_nohup=125 expected_failure_status_stdbuf=125 expected_failure_status_su=125 expected_failure_status_timeout=125 +expected_failure_status_runuser=125 expected_failure_status_printenv=2 expected_failure_status_tty=3 expected_failure_status_sort=2 @@ -209,6 +210,7 @@ seq_setup () { args=10; } sleep_setup () { args=0; } su_setup () { args=--version; } stdbuf_setup () { args="-oL true"; } +runuser_setup () { args=--version; } timeout_setup () { args=--version; } # I'd rather not run sync, since it spins up disks that I've diff -urNp coreutils-8.7-orig/tests/misc/invalid-opt coreutils-8.7/tests/misc/invalid-opt --- coreutils-8.7-orig/tests/misc/invalid-opt 2010-10-11 19:35:11.000000000 +0200 +++ coreutils-8.7/tests/misc/invalid-opt 2010-11-15 10:45:46.451938873 +0100 @@ -37,6 +37,7 @@ my %exit_status = sort => 2, stdbuf => 125, su => 125, + runuser => 125, test => 0, timeout => 125, true => 0,