[297] in Kerberos-V5-bugs

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

appl-bsd.patch

daemon@ATHENA.MIT.EDU (Marc Horowitz)
Fri Feb 26 17:55:30 1993

To: krb5-bugs@MIT.EDU
Date: Fri, 26 Feb 1993 17:51:20 -0500
From: Marc Horowitz <marc@Aktis.COM>

** Complete reworking of bsd stuff.  In production use at GZA on Sun's
and NeXT's

./appl/bsd/Imakefile
./appl/bsd/kcmd.c
./appl/bsd/krcp.c
./appl/bsd/krlogin.c
./appl/bsd/krlogind.c
./appl/bsd/krsh.c
./appl/bsd/krshd.c
./appl/bsd/login.c
./appl/bsd/logutil.c
	Significant changes in general:
		updated to use new krb5_sname_to_principal function
		Many portability and code fixes.
	Imakefile:
		added -DLOGIN_PROGRAM to compilation of login.krb5
	krlogind.c:
		added standalone debugging mode, port can be specified
		added #define CRYPT by default
		added cpp symbol LOGIN_PROGRAM so the path to login.krb5 can
			be passed in
		don't vhangup() in debug mode
		added setsid() call in the right place for POSIX and sun
		changed the way krlogind and login.krb5 work together.
			Info is no longer passed in-band.
	krsh.c:
		added cpp symbol RLOGIN_PROGRAM so the path to the berkeley
			rlogin can be passed in.
	krshd.c:
		(changes relative to krb5-bugs [0244])
		added standalone debugging mode, port can be specified


*** ./appl/bsd/Imakefile.old	1992/11/25 15:08:11
--- ./appl/bsd/Imakefile	1992/12/09 14:58:27
***************
*** 29,35 ****
  #else
  LOCAL_LIBRARIES = $(KLIB)
  #endif
!         DEFINES = $(APPL_BSD_DEF)
  
  CLIENTSRCS= krcp.c krlogin.c krsh.c kcmd.c logutil.c
  CLIENTOBJS= krcp.o krlogin.o krsh.o kcmd.o logutil.o
--- 29,35 ----
  #else
  LOCAL_LIBRARIES = $(KLIB)
  #endif
!         DEFINES = $(APPL_BSD_DEF) -DLOGIN_PROGRAM=\"$(SERVER_BINDIR)/login.krb5\"
  
  CLIENTSRCS= krcp.c krlogin.c krsh.c kcmd.c logutil.c
  CLIENTOBJS= krcp.o krlogin.o krsh.o kcmd.o logutil.o
***************
*** 45,53 ****
  SRCS= $(CLIENTSRCS) $(SERVERSRCS)
  
  #ifdef CrayArchitecture
! all::	rsh rcp rlogin krshd 
  #else
! all::	rsh rcp rlogin krshd krlogind
  #endif
  
  NormalProgramTarget(rsh,krsh.o kcmd.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
--- 45,53 ----
  SRCS= $(CLIENTSRCS) $(SERVERSRCS)
  
  #ifdef CrayArchitecture
! all::	rsh rcp rlogin krshd login.krb5
  #else
! all::	rsh rcp rlogin krshd login.krb5 krlogind
  #endif
  
  NormalProgramTarget(rsh,krsh.o kcmd.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
***************
*** 61,66 ****
--- 61,70 ----
  
  NormalProgramTarget(krshd,krshd.o kcmd.o logutil.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
  Krb5InstallServerProgram(krshd)
+ 
+ /* The only thing login.krb5 needs from libkrb is setenv.  sigh. */
+ NormalProgramTarget(login.krb5,login.o logutil.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
+ InstallProgram(login.krb5,$(SERVER_BINDIR))
  
  #ifndef CrayArchitecture
  NormalProgramTarget(krlogind,krlogind.o logutil.o kcmd.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)

*** ./appl/bsd/krsh.c.old	1992/12/07 15:19:32
--- ./appl/bsd/krsh.c	1992/12/09 14:55:33
***************
*** 77,85 ****
--- 77,89 ----
  char	*krb_realm = (char *)0;
       void	try_normal();
  #define UCB_RSH "/usr/ucb/rsh"
+ #ifndef RLOGIN_PROGRAM
  #define RLOGIN_PROGRAM "/nfs/kerberos/bin/sun3/rlogin"
+ #endif
  #else /* KERBEROS */
+ #ifndef RLOGIN_PROGRAM
  #define RLOGIN_PROGRAM "/usr/ucb/rlogin"
+ #endif
  #endif  /* KERBEROS */
       
  #define	mask(s)	(1 << ((s) - 1))

*** ./appl/bsd/kcmd.c.old	1992/12/07 13:54:58
--- ./appl/bsd/kcmd.c	1992/12/09 15:32:52
***************
*** 136,147 ****
          fprintf(stderr,"kcmd: no memory\n");
          return(-1);
      }
!     if ((realm == NULL) || (realm[0] == '\0')) {
! 	krb5_sname_to_principal(host_save,service,1,&ret_cred->server);
!     }
!     else {
!         sprintf(tmpstr,"%s/%s@%s",service,host_save,realm);
!         krb5_parse_name(tmpstr,&ret_cred->server);
      }
  #ifdef sgi
      oldmask = sigignore(sigmask(SIGURG));
--- 136,152 ----
          fprintf(stderr,"kcmd: no memory\n");
          return(-1);
      }
!     krb5_sname_to_principal(host_save,service,KRB5_NT_SRV_HST,
! 			    &ret_cred->server);
!     if (realm && *realm) {
!        char *copyrealm;
!        krb5_data rdata;
! 
!        rdata.length = strlen(realm);
!        rdata.data = (char *) malloc(rdata.length+1);
!        strcpy(rdata.data, realm);
! 
!        krb5_princ_set_realm(ret_cred->server, &rdata);
      }
  #ifdef sgi
      oldmask = sigignore(sigmask(SIGURG));

*** ./appl/bsd/krshd.c.old	1992/09/29 14:45:38
--- ./appl/bsd/krshd.c	1992/12/09 15:06:36
***************
*** 153,161 ****
  
  #include <com_err.h>
  
! #define ARGSTR	"rRkK?"
  #else /* !KERBEROS */
! #define ARGSTR	"rR?"
       
  char *strsave();
  #endif /* KERBEROS */
--- 153,161 ----
  
  #include <com_err.h>
  
! #define ARGSTR	"rRkKD:?"
  #else /* !KERBEROS */
! #define ARGSTR	"rRD:?"
       
  char *strsave();
  #endif /* KERBEROS */
***************
*** 172,178 ****
  #endif /* CRAY */
  int     errno;
  
! char	*index(), *rindex(), *strncat();
  /*VARARGS1*/
  int	error();
  
--- 172,184 ----
  #endif /* CRAY */
  int     errno;
  
! char	*strncat();
! #ifndef index
! char	*index();
! #endif
! #ifndef rindex
! char	*rindex();
! #endif
  /*VARARGS1*/
  int	error();
  
***************
*** 191,196 ****
--- 197,204 ----
      extern char *optarg;
      char *options, ch;
      int i;
+     int fd;
+     int debug_port = 0;
      
  #ifdef CRAY
      secflag = sysconf(_SC_CRAY_SECURE_SYS);
***************
*** 241,246 ****
--- 249,257 ----
  	  if (must_pass_one)
  	    must_pass_one = 0;
  	  break;
+ 	case 'D':
+ 	  debug_port = atoi(optarg);
+ 	  break;
  #ifdef KERBEROS
  	case 'k':
  	  must_pass_one = 1; /* If just 'k', any one check must succeed */
***************
*** 261,272 ****
      argv += optind;
      
      fromlen = sizeof (from);
!     if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! 	fprintf(stderr, "%s: ", progname);
! 	perror("getpeername");
! 	_exit(1);
      }
!     if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
  		   sizeof (on)) < 0)
        syslog(LOG_WARNING,
  	     "setsockopt (SO_KEEPALIVE): %m");
--- 272,319 ----
      argv += optind;
      
      fromlen = sizeof (from);
! 
!     if (debug_port) {
! 	int s;
! 	struct sockaddr_in sin;
! 
! 	if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
! 	    fprintf(stderr, "Error in socket: %s\n", strerror(errno));
! 	    exit(2);
! 	}
! 
! 	bzero((char *) &sin,sizeof(sin));
! 	sin.sin_family = AF_INET;
! 	sin.sin_port = htons(debug_port);
! 	sin.sin_addr.s_addr = INADDR_ANY;
! 
! 	if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
! 	    fprintf(stderr, "Error in bind: %s\n", strerror(errno));
! 	    exit(2);
! 	}
! 
! 	if ((listen(s, 5)) < 0) {
! 	    fprintf(stderr, "Error in listen: %s\n", strerror(errno));
! 	    exit(2);
! 	}
! 
! 	if ((fd = accept(s, &from, &fromlen)) < 0) {
! 	    fprintf(stderr, "Error in accept: %s\n", strerror(errno));
! 	    exit(2);
! 	}
! 
! 	close(s);
!     } else {
! 	if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! 	    fprintf(stderr, "%s: ", progname);
! 	    perror("getpeername");
! 	    _exit(1);
! 	}
! 
! 	fd = 0;
      }
! 
!     if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
  		   sizeof (on)) < 0)
        syslog(LOG_WARNING,
  	     "setsockopt (SO_KEEPALIVE): %m");
***************
*** 273,283 ****
  #if defined(BSD) && BSD >= 43
      linger.l_onoff = 1;
      linger.l_linger = 60;			/* XXX */
!     if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger,
  		   sizeof (linger)) < 0)
        syslog(LOG_WARNING , "setsockopt (SO_LINGER): %m");
  #endif
!     doit(dup(0), &from);
  }
  
  #ifdef CRAY
--- 320,332 ----
  #if defined(BSD) && BSD >= 43
      linger.l_onoff = 1;
      linger.l_linger = 60;			/* XXX */
!     if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&linger,
  		   sizeof (linger)) < 0)
        syslog(LOG_WARNING , "setsockopt (SO_LINGER): %m");
  #endif
!     doit(dup(fd), &from);
! 
! 
  }
  
  #ifdef CRAY
***************
*** 318,324 ****
  #endif /* CRAY */
  #endif /* KERBEROS */
  
! char	**environ;
  char ttyn[12];		/* Line string for wtmp entries */
  
  #if defined (alliant) /* Alliant compiler complains of too many 
--- 367,373 ----
  #endif /* CRAY */
  #endif /* KERBEROS */
  
! extern char	**environ;
  char ttyn[12];		/* Line string for wtmp entries */
  
  #if defined (alliant) /* Alliant compiler complains of too many 
***************
*** 535,552 ****
  	peeraddr.addrtype = fromp->sin_family;
  	peeraddr.length = SIZEOF_INADDR;
  	peeraddr.contents = (krb5_octet *)&fromp->sin_addr;
! 	strcpy(srv_name, "host/");
  	
! 	gethostname(def_host, 100);
! 	strcat(srv_name, def_host);
! 	if (status = krb5_parse_name(srv_name, &server)) {
  	    syslog(LOG_ERR, "parse server name %s: %s", "host",
  		   error_message(status));
  	    exit(1);
  	}
