remove BSD ifdefs
[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
fc532fe5 25static char sccsid[] = "@(#)login.c 5.45 (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>
80f91e3f 41#include <sys/ioctl.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
d0faf133 126 fflag = hflag = pflag = rflag = 0;
80f91e3f 127 passwd_req = 1;
d0faf133 128 while ((ch = getopt(argc, argv, "fh:pr:")) != EOF)
ede75793 129 switch (ch) {
80f91e3f 130 case 'f':
d0faf133
KB
131 if (rflag) {
132 fprintf(stderr,
133 "login: only one of -r and -f allowed.\n");
134 exit(1);
135 }
80f91e3f 136 fflag = 1;
80f91e3f
KB
137 break;
138 case 'h':
139 if (getuid()) {
0e08a2b3 140 (void)fprintf(stderr,
80f91e3f 141 "login: -h for super-user only.\n");
b6f7cade 142 exit(1);
5dbe2745 143 }
d0faf133
KB
144 if (rflag) {
145 fprintf(stderr,
146 "login: only one of -r and -h allowed.\n");
147 exit(1);
148 }
80f91e3f
KB
149 hflag = 1;
150 if (domain && (p = index(optarg, '.')) &&
abc4056e 151 strcasecmp(p, domain) == 0)
80f91e3f
KB
152 *p = 0;
153 hostname = optarg;
154 break;
155 case 'p':
d3737d51 156 pflag = 1;
80f91e3f 157 break;
d0faf133
KB
158 case 'r':
159 if (hflag || fflag) {
160 fprintf(stderr,
161 "login: -f and -h not allowed with -r.\n");
162 exit(1);
163 }
164 if (getuid()) {
165 fprintf(stderr,
166 "login: -r for super-user only.\n");
167 exit(1);
168 }
169 /* "-r hostname" must be last args */
170 if (optind != argc) {
171 fprintf(stderr, "Syntax error.\n");
172 exit(1);
173 }
174 rflag = 1;
175 passwd_req = (doremotelogin(optarg) == -1);
176 if (domain && (p = index(optarg, '.')) &&
177 !strcmp(p, domain))
178 *p = '\0';
179 hostname = optarg;
180 break;
80f91e3f
KB
181 case '?':
182 default:
b32e4ad7 183 syslog(LOG_ERR, "invalid flag");
0e08a2b3
KB
184 (void)fprintf(stderr,
185 "usage: login [-fp] [username]\n");
80f91e3f 186 exit(1);
d3737d51 187 }
80f91e3f
KB
188 argc -= optind;
189 argv += optind;
f0c0c252 190 if (*argv) {
80f91e3f 191 username = *argv;
659be7fb
MK
192 ask = 0;
193 } else
f0c0c252 194 ask = 1;
d0faf133
KB
195 if (rflag)
196 ask = 0;
80f91e3f
KB
197
198 ioctlval = 0;
199 (void)ioctl(0, TIOCLSET, &ioctlval);
200 (void)ioctl(0, TIOCNXCL, 0);
ede75793
KB
201 (void)fcntl(0, F_SETFL, ioctlval);
202 (void)ioctl(0, TIOCGETP, &sgttyb);
d0faf133
KB
203
204 /*
205 * If talking to an rlogin process, propagate the terminal type and
206 * baud rate across the network.
207 */
208 if (rflag)
209 doremoteterm(&sgttyb);
ede75793
KB
210 sgttyb.sg_erase = CERASE;
211 sgttyb.sg_kill = CKILL;
80f91e3f
KB
212 (void)ioctl(0, TIOCSLTC, &ltc);
213 (void)ioctl(0, TIOCSETC, &tc);
ede75793 214 (void)ioctl(0, TIOCSETP, &sgttyb);
80f91e3f
KB
215
216 for (cnt = getdtablesize(); cnt > 2; cnt--)
217 close(cnt);
218
88a01c09 219 ttyn = ttyname(0);
a339b173
KB
220 if (ttyn == NULL || *ttyn == '\0') {
221 (void)sprintf(tname, "%s??", _PATH_TTY);
222 ttyn = tname;
223 }
80f91e3f
KB
224 if (tty = rindex(ttyn, '/'))
225 ++tty;
9479aa87 226 else
80f91e3f
KB
227 tty = ttyn;
228
076ae92c 229 openlog("login", LOG_ODELAY, LOG_AUTH);
80f91e3f 230
f0c0c252 231 for (cnt = 0;; ask = 1) {
7e845b92 232 ioctlval = TTYDISC;
80f91e3f
KB
233 (void)ioctl(0, TIOCSETD, &ioctlval);
234
f0c0c252 235 if (ask) {
ede75793 236 fflag = 0;
80f91e3f 237 getloginname();
ede75793 238 }
659be7fb
MK
239 /*
240 * Note if trying multiple user names;
241 * log failures for previous user name,
242 * but don't bother logging one failure
243 * for nonexistent name (mistyped username).
244 */
245 if (failures && strcmp(tbuf, username)) {
246 if (failures > (pwd ? 0 : 1))
f0c0c252 247 badlogin(tbuf);
659be7fb 248 failures = 0;
f0c0c252 249 }
659be7fb 250 (void)strcpy(tbuf, username);
ede75793
KB
251 if (pwd = getpwnam(username))
252 salt = pwd->pw_passwd;
253 else
254 salt = "xx";
80f91e3f
KB
255
256 /* if user not super-user, check for disabled logins */
ede75793 257 if (pwd == NULL || pwd->pw_uid)
80f91e3f
KB
258 checknologin();
259
3b8dd95e 260 /*
ede75793
KB
261 * Disallow automatic login to root; if not invoked by
262 * root, disallow if the uid's differ.
3b8dd95e 263 */
ede75793 264 if (fflag && pwd) {
5dbe2745
MK
265 int uid = getuid();
266
b32e4ad7
KF
267 passwd_req =
268#ifndef KERBEROS
269 pwd->pw_uid == 0 ||
270#endif
ede75793 271 (uid && uid != pwd->pw_uid);
f570e1ff 272 }
80f91e3f 273
3b8dd95e 274 /*
ee1eff74 275 * If no pre-authentication and a password exists
80f91e3f 276 * for this user, prompt for one and verify it.
3b8dd95e 277 */
9d6a5a69 278 if (!passwd_req || (pwd && !*pwd->pw_passwd))
80f91e3f
KB
279 break;
280
281 setpriority(PRIO_PROCESS, 0, -4);
9d6a5a69
KF
282 pp = getpass("Password:");
283 p = crypt(pp, salt);
80f91e3f 284 setpriority(PRIO_PROCESS, 0, 0);
9d6a5a69 285
9d6a5a69 286 (void) bzero(pp, strlen(pp));
ede75793 287 if (pwd && !strcmp(p, pwd->pw_passwd))
80f91e3f
KB
288 break;
289
0e08a2b3 290 (void)printf("Login incorrect\n");
659be7fb 291 failures++;
f0c0c252
KB
292 /* we allow 10 tries, but after 3 we start backing off */
293 if (++cnt > 3) {
294 if (cnt >= 10) {
295 badlogin(username);
296 (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL);
297 sleepexit(1);
298 }
299 sleep((u_int)((cnt - 3) * 5));
f570e1ff 300 }
80f91e3f 301 }
88a01c09 302
80f91e3f
KB
303 /* committed to login -- turn off timeout */
304 (void)alarm((u_int)0);
305
a339b173
KB
306 /* paranoia... */
307 endpwent();
308
80f91e3f
KB
309 /*
310 * If valid so far and root is logging in, see if root logins on
311 * this terminal are permitted.
312 */
659be7fb 313 if (pwd->pw_uid == 0 && !rootterm(tty)) {
80f91e3f 314 if (hostname)
659be7fb
MK
315 syslog(LOG_NOTICE, "ROOT LOGIN REFUSED FROM %s",
316 hostname);
22d4760e 317 else
659be7fb 318 syslog(LOG_NOTICE, "ROOT LOGIN REFUSED ON %s", tty);
0e08a2b3 319 (void)printf("Login incorrect\n");
80f91e3f 320 sleepexit(1);
22d4760e 321 }
80f91e3f 322
80f91e3f
KB
323 if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
324 switch(errno) {
325 case EUSERS:
0e08a2b3 326 (void)fprintf(stderr,
80f91e3f
KB
327 "Too many users logged on already.\nTry again later.\n");
328 break;
329 case EPROCLIM:
0e08a2b3 330 (void)fprintf(stderr,
80f91e3f
KB
331 "You have too many processes running.\n");
332 break;
333 default:
334 perror("quota (Q_SETUID)");
f570e1ff 335 }
80f91e3f
KB
336 sleepexit(0);
337 }
338
ede75793 339 if (chdir(pwd->pw_dir) < 0) {
0e08a2b3 340 (void)printf("No directory %s!\n", pwd->pw_dir);
ede75793
KB
341 if (chdir("/"))
342 exit(0);
343 pwd->pw_dir = "/";
0e08a2b3 344 (void)printf("Logging in with home = \"/\".\n");
ede75793
KB
345 }
346
83cc7253
KB
347#define TWOWEEKS (14*24*60*60)
348 if (pwd->pw_change || pwd->pw_expire)
349 (void)gettimeofday(&tp, (struct timezone *)NULL);
350 if (pwd->pw_change)
351 if (tp.tv_sec >= pwd->pw_change) {
352 printf("Sorry -- your password has expired.\n");
353 sleepexit(1);
354 }
355 else if (tp.tv_sec - pwd->pw_change < TWOWEEKS) {
356 ttp = localtime(&pwd->pw_change);
357 printf("Warning: your password expires on %s %d, 19%d\n",
358 months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
359 }
360 if (pwd->pw_expire)
361 if (tp.tv_sec >= pwd->pw_expire) {
362 printf("Sorry -- your account has expired.\n");
363 sleepexit(1);
364 }
365 else if (tp.tv_sec - pwd->pw_expire < TWOWEEKS) {
366 ttp = localtime(&pwd->pw_expire);
367 printf("Warning: your account expires on %s %d, 19%d\n",
368 months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year);
369 }
370
c91c86eb
KB
371 if (pwd->pw_change || pwd->pw_expire)
372 (void)gettimeofday(&tp, (struct timezone *)NULL);
373 if (pwd->pw_change)
374 if (tp.tv_sec >= pwd->pw_change) {
0e08a2b3 375 (void)printf("Sorry -- your password has expired.\n");
c91c86eb
KB
376 sleepexit(1);
377 }
50112e48
KB
378 else if (pwd->pw_change - tp.tv_sec <
379 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) {
c91c86eb 380 ttp = localtime(&pwd->pw_change);
0e08a2b3 381 (void)printf("Warning: your password expires on %s %d, %d\n",
50112e48
KB
382 months[ttp->tm_mon], ttp->tm_mday,
383 TM_YEAR_BASE + ttp->tm_year);
c91c86eb
KB
384 }
385 if (pwd->pw_expire)
386 if (tp.tv_sec >= pwd->pw_expire) {
0e08a2b3 387 (void)printf("Sorry -- your account has expired.\n");
c91c86eb
KB
388 sleepexit(1);
389 }
50112e48
KB
390 else if (pwd->pw_expire - tp.tv_sec <
391 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) {
c91c86eb 392 ttp = localtime(&pwd->pw_expire);
0e08a2b3 393 (void)printf("Warning: your account expires on %s %d, %d\n",
50112e48
KB
394 months[ttp->tm_mon], ttp->tm_mday,
395 TM_YEAR_BASE + ttp->tm_year);
c91c86eb
KB
396 }
397
ede75793 398 /* nothing else left to fail -- really log in */
80f91e3f
KB
399 {
400 struct utmp utmp;
401
659be7fb 402 bzero((char *)&utmp, sizeof(utmp));
80f91e3f
KB
403 (void)time(&utmp.ut_time);
404 strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
a829b33b
KB
405 if (hostname)
406 strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
80f91e3f
KB
407 strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
408 login(&utmp);
f570e1ff 409 }
80f91e3f 410
f0c0c252 411 dolastlog(quietlog);
80f91e3f 412
d0faf133 413 if (!hflag && !rflag) { /* XXX */
80f91e3f
KB
414 static struct winsize win = { 0, 0, 0, 0 };
415
416 (void)ioctl(0, TIOCSWINSZ, &win);
417 }
418
419 (void)chown(ttyn, pwd->pw_uid,
420 (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
421 (void)chmod(ttyn, 0620);
422 (void)setgid(pwd->pw_gid);
423
424 initgroups(username, pwd->pw_gid);
425
22d4760e 426 quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
3daca631 427
ede75793 428 if (*pwd->pw_shell == '\0')
fb6e7f7e 429 pwd->pw_shell = _PATH_BSHELL;
ede75793 430
80f91e3f 431 /* destroy environment unless user has requested preservation */
d3737d51
SL
432 if (!pflag)
433 environ = envinit;
ede75793
KB
434 (void)setenv("HOME", pwd->pw_dir, 1);
435 (void)setenv("SHELL", pwd->pw_shell, 1);
d3737d51 436 if (term[0] == '\0')
659be7fb 437 strncpy(term, stypeof(tty), sizeof(term));
ede75793
KB
438 (void)setenv("TERM", term, 0);
439 (void)setenv("USER", pwd->pw_name, 1);
c502712b 440 (void)setenv("PATH", _PATH_DEFPATH, 0);
d3737d51 441
9479aa87 442 if (tty[sizeof("tty")-1] == 'd')
d3737d51
SL
443 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
444 if (pwd->pw_uid == 0)
80f91e3f 445 if (hostname)
659be7fb 446 syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s",
f0c0c252 447 tty, hostname);
df9d9536 448 else
659be7fb 449 syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty);
80f91e3f 450
4f8d3876 451 if (!quietlog) {
6821e9c5 452 struct stat st;
d3737d51 453
80f91e3f 454 motd();
fb6e7f7e 455 (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
80f91e3f 456 if (stat(tbuf, &st) == 0 && st.st_size != 0)
0e08a2b3 457 (void)printf("You have %smail.\n",
80f91e3f 458 (st.st_mtime > st.st_atime) ? "new " : "");
f570e1ff 459 }
80f91e3f
KB
460
461 (void)signal(SIGALRM, SIG_DFL);
462 (void)signal(SIGQUIT, SIG_DFL);
463 (void)signal(SIGINT, SIG_DFL);
464 (void)signal(SIGTSTP, SIG_IGN);
465
466 tbuf[0] = '-';
467 strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ?
468 p + 1 : pwd->pw_shell);
0e08a2b3 469
a339b173
KB
470 if (setlogname(pwd->pw_name, strlen(pwd->pw_name)) < 0)
471 syslog(LOG_ERR, "setlogname() failure: %m");
472
0e08a2b3
KB
473 /* discard permissions last so can't get killed and drop core */
474 (void)setuid(pwd->pw_uid);
475
80f91e3f 476 execlp(pwd->pw_shell, tbuf, 0);
0e08a2b3 477 (void)fprintf(stderr, "login: no shell: %s.\n", strerror(errno));
88a01c09
BJ
478 exit(0);
479}
480
80f91e3f 481getloginname()
3b8dd95e 482{
80f91e3f
KB
483 register int ch;
484 register char *p;
485 static char nbuf[UT_NAMESIZE + 1];
3b8dd95e 486
80f91e3f 487 for (;;) {
0e08a2b3 488 (void)printf("login: ");
ede75793 489 for (p = nbuf; (ch = getchar()) != '\n'; ) {
f0c0c252
KB
490 if (ch == EOF) {
491 badlogin(username);
3b8dd95e 492 exit(0);
f0c0c252 493 }
ede75793 494 if (p < nbuf + UT_NAMESIZE)
80f91e3f 495 *p++ = ch;
3b8dd95e 496 }
80f91e3f
KB
497 if (p > nbuf)
498 if (nbuf[0] == '-')
0e08a2b3 499 (void)fprintf(stderr,
80f91e3f
KB
500 "login names may not start with '-'.\n");
501 else {
502 *p = '\0';
503 username = nbuf;
ede75793 504 break;
80f91e3f 505 }
3b8dd95e 506 }
3b8dd95e
SL
507}
508
509timedout()
510{
0e08a2b3 511 (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
3b8dd95e
SL
512 exit(0);
513}
514
659be7fb
MK
515rootterm(ttyn)
516 char *ttyn;
88a01c09 517{
80f91e3f 518 struct ttyent *t;
1886582e 519
659be7fb 520 return((t = getttynam(ttyn)) && t->ty_status&TTY_SECURE);
88a01c09
BJ
521}
522
ede75793
KB
523jmp_buf motdinterrupt;
524
80f91e3f 525motd()
f570e1ff 526{
ede75793 527 register int fd, nchars;
b32e4ad7
KF
528 sig_t oldint;
529 int sigint();
ede75793 530 char tbuf[8192];
80f91e3f 531
fb6e7f7e 532 if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
80f91e3f
KB
533 return;
534 oldint = signal(SIGINT, sigint);
ede75793
KB
535 if (setjmp(motdinterrupt) == 0)
536 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
537 (void)write(fileno(stdout), tbuf, nchars);
80f91e3f 538 (void)signal(SIGINT, oldint);
ede75793 539 (void)close(fd);
80f91e3f 540}
9479aa87 541
80f91e3f
KB
542sigint()
543{
ede75793 544 longjmp(motdinterrupt, 1);
80f91e3f
KB
545}
546
547checknologin()
548{
549 register int fd, nchars;
ede75793 550 char tbuf[8192];
80f91e3f 551
fb6e7f7e 552 if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
80f91e3f
KB
553 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
554 (void)write(fileno(stdout), tbuf, nchars);
555 sleepexit(0);
f570e1ff 556 }
f570e1ff
BJ
557}
558
f0c0c252 559dolastlog(quiet)
80f91e3f 560 int quiet;
88a01c09 561{
80f91e3f
KB
562 struct lastlog ll;
563 int fd;
c91c86eb 564 char *ctime();
83cc7253 565 char *ctime();
80f91e3f 566
fb6e7f7e 567 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
ede75793 568 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
80f91e3f
KB
569 if (!quiet) {
570 if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
571 ll.ll_time != 0) {
0e08a2b3 572 (void)printf("Last login: %.*s ",
80f91e3f
KB
573 24-5, (char *)ctime(&ll.ll_time));
574 if (*ll.ll_host != '\0')
0e08a2b3 575 (void)printf("from %.*s\n",
80f91e3f
KB
576 sizeof(ll.ll_host), ll.ll_host);
577 else
0e08a2b3 578 (void)printf("on %.*s\n",
80f91e3f
KB
579 sizeof(ll.ll_line), ll.ll_line);
580 }
ede75793 581 (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
80f91e3f 582 }
659be7fb 583 bzero((char *)&ll, sizeof(ll));
80f91e3f
KB
584 (void)time(&ll.ll_time);
585 strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
a829b33b
KB
586 if (hostname)
587 strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
80f91e3f
KB
588 (void)write(fd, (char *)&ll, sizeof(ll));
589 (void)close(fd);
88a01c09 590 }
88a01c09
BJ
591}
592
f0c0c252
KB
593badlogin(name)
594 char *name;
595{
659be7fb 596 if (failures == 0)
f0c0c252
KB
597 return;
598 if (hostname)
659be7fb
MK
599 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s",
600 failures, failures > 1 ? "S" : "", hostname, name);
f0c0c252 601 else
659be7fb
MK
602 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s, %s",
603 failures, failures > 1 ? "S" : "", tty, name);
f0c0c252
KB
604}
605
f570e1ff 606#undef UNKNOWN
80f91e3f 607#define UNKNOWN "su"
88a01c09
BJ
608
609char *
659be7fb
MK
610stypeof(ttyid)
611 char *ttyid;
88a01c09 612{
80f91e3f 613 struct ttyent *t;
88a01c09 614
659be7fb 615 return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
88a01c09 616}
86eb6c9e
BJ
617
618getstr(buf, cnt, err)
80f91e3f 619 char *buf, *err;
86eb6c9e 620 int cnt;
86eb6c9e 621{
80f91e3f 622 char ch;
86eb6c9e
BJ
623
624 do {
80f91e3f 625 if (read(0, &ch, sizeof(ch)) != sizeof(ch))
86eb6c9e
BJ
626 exit(1);
627 if (--cnt < 0) {
0e08a2b3 628 (void)fprintf(stderr, "%s too long\r\n", err);
80f91e3f 629 sleepexit(1);
86eb6c9e 630 }
80f91e3f
KB
631 *buf++ = ch;
632 } while (ch);
86eb6c9e 633}
4f8d3876 634
80f91e3f
KB
635sleepexit(eval)
636 int eval;
c89291e2 637{
80f91e3f
KB
638 sleep((u_int)5);
639 exit(eval);
c89291e2 640}
d0faf133
KB
641
642doremotelogin(host)
643 char *host;
644{
645 static char lusername[UT_NAMESIZE+1];
646 char rusername[UT_NAMESIZE+1];
647
648 getstr(rusername, sizeof(rusername), "remuser");
649 getstr(lusername, sizeof(lusername), "locuser");
650 getstr(term, sizeof(term), "Terminal type");
651 username = lusername;
652 pwd = getpwnam(username);
653 if (pwd == NULL)
654 return(-1);
655 return(ruserok(host, (pwd->pw_uid == 0), rusername, username));
656}
657
658char *speeds[] = {
659 "0", "50", "75", "110", "134", "150", "200", "300", "600",
660 "1200", "1800", "2400", "4800", "9600", "19200", "38400",
661};
662#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0]))
663
664doremoteterm(tp)
665 struct sgttyb *tp;
666{
667 register char *cp = index(term, '/'), **cpp;
668 char *speed;
669
670 if (cp) {
671 *cp++ = '\0';
672 speed = cp;
673 cp = index(speed, '/');
674 if (cp)
675 *cp++ = '\0';
676 for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
677 if (strcmp(*cpp, speed) == 0) {
678 tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
679 break;
680 }
681 }
682 tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
683}