xref: /aosp_15_r20/external/toybox/toys/pending/sulogin.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1*cf5a6c84SAndroid Build Coastguard Worker /* sulogin.c - Single User Login.
2*cf5a6c84SAndroid Build Coastguard Worker  *
3*cf5a6c84SAndroid Build Coastguard Worker  * Copyright 2014 Ashish Kumar Gupta <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker  * Copyright 2014 Kyungwan Han <[email protected]>
5*cf5a6c84SAndroid Build Coastguard Worker  *
6*cf5a6c84SAndroid Build Coastguard Worker  *
7*cf5a6c84SAndroid Build Coastguard Worker  * Relies on libcrypt for hash calculation.
8*cf5a6c84SAndroid Build Coastguard Worker  * No support for PAM/securetty/selinux/login script/issue/utmp
9*cf5a6c84SAndroid Build Coastguard Worker 
10*cf5a6c84SAndroid Build Coastguard Worker 
11*cf5a6c84SAndroid Build Coastguard Worker USE_SULOGIN(NEWTOY(sulogin, "t#<0=0", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
12*cf5a6c84SAndroid Build Coastguard Worker 
13*cf5a6c84SAndroid Build Coastguard Worker config SULOGIN
14*cf5a6c84SAndroid Build Coastguard Worker   bool "sulogin"
15*cf5a6c84SAndroid Build Coastguard Worker   default n
16*cf5a6c84SAndroid Build Coastguard Worker   help
17*cf5a6c84SAndroid Build Coastguard Worker     usage: sulogin [-t time] [tty]
18*cf5a6c84SAndroid Build Coastguard Worker 
19*cf5a6c84SAndroid Build Coastguard Worker     Single User Login.
20*cf5a6c84SAndroid Build Coastguard Worker     -t	Default Time for Single User Login
21*cf5a6c84SAndroid Build Coastguard Worker */
22*cf5a6c84SAndroid Build Coastguard Worker #define FOR_sulogin
23*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
24*cf5a6c84SAndroid Build Coastguard Worker 
GLOBALS(long timeout;struct termios crntio;)25*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
26*cf5a6c84SAndroid Build Coastguard Worker   long timeout;
27*cf5a6c84SAndroid Build Coastguard Worker   struct termios crntio;
28*cf5a6c84SAndroid Build Coastguard Worker )
29*cf5a6c84SAndroid Build Coastguard Worker 
30*cf5a6c84SAndroid Build Coastguard Worker static void timeout_handle(int signo)
31*cf5a6c84SAndroid Build Coastguard Worker {
32*cf5a6c84SAndroid Build Coastguard Worker   tcsetattr(0, TCSANOW, &(TT.crntio));
33*cf5a6c84SAndroid Build Coastguard Worker   fflush(stdout);
34*cf5a6c84SAndroid Build Coastguard Worker   xprintf("\n Timed out - Normal startup\n");
35*cf5a6c84SAndroid Build Coastguard Worker   exit(0);
36*cf5a6c84SAndroid Build Coastguard Worker }
37*cf5a6c84SAndroid Build Coastguard Worker 
validate_password(char * pwd)38*cf5a6c84SAndroid Build Coastguard Worker static int validate_password(char *pwd)
39*cf5a6c84SAndroid Build Coastguard Worker {
40*cf5a6c84SAndroid Build Coastguard Worker   struct sigaction sa;
41*cf5a6c84SAndroid Build Coastguard Worker   int ret;
42*cf5a6c84SAndroid Build Coastguard Worker   char *s = "Give root password for system maintenance\n"
43*cf5a6c84SAndroid Build Coastguard Worker     "(or type Control-D for normal startup):",
44*cf5a6c84SAndroid Build Coastguard Worker     *pass;
45*cf5a6c84SAndroid Build Coastguard Worker 
46*cf5a6c84SAndroid Build Coastguard Worker   tcgetattr(0, &(TT.crntio));
47*cf5a6c84SAndroid Build Coastguard Worker   sa.sa_handler = timeout_handle;
48*cf5a6c84SAndroid Build Coastguard Worker 
49*cf5a6c84SAndroid Build Coastguard Worker   if(TT.timeout) {
50*cf5a6c84SAndroid Build Coastguard Worker     sigaction(SIGALRM, &sa, NULL);
51*cf5a6c84SAndroid Build Coastguard Worker     alarm(TT.timeout);
52*cf5a6c84SAndroid Build Coastguard Worker   }
53*cf5a6c84SAndroid Build Coastguard Worker 
54*cf5a6c84SAndroid Build Coastguard Worker   ret = read_password(toybuf, sizeof(toybuf), s);
55*cf5a6c84SAndroid Build Coastguard Worker   if(TT.timeout) alarm(0);
56*cf5a6c84SAndroid Build Coastguard Worker 
57*cf5a6c84SAndroid Build Coastguard Worker   if ( ret && !toybuf[0]) {
58*cf5a6c84SAndroid Build Coastguard Worker     xprintf("Normal startup.\n");
59*cf5a6c84SAndroid Build Coastguard Worker     return -1;
60*cf5a6c84SAndroid Build Coastguard Worker   }
61*cf5a6c84SAndroid Build Coastguard Worker 
62*cf5a6c84SAndroid Build Coastguard Worker   pass = crypt(toybuf, pwd);
63*cf5a6c84SAndroid Build Coastguard Worker   ret = 1;
64*cf5a6c84SAndroid Build Coastguard Worker   if( pass && !strcmp(pass, pwd)) ret = 0;
65*cf5a6c84SAndroid Build Coastguard Worker 
66*cf5a6c84SAndroid Build Coastguard Worker   return ret;
67*cf5a6c84SAndroid Build Coastguard Worker }
68*cf5a6c84SAndroid Build Coastguard Worker 
run_shell(char * shell)69*cf5a6c84SAndroid Build Coastguard Worker static void run_shell(char *shell)
70*cf5a6c84SAndroid Build Coastguard Worker {
71*cf5a6c84SAndroid Build Coastguard Worker   snprintf(toybuf,sizeof(toybuf), "-%s", shell);
72*cf5a6c84SAndroid Build Coastguard Worker   execl(shell, toybuf, NULL);
73*cf5a6c84SAndroid Build Coastguard Worker   error_exit("Failed to spawn shell");
74*cf5a6c84SAndroid Build Coastguard Worker }
75*cf5a6c84SAndroid Build Coastguard Worker 
sulogin_main(void)76*cf5a6c84SAndroid Build Coastguard Worker void sulogin_main(void)
77*cf5a6c84SAndroid Build Coastguard Worker {
78*cf5a6c84SAndroid Build Coastguard Worker   struct passwd *pwd = NULL;
79*cf5a6c84SAndroid Build Coastguard Worker   struct spwd * spwd = NULL;
80*cf5a6c84SAndroid Build Coastguard Worker   char *forbid[] = {
81*cf5a6c84SAndroid Build Coastguard Worker     "BASH_ENV", "ENV", "HOME", "IFS", "LD_LIBRARY_PATH", "LD_PRELOAD",
82*cf5a6c84SAndroid Build Coastguard Worker     "LD_TRACE_LOADED_OBJECTS", "LD_BIND_NOW", "LD_AOUT_LIBRARY_PATH",
83*cf5a6c84SAndroid Build Coastguard Worker     "LD_AOUT_PRELOAD", "LD_NOWARN", "LD_KEEPDIR", "SHELL", NULL
84*cf5a6c84SAndroid Build Coastguard Worker   };
85*cf5a6c84SAndroid Build Coastguard Worker   char *shell = NULL, *pass = NULL, **temp = forbid;
86*cf5a6c84SAndroid Build Coastguard Worker 
87*cf5a6c84SAndroid Build Coastguard Worker   if (toys.optargs[0]) {
88*cf5a6c84SAndroid Build Coastguard Worker     int fd;
89*cf5a6c84SAndroid Build Coastguard Worker 
90*cf5a6c84SAndroid Build Coastguard Worker     dup2((fd = xopen_stdio(toys.optargs[0], O_RDWR)), 0);
91*cf5a6c84SAndroid Build Coastguard Worker     if (!isatty(0)) error_exit("%s: it is not a tty", toys.optargs[0]);
92*cf5a6c84SAndroid Build Coastguard Worker     dup2( fd, 1);
93*cf5a6c84SAndroid Build Coastguard Worker     dup2( fd, 2);
94*cf5a6c84SAndroid Build Coastguard Worker     if (fd > 2) close(fd);
95*cf5a6c84SAndroid Build Coastguard Worker   }
96*cf5a6c84SAndroid Build Coastguard Worker 
97*cf5a6c84SAndroid Build Coastguard Worker   for (temp = forbid; *temp; temp++) unsetenv(*temp);
98*cf5a6c84SAndroid Build Coastguard Worker 
99*cf5a6c84SAndroid Build Coastguard Worker   if (!(pwd = getpwuid(0))) error_exit("invalid user");
100*cf5a6c84SAndroid Build Coastguard Worker   pass = pwd->pw_passwd;
101*cf5a6c84SAndroid Build Coastguard Worker 
102*cf5a6c84SAndroid Build Coastguard Worker   if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) {
103*cf5a6c84SAndroid Build Coastguard Worker     if ((spwd = getspnam (pwd->pw_name))) pass = spwd->sp_pwdp;
104*cf5a6c84SAndroid Build Coastguard Worker   }
105*cf5a6c84SAndroid Build Coastguard Worker 
106*cf5a6c84SAndroid Build Coastguard Worker   while (1) {
107*cf5a6c84SAndroid Build Coastguard Worker     int r = validate_password(pass);
108*cf5a6c84SAndroid Build Coastguard Worker 
109*cf5a6c84SAndroid Build Coastguard Worker     if (r == 1) xprintf("Incorrect Login.\n");
110*cf5a6c84SAndroid Build Coastguard Worker     else if (r == 0) break;
111*cf5a6c84SAndroid Build Coastguard Worker     else if (r == -1) return;
112*cf5a6c84SAndroid Build Coastguard Worker   }
113*cf5a6c84SAndroid Build Coastguard Worker 
114*cf5a6c84SAndroid Build Coastguard Worker   if ((shell = getenv("SUSHELL")) || (shell = getenv("sushell"))
115*cf5a6c84SAndroid Build Coastguard Worker       || (shell = pwd->pw_shell))
116*cf5a6c84SAndroid Build Coastguard Worker     run_shell((shell && *shell)? shell: "/bin/sh");
117*cf5a6c84SAndroid Build Coastguard Worker }
118