[2952] in Release_Engineering
[jik@pit-manager.MIT.EDU: /source/athena/bin/login/login.c: do better logging]
daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Tue Dec 15 18:27:27 1992
Date: Tue, 15 Dec 92 18:27:10 -0500
From: "Jonathan I. Kamens" <jik@pit-manager.MIT.EDU>
To: rel-eng@Athena.MIT.EDU
----- Forwarded message
Date: Tue, 15 Dec 92 18:17:54 -0500
From: "Jonathan I. Kamens" <jik@pit-manager.MIT.EDU>
Sender: jik@pit-manager.MIT.EDU
To: bugs@Athena.MIT.EDU
Subject: /source/athena/bin/login/login.c: do better logging
Three bugs are fixed with this patch:
1) When there are login failures, usernames attempted are logged,
rather than just the last one.
2) Login failures are logged whenever a connection fails to result in
a login, not just when more than 5 failures are detected.
3) When logging, the full host name is logged, rather than the
truncated version that appears in utmp.
jik
*** 1.55 1992/08/01 16:11:05
--- login.c 1992/12/15 23:10:55
***************
*** 120,125 ****
--- 120,131 ----
extern char *krb_err_txt[]; /* From libkrb */
+ #ifndef MAX_LOGIN_FAILURES
+ #define MAX_LOGIN_FAILURES 5
+ #endif /* MAX_LOGIN_FAILURES */
+
+ char *login_failures[MAX_LOGIN_FAILURES+1] = { 0 };
+
char nolog[] = "/etc/nologin";
char qlog[] = ".hushlogin";
char maildir[30] = "/usr/spool/mail/";
***************
*** 178,183 ****
--- 184,191 ----
struct sgttyb ttyb;
struct utmp utmp;
+ char *tty;
+ char full_host[MAXHOSTNAMELEN];
char minusnam[16] = "-";
char *envinit[] = { 0 }; /* now set by setenv calls */
/*
***************
*** 239,245 ****
int pflag = 0, hflag = 0, t, f, c;
int invalid, quietlog, forkval;
FILE *nlfd;
! char *ttyn, *tty, saltc[2];
long salt;
int ldisc = 0, zero = 0, found = 0, i, j;
char **envnew;
--- 247,253 ----
int pflag = 0, hflag = 0, t, f, c;
int invalid, quietlog, forkval;
FILE *nlfd;
! char *ttyn, saltc[2];
long salt;
int ldisc = 0, zero = 0, found = 0, i, j;
char **envnew;
***************
*** 280,286 ****
exit(1);
rflag = 1;
usererr = doremotelogin(argv[2]);
! SCPYN(utmp.ut_host, argv[2]);
argc -= 2;
argv += 2;
continue;
--- 288,294 ----
exit(1);
rflag = 1;
usererr = doremotelogin(argv[2]);
! SCPYN(full_host, argv[2]);
argc -= 2;
argv += 2;
continue;
***************
*** 292,298 ****
}
kflag = 1;
usererr = doKerberosLogin(argv[2]);
! SCPYN(utmp.ut_host, argv[2]);
argc -= 2;
argv += 2;
continue;
--- 300,306 ----
}
kflag = 1;
usererr = doKerberosLogin(argv[2]);
! SCPYN(full_host, argv[2]);
argc -= 2;
argv += 2;
continue;
***************
*** 304,310 ****
}
Kflag = 1;
usererr = doKerberosLogin(argv[2]);
! SCPYN(utmp.ut_host, argv[2]);
argc -= 2;
argv += 2;
continue;
--- 312,318 ----
}
Kflag = 1;
usererr = doKerberosLogin(argv[2]);
! SCPYN(full_host, argv[2]);
argc -= 2;
argv += 2;
continue;
***************
*** 315,321 ****
exit(1);
}
hflag = 1;
! SCPYN(utmp.ut_host, argv[2]);
argc -= 2;
argv += 2;
continue;
--- 323,329 ----
exit(1);
}
hflag = 1;
! SCPYN(full_host, argv[2]);
argc -= 2;
argv += 2;
continue;
***************
*** 684,693 ****
* see if root logins on this terminal are permitted.
*/
if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) {
! if (utmp.ut_host[0])
syslog(LOG_CRIT,
"ROOT LOGIN REFUSED ON %s FROM %.*s",
! tty, HMAX, utmp.ut_host);
else
syslog(LOG_CRIT,
"ROOT LOGIN REFUSED ON %s", tty);
--- 692,701 ----
* see if root logins on this terminal are permitted.
*/
if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) {
! if (*full_host)
syslog(LOG_CRIT,
"ROOT LOGIN REFUSED ON %s FROM %.*s",
! tty, sizeof(full_host), full_host);
else
syslog(LOG_CRIT,
"ROOT LOGIN REFUSED ON %s", tty);
***************
*** 696,711 ****
if (invalid) {
if (!errorprtflag)
printf("Login incorrect\n");
! if (++t >= 5) {
! if (utmp.ut_host[0])
! syslog(LOG_CRIT,
! "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
! tty, HMAX, utmp.ut_host,
! NMAX, utmp.ut_name);
! else
! syslog(LOG_CRIT,
! "REPEATED LOGIN FAILURES ON %s, %.*s",
! tty, NMAX, utmp.ut_name);
ioctl(0, TIOCHPCL, (struct sgttyb *) 0);
close(0), close(1), close(2);
sleep(10);
--- 704,716 ----
if (invalid) {
if (!errorprtflag)
printf("Login incorrect\n");
! login_failures[t] = malloc(NMAX);
! if (login_failures[t]) {
! strncpy(login_failures[t], utmp.ut_name, NMAX);
! login_failures[t][NMAX-1] = '\0';
! }
! if (++t >= MAX_LOGIN_FAILURES) {
! log_failures(1);
ioctl(0, TIOCHPCL, (struct sgttyb *) 0);
close(0), close(1), close(2);
sleep(10);
***************
*** 734,741 ****
* Remote login invalid must have been because
* of a restriction of some sort, no extra chances.
*/
! if (!usererr && invalid)
exit(1);
} while (invalid);
/* committed to login turn off timeout */
--- 739,748 ----
* Remote login invalid must have been because
* of a restriction of some sort, no extra chances.
*/
! if (!usererr && invalid) {
! log_failures(0);
exit(1);
+ }
} while (invalid);
/* committed to login turn off timeout */
***************
*** 774,779 ****
--- 781,787 ----
t = ttyslot();
if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) {
lseek(f, (long)(t*sizeof(utmp)), 0);
+ SCPYN(utmp.ut_host, full_host);
SCPYN(utmp.ut_line, tty);
write(f, (char *)&utmp, sizeof(utmp));
close(f);
***************
*** 790,795 ****
--- 798,804 ----
if (ut_tmp.ut_pid == getppid())
lseek(f, -(long) sizeof(ut_tmp), 1);
strncpy(utmp.ut_id, ut_tmp.ut_id, 6);
+ SCPYN(utmp.ut_host, full_host);
SCPYN(utmp.ut_line, tty);
write(f, (char *)&utmp, sizeof(utmp));
close(f);
***************
*** 868,882 ****
if (tty[sizeof("tty")-1] == 'd')
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
if (pwd->pw_uid == 0)
! if (utmp.ut_host[0])
if (kdata) {
syslog(LOG_NOTICE, "ROOT LOGIN via Kerberos from %.*s",
! HMAX, utmp.ut_host);
syslog(LOG_NOTICE, " (name=%s, instance=%s, realm=%s).",
kdata->pname, kdata->pinst, kdata->prealm );
} else {
syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
! tty, HMAX, utmp.ut_host);
}
else
if (kdata) {
--- 877,891 ----
if (tty[sizeof("tty")-1] == 'd')
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
if (pwd->pw_uid == 0)
! if (*full_host)
if (kdata) {
syslog(LOG_NOTICE, "ROOT LOGIN via Kerberos from %.*s",
! sizeof(full_host), full_host);
syslog(LOG_NOTICE, " (name=%s, instance=%s, realm=%s).",
kdata->pname, kdata->pinst, kdata->prealm );
} else {
syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
! tty, sizeof(full_host), full_host);
}
else
if (kdata) {
***************
*** 933,940 ****
while ((c = getchar()) != '\n') {
if (c == ' ')
c = '_';
! if (c == EOF)
exit(0);
if (namep < up->ut_name+NMAX)
*namep++ = c;
}
--- 942,951 ----
while ((c = getchar()) != '\n') {
if (c == ' ')
c = '_';
! if (c == EOF) {
! log_failures(0);
exit(0);
+ }
if (namep < up->ut_name+NMAX)
*namep++ = c;
}
***************
*** 952,957 ****
--- 963,969 ----
{
printf("Login timed out after %d seconds\n", timeout);
+ log_failures(0);
exit(0);
}
***************
*** 1081,1086 ****
--- 1093,1099 ----
* daemon to disallow even password access here.
*/
printf("Sorry, you must have Kerberos authentication to access this host.\r\n");
+ log_failures(0);
exit(1);
}
}
***************
*** 1111,1116 ****
--- 1124,1130 ----
if (rc=kuserok(kdata,lusername)) {
printf("login: %s has not given you permission to login without a password.\r\n",lusername);
if (Kflag) {
+ log_failures(0);
exit(1);
}
return(-1);
***************
*** 1129,1139 ****
char c;
do {
! if (read(0, &c, 1) != 1)
exit(1);
if (--cnt < 0) {
fprintf(stderr, "%s '%.*s' too long, %d characters maximum.\r\n",
err, ocnt, obuf, ocnt-1);
exit(1);
}
*buf++ = c;
--- 1143,1156 ----
char c;
do {
! if (read(0, &c, 1) != 1) {
! log_failures(0);
exit(1);
+ }
if (--cnt < 0) {
fprintf(stderr, "%s '%.*s' too long, %d characters maximum.\r\n",
err, ocnt, obuf, ocnt-1);
+ log_failures(0);
exit(1);
}
*buf++ = c;
***************
*** 1928,1931 ****
--- 1945,1983 ----
bzero (&ticket, sizeof (ticket));
bzero (&authdata, sizeof (authdata));
return retval;
+ }
+
+ log_failures(repeated)
+ int repeated;
+ {
+ char log_buffer[BUFSIZ];
+ char **names = login_failures;
+
+ if (! *names) {
+ return;
+ }
+
+ *log_buffer = '\0';
+
+ if (repeated) {
+ (void) strcat(log_buffer, "REPEATED ");
+ }
+
+ (void) strcat(log_buffer, "LOGIN FAILURES ON ");
+ (void) strcat(log_buffer, tty);
+ (void) strcat(log_buffer, " ");
+
+ if (*full_host) {
+ (void) strcat(log_buffer, "FROM ");
+ (void) strncat(log_buffer, full_host, sizeof(full_host));
+ }
+
+ while (*names) {
+ if (**names) {
+ (void) strcat(log_buffer, ", ");
+ (void) strncat(log_buffer, *names++, NMAX);
+ }
+ }
+
+ syslog(LOG_CRIT, "%s", log_buffer);
}
----- End of forwarded message