! 	krb5_princ_type(server) = KRB5_NT_SRV_HST;
! 	krb5_init_ets();
! 	
  	if (status = krb5_recvauth(&f,
  				   "KCMDV0.1",
  				   server,
--- 584,599 ----
  	peeraddr.addrtype = fromp->sin_family;
  	peeraddr.length = SIZEOF_INADDR;
  	peeraddr.contents = (krb5_octet *)&fromp->sin_addr;
! 
! 	krb5_init_ets();
  	
! 	if (status = krb5_sname_to_principal(NULL,"host",KRB5_NT_SRV_HST,
! 					     &server)) {
  	    syslog(LOG_ERR, "parse server name %s: %s", "host",
  		   error_message(status));
  	    exit(1);
  	}
! 
  	if (status = krb5_recvauth(&f,
  				   "KCMDV0.1",
  				   server,
***************
*** 572,578 ****
  	    error("Error no memory\n");
  	    exit(1);
  	}
! 	getstr(remuser, sizeof(locuser), "remuser");
      }
  
      /* These two reads will be used in the next release to obtain
--- 619,625 ----
  	    error("Error no memory\n");
  	    exit(1);
  	}
! 	getstr(f, remuser, sizeof(locuser), "remuser");
      }
  
      /* These two reads will be used in the next release to obtain
***************
*** 597,606 ****
      }
   	
  #else
!     getstr(remuser, sizeof(remuser), "remuser");
  #endif /* KERBEROS */
!     getstr(locuser, sizeof(locuser), "locuser");
!     getstr(cmdbuf, sizeof(cmdbuf), "command");
      
  #ifdef KERBEROS
      if (!(remuser = malloc(sizeof(locuser) + 1))){
--- 644,653 ----
      }
   	
  #else
!     getstr(f, remuser, sizeof(remuser), "remuser");
  #endif /* KERBEROS */
!     getstr(f, locuser, sizeof(locuser), "locuser");
!     getstr(f, cmdbuf, sizeof(cmdbuf), "command");
      
  #ifdef KERBEROS
      if (!(remuser = malloc(sizeof(locuser) + 1))){
***************
*** 607,613 ****
  	error("Error no memory\n");
  	exit(1);
      }
!     getstr(remuser, sizeof(locuser), "remuser");
  #endif
      
  #ifdef CRAY
--- 654,660 ----
  	error("Error no memory\n");
  	exit(1);
      }
!     getstr(f, remuser, sizeof(locuser), "remuser");
  #endif
      
  #ifdef CRAY
***************
*** 1083,1089 ****
  
  
  
! getstr(buf, cnt, err)
       char *buf;
       int cnt;
       char *err;
--- 1130,1137 ----
  
  
  
! getstr(fd, buf, cnt, err)
!      int fd;
       char *buf;
       int cnt;
       char *err;
***************
*** 1091,1097 ****
      char c;
      
      do {
! 	if (read(0, &c, 1) != 1)
  	  exit(1);
  	*buf++ = c;
  	if (--cnt == 0) {
--- 1139,1145 ----
      char c;
      
      do {
! 	if (read(fd, &c, 1) != 1)
  	  exit(1);
  	*buf++ = c;
  	if (--cnt == 0) {

*** ./appl/bsd/login.c.old	1993/02/26 22:20:55
--- ./appl/bsd/login.c	1993/02/26 22:21:20
***************
*** 6,12 ****
  
  #ifndef lint
  static char rcsid_login_c[] = "$Id$";
! #endif lint
  
  /*
   * Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
--- 6,12 ----
  
  #ifndef lint
  static char rcsid_login_c[] = "$Id$";
! #endif /* lint */
  
  /*
   * Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
***************
*** 27,33 ****
  
  #ifndef lint
  char copyright[] =
!   "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\
   All rights reserved.\n";
  #endif /* not lint */
  
--- 27,33 ----
  
  #ifndef lint
  char copyright[] =
! "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\
   All rights reserved.\n";
  #endif /* not lint */
  
***************
*** 35,63 ****
  static char sccsid[] = "@(#)login.c	5.25 (Berkeley) 1/6/89";
  #endif /* not lint */
  
! #define KERBEROS
!      
!      /*
!       * login -f name	(for pre-authenticated login)
!       * login name           (for non-authenticated/non-authorized login)
!       */
!      
! #define VFS
! #define BYPASS_ROOT_CHK
!      
  #include <sys/param.h>
! #ifndef VFS
  #include <sys/quota.h>
! #endif VFS
  #include <sys/stat.h>
  #include <sys/time.h>
  #include <sys/resource.h>
  #include <sys/file.h>
  #include <sys/ioctl.h>
!      
  #include <utmp.h>
  #include <signal.h>
  #include <lastlog.h>
  #include <errno.h>
  #ifndef NOTTYENT
  #include <ttyent.h>
--- 35,74 ----
  static char sccsid[] = "@(#)login.c	5.25 (Berkeley) 1/6/89";
  #endif /* not lint */
  
! /*
!  * login [ name ]
!  * login -r hostname	(for rlogind)
!  * login -h hostname	(for telnetd, etc.)
!  * login -f name	(for pre-authenticated login: datakit, xterm, etc.)
!  * login -e name	(for pre-authenticated encrypted, must do term
!  *			 negotiation)
!  * ifdef KERBEROS
!  * login -k hostname (for Kerberos rlogind with password access)
!  * login -K hostname (for Kerberos rlogind with restricted access)
!  * endif KERBEROS 
!  *
!  * only one of: -r -f -e -k -K
!  * only one of: -r -h -k -K
!  */
! 
! #include <sys/types.h>
  #include <sys/param.h>
! #ifdef OQUOTA
  #include <sys/quota.h>
! #endif
  #include <sys/stat.h>
  #include <sys/time.h>
  #include <sys/resource.h>
  #include <sys/file.h>
  #include <sys/ioctl.h>
! 
  #include <utmp.h>
  #include <signal.h>
+ 
+ #if !defined(_AIX)
  #include <lastlog.h>
+ #endif
+ 
  #include <errno.h>
  #ifndef NOTTYENT
  #include <ttyent.h>
***************
*** 68,86 ****
  #include <setjmp.h>
  #include <stdio.h>
  #include <strings.h>
!      
  #ifdef UIDGID_T
!      uid_t getuid();
  #define uid_type uid_t
  #define gid_type gid_t
  #else
!      int getuid();
  #define uid_type int
  #define gid_type int
  #endif /* UIDGID_T */
!      
  #define	TTYGRPNAME	"tty"		/* name of group to own ttys */
!      
  #define	MOTDFILE	"/etc/motd"
  #define	MAILDIR		"/usr/spool/mail"
  #define	NOLOGIN		"/etc/nologin"
--- 79,127 ----
  #include <setjmp.h>
  #include <stdio.h>
  #include <strings.h>
! #ifdef KERBEROS
! #include <krb.h>
! #include <netdb.h>
! #include <netinet/in.h>
! #ifdef BIND_HACK
! #include <arpa/nameser.h>
! #include <arpa/resolv.h>
! #endif /* BIND_HACK */
! #endif /* KERBEROS */
! 
! #ifdef POSIX
! #include <stdlib.h>
! #include <termios.h>
! #ifdef _AIX
! #include <termio.h>
! #endif
! #endif
! 
! #ifdef _IBMR2
! #include <usersec.h>
! #include <sys/id.h>
! #endif
! 
! #if defined(_AIX)
! #define PRIO_OFFSET 20
! #else
! #define PRIO_OFFSET 0
! #endif
! 
  #ifdef UIDGID_T
! uid_t getuid();
  #define uid_type uid_t
  #define gid_type gid_t
  #else
! int getuid();
  #define uid_type int
  #define gid_type int
  #endif /* UIDGID_T */
! 
! #define SETPAG
!     
  #define	TTYGRPNAME	"tty"		/* name of group to own ttys */
! 
  #define	MOTDFILE	"/etc/motd"
  #define	MAILDIR		"/usr/spool/mail"
  #define	NOLOGIN		"/etc/nologin"
***************
*** 87,123 ****
  #define	HUSHLOGIN	".hushlogin"
  #define	LASTLOG		"/usr/adm/lastlog"
  #define	BSHELL		"/bin/sh"
!      
! #ifdef VFS
  #define QUOTAWARN	"/usr/ucb/quota" /* warn user about quotas */
! #endif VFS
!      
  #define	UT_HOSTSIZE	sizeof(((struct utmp *)0)->ut_host)
  #define	UT_NAMESIZE	sizeof(((struct utmp *)0)->ut_name)
!      
  /*
   * This bounds the time given to login.  Not a define so it can
   * be patched on machines where it's too small.
   */
! int timeout = 300;
  
  struct passwd *pwd;
! char term[64], *hostname, *username = NULL;
  
  struct sgttyb sgttyb;
  struct tchars tc = {
!     CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
!   };
  struct ltchars ltc = {
!     CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
!   };
  
  extern int errno;
  
  char *getenv();
! int putenv();
! void setenv();
  void dofork();
  
  #ifdef POSIX
  typedef void sigtype;
--- 128,193 ----
  #define	HUSHLOGIN	".hushlogin"
  #define	LASTLOG		"/usr/adm/lastlog"
  #define	BSHELL		"/bin/sh"
! 
! #if !defined(OQUOTA) && !defined(QUOTAWARN)
  #define QUOTAWARN	"/usr/ucb/quota" /* warn user about quotas */
! #endif
! 
! #define PROTOTYPE_DIR	"/usr/athena/lib/prototype_tmpuser"
! #define TEMP_DIR_PERM	0711
! 
! #define NOATTACH	"/etc/noattach"
! #define NOCREATE	"/etc/nocreate"
! #define NOREMOTE	"/etc/noremote"
! #define REGISTER	"/usr/etc/go_register"
! #define GET_MOTD	"/bin/athena/get_message"
! 
  #define	UT_HOSTSIZE	sizeof(((struct utmp *)0)->ut_host)
  #define	UT_NAMESIZE	sizeof(((struct utmp *)0)->ut_name)
! 
! #define MAXENVIRON	32
! 
  /*
   * This bounds the time given to login.  Not a define so it can
   * be patched on machines where it's too small.
   */
! int	timeout = 300;
  
  struct passwd *pwd;
! char term[64], *hostname, *username;
  
+ #ifndef POSIX
  struct sgttyb sgttyb;
  struct tchars tc = {
! 	CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
! };
  struct ltchars ltc = {
! 	CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
! };
! #endif
  
  extern int errno;
  
+ #ifdef KERBEROS
+ #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 Kerberos
+ 					   passsword */
+ 
+ extern char *krb_err_txt[];		/* From libkrb */
+ 
+ AUTH_DAT *kdata = (AUTH_DAT *) NULL;
+ KTEXT ticket = (KTEXT) NULL;
+ char tkfile[MAXPATHLEN];
+ int krbflag = 0;			/* set if tickets have been obtained */
+ #ifdef SETPAG
+ int pagflag = 0;			/* true if setpag() has been called */
+ #endif
+ 
  char *getenv();
! char *strsave();
  void dofork();
+ #endif /* KERBEROS */
  
  #ifdef POSIX
  typedef void sigtype;
***************
*** 125,684 ****
  typedef int sigtype;
  #endif /* POSIX */
  
! #ifdef CRAY
! char    user[32] = "LOGNAME=";
! #include <tmpdir.h>
! char tmpdir[64] = "TMPDIR=";
! #else
! char	user[20] = "USER=";
! #endif
! 
! char	homedir[64] = "HOME=";
! char	shell[64] = "SHELL=";
  
  
  #ifdef KERBEROS
! char    *envinit[] =
! #ifdef CRAY
!     {homedir, shell, PATH, user, "TZ=GMT0", tmpdir, 0};
! #define TZENV   4
! #define TMPDIRENV 5
! char    *getenv();
! extern
! #else
!     {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin:/usr/bin/kerberos",
!    user, 0};
! #endif /* CRAY */
! #else /* !KERBEROS */
! char	*envinit[] =
! #ifdef CRAY
!     {homedir, shell, PATH, user, "TZ=GMT0", tmpdir, 0};
! #define TZENV   4
! #define TMPDIRENV 5
! char    *getenv();
! extern
! #else
!     {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin:/usr/bin/kerberos",
!    user, 0};
! #endif /* CRAY */
  #endif /* KERBEROS */
! char **environ;
  
! main(argc, argv)
!      int argc;
!      char **argv;
! {
!     extern int optind;
!     extern char *optarg;
!     struct group *gr;
!     register int ch;
!     register char *p;
!     int fflag, pflag, cnt;
!     int quietlog, ioctlval;
!     sigtype timedout();
!     char *domain, *salt, *ttyn, *tty;
!     char tbuf[MAXPATHLEN + 2];
!     char *ttyname(), *stypeof(), *crypt(), *getpass();
!     time_t time();
!     off_t lseek();
!     int passwd_req = 1, preserve_env = 0;
!     
!     (void)signal(SIGALRM, timedout);
!     (void)alarm((u_int)timeout);
!     (void)signal(SIGQUIT, SIG_IGN);
!     (void)signal(SIGINT, SIG_IGN);
!     (void)setpriority(PRIO_PROCESS, 0, 0);
! #ifndef VFS
!     (void)quota(Q_SETUID, 0, 0, 0);
! #endif VFS
!     
!     (void)gethostname(tbuf, sizeof(tbuf));
!     domain = index(tbuf, '.');
!     
!     passwd_req = 1;
!     while ((ch = getopt(argc, argv, "fp")) != EOF)
!       switch (ch) {
! 	case 'f':
! 	  passwd_req = 0;
! 	  break;
! 	case 'p':
! 	  preserve_env = 1;
! 	  break;
! 	case '?':
! 	default:
! 	  fprintf(stderr, "usage: login [-fp] [username]\n");
! 	  exit(1);
! 	  break;
!       }
!     argc -= optind;
!     argv += optind;
!     if (*argv)
!       hostname = *argv;
!     
!     ioctlval = 0;
!     (void)ioctl(0, TIOCLSET, (char *)&ioctlval);
!     (void)ioctl(0, TIOCNXCL, (char *)0);
!     (void)fcntl(0, F_SETFL, ioctlval);
!     (void)ioctl(0, TIOCGETP, (char *)&sgttyb);
!     
!     doremotelogin();
!     
!     /*
!      * If talking to an rlogin process, propagate the terminal type and
!      * baud rate across the network.
!      */
!     doremoteterm(&sgttyb);	
!     sgttyb.sg_erase = CERASE;
!     sgttyb.sg_kill = CKILL;
!     (void)ioctl(0, TIOCSLTC, (char *)&ltc);
!     (void)ioctl(0, TIOCSETC, (char *)&tc);
!     (void)ioctl(0, TIOCSETP, (char *)&sgttyb);
!     
!     for (cnt = getdtablesize(); cnt > 2; cnt--)
!       (void) close(cnt);
!     
!     ttyn = ttyname(0);
!     if (ttyn == NULL || *ttyn == '\0')
!       ttyn = "/dev/tty??";
!     if (tty = rindex(ttyn, '/'))
!       ++tty;
!     else
!       tty = ttyn;
!     
! #ifndef LOG_ODELAY /* 4.2 syslog ... */                      
!     openlog("login", 0);
! #else
!     openlog("login", LOG_ODELAY, LOG_AUTH);
! #endif /* 4.2 syslog */
!     
!     for (cnt = 0;; username = NULL) {
  	ioctlval = 0;
! 	(void)ioctl(0, TIOCSETD, (char *)&ioctlval);
! 	
! 	if (username == NULL) 
! 	  getloginname();
! 	
! 	if (pwd = getpwnam(username))
! 	  salt = pwd->pw_passwd;
! 	else
! 	  salt = "xx";
! 	
! 	/* if user not super-user, check for disabled logins */
! 	if (pwd == NULL || pwd->pw_uid)
! 	  checknologin();
! 	
  	/*
! 	 * Disallow automatic login to root; if not invoked by
! 	 * root, disallow if the uid's differ.
  	 */
! 	if (!passwd_req && pwd) {
! 	    int uid = (int) getuid();
! 	    
! 	    passwd_req = (uid && uid != pwd->pw_uid)
! #ifndef BYPASS_ROOT_CHK
! 	      || (pwd->pw_uid == 0);
  #else
! 	    ;
  #endif
  	}
! 	
  	/*
! 	 * If no remote login authentication and a password exists
! 	 * for this user, prompt for one and verify it.
  	 */
! 	if (!passwd_req || pwd && !*pwd->pw_passwd)
! 	  break;
! 	
! 	(void) setpriority(PRIO_PROCESS, 0, -4);
! 	p = crypt(getpass("Password:"), salt);
! 	(void) setpriority(PRIO_PROCESS, 0, 0);
! 	if (pwd && !strcmp(p, pwd->pw_passwd))
! 	  break;
! 	
! 	printf("Login incorrect\n");
! 	if (++cnt >= 5) {
! 	    if (hostname)
! 	      syslog(LOG_ERR,
! 		     "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
! 		     tty, UT_HOSTSIZE, hostname, UT_NAMESIZE,
! 		     username);
! 	    else
! 	      syslog(LOG_ERR,
! 		     "REPEATED LOGIN FAILURES ON %s, %.*s",
! 		     tty, UT_NAMESIZE, username);
! 	    (void)ioctl(0, TIOCHPCL, (char *)0);
! 	    sleepexit(1);
  	}
!     }
!     
!     /* committed to login -- turn off timeout */
!     (void)alarm((u_int)0);
!     
!     /*
!      * If valid so far and root is logging in, see if root logins on
!      * this terminal are permitted.
!      */
! #ifndef BYPASS_ROOT_CHK
!     if (pwd->pw_uid == 0 && !rootterm(tty)) {
! 	if (hostname)
! 	  syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s",
! 		 tty, UT_HOSTSIZE, hostname);
! 	else
! 	  syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty);
! 	printf("Login incorrect\n");
! 	sleepexit(1);
!     }
  #endif
!     
! #ifndef VFS
!     if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
! 	switch(errno) {
! 	  case EUSERS:
! 	    fprintf(stderr,
! 		    "Too many users logged on already.\nTry again later.\n");
! 	    break;
! 	  case EPROCLIM:
! 	    fprintf(stderr,
! 		    "You have too many processes running.\n");
! 	    break;
! 	  default:
! 	    perror("quota (Q_SETUID)");
  	}
! 	sleepexit(0);
!     }
! #endif /* !VFS */
!     
!     if (chdir(pwd->pw_dir) < 0) {
! 	printf("No directory %s!\n", pwd->pw_dir);
! 	if (chdir("/"))
! 	  exit(0);
! 	pwd->pw_dir = "/";
! 	printf("Logging in with home = \"/\".\n");
!     }
!     
!     /* nothing else left to fail -- really log in */
!     {
! 	struct utmp utmp;
! 	
! 	(void)time(&utmp.ut_time);
! 	(void) strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
! 	if (hostname)
! 	  (void) strncpy(utmp.ut_host, hostname,
! 			 sizeof(utmp.ut_host));
! 	else
! 	  bzero(utmp.ut_host, sizeof(utmp.ut_host));
! 	(void) strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
! 	login(&utmp);
!     }
!     
!     quietlog = access(HUSHLOGIN, F_OK) == 0;
!     dolastlog(quietlog, tty);
!     
!     {
! 	static struct winsize win = { 0, 0, 0, 0 };
! 	
! 	(void)ioctl(0, TIOCSWINSZ, (char *)&win);
!     }
!     
!     (void)chown(ttyn, pwd->pw_uid,
! 		(gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
!     
!     (void)chmod(ttyn, 0620);
!     
!     (void)setgid((gid_type) pwd->pw_gid);
!     
!     (void) initgroups(username, pwd->pw_gid);
!     
! #ifndef VFS
!     quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
  #endif
!     (void)setuid((uid_type) pwd->pw_uid);
!     
!     if (*pwd->pw_shell == '\0')
!       pwd->pw_shell = BSHELL;
!     /* turn on new line discipline for the csh */
!     else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
! 	ioctlval = NTTYDISC;
! 	(void)ioctl(0, TIOCSETD, (char *)&ioctlval);
!     }
!     /* Destroy old environment unless requested. */ 
!     if (!preserve_env)
!       environ = envinit;
!     
!     setenv("HOME", pwd->pw_dir);
!     setenv("SHELL", pwd->pw_shell);
!     if (term[0] == '\0')
!       (void) strncpy(term, stypeof(tty), sizeof(term));
!     setenv("TERM", term);
!     setenv("USER", pwd->pw_name);
!     setenv("PATH", "/usr/ucb:/bin:/usr/bin:");
!     
!     if (tty[sizeof("tty")-1] == 'd')
!       syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
!     
!     if (!quietlog) {
! 	struct stat st;
! 	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 " : "");
!     }
!     
! #ifdef VFS
!     if (! access( QUOTAWARN, X_OK)) (void) system(QUOTAWARN);
! #endif VFS
!     (void)signal(SIGALRM, SIG_DFL);
!     (void)signal(SIGQUIT, SIG_DFL);
!     (void)signal(SIGINT, SIG_DFL);
!     (void)signal(SIGTSTP, SIG_IGN);
!     
!     tbuf[0] = '-';
!     (void) strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ?
! 		  p + 1 : pwd->pw_shell);
!     execlp(pwd->pw_shell, tbuf, 0);
!     fprintf(stderr, "login: no shell: ");
!     perror(pwd->pw_shell);
!     exit(0);
! }
  
  
  
  getloginname()
  {
!     register int ch;
!     register char *p;
!     static char nbuf[UT_NAMESIZE + 1];
!     
!     for (;;) {
! 	printf("login: ");
! 	for (p = nbuf; (ch = getchar()) != '\n'; ) {
! 	    if (ch == EOF)
! 	      exit(0);
! 	    if (p < nbuf + UT_NAMESIZE)
! 	      *p++ = ch;
! 	}
! 	if (p > nbuf)
! 	  if (nbuf[0] == '-')
! 	    fprintf(stderr,
! 		    "login names may not start with '-'.\n");
! 	  else {
! 	      *p = '\0';
! 	      username = nbuf;
! 	      break;
! 	  }
!     }
  }
  
- 
- 
  sigtype
!   timedout()
  {
!     fprintf(stderr, "Login timed out after %d seconds\n", timeout);
!     exit(0);
  }
  
- 
- 
  #ifdef NOTTYENT
! int root_tty_security = 0;
  #endif
  rootterm(tty)
!      char *tty;
  {
  #ifdef NOTTYENT
!     return(root_tty_security);
  #else
!     struct ttyent *t;
!     
!     return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
! #endif NOTTYENT
! }
  
! 
  
  jmp_buf motdinterrupt;
  
  motd()
  {
!     register int fd, nchars;
!     sigtype (*oldint)(), sigint();
!     char tbuf[8192];
!     
!     if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
!       return;
!     oldint = (sigtype (*)()) signal(SIGINT, sigint);
!     if (setjmp(motdinterrupt) == 0)
!       while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
! 	(void)write(fileno(stdout), tbuf, nchars);
!     (void)signal(SIGINT, oldint);
!     (void)close(fd);
  }
  
- 
- 
  sigtype
!   sigint()
  {
!     longjmp(motdinterrupt, 1);
  }
  
- 
- 
  checknologin()
  {
!     register int fd, nchars;
!     char tbuf[8192];
!     
!     if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
! 	while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
! 	  (void)write(fileno(stdout), tbuf, nchars);
! 	sleepexit(0);
!     }
! }
! 
  
  
  dolastlog(quiet, tty)
!      int quiet;
!      char *tty;
  {
!     struct lastlog ll;
!     int fd;
!     
!     if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
! 	(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
! 	if (!quiet) {
! 	    if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
! 		ll.ll_time != 0) {
! 		printf("Last login: %.*s ",
! 		       24-5, (char *)ctime(&ll.ll_time));
! 		if (*ll.ll_host != '\0')
! 		  printf("from %.*s\n",
! 			 sizeof(ll.ll_host), ll.ll_host);
  		else
! 		  printf("on %.*s\n",
! 			 sizeof(ll.ll_line), ll.ll_line);
! 	    }
! 	    (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
  	}
! 	(void)time(&ll.ll_time);
! 	(void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
! 	if (hostname)
! 	  (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
! 	else
! 	  (void) bzero(ll.ll_host, sizeof(ll.ll_host));
! 	(void)write(fd, (char *)&ll, sizeof(ll));
! 	(void)close(fd);
!     }
  }
  
- 
- 
  #undef	UNKNOWN
  #define	UNKNOWN	"su"
  
! char *stypeof(ttyid)
!      char *ttyid;
  {
  #ifdef NOTTYENT
!     return(UNKNOWN);
  #else
!     struct ttyent *t;
!     
!     return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
  #endif
  }
  
  
  
! getstr(buf, cnt, err)
!      char *buf, *err;
!      int cnt;
  {
!     char ch;
!     
!     do {
! 	if (read(0, &ch, sizeof(ch)) != sizeof(ch))
! 	  exit(1);
! 	if (--cnt < 0) {
! 	    fprintf(stderr, "%s too long\r\n", err);
! 	    sleepexit(1);
  	}
! 	*buf++ = ch;
!     } while (ch);
! }
  
  
  
! doremotelogin()
! {
!     static char lusername[UT_NAMESIZE+1];
!     char rusername[UT_NAMESIZE+1];
!     
!     getstr(rusername, sizeof(rusername), "remuser");
!     getstr(lusername, sizeof(lusername), "locuser");
!     if (username == NULL)
!       username = lusername;
!     getstr(term, sizeof(term), "Terminal type");
  }
! 
  
  
  char *speeds[] = {
!     "0", "50", "75", "110", "134", "150", "200", "300", "600",
!     "1200", "1800", "2400", "4800", "9600", "19200", "38400",
  };
  #define	NSPEEDS	(sizeof(speeds) / sizeof(speeds[0]))
  
  doremoteterm(tp)
!      struct sgttyb *tp;
  {
!     register char *cp = index(term, '/'), **cpp;
!     char *speed;
!     
!     if (cp) {
! 	*cp++ = '\0';
! 	speed = cp;
! 	cp = index(speed, '/');
! 	if (cp)
! 	  *cp++ = '\0';
! 	for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
! 	  if (strcmp(*cpp, speed) == 0) {
! 	      tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
! 	      break;
! 	  }
!     }
!     tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
! }
! 
  
  
  sleepexit(eval)
!      int eval;
  {
!     sleep((u_int)5);
!     exit(eval);
  }
  
  
  
! void setenv(var, value)
!      char *var, *value;
! {
!     char *env_str;
!     int retval, str_size = strlen(var) + strlen(value) + strlen("=") + 1;
!     
!     env_str = (char *) malloc(str_size);
      
!     strcpy(env_str, var);
!     strcat(env_str, "=");
!     strcat(env_str, value);
!     env_str[str_size-1] = '\0';
!     
!     if (retval = putenv(env_str)) {
! 	syslog(LOG_ERR, "Not enough memory\n");
! 	exit(1);
      }
  }
--- 195,1243 ----
  typedef int sigtype;
  #endif /* POSIX */
  
! #define EXCL_AUTH_TEST if (rflag || kflag || Kflag || eflag) { \
! 				fprintf(stderr, \
! 				    "login: only one of -r, -k, -K, -e, and -f allowed.\n"); \
! 				exit(1);\
! 			}
! 
! #define EXCL_HOST_TEST if (rflag || kflag || Kflag || hflag) { \
! 				fprintf(stderr, \
! 				    "login: only one of -r, -k, -K, and -h allowed.\n"); \
! 				exit(1);\
! 			}
! 
! main(argc, argv)
! 	int argc;
! 	char **argv;
! {
! 	extern int optind;
! 	extern char *optarg, **environ;
! 	struct group *gr;
! 	register int ch, i;
! 	register char *p;
! 	int fflag, hflag, pflag, rflag, cnt;
! 	int kflag, Kflag, eflag;
! 	int quietlog, passwd_req, ioctlval;
! 	sigtype timedout();
! 	char *domain, *salt, **envinit, *ttyn, *tty, *ktty;
! 	char tbuf[MAXPATHLEN + 2];
! 	char *ttyname(), *stypeof(), *crypt(), *getpass();
! 	time_t time(), login_time;
! 	off_t lseek();
! #ifdef POSIX
! 	struct termios tc;
! #endif
! 
! 	(void)signal(SIGALRM, timedout);
! 	(void)alarm((u_int)timeout);
! 	(void)signal(SIGQUIT, SIG_IGN);
! 	(void)signal(SIGINT, SIG_IGN);
! 	(void)setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
! #ifdef OQUOTA
! 	(void)quota(Q_SETUID, 0, 0, 0);
! #endif
  
+ 	/*
+ 	 * -p is used by getty to tell login not to destroy the environment
+ 	 * -r is used by rlogind to cause the autologin protocol;
+  	 * -f is used to skip a second login authentication 
+ 	 * -e is used to skip a second login authentication, but allows
+ 	 * 	login as root.
+ 	 * -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 autologin protocol;
+ 	 * -K is used by klogind to cause the Kerberos autologin protocol with
+ 	 *    restricted access.;
+ 	 */
+ 	(void)gethostname(tbuf, sizeof(tbuf));
+ 	domain = index(tbuf, '.');
  
+ 	fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0;
+ 	passwd_req = 1;
+ 	while ((ch = getopt(argc, argv, "feh:pr:k:K:")) != EOF)
+ 		switch (ch) {
+ 		case 'f':
+ 			EXCL_AUTH_TEST;
+ 			fflag = 1;
+ 			break;
+ 		case 'h':
+ 			EXCL_HOST_TEST;
+ 			if (getuid()) {
+ 				fprintf(stderr,
+ 				    "login: -h for super-user only.\n");
+ 				exit(1);
+ 			}
+ 			hflag = 1;
+ 			if (domain && (p = index(optarg, '.')) &&
+ 			    strcmp(p, domain) == 0)
+ 				*p = 0;
+ 			hostname = optarg;
+ 			break;
+ 		case 'p':
+ 			pflag = 1;
+ 			break;
+ 		case 'r':
+ 			EXCL_AUTH_TEST;
+ 			EXCL_HOST_TEST;
+ 			if (getuid()) {
+ 				fprintf(stderr,
+ 				    "login: -r for super-user only.\n");
+ 				exit(1);
+ 			}
+ 			/* "-r hostname" must be last args */
+ 			if (optind != argc) {
+ 				fprintf(stderr, "Syntax error.\n");
+ 				exit(1);
+ 			}
+ 			rflag = 1;
+ 			passwd_req = (doremotelogin(optarg) == -1);
+ 			if (domain && (p = index(optarg, '.')) &&
+ 			    !strcmp(p, domain))
+ 				*p = '\0';
+ 			hostname = optarg;
+ 			break;
  #ifdef KERBEROS
! 		case 'k':
! 		case 'K':
! 			EXCL_AUTH_TEST;
! 			EXCL_HOST_TEST;
! 			if (getuid()) {
! 				fprintf(stderr,
! 				    "login: -%c for super-user only.\n", ch);
! 				exit(1);
! 			}
! 			/* "-k hostname" must be last args */
! 			if (optind != argc) {
! 				fprintf(stderr, "Syntax error.\n");
! 				exit(1);
! 			}
! 			if (ch == 'K')
! 			    Kflag = 1;
! 			else
! 			    kflag = 1;
! 			passwd_req = (do_krb_login(optarg,
! 						   Kflag ? 1 : 0) == -1);
! 			if (domain && (p = index(optarg, '.')) &&
! 			    !strcmp(p, domain))
! 				*p = '\0';
! 			hostname = optarg;
! 			break;
  #endif /* KERBEROS */
! 		case 'e':
! 			EXCL_AUTH_TEST;
! 			if (getuid()) {
! 			    fprintf(stderr,
! 				    "login: -e for super-user only.\n");
! 			    exit(1);
! 			}
! 			eflag = 1;
! 			passwd_req = 0;
! 			break;
! 		case '?':
! 		default:
! 			fprintf(stderr, "usage: login [-fp] [username]\n");
! 			exit(1);
! 		}
! 	argc -= optind;
! 	argv += optind;
! 	if (*argv)
! 		username = *argv;
  
! #if !defined(_AIX)
  	ioctlval = 0;
! 	(void)ioctl(0, TIOCLSET, (char *)&ioctlval);
! 	(void)ioctl(0, TIOCNXCL, (char *)0);
! 	(void)fcntl(0, F_SETFL, ioctlval);
! #endif
! #ifdef POSIX
! 	(void)tcgetattr(0, &tc);
! #else
! 	(void)ioctl(0, TIOCGETP, (char *)&sgttyb);
! #endif
! 
  	/*
! 	 * If talking to an rlogin process, propagate the terminal type and
! 	 * baud rate across the network.
  	 */
! 	if (eflag)
! 	    	lgetstr(term, sizeof(term), "Terminal type");
! #ifdef POSIX
! 	if (rflag || kflag || Kflag || eflag)
! 		doremoteterm(&tc);
! 	tc.c_cc[VMIN] = 1;
! 	tc.c_cc[VTIME] = 0;
! 	tc.c_cc[VERASE] = CERASE;
! 	tc.c_cc[VKILL] = CKILL;
! 	tc.c_cc[VEOF] = CEOF;
! 	tc.c_cc[VINTR] = CINTR;
! 	tc.c_cc[VQUIT] = CQUIT;
! 	tc.c_cc[VSTART] = CSTART;
! 	tc.c_cc[VSTOP] = CSTOP;
! 	tc.c_cc[VEOL] = CNUL;
! 	/* The following are common extensions to POSIX */
! #ifdef VEOL2
! 	tc.c_cc[VEOL2] = CNUL;
! #endif
! #ifdef VSUSP
! 	tc.c_cc[VSUSP] = CSUSP;
! #endif
! #ifdef VDSUSP
! 	tc.c_cc[VDSUSP] = CDSUSP;
! #endif
! #ifdef VLNEXT
! 	tc.c_cc[VLNEXT] = CLNEXT;
! #endif
! #ifdef VREPRINT
! 	tc.c_cc[VREPRINT] = CRPRNT;
! #endif
! #ifdef VDISCRD
! 	tc.c_cc[VDISCRD] = CFLUSH;
! #endif
! #ifdef VWERSE
! 	tc.c_cc[VWERSE] = CWERASE;
! #endif
! 	tcsetattr(0, TCSANOW, &tc);
  #else
! 	if (rflag || kflag || Kflag || eflag)
! 		doremoteterm(&sgttyb);
! 	sgttyb.sg_erase = CERASE;
! 	sgttyb.sg_kill = CKILL;
! 	(void)ioctl(0, TIOCSLTC, (char *)&ltc);
! 	(void)ioctl(0, TIOCSETC, (char *)&tc);
! 	(void)ioctl(0, TIOCSETP, (char *)&sgttyb);
! #endif
! 
! 	for (cnt = getdtablesize(); cnt > 2; cnt--)
! 		(void) close(cnt);
! 
! 	ttyn = ttyname(0);
! 	if (ttyn == NULL || *ttyn == '\0')
! 		ttyn = "/dev/tty??";
! 
! 	/* This allows for tty names of the form /dev/pts/4 as well */
! 	if ((tty = index(ttyn, '/')) && (tty = index(tty+1, '/')))
! 		++tty;
! 	else
! 		tty = ttyn;
! 
! 	/* For kerberos tickets, extract only the last part of the ttyname */
! 	if (ktty = rindex(tty, '/'))
! 		++ktty;
! 	else
! 		ktty = tty;
! 
! #ifndef LOG_ODELAY /* 4.2 syslog ... */                      
! 	openlog("login", 0);
! #else
! 	openlog("login", LOG_ODELAY, LOG_AUTH);
! #endif /* 4.2 syslog */
! 
! 	for (cnt = 0;; username = NULL) {
! #ifdef KERBEROS
! 		char pp[9], pp2[MAXPWSIZE], *namep;
! 		int krbval;
! 		char realm[REALM_SZ];
! 		int kpass_ok,lpass_ok;
! #ifdef NOENCRYPTION
! #define read_long_pw_string placebo_read_pw_string
! #else
! #define read_long_pw_string des_read_pw_string
  #endif
+ 		int read_long_pw_string();
+ #endif
+ #if !defined(_IBMR2)
+ 		ioctlval = 0;
+ 		(void)ioctl(0, TIOCSETD, (char *)&ioctlval);
+ #endif
+ 
+ 		if (username == NULL) {
+ 			fflag = 0;
+ 			getloginname();
+ 		}
+ 
+ 		if (pwd = getpwnam(username))
+ 			salt = pwd->pw_passwd;
+ 		else
+ 			salt = "xx";
+ 
+ 		/* if user not super-user, check for disabled logins */
+ 		if (pwd == NULL || pwd->pw_uid)
+ 			checknologin();
+ 
+ 		/*
+ 		 * Disallow automatic login to root; if not invoked by
+ 		 * root, disallow if the uid's differ.
+ 		 */
+ 		if (fflag && pwd) {
+ 			int uid = (int) getuid();
+ 
+ 			passwd_req = pwd->pw_uid == 0 ||
+ 			    (uid && uid != pwd->pw_uid);
+ 		}
+ 
+ 		/*
+ 		 * If no remote login authentication and a password exists
+ 		 * for this user, prompt for one and verify it.
+ 		 */
+ 		if (!passwd_req || pwd && !*pwd->pw_passwd)
+ 			break;
+ 
+ #ifdef KERBEROS
+ 		kpass_ok = 0;
+ 		lpass_ok = 0;
+ 
+ 		(void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
+ 		if (read_long_pw_string(pp2, sizeof(pp2)-1, "Password: ", 0)) {
+ 		    /* reading password failed... */
+ 		    (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ 		    goto bad_login;
+ 		}
+ 		if (!pwd)		/* avoid doing useless work */
+ 		    goto bad_login;
+ 
+ 		/* Modifications for Kerberos authentication -- asp */
+ 		(void) strncpy(pp, pp2, sizeof(pp));
+ 		pp[8]='\0';
+ 		namep = crypt(pp, pwd->pw_passwd);
+ 		bzero (pp, sizeof(pp));	/* To the best of my recollection, Senator... */
+ 		lpass_ok = !strcmp (namep, pwd->pw_passwd);
+ 		
+ 		if (pwd->pw_uid != 0) { /* Don't get tickets for root */
+ 
+ 		    if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+ 			(void) strncpy(realm, KRB_REALM, sizeof(realm));
+ 		    }
+ #ifdef BIND_HACK
+ 		    /* Set name server timeout to be reasonable,
+ 		       so that people don't take 5 minutes to
+ 		       log in.  Can you say abstraction violation? */
+ 		    _res.retrans = 1;
+ #endif
+ #if 0  /* XXX krb5 has defaults; don't do this. */
+ 		    /* Set up the ticket file environment variable */
+ 		    strncpy(tkfile, KRB_TK_DIR, sizeof(tkfile));
+ 		    strncat(tkfile, ktty,
+ 			    sizeof(tkfile) - strlen(tkfile) - 1);
+ 		    (void) setenv(KRB_ENVIRON, tkfile, 1);
+ 		    krb_set_tkt_string(tkfile);
+ #endif
+ 
+ #ifdef _IBMR2
+ 		    krbval = setuidx(ID_REAL|ID_EFFECTIVE, pwd->pw_uid);
+ #else
+ 		    krbval = setreuid(pwd->pw_uid, -1);
+ #endif
+ 		    if (krbval) {
+ 			/* can't set ruid to user! */
+ 			krbval = -1;
+ 			fprintf(stderr,
+ 				"login: Can't set ruid for ticket file.\n");
+ 		    } else
+ 			krbval = krb_get_pw_in_tkt(username, "",
+ 						   realm, "krbtgt",
+ 						   realm,
+ 						   DEFAULT_TKT_LIFE, pp2);
+ 		    bzero (pp2, sizeof(pp2));
+ 		    (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ 		    switch (krbval) {
+ 		    case INTK_OK:
+ 			kpass_ok = 1;
+ 			krbflag = 1;
+ 			break;	
+ 
+ 		    /* These errors should be silent */
+ 		    /* So the Kerberos database can't be probed */
+ 		    case KDC_NULL_KEY:
+ 		    case KDC_PR_UNKNOWN:
+ 		    case INTK_BADPW:
+ 		    case KDC_PR_N_UNIQUE:
+ 		    case -1:
+ 			break;
+ 		    /* These should be printed but are not fatal */
+ 		    case INTK_W_NOTALL:
+ 			krbflag = 1;
+ 			kpass_ok = 1;
+ 			fprintf(stderr, "Kerberos error: %s\n",
+ 				krb_err_txt[krbval]);
+ 			break;
+ 		    default:
+ 			fprintf(stderr, "Kerberos error: %s\n",
+ 				krb_err_txt[krbval]);
+ 			break;
+ 		    }
+ 		} else {
+ 		    (void) bzero (pp2, sizeof(pp2));
+ 		    (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ 		}
+ 
+ 		/* Policy: If local password is good, user is good.
+ 		   We really can't trust the Kerberos password,
+ 		   because somebody on the net could spoof the
+ 		   Kerberos server (not easy, but possible).
+ 		   Some sites might want to use it anyways, in
+ 		   which case they should change this line
+ 		   to:
+ 		   if (kpass_ok)
+ 		   */
+ 		if (lpass_ok)
+ 		    break;
+ bad_login:
+ 		if (krbflag)
+ 		    dest_tkt();		/* clean up tickets if login fails */
+ #else
+ 		(void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
+ 		p = crypt(getpass("password:"), salt);
+ 		(void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ 		if (pwd && !strcmp(p, pwd->pw_passwd))
+ 			break;
+ #endif /* KERBEROS */
+ 
+ 		printf("Login incorrect\n");
+ 		if (++cnt >= 5) {
+ 			if (hostname)
+ 			    syslog(LOG_ERR,
+ 				"REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
+ 				tty, UT_HOSTSIZE, hostname, UT_NAMESIZE,
+ 				username);
+ 			else
+ 			    syslog(LOG_ERR,
+ 				"REPEATED LOGIN FAILURES ON %s, %.*s",
+ 				tty, UT_NAMESIZE, username);
+ 			(void)ioctl(0, TIOCHPCL, (char *)0);
+ 			sleepexit(1);
+ 		}
  	}
! 
! 	/* committed to login -- turn off timeout */
! 	(void)alarm((u_int)0);
! 
  	/*
! 	 * If valid so far and root is logging in, see if root logins on
! 	 * this terminal are permitted.
! 	 *
! 	 * We allow authenticated remote root logins (except -r style)
  	 */
! 	if (pwd->pw_uid == 0 && !rootterm(tty) && (passwd_req || rflag)) {
! 		if (hostname)
! 			syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s",
! 			    tty, UT_HOSTSIZE, hostname);
! 		else
! 			syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty);
! 		printf("Login incorrect\n");
! 		sleepexit(1);
  	}
! 
! #ifdef OQUOTA
! 	if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
! 		switch(errno) {
! 		case EUSERS:
! 			fprintf(stderr,
! 		"Too many users logged on already.\nTry again later.\n");
! 			break;
! 		case EPROCLIM:
! 			fprintf(stderr,
! 			    "You have too many processes running.\n");
! 			break;
! 		default:
! 			perror("quota (Q_SETUID)");
! 		}
! 		sleepexit(0);
! 	}
  #endif
! 
! 	if (chdir(pwd->pw_dir) < 0) {
! 		printf("No directory %s!\n", pwd->pw_dir);
! 		if (chdir("/"))
! 			exit(0);
! 		pwd->pw_dir = "/";
! 		printf("Logging in with home = \"/\".\n");
  	}
! 
! 	/* nothing else left to fail -- really log in */
! 	{
! 		struct utmp utmp;
! 
! 		bzero((char *)&utmp, sizeof(utmp));
! 		login_time = time(&utmp.ut_time);
! 		(void) strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
! 		if (hostname)
! 		    (void) strncpy(utmp.ut_host, hostname,
! 				   sizeof(utmp.ut_host));
! 		else
! 		    bzero(utmp.ut_host, sizeof(utmp.ut_host));
! 		(void) strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
! 		login(&utmp);
! 	}
! 
! 	quietlog = access(HUSHLOGIN, F_OK) == 0;
! 	dolastlog(quietlog, tty);
! 
! 	if (!hflag && !rflag && !kflag && !Kflag && !eflag) {	/* XXX */
! 		static struct winsize win = { 0, 0, 0, 0 };
! 
! 		(void)ioctl(0, TIOCSWINSZ, (char *)&win);
! 	}
! 
! 	(void)chown(ttyn, pwd->pw_uid,
! 	    (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
! #ifdef KERBEROS
! 	if(krbflag)
! 	    (void) chown(getenv(KRB_ENVIRON), pwd->pw_uid, pwd->pw_gid);
  #endif
! 	(void)chmod(ttyn, 0620);
! #ifdef KERBEROS
! #ifdef SETPAG
! 	if (pwd->pw_uid) {
! 	    /* Only reset the pag for non-root users. */
! 	    /* This allows root to become anything. */
! 	    pagflag = 1;
! 	    setpag();
! 	}
! #endif
! 	/* Fork so that we can call kdestroy */
! 	dofork();
! #endif /* KERBEROS */
! 	(void)setgid((gid_type) pwd->pw_gid);
! 	(void) initgroups(username, pwd->pw_gid);
! 
! #ifdef OQUOTA
! 	quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
! #endif
! 	/* This call MUST succeed */
! #ifdef _IBMR2
! 	setuidx(ID_LOGIN, pwd->pw_uid);
! #endif
! 	if(setuid((uid_type) pwd->pw_uid) < 0) {
! 	     perror("setuid");
! 	     sleepexit(1);
! 	}
! 
! 	if (*pwd->pw_shell == '\0')
! 		pwd->pw_shell = BSHELL;
! 	/* turn on new line discipline for the csh */
! 	else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
! #if !defined(_IBMR2)
! 		ioctlval = NTTYDISC;
! 		(void)ioctl(0, TIOCSETD, (char *)&ioctlval);
! #endif
! 	}
! 
! 	/* destroy environment unless user has requested preservation */
! 	envinit = (char **)malloc(MAXENVIRON * sizeof(char *));
! 	if (envinit == 0) {
! 		fprintf(stderr, "Can't malloc empty environment.\n");
! 		sleepexit(1);
! 	}
! 	if (!pflag)
! 		environ = envinit;
! 
! 	i = 0;
! 
! #if defined(_AIX) && defined(_IBMR2)
! 	{
! 	    FILE *fp;
! 	    if ((fp = fopen("/etc/environment", "r")) != NULL) {
! 		while(fgets(tbuf, sizeof(tbuf), fp)) {
! 		    if ((tbuf[0] == '#') || (strchr(tbuf, '=') == 0))
! 			continue;
! 		    for (p = tbuf; *p; p++)
! 			if (*p == '\n') {
! 			    *p = '\0';
! 			    break;
! 			}
! 		    envinit[i++] = strsave(tbuf);
! 		}
! 		fclose(fp);
! 	    }
! 	}
! #endif
! 	sprintf(tbuf,"LOGNAME=%s",pwd->pw_name);
! 	envinit[i++] = strsave(tbuf);
! 	sprintf(tbuf,"LOGIN=%s",pwd->pw_name);
! 	envinit[i++] = strsave(tbuf);
! 
! 	envinit[i++] = NULL;
! 
! 	setenv("HOME", pwd->pw_dir, 0);
! 	setenv("PATH", "/usr/local/krb5/bin:/usr/local/bin:/usr/bin/X11:/usr/ucb:/bin:/usr/bin:.", 0);
! 	setenv("USER", pwd->pw_name, 0);
! 	setenv("SHELL", pwd->pw_shell, 0);
! 
! 	if (term[0] == '\0')
! 		(void) strncpy(term, stypeof(tty), sizeof(term));
! 	(void)setenv("TERM", term, 0);
! #ifdef KERBEROS
! 	/* tkfile[0] is only set if we got tickets above */
! 	if (tkfile[0])
! 	    (void) setenv(KRB_ENVIRON, tkfile, 1);
! #endif /* KERBEROS */
! 
! #if 0
! 	strcpy(wgfile, "/tmp/wg.XXXXXX");
! 	mktemp(wgfile);
! 	setenv("WGFILE", wgfile, 0);
! #endif
! 
! 	if (tty[sizeof("tty")-1] == 'd')
! 		syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
! 	if (pwd->pw_uid == 0)
! 		if (hostname)
! #ifdef KERBEROS
! 			if (kdata) {
! 			    /* @*$&@#*($)#@$ syslog doesn't handle very
! 			       many arguments */
! 			    char buf[BUFSIZ];
! 			    (void) sprintf(buf,
! 				   "ROOT LOGIN (krb) %s from %.*s, %s.%s@%s",
! 				   tty, UT_HOSTSIZE, hostname,
! 				   kdata->pname, kdata->pinst,
! 				   kdata->prealm);
! 			    syslog(LOG_NOTICE, buf);
! 		        } else {
! #endif /* KERBEROS */
! 			syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
! 			    tty, UT_HOSTSIZE, hostname);
! #ifdef KERBEROS
! 			}
!   		else 
! 			if (kdata) {
! 			    syslog(LOG_NOTICE,
! 				   "ROOT LOGIN (krb) %s, %s.%s@%s",
! 				   tty,
! 				   kdata->pname, kdata->pinst,
! 				   kdata->prealm);
! 			} 
! #endif /* KERBEROS */
! 		else
! 			syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
  
+ 	if (!quietlog) {
+ 		struct stat st;
  
+ #ifdef KERBEROS
+ 		if (!krbflag)
+ 		    printf("\nWarning: No Kerberos tickets obtained.\n\n");
+ #endif /* KERBEROS */
+ 		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 " : "");
+ 	}
+ 
+ #ifndef OQUOTA
+ 	if (! access( QUOTAWARN, X_OK)) (void) system(QUOTAWARN);
+ #endif
+ 	(void)signal(SIGALRM, SIG_DFL);
+ 	(void)signal(SIGQUIT, SIG_DFL);
+ 	(void)signal(SIGINT, SIG_DFL);
+ 	(void)signal(SIGTSTP, SIG_IGN);
+ 
+ 	tbuf[0] = '-';
+ 	(void) strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ?
+ 	    p + 1 : pwd->pw_shell);
+ 	execlp(pwd->pw_shell, tbuf, 0);
+ 	fprintf(stderr, "login: no shell: ");
+ 	perror(pwd->pw_shell);
+ 	exit(0);
+ }
  
  getloginname()
  {
! 	register int ch;
! 	register char *p;
! 	static char nbuf[UT_NAMESIZE + 1];
! 
! 	for (;;) {
! 		printf("login: ");
! 		for (p = nbuf; (ch = getchar()) != '\n'; ) {
! 			if (ch == EOF)
! 				exit(0);
! 			if (p < nbuf + UT_NAMESIZE)
! 				*p++ = ch;
! 		}
! 		if (p > nbuf)
! 			if (nbuf[0] == '-')
! 				fprintf(stderr,
! 				    "login names may not start with '-'.\n");
! 			else {
! 				*p = '\0';
! 				username = nbuf;
! 				break;
! 			}
! 	}
  }
  
  sigtype
! timedout()
  {
! 	fprintf(stderr, "Login timed out after %d seconds\n", timeout);
! 	exit(0);
  }
  
  #ifdef NOTTYENT
! int root_tty_security = 1;
  #endif
  rootterm(tty)
! 	char *tty;
  {
  #ifdef NOTTYENT
! 	return(root_tty_security);
  #else
! 	struct ttyent *t;
  
! 	return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
! #endif /* NOTTYENT */
! }
  
  jmp_buf motdinterrupt;
  
  motd()
  {
! 	register int fd, nchars;
! 	sigtype (*oldint)(), sigint();
! 	char tbuf[8192];
! 
! 	if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
! 		return;
! 	oldint = signal(SIGINT, sigint);
! 	if (setjmp(motdinterrupt) == 0)
! 		while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
! 			(void)write(fileno(stdout), tbuf, nchars);
! 	(void)signal(SIGINT, oldint);
! 	(void)close(fd);
  }
  
  sigtype
! sigint()
  {
! 	longjmp(motdinterrupt, 1);
  }
  
  checknologin()
  {
! 	register int fd, nchars;
! 	char tbuf[8192];
  
+ 	if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
+ 		while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
+ 			(void)write(fileno(stdout), tbuf, nchars);
+ 		sleepexit(0);
+ 	}
+ }
  
  dolastlog(quiet, tty)
! 	int quiet;
! 	char *tty;
  {
! #if !defined(_AIX)
! 	struct lastlog ll;
! 	int fd;
! 
! 	if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
! 		(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
! 		if (!quiet) {
! 			if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
! 			    ll.ll_time != 0) {
! 				printf("Last login: %.*s ",
! 				    24-5, (char *)ctime(&ll.ll_time));
! 				if (*ll.ll_host != '\0')
! 					printf("from %.*s\n",
! 					    sizeof(ll.ll_host), ll.ll_host);
! 				else
! 					printf("on %.*s\n",
! 					    sizeof(ll.ll_line), ll.ll_line);
! 			}
! 			(void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
! 		}
! 		(void)time(&ll.ll_time);
! 		(void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
! 		if (hostname)
! 		    (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
  		else
! 		    (void) bzero(ll.ll_host, sizeof(ll.ll_host));
! 		(void)write(fd, (char *)&ll, sizeof(ll));
! 		(void)close(fd);
  	}
! #endif
  }
  
  #undef	UNKNOWN
  #define	UNKNOWN	"su"
  
! char *
! stypeof(ttyid)
! 	char *ttyid;
  {
  #ifdef NOTTYENT
! 	return(UNKNOWN);
  #else
! 	struct ttyent *t;
! 
! 	return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
  #endif
  }
  
+ doremotelogin(host)
+ 	char *host;
+ {
+ 	static char lusername[UT_NAMESIZE+1];
+ 	char rusername[UT_NAMESIZE+1];
  
+ 	lgetstr(rusername, sizeof(rusername), "Remote user");
+ 	lgetstr(lusername, sizeof(lusername), "Local user");
+ 	lgetstr(term, sizeof(term), "Terminal type");
+ 	username = lusername;
+ 	pwd = getpwnam(username);
+ 	if (pwd == NULL)
+ 		return(-1);
+ 	return(ruserok(host, (pwd->pw_uid == 0), rusername, username));
+ }
  
! #ifdef KERBEROS
! do_krb_login(host, strict)
! 	char *host;
! 	int strict;
  {
! 	int rc;
! 	struct sockaddr_in sin;
! 	char instance[INST_SZ], version[9];
! 	long authoptions = 0L;
!         struct hostent *hp = gethostbyname(host);
! 	static char lusername[UT_NAMESIZE+1];
! 
! 	/*
! 	 * Kerberos autologin protocol.
! 	 */
! 
! 	(void) bzero((char *) &sin, (int) sizeof(sin));
! 
!         if (hp)
!                 (void) bcopy (hp->h_addr, (char *)&sin.sin_addr,
! 			      sizeof(sin.sin_addr));
! 	else
! 		sin.sin_addr.s_addr = inet_addr(host);
! 
! 	if ((hp == NULL) && (sin.sin_addr.s_addr == -1)) {
! 	    printf("Hostname did not resolve to an address, so Kerberos authentication failed\r\n");
!                 /*
! 		 * No host addr prevents auth, so
!                  * punt krb and require password
! 		 */
!                 if (strict) {
!                         goto paranoid;
!                 } else {
! 			pwd = NULL;
!                         return(-1);
! 		}
  	}
! 
! 	kdata = (AUTH_DAT *)malloc( sizeof(AUTH_DAT) );
! 	ticket = (KTEXT) malloc(sizeof(KTEXT_ST));
  
+ 	(void) strcpy(instance, "*");
+ 	if (rc=krb_recvauth(authoptions, 0, ticket, "rcmd",
+ 			    instance, &sin,
+ 			    (struct sockaddr_in *)0,
+ 			    kdata, "", (bit_64 *) 0, version)) {
+ 		printf("Kerberos rlogin failed: %s\r\n",krb_err_txt[rc]);
+ 		if (strict) {
+ paranoid:
+ 			/*
+ 			 * Paranoid hosts, such as a Kerberos server,
+ 			 * specify the Klogind daemon to disallow
+ 			 * even password access here.
+ 			 */
+ 			printf("Sorry, you must have Kerberos authentication to access this host.\r\n");
+ 			exit(1);
+ 		}
+ 	}
+ 	(void) lgetstr(lusername, sizeof (lusername), "Local user");
+ 	(void) lgetstr(term, sizeof(term), "Terminal type");
+ 	username = lusername;
+ 	if (getuid()) {
+ 		pwd = NULL;
+ 		return(-1);
+ 	}
+ 	pwd = getpwnam(lusername);
+ 	if (pwd == NULL) {
+ 		pwd = NULL;
+ 		return(-1);
+ 	}
  
+ 	/*
+ 	 * if Kerberos login failed because of an error in krb_recvauth,
+ 	 * return the indication of a bad attempt.  User will be prompted
+ 	 * for a password.  We CAN'T check the .rhost file, because we need 
+ 	 * the remote username to do that, and the remote username is in the 
+ 	 * Kerberos ticket.  This affects ONLY the case where there is
+ 	 * Kerberos on both ends, but Kerberos fails on the server end. 
+ 	 */
+ 	if (rc) {
+ 		return(-1);
+ 	}
  
! 	if (rc=kuserok(kdata,lusername)) {
! 		printf("login: %s has not given you permission to login without a password.\r\n",lusername);
! 		if (strict) {
! 		  exit(1);
! 		}
! 		return(-1);
! 	}
! 	return(0);
  }
! #endif /* KERBEROS */
  
+ lgetstr(buf, cnt, err)
+ 	char *buf, *err;
+ 	int cnt;
+ {
+ 	int ocnt = cnt;
+ 	char *obuf = buf;
+ 	char ch;
+ 
+ 	do {
+ 		if (read(0, &ch, sizeof(ch)) != sizeof(ch))
+ 			exit(1);
+ 		if (--cnt < 0) {
+ 			fprintf(stderr,"%s '%.*s' too long, %d characters maximum.\r\n",
+ 			       err, ocnt, obuf, ocnt-1);
+ 			sleepexit(1);
+ 		}
+ 		*buf++ = ch;
+ 	} while (ch);
+ }
  
  char *speeds[] = {
! 	"0", "50", "75", "110", "134", "150", "200", "300", "600",
! 	"1200", "1800", "2400", "4800", "9600", "19200", "38400",
  };
  #define	NSPEEDS	(sizeof(speeds) / sizeof(speeds[0]))
  
  doremoteterm(tp)
! #ifdef POSIX
! 	struct termios *tp;
! #else
! 	struct sgttyb *tp;
! #endif
  {
! 	register char *cp = index(term, '/'), **cpp;
! 	char *speed;
  
+ 	if (cp) {
+ 		*cp++ = '\0';
+ 		speed = cp;
+ 		cp = index(speed, '/');
+ 		if (cp)
+ 			*cp++ = '\0';
+ 		for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
+ 			if (strcmp(*cpp, speed) == 0) {
+ #ifdef POSIX
+ 				tp->c_cflag =
+ 					(tp->c_cflag & ~CBAUD) | (cpp-speeds);
+ #else
+ 				tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
+ #endif
+ 				break;
+ 			}
+ 	}
+ #ifdef POSIX
+  	/* set all standard echo, edit, and job control options */
+  	tp->c_lflag = ECHO|ECHOE|ECHOK|ICANON|ISIG;
+  	tp->c_iflag |= ICRNL|BRKINT;
+  	tp->c_oflag |= ONLCR|OPOST|TAB3;
+ #else /* !POSIX */
+ 	tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
+ #endif
+ }
  
  sleepexit(eval)
! 	int eval;
  {
! #ifdef KERBEROS
! 	if (krbflag)
! 	    (void) dest_tkt();
! #endif /* KERBEROS */
! 	sleep((u_int)5);
! 	exit(eval);
  }
  
+ #ifdef KERBEROS
+ /*
+  * This routine handles cleanup stuff, and the like.
+  * It exits only in the child process.
+  */
+ #include <sys/wait.h>
+ void
+ dofork()
+ {
+     int child;
  
+ #ifdef _IBMR2
+     update_ref_count(1);
+ #endif
+     if(!(child=fork()))
+ 	    return; /* Child process */
  
!     /* Setup stuff?  This would be things we could do in parallel with login */
!     (void) chdir("/");	/* Let's not keep the fs busy... */
      
!     /* If we're the parent, watch the child until it dies */
!     while(wait((union wait *)0) != child)
! 	    ;
! 
!     /* Cleanup stuff */
!     /* Run dest_tkt to destroy tickets */
!     (void) dest_tkt();		/* If this fails, we lose quietly */
! #ifdef SETPAG
!     if (pagflag)
! 	ktc_ForgetAllTokens();
! #endif
! #ifdef _IBMR2
!     update_ref_count(-1);
! #endif
! 
!     /* Leave */
!     exit(0);
! }
! #endif /* KERBEROS */
! 
! 
! char *strsave(s)
! char *s;
! {
!     char *ret = (char *)malloc(strlen(s) + 1);
!     strcpy(ret, s);
!     return(ret);
! }
! 
! #ifdef _IBMR2
! update_ref_count(int adj)
! {
!     static char *empty = "\0";
!     char *grp;
!     int i;
! 
!     /* Update reference count on all user's temporary groups */
!     setuserdb(S_READ|S_WRITE);
!     if (getuserattr(username, S_GROUPS, (void *)&grp, SEC_LIST) == 0) {
! 	while (*grp) {
! 	    if (getgroupattr(grp, "athena_temp", (void *)&i, SEC_INT) == 0) {
! 		i += adj;
! 		if (i > 0) {
! 		    putgroupattr(grp, "athena_temp", (void *)i, SEC_INT);
! 		    putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
! 		} else {
! 		    putgroupattr(grp, S_USERS, (void *)empty, SEC_LIST);
! 		    putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
! 		    rmufile(grp, 0, GROUP_TABLE);
! 		}
! 	    }
! 	    while (*grp) grp++;
! 	    grp++;
! 	}
      }
+     enduserdb();
  }
+ #endif

*** ./appl/bsd/krcp.c.old	1992/11/20 14:40:59
--- ./appl/bsd/krcp.c	1992/11/20 14:41:33
***************
*** 104,110 ****
  #endif /* KERBEROS */
  
  int	rem;
! char	*colon(), *index(), *rindex(), *strcpy();
  int	errs;
  krb5_sigtype	lostconn();
  int	errno;
--- 104,116 ----
  #endif /* KERBEROS */
  
  int	rem;
! char	*colon(), *strcpy();
! #ifndef index
! char	*index();
! #endif
! #ifndef rindex
! char	*rindex();
! #endif
  int	errs;
  krb5_sigtype	lostconn();
  int	errno;

*** ./appl/bsd/logutil.c.old	1993/02/26 22:20:55
--- ./appl/bsd/logutil.c	1993/02/26 22:21:20
***************
*** 15,178 ****
   * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)login.c	5.1 (Berkeley) 9/27/88";
- #endif /* LIBC_SCCS and not lint */
-      
  #include <sys/types.h>
  #include <sys/file.h>
- #if defined (CRAY) || defined (sgi)
- #include <sys/fcntl.h>
- #define L_SET 0
- #define L_INCR 1
- #endif
  #include <utmp.h>
  #include <stdio.h>
  #include <sys/time.h>
  #include <sys/stat.h>
-      
- #ifndef UTMP_FILE
- #define	UTMP_FILE	"/etc/utmp"
- #endif
- #ifndef WTMP_FILE
- #ifdef SYSV
- #define WTMPFILE    "/etc/wtmp"
- #else
- #define	WTMP_FILE	"/usr/adm/wtmp"
- #endif
- #endif
-      
- void login(ut)
-      struct utmp *ut;
- {
-     register int fd;
-     int tty;
-     off_t lseek();
-     
-     tty = ttyslot();
-     if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) {
- 	(void)lseek(fd, (long)(tty * sizeof(struct utmp)), L_SET);
- 	(void)write(fd, (char *)ut, sizeof(struct utmp));
- 	(void)close(fd);
-     }
-     if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) >= 0) {
- 	(void)write(fd, (char *)ut, sizeof(struct utmp));
- 	(void)close(fd);
-     }
- }
  
  
  
