annotate toys/pending/sulogin.c @ 1564:685a0da6ca59 draft

probe for getspnam(), forkpty(), utmpx, replace sethostname() Android is missing all of these; we need to probe for some so we have a config symbol to depend on. sethostname() is easily replaced. We got termios.h via pty.h; now it's not included in configure-step tools, so we need termios.h to generate globals.
author Isaac Dunham <ibid.ag@gmail.com>
date Wed, 19 Nov 2014 16:38:46 -0600
parents 5d64dc59e569
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1312
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
1 /* sulogin.c - Single User Login.
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
2 *
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
3 * Copyright 2014 Ashish Kumar Gupta <ashishkguptaiit.cse@gmail.com>
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
4 * Copyright 2014 Kyungwan Han <asura321@gmail.com>
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
5 *
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
6 *
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
7 * Relies on libcrypt for hash calculation.
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
8 * No support for PAM/securetty/selinux/login script/issue/utmp
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
9
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
10
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
11 USE_SULOGIN(NEWTOY(sulogin, "t#<0=0", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
12
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
13 config SULOGIN
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
14 bool "sulogin"
1313
5d64dc59e569 Pending commands should default n
Rob Landley <rob@landley.net>
parents: 1312
diff changeset
15 default n
1564
685a0da6ca59 probe for getspnam(), forkpty(), utmpx, replace sethostname()
Isaac Dunham <ibid.ag@gmail.com>
parents: 1313
diff changeset
16 depends on TOYBOX_SHADOW
1312
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
17 help
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
18 usage: sulogin [-t time] [tty]
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
19
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
20 Single User Login.
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
21 -t Default Time for Single User Login
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
22 */
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
23 #define FOR_sulogin
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
24 #include "toys.h"
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
25
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
26 GLOBALS(
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
27 long timeout;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
28 struct termios crntio;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
29 )
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
30
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
31 static void timeout_handle(int signo)
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
32 {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
33 tcsetattr(0, TCSANOW, &(TT.crntio));
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
34 fflush(stdout);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
35 xprintf("\n Timed out - Normal startup\n");
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
36 exit(0);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
37 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
38
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
39 static int validate_password(char *pwd)
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
40 {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
41 struct sigaction sa;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
42 int ret;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
43 char *s = "Give root password for system maintenance\n"
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
44 "(or type Control-D for normal startup):",
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
45 *pass;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
46
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
47 tcgetattr(0, &(TT.crntio));
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
48 sa.sa_handler = timeout_handle;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
49
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
50 if(TT.timeout) {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
51 sigaction(SIGALRM, &sa, NULL);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
52 alarm(TT.timeout);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
53 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
54
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
55 ret = read_password(toybuf, sizeof(toybuf), s);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
56 if(TT.timeout) alarm(0);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
57
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
58 if ( ret && !toybuf[0]) {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
59 xprintf("Normal startup.\n");
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
60 return -1;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
61 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
62
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
63 pass = crypt(toybuf, pwd);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
64 ret = 1;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
65 if( pass && !strcmp(pass, pwd)) ret = 0;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
66
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
67 return ret;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
68 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
69
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
70 static void run_shell(char *shell)
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
71 {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
72 snprintf(toybuf,sizeof(toybuf), "-%s", shell);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
73 execl(shell, toybuf, NULL);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
74 error_exit("Failed to spawn shell");
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
75 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
76
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
77 void sulogin_main(void)
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
78 {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
79 struct passwd *pwd = NULL;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
80 struct spwd * spwd = NULL;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
81 char *forbid[] = {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
82 "BASH_ENV", "ENV", "HOME", "IFS", "LD_LIBRARY_PATH", "LD_PRELOAD",
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
83 "LD_TRACE_LOADED_OBJECTS", "LD_BIND_NOW", "LD_AOUT_LIBRARY_PATH",
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
84 "LD_AOUT_PRELOAD", "LD_NOWARN", "LD_KEEPDIR", "SHELL", NULL
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
85 };
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
86 char *shell = NULL, *pass = NULL, **temp = forbid;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
87
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
88 if (toys.optargs[0]) {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
89 int fd;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
90
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
91 dup2((fd = xopen(toys.optargs[0], O_RDWR)), 0);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
92 if (!isatty(0)) error_exit("%s: it is not a tty", toys.optargs[0]);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
93 dup2( fd, 1);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
94 dup2( fd, 2);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
95 if (fd > 2) close(fd);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
96 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
97
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
98 for (temp = forbid; *temp; temp++) unsetenv(*temp);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
99
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
100 if (!(pwd = getpwuid(0))) error_exit("invalid user");
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
101 pass = pwd->pw_passwd;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
102
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
103 if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
104 if ((spwd = getspnam (pwd->pw_name))) pass = spwd->sp_pwdp;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
105 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
106
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
107 while (1) {
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
108 int r = validate_password(pass);
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
109
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
110 if (r == 1) xprintf("Incorrect Login.\n");
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
111 else if (r == 0) break;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
112 else if (r == -1) return;
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
113 }
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
114
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
115 if ((shell = getenv("SUSHELL")) || (shell = getenv("sushell"))
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
116 || (shell = pwd->pw_shell))
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
117 run_shell((shell && *shell)? shell: "/bin/sh");
ff3ecf9e5095 Single-user login.
Ashwini Sharma <ak.ashwini1981@gmail.com>
parents:
diff changeset
118 }