| 1 |
diff -urNp coreutils-7.0.orig/AUTHORS coreutils-7.0/AUTHORS
|
| 2 |
--- coreutils-7.0.orig/AUTHORS 2008-08-24 22:58:15.000000000 +0200
|
| 3 |
+++ coreutils-7.0/AUTHORS 2009-01-28 18:11:00.316247411 +0100
|
| 4 |
@@ -64,6 +64,7 @@ pwd: Jim Meyering
|
| 5 |
rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering
|
| 6 |
rmdir: David MacKenzie
|
| 7 |
runcon: Russell Coker
|
| 8 |
+runuser: David MacKenzie, Dan Walsh
|
| 9 |
seq: Ulrich Drepper
|
| 10 |
sha1sum: Ulrich Drepper, Scott Miller, David Madore
|
| 11 |
sha224sum: Ulrich Drepper, Scott Miller, David Madore
|
| 12 |
diff -urNp coreutils-7.0.orig/man/Makefile.am coreutils-7.0/man/Makefile.am
|
| 13 |
--- coreutils-7.0.orig/man/Makefile.am 2008-09-27 19:28:54.000000000 +0200
|
| 14 |
+++ coreutils-7.0/man/Makefile.am 2009-01-28 18:11:00.317247417 +0100
|
| 15 |
@@ -93,6 +93,7 @@ readlink.1: $(common_dep) $(srcdir)/read
|
| 16 |
rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c
|
| 17 |
rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c
|
| 18 |
runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c
|
| 19 |
+runuser.1: $(common_dep) $(srcdir)/runuser.x ../src/su.c
|
| 20 |
seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c
|
| 21 |
sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c
|
| 22 |
sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c
|
| 23 |
diff -urNp coreutils-7.0.orig/man/runuser.x coreutils-7.0/man/runuser.x
|
| 24 |
--- coreutils-7.0.orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100
|
| 25 |
+++ coreutils-7.0/man/runuser.x 2009-01-28 18:11:00.321247443 +0100
|
| 26 |
@@ -0,0 +1,12 @@
|
| 27 |
+[NAME]
|
| 28 |
+runuser \- run a shell with substitute user and group IDs
|
| 29 |
+[DESCRIPTION]
|
| 30 |
+.\" Add any additional description here
|
| 31 |
+[SEE ALSO]
|
| 32 |
+.TP
|
| 33 |
+More detailed Texinfo documentation could be found by command
|
| 34 |
+.TP
|
| 35 |
+\t\fBinfo coreutils \(aqsu invocation\(aq\fR\t
|
| 36 |
+.TP
|
| 37 |
+since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR.
|
| 38 |
+.br
|
| 39 |
diff -urNp coreutils-7.0.orig/README coreutils-7.0/README
|
| 40 |
--- coreutils-7.0.orig/README 2008-08-24 22:30:10.000000000 +0200
|
| 41 |
+++ coreutils-7.0/README 2009-01-28 18:11:00.318247424 +0100
|
| 42 |
@@ -12,10 +12,10 @@ The programs that can be built with this
|
| 43 |
factor false fmt fold groups head hostid hostname id install join kill
|
| 44 |
link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup
|
| 45 |
od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir
|
| 46 |
- runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf
|
| 47 |
- sleep sort split stat stdbuf stty su sum sync tac tail tee test timeout
|
| 48 |
- touch tr true truncate tsort tty uname unexpand uniq unlink uptime users
|
| 49 |
- vdir wc who whoami yes
|
| 50 |
+ runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum shred
|
| 51 |
+ shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test
|
| 52 |
+ timeout touch tr true truncate tsort tty uname unexpand uniq unlink uptime
|
| 53 |
+ users vdir wc who whoami yes
|
| 54 |
|
| 55 |
See the file NEWS for a list of major changes in the current release.
|
| 56 |
|
| 57 |
diff -urNp coreutils-7.0.orig/src/Makefile.am coreutils-7.0/src/Makefile.am
|
| 58 |
--- coreutils-7.0.orig/src/Makefile.am 2009-01-28 18:10:10.756926000 +0100
|
| 59 |
+++ coreutils-7.0/src/Makefile.am 2009-01-28 18:11:59.658631933 +0100
|
| 60 |
@@ -38,7 +38,7 @@ EXTRA_PROGRAMS = \
|
| 61 |
shuf sort split sum tac tail tr tsort unexpand uniq wc \
|
| 62 |
basename date dirname echo env expr factor false \
|
| 63 |
id kill logname pathchk printenv printf pwd \
|
| 64 |
- runcon seq sleep tee \
|
| 65 |
+ runcon runuser seq sleep tee \
|
| 66 |
test timeout true truncate tty whoami yes \
|
| 67 |
base64
|
| 68 |
|
| 69 |
@@ -154,6 +154,10 @@ cp_LDADD += $(LIB_ACL) $(LIB_XATTR)
|
| 70 |
mv_LDADD += $(LIB_ACL) $(LIB_XATTR)
|
| 71 |
ginstall_LDADD += $(LIB_ACL) $(LIB_XATTR)
|
| 72 |
|
| 73 |
+runuser_SOURCES = su.c
|
| 74 |
+runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\""
|
| 75 |
+runuser_LDADD = $(LDADD) $(LIB_CRYPT) @LIB_PAM@
|
| 76 |
+
|
| 77 |
stat_LDADD = $(LDADD) $(LIB_SELINUX)
|
| 78 |
|
| 79 |
# Append $(LIBICONV) to each program that uses proper_name_utf8.
|
| 80 |
@@ -173,7 +177,7 @@ RELEASE_YEAR = \
|
| 81 |
`sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \
|
| 82 |
$(top_srcdir)/lib/version-etc.c`
|
| 83 |
|
| 84 |
-all-local: su$(EXEEXT)
|
| 85 |
+all-local: su$(EXEEXT) runuser
|
| 86 |
|
| 87 |
installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'`
|
| 88 |
|
| 89 |
diff -urNp coreutils-7.0.orig/src/su.c coreutils-7.0/src/su.c
|
| 90 |
--- coreutils-7.0.orig/src/su.c 2009-01-28 18:10:10.801926000 +0100
|
| 91 |
+++ coreutils-7.0/src/su.c 2009-01-28 18:11:00.320247437 +0100
|
| 92 |
@@ -109,9 +109,15 @@
|
| 93 |
#include "error.h"
|
| 94 |
|
| 95 |
/* The official name of this program (e.g., no `g' prefix). */
|
| 96 |
+#ifndef RUNUSER
|
| 97 |
#define PROGRAM_NAME "su"
|
| 98 |
+#else
|
| 99 |
+#define PROGRAM_NAME "runuser"
|
| 100 |
+#endif
|
| 101 |
|
| 102 |
+#ifndef AUTHORS
|
| 103 |
#define AUTHORS proper_name ("David MacKenzie")
|
| 104 |
+#endif
|
| 105 |
|
| 106 |
#if HAVE_PATHS_H
|
| 107 |
# include <paths.h>
|
| 108 |
@@ -149,11 +155,18 @@
|
| 109 |
#ifndef USE_PAM
|
| 110 |
char *crypt (char const *key, char const *salt);
|
| 111 |
#endif
|
| 112 |
+#ifndef CHECKPASSWD
|
| 113 |
+#define CHECKPASSWD 1
|
| 114 |
+#endif
|
| 115 |
|
| 116 |
extern char **environ;
|
| 117 |
|
| 118 |
static void run_shell (char const *, char const *, char **, size_t,
|
| 119 |
- const struct passwd *)
|
| 120 |
+ const struct passwd *
|
| 121 |
+#ifdef RUNUSER
|
| 122 |
+ , gid_t *groups, int num_groups
|
| 123 |
+#endif
|
| 124 |
+ )
|
| 125 |
#ifdef USE_PAM
|
| 126 |
;
|
| 127 |
#else
|
| 128 |
@@ -183,6 +197,10 @@ static struct option const longopts[] =
|
| 129 |
{"login", no_argument, NULL, 'l'},
|
| 130 |
{"preserve-environment", no_argument, NULL, 'p'},
|
| 131 |
{"shell", required_argument, NULL, 's'},
|
| 132 |
+#ifdef RUNUSER
|
| 133 |
+ {"group", required_argument, NULL, 'g'},
|
| 134 |
+ {"supp-group", required_argument, NULL, 'G'},
|
| 135 |
+#endif
|
| 136 |
{GETOPT_HELP_OPTION_DECL},
|
| 137 |
{GETOPT_VERSION_OPTION_DECL},
|
| 138 |
{NULL, 0, NULL, 0}
|
| 139 |
@@ -284,10 +302,12 @@ correct_password (const struct passwd *p
|
| 140 |
retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh);
|
| 141 |
PAM_BAIL_P;
|
| 142 |
|
| 143 |
+#ifndef RUNUSER
|
| 144 |
if (getuid() != 0 && !isatty(0)) {
|
| 145 |
fprintf(stderr, "standard in must be a tty\n");
|
| 146 |
exit(1);
|
| 147 |
}
|
| 148 |
+#endif
|
| 149 |
|
| 150 |
caller = getpwuid(getuid());
|
| 151 |
if(caller != NULL && caller->pw_name != NULL) {
|
| 152 |
@@ -304,6 +324,11 @@ correct_password (const struct passwd *p
|
| 153 |
retval = pam_set_item(pamh, PAM_TTY, tty_name);
|
| 154 |
PAM_BAIL_P;
|
| 155 |
}
|
| 156 |
+#ifdef RUNUSER
|
| 157 |
+ if (getuid() != geteuid())
|
| 158 |
+ /* safety net: deny operation if we are suid by accident */
|
| 159 |
+ error(EXIT_FAILURE, 1, "runuser may not be setuid");
|
| 160 |
+#else
|
| 161 |
retval = pam_authenticate(pamh, 0);
|
| 162 |
PAM_BAIL_P;
|
| 163 |
retval = pam_acct_mgmt(pamh, 0);
|
| 164 |
@@ -313,6 +338,7 @@ correct_password (const struct passwd *p
|
| 165 |
PAM_BAIL_P;
|
| 166 |
}
|
| 167 |
PAM_BAIL_P;
|
| 168 |
+#endif
|
| 169 |
/* must be authenticated if this point was reached */
|
| 170 |
return 1;
|
| 171 |
#else /* !USE_PAM */
|
| 172 |
@@ -394,11 +420,22 @@ modify_environment (const struct passwd
|
| 173 |
/* Become the user and group(s) specified by PW. */
|
| 174 |
|
| 175 |
static void
|
| 176 |
-change_identity (const struct passwd *pw)
|
| 177 |
+change_identity (const struct passwd *pw
|
| 178 |
+#ifdef RUNUSER
|
| 179 |
+ , gid_t *groups, int num_groups
|
| 180 |
+#endif
|
| 181 |
+ )
|
| 182 |
{
|
| 183 |
#ifdef HAVE_INITGROUPS
|
| 184 |
+ int rc = 0;
|
| 185 |
errno = 0;
|
| 186 |
- if (initgroups (pw->pw_name, pw->pw_gid) == -1) {
|
| 187 |
+#ifdef RUNUSER
|
| 188 |
+ if (num_groups)
|
| 189 |
+ rc = setgroups(num_groups, groups);
|
| 190 |
+ else
|
| 191 |
+#endif
|
| 192 |
+ rc = initgroups(pw->pw_name, pw->pw_gid);
|
| 193 |
+ if (rc == -1) {
|
| 194 |
#ifdef USE_PAM
|
| 195 |
pam_close_session(pamh, 0);
|
| 196 |
pam_end(pamh, PAM_ABORT);
|
| 197 |
@@ -445,7 +482,11 @@ pam_copyenv (pam_handle_t *pamh)
|
| 198 |
|
| 199 |
static void
|
| 200 |
run_shell (char const *shell, char const *command, char **additional_args,
|
| 201 |
- size_t n_additional_args, const struct passwd *pw)
|
| 202 |
+ size_t n_additional_args, const struct passwd *pw
|
| 203 |
+#ifdef RUNUSER
|
| 204 |
+ , gid_t *groups, int num_groups
|
| 205 |
+#endif
|
| 206 |
+ )
|
| 207 |
{
|
| 208 |
size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1;
|
| 209 |
char const **args = xnmalloc (n_args, sizeof *args);
|
| 210 |
@@ -476,7 +517,11 @@ run_shell (char const *shell, char const
|
| 211 |
|
| 212 |
child = fork();
|
| 213 |
if (child == 0) { /* child shell */
|
| 214 |
- change_identity (pw);
|
| 215 |
+ change_identity (pw
|
| 216 |
+#ifdef RUNUSER
|
| 217 |
+ , groups, num_groups
|
| 218 |
+#endif
|
| 219 |
+ );
|
| 220 |
pam_end(pamh, 0);
|
| 221 |
if (!same_session)
|
| 222 |
setsid ();
|
| 223 |
@@ -620,6 +665,28 @@ usage (int status)
|
| 224 |
else
|
| 225 |
{
|
| 226 |
printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
|
| 227 |
+#ifdef RUNUSER
|
| 228 |
+ printf (_("\
|
| 229 |
+Change the effective user id and group id to that of USER. Only session PAM\n\
|
| 230 |
+hooks are run, and there is no password prompt. This command is useful only\n\
|
| 231 |
+when run as the root user. If run as a non-root user without privilege\n\
|
| 232 |
+to set user ID, the command will fail as the binary is not setuid.\n\
|
| 233 |
+As %s doesn't run auth and account PAM hooks, it runs with lower overhead\n\
|
| 234 |
+than su.\n\
|
| 235 |
+\n\
|
| 236 |
+ -, -l, --login make the shell a login shell, uses runuser-l\n\
|
| 237 |
+ PAM file instead of default one\n\
|
| 238 |
+ -g --group=group specify the primary group\n\
|
| 239 |
+ -G --supp-group=group specify a supplemental group\n\
|
| 240 |
+ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
|
| 241 |
+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\
|
| 242 |
+ and do not create a new session\n\
|
| 243 |
+ -f, --fast pass -f to the shell (for csh or tcsh)\n\
|
| 244 |
+ -m, --preserve-environment do not reset environment variables\n\
|
| 245 |
+ -p same as -m\n\
|
| 246 |
+ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
|
| 247 |
+"), program_name);
|
| 248 |
+#else
|
| 249 |
fputs (_("\
|
| 250 |
Change the effective user id and group id to that of USER.\n\
|
| 251 |
\n\
|
| 252 |
@@ -632,6 +697,7 @@ Change the effective user id and group i
|
| 253 |
-p same as -m\n\
|
| 254 |
-s, --shell=SHELL run SHELL if /etc/shells allows it\n\
|
| 255 |
"), stdout);
|
| 256 |
+#endif
|
| 257 |
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
| 258 |
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
| 259 |
fputs (_("\
|
| 260 |
@@ -653,6 +719,12 @@ main (int argc, char **argv)
|
| 261 |
char *shell = NULL;
|
| 262 |
struct passwd *pw;
|
| 263 |
struct passwd pw_copy;
|
| 264 |
+#ifdef RUNUSER
|
| 265 |
+ struct group *gr;
|
| 266 |
+ gid_t groups[NGROUPS_MAX];
|
| 267 |
+ int num_supp_groups = 0;
|
| 268 |
+ int use_gid = 0;
|
| 269 |
+#endif
|
| 270 |
|
| 271 |
initialize_main (&argc, &argv);
|
| 272 |
set_program_name (argv[0]);
|
| 273 |
@@ -667,7 +739,11 @@ main (int argc, char **argv)
|
| 274 |
simulate_login = false;
|
| 275 |
change_environment = true;
|
| 276 |
|
| 277 |
- while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1)
|
| 278 |
+ while ((optc = getopt_long (argc, argv, "c:flmps:"
|
| 279 |
+#ifdef RUNUSER
|
| 280 |
+ "g:G:"
|
| 281 |
+#endif
|
| 282 |
+ , longopts, NULL)) != -1)
|
| 283 |
{
|
| 284 |
switch (optc)
|
| 285 |
{
|
| 286 |
@@ -697,6 +773,28 @@ main (int argc, char **argv)
|
| 287 |
shell = optarg;
|
| 288 |
break;
|
| 289 |
|
| 290 |
+#ifdef RUNUSER
|
| 291 |
+ case 'g':
|
| 292 |
+ gr = getgrnam(optarg);
|
| 293 |
+ if (!gr)
|
| 294 |
+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
|
| 295 |
+ use_gid = 1;
|
| 296 |
+ groups[0] = gr->gr_gid;
|
| 297 |
+ break;
|
| 298 |
+
|
| 299 |
+ case 'G':
|
| 300 |
+ num_supp_groups++;
|
| 301 |
+ if (num_supp_groups >= NGROUPS_MAX)
|
| 302 |
+ error (EXIT_FAILURE, 0,
|
| 303 |
+ _("Can't specify more than %d supplemental groups"),
|
| 304 |
+ NGROUPS_MAX - 1);
|
| 305 |
+ gr = getgrnam(optarg);
|
| 306 |
+ if (!gr)
|
| 307 |
+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
|
| 308 |
+ groups[num_supp_groups] = gr->gr_gid;
|
| 309 |
+ break;
|
| 310 |
+#endif
|
| 311 |
+
|
| 312 |
case_GETOPT_HELP_CHAR;
|
| 313 |
|
| 314 |
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
| 315 |
@@ -735,7 +833,20 @@ main (int argc, char **argv)
|
| 316 |
: DEFAULT_SHELL);
|
| 317 |
endpwent ();
|
| 318 |
|
| 319 |
- if (!correct_password (pw))
|
| 320 |
+#ifdef RUNUSER
|
| 321 |
+ if (num_supp_groups && !use_gid)
|
| 322 |
+ {
|
| 323 |
+ pw->pw_gid = groups[1];
|
| 324 |
+ memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups);
|
| 325 |
+ }
|
| 326 |
+ else if (use_gid)
|
| 327 |
+ {
|
| 328 |
+ pw->pw_gid = groups[0];
|
| 329 |
+ num_supp_groups++;
|
| 330 |
+ }
|
| 331 |
+#endif
|
| 332 |
+
|
| 333 |
+ if (CHECKPASSWD && !correct_password (pw))
|
| 334 |
{
|
| 335 |
#ifdef SYSLOG_FAILURE
|
| 336 |
log_su (pw, false);
|
| 337 |
@@ -767,8 +878,16 @@ main (int argc, char **argv)
|
| 338 |
modify_environment (pw, shell);
|
| 339 |
|
| 340 |
#ifndef USE_PAM
|
| 341 |
- change_identity (pw);
|
| 342 |
+ change_identity (pw
|
| 343 |
+#ifdef RUNUSER
|
| 344 |
+ , groups, num_supp_groups
|
| 345 |
+#endif
|
| 346 |
+ );
|
| 347 |
#endif
|
| 348 |
|
| 349 |
- run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw);
|
| 350 |
+ run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw
|
| 351 |
+#ifdef RUNUSER
|
| 352 |
+ , groups, num_supp_groups
|
| 353 |
+#endif
|
| 354 |
+ );
|
| 355 |
}
|
| 356 |
diff -urNp coreutils-7.5.orig/tests/misc/help-version coreutils-7.5/tests/misc/help-version
|
| 357 |
--- coreutils-7.5.orig/tests/misc/help-version
|
| 358 |
+++ coreutils-7.5/tests/misc/help-version
|
| 359 |
@@ -150,6 +150,7 @@ printf_args=foo
|
| 360 |
sleep_args=0
|
| 361 |
su_args=--version
|
| 362 |
stdbuf_args="-oL true"
|
| 363 |
+runuser_args=--version
|
| 364 |
timeout_args=--version
|
| 365 |
|
| 366 |
# I'd rather not run sync, since it spins up disks that I've
|
| 367 |
diff -urNp coreutils-7.6-orig/man/help2man coreutils-7.6/man/help2man
|
| 368 |
--- coreutils-7.6-orig/man/help2man 2009-09-01 13:01:16.000000000 +0200
|
| 369 |
+++ coreutils-7.6/man/help2man 2009-09-22 15:15:01.000000000 +0200
|
| 370 |
@@ -550,6 +550,9 @@ while (length)
|
| 371 |
$include{$sect} .= $content;
|
| 372 |
}
|
| 373 |
|
| 374 |
+# There is no info documentation for runuser (shared with su).
|
| 375 |
+$opt_no_info = 1 if $program eq 'runuser';
|
| 376 |
+
|
| 377 |
# Refer to the real documentation.
|
| 378 |
unless ($opt_no_info)
|
| 379 |
{
|