- /*
-  * Copyright (c) 1988 The Regents of the University of California.
-  * All rights reserved.
-  *
-  * Redistribution and use in source and binary forms are permitted
-  * provided that the above copyright notice and this paragraph are
-  * duplicated in all such forms and that any documentation,
-  * advertising materials, and other materials related to such
-  * distribution and use acknowledge that the software was developed
-  * by the University of California, Berkeley.  The name of the
-  * University may not be used to endorse or promote products derived
-  * from this software without specific prior written permission.
-  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-  */
- 
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)logout.c	5.1 (Berkeley) 8/31/88";
- #endif /* LIBC_SCCS and not lint */
-      
  logout(line)
!      register char *line;
  {
!     register FILE *fp;
!     struct utmp ut;
!     int rval;
!     time_t time();
!     
!     if (!(fp = fopen(UTMP_FILE, "r+")))
!       return(0);
!     rval = 1;
!     while (fread((char *)&ut, sizeof(struct utmp), 1, fp) == 1) {
! 	if (!ut.ut_name[0] ||
! 	    strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
! 	  continue;
! 	memset(ut.ut_name,0, sizeof(ut.ut_name));
! #ifndef  NO_UT_HOST
! 	memset(ut.ut_host,0, sizeof(ut.ut_host));
! #endif
! 	(void)time(&ut.ut_time);
! 	(void)fseek(fp, (long)-sizeof(struct utmp), L_INCR);
! 	(void)fwrite((char *)&ut, sizeof(struct utmp), 1, fp);
! 	(void)fseek(fp, (long)0, L_INCR);
! 	rval = 0;
!     }
!     (void)fclose(fp);
!     return(rval);
  }
  
! 
! 
! /*
!  * Copyright (c) 1988 The Regents of the University of California.
!  * All rights reserved.
!  *
!  * Redistribution and use in source and binary forms are permitted
!  * provided that the above copyright notice and this paragraph are
!  * duplicated in all such forms and that any documentation,
!  * advertising materials, and other materials related to such
!  * distribution and use acknowledge that the software was developed
!  * by the University of California, Berkeley.  The name of the
!  * University may not be used to endorse or promote products derived
!  * from this software without specific prior written permission.
!  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
!  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
!  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
!  */
! 
! #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)logwtmp.c	5.2 (Berkeley) 9/20/88";
! #endif /* LIBC_SCCS and not lint */
!      
! static int fd = -1;
! 
! #ifndef SYSV
! logwtmp(line, name, host, keep_open)
! #else
! logwtmp(line, name, host, keep_open, logingin)
! #endif
!      char *line, *name, *host;
!      int keep_open;
! #ifdef  SYSV
!      int logingin;
! #endif
  {
!     struct utmp ut;
!     struct stat buf;
!     time_t time();
!     char *strncpy();
!     
!     if (fd < 0 && (fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0)
!       return;
!     if (!fstat(fd, &buf)) {
! 	(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
! 	(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
! #ifndef  NO_UT_HOST
! 	(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
! #endif 
! #ifdef  SYSV
! 	(void)strncpy(ut.ut_id, (char *)ut.ut_line + 4,
! 		      sizeof(ut.ut_id));
! 	ut.ut_type = logingin ? USER_PROCESS : DEAD_PROCESS;
! 	ut.ut_pid = getpid();
! #endif
! 	(void)time(&ut.ut_time);
! 	if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
! 	    sizeof(struct utmp))
! 	  (void)ftruncate(fd, buf.st_size);
!     }
!     if ( !keep_open)
!       (void)close(fd);
  }
--- 15,125 ----
   * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   */
  
  #include <sys/types.h>
  #include <sys/file.h>
  #include <utmp.h>
  #include <stdio.h>
+ #include <strings.h>
  #include <sys/time.h>
  #include <sys/stat.h>
  
+ #define	UTMPFILE	"/etc/utmp"
+ #define	WTMPFILE	"/usr/adm/wtmp"
+ 
+ void
+ login(ut)
+ 	struct utmp *ut;
+ {
+ 	register int fd;
+ 	struct utmp utmp;
+ 	int tty;
+ 
+ #if defined(_AIX)
+ 	if (!ut->ut_pid)
+ 		ut->ut_pid = getppid();
+ 	ut->ut_type = USER_PROCESS;
+ 	(void) strncpy(ut->ut_id, ut->ut_line, sizeof(ut->ut_id));
+ 
+ 	(void) setutent();
+ 	(void) bzero((char *)&utmp, sizeof(utmp));
+ 	(void) strncpy(utmp.ut_id, ut->ut_id, sizeof(utmp.ut_id));
+ 	utmp.ut_type = DEAD_PROCESS;
+ 	(void) getutid(&utmp);
  
+ 	(void) pututline(ut);
+ 	(void) endutent();
+ #else
+ 	tty = ttyslot();
+ 	if (tty > 0 && (fd = open(UTMPFILE, O_WRONLY, 0)) >= 0) {
+ 		(void)lseek(fd, (long)(tty * sizeof(struct utmp)), L_SET);
+ 		(void)write(fd, (char *)ut, sizeof(struct utmp));
+ 		(void)close(fd);
+ 	}
+ #endif
+ 	if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) >= 0) {
+ 		(void)write(fd, (char *)ut, sizeof(struct utmp));
+ 		(void)close(fd);
+ 	}
+ }
  
  logout(line)
! 	register char *line;
  {
! 	register FILE *fp;
! 	struct utmp ut;
! 	int rval;
! 
! 	if (!(fp = fopen(UTMPFILE, "r+")))
! 		return(0);
! 	rval = 1;
! 	while (fread((char *)&ut, sizeof(struct utmp), 1, fp) == 1) {
! 		if (!ut.ut_name[0] ||
! 		    strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
! 			continue;
! 		(void)bzero(ut.ut_name, sizeof(ut.ut_name));
! 		(void)bzero(ut.ut_host, sizeof(ut.ut_host));
! 		(void)time(&ut.ut_time);
! #if defined(_AIX)
! 		(void)bzero(ut.ut_id, sizeof(ut.ut_id));
! 		ut.ut_pid = ut.ut_exit.e_exit = 0;
! 		ut.ut_type = EMPTY;
! #endif
! 		(void)fseek(fp, (long)-sizeof(struct utmp), L_INCR);
! 		(void)fwrite((char *)&ut, sizeof(struct utmp), 1, fp);
! 		(void)fseek(fp, (long)0, L_INCR);
! 		rval = 0;
! 	}
! 	(void)fclose(fp);
! 	return(rval);
  }
  
! logwtmp(line, name, host)
! 	char *line, *name, *host;
  {
! 	struct utmp ut;
! 	struct stat buf;
! 	int fd;
! 
! 	if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
! 		return;
! 	if (!fstat(fd, &buf)) {
! 		(void)bzero((char *)&ut, sizeof(ut));
! 		(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
! 		(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
! 		(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
! 		(void)time(&ut.ut_time);
! #if defined(_AIX)
! 		if (*name) {
! 			if (!ut.ut_pid)
! 				ut.ut_pid = getpid();
! 			ut.ut_type = USER_PROCESS;
! 		} else {
! 			ut.ut_type = EMPTY;
! 		}
! #endif
! 		if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
! 		    sizeof(struct utmp))
! 			(void)ftruncate(fd, buf.st_size);
! 	}
! 	(void)close(fd);
  }

*** ./appl/bsd/krlogin.c.old	1992/11/20 15:23:26
--- ./appl/bsd/krlogin.c	1992/11/20 15:23:46
***************
*** 136,142 ****
  # define SIGUSR1 30
  # endif /* SIGUSR1 */
  
! char	*index(), *rindex(), *getenv(), *strcat(), *strcpy();
  #ifndef convex
  struct	passwd *getpwuid();
  #endif
--- 136,148 ----
  # define SIGUSR1 30
  # endif /* SIGUSR1 */
  
! char	*getenv(), *strcat(), *strcpy();
! #ifndef index
! char	*index();
! #endif
! #ifndef rindex
! char	*rindex();
! #endif
  #ifndef convex
  struct	passwd *getpwuid();
  #endif

*** ./appl/bsd/krlogind.c.old	1992/11/20 15:27:32
--- ./appl/bsd/krlogind.c	1992/12/09 15:03:14
***************
*** 95,101 ****
--- 95,106 ----
        */
       
  #define LOG_REMOTE_REALM
+ 
+ /* XXXX These should be in the site.def file; the Imakefile needs some
+ changes */
+ 
  #define KERBEROS 
+ #define CRYPT
       
  #include <stdio.h>
  #include <sys/types.h>
***************
*** 139,144 ****
--- 144,150 ----
  #include <netdb.h>
  #include <syslog.h>
  #include <strings.h>
+ #include <ctype.h>
  #include <sys/param.h>
  #include <utmp.h>
       
***************
*** 180,192 ****
  #endif
  #endif
  
! #define ARGSTR	"rRkKeExXpP?"
  #else /* !KERBEROS */
! #define ARGSTR	"rRpP?"
  #define des_read        read
  #define des_write       write
  #endif /* KERBEROS */
  
  #ifdef DO_NOT_USE_K_LOGIN
  #ifdef sysvimp
  #define LOGIN_PROGRAM "/bin/remlogin"
--- 186,199 ----
  #endif
  #endif
  
! #define ARGSTR	"rRkKeExXpPD:?"
  #else /* !KERBEROS */
! #define ARGSTR	"rRpPD:?"
  #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"
***************
*** 196,201 ****
--- 203,209 ----
  #else /* DO_NOT_USE_K_LOGIN */
  #define LOGIN_PROGRAM "/krb5/etc/login.krb5"
  #endif
+ #endif
  
  struct utmp	wtmp;
  #define NMAX    sizeof(wtmp.ut_name)
***************
*** 212,218 ****
  extern	int errno;
  int	reapchild();
  struct	passwd *getpwnam();
! #ifndef ultrix
  char	*malloc();
  #endif
  char 	*progname;
--- 220,226 ----
  extern	int errno;
  int	reapchild();
  struct	passwd *getpwnam();
! #ifndef __STDC__
  char	*malloc();
  #endif
  char 	*progname;
***************
*** 228,237 ****
       int argc;
       char **argv;
  {
!     extern int opterr, optind;
      int on = 1, fromlen, ch, i;
      struct sockaddr_in from;
      char *options;
      
      progname = *argv;
      
--- 236,247 ----
       int argc;
       char **argv;
  {
!     extern int opterr, optind, optarg;
      int on = 1, fromlen, ch, i;
      struct sockaddr_in from;
      char *options;
+     int debug_port = 0;
+     int fd;
      
      progname = *argv;
      
***************
*** 267,277 ****
  	options[0] = '\0';
  	for (i = 0; (progname[i] != '\0') && (i < MAX_PROG_NAME); i++)
  	  if (!strcmp(progname+i, "logind")) {
  	      strcpy(options, "-");
  	      strncat(options, progname, i);
  	      argc = 2;
! 	      argv[1] = options;
! 	      argv[2] = NULL;
  	      break;
  	  }
  	if (options[0] == '\0') {
--- 277,294 ----
  	options[0] = '\0';
  	for (i = 0; (progname[i] != '\0') && (i < MAX_PROG_NAME); i++)
  	  if (!strcmp(progname+i, "logind")) {
+ 	      char **newargv;
+ 
+ 	      newargv = (char **) malloc(sizeof(char *) * 3);
+ 
  	      strcpy(options, "-");
  	      strncat(options, progname, i);
+ 
+ 	      newargv[0] = argv[0];
+ 	      newargv[1] = options;
+ 	      newargv[2] = NULL;
  	      argc = 2;
! 	      argv = newargv;
  	      break;
  	  }
  	if (options[0] == '\0') {
***************
*** 316,321 ****
--- 333,341 ----
  	case 'P':         /* passwd is a must */
  	  passwd_req = 1;
  	  break;
+ 	case 'D':
+ 	  debug_port = atoi(optarg);
+ 	  break;
  	case '?':
  	default:
  	  usage();
***************
*** 326,344 ****
      argv += optind;
      
      fromlen = sizeof (from);
!     if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! 	syslog(LOG_ERR,"Can't get peer name of remote host: %m");
  #ifdef STDERR_FILENO
! 	fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
  #else
! 	fatal(3, "Can't get peer name of remote host", 1);
  #endif
! 	
      }
!     if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
        syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
      
!     doit(0, &from);
  }
  
  
--- 346,399 ----
      argv += optind;
      
      fromlen = sizeof (from);
! 
!     if (debug_port) {
!        int s;
!        struct sockaddr_in sin;
! 
!        if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
! 	  fprintf(stderr, "Error in socket: %s\n", strerror(errno));
! 	  exit(2);
!        }
! 
!        bzero((char *) &sin,sizeof(sin));
!        sin.sin_family = AF_INET;
!        sin.sin_port = htons(debug_port);
!        sin.sin_addr.s_addr = INADDR_ANY;
!        
!        if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
! 	  fprintf(stderr, "Error in bind: %s\n", strerror(errno));
! 	  exit(2);
!        }
! 
!        if ((listen(s, 5)) < 0) {
! 	  fprintf(stderr, "Error in listen: %s\n", strerror(errno));
! 	  exit(2);
!        }
! 
!        if ((fd = accept(s, &from, &fromlen)) < 0) {
! 	  fprintf(stderr, "Error in accept: %s\n", strerror(errno));
! 	  exit(2);
!        }
! 
!        close(s);
!     } else {
!        if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! 	  syslog(LOG_ERR,"Can't get peer name of remote host: %m");
  #ifdef STDERR_FILENO
! 	  fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
  #else
! 	  fatal(3, "Can't get peer name of remote host", 1);
  #endif
!        }
! 
!        fd = 0;
      }
! 
!     if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
        syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
      
!     doit(fd, &from);
  }
  
  
***************
*** 435,443 ****
      }
  #else
      rusername = malloc(sizeof (lusername) + 1);
!     getstr(rusername, sizeof(lusername), "remuser");
!     getstr(lusername, sizeof(lusername), "locuser");
!     getstr(term, sizeof(term), "Terminal type");
  #endif
      
      write(f, "", 1);
--- 490,498 ----
      }
  #else
      rusername = malloc(sizeof (lusername) + 1);
!     getstr(f, rusername, sizeof(lusername), "remuser");
!     getstr(f, lusername, sizeof(lusername), "locuser");
!     getstr(f, term, sizeof(term), "Terminal type");
  #endif
      
      write(f, "", 1);
***************
*** 462,474 ****
  #endif
  	fatalperror(f, line);
  #ifndef SYSV
!     signal(SIGHUP, SIG_IGN);
!     vhangup();
!     signal(SIGHUP, SIG_DFL);
  #ifdef ultrix   /* Someone needs to cleanup all this and have a consistant
  		   way of associating controlling tty to a process. */
      setpgrp();
  #endif
      t = open(line, O_RDWR);
      if (t < 0)
        fatalperror(f, line);
--- 517,534 ----
  #endif
  	fatalperror(f, line);
  #ifndef SYSV
!     if (f == 0) {	/* if operating standalone, do not reset tty!! */
!        signal(SIGHUP, SIG_IGN);
!        vhangup();
!        signal(SIGHUP, SIG_DFL);
!     }
  #ifdef ultrix   /* Someone needs to cleanup all this and have a consistant
  		   way of associating controlling tty to a process. */
      setpgrp();
  #endif
+ #if defined (sun) || defined (POSIX)
+     setsid();
+ #endif
      t = open(line, O_RDWR);
      if (t < 0)
        fatalperror(f, line);
***************
*** 607,615 ****
  	execl(LOGIN_PROGRAM, "login", "-r", rhost_name, 0);
  #else
  	if (passwd_req)
! 	  execl(LOGIN_PROGRAM, "login", rhost_name,0);
  	else
! 	  execl(LOGIN_PROGRAM, "login", "-f", rhost_name, 0);
  #endif
  	
  	fatalperror(2, LOGIN_PROGRAM, errno);
--- 667,675 ----
  	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, errno);
