[5204] in Kerberos

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

improper use of free in krb5/src/lib/krb5/krb/mk_cred.c

daemon@ATHENA.MIT.EDU (Wolfgang Rupprecht)
Fri May 19 15:17:21 1995

To: kerberos@MIT.EDU
Date: 19 May 1995 11:31:34 -0700
From: wolfgang@wsrcc.com (Wolfgang Rupprecht)

> schwartz@galapagos.cse.psu.edu (Scott Schwartz) writes:
> After applying this patch, rlogin doesn't dump core, so rlogind is able
> to puts a tgt in /tmp/krb5cc_p%d but the child shell never gets the
> KRB5CCNAME env variable for some reason.  Any ideas?  Naturally,
> login.krb5 doesn't delete the ticket cache when the session finished.

The problem is that login.c clears any env vars.  (See the code for
the -p flag.)  I hacked up login to take a "-c" flag so that the
credetials var could be passed in.  Alternately I guess you could do a
getenv()/setenv() to propagate the K5CCNAME var.

Now to figure out why I can forward tickets from a sun-4.1.3 system to
a bsdi 2.0 system (via rlogin -f or rlogin -F), but not between two
suns and not from the bsdi to the sun.

-wolfgang

#
# patch generated by wolfgang on Fri May 19 10:42:26 PDT 1995 
# in directory wsrcc.com:/v/src/krb5.5/src/appl/bsd .
# Patched files are: 
#
# forward.c
# krlogin.c
# krlogind.c
# login.c
# logutil.c
#
*** orig/forward.c	Tue Apr 25 19:51:15 1995
--- forward.c	Tue May 16 20:34:54 1995
***************
*** 27,36 ****
--- 27,38 ----
  #include <pwd.h>
  #include <netdb.h>
  
  #include "k5-int.h"
  
+ char ccname[MAXPATHLEN + 5];
+ 
  /* Decode, decrypt and store the forwarded creds in the local ccache. */
  krb5_error_code
  rd_and_store_for_creds(context, auth_context, inbuf, ticket, lusername)
      krb5_context context;
      krb5_auth_context * auth_context;
***************
*** 38,48 ****
      krb5_ticket *ticket;
      char *lusername;
  {
      krb5_creds ** creds;
      krb5_error_code retval;
!     char ccname[35];
      krb5_ccache ccache = NULL;
      struct passwd *pwd;
  
      if (!(pwd = (struct passwd *) getpwnam(lusername)))
  	return -1;
--- 40,50 ----
      krb5_ticket *ticket;
      char *lusername;
  {
      krb5_creds ** creds;
      krb5_error_code retval;
!     /* char ccname[35]; */
      krb5_ccache ccache = NULL;
      struct passwd *pwd;
  
      if (!(pwd = (struct passwd *) getpwnam(lusername)))
  	return -1;
*** orig/krlogin.c	Fri Apr 21 12:11:00 1995
--- krlogin.c	Tue May 16 22:04:24 1995
***************
*** 944,955 ****
  #endif
      }
      dosigwinch = 1;
  }
  
  
- 
  krb5_sigtype
    catchild()
  {
  #ifdef WAIT_USES_INT
      int status;
--- 944,957 ----
  #endif
      }
      dosigwinch = 1;
  }
  
