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  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_stdio(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