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