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