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