]>
Commit | Line | Data |
---|---|---|
0efbb74b MT |
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 | |
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-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; | |
17 | } | |
18 | ||
19 | +# There is no info documentation for runuser (shared with su). | |
20 | +$opt_no_info = 1 if $program eq 'runuser'; | |
21 | + | |
22 | # Refer to the real documentation. | |
23 | unless ($opt_no_info) | |
24 | { | |
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 | |
39 | @@ -0,0 +1,12 @@ | |
40 | +[NAME] | |
41 | +runuser \- run a shell with substitute user and group IDs | |
42 | +[DESCRIPTION] | |
43 | +.\" Add any additional description here | |
44 | +[SEE ALSO] | |
45 | +.TP | |
46 | +More detailed Texinfo documentation could be found by command | |
47 | +.TP | |
48 | +\t\fBinfo coreutils \(aqsu invocation\(aq\fR\t | |
49 | +.TP | |
50 | +since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR. | |
51 | +.br | |
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 | |
65 | ||
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 = \ | |
70 | rm \ | |
71 | rmdir \ | |
72 | runcon \ | |
73 | + runuser \ | |
74 | seq \ | |
75 | sha1sum \ | |
76 | sha224sum \ | |
77 | @@ -300,6 +301,10 @@ cp_LDADD += $(copy_LDADD) | |
78 | ginstall_LDADD += $(copy_LDADD) | |
79 | mv_LDADD += $(copy_LDADD) | |
80 | ||
81 | +runuser_SOURCES = su.c | |
82 | +runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\"" | |
83 | +runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS) | |
84 | + | |
85 | remove_LDADD = | |
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` | |
91 | ||
92 | -all-local: su$(EXEEXT) | |
93 | +all-local: su$(EXEEXT) runuser | |
94 | ||
95 | installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'` | |
96 | ||
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 | |
100 | @@ -100,9 +100,15 @@ | |
101 | #include "error.h" | |
102 | ||
103 | /* The official name of this program (e.g., no 'g' prefix). */ | |
104 | +#ifndef RUNUSER | |
105 | #define PROGRAM_NAME "su" | |
106 | +#else | |
107 | +#define PROGRAM_NAME "runuser" | |
108 | +#endif | |
109 | ||
110 | +#ifndef AUTHORS | |
111 | #define AUTHORS proper_name ("David MacKenzie") | |
112 | +#endif | |
113 | ||
114 | #if HAVE_PATHS_H | |
115 | # include <paths.h> | |
116 | @@ -140,6 +146,9 @@ | |
117 | #ifndef USE_PAM | |
118 | char *crypt (char const *key, char const *salt); | |
119 | #endif | |
120 | +#ifndef CHECKPASSWD | |
121 | +#define CHECKPASSWD 1 | |
122 | +#endif | |
123 | ||
124 | static void run_shell (char const *, char const *, char **, size_t) | |
125 | ATTRIBUTE_NORETURN; | |
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'}, | |
130 | +#ifdef RUNUSER | |
131 | + {"group", required_argument, NULL, 'g'}, | |
132 | + {"supp-group", required_argument, NULL, 'G'}, | |
133 | +#endif | |
134 | {GETOPT_HELP_OPTION_DECL}, | |
135 | {GETOPT_VERSION_OPTION_DECL}, | |
136 | {NULL, 0, NULL, 0} | |
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); | |
140 | } | |
141 | +#ifdef RUNUSER | |
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"); | |
145 | +#else | |
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); | |
151 | } | |
152 | PAM_BAIL_P (return false); | |
153 | +#endif | |
154 | /* Must be authenticated if this point was reached. */ | |
155 | return true; | |
156 | #else /* !USE_PAM */ | |
157 | @@ -533,11 +552,22 @@ modify_environment (const struct passwd | |
158 | /* Become the user and group(s) specified by PW. */ | |
159 | ||
160 | static void | |
161 | -init_groups (const struct passwd *pw) | |
162 | +init_groups (const struct passwd *pw | |
163 | +#ifdef RUNUSER | |
164 | + , gid_t *groups, int num_groups | |
165 | +#endif | |
166 | + ) | |
167 | { | |
168 | #ifdef HAVE_INITGROUPS | |
169 | + int rc = 0; | |
170 | errno = 0; | |
171 | - if (initgroups (pw->pw_name, pw->pw_gid) == -1) | |
172 | +#ifdef RUNUSER | |
173 | + if (num_groups) | |
174 | + rc = setgroups(num_groups, groups); | |
175 | + else | |
176 | +#endif | |
177 | + rc = initgroups(pw->pw_name, pw->pw_gid); | |
178 | + if (rc == -1) | |
179 | { | |
180 | #ifdef USE_PAM | |
181 | cleanup_pam (PAM_ABORT); | |
182 | @@ -639,6 +669,28 @@ usage (int status) | |
183 | else | |
184 | { | |
185 | printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name); | |
186 | +#ifdef RUNUSER | |
187 | + printf (_("\ | |
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\ | |
193 | +than su.\n\ | |
194 | +\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\ | |
204 | + -p same as -m\n\ | |
205 | + -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ | |
206 | +"), program_name); | |
207 | +#else | |
208 | fputs (_("\ | |
209 | Change the effective user id and group id to that of USER.\n\ | |
210 | \n\ | |
211 | @@ -651,6 +703,7 @@ Change the effective user id and group i | |
212 | -p same as -m\n\ | |
213 | -s, --shell=SHELL run SHELL if /etc/shells allows it\n\ | |
214 | "), stdout); | |
215 | +#endif | |
216 | fputs (HELP_OPTION_DESCRIPTION, stdout); | |
217 | fputs (VERSION_OPTION_DESCRIPTION, stdout); | |
218 | fputs (_("\ | |
219 | @@ -672,6 +725,12 @@ main (int argc, char **argv) | |
220 | char *shell = NULL; | |
221 | struct passwd *pw; | |
222 | struct passwd pw_copy; | |
223 | +#ifdef RUNUSER | |
224 | + struct group *gr; | |
225 | + gid_t groups[NGROUPS_MAX]; | |
226 | + int num_supp_groups = 0; | |
227 | + int use_gid = 0; | |
228 | +#endif | |
229 | ||
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; | |
235 | ||
236 | - while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1) | |
237 | + while ((optc = getopt_long (argc, argv, "c:flmps:" | |
238 | +#ifdef RUNUSER | |
239 | + "g:G:" | |
240 | +#endif | |
241 | + , longopts, NULL)) != -1) | |
242 | { | |
243 | switch (optc) | |
244 | { | |
245 | @@ -716,6 +779,28 @@ main (int argc, char **argv) | |
246 | shell = optarg; | |
247 | break; | |
248 | ||
249 | +#ifdef RUNUSER | |
250 | + case 'g': | |
251 | + gr = getgrnam(optarg); | |
252 | + if (!gr) | |
253 | + error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); | |
254 | + use_gid = 1; | |
255 | + groups[0] = gr->gr_gid; | |
256 | + break; | |
257 | + | |
258 | + case 'G': | |
259 | + num_supp_groups++; | |
260 | + if (num_supp_groups >= NGROUPS_MAX) | |
261 | + error (EXIT_FAILURE, 0, | |
262 | + _("Can't specify more than %d supplemental groups"), | |
263 | + NGROUPS_MAX - 1); | |
264 | + gr = getgrnam(optarg); | |
265 | + if (!gr) | |
266 | + error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg); | |
267 | + groups[num_supp_groups] = gr->gr_gid; | |
268 | + break; | |
269 | +#endif | |
270 | + | |
271 | case_GETOPT_HELP_CHAR; | |
272 | ||
273 | case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); | |
274 | @@ -754,7 +839,20 @@ main (int argc, char **argv) | |
275 | : DEFAULT_SHELL); | |
276 | endpwent (); | |
277 | ||
278 | - if (!correct_password (pw)) | |
279 | +#ifdef RUNUSER | |
280 | + if (num_supp_groups && !use_gid) | |
281 | + { | |
282 | + pw->pw_gid = groups[1]; | |
283 | + memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups); | |
284 | + } | |
285 | + else if (use_gid) | |
286 | + { | |
287 | + pw->pw_gid = groups[0]; | |
288 | + num_supp_groups++; | |
289 | + } | |
290 | +#endif | |
291 | + | |
292 | + if (CHECKPASSWD && !correct_password (pw)) | |
293 | { | |
294 | #ifdef SYSLOG_FAILURE | |
295 | log_su (pw, false); | |
296 | @@ -784,7 +882,11 @@ main (int argc, char **argv) | |
297 | } | |
298 | shell = xstrdup (shell ? shell : pw->pw_shell); | |
299 | ||
300 | - init_groups (pw); | |
301 | + init_groups (pw | |
302 | +#ifdef RUNUSER | |
303 | + , groups, num_supp_groups | |
304 | +#endif | |
305 | + ); | |
306 | ||
307 | #ifdef USE_PAM | |
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; } | |
326 | ||
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 = | |
332 | sort => 2, | |
333 | stdbuf => 125, | |
334 | su => 125, | |
335 | + runuser => 125, | |
336 | test => 0, | |
337 | timeout => 125, | |
338 | true => 0, |