+ #ifdef bsdi
+ # define WAIT_USES_INT 1
+ #endif
  
  krb5_sigtype
    catchild()
  {
  #ifdef WAIT_USES_INT
      int status;
***************
*** 1009,1019 ****
      for (;;) {
  	FD_ZERO(&waitread);
  	FD_SET(0, &waitread);
  	n = select(8*sizeof(waitread), &waitread, 0, 0, 0, 0);
  	if (n < 0 && errno == EINTR)
! 	  continue;
  	if (n > 0)
  	  break;
  	else
  	  if (n < 0) {
  	      perror("select");
--- 1011,1021 ----
      for (;;) {
  	FD_ZERO(&waitread);
  	FD_SET(0, &waitread);
  	n = select(8*sizeof(waitread), &waitread, 0, 0, 0, 0);
  	if (n < 0 && errno == EINTR)
! 	    continue;
  	if (n > 0)
  	  break;
  	else
  	  if (n < 0) {
  	      perror("select");
***************
*** 1023,1033 ****
  #endif /* ultrix */
      for (;;) {
  	n = read(0, &c, 1);
  	if (n <= 0) {
  	    if (n < 0 && errno == EINTR)
! 	      continue;
  	    break;
  	}
  	/*
  	 * If we're at the beginning of the line
  	 * and recognize a command character, then
--- 1025,1038 ----
  #endif /* ultrix */
      for (;;) {
  	n = read(0, &c, 1);
  	if (n <= 0) {
  	    if (n < 0 && errno == EINTR)
! 	    {
! 		errno = 0; /* not resetting errno is clearly a bug -wsr */
! 		continue;
! 	    }
  	    break;
  	}
  	/*
  	 * If we're at the beginning of the line
  	 * and recognize a command character, then
***************
*** 1438,1448 ****
  	rcvcnt = des_read(rem, rcvbuf, sizeof (rcvbuf));
  	if (rcvcnt == 0)
  	  return (0);
  	if (rcvcnt < 0) {
  	    if (errno == EINTR)
! 	      continue;
  	    perror("read");
  	    return (-1);
  	}
      }
  }
--- 1443,1456 ----
  	rcvcnt = des_read(rem, rcvbuf, sizeof (rcvbuf));
  	if (rcvcnt == 0)
  	  return (0);
  	if (rcvcnt < 0) {
  	    if (errno == EINTR)
! 	    {
! 		errno = 0;	/* -wsr */
! 		continue;
! 	    }
  	    perror("read");
  	    return (-1);
  	}
      }
  }
***************
*** 1483,1498 ****
--- 1491,1512 ----
  			newtty.c_lflag &= ~(ICANON|ISIG|ECHO);
  			newtty.c_iflag &= ~(INLCR|ICRNL);
  			/* newtty.c_iflag |=  (BRKINT|ISTRIP|IXON|IXANY); */
  			newtty.c_iflag &= ~(IXON|IXANY);
  			newtty.c_iflag |=  (BRKINT|ISTRIP);
+ #ifdef bsdi
+ 			newtty.c_oflag &= ~(ONLCR /* | ONOCR */);
+ #else
  			newtty.c_oflag &= ~(ONLCR|ONOCR);
+ #endif
  			newtty.c_oflag |=  (OPOST);
  		}
+ #ifndef bsdi
  		/* preserve tab delays, but turn off XTABS */
  		if ((newtty.c_oflag & TABDLY) == TAB3)
  			newtty.c_oflag &= ~TABDLY;
+ #endif
  
  		if (litout)
  			newtty.c_oflag &= ~OPOST;
  
  		newtty.c_cc[VMIN] = 1;
*** orig/krlogind.c	Wed May  3 00:46:06 1995
--- krlogind.c	Thu May 18 22:06:36 1995
***************
*** 1,5 ****
--- 1,6 ----
+ #define C_HACK
  /*
   *	appl/bsd/krlogind.c
   */
  
  /*
***************
*** 97,106 ****
--- 98,108 ----
   *
   * #define KERBEROS
   */
  #define LOG_REMOTE_REALM
  #define CRYPT
+ #define LOG_ALL_LOGINS
  
  
  #ifdef HAVE_UNISTD_H
  #include <unistd.h>
  #endif
***************
*** 253,271 ****
  #define (*des_read)  read
  #define (*des_write) write
  #endif /* KERBEROS */
  
  #ifndef LOGIN_PROGRAM
! #ifdef DO_NOT_USE_K_LOGIN
! #ifdef sysvimp
! #define LOGIN_PROGRAM "/bin/remlogin"
! #else
! #define LOGIN_PROGRAM "/bin/login"
! #endif
! #else /* DO_NOT_USE_K_LOGIN */
! #define LOGIN_PROGRAM KRB5_PATH_LOGIN
! #endif /* DO_NOT_USE_K_LOGIN */
  #endif /* LOGIN_PROGRAM */
  
  char *login_program = LOGIN_PROGRAM;
  
  #define MAXRETRIES 4
--- 255,273 ----
  #define (*des_read)  read
  #define (*des_write) write
  #endif /* KERBEROS */
  
  #ifndef LOGIN_PROGRAM
! # ifdef DO_NOT_USE_K_LOGIN
! #  ifdef sysvimp
! #   define LOGIN_PROGRAM "/bin/remlogin"
! #  else
! #   define LOGIN_PROGRAM "/bin/login"
! #  endif
! # else /* DO_NOT_USE_K_LOGIN */
! #  define LOGIN_PROGRAM KRB5_PATH_LOGIN
! # endif /* DO_NOT_USE_K_LOGIN */
  #endif /* LOGIN_PROGRAM */
  
  char *login_program = LOGIN_PROGRAM;
  
  #define MAXRETRIES 4
***************
*** 301,310 ****
--- 303,314 ----
  krb5_sigtype	cleanup();
  
  int must_pass_rhosts = 0, must_pass_k5 = 0, must_pass_one = 0;
  int do_encrypt = 0, passwd_if_fail = 0, passwd_req = 0;
  
+ extern char ccname[];
+ 
  main(argc, argv)
       int argc;
       char **argv;
  {
      extern int opterr, optind;
***************
*** 317,326 ****
--- 321,331 ----
  #ifdef KERBEROS
      krb5_error_code status;
  #endif
      
      progname = *argv;
+     ccname[0] = '\0';
      
  #ifndef LOG_NDELAY
  #define LOG_NDELAY 0
  #endif
      
***************
*** 622,642 ****
  
  #ifdef HAVE_SETSID
      (void) setsid();
  #endif
  
! #ifdef ultrix
      /* The Ultrix (and other BSD tty drivers) require the process group
       * to be zero, in order to acquire the new tty as a controlling tty. */
      (void) setpgrp(0, 0);
  #endif
  
      t = open(line, O_RDWR);
      if (t < 0)
        fatalperror(f, line);
  
! #ifdef ultrix
      setpgrp(0, getpid());
  #endif
  	
  #if defined(VHANG_FIRST) && !defined(VHANG_NO_CLOSE)
      (void) close(vfd);
--- 627,651 ----
  
  #ifdef HAVE_SETSID
      (void) setsid();
  #endif
  
! #if defined(ultrix) || defined(_AIX) || defined(SYSV) 
      /* The Ultrix (and other BSD tty drivers) require the process group
       * to be zero, in order to acquire the new tty as a controlling tty. */
+ #ifdef SETPGRP_TWOARGS
      (void) setpgrp(0, 0);
+ #else
+ 	(void) setpgrp();
  #endif
+ #endif
  
      t = open(line, O_RDWR);
      if (t < 0)
        fatalperror(f, line);
  
! #ifdef ultrix 
      setpgrp(0, getpid());
  #endif
  	
  #if defined(VHANG_FIRST) && !defined(VHANG_NO_CLOSE)
      (void) close(vfd);
***************
*** 788,801 ****
  #endif
  
  #ifdef DO_NOT_USE_K_LOGIN
  	execl(login_program, "login", "-r", rhost_name, 0);
  #else
  	if (passwd_req)
! 	  execl(login_program, "login","-h", rhost_name, lusername, 0);
  	else
! 	  execl(login_program, "login", "-h", rhost_name, "-e", lusername, 0);
  #endif
  	
  	fatalperror(2, login_program);
  	/*NOTREACHED*/
      } /* if (pid == 0) */
--- 797,834 ----
  #endif
  
  #ifdef DO_NOT_USE_K_LOGIN
  	execl(login_program, "login", "-r", rhost_name, 0);
  #else
+ #ifdef C_HACK
+ 
+ 	/*
+ 	 * NOTE: It's probably safer to pass ccache to login via the
+ 	 * command line then the environement. -wsr
+ 	 */
+ 
+ 	if (ccname[0]){
+ 	    if (passwd_req)
+ 		execl(login_program, "login", "-c", ccname,
+ 		      "-h", rhost_name, lusername, 0);
+ 	    else
+ 		execl(login_program, "login", "-c", ccname,
+ 		      "-h", rhost_name, "-e", lusername, 0);
+ 	} else {
+ 	    if (passwd_req)
+ 		execl(login_program, "login","-h", rhost_name, lusername, 0);
+ 	    else
+ 		execl(login_program, "login", "-h", rhost_name, "-e",
+ 		      lusername, 0);
+ 	}
+ #else
  	if (passwd_req)
! 	    execl(login_program, "login","-h", rhost_name, lusername, 0);
  	else
! 	    execl(login_program, "login", "-h", rhost_name, "-e",
! 		  lusername, 0);
! #endif /* C_HACK */
  #endif
  	
  	fatalperror(2, login_program);
  	/*NOTREACHED*/
      } /* if (pid == 0) */
***************
*** 1118,1128 ****
--- 1151,1165 ----
       int f;
       char *msg;
  {
      char buf[512];
      extern int sys_nerr;
+ #ifdef bsdi
+     extern const char * const sys_errlist[];
+ #else
      extern char *sys_errlist[];
+ #endif
      
      if ((unsigned)errno < sys_nerr)
        (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]);
      else
        (void) sprintf(buf, "%s: Error %d", msg, errno);
***************
*** 1427,1441 ****
  
  #ifdef HAVE_GRANTPT
  	if (grantpt(*fd) || unlockpt(*fd)) return 1;
  #endif
      
! #ifdef	HAVE_TTYNAME
! 	p = ttyname(*fd);
! #else
! #ifdef HAVE_PTSNAME
  	p = ptsname(*fd);
  #else
  	/* XXX If we don't have either what do we do */
  #endif
  #endif
  	if (p) {
--- 1464,1478 ----
  
  #ifdef HAVE_GRANTPT
  	if (grantpt(*fd) || unlockpt(*fd)) return 1;
  #endif
      
! #ifdef	HAVE_PTSNAME
  	p = ptsname(*fd);
+ #else
+ #ifdef HAVE_TTYNAME
+ 	p = ttyname(*fd);
  #else
  	/* XXX If we don't have either what do we do */
  #endif
  #endif
  	if (p) {
*** orig/login.c	Fri Apr 28 17:36:13 1995
--- login.c	Tue May 16 22:44:02 1995
***************
*** 183,193 ****
  #endif
  
  extern int errno;
  
  #ifdef KRB4
! #define KRB_ENVIRON	"KRBTKFILE"	/* Ticket file environment variable */
  #define KRB_TK_DIR	"/tmp/tkt_"	/* Where to put the ticket */
  #define MAXPWSIZE	128		/* Biggest string accepted for KRB4
  					   passsword */
  
  AUTH_DAT *kdata = (AUTH_DAT *) NULL;
--- 183,193 ----
  #endif
  
  extern int errno;
  
  #ifdef KRB4
! #define KRB_ENVIRON	"KRB5CCNAME"	/* Ticket file environment variable */
  #define KRB_TK_DIR	"/tmp/tkt_"	/* Where to put the ticket */
  #define MAXPWSIZE	128		/* Biggest string accepted for KRB4
  					   passsword */
  
  AUTH_DAT *kdata = (AUTH_DAT *) NULL;
***************
*** 249,258 ****
--- 249,259 ----
  	int kflag, Kflag, eflag;
  	int quietlog, passwd_req, ioctlval;
  	sigtype timedout();
  	char *domain, *salt, **envinit, *ttyn, *tty;
  	char tbuf[MAXPATHLEN + 2];
+ 	char *ccname = NULL;
  	char *ttyname(), *stypeof(), *crypt(), *getpass();
  	time_t login_time;
  	off_t lseek();
  #ifdef POSIX_TERMIOS
  	struct termios tc;
***************
*** 294,310 ****
  	 * -h is used by other servers to pass the name of the
  	 * remote host to login so that it may be placed in utmp and wtmp
  	 * -k is used by klogind to cause the Kerberos V4 autologin protocol;
  	 * -K is used by klogind to cause the Kerberos V4 autologin
  	 *    protocol with restricted access.
  	 */
  	(void)gethostname(tbuf, sizeof(tbuf));
  	domain = strchr(tbuf, '.');
  
  	Fflag = fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0;
  	passwd_req = 1;
! 	while ((ch = getopt(argc, argv, "Ffeh:pr:k:K:")) != EOF)
  		switch (ch) {
  		case 'f':
  			EXCL_AUTH_TEST;
  			fflag = 1;
  			break;
--- 295,312 ----
  	 * -h is used by other servers to pass the name of the
  	 * remote host to login so that it may be placed in utmp and wtmp
  	 * -k is used by klogind to cause the Kerberos V4 autologin protocol;
  	 * -K is used by klogind to cause the Kerberos V4 autologin
  	 *    protocol with restricted access.
+ 	 * -c credential's file name (eg. KRB5CCNAME=FILE:/tmp/K5C:0)
  	 */
  	(void)gethostname(tbuf, sizeof(tbuf));
  	domain = strchr(tbuf, '.');
  
  	Fflag = fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0;
  	passwd_req = 1;
! 	while ((ch = getopt(argc, argv, "Ffeh:pr:k:K:c:")) != EOF)
  		switch (ch) {
  		case 'f':
  			EXCL_AUTH_TEST;
  			fflag = 1;
  			break;
***************
*** 372,381 ****
--- 374,389 ----
  			if (domain && (p = strchr(optarg, '.')) &&
  			    !strcmp(p, domain))
  				*p = '\0';
  			hostname = optarg;
  			break;
+ 
+ 			/* WSR HACK propagate credentials file */
+ 		case 'c':
+ 			ccname = optarg;
+ 			break;
+ 
  #endif /* KRB4 */
  		case 'e':
  			EXCL_AUTH_TEST;
  			if (getuid()) {
  			    fprintf(stderr,
***************
*** 643,652 ****
--- 651,673 ----
  			krbflag = 1;
  			kpass_ok = 1;
  			fprintf(stderr, "Kerberos error: %s\n",
  				krb_err_txt[krbval]);
  			break;
+ 
+ 			/*
+ 			 * Get rid of the following msg that occurs
+ 			 * every time we telnet in to /krb5/sbin/telnetd
+ 			 * from a normal telnet. -wsr
+ 			 * Kerberos error: Can't send request (send_to_kdc)
+ 			 */
+ 		    case SKDC_CANT:
+ 			if (!hflag)
+ 			    fprintf(stderr, "Kerberos error: %s\n",
+ 				    krb_err_txt[krbval]);
+ 			break;
+ 
  		    default:
  			fprintf(stderr, "Kerberos error: %s\n",
  				krb_err_txt[krbval]);
  			break;
  		    }
***************
*** 882,891 ****
--- 903,914 ----
  #ifdef KRB4
  	/* tkfile[0] is only set if we got tickets above */
  	if (tkfile[0])
  	    (void) setenv(KRB_ENVIRON, tkfile, 1);
  #endif /* KRB4 */
+ 	if (ccname)
+ 	    (void) setenv("KRB5CCNAME", ccname, 1);
  
  #if 0
  	strcpy(wgfile, "/tmp/wg.XXXXXX");
  	mktemp(wgfile);
  	setenv("WGFILE", wgfile, 0);
***************
*** 938,951 ****
  			syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
  
  	if (!quietlog) {
  		struct stat st;
  
! #ifdef KRB4
  		if (!krbflag)
  		    printf("\nWarning: No Kerberos tickets obtained.\n\n");
! #endif /* KRB4 */
  		motd();
  		(void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name);
  		if (stat(tbuf, &st) == 0 && st.st_size != 0)
  			printf("You have %smail.\n",
  			    (st.st_mtime > st.st_atime) ? "new " : "");
--- 961,974 ----
  			syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
  
  	if (!quietlog) {
  		struct stat st;
  
! #ifdef KRB4_BS			/* this warning is BS */
  		if (!krbflag)
  		    printf("\nWarning: No Kerberos tickets obtained.\n\n");
! #endif /* KRB4_BS */
  		motd();
  		(void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name);
  		if (stat(tbuf, &st) == 0 && st.st_size != 0)
  			printf("You have %smail.\n",
  			    (st.st_mtime > st.st_atime) ? "new " : "");
***************
*** 1327,1337 ****
--- 1350,1364 ----
  #ifdef ECHOKE
  	/* Not POSIX, but if we have it, we probably want it */
   	tp->c_lflag |= ECHOKE;
  #endif
   	tp->c_iflag |= ICRNL|BRKINT;
+ #ifdef bsdi
+  	tp->c_oflag |= ONLCR|OPOST;
+ #else
   	tp->c_oflag |= ONLCR|OPOST|TAB3;
+ #endif
  #else /* !POSIX_TERMIOS */
  	tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
  #endif
  }
  
*** orig/logutil.c	Wed Apr 26 14:44:19 1995
--- logutil.c	Tue May 16 23:10:46 1995
***************
*** 32,41 ****
--- 32,46 ----
  #include <utmp.h>
  #ifdef HAVE_SETUTXENT
  #include <utmpx.h>
  #endif
  
+ #ifdef bsdi
+ #define	UTMP_FILE	"/var/run/utmp"
+ #define	WTMP_FILE	"/usr/log/wtmp"
+ #endif
+ 
  #ifndef UTMP_FILE
  #define	UTMP_FILE	"/etc/utmp"
  #endif
  #ifndef WTMP_FILE
  #define	WTMP_FILE	"/usr/adm/wtmp"



-- 
Wolfgang Rupprecht <wolfgang@wsrcc.com>  <http://www.wsrcc.com/>

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