summaryrefslogtreecommitdiffstats
path: root/src/appl
diff options
context:
space:
mode:
Diffstat (limited to 'src/appl')
-rw-r--r--src/appl/bsd/ChangeLog78
-rw-r--r--src/appl/bsd/Makefile.in4
-rw-r--r--src/appl/bsd/configure.in56
-rw-r--r--src/appl/bsd/forward.c15
-rw-r--r--src/appl/bsd/krcp.c48
-rw-r--r--src/appl/bsd/krlogin.c9
-rw-r--r--src/appl/bsd/krlogind.c37
-rw-r--r--src/appl/bsd/krsh.c5
-rw-r--r--src/appl/bsd/krshd.c16
-rw-r--r--src/appl/bsd/login.c1831
-rw-r--r--src/appl/bsd/loginpaths.h6
-rw-r--r--src/appl/bsd/rlogin.M34
-rw-r--r--src/appl/bsd/rsh.M37
13 files changed, 1547 insertions, 629 deletions
diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog
index 93148ff5b1..21e8a1277c 100644
--- a/src/appl/bsd/ChangeLog
+++ b/src/appl/bsd/ChangeLog
@@ -1,14 +1,81 @@
Mon Apr 29 17:02:44 1996 Ken Raeburn <raeburn@cygnus.com>
+ Merge with Cygnus sources, changes from Mark Eichin, Marc
+ Horowitz, Chris Provenzano and me:
+
* Makefile.in (install): Install correct set of man pages, and
check for failures.
* kshd.M, klogind.M: Renamed from kr*.M versions.
-
- Wed Sep 13 23:19:17 1995 Mark Eichin <eichin@cygnus.com>
-
* login.M: New file. Man page for login with some description of
new features.
+ * rlogin.M: Remove references to using program with target
+ hostname as argv[0].
+ * rsh.M: Ditto. Also document -f, -F, -x options.
+
+ * login.c: Massive changes. Split much functionality out of main
+ and into separate file sections: terminal flag settings, Kerberos
+ 4 and 5 support, UNIX password support, mail check, signal handler
+ handling, some other support routines. Revamp controlling tty and
+ process group handling. For AFS configuration, use setpag and run
+ aklog. Try validating password using krb5. Always set tty flags,
+ not just for rlogin session. When validating tickets, treat an
+ existing key file that doesn't contain the key we think we want
+ (possibly because DNS was spoofed) as an error condition.
+ * Makefile.in (LOGINLIBS): List libkrb524.a here.
+ (LIBOBJS): Not here.
+ (login.krb5): Reverse the order of LIBOBJS and LOGINLIBS.
+ * configure.in: Check for --with-afs. Add AFS libs and define
+ SETPAG if supplied.
+
+ * login.c (KRB5_GET_TICKETS, KRB4_GET_TICKETS, KRB_RUN_AKLOG): new
+ macros selecting single signon options. krb5.conf profile support
+ for control over authentication options, above the compile time
+ selection.
+ (conf_affirmative): new function, recognize yes/no in profile
+ value.
+ (login_get_kconf): new function, look for all [login] flags and
+ set them in appropriate globals (via login_conf_set array.)
+ (main, sleepexit, destroy_tickets): Check the new login_* flags.
+ (main): rename KRB4_USE_524 to KRB4_CONVERT.
+
+ * configure.in: Added checks for tcsetpgrp, tcgetpgrp, setpgid.
+ * krlogind.c (control): Use tcgetpgrp if it's available.
+
+ * loginpaths.h (RPATH, LPATH, LPATH_root): Define HP/UX 9.04
+ versions, conditionalized on __hpux and !hpux.
+
+ * login.c and configure.in: instead of checking _IBMR2 and
+ __sgi__, write configure tests to check for the existence of
+ /etc/environment and /etc/TIMEZONE files, respectively.
+
+ * forward.c (rd_and_store_for_creds) : If chown fails then only
+ pass failure back if owner is different than intended owner. This
+ is to make rsh.exp test work without requiring root privlidges.
+
+ * login.c (main): Don't set TERM to an empty value.
+ (stypeof) [__hpux]: Return null if unknown.
+
+ * krlogin.c (catchild): remove hp/ux kludge because of aclocal.m4 fix.
+ (speeds): test __hpux for hpux speed list.
+ (main): test __hpux for use of FIOSSAIOSTAT and FIOSSAIOOWN
+ (USE_TERMIO): test __hpux for bsdtty/ptyio headers.
+ * krlogind.c: test __hpux for bsdtty/ptyio headers.
+ (doit): test __hpux for use of setpgrp2.
+ * krcp.c (main): test __hpux as well for remsh vs. rsh.
+
+ * krcp.c (des_write): Make sure the buffer for the encrypted data
+ is large enough. Only return an error in malloc fails.
+
+ * krsh.c (main): Always turn on anyport -A option.
+
+ * krlogind.c (ptsname): Declare if it's going to be used.
+
+ * krshd.c (main): Use basename of argv[0] for progname.
+
+ * login.c (dofork): On linux, TIOCNOTTY causes us to die on a
+ SIGHUP, so don't even try it.
+
Sun Apr 21 12:52:35 1996 Richard Basch <basch@lehman.com>
* krshd.c: If checksumming is required & ALWAYS_V5_KUSEROK is
@@ -294,13 +361,14 @@ Fri Jan 19 10:45:29 1996 Sam Hartman <hartmans@tertius.mit.edu>
(recvauth): Fix accidental memory leak with authenticator and fix
include correct username in checksum
- * kcmd.c: Send authenticator with checksum of command line and remote user.
+ * kcmd.c: Send authenticator with checksum of command line and
+ remote user.
* krlogin.c (des_read): Return 0 or -1 on close/error respectively.
Wed Jan 17 15:14:33 1996 Sam Hartman <hartmans@tertius.mit.edu>
- * krlogin.c ((reader): Use select to find out-of-band data, not signals.
+ * krlogin.c (reader): Use select to find out-of-band data, not signals.
(oob): No longer a signal handler; just a function.
(writer): get rid of copytochild setup as sigurg no longer needed
(main): Don't block SIGURG
diff --git a/src/appl/bsd/Makefile.in b/src/appl/bsd/Makefile.in
index de249d94ef..013f0d487e 100644
--- a/src/appl/bsd/Makefile.in
+++ b/src/appl/bsd/Makefile.in
@@ -3,7 +3,7 @@ LOCALINCLUDE=-I$(SRCTOP)/include/kerberosIV
SETENVSRC=@SETENVSRC@
SETENVOBJ=@SETENVOBJ@
-LOGINLIBS = @LOGINLIBS@
+LOGINLIBS = ../../krb524/libkrb524.a @LOGINLIBS@
LIBOBJS=@LIBOBJS@
LOCAL_LIBRARIES=-lpty
@@ -71,7 +71,7 @@ install::
# referenced by klogind.
#
login.krb5: login.o $(SETENVOBJ) $(LIBOBJS) $(DEPLIBS)
- $(LD) $(LDFLAGS) $(LDARGS) -o login.krb5 login.o $(SETENVOBJ) $(LIBOBJS) $(LIBS) $(LOGINLIBS)
+ $(LD) $(LDFLAGS) $(LDARGS) -o login.krb5 login.o $(SETENVOBJ) $(LIBOBJS) $(LOGINLIBS) $(LIBS)
install::
$(INSTALL_PROGRAM) login.krb5 $(DESTDIR)$(SERVER_BINDIR)/login.krb5
diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in
index 1792fa404e..cb7ae23f57 100644
--- a/src/appl/bsd/configure.in
+++ b/src/appl/bsd/configure.in
@@ -1,5 +1,14 @@
AC_INIT(krlogind.c)
CONFIG_RULES
+LOGINLIBS=
+AC_ARG_WITH([afs],
+[ --without-afs don't have afs libraries to build against (default)
+ --with-afs=AFSDIR use preinstalled AFS library tree],
+,with_afs=no)dnl
+if test $with_afs != no; then
+ AC_DEFINE(SETPAG)
+ LOGINLIBS="$LOGINLIBS -L$with_afs/lib -L$with_afs/lib/afs -lauth -lsys -lrx -llwp"
+fi
AC_PROG_INSTALL
dnl dbm libs for use of an_to_ln
AC_CHECK_LIB(util,main)
@@ -7,11 +16,10 @@ USE_ANAME
AC_CHECK_LIB(crypt,crypt)
dnl
dnl AIX has them all; SCO might too
-LOGINLIBS=
AC_CHECK_LIB(odm,main,
AC_CHECK_LIB(s,main,
AC_CHECK_LIB(cfg,main,
- LOGINLIBS="-lodm -ls -lcfg"
+ LOGINLIBS="$LOGINLIBS -lodm -ls -lcfg"
)))
dnl
dnl Make our operating system-specific security checks and definitions for
@@ -53,6 +61,9 @@ AC_FUNC_CHECK(grantpt,AC_DEFINE(HAVE_GRANTPT))
AC_FUNC_CHECK(openpty,AC_DEFINE(HAVE_OPENPTY))
AC_FUNC_CHECK(setlogin,AC_DEFINE(HAVE_SETLOGIN))
AC_FUNC_CHECK(logwtmp,AC_DEFINE(HAVE_LOGWTMP))
+AC_FUNC_CHECK(tcgetpgrp,AC_DEFINE(HAVE_TCGETPGRP))
+AC_FUNC_CHECK(tcsetpgrp,AC_DEFINE(HAVE_TCSETPGRP))
+AC_FUNC_CHECK(setpgid,AC_DEFINE(HAVE_SETPGID))
AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h )
AC_CHECK_HEADERS(sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h )
AC_CHECK_HEADERS(sys/ptyvar.h utmp.h utmpx.h sys/time.h)
@@ -161,6 +172,47 @@ if test $krb5_cv_shadow_pwd = yes; then
AC_DEFINE(HAVE_SHADOW)
fi
dnl
+dnl
+AC_MSG_CHECKING([/etc/environment])
+AC_CACHE_VAL(krb5_cv_etc_environment,
+[AC_C_CROSS
+if test $ac_cv_c_cross = yes; then
+errprint(__file__:__line__: warning: Cannot check for file existence when cross compiling
+)dnl
+AC_MSG_ERROR(Cannot check for file existence when cross compiling)
+else
+if test -r /etc/environment; then
+krb5_cv_etc_environment=yes
+else
+krb5_cv_etc_environment=no
+fi
+fi])
+AC_MSG_RESULT($krb5_cv_etc_environment)
+if test $krb5_cv_etc_environment = yes; then
+AC_DEFINE(HAVE_ETC_ENVIRONMENT)
+fi
+dnl
+dnl
+AC_MSG_CHECKING([/etc/TIMEZONE])
+AC_CACHE_VAL(krb5_cv_etc_timezone,
+[AC_C_CROSS
+if test $ac_cv_c_cross = yes; then
+errprint(__file__:__line__: warning: Cannot check for file existence when cross compiling
+)dnl
+AC_MSG_ERROR(Cannot check for file existence when cross compiling)
+else
+if test -r /etc/TIMEZONE; then
+krb5_cv_etc_timezone=yes
+else
+krb5_cv_etc_timezone=no
+fi
+fi])
+AC_MSG_RESULT($krb5_cv_etc_timezone)
+if test $krb5_cv_etc_timezone = yes; then
+AC_DEFINE(HAVE_ETC_TIMEZONE)
+fi
+dnl
+dnl
KRB5_CHECK_PROTOS
dnl
ADD_DEF(-DKERBEROS)
diff --git a/src/appl/bsd/forward.c b/src/appl/bsd/forward.c
index 8c74eb2e47..54594b9b97 100644
--- a/src/appl/bsd/forward.c
+++ b/src/appl/bsd/forward.c
@@ -23,6 +23,8 @@
#include <stdio.h>
#include <pwd.h>
#include <netdb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "k5-int.h"
@@ -65,7 +67,18 @@ rd_and_store_for_creds(context, auth_context, inbuf, ticket, lusername, ccache)
if (retval = krb5_cc_store_cred(context, *ccache, *creds))
goto cleanup;
- retval = chown(ccname+5, pwd->pw_uid, -1);
+ if (retval = chown(ccname+5, pwd->pw_uid, -1)) {
+ /*
+ * If the file owner is the same as the user id then return ok.
+ * This is for testing only --proven
+ */
+ struct stat statbuf;
+
+ if (stat(ccname + 5, & statbuf) == 0) {
+ if (statbuf.st_uid == pwd->pw_uid)
+ retval = 0;
+ }
+ }
cleanup:
krb5_free_creds(context, *creds);
diff --git a/src/appl/bsd/krcp.c b/src/appl/bsd/krcp.c
index 32a6eb1a86..36ad114ceb 100644
--- a/src/appl/bsd/krcp.c
+++ b/src/appl/bsd/krcp.c
@@ -381,7 +381,7 @@ int main(argc, argv)
suser = pwd->pw_name;
else if (!okname(suser))
continue;
-#ifdef hpux
+#if defined(hpux) || defined(__hpux)
(void) sprintf(buf, "remsh %s -l %s -n %s %s '%s%s%s:%s'",
#else
(void) sprintf(buf, "rsh %s -l %s -n %s %s '%s%s%s:%s'",
@@ -391,7 +391,7 @@ int main(argc, argv)
tuser ? "@" : "",
thost, targ);
} else
-#ifdef hpux
+#if defined(hpux) || defined(__hpux)
(void) sprintf(buf, "remsh %s -n %s %s '%s%s%s:%s'",
#else
(void) sprintf(buf, "rsh %s -n %s %s '%s%s%s:%s'",
@@ -1125,7 +1125,7 @@ struct buffer *allocbuf(bp, fd, blksize)
size = roundup(stb.st_blksize, blksize);
#endif
- size = blksize;
+ size = blksize;
if (bp->cnt < size) {
if (bp->buf != 0)
free(bp->buf);
@@ -1413,33 +1413,41 @@ int des_read(fd, buf, len)
}
-
int des_write(fd, buf, len)
int fd;
char *buf;
int len;
{
+ static krb5_data des_write_buf;
+ static int des_write_maxsize;
unsigned char len_buf[4];
-/* Note that rcp depends on the same
- * file descriptor being both input and output to the remote
- * side. This is bogus, especially when rcp
- * is being run by a rsh that pipes. Fix it here because
- * it would require significantly more work in other places. --hartmans 1/96*/
+
+ /*
+ * Note that rcp depends on the same file descriptor being both
+ * input and output to the remote side. This is bogus, especially
+ * when rcp is being run by a rsh that pipes. Fix it here because it
+ * would require significantly more work in other places. --hartmans 1/96
+ */
if (fd == 0)
fd = 1;
if (!encryptflag)
return(krb5_net_write(bsd_context, fd, buf, len));
- desoutbuf.length = krb5_encrypt_size(len,eblock.crypto_entry);
- if (desoutbuf.length > (int) sizeof(des_outbuf)){
- return(-1);
+ des_write_buf.length = krb5_encrypt_size(len,eblock.crypto_entry);
+
+ if (des_write_buf.length > des_write_maxsize) {
+ if (des_write_buf.data)
+ free(des_write_buf.data);
+ des_write_maxsize = des_write_buf.length;
+ if ((des_write_buf.data = malloc(des_write_maxsize)) == NULL) {
+ des_write_maxsize = 0;
+ return(-1);
+ }
}
- if (( krb5_encrypt(bsd_context, (krb5_pointer)buf,
- desoutbuf.data,
- len,
- &eblock,
- 0))){
+
+ if ((krb5_encrypt(bsd_context, (krb5_pointer)buf, des_write_buf.data,
+ len, &eblock, 0))) {
return(-1);
}
@@ -1447,11 +1455,11 @@ int des_write(fd, buf, len)
len_buf[1] = (len & 0xff0000) >> 16;
len_buf[2] = (len & 0xff00) >> 8;
len_buf[3] = (len & 0xff);
- (void) write(fd, len_buf, 4);
- if (write(fd, desoutbuf.data,desoutbuf.length) != desoutbuf.length){
+ if ((write(fd, len_buf, 4) != 4) || (write(fd, des_write_buf.data,
+ des_write_buf.length) != des_write_buf.length)) {
return(-1);
}
- else return(len);
+ return(len);
}
#endif /* KERBEROS */
diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c
index e8b205da88..831806c626 100644
--- a/src/appl/bsd/krlogin.c
+++ b/src/appl/bsd/krlogin.c
@@ -192,7 +192,7 @@ int flowcontrol; /* Since emacs can alter the
the original characteristics */
int confirm = 0; /* ask if ~. is given before dying. */
int litout;
-#ifdef hpux
+#if defined(hpux) || defined(__hpux)
char *speeds[] =
{ "0", "50", "75", "110", "134", "150", "200", "300", "600",
"900", "1200", "1800", "2400", "3600", "4800", "7200", "9600",
@@ -674,7 +674,7 @@ char deferase, defkill;
#ifdef USE_TERMIO
char defvtim, defvmin;
-#ifdef hpux
+#if defined(hpux) || defined(__hpux)
#include <sys/bsdtty.h>
#include <sys/ptyio.h>
#endif
@@ -952,12 +952,7 @@ int signo;
if (pid < 0 || (pid == child && !WIFSTOPPED(status)))
done(status);
#else
-#if defined(hpux)
- /* I think this one is wrong: XXX -- [eichin:19940727.1853EST] */
- if ((pid < 0) || ((pid == child) && (!WIFSTOPPED(status.w_stopval))))
-#else
if ((pid < 0) || ((pid == child) && (!WIFSTOPPED(status))))
-#endif
done((int)(status.w_termsig | status.w_retcode));
#endif
goto again;
diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c
index 26fb2cd216..0a44c8debf 100644
--- a/src/appl/bsd/krlogind.c
+++ b/src/appl/bsd/krlogind.c
@@ -129,7 +129,7 @@ char copyright[] =
#include <signal.h>
-#ifdef hpux
+#if defined(hpux) || defined(__hpux)
#include <sys/ptyio.h>
#endif
#ifdef sysvimp
@@ -181,11 +181,15 @@ char copyright[] =
#include <sys/filio.h>
#endif
-
#ifndef HAVE_KILLPG
#define killpg(pid, sig) kill(-(pid), (sig))
#endif
+#ifdef HAVE_PTSNAME
+/* HP/UX 9.04 has but does not declare ptsname. */
+extern char *ptsname ();
+#endif
+
#ifdef NO_WINSIZE
struct winsize {
unsigned short ws_row, ws_col;
@@ -325,7 +329,7 @@ int main(argc, argv)
progname = *argv;
-pty_init();
+ pty_init();
#ifndef LOG_NDELAY
#define LOG_NDELAY 0
@@ -342,7 +346,6 @@ pty_init();
openlog(progname, LOG_PID | LOG_NDELAY, LOG_AUTH);
#endif /* 4.2 syslog */
-
/* Analyse parameters. */
opterr = 0;
while ((ch = getopt(argc, argv, ARGSTR)) != EOF)
@@ -619,7 +622,7 @@ int syncpipe[2];
new_termio.c_lflag |= (ICANON|ECHO|ISIG|IEXTEN);
new_termio.c_iflag|= (IXON|IXANY|BRKINT|INLCR|ICRNL);
#endif /*Do we need binary stream?*/
-new_termio.c_iflag &= ~(ISTRIP);
+ new_termio.c_iflag &= ~(ISTRIP);
/* new_termio.c_iflag = 0; */
/* new_termio.c_oflag = 0; */
new_termio.c_cc[VMIN] = 1;
@@ -821,7 +824,7 @@ int control(pty, cp, n)
int n;
{
struct winsize w;
- int pgrp;
+ int pgrp, got_pgrp;
if (n < (int) 4+sizeof (w) || cp[2] != 's' || cp[3] != 's')
return (0);
@@ -833,7 +836,13 @@ int control(pty, cp, n)
w.ws_xpixel = ntohs(w.ws_xpixel);
w.ws_ypixel = ntohs(w.ws_ypixel);
(void)ioctl(pty, TIOCSWINSZ, &w);
- if (ioctl(pty, TIOCGPGRP, &pgrp) >= 0)
+#ifdef HAVE_TCGETPGRP
+ pgrp = tcgetpgrp (pty);
+ got_pgrp = pgrp != -1;
+#else
+ got_pgrp = ioctl(pty, TIOCGPGRP, &pgrp) >= 0;
+#endif
+ if (got_pgrp)
(void) killpg(pgrp, SIGWINCH);
#endif
return (4+sizeof (w));
@@ -855,14 +864,14 @@ void protocol(f, p)
struct sigaction sa;
#endif
#ifdef TIOCPKT
- register tiocpkt_on = 0;
- int on = 1;
+ register tiocpkt_on = 0;
+ int on = 1;
#endif
#if defined(TIOCPKT) && !defined(__svr4__) || defined(solaris20)
- /* if system has TIOCPKT, try to turn it on. Some drivers
+ /* if system has TIOCPKT, try to turn it on. Some drivers
* may not support it. Save flag for later.
- */
+ */
if ( ioctl(p, TIOCPKT, &on) < 0)
tiocpkt_on = 0;
else tiocpkt_on = 1;
@@ -964,7 +973,7 @@ void protocol(f, p)
else if (pcc <= 0)
break;
#ifdef TIOCPKT
- else if (tiocpkt_on) {
+ else if (tiocpkt_on) {
if (pibuf[0] == 0)
pbp++, pcc--;
else {
@@ -974,7 +983,7 @@ void protocol(f, p)
}
pcc = 0;
}
- }
+ }
#endif
}
if (FD_ISSET(f, &obits) && pcc > 0) {
@@ -1444,7 +1453,7 @@ recvauth(valid_checksum)
&auth_sys, /* which authentication system*/
&v4_kdata, v4_schedule, v4_version))) {
- if (auth_sys == KRB5_RECVAUTH_V5) {
+ if (auth_sys == KRB5_RECVAUTH_V5) {
/*
* clean up before exiting
*/
diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c
index 88c630e232..0a59cb3ddc 100644
--- a/src/appl/bsd/krsh.c
+++ b/src/appl/bsd/krsh.c
@@ -142,7 +142,7 @@ main(argc, argv0)
#ifdef KERBEROS
krb5_flags authopts;
krb5_error_code status;
- int fflag = 0, Fflag = 0, Aflag = 0;
+ int fflag = 0, Fflag = 0;
#endif /* KERBEROS */
int debug_port = 0;
@@ -226,7 +226,6 @@ main(argc, argv0)
goto another;
}
if (argc > 0 && !strncmp(*argv, "-A", 2)) {
- Aflag++;
argv++, argc--;
goto another;
}
@@ -355,7 +354,7 @@ main(argc, argv0)
(struct sockaddr_in *) 0,
(struct sockaddr_in *) 0,
authopts,
- Aflag); /* Any port #? */
+ 1); /* Always set anyport, there is no need not to. --proven */
if (status) {
/* check NO_TKT_FILE or equivalent... */
fprintf(stderr,
diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c
index b3e2656924..64b1b2974e 100644
--- a/src/appl/bsd/krshd.c
+++ b/src/appl/bsd/krshd.c
@@ -263,7 +263,8 @@ int main(argc, argv)
secflag = sysconf(_SC_CRAY_SECURE_SYS);
#endif
- progname = *argv;
+ progname = strrchr (*argv, '/');
+ progname = progname ? progname + 1 : *argv;
#ifndef LOG_ODELAY /* 4.2 syslog */
openlog(progname, LOG_PID);
@@ -415,8 +416,7 @@ int main(argc, argv)
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
sizeof (on)) < 0)
- syslog(LOG_WARNING,
- "setsockopt (SO_KEEPALIVE): %m");
+ syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
#if defined(BSD) && BSD+0 >= 43
linger.l_onoff = 1;
linger.l_linger = 60; /* XXX */
@@ -1288,12 +1288,12 @@ if(port)
int i;
char *buf = (char *)malloc(strlen(getenv("KRB5CCNAME"))
+strlen("KRB5CCNAME=")+1);
- if (buf) {
- sprintf(buf, "KRB5CCNAME=%s",getenv("KRB5CCNAME"));
+ if (buf) {
+ sprintf(buf, "KRB5CCNAME=%s",getenv("KRB5CCNAME"));
- for (i = 0; envinit[i]; i++);
- envinit[i] =buf;
- }
+ for (i = 0; envinit[i]; i++);
+ envinit[i] =buf;
+ }
}
/* If we do anything else, make sure there is space in the array. */
diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c
index d1e98e23ac..778d73d4e1 100644
--- a/src/appl/bsd/login.c
+++ b/src/appl/bsd/login.c
@@ -27,19 +27,51 @@ char copyright[] =
/* based on @(#)login.c 5.25 (Berkeley) 1/6/89 */
+/* While the code may be compiled with some of these options turned off,
+ the default will be to turn them *all* on if v4 compatibility is
+ available, and allow them to be configured via krb5.conf. */
+/* The configuration is of the form
+ [login]
+ # login stanza
+ krb5_get_tickets = 1
+ # use password to get v5 tickets
+ krb4_get_tickets = 1
+ # use password to get v4 tickets
+ krb4_convert = 1
+ # use kerberos conversion daemon to get v4 tickets
+ krb_run_aklog = 1
+ # attempt to run aklog
+ aklog_path = $(prefix)/bin/aklog
+ # where to find it [not yet implemented]
+ accept_passwd = 0
+ # don't accept plaintext passwords [not yet implemented]
+*/
+#define KRB5_GET_TICKETS
+int login_krb5_get_tickets = 1;
+#ifdef KRB5_KRB4_COMPAT
+#define KRB4_GET_TICKETS
+int login_krb4_get_tickets = 1;
+#define KRB4_CONVERT
+int login_krb4_convert = 1;
+#define KRB_RUN_AKLOG
+int login_krb_run_aklog = 1;
+#endif /* KRB5_KRB4_COMPAT */
+int login_accept_passwd = 0;
+
/*
* login [ name ]
* login -r hostname (for rlogind)
* login -h hostname (for telnetd, etc.)
- * login -f name (for pre-authenticated login: datakit, xterm, etc.)
+ * login -f name (for pre-authenticated login: datakit, xterm, etc.,
+ * does not allow preauthenticated login as root)
* login -F name (for pre-authenticated login: datakit, xterm, etc.,
* allows preauthenticated login as root)
* login -e name (for pre-authenticated encrypted, must do term
* negotiation)
- * ifdef KRB4
+ * ifdef KRB4_KLOGIN
* login -k hostname (for Kerberos V4 rlogind with password access)
* login -K hostname (for Kerberos V4 rlogind with restricted access)
- * endif KRB4
+ * endif KRB4_KLOGIN
*
* only one of: -r -f -e -k -K -F
* only one of: -r -h -k -K
@@ -68,6 +100,8 @@ char copyright[] =
#include <utmp.h>
#include <signal.h>
+#include <assert.h>
+
#ifdef HAVE_LASTLOG_H
#include <lastlog.h>
#endif
@@ -87,13 +121,54 @@ char copyright[] =
#include <stdio.h>
#include <grp.h>
#include <pwd.h>
-#include <setjmp.h>
#include <string.h>
+#include <setjmp.h>
+#ifndef POSIX_SETJMP
+#undef sigjmp_buf
+#undef sigsetjmp
+#undef siglongjmp
+#define sigjmp_buf jmp_buf
+#define sigsetjmp(j,s) setjmp(j)
+#define siglongjmp longjmp
+#endif
+
+#ifdef POSIX_SIGNALS
+typedef struct sigaction handler;
+#define handler_init(H,F) (sigemptyset(&(H).sa_mask), \
+ (H).sa_flags=0, \
+ (H).sa_handler=(F))
+#define handler_swap(S,NEW,OLD) sigaction(S, &NEW, &OLD)
+#define handler_set(S,OLD) sigaction(S, &OLD, NULL)
+#else
+typedef sigtype (*handler)();
+#define handler_init(H,F) ((H) = (F))
+#define handler_swap(S,NEW,OLD) ((OLD) = signal ((S), (NEW)))
+#define handler_set(S,OLD) (signal ((S), (OLD)))
+#endif
+
+
#ifdef HAVE_SHADOW
#include <shadow.h>
#endif
+#ifdef KRB5_GET_TICKETS
+/* #include "krb5.h" */
+/* need k5-int.h to get ->profile from krb5_context */
+#include "k5-int.h"
+#include "osconf.h"
+#endif /* KRB5_GET_TICKETS */
+
+#ifdef KRB4_KLOGIN
+/* support for running under v4 klogind, -k -K flags */
+#define KRB4
+#endif
+
+#ifdef KRB4_GET_TICKETS
+/* support for prompting for v4 initial tickets */
+#define KRB4
+#endif
+
#ifdef KRB4
#include <krb.h>
#include <netdb.h>
@@ -106,6 +181,12 @@ char copyright[] =
#endif /* BIND_HACK */
#endif /* KRB4 */
+#ifndef __STDC__
+#ifndef volatile
+#define volatile
+#endif
+#endif
+
#include "loginpaths.h"
#ifdef POSIX_TERMIOS
@@ -144,15 +225,6 @@ char copyright[] =
#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"
-
#ifndef NO_UT_HOST
#ifndef UT_HOSTSIZE
/* linux defines it directly in <utmp.h> */
@@ -164,6 +236,11 @@ char copyright[] =
#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
#endif
+#ifndef HAVE_SETPRIORITY
+/* if we don't have it, punt it cleanly */
+#define setpriority(which,who,prio)
+#endif /* HAVE_SETPRIORITY */
+
#define MAXENVIRON 32
/*
@@ -172,44 +249,23 @@ char copyright[] =
*/
int timeout = 300;
-struct passwd *pwd;
-#ifdef HAVE_SHADOW
-struct spwd *spwd;
-#endif
-
char term[64], *hostname, *username;
-#ifndef POSIX_TERMIOS
-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 KRB4
+#ifdef KRB4_GET_TICKETS
#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;
-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 /* SETPAG */
-#endif /* KRB4 */
+#endif /* KRB4_GET_TICKETS */
char *getenv();
void dofork();
int doremotelogin(), do_krb_login(), rootterm();
-void lgetstr(), doremoteterm(), getloginname(), checknologin(), sleepexit();
-void dolastlog(), motd();
+void lgetstr(), getloginname(), checknologin(), sleepexit();
+void dolastlog(), motd(), check_mail();
#ifndef HAVE_STRSAVE
char * strsave();
@@ -218,6 +274,783 @@ char * strsave();
typedef krb5_sigtype sigtype;
+#ifndef HAVE_INITGROUPS
+static int initgroups(char* name, gid_t basegid) {
+ gid_t others[NGROUPS_MAX+1];
+ int ngrps;
+
+ others[0] = basegid;
+ ngrps = getgroups(NGROUPS_MAX, others+1);
+ return setgroups(ngrps+1, others);
+}
+#endif
+
+#ifdef KRB5_GET_TICKETS
+static struct login_confs {
+ char *flagname;
+ int *flag;
+} login_conf_set[] = {
+ "krb5_get_tickets", &login_krb5_get_tickets,
+#ifdef KRB5_KRB4_COMPAT
+ "krb4_get_tickets", &login_krb4_get_tickets,
+ "krb4_convert", &login_krb4_convert,
+ "krb4_run_aklog", &login_krb_run_aklog,
+#endif /* KRB5_KRB4_COMPAT */
+};
+static char *conf_yes[] = {
+ "y", "yes", "true", "t", "1", "on",
+ 0
+};
+static char *conf_no[] = {
+ "n", "no", "false", "nil", "0", "off",
+ 0
+};
+/* 1 = true, 0 = false, -1 = ambiguous */
+static int conf_affirmative(s)
+ char *s;
+{
+ char **p;
+ for(p=conf_yes; *p; p++) {
+ if (!strcasecmp(*p,s))
+ return 1;
+ }
+ for(p=conf_no; *p; p++) {
+ if (!strcasecmp(*p,s))
+ return 0;
+ }
+ /* ambiguous */
+ return -1;
+}
+#endif /* KRB5_GET_TICKETS */
+
+#ifdef KRB5_GET_TICKETS
+krb5_data tgtname = {
+ 0,
+ KRB5_TGS_NAME_SIZE,
+ KRB5_TGS_NAME
+};
+#endif
+
+#ifdef KRB5_GET_TICKETS
+/* get flags (listed above) from the profile */
+void login_get_kconf(k)
+ krb5_context k;
+{
+ int i, max_i;
+ const char* kconf_names[3];
+ char **kconf_val;
+ int retval;
+
+ max_i = sizeof(login_conf_set)/sizeof(struct login_confs);
+ for (i = 0; i<max_i; i++) {
+ kconf_names[0] = "login";
+ kconf_names[1] = login_conf_set[i].flagname;
+ kconf_names[2] = 0;
+ retval = profile_get_values(k->profile,
+ kconf_names, &kconf_val);
+ if (retval) {
+ /* ignore most (all?) errors */
+ } else if (kconf_val) {
+ switch(conf_affirmative(*kconf_val)) {
+ case 1:
+ *login_conf_set[i].flag = 1;
+ break;
+ case 0:
+ *login_conf_set[i].flag = 0;
+ break;
+ default:
+ case -1:
+ com_err("login/kconf", 0,
+ "invalid flag value %s for flag %s",
+ *kconf_val, kconf_names[1]);
+ break;
+ }
+ }
+ }
+}
+#endif /* KRB5_GET_TICKETS */
+
+
+/* UNIX password support */
+
+struct passwd *pwd;
+static char *salt;
+
+#ifdef HAVE_SHADOW
+struct spwd *spwd;
+#endif
+
+void lookup_user (name)
+ char *name;
+{
+ pwd = getpwnam (name);
+ salt = pwd ? pwd->pw_passwd : "xx";
+#ifdef HAVE_SHADOW
+ spwd = getspnam (name);
+ if (spwd)
+ salt = spwd->sp_pwdp;
+#endif
+}
+
+int unix_needs_passwd ()
+{
+#ifdef HAVE_SHADOW
+ if (spwd)
+ return spwd->sp_pwdp[0] != 0;
+#endif
+ if (pwd)
+ return pwd->pw_passwd[0] != 0;
+ return 1;
+}
+
+int unix_passwd_okay (pass)
+ char *pass;
+{
+ char user_pwcopy[9], *namep;
+ char *crypt ();
+
+ assert (pwd != 0);
+
+ /* copy the first 8 chars of the password for unix crypt */
+ strncpy(user_pwcopy, pass, sizeof(user_pwcopy));
+ user_pwcopy[8]='\0';
+ namep = crypt(user_pwcopy, salt);
+ memset (user_pwcopy, 0, sizeof(user_pwcopy));
+ /* ... and wipe the copy now that we have the string */
+
+ /* verify the local password string */
+#ifdef HAVE_SHADOW
+ if (spwd)
+ return !strcmp(namep, spwd->sp_pwdp);
+#endif
+ return !strcmp (namep, pwd->pw_passwd);
+}
+
+/* Kerberos support */
+#ifdef KRB5_GET_TICKETS
+krb5_context kcontext;
+krb5_ccache ccache;
+static int got_v5_tickets, got_v4_tickets;
+char ccfile[MAXPATHLEN+6]; /* FILE:path+\0 */
+int krbflag; /* set if tickets have been obtained */
+
+#ifdef KRB4_GET_TICKETS
+AUTH_DAT *kdata = (AUTH_DAT *) NULL;
+KTEXT ticket = (KTEXT) NULL;
+char tkfile[MAXPATHLEN];
+char realm[REALM_SZ];
+#endif
+
+void k_init (ttyn)
+ char *ttyn;
+{
+ krb5_init_context(&kcontext);
+ krb5_init_ets(kcontext);
+ login_get_kconf(kcontext);
+
+ /* Set up the credential cache environment variable */
+ if (!getenv(KRB5_ENV_CCNAME)) {
+ sprintf(ccfile, "FILE:/tmp/krb5cc_%s", strrchr(ttyn, '/')+1);
+ setenv(KRB5_ENV_CCNAME, ccfile, 1);
+ unlink(ccfile+strlen("FILE:"));
+ } else {
+ /* note it correctly */
+ strcpy(ccfile, getenv(KRB5_ENV_CCNAME));
+ }
+
+#ifdef KRB4_GET_TICKETS
+ if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+ strncpy(realm, KRB_REALM, sizeof(realm));
+ }
+ if (login_krb4_get_tickets) {
+ /* Set up the ticket file environment variable */
+ strncpy(tkfile, KRB_TK_DIR, sizeof(tkfile));
+ strncat(tkfile, strrchr(ttyn, '/')+1,
+ sizeof(tkfile) - strlen(tkfile));
+ (void) unlink (tkfile);
+ setenv(KRB_ENVIRON, tkfile, 1);
+ }
+#endif
+
+#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 /* BIND_HACK */
+}
+
+int k5_get_password (user_pwstring, pwsize)
+ char *user_pwstring;
+{
+ krb5_error_code code;
+ char prompt[255];
+ sprintf(prompt,"Password for %s: ", username);
+
+ /* reduce opportunities to be swapped out */
+ code = krb5_read_password(kcontext, prompt, 0, user_pwstring, &pwsize);
+ if (code || pwsize == 0) {
+ fprintf(stderr, "Error while reading password for '%s'\n", username);
+ /* reading password failed... */
+ return 0;
+ }
+ if (pwsize == 0) {
+ fprintf(stderr, "No password read\n");
+ /* reading password failed... */
+ return 0;
+ }
+ return 1;
+}
+
+#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
+int krb5_options = 0;
+krb5_deltat krb5_ticket_lifetime = KRB5_DEFAULT_LIFE;
+
+int try_krb5 (me_p, pass)
+ krb5_principal *me_p;
+ char *pass;
+{
+ krb5_error_code code;
+ krb5_principal server, me;
+ krb5_creds my_creds;
+ krb5_timestamp now;
+ krb5_deltat lifetime = krb5_ticket_lifetime;
+
+ /* set up credential cache -- obeying KRB5_ENV_CCNAME
+ set earlier */
+ /* (KRB5_ENV_CCNAME == "KRB5CCNAME" via osconf.h) */
+ if (code = krb5_cc_default(kcontext, &ccache)) {
+ com_err("login", code, "while getting default ccache");
+ return 0;
+ }
+ /* setup code from v5 kinit */
+ memset((char *)&my_creds, 0, sizeof(my_creds));
+
+ code = krb5_parse_name (kcontext, username, &me);
+ if (code) {
+ com_err ("login", code, "when parsing name %s",username);
+ return 0;
+ }
+ *me_p = my_creds.client = me;
+
+ code = krb5_cc_initialize (kcontext, ccache, me);
+ if (code) {
+ com_err ("login", code,
+ "when initializing cache");
+ return 0;
+ }
+
+ code = krb5_build_principal_ext(kcontext, &server,
+ krb5_princ_realm(kcontext, me)->length,
+ krb5_princ_realm(kcontext, me)->data,
+ tgtname.length, tgtname.data,
+ krb5_princ_realm(kcontext, me)->length,
+ krb5_princ_realm(kcontext, me)->data,
+ 0);
+ if (code) {
+ com_err("login", code,
+ "while building server name");
+ goto nuke_ccache;
+ }
+
+ my_creds.server = server;
+ code = krb5_timeofday(kcontext, &now);
+ if (code) {
+ com_err("login", code,
+ "while getting time of day");
+ goto nuke_ccache;
+ }
+ my_creds.times.starttime = 0; /* start timer when
+ request gets to KDC */
+ my_creds.times.endtime = now + lifetime;
+ my_creds.times.renew_till = 0;
+
+ code = krb5_get_in_tkt_with_password(kcontext, krb5_options,
+ 0, NULL, 0 /*preauth*/,
+ pass,
+ ccache,
+ &my_creds, 0);
+
+ if (code) {
+ if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
+ fprintf (stderr,
+ "%s: Kerberos password incorrect\n",
+ username);
+ else
+ com_err ("login", code,
+ "while getting initial credentials");
+ nuke_ccache:
+ krb5_cc_destroy (kcontext, ccache);
+ return 0;
+ } else {
+ /* get_name pulls out just the name not the
+ type */
+ strcpy(ccfile, krb5_cc_get_name(kcontext, ccache));
+ (void) chown(ccfile, pwd->pw_uid, pwd->pw_gid);
+ krbflag = got_v5_tickets = 1;
+ return 1;
+ }
+}
+
+int have_v5_tickets (me)
+ krb5_principal *me;
+{
+ if (krb5_cc_default (kcontext, &ccache))
+ return 0;
+ if (krb5_cc_get_principal (kcontext, ccache, me)) {
+ krb5_cc_close (kcontext, ccache);
+ return 0;
+ }
+ krbflag = 1;
+ return 1;
+}
+
+#ifdef KRB4_CONVERT
+try_convert524 (kcontext, me)
+ krb5_context kcontext;
+ krb5_principal me;
+{
+ krb5_principal kpcserver;
+ krb5_error_code kpccode;
+ int kpcval;
+ krb5_creds increds, *v5creds;
+ CREDENTIALS v4creds;
+
+ if (!got_v5_tickets)
+ return 0;
+
+ /* or do this directly with krb524_convert_creds_kdc */
+ krb524_init_ets(kcontext);
+ /* cc->ccache, already set up */
+ /* client->me, already set up */
+ if ((kpccode = krb5_build_principal(kcontext,
+ &kpcserver,
+ krb5_princ_realm(kcontext, me)->length,
+ krb5_princ_realm(kcontext, me)->data,
+ "krbtgt",
+ krb5_princ_realm(kcontext, me)->data,
+ NULL))) {
+ com_err("login/v4", kpccode,
+ "while creating service principal name");
+ return 0;
+ }
+
+ memset((char *) &increds, 0, sizeof(increds));
+ increds.client = me;
+ increds.server = kpcserver;
+ increds.times.endtime = 0;
+ increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
+ if ((kpccode = krb5_get_credentials(kcontext, 0,
+ ccache,
+ &increds,
+ &v5creds))) {
+ com_err("login/v4", kpccode,
+ "getting V5 credentials");
+ return 0;
+ }
+ if ((kpccode = krb524_convert_creds_kdc(kcontext,
+ v5creds,
+ &v4creds))) {
+ com_err("login/v4", kpccode,
+ "converting to V4 credentials");
+ return 0;
+ }
+ /* this is stolen from the v4 kinit */
+ /* initialize ticket cache */
+ if ((kpcval = in_tkt(v4creds.pname,v4creds.pinst)
+ != KSUCCESS)) {
+ com_err("login/v4", kpcval,
+ "trying to create the V4 ticket file");
+ return 0;
+ }
+ /* stash ticket, session key, etc. for future use */
+ if ((kpcval = krb_save_credentials(v4creds.service,
+ v4creds.instance,
+ v4creds.realm,
+ v4creds.session,
+ v4creds.lifetime,
+ v4creds.kvno,
+ &(v4creds.ticket_st),
+ v4creds.issue_date))) {
+ com_err("login/v4", kpcval,
+ "trying to save the V4 ticket");
+ return 0;
+ }
+ got_v4_tickets = 1;
+ strcpy(tkfile, tkt_string());
+ (void) chown(tkfile, pwd->pw_uid, pwd->pw_gid);
+ return 1;
+}
+#endif
+
+#ifdef KRB4_GET_TICKETS
+try_krb4 (me, user_pwstring)
+ krb5_principal me;
+ char *user_pwstring;
+{
+ int krbval, kpass_ok = 0;
+
+ krbval = krb_get_pw_in_tkt(username, "", realm,
+ "krbtgt", realm,
+ DEFAULT_TKT_LIFE,
+ user_pwstring);
+
+ switch (krbval) {
+ case INTK_OK:
+ kpass_ok = 1;
+ krbflag = 1;
+ strcpy(tkfile, tkt_string());
+ (void) chown(tkfile, pwd->pw_uid, pwd->pw_gid);
+ 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;
+#if 0 /* I want to see where INTK_W_NOTALL comes from before letting
+ kpass_ok be set in that case. KR */
+ /* These should be printed but are not fatal */
+ case INTK_W_NOTALL:
+ krbflag = 1;
+ kpass_ok = 1;
+ fprintf(stderr, "Kerberos error: %s\n",
+ krb_get_err_text(krbval));
+ break;
+#endif
+ default:
+ fprintf(stderr, "Kerberos error: %s\n",
+ krb_get_err_text(krbval));
+ break;
+ }
+ got_v4_tickets = kpass_ok;
+ return kpass_ok;
+}
+#endif /* KRB4_GET_TICKETS */
+
+/* Kerberos ticket-handling routines */
+
+#ifdef KRB4_GET_TICKETS
+/* call already conditionalized on login_krb4_get_tickets */
+/*
+ * Verify the Kerberos ticket-granting ticket just retrieved for the
+ * user. If the Kerberos server doesn't respond, assume the user is
+ * trying to fake us out (since we DID just get a TGT from what is
+ * supposedly our KDC). If the rcmd.<host> service is unknown (i.e.,
+ * the local srvtab doesn't have it), let her in.
+ *
+ * Returns 1 for confirmation, -1 for failure, 0 for uncertainty.
+ */
+int verify_krb_v4_tgt (realm)
+ char *realm;
+{
+ char hostname[MAXHOSTNAMELEN], phost[BUFSIZ];
+ struct hostent *hp;
+ KTEXT_ST ticket;
+ AUTH_DAT authdata;
+ unsigned long addr;
+ static /*const*/ char rcmd[] = "rcmd";
+ char key[8];
+ int krbval, retval, have_keys;
+
+ if (gethostname(hostname, sizeof(hostname)) == -1) {
+ perror ("cannot retrieve local hostname");
+ return -1;
+ }
+ strncpy (phost, krb_get_phost (hostname), sizeof (phost));
+ phost[sizeof(phost)-1] = 0;
+ hp = gethostbyname (hostname);
+ if (!hp) {
+ perror ("cannot retrieve local host address");
+ return -1;
+ }
+ memcpy ((char *) &addr, (char *)hp->h_addr, sizeof (addr));
+ /* Do we have rcmd.<host> keys? */
+#if 0 /* Be paranoid. If srvtab exists, assume it must contain the
+ right key. */
+ have_keys = read_service_key (rcmd, phost, realm, 0, KEYFILE, key)
+ ? 0 : 1;
+ memset (key, 0, sizeof (key));
+#else
+ have_keys = 0 == access (KEYFILE, F_OK);
+#endif
+ krbval = krb_mk_req (&ticket, rcmd, phost, realm, 0);
+ if (krbval == KDC_PR_UNKNOWN) {
+ /*
+ * Our rcmd.<host> principal isn't known -- just assume valid
+ * for now? This is one case that the user _could_ fake out.
+ */
+ if (have_keys)
+ return -1;
+ else
+ return 0;
+ }
+ else if (krbval != KSUCCESS) {
+ printf ("Unable to verify Kerberos TGT: %s\n",
+ krb_get_err_text(krbval));
+#ifndef SYSLOG42
+ syslog (LOG_NOTICE|LOG_AUTH, "Kerberos TGT bad: %s",
+ krb_get_err_text(krbval));
+#endif
+ return -1;
+ }
+ /* got ticket, try to use it */
+ krbval = krb_rd_req (&ticket, rcmd, phost, addr, &authdata, "");
+ if (krbval != KSUCCESS) {
+ if (krbval == RD_AP_UNDEC && !have_keys)
+ retval = 0;
+ else {
+ retval = -1;
+ printf ("Unable to verify `rcmd' ticket: %s\n",
+ krb_get_err_text(krbval));
+ }
+#ifndef SYSLOG42
+ syslog (LOG_NOTICE|LOG_AUTH, "can't verify rcmd ticket: %s;%s\n",
+ krb_get_err_text(krbval),
+ retval
+ ? "srvtab found, assuming failure"
+ : "no srvtab found, assuming success");
+#endif
+ goto EGRESS;
+ }
+ /*
+ * The rcmd.<host> ticket has been received _and_ verified.
+ */
+ retval = 1;
+ /* do cleanup and return */
+EGRESS:
+ memset (&ticket, 0, sizeof (ticket));
+ memset (&authdata, 0, sizeof (authdata));
+ return retval;
+}
+#endif /* KRB4_GET_TICKETS */
+
+/* call already conditionalized on login_krb5_get_tickets */
+/*
+ * Verify the Kerberos ticket-granting ticket just retrieved for the
+ * user. If the Kerberos server doesn't respond, assume the user is
+ * trying to fake us out (since we DID just get a TGT from what is
+ * supposedly our KDC). If the host/<host> service is unknown (i.e.,
+ * the local keytab doesn't have it), let her in.
+ *
+ * Returns 1 for confirmation, -1 for failure, 0 for uncertainty.
+ */
+int verify_krb_v5_tgt (c, realm)
+ krb5_context c;
+ char *realm;
+{
+ char phost[BUFSIZ];
+ krb5_ccache ccdef;
+ int retval, have_keys;
+ krb5_principal princ;
+ krb5_keyblock *kb = 0;
+ krb5_error_code krbval;
+ krb5_data packet;
+ krb5_auth_context auth_context = NULL;
+ krb5_ticket *ticket = NULL;
+
+ /* XXX This is to work around a library bug. I'm not sure if it's
+ been fixed for beta-6, so leave this in for now. Remove it (and
+ fix the bug if necessary) after beta-6 ships. */
+ sleep(2);
+
+ /* get the server principal for the local host */
+ /* (use defaults of "host" and canonicalized local name) */
+ krbval = krb5_sname_to_principal(c, 0, 0, KRB5_NT_SRV_HST, &princ);
+ if (krbval) {
+ com_err ("login", krbval, "constructing local service name");
+ return -1;
+ }
+
+ /* since krb5_sname_to_principal has done the work for us, just
+ extract the name directly */
+ strncpy(phost, krb5_princ_component(c, princ, 1)->data, BUFSIZ);
+
+ /* Do we have host/<host> keys? */
+ /* (use default keytab, kvno IGNORE_VNO to get the first match,
+ and enctype is currently ignored anyhow.) */
+ krbval = krb5_kt_read_service_key (c, NULL, princ, 0, ENCTYPE_DES_CBC_CRC, &kb);
+ if (kb)
+ krb5_free_keyblock (c, kb);
+ /* any failure means we don't have keys at all. */
+ have_keys = krbval ? 0 : 1;
+
+ /* set up credential cache -- obeying KRB5_ENV_CCNAME set earlier */
+ /* (KRB5_ENV_CCNAME == "KRB5CCNAME" via osconf.h) */
+ if (krbval = krb5_cc_default(c, &ccdef)) {
+ com_err("login", krbval, "while getting default ccache");
+ return -1;
+ }
+ /* talk to the kdc and construct the ticket */
+ krbval = krb5_mk_req(c, &auth_context, 0, "host", phost,
+ 0, ccdef, &packet);
+ /* wipe the auth context for mk_req */
+ if (auth_context) {
+ krb5_auth_con_free(c, auth_context);
+ auth_context = NULL;
+ }
+ if (krbval == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) {
+ /* we have a service key, so something should be
+ in the database, therefore this error packet could
+ have come from an attacker. */
+ if (have_keys) { retval = -1; goto EGRESS; }
+ /* but if it is unknown and we've got no key, we don't
+ have any security anyhow, so it is ok. */
+ else { retval = 0; goto EGRESS; }
+ }
+ else if (krbval) {
+ com_err("login", krbval,
+ "Unable to verify Kerberos V5 TGT: %s", phost);
+#ifndef SYSLOG42
+ syslog (LOG_NOTICE|LOG_AUTH, "Kerberos V5 TGT bad: %s",
+ error_message(krbval));
+#endif
+ retval = -1;
+ goto EGRESS;
+ }
+ /* got ticket, try to use it */
+ krbval = krb5_rd_req(c, &auth_context, &packet,
+ princ, NULL, NULL, &ticket);
+ if (krbval) {
+ if (!have_keys)
+ /* The krb5 errors aren't specified well, but I think
+ these values cover the cases we expect. */
+ switch (krbval) {
+ /* no keytab */
+ case ENOENT:
+ /* keytab found, missing entry */
+#if 0 /* Don't depend on the nameserver for security. Assume that if
+ we have a keytab, it must contain the right host/FQDN key. */
+ case KRB5_KT_NOTFOUND:
+#endif
+ retval = 0;
+ break;
+ default:
+ /* unexpected error: fail */
+ retval = -1;
+ break;
+ }
+ else
+ /* Any error here is bad. */
+ retval = -1;
+ com_err("login", krbval, "Unable to verify host ticket");
+#ifndef SYSLOG42
+ syslog (LOG_NOTICE|LOG_AUTH, "can't verify v5 ticket: %s; %s\n",
+ error_message(krbval),
+ retval
+ ? "keytab found, assuming failure"
+ : "no keytab found, assuming success");
+#endif
+ goto EGRESS;
+ }
+ /*
+ * The host/<host> ticket has been received _and_ verified.
+ */
+ retval = 1;
+ /* do cleanup and return */
+EGRESS:
+ if (auth_context) krb5_auth_con_free(c, auth_context);
+ krb5_free_principal(c, princ);
+ /* possibly ticket and packet need freeing here as well */
+ /* memset (&ticket, 0, sizeof (ticket)); */
+ return retval;
+}
+
+destroy_tickets()
+{
+ krb5_context c;
+ krb5_ccache cache;
+
+ if (login_krb5_get_tickets) {
+ krb5_init_context(&c);
+
+ if(!krb5_cc_default(c, &cache))
+ krb5_cc_destroy (c, cache);
+ }
+#ifdef KRB4_GET_TICKETS
+ if (login_krb4_get_tickets)
+ dest_tkt();
+#endif /* KRB4_GET_TICKETS */
+}
+
+#endif /* KRB5_GET_TICKETS */
+
+/* AFS support routines */
+#ifdef SETPAG
+
+int pagflag = 0; /* true if setpag() has been called */
+
+static sigjmp_buf setpag_buf;
+
+static sigtype sigsys ()
+{
+ siglongjmp(setpag_buf, 1);
+}
+
+static int try_afscall ()
+{
+ handler sa, osa;
+ volatile int retval = 0;
+
+ (void) &retval;
+ handler_init (sa, sigsys);
+ handler_swap (SIGSYS, sa, osa);
+ if (sigsetjmp(setpag_buf, 1) == 0) {
+ setpag ();
+ retval = 1;
+ }
+ handler_set (SIGSYS, osa);
+ return retval;
+}
+
+/* This doesn't seem to be declared in the AFS header files. */
+extern ktc_ForgetAllTokens (), setpag ();
+
+#define try_setpag() try_afscall(setpag)
+#define try_unlog() try_afscall(ktc_ForgetAllTokens)
+#endif /* SETPAG */
+
+void
+afs_login ()
+{
+#ifdef KRB4_GET_TICKETS
+#ifdef SETPAG
+ if (login_krb4_get_tickets && pwd->pw_uid) {
+ /* Only reset the pag for non-root users. */
+ /* This allows root to become anything. */
+ pagflag = try_setpag ();
+ }
+#endif
+#endif /* KRB4_GET_TICKETS */
+#ifdef KRB_RUN_AKLOG
+ if (got_v4_tickets && login_krb_run_aklog) {
+ /* KPROGDIR is $(prefix)/bin */
+ char aklog_path[MAXPATHLEN];
+ struct stat st;
+ /* construct the name */
+ /* get this from profile later */
+ strcpy (aklog_path, KPROGDIR);
+ strcat (aklog_path, "/aklog");
+ /* only run it if we can find it */
+ if (stat (aklog_path, &st) == 0) {
+ system(aklog_path);
+ }
+ }
+#endif /* KRB_RUN_AKLOG */
+}
+
+void
+afs_cleanup ()
+{
+#ifdef SETPAG
+ if (pagflag)
+ try_unlog ();
+#endif
+}
+
+/* Main routines */
#define EXCL_AUTH_TEST if (rflag || kflag || Kflag || eflag || fflag || Fflag ) { \
fprintf(stderr, \
"login: only one of -r, -k, -K, -e, -F, and -f allowed.\n"); \
@@ -230,16 +1063,54 @@ typedef krb5_sigtype sigtype;
exit(1);\
}
-#ifndef HAVE_INITGROUPS
-int initgroups(char* name, gid_t basegid) {
- gid_t others[NGROUPS_MAX+1];
- int ngrps;
-
- others[0] = basegid;
- ngrps = getgroups(NGROUPS_MAX, others+1);
- return setgroups(ngrps+1, others);
+static void
+read_env_vars_from_file (filename)
+ char *filename;
+{
+ FILE *fp;
+ char *p, *eq;
+ char tbuf[MAXPATHLEN+2];
+
+ if ((fp = fopen("/etc/environment", "r")) != NULL) {
+ while (fgets(tbuf, sizeof(tbuf), fp)) {
+ if (tbuf[0] == '#')
+ continue;
+ eq = strchr(tbuf, '=');
+ if (eq == 0)
+ continue;
+ p = strchr (tbuf, '\n');
+ if (p)
+ *p = 0;
+ *eq++ = 0;
+ /* Don't override, in case -p was used. */
+ setenv (tbuf, eq, 0);
+ }
+ fclose(fp);
+ }
}
+
+static void
+log_repeated_failures (tty, hostname)
+ char *tty, *hostname;
+{
+ if (hostname) {
+#ifdef UT_HOSTSIZE
+ 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 FROM %s, %.*s",
+ tty, hostname, UT_NAMESIZE,
+ username);
#endif
+ }
+ else
+ syslog(LOG_ERR,
+ "REPEATED LOGIN FAILURES ON %s, %.*s",
+ tty, UT_NAMESIZE, username);
+}
int main(argc, argv)
int argc;
@@ -248,46 +1119,34 @@ int main(argc, argv)
extern int optind;
extern char *optarg, **environ;
struct group *gr;
- register int ch, i;
- register char *p;
+ int ch;
+ char *p;
int fflag, hflag, pflag, rflag, Fflag, cnt;
int kflag, Kflag, eflag;
int quietlog, passwd_req, ioctlval;
sigtype timedout();
- char *domain, *salt, **envinit, *ttyn, *tty;
+ char *domain, **envinit, *ttyn, *tty;
char tbuf[MAXPATHLEN + 2];
char *ttyname(), *stypeof(), *crypt(), *getpass();
time_t login_time;
+ int retval;
+#ifdef KRB5_GET_TICKETS
+ krb5_principal me;
+#endif /* KRB5_GET_TICKETS */
char *ccname = 0; /* name of forwarded cache */
-int retval;
-
+ char *tz = 0;
+
off_t lseek();
-#ifdef POSIX_TERMIOS
- struct termios tc;
-#endif
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
+ handler sa;
-#ifdef POSIX_SIGNALS
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = timedout;
- (void)sigaction(SIGALRM, &sa, (struct sigaction *)0);
-#else
- (void)signal(SIGALRM, timedout);
-#endif
+ handler_init (sa, timedout);
+ handler_set (SIGALRM, sa);
(void)alarm((u_int)timeout);
-#ifdef POSIX_SIGNALS
- sa.sa_handler = SIG_IGN;
- (void)sigaction(SIGALRM, &sa, (struct sigaction *)0);
-#else
- (void)signal(SIGQUIT, SIG_IGN);
- (void)signal(SIGINT, SIG_IGN);
-#endif
-#ifdef HAVE_SETPRIORITY
- (void)setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
-#endif
+
+ handler_init (sa, SIG_IGN);
+ handler_set (SIGQUIT, sa);
+ handler_set (SIGINT, sa);
+ setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
#ifdef OQUOTA
(void)quota(Q_SETUID, 0, 0, 0);
#endif
@@ -356,7 +1215,7 @@ int retval;
*p = '\0';
hostname = optarg;
break;
-#ifdef KRB4
+#ifdef KRB4_KLOGIN
case 'k':
case 'K':
EXCL_AUTH_TEST;
@@ -382,7 +1241,7 @@ int retval;
*p = '\0';
hostname = optarg;
break;
-#endif /* KRB4 */
+#endif /* KRB4_KLOGIN */
case 'e':
EXCL_AUTH_TEST;
if (getuid()) {
@@ -422,85 +1281,14 @@ int retval;
#endif
(void)fcntl(0, F_SETFL, ioctlval);
-#ifdef POSIX_TERMIOS
- (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_TERMIOS
- if (rflag || kflag || Kflag || eflag)
- doremoteterm(&tc);
- tc.c_cc[VMIN] = 1;
- tc.c_cc[VTIME] = 0;
-#ifndef NO_INIT_CC
- 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;
-#ifndef CNUL
-#define CNUL CEOL
-#endif
- tc.c_cc[VEOL] = CNUL;
- /* The following are common extensions to POSIX */
-#ifdef VEOL2
- tc.c_cc[VEOL2] = CNUL;
-#endif
-#ifdef VSUSP
-#if !defined(CSUSP) && defined(CSWTCH)
-#define CSUSP CSWTCH
-#endif
- 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 VDISCARD
-#ifndef CDISCARD
-#define CDISCARD CFLUSH
-#endif
- tc.c_cc[VDISCARD] = CDISCARD;
-#endif
-#ifdef VWERSE
- tc.c_cc[VWERSE] = CWERASE;
-#endif
-#ifdef VWERASE
- tc.c_cc[VWERASE] = CWERASE;
-#endif
-#ifdef VSTATUS
-#ifdef CSTATUS
- tc.c_cc[VSTATUS] = CSTATUS;
-#endif /* CSTATUS */
-#endif /* VSTATUS */
-#endif /* NO_INIT_CC */
- 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
+ term_init (rflag || kflag || Kflag || eflag);
+
for (cnt = getdtablesize(); cnt > 2; cnt--)
(void) close(cnt);
@@ -520,36 +1308,35 @@ int retval;
openlog("login", LOG_ODELAY, LOG_AUTH);
#endif /* 4.2 syslog */
+/******* begin askpw *******/
+ /* overall:
+ ask for username if we don't have it already
+ look it up in local pw or shadow file (to get crypt string)
+ ask for password
+ try and get v4, v5 tickets with it
+ try and use the tickets against the local srvtab
+ if the password matches, always let them in
+ if the ticket decrypts, let them in.
+ v5 needs to work, does v4?
+ */
+
+#ifdef KRB5_GET_TICKETS
+ k_init (ttyn);
+#endif
+
for (cnt = 0;; username = NULL) {
-#ifdef KRB4
- char pp[9], pp2[MAXPWSIZE], *namep;
- int krbval;
- char realm[REALM_SZ];
+#ifdef KRB5_GET_TICKETS
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 /* KRB4 */
-#if defined(TIOCSETD)&&(!defined(POSIX_TERMIOS))
- ioctlval = 0;
- (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
-#endif
+ char user_pwstring[MAXPWSIZE];
+ /* variables from v5 kinit */
+#endif /* KRB5_GET_TICKETS */
+
if (username == NULL) {
fflag = Fflag = 0;
getloginname();
}
- if ((pwd = getpwnam(username)))
- salt = pwd->pw_passwd;
- else
- salt = "xx";
-#ifdef HAVE_SHADOW
- if (spwd = getspnam(username))
- salt = spwd->sp_pwdp;
-#endif
+ lookup_user (username); /* sets pwd */
/* if user not super-user, check for disabled logins */
if (pwd == NULL || pwd->pw_uid)
@@ -580,96 +1367,56 @@ int retval;
* If no remote login authentication and a password exists
* for this user, prompt for one and verify it.
*/
- if (!passwd_req) break;
-#ifdef HAVE_SHADOW
- if (spwd) {
- if (!*(spwd->sp_pwdp)) break;
- } else
-#endif
- if (pwd && !*(pwd->pw_passwd))
- break;
+ if (!passwd_req)
+ break;
-#ifdef KRB4
+ if (! unix_needs_passwd ())
+ break;
+
+ /* we have several sets of code:
+ 1) get v5 tickets alone -DKRB5_GET_TICKETS
+ 2) get v4 tickets alone [** don't! only get them *with* v5 **]
+ 3) get both tickets -DKRB5_GET_TICKETS -DKRB4_GET_TICKETS
+ 3a) use krb524 calls to get the v4 tickets -DKRB4_CONVERT plus (3).
+ 4) get no tickets and use the password file (none of thes defined.)
+
+ Likewise we need to (optionally?) test these tickets against local srvtabs.
+ */
+#ifdef KRB5_GET_TICKETS
+ if (login_krb5_get_tickets) {
+ /* rename these to something more verbose */
kpass_ok = 0;
lpass_ok = 0;
-#ifdef HAVE_SETPRIORITY
- (void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
-#endif
- if (read_long_pw_string(pp2, sizeof(pp2)-1, "Password: ", 0)) {
- /* reading password failed... */
-#ifdef HAVE_SETPRIORITY
- (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
-#endif
+ setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
+ if (! k5_get_password (user_pwstring, sizeof (user_pwstring))) {
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, salt);
- memset (pp, 0, sizeof(pp)); /* To the best of my recollection, Senator... */
+ /* now that we have the password, we've obscured things
+ sufficiently, and can avoid trying tickets */
+ if (!pwd)
+ goto bad_login;
+
+ lpass_ok = unix_passwd_okay (user_pwstring);
-#ifdef HAVE_SHADOW
- if (spwd)
- lpass_ok = !strcmp(namep, spwd->sp_pwdp);
- else
-#endif
- lpass_ok = !strcmp (namep, pwd->pw_passwd);
-
if (pwd->pw_uid != 0) { /* Don't get tickets for root */
+ try_krb5 (&me, user_pwstring);
- 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 /* BIND_HACK */
+#ifdef KRB4_GET_TICKETS
+ if (login_krb4_get_tickets
+ && (!got_v5_tickets
+ || !login_krb4_convert))
+ try_krb4 (me, user_pwstring);
+#endif
+ krbflag = got_v5_tickets || got_v4_tickets;
+ memset (user_pwstring, 0, sizeof(user_pwstring));
+ /* password wiped, so we can relax */
+ setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
- krbval = krb_get_pw_in_tkt(username, "", realm, "krbtgt",
- realm, DEFAULT_TKT_LIFE, pp2);
- memset (pp2, 0, sizeof(pp2));
-#ifdef HAVE_SETPRIORITY
- (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
-#endif
- switch (krbval) {
- case INTK_OK:
- kpass_ok = 1;
- krbflag = 1;
- strcpy(tkfile, tkt_string());
- (void) chown(tkfile, pwd->pw_uid, pwd->pw_gid);
- 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) memset (pp2, 0, sizeof(pp2));
-#ifdef HAVE_SETPRIORITY
- (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
-#endif
+ memset (user_pwstring, 0, sizeof(user_pwstring));
+ setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
}
/* Policy: If local password is good, user is good.
@@ -682,52 +1429,41 @@ int retval;
if (kpass_ok)
*/
if (lpass_ok)
- break;
-bad_login:
- if (krbflag)
- dest_tkt(); /* clean up tickets if login fails */
-#else /* !KRB4 */
-#ifdef HAVE_SETPRIORITY
- (void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
-#endif
- p = crypt(getpass("Password:"), salt);
-#ifdef HAVE_SETPRIORITY
- (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
-#endif
-#ifdef HAVE_SHADOW
- if (spwd && !strcmp(p, spwd->sp_pwdp))
- break;
- else
-#endif
- if (pwd && !strcmp(p, pwd->pw_passwd))
break;
-#endif /* KRB4 */
+ if (got_v5_tickets
+ && verify_krb_v5_tgt(kcontext, realm) != -1)
+ break; /* we're ok */
+#ifdef KRB4_GET_TICKETS
+ if (login_krb4_get_tickets) {
+ if (got_v4_tickets
+ && ! got_v5_tickets
+ && verify_krb_v4_tgt(realm) != -1)
+ break; /* we're ok */
+ }
+#endif /* KRB4_GET_TICKETS */
+ bad_login:
+ setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ if (krbflag)
+ destroy_tickets(); /* clean up tickets if login fails */
+ }
+#endif /* KRB5_GET_TICKETS */
+#ifdef OLD_PASSWD
+ p = getpass ("Password:");
+ /* conventional password only */
+ if (unix_passwd_okay (p))
+ break;
+#endif /* OLD_PASSWD */
printf("Login incorrect\n");
if (++cnt >= 5) {
- if (hostname)
-#ifdef UT_HOSTSIZE
- 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 FROM %s, %.*s",
- tty, hostname, UT_NAMESIZE,
- username);
-#endif
- else
- syslog(LOG_ERR,
- "REPEATED LOGIN FAILURES ON %s, %.*s",
- tty, UT_NAMESIZE, username);
+ log_repeated_failures (tty, hostname);
/* irix has no tichpcl */
#ifdef TIOCHPCL
(void)ioctl(0, TIOCHPCL, (char *)0);
#endif
sleepexit(1);
}
- }
+ } /* end of password retry loop */
/* committed to login -- turn off timeout */
(void)alarm((u_int)0);
@@ -770,7 +1506,6 @@ bad_login:
sleepexit(0);
}
#endif
-
if (chdir(pwd->pw_dir) < 0) {
printf("No directory %s!\n", pwd->pw_dir);
if (chdir("/"))
@@ -801,17 +1536,26 @@ bad_login:
(gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
(void)chmod(ttyn, 0620);
-#ifdef KRB4
-#ifdef SETPAG
- if (pwd->pw_uid) {
- /* Only reset the pag for non-root users. */
- /* This allows root to become anything. */
- pagflag = 1;
- setpag();
+
+#ifdef KRB4_GET_TICKETS
+ if (login_krb4_get_tickets && login_krb4_convert && !got_v4_tickets) {
+
+ /* Maybe telnetd got tickets for us? */
+ if (!got_v5_tickets && have_v5_tickets (&me))
+ got_v5_tickets = 1;
+
+ if (got_v5_tickets)
+ try_convert524 (kcontext, me);
+
}
#endif
- /* Fork so that we can call kdestroy */
- dofork();
+
+#ifdef KRB5_GET_TICKETS
+ if (login_krb4_get_tickets || login_krb5_get_tickets) {
+ /* Fork so that we can call kdestroy */
+ dofork();
+ }
+#endif /* KRB4_GET_TICKETS */
/* If the user's shell does not do job control we should put it in a
different process group than than us, and set the tty process group
@@ -819,25 +1563,48 @@ bad_login:
telnetd or rlogind if they don't properly detach from their
controlling tty, which is the case (under SunOS at least.) */
- { int p = getpid();
- if (setpgrp(p,p) < 0) perror("login.krb5: setpgrp");
- if (ioctl(0, TIOCSPGRP, &p) < 0) perror("login.krb5: tiocspgrp");
- }
-
-/* SunOS has an ioctl which can set the controlling tty and make sure
- that no other process also has it. That's exactly what we want to
- do for the shell we are about to exec, since it is the documented
- way to avoid the problem noted just above. */
+ {
+ int p = getpid();
+ struct sigaction sa, osa;
-#ifdef sun
-#ifdef TIOCSCTTY
- { if (setsid() < 0) perror("login.krb5: setsid");
- if (ioctl(0, TIOCSCTTY, 1) < 0) perror("login.krb5: tiocsctty");
- }
+ /* this will set the PGID to the PID. */
+#ifdef HAVE_SETPGID
+ if (setpgid(p,p) < 0) perror("login.krb5: setpgid");
+#else
+#ifdef SETPGRP_TWOARG
+ if (setpgrp(p,p) < 0) perror("login.krb5: setpgrp");
+#else
+ if (setpgrp() < 0) perror("login.krb5: setpgrp");
#endif
#endif
-#endif /* KRB4 */
+ /* This will cause SIGTTOU to be ignored for the duration
+ of the TIOCSPGRP. If this is not done, and the parent's
+ process group is the foreground pgrp of the tty, then
+ this will suspend the child, which is bad. */
+
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&(sa.sa_mask));
+
+ if (sigaction(SIGTTOU, &sa, &osa))
+ perror("login.krb5: sigaction(SIGTTOU, SIG_IGN)");
+
+ /* This will set the foreground process group of the
+ controlling terminal to this process group (containing
+ only this process). */
+#ifdef HAVE_TCSETPGRP
+ if (tcsetpgrp(0, p) < 0) perror("login.krb5: tcsetpgrp");
+#else
+ if (ioctl(0, TIOCSPGRP, &p) < 0) perror("login.krb5: tiocspgrp");
+#endif
+
+ /* This will reset the SIGTTOU handler */
+
+ if (sigaction(SIGTTOU, &osa, NULL))
+ perror("login.krb5: sigaction(SIGTTOU, [old handler])");
+ }
+
(void)setgid((gid_t) pwd->pw_gid);
(void) initgroups(username, pwd->pw_gid);
@@ -872,69 +1639,41 @@ bad_login:
pwd->pw_shell = BSHELL;
#if defined(NTTYDISC) && defined(TIOCSETD)
/* turn on new line discipline for the csh */
- else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
+ if (!strcmp(pwd->pw_shell, "/bin/csh")) {
ioctlval = NTTYDISC;
(void)ioctl(0, TIOCSETD, (char *)&ioctlval);
}
#endif
ccname = getenv("KRB5CCNAME"); /* save cache */
+ tz = getenv("TZ"); /* and time zone */
/* destroy environment unless user has requested preservation */
- envinit = (char **)malloc(MAXENVIRON * sizeof(char *));
- if (envinit == 0) {
+ if (!pflag) {
+ envinit = (char **)malloc(MAXENVIRON * sizeof(char *));
+ if (envinit == 0) {
fprintf(stderr, "Can't malloc empty environment.\n");
sleepexit(1);
+ }
+ envinit[0] = NULL;
+ environ = envinit;
}
- if (!pflag)
- environ = envinit;
- i = 0;
+ setenv ("LOGNAME", pwd->pw_name, 1);
+ setenv ("LOGIN", pwd->pw_name, 1);
-#ifdef _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
-/* Set login timezone for date information (PDG) */
-#ifdef __sgi__
- {
- FILE *fp;
- if ((fp = fopen("/etc/TIMEZONE", "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);
- }
- }
+ /* read the /etc/environment file on AIX */
+#ifdef HAVE_ETC_ENVIRONMENT
+ read_env_vars_from_file ("/etc/environment");
#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;
+ /* Set login timezone for date information (sgi PDG) */
+#ifdef HAVE_ETC_TIMEZONE
+ read_env_vars_from_file ("/etc/TIMEZONE");
+#else
+ if (tz)
+ setenv ("TZ", tz, 0);
+#endif
if (ccname)
setenv("KRB5CCNAME", ccname, 0);
@@ -946,24 +1685,24 @@ bad_login:
if (term[0] == '\0')
(void) strncpy(term, stypeof(tty), sizeof(term));
- (void)setenv("TERM", term, 0);
-#ifdef KRB4
+ if (term[0])
+ (void)setenv("TERM", term, 0);
+#ifdef KRB4_GET_TICKETS
/* tkfile[0] is only set if we got tickets above */
- if (tkfile[0])
+ if (login_krb4_get_tickets && tkfile[0])
(void) setenv(KRB_ENVIRON, tkfile, 1);
-#endif /* KRB4 */
-
-#if 0
- strcpy(wgfile, "/tmp/wg.XXXXXX");
- mktemp(wgfile);
- setenv("WGFILE", wgfile, 0);
-#endif
+#endif /* KRB4_GET_TICKETS */
+#ifdef KRB5_GET_TICKETS
+ /* ccfile[0] is only set if we got tickets above */
+ if (login_krb5_get_tickets && ccfile[0])
+ (void) setenv(KRB5_ENV_CCNAME, ccfile, 1);
+#endif /* KRB5_GET_TICKETS */
if (tty[sizeof("tty")-1] == 'd')
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
if (pwd->pw_uid == 0)
if (hostname)
-#ifdef KRB4
+#ifdef KRB4_KLOGIN
if (kdata) {
/* @*$&@#*($)#@$ syslog doesn't handle very
many arguments */
@@ -983,7 +1722,7 @@ bad_login:
#endif
syslog(LOG_NOTICE, "%s", buf);
} else {
-#endif /* KRB4 */
+#endif /* KRB4_KLOGIN */
#ifdef UT_HOSTSIZE
syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
tty, UT_HOSTSIZE, hostname);
@@ -991,7 +1730,7 @@ bad_login:
syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s",
tty, hostname);
#endif
-#ifdef KRB4
+#ifdef KRB4_KLOGIN
}
else
if (kdata) {
@@ -1001,43 +1740,30 @@ bad_login:
kdata->pname, kdata->pinst,
kdata->prealm);
}
-#endif /* KRB4 */
+#endif /* KRB4_KLOGIN */
else
syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
- if (!quietlog) {
- struct stat st;
+ afs_login ();
-#ifdef KRB4
+ if (!quietlog) {
+#ifdef KRB4_KLOGIN
if (!krbflag && !fflag && !Fflag && !eflag )
printf("\nWarning: No Kerberos tickets obtained.\n\n");
-#endif /* KRB4 */
-#ifndef NO_MOTD
- motd();
-#endif
- (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 " : "");
+#endif /* KRB4_KLOGIN */
+ motd ();
+ check_mail ();
}
#ifndef OQUOTA
if (! access( QUOTAWARN, X_OK)) (void) system(QUOTAWARN);
#endif
-#ifdef POSIX_SIGNALS
- sa.sa_handler = SIG_DFL;
- (void)sigaction(SIGALRM, &sa, (struct sigaction *)0);
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
-
- sa.sa_handler = SIG_IGN;
- (void)sigaction(SIGTSTP, &sa, (struct sigaction *)0);
-#else
- (void)signal(SIGALRM, SIG_DFL);
- (void)signal(SIGQUIT, SIG_DFL);
- (void)signal(SIGINT, SIG_DFL);
- (void)signal(SIGTSTP, SIG_IGN);
-#endif
+ handler_init (sa, SIG_DFL);
+ handler_set (SIGALRM, sa);
+ handler_set (SIGQUIT, sa);
+ handler_set (SIGINT, sa);
+ handler_init (sa, SIG_IGN);
+ handler_set (SIGTSTP, sa);
tbuf[0] = '-';
(void) strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
@@ -1048,6 +1774,150 @@ bad_login:
exit(0);
}
+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]))
+
+#ifdef POSIX_TERMIOS
+/* this must be in sync with the list above */
+speed_t b_speeds[] = {
+ B0, B50, B75, B110, B134, B150, B200, B300, B600,
+ B1200, B1800, B2400, B4800, B9600, B19200, B38400,
+};
+#endif
+
+term_init (do_rlogin)
+{
+ int line_speed = -1;
+
+ if (do_rlogin) {
+ register char *cp = strchr(term, '/'), **cpp;
+ char *speed;
+
+ if (cp) {
+ *cp++ = '\0';
+ speed = cp;
+ cp = strchr(speed, '/');
+ if (cp)
+ *cp++ = '\0';
+ for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
+ if (strcmp(*cpp, speed) == 0) {
+ line_speed = cpp-speeds;
+ break;
+ }
+ }
+ }
+#ifdef POSIX_TERMIOS
+ {
+ struct termios tc;
+
+ (void)tcgetattr(0, &tc);
+ if (line_speed != -1) {
+ cfsetispeed(&tc, b_speeds[line_speed]);
+ cfsetospeed(&tc, b_speeds[line_speed]);
+ }
+ tc.c_cc[VMIN] = 1;
+ tc.c_cc[VTIME] = 0;
+#ifndef NO_INIT_CC
+ 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;
+#ifndef CNUL
+#define CNUL CEOL
+#endif
+ tc.c_cc[VEOL] = CNUL;
+ /* The following are common extensions to POSIX */
+#ifdef VEOL2
+ tc.c_cc[VEOL2] = CNUL;
+#endif
+#ifdef VSUSP
+#if !defined(CSUSP) && defined(CSWTCH)
+#define CSUSP CSWTCH
+#endif
+ 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 VDISCARD
+#ifndef CDISCARD
+#define CDISCARD CFLUSH
+#endif
+ tc.c_cc[VDISCARD] = CDISCARD;
+#endif
+#ifdef VWERSE
+ tc.c_cc[VWERSE] = CWERASE;
+#endif
+#ifdef VWERASE
+ tc.c_cc[VWERASE] = CWERASE;
+#endif
+#if defined (VSTATUS) && defined (CSTATUS)
+ tc.c_cc[VSTATUS] = CSTATUS;
+#endif /* VSTATUS && CSTATUS */
+#endif /* NO_INIT_CC */
+ /* set all standard echo, edit, and job control options */
+ /* but leave any extensions */
+ tc.c_lflag |= ECHO|ECHOE|ECHOK|ICANON|ISIG|IEXTEN;
+ tc.c_lflag &= ~(NOFLSH|TOSTOP);
+#ifdef ECHOCTL
+ /* Not POSIX, but if we have it, we probably want it */
+ tc.c_lflag |= ECHOCTL;
+#endif
+#ifdef ECHOKE
+ /* Not POSIX, but if we have it, we probably want it */
+ tc.c_lflag |= ECHOKE;
+#endif
+ tc.c_iflag |= ICRNL|BRKINT;
+ tc.c_oflag |= ONLCR|OPOST|TAB3;
+ tcsetattr(0, TCSANOW, &tc);
+ }
+
+#else /* not POSIX_TERMIOS */
+
+ {
+ struct sgttyb sgttyb;
+ static struct tchars tc = {
+ CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
+ };
+ static struct ltchars ltc = {
+ CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
+ };
+
+ (void) ioctl(0, TIOCGETP, (char *)&sgttyb);
+ if (line_speed != -1)
+ sgttyb.sg_ispeed = sgttyb.sg_ospeed = line_speed;
+ sgttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS;
+ 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);
+#if defined(TIOCSETD)
+ {
+ int ioctlval;
+ ioctlval = 0;
+ (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
+ }
+#endif
+ }
+#endif
+}
+
void getloginname()
{
register int ch;
@@ -1096,58 +1966,42 @@ int rootterm(tty)
#endif /* HAVE_TTYENT_H */
}
-#ifdef POSIX_SETJMP
+#ifndef NO_MOTD
sigjmp_buf motdinterrupt;
-#else
-jmp_buf motdinterrupt;
-#endif
+sigtype
+sigint()
+{
+ siglongjmp(motdinterrupt, 1);
+}
void motd()
{
register int fd, nchars;
char tbuf[8192];
- sigtype sigint();
-#ifdef POSIX_SIGNALS
- struct sigaction sa, osa;
-#else
- sigtype (*oldint)();
-#endif
+ handler sa, osa;
if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
return;
-#ifdef POSIX_SIGNALS
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = sigint;
- (void)sigaction(SIGINT, &sa, &osa);
-#else
- oldint = signal(SIGINT, sigint);
-#endif
-#ifdef POSIX_SETJMP
+ handler_init (sa, sigint);
+ handler_swap (SIGINT, sa, osa);
if (sigsetjmp(motdinterrupt, 1) == 0)
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
(void)write(fileno(stdout), tbuf, nchars);
-#else
- if (setjmp(motdinterrupt) == 0)
- while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
- (void)write(fileno(stdout), tbuf, nchars);
-#endif
-#ifdef POSIX_SIGNALS
- (void)sigaction(SIGINT, &osa, (struct sigaction *)0);
-#else
- (void)signal(SIGINT, oldint);
-#endif
+ handler_set (SIGINT, osa);
(void)close(fd);
}
-
-sigtype
-sigint()
-{
-#ifdef POSIX_SETJMP
- siglongjmp(motdinterrupt, 1);
#else
- longjmp(motdinterrupt, 1);
+void motd () { }
#endif
+
+void check_mail ()
+{
+ char tbuf[MAXPATHLEN+2];
+ struct stat st;
+ (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 " : "");
}
void checknologin()
@@ -1199,7 +2053,11 @@ void dolastlog(quiet, tty)
}
#undef UNKNOWN
+#ifdef __hpux
+#define UNKNOWN 0
+#else
#define UNKNOWN "su"
+#endif
char *
stypeof(ttyid)
@@ -1230,7 +2088,7 @@ int doremotelogin(host)
return(ruserok(host, (pwd->pw_uid == 0), rusername, username));
}
-#ifdef KRB4
+#ifdef KRB4_KLOGIN
int do_krb_login(host, strict)
char *host;
int strict;
@@ -1276,7 +2134,7 @@ int do_krb_login(host, strict)
instance, &sin,
(struct sockaddr_in *)0,
kdata, "", (bit_64 *) 0, version))) {
- printf("Kerberos rlogin failed: %s\r\n",krb_err_txt[rc]);
+ printf("Kerberos rlogin failed: %s\r\n",krb_get_err_text(rc));
if (strict) {
paranoid:
/*
@@ -1322,7 +2180,7 @@ paranoid:
}
return(0);
}
-#endif /* KRB4 */
+#endif /* KRB4_KLOGIN */
void lgetstr(buf, cnt, err)
char *buf, *err;
@@ -1344,79 +2202,19 @@ void lgetstr(buf, cnt, err)
} 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]))
-
-#ifdef POSIX_TERMIOS
-/* this must be in sync with the list above */
-speed_t b_speeds[] = {
- B0, B50, B75, B110, B134, B150, B200, B300, B600,
- B1200, B1800, B2400, B4800, B9600, B19200, B38400,
-};
-#endif
-
-void doremoteterm(tp)
-#ifdef POSIX_TERMIOS
- struct termios *tp;
-#else
- struct sgttyb *tp;
-#endif
-{
- register char *cp = strchr(term, '/'), **cpp;
- char *speed;
-
- if (cp) {
- *cp++ = '\0';
- speed = cp;
- cp = strchr(speed, '/');
- if (cp)
- *cp++ = '\0';
- for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
- if (strcmp(*cpp, speed) == 0) {
-#ifdef POSIX_TERMIOS
- cfsetispeed(tp, b_speeds[cpp-speeds]);
- cfsetospeed(tp, b_speeds[cpp-speeds]);
-#else
- tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
-#endif
- break;
- }
- }
-#ifdef POSIX_TERMIOS
- /* set all standard echo, edit, and job control options */
- /* but leave any extensions */
- tp->c_lflag |= ECHO|ECHOE|ECHOK|ICANON|ISIG|IEXTEN;
- tp->c_lflag &= ~(NOFLSH|TOSTOP);
-#ifdef ECHOCTL
- /* Not POSIX, but if we have it, we probably want it */
- tp->c_lflag |= ECHOCTL;
-#endif
-#ifdef ECHOKE
- /* Not POSIX, but if we have it, we probably want it */
- tp->c_lflag |= ECHOKE;
-#endif
- tp->c_iflag |= ICRNL|BRKINT;
- tp->c_oflag |= ONLCR|OPOST|TAB3;
-#else /* !POSIX_TERMIOS */
- tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
-#endif
-}
-
void sleepexit(eval)
int eval;
{
-#ifdef KRB4
- if (krbflag)
- (void) dest_tkt();
-#endif /* KRB4 */
+#ifdef KRB4_GET_TICKETS
+ if (login_krb4_get_tickets && krbflag)
+ (void) destroy_tickets();
+#endif /* KRB4_GET_TICKETS */
sleep((u_int)5);
exit(eval);
}
-#ifdef KRB4
+#ifdef KRB4_GET_TICKETS
+/* call already conditionalized on login_krb4_get_tickets */
/*
* This routine handles cleanup stuff, and the like.
* It exits only in the child process.
@@ -1431,10 +2229,15 @@ dofork()
update_ref_count(1);
#endif
if(!(child=fork()))
- return; /* Child process */
+ return; /* Child process returns */
+
+ /* The parent continues here */
{ /* Try and get rid of our controlling tty. On SunOS, this may or may
not work depending on if our parent did a setsid before exec-ing us. */
+#ifndef __linux__
+ /* On linux, TIOCNOTTY causes us to die on a
+ SIGHUP, so don't even try it. */
#ifdef TIOCNOTTY
{ int fd;
if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
@@ -1443,10 +2246,15 @@ dofork()
}
}
#endif
+#endif /* __linux__ */
#ifdef HAVE_SETSID
(void)setsid();
#endif
+#ifdef SETPGRP_TWOARG
(void)setpgrp(0, 0);
+#else
+ (void)setpgrp();
+#endif
}
/* Setup stuff? This would be things we could do in parallel with login */
@@ -1464,12 +2272,9 @@ dofork()
#endif
/* Cleanup stuff */
- /* Run dest_tkt to destroy tickets */
- (void) dest_tkt(); /* If this fails, we lose quietly */
-#ifdef SETPAG
- if (pagflag)
- ktc_ForgetAllTokens();
-#endif
+ /* Run destroy_tickets to destroy tickets */
+ (void) destroy_tickets(); /* If this fails, we lose quietly */
+ afs_cleanup ();
#ifdef _IBMR2
update_ref_count(-1);
#endif
@@ -1477,7 +2282,7 @@ dofork()
/* Leave */
exit(0);
}
-#endif /* KRB4 */
+#endif /* KRB4_GET_TICKETS */
#ifndef HAVE_STRSAVE
diff --git a/src/appl/bsd/loginpaths.h b/src/appl/bsd/loginpaths.h
index a07b40c2a1..2f2de0bb81 100644
--- a/src/appl/bsd/loginpaths.h
+++ b/src/appl/bsd/loginpaths.h
@@ -20,6 +20,12 @@
/* hpux 8, both hppa and s300 */
#define LPATH "/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin"
#define RPATH "/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin"
+#else
+#ifdef __hpux /* 9.04 */
+#define LPATH_root ":/bin:/usr/bin:/etc"
+#define LPATH "/bin:/usr/bin"
+#define RPATH "/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin"
+#endif
#endif
#ifdef NeXT
diff --git a/src/appl/bsd/rlogin.M b/src/appl/bsd/rlogin.M
index b7e8765f39..d3774d5858 100644
--- a/src/appl/bsd/rlogin.M
+++ b/src/appl/bsd/rlogin.M
@@ -54,38 +54,6 @@ realm ] [
.B \-l
username ]
.PP
-.br
-rhost [
-\fB\-e\fR\fIc\fR
-] [
-.B \-8
-] [
-.B \-c
-] [
-.B \-a
-] [
-.B \-f
-] [
-.B \-F
-] [
-.B \-t
-termtype ] [
-.B \-n
-] [
-.B \-7
-] [
-.B \-d
-] [
-.B \-k
-realm ] [
-.B \-x
-] [
-.B \-noflow
-] [
-.B \-L
-] [
-.B \-l
-username ]
.SH DESCRIPTION
.I Rlogin
connects your terminal on the current local host system
@@ -213,8 +181,6 @@ significantly increases CPU utilization.
rsh(1), kerberos(3), krb_sendauth(3), krb_realmofhost(3),
rlogin(1) [UCB version]
.SH FILES
-/usr/hosts/* for \fIrhost\fP version of the command
-.br
\&.k5login in the user's home directory
.SH BUGS
More of the environment should be propagated.
diff --git a/src/appl/bsd/rsh.M b/src/appl/bsd/rsh.M
index 95ddfd0f11..d073832b53 100644
--- a/src/appl/bsd/rsh.M
+++ b/src/appl/bsd/rsh.M
@@ -33,20 +33,10 @@ username
] [
.B \-k
realm ] [
-.B \-A
-] command
-.br
-host
-[
-.B \-l
-username
+.B \-f | \-F
] [
-.B \-n
-] [
-.B \-d
+.B \-x
] [
-.B \-k
-realm ] [
.B \-A
] command
.SH DESCRIPTION
@@ -79,6 +69,21 @@ account name using the aname -> lname mapping rules (see \fIkrb5_anadd(8)\fP
for more details).
.PP
The
+.B \-x
+option causes the network session traffic to be encrypted.
+.PP
+The
+.B \-f
+and
+.B \-F
+options cause Kerberos credentials to be forwarded to the remote machine for
+use by the specified \fIcommand\fR. They will be removed when \fIcommand\fR
+finishes. If
+.B \-F
+is used, the forwarded credentials are themselves forwardable to other
+machines.
+.PP
+The
.B \-k
\fIrealm\fP option causes
.I rsh
@@ -129,18 +134,10 @@ appends
.I remotefile
to
.I otherremotefile.
-.PP
-The host names for local machines are also commands in the directory
-/usr/hosts; if you put this directory in your search path
-then the
-.B rsh
-on the command line can be omitted.
.SH FILES
.ta 2i
/etc/hosts
.br
-/usr/hosts/*
-.br
\&.k5login in the user's home directory
.DT
.SH SEE ALSO