[2952] in Release_Engineering

home help back first fref pref prev next nref lref last post

[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

home help back first fref pref prev next nref lref last post