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.2.2 2000/06/23 02:33:07 assar 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);
599 if (pwd->pw_change) {
602 if (tp.tv_sec >= pwd->pw_change) {
603 printf("Sorry -- your password has expired.\n");
605 } else if (pwd->pw_change - tp.tv_sec <
606 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) {
608 printf("Warning: your password expires on %s",
612 if (tp.tv_sec >= pwd->pw_expire) {
613 printf("Sorry -- your account has expired.\n");
615 } else if (pwd->pw_expire - tp.tv_sec <
616 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) {
618 printf("Warning: your account expires on %s",
621 #endif /* defined(HAVE_PASSWD_CHANGE) && defined(HAVE_PASSWD_EXPIRE) */
623 /* Nothing else left to fail -- really log in. */
626 * Update the utmp files, both BSD and SYSV style.
628 if (utmpx_login(tty, username, hostname ? hostname : "") != 0
630 printf("No utmpx entry. You must exec \"login\" from the lowest level \"sh\".\n");
633 utmp_login(ttyn, username, hostname ? hostname : "");
637 * Set device protections, depending on what terminal the
638 * user is logged in. This feature is used on Suns to give
639 * console users better privacy.
641 login_fbtab(tty, pwd->pw_uid, pwd->pw_gid);
643 if (chown(ttyn, pwd->pw_uid,
644 (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid) < 0)
645 err(1, "chown tty failed");
646 if (chmod(ttyn, S_IRUSR | S_IWUSR | S_IWGRP) < 0)
647 err(1, "chmod tty failed");
650 initgroups(username, pwd->pw_gid);
652 if (*pwd->pw_shell == '\0')
653 pwd->pw_shell = _PATH_BSHELL;
656 * Set up a new environment. With SYSV, some variables are always
657 * preserved; some varables are never preserved, and some variables
658 * are always clobbered. With BSD, nothing is always preserved, and
659 * some variables are always clobbered. We add code to make sure
660 * that LD_* and IFS are never preserved.
663 strlcpy(term, stypeof(tty), sizeof(term));
664 /* set up a somewhat censored environment. */
665 sysv_newenv(argc, argv, pwd, term, pflag);
668 setenv("KRBTKFILE", krbtkfile_env, 1);
671 if (tty[sizeof("tty")-1] == 'd')
672 syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
674 /* If fflag is on, assume caller/authenticator has logged root login. */
675 if (rootlogin && fflag == 0) {
677 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
678 username, tty, hostname);
680 syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
684 if (!quietlog && notickets == 1 && !noticketsdontcomplain)
685 printf("Warning: no Kerberos tickets issued.\n");
690 * Syslog each successful login, so we don't have to watch hundreds
691 * of wtmp or lastlogin files.
694 syslog(LOG_INFO, "login from %s as %s", hostname, pwd->pw_name);
696 syslog(LOG_INFO, "login on %s as %s", tty, pwd->pw_name);
702 * Optionally show the message of the day. System V login leaves
703 * motd and mail stuff up to the shell startup file.
708 printf("%s\n\t%s %s\n\n",
709 "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
710 "The Regents of the University of California. ",
711 "All rights reserved.");
715 snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
716 if (stat(tbuf, &st) == 0 && st.st_size != 0)
717 printf("You have %smail.\n",
718 (st.st_mtime > st.st_atime) ? "new " : "");
724 if (login_access(pwd, hostname ? full_hostname : tty) == 0) {
725 printf("Permission denied\n");
727 syslog(LOG_NOTICE, "%s LOGIN REFUSED FROM %s",
728 pwd->pw_name, hostname);
730 syslog(LOG_NOTICE, "%s LOGIN REFUSED ON %s",
736 signal(SIGALRM, SIG_DFL);
737 signal(SIGQUIT, SIG_DFL);
738 signal(SIGINT, SIG_DFL);
740 signal(SIGTSTP, SIG_IGN);
743 p = strrchr(pwd->pw_shell, '/');
744 snprintf (tbuf, sizeof(tbuf), "-%s", p ? p + 1 : pwd->pw_shell);
747 if (setlogin(pwd->pw_name) < 0)
748 syslog(LOG_ERR, "setlogin() failure: %m");
752 if (setpcred (pwd->pw_name, NULL) == -1)
753 syslog(LOG_ERR, "setpcred() failure: %m");
754 #endif /* HAVE_SETPCRED */
756 #if defined(SYSV_SHADOW) && defined(HAVE_GETSPNAM)
757 spwd = getspnam (username);
760 /* perhaps work some magic */
761 if(do_osfc2_magic(pwd->pw_uid))
763 #if defined(HAVE_SGI_GETCAPABILITYBYNAME) && defined(HAVE_CAP_SET_PROC)
764 /* XXX SGI capability hack IRIX 6.x (x >= 0?) has something
765 called capabilities, that allow you to give away
766 permissions (such as chown) to specific processes. From 6.5
767 this is default on, and the default capability set seems to
768 not always be the empty set. The problem is that the
769 runtime linker refuses to do just about anything if the
770 process has *any* capabilities set, so we have to remove
771 them here (unless otherwise instructed by /etc/capability).
772 In IRIX < 6.5, these functions was called sgi_cap_setproc,
773 etc, but we ignore this fact (it works anyway). */
775 struct user_cap *ucap = sgi_getcapabilitybyname(pwd->pw_name);
778 cap = cap_from_text("all=");
780 cap = cap_from_text(ucap->ca_default);
782 err(1, "cap_from_text");
783 if(cap_set_proc(cap) < 0)
784 err(1, "cap_set_proc");
789 /* Discard permissions last so can't get killed and drop core. */
791 int uid = rootlogin ? 0 : pwd->pw_uid;
792 if(setuid(uid) != 0){
793 warn("setuid(%d)", uid);
797 if (uid != 0 && setuid(0) != -1) {
798 syslog(LOG_ALERT | LOG_AUTH,
799 "Failed to drop privileges for user %d", uid);
806 * After dropping privileges and after cleaning up the environment,
807 * optionally run, as the user, /bin/passwd.
810 if (pwd->pw_passwd[0] == 0 &&
811 strcasecmp(default_passreq, "YES") == 0) {
812 printf("You don't have a password. Choose one.\n");
813 if (change_passwd(pwd))
819 if (spwd && sysv_expire(spwd)) {
820 if (change_passwd(pwd))
824 #endif /* SYSV_SHADOW */
827 if ((res=system(_PATH_CHPASS)))
834 /* XXX this is a fix for a bug in AFS for AIX 4.3, w/o
835 this hack the kernel crashes on the following
837 char *pw_dir = strdup(pwd->pw_dir);
839 char *pw_dir = pwd->pw_dir;
842 if(k_afs_cell_of_file(pw_dir, cell, sizeof(cell)) == 0)
847 execlp(pwd->pw_shell, tbuf, 0);
849 warnx("Can't exec %s, trying %s\n",
850 pwd->pw_shell, _PATH_BSHELL);
851 execlp(_PATH_BSHELL, tbuf, 0);
852 err(1, "%s", _PATH_BSHELL);
854 err(1, "%s", pwd->pw_shell);
859 #define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */
861 #define NBUFSIZ (UT_NAMESIZE + 1)
865 getloginname(int prompt)
869 static char nbuf[NBUFSIZ];
873 if (ttyprompt && *ttyprompt)
874 printf("%s", ttyprompt);
879 for (p = nbuf; (ch = getchar()) != '\n'; ) {
884 if (p < nbuf + (NBUFSIZ - 1))
889 warnx("login names may not start with '-'.");
900 find_in_etc_securetty (char *ttyn)
906 f = fopen (_PATH_ETC_SECURETTY, "r");
909 while (fgets(buf, sizeof(buf), f) != NULL) {
910 if(buf[strlen(buf) - 1] == '\n')
911 buf[strlen(buf) - 1] = '\0';
912 if (strcmp (buf, ttyn) == 0) {
928 t = getttynam (ttyn);
929 if (t && t->ty_status & TTY_SECURE)
933 if (find_in_etc_securetty(ttyn))
935 if (default_console == 0 || strcmp(default_console, ttyn) == 0)
943 fprintf(stderr, "Login timed out after %d seconds\n",
954 if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
955 while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
956 write(fileno(stdout), tbuf, nchars);
964 #if defined(HAVE_LASTLOG_H) || defined(HAVE_LOGIN_H)
969 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
970 lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
972 if (read(fd, &ll, sizeof(ll)) == sizeof(ll) &&
974 if (pwd->pw_uid && spwd && spwd->sp_inact > 0
975 && ll.ll_time / (24 * 60 * 60)
976 + spwd->sp_inact < time(0)) {
977 printf("Your account has been inactive too long.\n");
982 printf("Last login: %.*s ", 24-5, ctime(&t));
983 if (*ll.ll_host != '\0') {
984 printf("from %.*s\n",
985 (int)sizeof(ll.ll_host),
989 (int)sizeof(ll.ll_line),
993 lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
994 #else /* SYSV_SHADOW */
996 if (read(fd, &ll, sizeof(ll)) == sizeof(ll) &&
999 printf("Last login: %.*s ", 24-5, ctime(&t));
1000 if (*ll.ll_host != '\0')
1001 printf("from %.*s\n",
1002 (int)sizeof(ll.ll_host),
1006 (int)sizeof(ll.ll_line),
1009 lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
1011 #endif /* SYSV_SHADOW */
1012 memset(&ll, 0, sizeof(ll));
1013 ll.ll_time = time(NULL);
1014 strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
1016 strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
1017 write(fd, &ll, sizeof(ll));
1020 #endif /* DOLASTLOG */
1024 badlogin(char *name)
1030 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
1031 failures, failures > 1 ? "S" : "", hostname);
1032 syslog(LOG_AUTHPRIV|LOG_NOTICE,
1033 "%d LOGIN FAILURE%s FROM %s, %s",
1034 failures, failures > 1 ? "S" : "", hostname, name);
1036 syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
1037 failures, failures > 1 ? "S" : "", tty);
1038 syslog(LOG_AUTHPRIV|LOG_NOTICE,
1039 "%d LOGIN FAILURE%s ON %s, %s",
1040 failures, failures > 1 ? "S" : "", tty, name);
1045 #define UNKNOWN "su"
1048 stypeof(char *ttyid)
1050 /* TERM is probably a better guess than anything else. */
1051 char *term = getenv("TERM");
1053 if (term != 0 && term[0] != 0)
1057 #ifndef HAVE_TTYENT_H
1061 return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
1067 xgetstr(char *buf, int cnt, char *err)
1072 if (read(0, &ch, sizeof(ch)) != sizeof(ch))
1075 fprintf(stderr, "%s too long\r\n", err);
1083 * Some old rlogind's unknowingly pass remuser, locuser and
1084 * terminal_type/speed so we need to take care of that part of the
1085 * protocol here. Also, we can't make a getpeername(2) on the socket
1086 * so we have to trust that rlogind resolved the name correctly.
1090 doremotelogin(char *host)
1095 xgetstr(rusername, sizeof (rusername), "remuser");
1096 xgetstr(lusername, sizeof (lusername), "locuser");
1097 xgetstr(term, sizeof(term), "Terminal type");
1098 cp = strchr(term, '/');
1100 *cp = 0; /* For now ignore speed/bg */
1101 pwd = k_getpwnam(lusername);
1104 code = ruserok(host, (pwd->pw_uid == 0), rusername, lusername);
1107 "Warning: An old rlogind accepted login probably from host %s",