1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#define FOR_login
25#include "toys.h"
26
27GLOBALS(
28 char *h, *f;
29
30 int login_timeout, login_fail_timeout;
31)
32
33static void login_timeout_handler(int sig __attribute__((unused)))
34{
35 printf("\nLogin timed out after %d seconds.\n", TT.login_timeout);
36 xexit();
37}
38
39void login_main(void)
40{
41 int hh = FLAG(h), count, tty = tty_fd();
42 char *username, *pass = 0, *ss;
43 struct passwd *pwd = 0;
44
45
46 if (tty == -1) error_exit("no tty");
47
48 openlog("login", LOG_PID | LOG_CONS, LOG_AUTH);
49 xsignal(SIGALRM, login_timeout_handler);
50
51 if (TT.f) username = TT.f;
52 else username = *toys.optargs;
53 for (count = 0; count < 3; count++) {
54 alarm(TT.login_timeout = 60);
55 tcflush(0, TCIFLUSH);
56
57 if (!username) {
58 if (gethostname(toybuf, sizeof(toybuf)-1)) *toybuf = 0;
59 printf("%s%slogin: ", *toybuf ? toybuf : "", *toybuf ? " " : "");
60 fflush(stdout);
61
62 if(!fgets(toybuf, sizeof(toybuf)-1, stdin)) xexit();
63
64
65 for (ss = toybuf; *ss; ss++) if (*ss<=' ' || *ss==':') break;
66 *ss = 0;
67 if (!*(username = toybuf)) {
68 username = 0;
69 continue;
70 }
71 }
72
73
74 if ((pwd = getpwnam(username))) {
75
76 if (TT.f || !*pwd->pw_passwd) break;
77
78
79 if (*(pass = pwd->pw_passwd) == 'x') {
80 struct spwd *spwd = getspnam (username);
81
82 if (spwd) pass = spwd->sp_pwdp;
83 }
84 } else if (TT.f) error_exit("bad -f '%s'", TT.f);
85
86
87 if (!read_password(toybuf, sizeof(toybuf), "Password: ")) {
88 int x = pass && (ss = crypt(toybuf, pass)) && !strcmp(pass, ss);
89
90
91 memset(toybuf, 0, sizeof(toybuf));
92 if (x) break;
93 }
94
95 syslog(LOG_WARNING, "invalid password for '%s' on %s %s%s", pwd->pw_name,
96 ttyname(tty), hh ? "from " : "", hh ? TT.h : "");
97
98 sleep(3);
99 puts("Login incorrect");
100
101 username = 0;
102 pwd = 0;
103 }
104
105 alarm(0);
106 if (!pwd) error_exit("max retries (3)");
107
108
109
110 if (pwd->pw_uid && !access("/etc/nologin", R_OK)) {
111 ss = readfile("/etc/nologin", toybuf, sizeof(toybuf));
112 puts ((ss && *ss) ? ss : "nologin");
113 free(ss);
114 toys.exitval = 1;
115
116 return;
117 }
118
119 if (fchown(tty, pwd->pw_uid, pwd->pw_gid) || fchmod(tty, 0600))
120 printf("can't claim tty");
121 xsetuser(pwd);
122 reset_env(pwd, !FLAG(p));
123
124
125 if ((ss = readfile("/etc/motd", 0, 0))) puts(ss);
126
127 syslog(LOG_INFO, "%s logged in on %s %s %s", pwd->pw_name,
128 ttyname(tty), hh ? "from" : "", hh ? TT.h : "");
129
130
131 execl(pwd->pw_shell, xmprintf("-%s", pwd->pw_shell), (char *)0);
132 perror_exit("exec shell '%s'", pwd->pw_shell);
133}
134