***************
*** 660,665 ****
--- 720,727 ----
  #endif
      
  #if defined(KERBEROS) 
+ #if 0 /* the code in the login I'm using only reads term.  local user
+ 	 is passed in on the command line, and remote user is not used */
      /* Pass down rusername and lusername which we have
         obtained from ticket and authorized by PWC_ACCESS.
         Note lusername's .rhost should have entry for rusername.
***************
*** 666,671 ****
--- 728,734 ----
         */
      (void) write(p, rusername, strlen(rusername) +1);
      (void) write(p, lusername, strlen(lusername) +1);
+ #endif
      /* stuff term info down to login */
      if( write(p, term, strlen(term)+1) <= 0 ){
  	/*
***************
*** 945,950 ****
--- 1008,1015 ----
      krb5_principal server;
      char srv_name[100];
      char def_host[100];
+     struct hostent *he;
+     char *ptr;
      krb5_data inbuf;
      
      if (getuid()) {
***************
*** 968,983 ****
      peeraddr.length = SIZEOF_INADDR;
      peeraddr.contents = (krb5_octet *)&peersin.sin_addr;
      
!     strcpy(srv_name, "host/");
!     gethostname(def_host, 100);
!     strcat(srv_name, def_host);
!     if (status = krb5_parse_name(srv_name, &server)) {
  	syslog(LOG_ERR, "parse server name %s: %s", "host",
  	       error_message(status));
  	exit(1);
      }
!     krb5_princ_type(server) = KRB5_NT_SRV_HST;
!     
      if (status = krb5_recvauth(&netf, 
  			       "KCMDV0.1",
  			       server,     /* no match on server 
--- 1033,1045 ----
      peeraddr.length = SIZEOF_INADDR;
      peeraddr.contents = (krb5_octet *)&peersin.sin_addr;
      
!     if (status = krb5_sname_to_principal(NULL,"host",KRB5_NT_SRV_HST,
! 					 &server)) {
  	syslog(LOG_ERR, "parse server name %s: %s", "host",
  	       error_message(status));
  	exit(1);
      }
! 
      if (status = krb5_recvauth(&netf, 
  			       "KCMDV0.1",
  			       server,     /* no match on server 
***************
*** 1014,1023 ****
  	if (inbuf.length)
  	  fatal(netf, "Forwarding is not yet supported");
  	
! 	getstr(lusername, sizeof(lusername), "locuser");
! 	getstr(term, sizeof(term), "Terminal type");
  	rusername = malloc(sizeof (lusername) + 1);
! 	getstr(rusername, sizeof(lusername), "remuser");
  	
  	failed_auth = 1;
  	if (ticket)
--- 1076,1085 ----
  	if (inbuf.length)
  	  fatal(netf, "Forwarding is not yet supported");
  	
! 	getstr(netf, lusername, sizeof(lusername), "locuser");
! 	getstr(netf, term, sizeof(term), "Terminal type");
  	rusername = malloc(sizeof (lusername) + 1);
! 	getstr(netf, rusername, sizeof(lusername), "remuser");
  	
  	failed_auth = 1;
  	if (ticket)
***************
*** 1046,1055 ****
      if (inbuf.length)
        fatal(netf, "Forwarding is not yet supported");
  
!     getstr(lusername, sizeof(lusername), "locuser");
!     getstr(term, sizeof(term), "Terminal type");
      rusername = malloc(sizeof (lusername) + 1);
!     getstr(rusername, sizeof(lusername), "remuser");
      
      /* OK we have authenticated this user - now check authorization. */
      /* We must do this here since we want the same functionality as */
--- 1108,1117 ----
      if (inbuf.length)
        fatal(netf, "Forwarding is not yet supported");
  
!     getstr(netf, lusername, sizeof(lusername), "locuser");
!     getstr(netf, term, sizeof(term), "Terminal type");
      rusername = malloc(sizeof (lusername) + 1);
!     getstr(netf, rusername, sizeof(lusername), "remuser");
      
      /* OK we have authenticated this user - now check authorization. */
      /* We must do this here since we want the same functionality as */
***************
*** 1103,1120 ****
      return;
  }
  
