2 * Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * login -h hostname (for telnetd, etc.)
37 * login -f name (for pre-authenticated login: datakit, xterm, etc.)
41 #ifdef HAVE_CAPABILITY_H
42 #include <capability.h>
44 #ifdef HAVE_SYS_CAPABILITY_H
45 #include <sys/capability.h>
48 RCSID("$Id: login.c,v 1.125 1999/11/30 19:24:01 bg Exp $");
54 #include "sysv_default.h"
56 #include "sysv_shadow.h"
59 static void badlogin (char *);
60 static void checknologin (void);
61 static void dolastlog (int);
62 static void getloginname (int);
63 static int rootterm (char *);
64 static char *stypeof (char *);
65 static RETSIGTYPE timedout (int);
66 static int doremotelogin (char *);
67 void login_fbtab (char *, uid_t, gid_t);
69 int klogin (struct passwd *, char *, char *, char *);
72 #define TTYGRPNAME "tty" /* name of group to own ttys */
75 * This bounds the time given to login. Change it in
76 * `/etc/default/login'.
79 static u_int login_timeout;
83 int noticketsdontcomplain = 1;
90 static struct spwd *spwd = NULL;
93 static char *ttyprompt;
95 static struct passwd *pwd;
97 static char term[64], *hostname, *username, *tty;
99 static char rusername[100], lusername[100];
102 change_passwd(struct passwd *who)
107 switch (pid = fork()) {
109 warn("fork /bin/passwd");
112 execlp("/bin/passwd", "passwd", who->pw_name, (char *) 0);
115 waitpid(pid, &status, 0);
120 #ifndef NO_MOTD /* message of the day stuff */
122 jmp_buf motdinterrupt;
127 longjmp(motdinterrupt, 1);
134 RETSIGTYPE (*oldint)();
137 if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
139 oldint = signal(SIGINT, sigint);
140 if (setjmp(motdinterrupt) == 0)
141 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
142 write(fileno(stdout), tbuf, nchars);
143 signal(SIGINT, oldint);
147 #endif /* !NO_MOTD */
153 * getpwnam and try to detect the worst form of NIS attack.
156 static struct passwd *
157 paranoid_getpwnam (char *user)
161 p = k_getpwnam (user);
164 if (p->pw_uid == 0 && strcmp (username, "root") != 0) {
166 "NIS attack, user %s has uid 0", username);
173 main(int argc, char **argv)
176 int ask, ch, cnt, fflag, hflag, pflag, quietlog, nomailcheck;
181 char *domain, *p, passwd[128], *ttyn;
182 char tbuf[MaxPathLen + 2], tname[sizeof(_PATH_TTY) + 10];
183 char localhost[MaxHostNameLen];
184 char full_hostname[MaxHostNameLen];
185 int auth_level = AUTH_NONE;
189 int mask = 022; /* Default umask (set below) */
190 int maxtrys = 5; /* Default number of allowed failed logins */
192 set_progname(argv[0]);
194 openlog("login", LOG_ODELAY, LOG_AUTH);
196 /* Read defaults file and set the login timeout period. */
198 login_timeout = atoi(default_timeout);
199 maxtrys = atoi(default_maxtrys);
200 if (sscanf(default_umask, "%o", &mask) != 1 || (mask & ~0777))
201 syslog(LOG_WARNING, "bad umask default: %s", default_umask);
205 signal(SIGALRM, timedout);
206 alarm(login_timeout);
207 signal(SIGQUIT, SIG_IGN);
208 signal(SIGINT, SIG_IGN);
209 setpriority(PRIO_PROCESS, 0, 0);
212 * -p is used by getty to tell login not to destroy the environment
213 * -f is used to skip a second login authentication
214 * -h is used by other servers to pass the name of the remote
215 * host to login so that it may be placed in utmp and wtmp
216 * -r is used by old-style rlogind to execute the autologin protocol
219 *full_hostname = '\0';
221 if (gethostname(localhost, sizeof(localhost)) < 0)
222 syslog(LOG_ERR, "couldn't get local hostname: %m");
224 domain = strchr(localhost, '.');
226 fflag = hflag = pflag = rflag = 0;
228 while ((ch = getopt(argc, argv, "a:d:fh:pr:")) != -1)
231 if (strcmp (optarg, "none") == 0)
232 auth_level = AUTH_NONE;
234 else if (strcmp (optarg, "otp") == 0)
235 auth_level = AUTH_OTP;
238 warnx ("bad value for -a: %s", optarg);
246 if (rflag || hflag) {
247 printf("Only one of -r and -h allowed\n");
251 errx(1, "-h option: %s", strerror(EPERM));
253 strlcpy(full_hostname,
255 sizeof(full_hostname));
256 if (domain && (p = strchr(optarg, '.')) &&
257 strcasecmp(p, domain) == 0)
263 warnx("-p for super-user only.");
269 if (rflag || hflag) {
270 warnx("Only one of -r and -h allowed\n");
274 warnx("-r for super-user only.");
278 strlcpy(full_hostname,
280 sizeof(full_hostname));
281 if (domain && (p = strchr(optarg, '.')) &&
282 strcasecmp(p, domain) == 0)
285 fflag = (doremotelogin(full_hostname) == 0);
290 syslog(LOG_ERR, "invalid flag %c", ch);
296 " [-h hostname | -r hostname] [username]\n");
302 if (geteuid() != 0) {
303 warnx("only root may use login, use su");
304 /* Or install login setuid root, which is not necessary */
309 * Figure out if we should ask for the username or not. The name
310 * may be given on the command line or via the environment, and
311 * it may even be in the terminal input queue.
314 username = lusername;
317 if (*argv && strchr(*argv, '=')) {
320 if (*argv && strcmp(*argv, "-") == 0) {
330 } else if ((ttyprompt = getenv("TTYPROMPT")) && *ttyprompt) {
336 /* Default tty settings. */
339 for (cnt = getdtablesize(); cnt > 2; cnt--)
343 * Determine the tty name. BSD takes the basename, SYSV4 takes
344 * whatever remains after stripping the "/dev/" prefix. The code
345 * below should produce sensible results in either environment.
347 ttyn = ttyname(STDIN_FILENO);
348 if (ttyn == NULL || *ttyn == '\0') {
349 snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
352 if ((tty = strchr(ttyn + 1, '/')))
357 for (cnt = 0;; ask = 1) {
358 char prompt[128], ss[256];
366 if ((instance = strchr(username, '.')) != NULL) {
367 if (strcmp(instance, ".root") == 0)
373 if (strlen(username) > UT_NAMESIZE)
374 username[UT_NAMESIZE] = '\0';
377 * Note if trying multiple user names; log failures for
378 * previous user name, but don't bother logging one failure
379 * for nonexistent name (mistyped username).
381 if (failures && strcmp(tbuf, username)) {
382 if (failures > (pwd ? 0 : 1))
386 strlcpy(tbuf, username, sizeof(tbuf));
388 pwd = paranoid_getpwnam (username);
391 * if we have a valid account name, and it doesn't have a
392 * password, or the -f option was specified and the caller
393 * is root or the caller isn't changing their uid, don't
397 if (pwd->pw_uid == 0)
400 if (fflag && (uid == 0 || uid == pwd->pw_uid)) {
401 /* already authenticated */
403 } else if (pwd->pw_passwd[0] == '\0') {
404 /* pretend password okay */
412 setpriority(PRIO_PROCESS, 0, -4);
415 if (otp_challenge (&otp_ctx, username,
416 ss, sizeof(ss)) == 0)
417 snprintf (prompt, sizeof(prompt), "%s's %s Password: ",
422 if (auth_level == AUTH_NONE)
423 snprintf(prompt, sizeof(prompt), "%s's Password: ",
430 s = otp_error(&otp_ctx);
432 printf ("OTP: %s\n", s);
438 if (des_read_pw_string (passwd, sizeof(passwd) - 1, prompt, 0))
440 passwd[sizeof(passwd) - 1] = '\0';
442 /* Verify it somehow */
445 if (otp_verify_user (&otp_ctx, passwd) == 0)
451 else if (auth_level == AUTH_NONE) {
452 uid_t pwd_uid = pwd->pw_uid;
454 rval = unix_verify_user (username, passwd);
458 if (rootlogin && pwd_uid != 0)
463 rval = klogin(pwd, instance, localhost, passwd);
464 if (rval != 0 && rootlogin && pwd_uid != 0)
474 if ((s = otp_error(&otp_ctx)))
475 printf ("OTP: %s\n", s);
479 memset (passwd, 0, sizeof(passwd));
480 setpriority (PRIO_PROCESS, 0, 0);
483 * Santa Claus, give me a portable and reentrant getpwnam.
485 pwd = paranoid_getpwnam (username);
489 * If trying to log in as root without Kerberos,
490 * but with insecure terminal, refuse the login attempt.
495 if (pwd && !rval && rootlogin && !rootterm(tty)
496 && !rootterm(ttyn)) {
497 warnx("%s login refused on this terminal.",
501 "LOGIN %s REFUSED FROM %s ON TTY %s",
502 pwd->pw_name, hostname, tty);
505 "LOGIN %s REFUSED ON TTY %s",
513 printf("Login incorrect\n");
516 /* max number of attemps and delays taken from defaults file */
517 /* we allow maxtrys tries, but after 2 we start backing off */
519 if (cnt >= maxtrys) {
523 sleep((u_int)((cnt - 2) * atoi(default_sleep)));
527 /* committed to login -- turn off timeout */
532 #if defined(HAVE_GETUDBNAM) && defined(HAVE_SETLIM)
536 const long maxcpu = 46116860184; /* some random constant */
538 if(setjob(pwd->pw_uid, 0) < 0)
541 udb = getudbnam(pwd->pw_name);
543 errx(1, "Failed to get UDB entry.");
545 /* per process cpu limit */
546 t = udb->ue_pcpulim[UDBRC_INTER];
547 if(t == 0 || t > maxcpu)
552 if(limit(C_PROC, 0, L_CPU, t) < 0)
553 warn("limit process cpu");
555 /* per process memory limit */
556 if(limit(C_PROC, 0, L_MEM, udb->ue_pmemlim[UDBRC_INTER]) < 0)
557 warn("limit process memory");
559 /* per job cpu limit */
560 t = udb->ue_jcpulim[UDBRC_INTER];
561 if(t == 0 || t > maxcpu)
566 if(limit(C_JOB, 0, L_CPU, t) < 0)
567 warn("limit job cpu");
569 /* per job processor limit */
570 if(limit(C_JOB, 0, L_CPROC, udb->ue_jproclim[UDBRC_INTER]) < 0)
571 warn("limit job processors");
573 /* per job memory limit */
574 if(limit(C_JOB, 0, L_MEM, udb->ue_jmemlim[UDBRC_INTER]) < 0)
575 warn("limit job memory");
577 nice(udb->ue_nice[UDBRC_INTER]);
580 /* if user not super-user, check for disabled logins */
584 if (chdir(pwd->pw_dir) < 0) {
585 printf("No home directory %s!\n", pwd->pw_dir);
589 printf("Logging in with home = \"/\".\n");
592 quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
593 nomailcheck = access(_PATH_NOMAILCHECK, F_OK) == 0;
595 #if defined(HAVE_PASSWD_CHANGE) && defined(HAVE_PASSWD_EXPIRE)
596 if (pwd->pw_change || pwd->pw_expire)
597 gettimeofday(&tp, (struct timezone *)NULL);
600 if (tp.tv_sec >= pwd->pw_change) {
601 printf("Sorry -- your password has expired.\n");
603 } else if (pwd->pw_change - tp.tv_sec <
604 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
605 printf("Warning: your password expires on %s",
606 ctime(&pwd->pw_change));
608 if (tp.tv_sec >= pwd->pw_expire) {
609 printf("Sorry -- your account has expired.\n");
611 } else if (pwd->pw_expire - tp.tv_sec <
612 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
613 printf("Warning: your account expires on %s",
614 ctime(&pwd->pw_expire));
615 #endif /* defined(HAVE_PASSWD_CHANGE) && defined(HAVE_PASSWD_EXPIRE) */
617 /* Nothing else left to fail -- really log in. */
620 * Update the utmp files, both BSD and SYSV style.
622 if (utmpx_login(tty, username, hostname ? hostname : "") != 0
624 printf("No utmpx entry. You must exec \"login\" from the lowest level \"sh\".\n");
627 utmp_login(ttyn, username, hostname ? hostname : "");
631 * Set device protections, depending on what terminal the
632 * user is logged in. This feature is used on Suns to give
633 * console users better privacy.
635 login_fbtab(tty, pwd->pw_uid, pwd->pw_gid);
637 if (chown(ttyn, pwd->pw_uid,
638 (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid) < 0)
639 err(1, "chown tty failed");
640 if (chmod(ttyn, S_IRUSR | S_IWUSR | S_IWGRP) < 0)
641 err(1, "chmod tty failed");
644 initgroups(username, pwd->pw_gid);
646 if (*pwd->pw_shell == '\0')
647 pwd->pw_shell = _PATH_BSHELL;
650 * Set up a new environment. With SYSV, some variables are always
651 * preserved; some varables are never preserved, and some variables
652 * are always clobbered. With BSD, nothing is always preserved, and
653 * some variables are always clobbered. We add code to make sure
654 * that LD_* and IFS are never preserved.
657 strlcpy(term, stypeof(tty), sizeof(term));
658 /* set up a somewhat censored environment. */
659 sysv_newenv(argc, argv, pwd, term, pflag);
662 setenv("KRBTKFILE", krbtkfile_env, 1);
665 if (tty[sizeof("tty")-1] == 'd')
666 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
668 /* If fflag is on, assume caller/authenticator has logged root login. */
669 if (rootlogin && fflag == 0) {
671 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
672 username, tty, hostname);
674 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
678 if (!quietlog && notickets == 1 && !noticketsdontcomplain)
679 printf("Warning: no Kerberos tickets issued.\n");
684 * Syslog each successful login, so we don't have to watch hundreds
685 * of wtmp or lastlogin files.
688 syslog(LOG_INFO, "login from %s as %s", hostname, pwd->pw_name);
690 syslog(LOG_INFO, "login on %s as %s", tty, pwd->pw_name);
696 * Optionally show the message of the day. System V login leaves
697 * motd and mail stuff up to the shell startup file.
702 printf("%s\n\t%s %s\n\n",
703 "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
704 "The Regents of the University of California. ",
705 "All rights reserved.");
709 snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
710 if (stat(tbuf, &st) == 0 && st.st_size != 0)
711 printf("You have %smail.\n",
712 (st.st_mtime > st.st_atime) ? "new " : "");
718 if (login_access(pwd, hostname ? full_hostname : tty) == 0) {
719 printf("Permission denied\n");
721 syslog(LOG_NOTICE, "%s LOGIN REFUSED FROM %s",
722 pwd->pw_name, hostname);
724 syslog(LOG_NOTICE, "%s LOGIN REFUSED ON %s",
730 signal(SIGALRM, SIG_DFL);
731 signal(SIGQUIT, SIG_DFL);
732 signal(SIGINT, SIG_DFL);
734 signal(SIGTSTP, SIG_IGN);
737 p = strrchr(pwd->pw_shell, '/');
738 snprintf (tbuf, sizeof(tbuf), "-%s", p ? p + 1 : pwd->pw_shell);
741 if (setlogin(pwd->pw_name) < 0)
742 syslog(LOG_ERR, "setlogin() failure: %m");
746 if (setpcred (pwd->pw_name, NULL) == -1)
747 syslog(LOG_ERR, "setpcred() failure: %m");
748 #endif /* HAVE_SETPCRED */
750 #if defined(SYSV_SHADOW) && defined(HAVE_GETSPNAM)
751 spwd = getspnam (username);
754 /* perhaps work some magic */
755 if(do_osfc2_magic(pwd->pw_uid))
757 #if defined(HAVE_SGI_GETCAPABILITYBYNAME) && defined(HAVE_CAP_SET_PROC)
758 /* XXX SGI capability hack IRIX 6.x (x >= 0?) has something
759 called capabilities, that allow you to give away
760 permissions (such as chown) to specific processes. From 6.5
761 this is default on, and the default capability set seems to
762 not always be the empty set. The problem is that the
763 runtime linker refuses to do just about anything if the
764 process has *any* capabilities set, so we have to remove
765 them here (unless otherwise instructed by /etc/capability).
766 In IRIX < 6.5, these functions was called sgi_cap_setproc,
767 etc, but we ignore this fact (it works anyway). */
769 struct user_cap *ucap = sgi_getcapabilitybyname(pwd->pw_name);
772 cap = cap_from_text("all=");
774 cap = cap_from_text(ucap->ca_default);
776 err(1, "cap_from_text");
777 if(cap_set_proc(cap) < 0)
778 err(1, "cap_set_proc");
783 /* Discard permissions last so can't get killed and drop core. */
785 int uid = rootlogin ? 0 : pwd->pw_uid;
786 if(setuid(uid) != 0){
787 warn("setuid(%d)", uid);
795 * After dropping privileges and after cleaning up the environment,
796 * optionally run, as the user, /bin/passwd.
799 if (pwd->pw_passwd[0] == 0 &&
800 strcasecmp(default_passreq, "YES") == 0) {
801 printf("You don't have a password. Choose one.\n");
802 if (change_passwd(pwd))
808 if (spwd && sysv_expire(spwd)) {
809 if (change_passwd(pwd))
813 #endif /* SYSV_SHADOW */
816 if ((res=system(_PATH_CHPASS)))
823 /* XXX this is a fix for a bug in AFS for AIX 4.3, w/o
824 this hack the kernel crashes on the following
826 char *pw_dir = strdup(pwd->pw_dir);
828 char *pw_dir = pwd->pw_dir;
831 if(k_afs_cell_of_file(pw_dir, cell, sizeof(cell)) == 0)
836 execlp(pwd->pw_shell, tbuf, 0);
838 warnx("Can't exec %s, trying %s\n",
839 pwd->pw_shell, _PATH_BSHELL);
840 execlp(_PATH_BSHELL, tbuf, 0);
841 err(1, "%s", _PATH_BSHELL);
843 err(1, "%s", pwd->pw_shell);
848 #define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */
850 #define NBUFSIZ (UT_NAMESIZE + 1)
854 getloginname(int prompt)
858 static char nbuf[NBUFSIZ];
862 if (ttyprompt && *ttyprompt)
863 printf("%s", ttyprompt);
868 for (p = nbuf; (ch = getchar()) != '\n'; ) {
873 if (p < nbuf + (NBUFSIZ - 1))
878 warnx("login names may not start with '-'.");
889 find_in_etc_securetty (char *ttyn)
895 f = fopen (_PATH_ETC_SECURETTY, "r");
898 while (fgets(buf, sizeof(buf), f) != NULL) {
899 if(buf[strlen(buf) - 1] == '\n')
900 buf[strlen(buf) - 1] = '\0';
901 if (strcmp (buf, ttyn) == 0) {
917 t = getttynam (ttyn);
918 if (t && t->ty_status & TTY_SECURE)
922 if (find_in_etc_securetty(ttyn))
924 if (default_console == 0 || strcmp(default_console, ttyn) == 0)
932 fprintf(stderr, "Login timed out after %d seconds\n",
943 if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
944 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
945 write(fileno(stdout), tbuf, nchars);
953 #if defined(HAVE_LASTLOG_H) || defined(HAVE_LOGIN_H)
957 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
958 lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
960 if (read(fd, &ll, sizeof(ll)) == sizeof(ll) &&
962 if (pwd->pw_uid && spwd && spwd->sp_inact > 0
963 && ll.ll_time / (24 * 60 * 60)
964 + spwd->sp_inact < time(0)) {
965 printf("Your account has been inactive too long.\n");
969 printf("Last login: %.*s ",
970 24-5, ctime(&ll.ll_time));
971 if (*ll.ll_host != '\0') {
972 printf("from %.*s\n",
973 (int)sizeof(ll.ll_host),
977 (int)sizeof(ll.ll_line),
981 lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
982 #else /* SYSV_SHADOW */
984 if (read(fd, &ll, sizeof(ll)) == sizeof(ll) &&
986 printf("Last login: %.*s ",
987 24-5, ctime(&ll.ll_time));
988 if (*ll.ll_host != '\0')
989 printf("from %.*s\n",
990 (int)sizeof(ll.ll_host),
994 (int)sizeof(ll.ll_line),
997 lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
999 #endif /* SYSV_SHADOW */
1000 memset(&ll, 0, sizeof(ll));
1002 strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
1004 strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
1005 write(fd, &ll, sizeof(ll));
1008 #endif /* DOLASTLOG */
1012 badlogin(char *name)
1018 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
1019 failures, failures > 1 ? "S" : "", hostname);
1020 syslog(LOG_AUTHPRIV|LOG_NOTICE,
1021 "%d LOGIN FAILURE%s FROM %s, %s",
1022 failures, failures > 1 ? "S" : "", hostname, name);
1024 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
1025 failures, failures > 1 ? "S" : "", tty);
1026 syslog(LOG_AUTHPRIV|LOG_NOTICE,
1027 "%d LOGIN FAILURE%s ON %s, %s",
1028 failures, failures > 1 ? "S" : "", tty, name);
1033 #define UNKNOWN "su"
1036 stypeof(char *ttyid)
1038 /* TERM is probably a better guess than anything else. */
1039 char *term = getenv("TERM");
1041 if (term != 0 && term[0] != 0)
1045 #ifndef HAVE_TTYENT_H
1049 return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
1055 xgetstr(char *buf, int cnt, char *err)
1060 if (read(0, &ch, sizeof(ch)) != sizeof(ch))
1063 fprintf(stderr, "%s too long\r\n", err);
1071 * Some old rlogind's unknowingly pass remuser, locuser and
1072 * terminal_type/speed so we need to take care of that part of the
1073 * protocol here. Also, we can't make a getpeername(2) on the socket
1074 * so we have to trust that rlogind resolved the name correctly.
1078 doremotelogin(char *host)
1083 xgetstr(rusername, sizeof (rusername), "remuser");
1084 xgetstr(lusername, sizeof (lusername), "locuser");
1085 xgetstr(term, sizeof(term), "Terminal type");
1086 cp = strchr(term, '/');
1088 *cp = 0; /* For now ignore speed/bg */
1089 pwd = k_getpwnam(lusername);
1092 code = ruserok(host, (pwd->pw_uid == 0), rusername, lusername);
1095 "Warning: An old rlogind accepted login probably from host %s",