blob: 6edd2582b3f250acffda5fa92e9d7c91f2967fe1 [file] [log] [blame]
Eric Andersen27f64e12002-06-23 04:24:25 +00001/* vi: set sw=4 ts=4: */
"Robert P. J. Day"801ab142006-07-12 07:56:04 +00002/*
Rob Landleydd93abe2006-09-08 17:22:05 +00003 * Mini sulogin implementation for busybox
4 *
"Robert P. J. Day"801ab142006-07-12 07:56:04 +00005 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
6 */
7
Eric Andersen27f64e12002-06-23 04:24:25 +00008#include <syslog.h>
Eric Andersen27f64e12002-06-23 04:24:25 +00009
10#include "busybox.h"
11
"Vladimir N. Oleynik"6f347ef2005-10-15 10:23:55 +000012static const char * const forbid[] = {
Eric Andersen27f64e12002-06-23 04:24:25 +000013 "ENV",
14 "BASH_ENV",
15 "HOME",
16 "IFS",
17 "PATH",
18 "SHELL",
19 "LD_LIBRARY_PATH",
20 "LD_PRELOAD",
21 "LD_TRACE_LOADED_OBJECTS",
22 "LD_BIND_NOW",
23 "LD_AOUT_LIBRARY_PATH",
24 "LD_AOUT_PRELOAD",
25 "LD_NOWARN",
26 "LD_KEEPDIR",
27 (char *) 0
28};
29
30
Bernhard Reutner-Fischer30385572006-01-31 17:57:48 +000031static void catchalarm(int ATTRIBUTE_UNUSED junk)
Eric Andersen27f64e12002-06-23 04:24:25 +000032{
33 exit(EXIT_FAILURE);
34}
35
36
Rob Landleydfba7412006-03-06 20:47:33 +000037int sulogin_main(int argc, char **argv)
Eric Andersen27f64e12002-06-23 04:24:25 +000038{
39 char *cp;
Eric Andersen27f64e12002-06-23 04:24:25 +000040 int timeout = 0;
Rob Landleydd93abe2006-09-08 17:22:05 +000041 char *timeout_arg;
"Vladimir N. Oleynik"6f347ef2005-10-15 10:23:55 +000042 const char * const *p;
Rob Landleydd93abe2006-09-08 17:22:05 +000043 struct passwd *pwd;
44 struct spwd *spwd;
Eric Andersen27f64e12002-06-23 04:24:25 +000045
Denis Vlasenko9852d5a2006-09-09 14:00:58 +000046 logmode = LOGMODE_BOTH;
47 openlog(bb_applet_name, 0, LOG_AUTH);
Rob Landleydd93abe2006-09-08 17:22:05 +000048
Denis Vlasenko67b23e62006-10-03 21:00:06 +000049 if (getopt32 (argc, argv, "t:", &timeout_arg)) {
Rob Landleydd93abe2006-09-08 17:22:05 +000050 if (safe_strtoi(timeout_arg, &timeout)) {
51 timeout = 0;
Eric Andersen27f64e12002-06-23 04:24:25 +000052 }
53 }
Rob Landleydd93abe2006-09-08 17:22:05 +000054
55 if (argv[optind]) {
56 close(0);
57 close(1);
Rob Landleydd93abe2006-09-08 17:22:05 +000058 dup(xopen(argv[optind], O_RDWR));
Rob Landley69674942006-09-11 00:34:01 +000059 close(2);
Rob Landleydd93abe2006-09-08 17:22:05 +000060 dup(0);
61 }
62
Eric Andersen27f64e12002-06-23 04:24:25 +000063 if (!isatty(0) || !isatty(1) || !isatty(2)) {
Denis Vlasenko9852d5a2006-09-09 14:00:58 +000064 logmode = LOGMODE_SYSLOG;
65 bb_error_msg_and_die("not a tty");
Denis Vlasenkoa9801652006-09-07 16:20:03 +000066 }
Eric Andersen27f64e12002-06-23 04:24:25 +000067
68 /* Clear out anything dangerous from the environment */
69 for (p = forbid; *p; p++)
70 unsetenv(*p);
71
Eric Andersen27f64e12002-06-23 04:24:25 +000072 signal(SIGALRM, catchalarm);
Rob Landleydd93abe2006-09-08 17:22:05 +000073
74 if (!(pwd = getpwuid(0))) {
Denis Vlasenko9852d5a2006-09-09 14:00:58 +000075 goto auth_error;
Denis Vlasenko9213a9e2006-09-17 16:28:10 +000076 }
Rob Landleydd93abe2006-09-08 17:22:05 +000077
78 if (ENABLE_FEATURE_SHADOWPASSWDS) {
79 if (!(spwd = getspnam(pwd->pw_name))) {
Denis Vlasenko9852d5a2006-09-09 14:00:58 +000080 goto auth_error;
Eric Andersen27f64e12002-06-23 04:24:25 +000081 }
Rob Landleydd93abe2006-09-08 17:22:05 +000082 pwd->pw_passwd = spwd->sp_pwdp;
Eric Andersen27f64e12002-06-23 04:24:25 +000083 }
Rob Landleydd93abe2006-09-08 17:22:05 +000084
Eric Andersen27f64e12002-06-23 04:24:25 +000085 while (1) {
Rob Landleydd93abe2006-09-08 17:22:05 +000086 /* cp points to a static buffer that is zeroed every time */
Denis Vlasenko9852d5a2006-09-09 14:00:58 +000087 cp = bb_askpass(timeout,
88 "Give root password for system maintenance\n"
89 "(or type Control-D for normal startup):");
90
Eric Andersen27f64e12002-06-23 04:24:25 +000091 if (!cp || !*cp) {
Rob Landleydd93abe2006-09-08 17:22:05 +000092 bb_info_msg("Normal startup");
Denis Vlasenko9852d5a2006-09-09 14:00:58 +000093 return 0;
Eric Andersen27f64e12002-06-23 04:24:25 +000094 }
Rob Landleydd93abe2006-09-08 17:22:05 +000095 if (strcmp(pw_encrypt(cp, pwd->pw_passwd), pwd->pw_passwd) == 0) {
Eric Andersen27f64e12002-06-23 04:24:25 +000096 break;
97 }
Rob Landley84cb7672006-01-06 20:59:09 +000098 bb_do_delay(FAIL_DELAY);
Denis Vlasenko9852d5a2006-09-09 14:00:58 +000099 bb_error_msg("login incorrect");
Eric Andersen27f64e12002-06-23 04:24:25 +0000100 }
Rob Landleydd93abe2006-09-08 17:22:05 +0000101 memset(cp, 0, strlen(cp));
Eric Andersen27f64e12002-06-23 04:24:25 +0000102 signal(SIGALRM, SIG_DFL);
Rob Landley60158cb2005-05-03 06:25:50 +0000103
Rob Landleydd93abe2006-09-08 17:22:05 +0000104 bb_info_msg("System Maintenance Mode");
Rob Landley60158cb2005-05-03 06:25:50 +0000105
Rob Landleydd93abe2006-09-08 17:22:05 +0000106 USE_SELINUX(renew_current_security_context());
Rob Landley60158cb2005-05-03 06:25:50 +0000107
Rob Landleydd93abe2006-09-08 17:22:05 +0000108 run_shell(pwd->pw_shell, 1, 0, 0);
109 /* never returns */
Denis Vlasenko9852d5a2006-09-09 14:00:58 +0000110
Denis Vlasenko9213a9e2006-09-17 16:28:10 +0000111auth_error:
Denis Vlasenko9852d5a2006-09-09 14:00:58 +0000112 bb_error_msg_and_die("no password entry for `root'");
Eric Andersen27f64e12002-06-23 04:24:25 +0000113}