1 diff -urNp coreutils-8.7-orig/AUTHORS coreutils-8.7/AUTHORS
2 --- coreutils-8.7-orig/AUTHORS 2010-10-11 19:35:11.000000000 +0200
3 +++ coreutils-8.7/AUTHORS 2010-11-15 10:08:04.222078001 +0100
4 @@ -65,6 +65,7 @@ readlink: Dmitry V. Levin
5 rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering
8 +runuser: David MacKenzie, Dan Walsh
10 sha1sum: Ulrich Drepper, Scott Miller, David Madore
11 sha224sum: Ulrich Drepper, Scott Miller, David Madore
12 diff -urNp coreutils-8.7-orig/man/help2man coreutils-8.7/man/help2man
13 --- coreutils-8.7-orig/man/help2man 2010-10-11 19:35:11.000000000 +0200
14 +++ coreutils-8.7/man/help2man 2010-11-15 10:08:51.331054884 +0100
15 @@ -555,6 +555,9 @@ while (length)
16 $include{$sect} .= $content;
19 +# There is no info documentation for runuser (shared with su).
20 +$opt_no_info = 1 if $program eq 'runuser';
22 # Refer to the real documentation.
25 diff -urNp coreutils-8.7-orig/man/Makefile.am coreutils-8.7/man/Makefile.am
26 --- coreutils-8.7-orig/man/Makefile.am 2010-10-11 19:35:11.000000000 +0200
27 +++ coreutils-8.7/man/Makefile.am 2010-11-15 10:09:21.768922182 +0100
28 @@ -94,6 +94,7 @@ readlink.1: $(common_dep) $(srcdir)/read
29 rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c
30 rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c
31 runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c
32 +runuser.1: $(common_dep) $(srcdir)/runuser.x ../src/su.c
33 seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c
34 sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c
35 sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c
36 diff -urNp coreutils-8.7-orig/man/runuser.x coreutils-8.7/man/runuser.x
37 --- coreutils-8.7-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100
38 +++ coreutils-8.7/man/runuser.x 2010-11-15 10:09:57.437939015 +0100
41 +runuser \- run a shell with substitute user and group IDs
43 +.\" Add any additional description here
46 +More detailed Texinfo documentation could be found by command
48 +\t\fBinfo coreutils \(aqsu invocation\(aq\fR\t
50 +since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR.
52 diff -urNp coreutils-8.7-orig/README coreutils-8.7/README
53 --- coreutils-8.7-orig/README 2010-10-11 19:35:11.000000000 +0200
54 +++ coreutils-8.7/README 2010-11-15 10:10:43.002922253 +0100
55 @@ -11,8 +11,8 @@ The programs that can be built with this
56 factor false fmt fold groups head hostid hostname id install join kill
57 link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup
58 nproc od paste pathchk pinky pr printenv printf ptx pwd readlink realpath
59 - rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred
60 - shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test
61 + rm rmdir runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum
62 + shred shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test
63 timeout touch tr true truncate tsort tty uname unexpand uniq unlink
64 uptime users vdir wc who whoami yes
66 diff -urNp coreutils-8.7-orig/src/Makefile.am coreutils-8.7/src/Makefile.am
67 --- coreutils-8.7-orig/src/Makefile.am 2010-11-15 10:07:07.339171659 +0100
68 +++ coreutils-8.7/src/Makefile.am 2010-11-15 10:12:14.847094550 +0100
69 @@ -100,6 +100,7 @@ EXTRA_PROGRAMS = \
77 @@ -300,6 +301,10 @@ cp_LDADD += $(copy_LDADD)
78 ginstall_LDADD += $(copy_LDADD)
79 mv_LDADD += $(copy_LDADD)
81 +runuser_SOURCES = su.c
82 +runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\""
83 +runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS)
86 mv_LDADD += $(remove_LDADD)
87 rm_LDADD += $(remove_LDADD)
88 @@ -395,7 +400,7 @@ RELEASE_YEAR = \
89 `sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \
90 $(top_srcdir)/lib/version-etc.c`
92 -all-local: su$(EXEEXT)
93 +all-local: su$(EXEEXT) runuser
95 installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'`
97 diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c
98 --- coreutils-8.7-orig/src/su.c 2010-11-15 10:07:07.372933288 +0100
99 +++ coreutils-8.7/src/su.c 2010-11-15 10:42:12.569159230 +0100
103 /* The official name of this program (e.g., no 'g' prefix). */
105 #define PROGRAM_NAME "su"
107 +#define PROGRAM_NAME "runuser"
111 #define AUTHORS proper_name ("David MacKenzie")
118 char *crypt (char const *key, char const *salt);
121 +#define CHECKPASSWD 1
124 static void run_shell (char const *, char const *, char **, size_t)
126 @@ -169,6 +178,10 @@ static struct option const longopts[] =
127 {"login", no_argument, NULL, 'l'},
128 {"preserve-environment", no_argument, NULL, 'p'},
129 {"shell", required_argument, NULL, 's'},
131 + {"group", required_argument, NULL, 'g'},
132 + {"supp-group", required_argument, NULL, 'G'},
134 {GETOPT_HELP_OPTION_DECL},
135 {GETOPT_VERSION_OPTION_DECL},
137 @@ -444,6 +457,11 @@ correct_password (const struct passwd *p
138 retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name);
139 PAM_BAIL_P (return false);
142 + if (getuid() != geteuid())
143 + /* safety net: deny operation if we are suid by accident */
144 + error(EXIT_FAILURE, 1, "runuser may not be setuid");
146 retval = pam_authenticate (pamh, 0);
147 PAM_BAIL_P (return false);
148 retval = pam_acct_mgmt (pamh, 0);
149 @@ -454,6 +472,7 @@ correct_password (const struct passwd *p
150 PAM_BAIL_P (return false);
152 PAM_BAIL_P (return false);
154 /* Must be authenticated if this point was reached. */
157 @@ -533,11 +552,22 @@ modify_environment (const struct passwd
158 /* Become the user and group(s) specified by PW. */
161 -init_groups (const struct passwd *pw)
162 +init_groups (const struct passwd *pw
164 + , gid_t *groups, int num_groups
168 #ifdef HAVE_INITGROUPS
171 - if (initgroups (pw->pw_name, pw->pw_gid) == -1)
174 + rc = setgroups(num_groups, groups);
177 + rc = initgroups(pw->pw_name, pw->pw_gid);
181 cleanup_pam (PAM_ABORT);
182 @@ -639,6 +669,28 @@ usage (int status)
185 printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
188 +Change the effective user id and group id to that of USER. Only session PAM\n\
189 +hooks are run, and there is no password prompt. This command is useful only\n\
190 +when run as the root user. If run as a non-root user without privilege\n\
191 +to set user ID, the command will fail as the binary is not setuid.\n\
192 +As %s doesn't run auth and account PAM hooks, it runs with lower overhead\n\
195 + -, -l, --login make the shell a login shell, uses runuser-l\n\
196 + PAM file instead of default one\n\
197 + -g --group=group specify the primary group\n\
198 + -G --supp-group=group specify a supplemental group\n\
199 + -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
200 + --session-command=COMMAND pass a single COMMAND to the shell with -c\n\
201 + and do not create a new session\n\
202 + -f, --fast pass -f to the shell (for csh or tcsh)\n\
203 + -m, --preserve-environment do not reset environment variables\n\
205 + -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
209 Change the effective user id and group id to that of USER.\n\
211 @@ -651,6 +703,7 @@ Change the effective user id and group i
213 -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
216 fputs (HELP_OPTION_DESCRIPTION, stdout);
217 fputs (VERSION_OPTION_DESCRIPTION, stdout);
219 @@ -672,6 +725,12 @@ main (int argc, char **argv)
222 struct passwd pw_copy;
225 + gid_t groups[NGROUPS_MAX];
226 + int num_supp_groups = 0;
230 initialize_main (&argc, &argv);
231 set_program_name (argv[0]);
232 @@ -686,7 +745,11 @@ main (int argc, char **argv)
233 simulate_login = false;
234 change_environment = true;
236 - while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1)
237 + while ((optc = getopt_long (argc, argv, "c:flmps:"
241 + , longopts, NULL)) != -1)
245 @@ -716,6 +779,28 @@ main (int argc, char **argv)
251 + gr = getgrnam(optarg);
253 + error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
255 + groups[0] = gr->gr_gid;
260 + if (num_supp_groups >= NGROUPS_MAX)
261 + error (EXIT_FAILURE, 0,
262 + _("Can't specify more than %d supplemental groups"),
264 + gr = getgrnam(optarg);
266 + error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
267 + groups[num_supp_groups] = gr->gr_gid;
271 case_GETOPT_HELP_CHAR;
273 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
274 @@ -754,7 +839,20 @@ main (int argc, char **argv)
278 - if (!correct_password (pw))
280 + if (num_supp_groups && !use_gid)
282 + pw->pw_gid = groups[1];
283 + memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups);
287 + pw->pw_gid = groups[0];
292 + if (CHECKPASSWD && !correct_password (pw))
294 #ifdef SYSLOG_FAILURE
296 @@ -784,7 +882,11 @@ main (int argc, char **argv)
298 shell = xstrdup (shell ? shell : pw->pw_shell);
303 + , groups, num_supp_groups
308 create_watching_parent ();
309 diff -urNp coreutils-8.7-orig/tests/misc/help-version coreutils-8.7/tests/misc/help-version
310 --- coreutils-8.7-orig/tests/misc/help-version 2010-10-11 19:35:11.000000000 +0200
311 +++ coreutils-8.7/tests/misc/help-version 2010-11-15 10:45:18.473682325 +0100
312 @@ -32,6 +32,7 @@ expected_failure_status_nohup=125
313 expected_failure_status_stdbuf=125
314 expected_failure_status_su=125
315 expected_failure_status_timeout=125
316 +expected_failure_status_runuser=125
317 expected_failure_status_printenv=2
318 expected_failure_status_tty=3
319 expected_failure_status_sort=2
320 @@ -209,6 +210,7 @@ seq_setup () { args=10; }
321 sleep_setup () { args=0; }
322 su_setup () { args=--version; }
323 stdbuf_setup () { args="-oL true"; }
324 +runuser_setup () { args=--version; }
325 timeout_setup () { args=--version; }
327 # I'd rather not run sync, since it spins up disks that I've
328 diff -urNp coreutils-8.7-orig/tests/misc/invalid-opt coreutils-8.7/tests/misc/invalid-opt
329 --- coreutils-8.7-orig/tests/misc/invalid-opt 2010-10-11 19:35:11.000000000 +0200
330 +++ coreutils-8.7/tests/misc/invalid-opt 2010-11-15 10:45:46.451938873 +0100
331 @@ -37,6 +37,7 @@ my %exit_status =