diff options
| author | Ashwini Sharma <ak.ashwini1981@gmail.com> | 2014-05-24 14:40:02 -0500 | 
|---|---|---|
| committer | Ashwini Sharma <ak.ashwini1981@gmail.com> | 2014-05-24 14:40:02 -0500 | 
| commit | 5e936d65972316c26b7271086cc57838bf1f1e28 (patch) | |
| tree | af7605fa85763c82fd63978fa4929254f25398b5 | |
| parent | 3bc5d3d880627b1a9c38ed4b92ff894c7752f124 (diff) | |
| download | toybox-5e936d65972316c26b7271086cc57838bf1f1e28.tar.gz | |
Single-user login.
| -rw-r--r-- | toys/pending/sulogin.c | 117 | 
1 files changed, 117 insertions, 0 deletions
| diff --git a/toys/pending/sulogin.c b/toys/pending/sulogin.c new file mode 100644 index 00000000..fb562ca5 --- /dev/null +++ b/toys/pending/sulogin.c @@ -0,0 +1,117 @@ +/* sulogin.c - Single User Login. + * + * Copyright 2014 Ashish Kumar Gupta <ashishkguptaiit.cse@gmail.com> + * Copyright 2014 Kyungwan Han <asura321@gmail.com> + * + *  + * Relies on libcrypt for hash calculation.  + * No support for PAM/securetty/selinux/login script/issue/utmp + + +USE_SULOGIN(NEWTOY(sulogin, "t#<0=0", TOYFLAG_SBIN|TOYFLAG_NEEDROOT)) + +config SULOGIN +  bool "sulogin" +  default y +  help +    usage: sulogin [-t time] [tty] + +    Single User Login. +    -t	Default Time for Single User Login +*/ +#define FOR_sulogin +#include "toys.h" + +GLOBALS( +  long timeout; +  struct termios crntio; +) + +static void timeout_handle(int signo)  +{ +  tcsetattr(0, TCSANOW, &(TT.crntio)); +  fflush(stdout); +  xprintf("\n Timed out - Normal startup\n"); +  exit(0); +} + +static int validate_password(char *pwd) +{ +  struct sigaction sa; +  int ret; +  char *s = "Give root password for system maintenance\n" +    "(or type Control-D for normal startup):", +    *pass; + +  tcgetattr(0, &(TT.crntio)); +  sa.sa_handler = timeout_handle; + +  if(TT.timeout) { +    sigaction(SIGALRM, &sa, NULL); +    alarm(TT.timeout); +  } + +  ret = read_password(toybuf, sizeof(toybuf), s); +  if(TT.timeout) alarm(0); + +  if ( ret && !toybuf[0]) {    +    xprintf("Normal startup.\n"); +    return -1; +  } + +  pass = crypt(toybuf, pwd); +  ret = 1; +  if( pass && !strcmp(pass, pwd)) ret = 0; + +  return ret; +} + +static void run_shell(char *shell)  +{ +  snprintf(toybuf,sizeof(toybuf), "-%s", shell); +  execl(shell, toybuf, NULL); +  error_exit("Failed to spawn shell"); +} + +void sulogin_main(void) +{ +  struct passwd *pwd = NULL; +  struct spwd * spwd = NULL; +  char *forbid[] = { +    "BASH_ENV", "ENV", "HOME", "IFS", "LD_LIBRARY_PATH", "LD_PRELOAD", +    "LD_TRACE_LOADED_OBJECTS", "LD_BIND_NOW", "LD_AOUT_LIBRARY_PATH", +    "LD_AOUT_PRELOAD", "LD_NOWARN", "LD_KEEPDIR", "SHELL", NULL +  }; +  char *shell = NULL, *pass = NULL, **temp = forbid; + +  if (toys.optargs[0]) { +    int fd; + +    dup2((fd = xopen(toys.optargs[0], O_RDWR)), 0); +    if (!isatty(0)) error_exit("%s: it is not a tty", toys.optargs[0]); +    dup2( fd, 1); +    dup2( fd, 2); +    if (fd > 2) close(fd); +  }   + +  for (temp = forbid; *temp; temp++) unsetenv(*temp); + +  if (!(pwd = getpwuid(0))) error_exit("invalid user"); +  pass = pwd->pw_passwd; + +  if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) { +    if ((spwd = getspnam (pwd->pw_name))) pass = spwd->sp_pwdp; +  } + +  while (1) { +    int r = validate_password(pass); + +    if (r == 1) xprintf("Incorrect Login.\n"); +    else if (r == 0) break; +    else if (r == -1) return; +  } + +  if ((shell = getenv("SUSHELL")) || (shell = getenv("sushell")) +      || (shell = pwd->pw_shell)) +    run_shell((shell && *shell)? shell: "/bin/sh"); +} | 