! 
! 
! getstr(buf, cnt, err)
       char *buf;
       int cnt;
       char *err;
  {
-     
      char c;
      
      do {
! 	if (read(0, &c, 1) != 1) {
  	    exit(1);
  	}
  	if (--cnt < 0) {
--- 1165,1180 ----
      return;
  }
  
! getstr(fd, buf, cnt, err)
!      int fd;
       char *buf;
       int cnt;
       char *err;
  {
      char c;
      
      do {
! 	if (read(fd, &c, 1) != 1) {
  	    exit(1);
  	}
  	if (--cnt < 0) {
***************
*** 1318,1327 ****
  void usage()
  {
  #ifdef KERBEROS
!     syslog(LOG_ERR, 
! 	   "usage: klogind [-rRkKxpP] or [r/R][k/K][x/e][p/P]logind");
  #else
!     syslog(LOG_ERR, "usage: rlogind [-rRpP] or [r/R][p/P]logind");
  #endif
  }
  
--- 1378,1387 ----
  void usage()
  {
  #ifdef KERBEROS
!    syslog(LOG_ERR, 
! 	  "usage: klogind [-rRkKxpP] [-D port] or [r/R][k/K][x/e][p/P]logind");
  #else
!     syslog(LOG_ERR, "usage: rlogind [-rRpP] [-D port] or [r/R][p/P]logind");
  #endif
  }
  


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