don't allow kerberos root login if the root instance is missing
[unix-history] / usr / src / usr.bin / login / login.c
CommitLineData
9bcf1061 1/*-
55f766c6 2 * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994
1e31f488 3 * The Regents of the University of California. All rights reserved.
ede75793 4 *
9bcf1061 5 * %sccs.include.redist.c%
bcf1365c
DF
6 */
7
8#ifndef lint
1e31f488 9static char copyright[] =
55f766c6 10"@(#) Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994\n\
1e31f488 11 The Regents of the University of California. All rights reserved.\n";
ede75793 12#endif /* not lint */
bcf1365c 13
22d4760e 14#ifndef lint
011f52c6 15static char sccsid[] = "@(#)login.c 8.4 (Berkeley) %G%";
ede75793 16#endif /* not lint */
22d4760e 17
88a01c09
BJ
18/*
19 * login [ name ]
d0faf133 20 * login -r hostname (for rlogind)
5dbe2745
MK
21 * login -h hostname (for telnetd, etc.)
22 * login -f name (for pre-authenticated login: datakit, xterm, etc.)
88a01c09
BJ
23 */
24
7a625b73 25#include <sys/param.h>
3b8dd95e
SL
26#include <sys/stat.h>
27#include <sys/time.h>
28#include <sys/resource.h>
9479aa87 29#include <sys/file.h>
3b8dd95e 30
cc952d1c 31#include <err.h>
f4d21924 32#include <errno.h>
c89291e2 33#include <grp.h>
80f91e3f 34#include <pwd.h>
cc952d1c
JSP
35#include <setjmp.h>
36#include <signal.h>
80f91e3f 37#include <stdio.h>
f4d21924 38#include <stdlib.h>
38dde0cd 39#include <string.h>
cc952d1c
JSP
40#include <syslog.h>
41#include <ttyent.h>
42#include <tzfile.h>
43#include <unistd.h>
44#include <utmp.h>
45
fb6e7f7e 46#include "pathnames.h"
c89291e2 47
f4d21924
KB
48void badlogin __P((char *));
49void checknologin __P((void));
50void dolastlog __P((int));
51void getloginname __P((void));
52void motd __P((void));
53int rootterm __P((char *));
54void sigint __P((int));
55void sleepexit __P((int));
56char *stypeof __P((char *));
57void timedout __P((int));
80fc9234
KB
58#ifdef KERBEROS
59int klogin __P((struct passwd *, char *, char *, char *));
60#endif
f4d21924 61
cc952d1c
JSP
62extern void login __P((struct utmp *));
63
80f91e3f 64#define TTYGRPNAME "tty" /* name of group to own ttys */
88a01c09 65
3b8dd95e 66/*
80f91e3f
KB
67 * This bounds the time given to login. Not a define so it can
68 * be patched on machines where it's too small.
3b8dd95e 69 */
cc952d1c 70u_int timeout = 300;
f4d21924 71
9bcf1061
KB
72#ifdef KERBEROS
73int notickets = 1;
48f66865
MK
74char *instance;
75char *krbtkfile_env;
76int authok;
9bcf1061 77#endif
86eb6c9e 78
659be7fb
MK
79struct passwd *pwd;
80int failures;
657e5a3c 81char term[64], *envinit[1], *hostname, *username, *tty;
88a01c09 82
f4d21924 83int
c91c86eb
KB
84char *months[] =
85 { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
86 "Sep", "Oct", "Nov", "Dec" };
87
88a01c09 88main(argc, argv)
80f91e3f 89 int argc;
f4d21924 90 char *argv[];
88a01c09 91{
f4d21924 92 extern char **environ;
f4d21924
KB
93 struct group *gr;
94 struct stat st;
95 struct timeval tp;
96 struct utmp utmp;
cc952d1c
JSP
97 int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
98 uid_t uid;
99 char *domain, *p, *salt, *ttyn;
a339b173 100 char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
e2a7a526 101 char localhost[MAXHOSTNAMELEN];
80f91e3f
KB
102
103 (void)signal(SIGALRM, timedout);
cc952d1c 104 (void)alarm(timeout);
80f91e3f
KB
105 (void)signal(SIGQUIT, SIG_IGN);
106 (void)signal(SIGINT, SIG_IGN);
107 (void)setpriority(PRIO_PROCESS, 0, 0);
80f91e3f 108
9e76b9f1
KB
109 openlog("login", LOG_ODELAY, LOG_AUTH);
110
3b8dd95e 111 /*
d3737d51 112 * -p is used by getty to tell login not to destroy the environment
d0faf133 113 * -r is used by rlogind to cause the autologin protocol;
80fc9234 114 * -f is used to skip a second login authentication
ee1eff74
MK
115 * -h is used by other servers to pass the name of the remote
116 * host to login so that it may be placed in utmp and wtmp
3b8dd95e 117 */
e2a7a526
KF
118 domain = NULL;
119 if (gethostname(localhost, sizeof(localhost)) < 0)
120 syslog(LOG_ERR, "couldn't get local hostname: %m");
121 else
cc952d1c 122 domain = strchr(localhost, '.');
80f91e3f 123
d0faf133 124 fflag = hflag = pflag = rflag = 0;
2d4a74b8 125 uid = getuid();
d0faf133 126 while ((ch = getopt(argc, argv, "fh:pr:")) != EOF)
ede75793 127 switch (ch) {
80f91e3f 128 case 'f':
d0faf133
KB
129 if (rflag) {
130 fprintf(stderr,
131 "login: only one of -r and -f allowed.\n");
132 exit(1);
133 }
80f91e3f 134 fflag = 1;
80f91e3f
KB
135 break;
136 case 'h':
cc952d1c
JSP
137 if (uid)
138 errx(1, "-h option: %s", strerror(EPERM));
d0faf133
KB
139 if (rflag) {
140 fprintf(stderr,
141 "login: only one of -r and -h allowed.\n");
142 exit(1);
143 }
80f91e3f 144 hflag = 1;
cc952d1c 145 if (domain && (p = strchr(optarg, '.')) &&
abc4056e 146 strcasecmp(p, domain) == 0)
80f91e3f
KB
147 *p = 0;
148 hostname = optarg;
149 break;
150 case 'p':
d3737d51 151 pflag = 1;
80f91e3f 152 break;
d0faf133
KB
153 case 'r':
154 if (hflag || fflag) {
155 fprintf(stderr,
156 "login: -f and -h not allowed with -r.\n");
157 exit(1);
158 }
159 if (getuid()) {
160 fprintf(stderr,
161 "login: -r for super-user only.\n");
162 exit(1);
163 }
164 /* "-r hostname" must be last args */
165 if (optind != argc) {
166 fprintf(stderr, "Syntax error.\n");
167 exit(1);
168 }
169 rflag = 1;
170 passwd_req = (doremotelogin(optarg) == -1);
171 if (domain && (p = index(optarg, '.')) &&
172 !strcmp(p, domain))
173 *p = '\0';
174 hostname = optarg;
175 break;
80f91e3f
KB
176 case '?':
177 default:
2d4a74b8
KF
178 if (!uid)
179 syslog(LOG_ERR, "invalid flag %c", ch);
0e08a2b3 180 (void)fprintf(stderr,
5da51d2c 181 "usage: login [-fp] [-h hostname] [username]\n");
80f91e3f 182 exit(1);
d3737d51 183 }
80f91e3f
KB
184 argc -= optind;
185 argv += optind;
f4d21924 186
f0c0c252 187 if (*argv) {
80f91e3f 188 username = *argv;
659be7fb
MK
189 ask = 0;
190 } else
f0c0c252 191 ask = 1;
d0faf133
KB
192 if (rflag)
193 ask = 0;
80f91e3f 194
80f91e3f 195 for (cnt = getdtablesize(); cnt > 2; cnt--)
f4d21924 196 (void)close(cnt);
80f91e3f 197
f4d21924 198 ttyn = ttyname(STDIN_FILENO);
a339b173 199 if (ttyn == NULL || *ttyn == '\0') {
f4d21924 200 (void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
a339b173
KB
201 ttyn = tname;
202 }
cc952d1c 203 if (tty = strrchr(ttyn, '/'))
80f91e3f 204 ++tty;
9479aa87 205 else
80f91e3f
KB
206 tty = ttyn;
207
f0c0c252 208 for (cnt = 0;; ask = 1) {
f0c0c252 209 if (ask) {
ede75793 210 fflag = 0;
80f91e3f 211 getloginname();
ede75793 212 }
2b584583 213 rootlogin = 0;
48f66865 214#ifdef KERBEROS
cc952d1c 215 if ((instance = strchr(username, '.')) != NULL) {
48f66865 216 if (strncmp(instance, ".root", 5) == 0)
2b584583 217 rootlogin = 1;
48f66865 218 *instance++ = '\0';
2b584583 219 } else
48f66865 220 instance = "";
48f66865
MK
221#endif
222 if (strlen(username) > UT_NAMESIZE)
223 username[UT_NAMESIZE] = '\0';
224
659be7fb 225 /*
2d4a74b8
KF
226 * Note if trying multiple user names; log failures for
227 * previous user name, but don't bother logging one failure
659be7fb
MK
228 * for nonexistent name (mistyped username).
229 */
230 if (failures && strcmp(tbuf, username)) {
231 if (failures > (pwd ? 0 : 1))
f0c0c252 232 badlogin(tbuf);
659be7fb 233 failures = 0;
f0c0c252 234 }
659be7fb 235 (void)strcpy(tbuf, username);
320a5e84 236
ede75793
KB
237 if (pwd = getpwnam(username))
238 salt = pwd->pw_passwd;
320a5e84
KB
239 else
240 salt = "xx";
80f91e3f 241
3b8dd95e 242 /*
cb400a97
KB
243 * if we have a valid account name, and it doesn't have a
244 * password, or the -f option was specified and the caller
245 * is root or the caller isn't changing their uid, don't
246 * authenticate.
3b8dd95e 247 */
cb400a97
KB
248 if (pwd && (*pwd->pw_passwd == '\0' ||
249 fflag && (uid == 0 || uid == pwd->pw_uid)))
80f91e3f 250 break;
e83bda0c 251 fflag = 0;
48f66865
MK
252 if (pwd && pwd->pw_uid == 0)
253 rootlogin = 1;
254
255 (void)setpriority(PRIO_PROCESS, 0, -4);
256
257 p = getpass("Password:");
258
259 if (pwd) {
260#ifdef KERBEROS
261 rval = klogin(pwd, instance, localhost, p);
011f52c6
JSP
262 if (rval != 0 && rootlogin && pwd->pw_uid != 0)
263 rootlogin = 0;
48f66865
MK
264 if (rval == 0)
265 authok = 1;
2b584583 266 else if (rval == 1)
48f66865 267 rval = strcmp(crypt(p, salt), pwd->pw_passwd);
48f66865
MK
268#else
269 rval = strcmp(crypt(p, salt), pwd->pw_passwd);
270#endif
271 }
cc952d1c 272 memset(p, 0, strlen(p));
48f66865
MK
273
274 (void)setpriority(PRIO_PROCESS, 0, 0);
80f91e3f 275
2d4a74b8 276 /*
48f66865
MK
277 * If trying to log in as root without Kerberos,
278 * but with insecure terminal, refuse the login attempt.
2d4a74b8 279 */
48f66865
MK
280#ifdef KERBEROS
281 if (authok == 0)
282#endif
283 if (pwd && rootlogin && !rootterm(tty)) {
2d4a74b8
KF
284 (void)fprintf(stderr,
285 "%s login refused on this terminal.\n",
286 pwd->pw_name);
287 if (hostname)
288 syslog(LOG_NOTICE,
289 "LOGIN %s REFUSED FROM %s ON TTY %s",
290 pwd->pw_name, hostname, tty);
291 else
292 syslog(LOG_NOTICE,
293 "LOGIN %s REFUSED ON TTY %s",
294 pwd->pw_name, tty);
295 continue;
296 }
297
320a5e84 298 if (pwd && !rval)
80f91e3f
KB
299 break;
300
320a5e84 301 (void)printf("Login incorrect\n");
659be7fb 302 failures++;
f0c0c252
KB
303 /* we allow 10 tries, but after 3 we start backing off */
304 if (++cnt > 3) {
305 if (cnt >= 10) {
306 badlogin(username);
f0c0c252
KB
307 sleepexit(1);
308 }
309 sleep((u_int)((cnt - 3) * 5));
f570e1ff 310 }
80f91e3f 311 }
88a01c09 312
80f91e3f
KB
313 /* committed to login -- turn off timeout */
314 (void)alarm((u_int)0);
315
a339b173
KB
316 endpwent();
317
c374ff7b 318 /* if user not super-user, check for disabled logins */
5da51d2c 319 if (!rootlogin)
c374ff7b
KB
320 checknologin();
321
ede75793 322 if (chdir(pwd->pw_dir) < 0) {
5da51d2c 323 (void)printf("No home directory %s!\n", pwd->pw_dir);
ede75793
KB
324 if (chdir("/"))
325 exit(0);
326 pwd->pw_dir = "/";
0e08a2b3 327 (void)printf("Logging in with home = \"/\".\n");
ede75793 328 }
83cc7253
KB
329#define TWOWEEKS (14*24*60*60)
330 if (pwd->pw_change || pwd->pw_expire)
331 (void)gettimeofday(&tp, (struct timezone *)NULL);
332 if (pwd->pw_change)
333 if (tp.tv_sec >= pwd->pw_change) {
334 printf("Sorry -- your password has expired.\n");
335 sleepexit(1);
336 }
337 else if (tp.tv_sec - pwd->pw_change < TWOWEEKS) {
338 ttp = localtime(&pwd->pw_change);
339 printf("Warning: your password expires on %s %d, 19%d\n",
340 months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
341 }
342 if (pwd->pw_expire)
343 if (tp.tv_sec >= pwd->pw_expire) {
344 printf("Sorry -- your account has expired.\n");
345 sleepexit(1);
346 }
347 else if (tp.tv_sec - pwd->pw_expire < TWOWEEKS) {
348 ttp = localtime(&pwd->pw_expire);
349 printf("Warning: your account expires on %s %d, 19%d\n",
350 months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
351 }
352
c91c86eb
KB
353 if (pwd->pw_change || pwd->pw_expire)
354 (void)gettimeofday(&tp, (struct timezone *)NULL);
355 if (pwd->pw_change)
356 if (tp.tv_sec >= pwd->pw_change) {
0e08a2b3 357 (void)printf("Sorry -- your password has expired.\n");
c91c86eb 358 sleepexit(1);
48f66865 359 } else if (pwd->pw_change - tp.tv_sec <
44d9892d
KB
360 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
361 (void)printf("Warning: your password expires on %s",
28878bf0 362 ctime(&pwd->pw_change));
c91c86eb
KB
363 if (pwd->pw_expire)
364 if (tp.tv_sec >= pwd->pw_expire) {
0e08a2b3 365 (void)printf("Sorry -- your account has expired.\n");
c91c86eb 366 sleepexit(1);
48f66865 367 } else if (pwd->pw_expire - tp.tv_sec <
44d9892d
KB
368 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
369 (void)printf("Warning: your account expires on %s",
370 ctime(&pwd->pw_expire));
c91c86eb 371
f4d21924 372 /* Nothing else left to fail -- really log in. */
cc952d1c 373 memset((void *)&utmp, 0, sizeof(utmp));
f4d21924 374 (void)time(&utmp.ut_time);
80fc9234 375 (void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
f4d21924
KB
376 if (hostname)
377 (void)strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
378 (void)strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
379 login(&utmp);
80f91e3f 380
f0c0c252 381 dolastlog(quietlog);
80f91e3f 382
80f91e3f
KB
383 (void)chown(ttyn, pwd->pw_uid,
384 (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
80f91e3f
KB
385 (void)setgid(pwd->pw_gid);
386
387 initgroups(username, pwd->pw_gid);
388
ede75793 389 if (*pwd->pw_shell == '\0')
fb6e7f7e 390 pwd->pw_shell = _PATH_BSHELL;
ede75793 391
f4d21924 392 /* Destroy environment unless user has requested its preservation. */
d3737d51
SL
393 if (!pflag)
394 environ = envinit;
ede75793
KB
395 (void)setenv("HOME", pwd->pw_dir, 1);
396 (void)setenv("SHELL", pwd->pw_shell, 1);
d3737d51 397 if (term[0] == '\0')
80fc9234 398 (void)strncpy(term, stypeof(tty), sizeof(term));
ede75793 399 (void)setenv("TERM", term, 0);
0e1bafef 400 (void)setenv("LOGNAME", pwd->pw_name, 1);
ede75793 401 (void)setenv("USER", pwd->pw_name, 1);
c502712b 402 (void)setenv("PATH", _PATH_DEFPATH, 0);
48f66865
MK
403#ifdef KERBEROS
404 if (krbtkfile_env)
405 (void)setenv("KRBTKFILE", krbtkfile_env, 1);
406#endif
d3737d51 407
9479aa87 408 if (tty[sizeof("tty")-1] == 'd')
d3737d51 409 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
f4d21924
KB
410
411 /* If fflag is on, assume caller/authenticator has logged root login. */
48f66865 412 if (rootlogin && fflag == 0)
80f91e3f 413 if (hostname)
0cbdb7cb
KF
414 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
415 username, tty, hostname);
df9d9536 416 else
0cbdb7cb 417 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
80f91e3f 418
9bcf1061
KB
419#ifdef KERBEROS
420 if (!quietlog && notickets == 1)
421 (void)printf("Warning: no Kerberos tickets issued.\n");
422#endif
423
4f8d3876 424 if (!quietlog) {
89e39ba5 425 (void)printf("%s\n\t%s %s\n\n",
55f766c6 426 "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
89e39ba5
KM
427 "The Regents of the University of California. ",
428 "All rights reserved.");
80f91e3f 429 motd();
f4d21924
KB
430 (void)snprintf(tbuf,
431 sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
80f91e3f 432 if (stat(tbuf, &st) == 0 && st.st_size != 0)
0e08a2b3 433 (void)printf("You have %smail.\n",
80f91e3f 434 (st.st_mtime > st.st_atime) ? "new " : "");
f570e1ff 435 }
80f91e3f
KB
436
437 (void)signal(SIGALRM, SIG_DFL);
438 (void)signal(SIGQUIT, SIG_DFL);
439 (void)signal(SIGINT, SIG_DFL);
440 (void)signal(SIGTSTP, SIG_IGN);
441
442 tbuf[0] = '-';
cc952d1c 443 (void)strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
80f91e3f 444 p + 1 : pwd->pw_shell);
0e08a2b3 445
3d28f6dd
KS
446 if (setlogin(pwd->pw_name) < 0)
447 syslog(LOG_ERR, "setlogin() failure: %m");
a339b173 448
2b584583 449 /* Discard permissions last so can't get killed and drop core. */
48f66865 450 if (rootlogin)
0cbdb7cb
KF
451 (void) setuid(0);
452 else
48f66865 453 (void) setuid(pwd->pw_uid);
0e08a2b3 454
80f91e3f 455 execlp(pwd->pw_shell, tbuf, 0);
cc952d1c 456 err(1, "%s", pwd->pw_shell);
88a01c09
BJ
457}
458
0cbdb7cb 459#ifdef KERBEROS
f4d21924 460#define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */
0cbdb7cb
KF
461#else
462#define NBUFSIZ (UT_NAMESIZE + 1)
463#endif
464
f4d21924 465void
80f91e3f 466getloginname()
3b8dd95e 467{
cc952d1c
JSP
468 int ch;
469 char *p;
0cbdb7cb 470 static char nbuf[NBUFSIZ];
3b8dd95e 471
80f91e3f 472 for (;;) {
0e08a2b3 473 (void)printf("login: ");
ede75793 474 for (p = nbuf; (ch = getchar()) != '\n'; ) {
f0c0c252
KB
475 if (ch == EOF) {
476 badlogin(username);
3b8dd95e 477 exit(0);
f0c0c252 478 }
0cbdb7cb 479 if (p < nbuf + (NBUFSIZ - 1))
80f91e3f 480 *p++ = ch;
3b8dd95e 481 }
80f91e3f
KB
482 if (p > nbuf)
483 if (nbuf[0] == '-')
0e08a2b3 484 (void)fprintf(stderr,
80f91e3f
KB
485 "login names may not start with '-'.\n");
486 else {
487 *p = '\0';
488 username = nbuf;
ede75793 489 break;
80f91e3f 490 }
3b8dd95e 491 }
3b8dd95e
SL
492}
493
f4d21924 494int
659be7fb
MK
495rootterm(ttyn)
496 char *ttyn;
88a01c09 497{
80f91e3f 498 struct ttyent *t;
1886582e 499
cc952d1c 500 return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
88a01c09
BJ
501}
502
ede75793
KB
503jmp_buf motdinterrupt;
504
f4d21924 505void
80f91e3f 506motd()
f570e1ff 507{
cc952d1c 508 int fd, nchars;
b32e4ad7 509 sig_t oldint;
ede75793 510 char tbuf[8192];
80f91e3f 511
fb6e7f7e 512 if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
80f91e3f
KB
513 return;
514 oldint = signal(SIGINT, sigint);
ede75793
KB
515 if (setjmp(motdinterrupt) == 0)
516 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
517 (void)write(fileno(stdout), tbuf, nchars);
80f91e3f 518 (void)signal(SIGINT, oldint);
ede75793 519 (void)close(fd);
80f91e3f 520}
9479aa87 521
f4d21924 522/* ARGSUSED */
bc0c28c1 523void
f4d21924
KB
524sigint(signo)
525 int signo;
80f91e3f 526{
cc952d1c 527
ede75793 528 longjmp(motdinterrupt, 1);
80f91e3f
KB
529}
530
f4d21924
KB
531/* ARGSUSED */
532void
533timedout(signo)
534 int signo;
535{
cc952d1c 536
f4d21924
KB
537 (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
538 exit(0);
539}
540
541void
80f91e3f
KB
542checknologin()
543{
cc952d1c 544 int fd, nchars;
ede75793 545 char tbuf[8192];
80f91e3f 546
fb6e7f7e 547 if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
80f91e3f
KB
548 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
549 (void)write(fileno(stdout), tbuf, nchars);
550 sleepexit(0);
f570e1ff 551 }
f570e1ff
BJ
552}
553
f4d21924 554void
f0c0c252 555dolastlog(quiet)
80f91e3f 556 int quiet;
88a01c09 557{
80f91e3f
KB
558 struct lastlog ll;
559 int fd;
c91c86eb 560 char *ctime();
80f91e3f 561
fb6e7f7e 562 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
ede75793 563 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
80f91e3f
KB
564 if (!quiet) {
565 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
566 ll.ll_time != 0) {
0e08a2b3 567 (void)printf("Last login: %.*s ",
80f91e3f
KB
568 24-5, (char *)ctime(&ll.ll_time));
569 if (*ll.ll_host != '\0')
0e08a2b3 570 (void)printf("from %.*s\n",
80fc9234
KB
571 (int)sizeof(ll.ll_host),
572 ll.ll_host);
80f91e3f 573 else
0e08a2b3 574 (void)printf("on %.*s\n",
80fc9234
KB
575 (int)sizeof(ll.ll_line),
576 ll.ll_line);
80f91e3f 577 }
ede75793 578 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
80f91e3f 579 }
cc952d1c 580 memset((void *)&ll, 0, sizeof(ll));
80f91e3f 581 (void)time(&ll.ll_time);
80fc9234 582 (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
a829b33b 583 if (hostname)
80fc9234 584 (void)strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
80f91e3f
KB
585 (void)write(fd, (char *)&ll, sizeof(ll));
586 (void)close(fd);
88a01c09 587 }
88a01c09
BJ
588}
589
f4d21924 590void
f0c0c252
KB
591badlogin(name)
592 char *name;
593{
cc952d1c 594
659be7fb 595 if (failures == 0)
f0c0c252 596 return;
fdc8f1ac
KB
597 if (hostname) {
598 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
599 failures, failures > 1 ? "S" : "", hostname);
600 syslog(LOG_AUTHPRIV|LOG_NOTICE,
601 "%d LOGIN FAILURE%s FROM %s, %s",
659be7fb 602 failures, failures > 1 ? "S" : "", hostname, name);
fdc8f1ac
KB
603 } else {
604 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
605 failures, failures > 1 ? "S" : "", tty);
606 syslog(LOG_AUTHPRIV|LOG_NOTICE,
607 "%d LOGIN FAILURE%s ON %s, %s",
659be7fb 608 failures, failures > 1 ? "S" : "", tty, name);
fdc8f1ac 609 }
f0c0c252
KB
610}
611
f570e1ff 612#undef UNKNOWN
80f91e3f 613#define UNKNOWN "su"
88a01c09
BJ
614
615char *
659be7fb
MK
616stypeof(ttyid)
617 char *ttyid;
88a01c09 618{
80f91e3f 619 struct ttyent *t;
88a01c09 620
cc952d1c 621 return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
88a01c09 622}
86eb6c9e 623
f4d21924 624void
80f91e3f
KB
625sleepexit(eval)
626 int eval;
c89291e2 627{
cc952d1c
JSP
628
629 (void)sleep(5);
80f91e3f 630 exit(eval);
c89291e2 631}
d0faf133
KB
632
633doremotelogin(host)
634 char *host;
635{
636 static char lusername[UT_NAMESIZE+1];
637 char rusername[UT_NAMESIZE+1];
638
639 getstr(rusername, sizeof(rusername), "remuser");
640 getstr(lusername, sizeof(lusername), "locuser");
641 getstr(term, sizeof(term), "Terminal type");
642 username = lusername;
643 pwd = getpwnam(username);
644 if (pwd == NULL)
645 return(-1);
646 return(ruserok(host, (pwd->pw_uid == 0), rusername, username));
647}
648
649char *speeds[] = {
650 "0", "50", "75", "110", "134", "150", "200", "300", "600",
651 "1200", "1800", "2400", "4800", "9600", "19200", "38400",
652};
653#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0]))
654
655doremoteterm(tp)
656 struct sgttyb *tp;
657{
658 register char *cp = index(term, '/'), **cpp;
659 char *speed;
660
661 if (cp) {
662 *cp++ = '\0';
663 speed = cp;
664 cp = index(speed, '/');
665 if (cp)
666 *cp++ = '\0';
667 for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
668 if (strcmp(*cpp, speed) == 0) {
669 tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
670 break;
671 }
672 }
673 tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
674}