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