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