summaryrefslogtreecommitdiffstats
path: root/src/appl/bsd
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-11-22 14:58:54 +0000
committerGreg Hudson <ghudson@mit.edu>2009-11-22 14:58:54 +0000
commit14590b7c281e1fbf68afec2f3f4104b87e6010f4 (patch)
treee3f6c44278d9a69c45fbabd4b93146a99aa29244 /src/appl/bsd
parent829462f1ae36623021b57a03aa1e4e6bb2dfbb6d (diff)
downloadkrb5-14590b7c281e1fbf68afec2f3f4104b87e6010f4.tar.gz
krb5-14590b7c281e1fbf68afec2f3f4104b87e6010f4.tar.xz
krb5-14590b7c281e1fbf68afec2f3f4104b87e6010f4.zip
Unbundle applications into separate repository
Remove libpty, gssftp, telnet, and the bsd applications from the source tree, build system, and tests. Docs still need to be updated to remove mentions of the applications. The build system should be simplified now that we're down to one configure script and don't need some of the functionality currently in aclocal.m4. ticket: 6583 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23305 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl/bsd')
-rw-r--r--src/appl/bsd/Makefile.in84
-rw-r--r--src/appl/bsd/configure.in159
-rw-r--r--src/appl/bsd/defines.h85
-rw-r--r--src/appl/bsd/deps82
-rw-r--r--src/appl/bsd/forward.c76
-rw-r--r--src/appl/bsd/getdtablesize.c19
-rw-r--r--src/appl/bsd/kcmd.c1035
-rw-r--r--src/appl/bsd/klogind.M174
-rw-r--r--src/appl/bsd/krcp.c1363
-rw-r--r--src/appl/bsd/krlogin.c1807
-rw-r--r--src/appl/bsd/krlogind.c1430
-rw-r--r--src/appl/bsd/krsh.c595
-rw-r--r--src/appl/bsd/krshd.c2047
-rw-r--r--src/appl/bsd/kshd.M211
-rw-r--r--src/appl/bsd/login.M77
-rw-r--r--src/appl/bsd/login.c1930
-rw-r--r--src/appl/bsd/loginpaths.h113
-rw-r--r--src/appl/bsd/rcp.M160
-rw-r--r--src/appl/bsd/rlogin.M157
-rw-r--r--src/appl/bsd/rpaths.h30
-rw-r--r--src/appl/bsd/rsh.M173
-rw-r--r--src/appl/bsd/setenv.c166
22 files changed, 0 insertions, 11973 deletions
diff --git a/src/appl/bsd/Makefile.in b/src/appl/bsd/Makefile.in
deleted file mode 100644
index 5ec3c950fb..0000000000
--- a/src/appl/bsd/Makefile.in
+++ /dev/null
@@ -1,84 +0,0 @@
-thisconfigdir=.
-myfulldir=appl/bsd
-mydir=.
-BUILDTOP=$(REL)..$(S)..
-PROG_LIBPATH=-L$(TOPLIBD)
-PROG_RPATH=$(KRB5_LIBDIR)
-
-SETENVSRC=@SETENVSRC@
-SETENVOBJ=@SETENVOBJ@
-
-LOGINLIBS=@LOGINLIBS@
-LIBOBJS=@LIBOBJS@
-KRSHDLIBS=@KRSHDLIBS@
-
-SRCS= $(srcdir)/krcp.c $(srcdir)/krlogin.c $(srcdir)/krsh.c $(srcdir)/kcmd.c \
- $(srcdir)/forward.c $(srcdir)/login.c $(srcdir)/krshd.c \
- $(srcdir)/krlogind.c
-OBJS= krcp.o krlogin.o krsh.o kcmd.o forward.o $(SETENVOBJ) login.o krshd.o \
- krlogind.o $(LIBOBJS)
-
-UCB_RLOGIN = @UCB_RLOGIN@
-UCB_RSH = @UCB_RSH@
-UCB_RCP = @UCB_RCP@
-
-RSH= -DKRB5_PATH_RLOGIN=\"$(CLIENT_BINDIR)/rlogin\"
-BSD= -DUCB_RLOGIN=\"$(UCB_RLOGIN)\" \
- -DUCB_RSH=\"$(UCB_RSH)\" -DUCB_RCP=\"$(UCB_RCP)\"
-
-DEFINES = $(RSH) $(BSD) $(RPROGS) -DKERBEROS \
- -DLOGIN_PROGRAM=\"$(SERVER_BINDIR)/login.krb5\" -DKPROGDIR=\"$(CLIENT_BINDIR)\" \
- -DHEIMDAL_FRIENDLY
-
-all:: rsh rcp rlogin kshd klogind login.krb5
-
-clean::
- $(RM) rsh rcp rlogin kshd klogind login.krb5
-
-rsh: krsh.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o rsh krsh.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_LIBS)
-
-rcp: krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o rcp krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_LIBS)
-
-rlogin: krlogin.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o rlogin krlogin.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB5_BASE_LIBS)
-
-install::
- for f in rsh rcp rlogin; do \
- ($(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(CLIENT_BINDIR)/`echo $$f|sed '$(transform)'` && \
- $(INSTALL_DATA) $(srcdir)/$$f.M \
- ${DESTDIR}$(CLIENT_MANDIR)/`echo $$f|sed '$(transform)'`.1 \
- ) || exit 1; \
- done
-
-kshd: krshd.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB)
- $(CC_LINK) -o kshd krshd.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRSHDLIBS) $(PTY_LIB) $(UTIL_LIB) $(KRB5_BASE_LIBS) $(APPUTILS_LIB)
-
-klogind: krlogind.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB)
- $(CC_LINK) -o klogind krlogind.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_LIB) $(UTIL_LIB) $(KRB5_BASE_LIBS) $(APPUTILS_LIB)
-
-install::
- for f in kshd klogind; do \
- ($(INSTALL_PROGRAM) $$f \
- $(DESTDIR)$(SERVER_BINDIR)/`echo $$f|sed '$(transform)'` && \
- $(INSTALL_DATA) $(srcdir)/$$f.M \
- ${DESTDIR}$(SERVER_MANDIR)/`echo $$f|sed '$(transform)'`.8 \
- ) || exit 1 ; \
- done
-
-# No program name transformation is done with login.krb5 since it is directly
-# referenced by klogind.
-#
-login.krb5: login.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB5_BASE_DEPLIBS)
- $(CC_LINK) -o login.krb5 login.o $(SETENVOBJ) $(LIBOBJS) $(LOGINLIBS) $(PTY_LIB) $(KRB5_BASE_LIBS)
-
-install::
- $(INSTALL_PROGRAM) login.krb5 $(DESTDIR)$(SERVER_BINDIR)/login.krb5
- $(INSTALL_DATA) $(srcdir)/login.M \
- ${DESTDIR}$(SERVER_MANDIR)/login.krb5.8
-
-getdtablesize.o: $(srcdir)/getdtablesize.c
-
-kcmd.o krcp.o krlogin.o krlogind.o krsh.o krshd.o forward.o: defines.h
diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in
deleted file mode 100644
index 330c87d514..0000000000
--- a/src/appl/bsd/configure.in
+++ /dev/null
@@ -1,159 +0,0 @@
-K5_AC_INIT(krlogind.c)
-CONFIG_RULES
-KRB5_AC_INET6
-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,1,[Define if setpag should be used])
- 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
-save_LIBS="$LIBS"
- LIBS=
- AC_CHECK_LIB(crypt,crypt)
- LOGINLIBS="$LOGINLIBS $LIBS"
-LIBS="$save_LIBS"
-dnl
-dnl AIX has them all; SCO might too
-AC_CHECK_LIB(odm,main,
- AC_CHECK_LIB(s,main,
- AC_CHECK_LIB(cfg,main,
- LOGINLIBS="$LOGINLIBS -lodm -ls -lcfg"
- )))
-dnl
-dnl Make our operating system-specific security checks and definitions for
-dnl login.
-dnl
-case $krb5_cv_host in
-*-*-aix3*)
- # AIX has streams include files but not streams TTY
- # Moreover, strops.h trashes sys/ioctl.h
- krb5_cv_has_streams=no
- ;;
-alpha*-dec-osf*)
- AC_CHECK_LIB(security,setluid,
- AC_DEFINE(HAVE_SETLUID,1,[Define if setluid is supplied by the OSF/1 security library])
- LOGINLIBS="$LOGINLIBS -lsecurity"
- )
- ;;
-esac
-dnl
-KRSHDLIBS="$LOGINLIBS"
-dnl
-AC_SUBST(KRSHDLIBS)
-AC_SUBST(LOGINLIBS)
-dnl
-AC_FUNC_VFORK
-AC_TYPE_MODE_T
-AC_CHECK_FUNCS(isatty inet_aton getenv gettosbyname killpg initgroups setpriority setreuid setresuid waitpid setsid ptsname setlogin tcgetpgrp tcsetpgrp setpgid strsave utimes rmufile rresvport_af)
-AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h sys/ptyvar.h utmp.h sys/time.h sys/ioctl_compat.h paths.h arpa/nameser.h)
-AC_HEADER_STDARG
-AC_REPLACE_FUNCS(getdtablesize)
-dnl
-KRB5_AC_NEED_DAEMON
-dnl
-KRB5_SIGTYPE
-CHECK_SIGNALS
-CHECK_SETJMP
-CHECK_DIRENT
-CHECK_WAIT_TYPE
-AC_CHECK_HEADER(termios.h,[AC_CHECK_FUNC(cfsetispeed,AC_DEFINE(POSIX_TERMIOS,1,[Define if POSIX-compatible termios interface is found]))])
-CHECK_UTMP
-KRB5_GETSOCKNAME_ARGS
-dnl
-dnl Check for where the BSD rlogin, rcp, and rsh programs live.
-dnl
-save_path=$PATH
-ifdef([_AC_PROG_ECHO], [_AC_PROG_ECHO])
-ifdef([AC_PROG_ECHO_N], [AC_PROG_ECHO_N])
-AC_ARG_ENABLE([athena],
-[ --enable-athena build with MIT Project Athena configuration],
-[PATH=/usr/athena/bin:/bin:/usr/bin:/usr/bsd:/usr/ucb],
-[PATH=/bin:/usr/bin:/usr/bsd:/usr/ucb])
-AC_PATH_PROG(UCB_RLOGIN,rlogin,/usr/ucb/rlogin)
-AC_PATH_PROG(UCB_RSH,rsh,/usr/ucb/rsh)
-AC_PATH_PROG(UCB_RCP,rcp,/usr/ucb/rcp)
-PATH=$save_path
-ifdef([_AC_PROG_ECHO], [_AC_PROG_ECHO])
-ifdef([AC_PROG_ECHO_N], [AC_PROG_ECHO_N])
-dnl
-dnl
-AC_MSG_CHECKING([streams interface])
-AC_CACHE_VAL(krb5_cv_has_streams,
-[AC_TRY_COMPILE(
-[#include <sys/stream.h>
-#include <sys/stropts.h>], [],
-krb5_cv_has_streams=yes, krb5_cv_has_streams=no)])
-AC_MSG_RESULT($krb5_cv_has_streams)
-if test $krb5_cv_has_streams = yes; then
-AC_DEFINE(HAVE_STREAMS,1,[Define if the OS uses streams])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([F_SETOWN])
-AC_CACHE_VAL(krb5_cv_f_setown,
-[AC_TRY_COMPILE(
-[#include <sys/types.h>
-#include <fcntl.h>], [1+F_SETOWN;],
-krb5_cv_f_setown=yes,krb5_cv_f_setown=no)])
-AC_MSG_RESULT($krb5_cv_f_setown)
-if test $krb5_cv_f_setown = yes; then
-AC_DEFINE(HAVE_SETOWN,1,[Define if F_SETOWN is available])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([setenv])
-AC_CACHE_VAL(krb5_cv_setenv,
-[AC_TRY_LINK(
-[],[setenv("PATH","/bin",0);],
-krb5_cv_setenv=yes,krb5_cv_setenv=no)])
-AC_MSG_RESULT($krb5_cv_setenv)
-if test $krb5_cv_setenv = no; then
-SETENVSRC=setenv.c
-SETENVOBJ=setenv.o
-AC_SUBST([SETENVSRC])
-AC_SUBST([SETENVOBJ])
-AC_DEFINE([NEED_SETENV],1,[Define if setenv needs to be defined])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([number of arguments to setpgrp])
-AC_CACHE_VAL(krb5_cv_setpgrp_args,
-[AC_TRY_COMPILE(
-[#ifndef __STDC__
-#define __STDC__ 1
-#endif
-#include <unistd.h>],[setpgrp(0,0)],
-krb5_cv_setpgrp_args=two, krb5_cv_setpgrp_args=void)])
-AC_MSG_RESULT($krb5_cv_setpgrp_args)
-if test $krb5_cv_setpgrp_args = two; then
-AC_DEFINE(SETPGRP_TWOARG,1,[Define if setpgrp takes two arguments])
-fi
-dnl
-dnl
-AC_MSG_CHECKING([shadow password support])
-AC_CACHE_VAL(krb5_cv_shadow_pwd,
-[AC_TRY_LINK(
-[#include <sys/types.h>
-#include <pwd.h>
-#include <shadow.h>],
-[struct spwd *sp = getspnam("root")],
-krb5_cv_shadow_pwd=yes, krb5_cv_shadow_pwd=no)])
-AC_MSG_RESULT($krb5_cv_shadow_pwd)
-if test $krb5_cv_shadow_pwd = yes; then
-AC_DEFINE(HAVE_SHADOW,1,[Define if shadow password interface is available])
-fi
-dnl
-dnl
-K5_AC_CHECK_FILES(/etc/environment /etc/TIMEZONE)
-dnl
-dnl
-AC_C_CONST
-
-KRB5_AC_LIBUTIL
-KRB5_BUILD_PROGRAM
-V5_AC_OUTPUT_MAKEFILE
diff --git a/src/appl/bsd/defines.h b/src/appl/bsd/defines.h
deleted file mode 100644
index b565cd87d4..0000000000
--- a/src/appl/bsd/defines.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#define OPTS_FORWARD_CREDS 0x00000020
-#define OPTS_FORWARDABLE_CREDS 0x00000010
-#define RCMD_BUFSIZ 5120
-
-enum kcmd_proto {
- /* Old protocol: DES encryption only. No subkeys. No protection
- for cleartext length. No ivec supplied. OOB hacks used for
- rlogin. Checksum may be omitted at connection startup. */
- KCMD_OLD_PROTOCOL = 1,
- /* New protocol: Any encryption scheme. Client-generated subkey
- required. Prepend cleartext-length to cleartext data (but don't
- include it in count). Starting ivec defined, chained. In-band
- signalling. Checksum required. */
- KCMD_NEW_PROTOCOL,
- /* Hack: Get credentials, and use the old protocol iff the session
- key type is single-DES. */
- KCMD_PROTOCOL_COMPAT_HACK,
- /* Using Kerberos version 4. */
- KCMD_V4_PROTOCOL,
- /* ??? */
- KCMD_UNKNOWN_PROTOCOL
-};
-
-extern int kcmd (int *sock, char **ahost, int /* u_short */ rport,
- char *locuser, char *remuser, char *cmd,
- int *fd2p, char *service, char *realm,
- krb5_creds **cred,
- krb5_int32 *seqno, krb5_int32 *server_seqno,
- struct sockaddr_in *laddr,
- struct sockaddr_in *faddr,
- krb5_auth_context *authconp,
- krb5_flags authopts,
- int anyport, int suppress_err,
- enum kcmd_proto *protonum /* input and output */
- );
-
-extern int rcmd_stream_read (int fd, char *buf, size_t len, int secondary);
-extern int rcmd_stream_write (int fd, char *buf, size_t len, int secondary);
-extern int getport (int * /* portnum */, int * /* addrfamily */);
-
-extern void rcmd_stream_init_krb5 (krb5_keyblock *in_keyblock,
- int encrypt_flag, int lencheck,
- int am_client, enum kcmd_proto protonum);
-
-extern void rcmd_stream_init_normal(void);
-
-#ifndef HAVE_STRSAVE
-extern char *strsave(const char *sp);
-#endif
-
-krb5_error_code rd_and_store_for_creds(krb5_context context,
- krb5_auth_context auth_context,
- krb5_data *inbuf, krb5_ticket *ticket,
- krb5_ccache *ccache);
-
-
-int princ_maps_to_lname(krb5_principal principal, char *luser);
-int default_realm(krb5_principal principal);
-
-#ifdef NEED_SETENV
-extern int setenv(char *, char *, int);
-#endif
-
-#include "fake-addrinfo.h"
-
-#ifdef KRB_DEFS
-krb5_error_code krb5_compat_recvauth(krb5_context, krb5_auth_context *,
- krb5_pointer, char *, krb5_principal,
- krb5_int32, krb5_keytab,
- krb5_int32, char *, char *,
- struct sockaddr_in *,
- struct sockaddr_in *, char *,
- krb5_ticket **, krb5_int32 *,
- AUTH_DAT **, Key_schedule, char *);
-
-krb5_error_code
-krb5_compat_recvauth_version(krb5_context, krb5_auth_context *,
- krb5_pointer, krb5_principal, krb5_int32,
- krb5_keytab, krb5_int32, char *, char *,
- struct sockaddr_in *, struct sockaddr_in *,
- char *, krb5_ticket **, krb5_int32*,
- AUTH_DAT **, Key_schedule, krb5_data *);
-#endif
-
-#include "port-sockets.h"
diff --git a/src/appl/bsd/deps b/src/appl/bsd/deps
deleted file mode 100644
index f83d52390d..0000000000
--- a/src/appl/bsd/deps
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# Generated makefile dependencies follow.
-#
-$(OUTPRE)krcp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/krb5.h \
- $(SRCTOP)/include/krb5/authdata_plugin.h $(SRCTOP)/include/krb5/locate_plugin.h \
- $(SRCTOP)/include/krb5/preauth_plugin.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h defines.h krcp.c
-$(OUTPRE)krlogin.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h defines.h krlogin.c \
- rpaths.h
-$(OUTPRE)krsh.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/port-sockets.h \
- $(SRCTOP)/include/socket-utils.h defines.h krsh.c
-$(OUTPRE)kcmd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h kcmd.c
-$(OUTPRE)forward.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \
- $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h forward.c
-$(OUTPRE)login.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/k5-buf.h $(SRCTOP)/include/k5-err.h \
- $(SRCTOP)/include/k5-gmt_mktime.h $(SRCTOP)/include/k5-int-pkinit.h \
- $(SRCTOP)/include/k5-int.h $(SRCTOP)/include/k5-platform.h \
- $(SRCTOP)/include/k5-plugin.h $(SRCTOP)/include/k5-thread.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- login.c loginpaths.h
-$(OUTPRE)krshd.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/k5-buf.h \
- $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \
- $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/k5-util.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h krshd.c loginpaths.h
-$(OUTPRE)krlogind.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/libpty.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/k5-buf.h \
- $(SRCTOP)/include/k5-err.h $(SRCTOP)/include/k5-gmt_mktime.h \
- $(SRCTOP)/include/k5-int-pkinit.h $(SRCTOP)/include/k5-int.h \
- $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-plugin.h \
- $(SRCTOP)/include/k5-thread.h $(SRCTOP)/include/k5-util.h \
- $(SRCTOP)/include/krb5.h $(SRCTOP)/include/krb5/authdata_plugin.h \
- $(SRCTOP)/include/krb5/locate_plugin.h $(SRCTOP)/include/krb5/preauth_plugin.h \
- $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \
- defines.h krlogind.c
diff --git a/src/appl/bsd/forward.c b/src/appl/bsd/forward.c
deleted file mode 100644
index ad0680cd76..0000000000
--- a/src/appl/bsd/forward.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * appl/bsd/forward.c
- */
-
-/*
- * Copyright (c) 1983 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(KERBEROS) || defined(KRB5)
-#include <stdio.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "k5-int.h"
-
-#include "defines.h"
-
-/* Decode, decrypt and store the forwarded creds in the local ccache. */
-krb5_error_code
-rd_and_store_for_creds(context, auth_context, inbuf, ticket, ccache)
- krb5_context context;
- krb5_auth_context auth_context;
- krb5_data *inbuf;
- krb5_ticket *ticket;
- krb5_ccache *ccache;
-{
- krb5_creds ** creds;
- krb5_error_code retval;
- char ccname[35];
-
- *ccache = NULL;
-
- retval = krb5_rd_cred(context, auth_context, inbuf, &creds, NULL);
- if (retval)
- return(retval);
-
- /* Set the KRB5CCNAME ENV variable to keep sessions
- * seperate. Use the process id of this process which is
- * the rlogind or rshd. Set the environment variable as well.
- */
-
- snprintf(ccname, sizeof(ccname), "FILE:/tmp/krb5cc_p%ld", (long) getpid());
- setenv("KRB5CCNAME", ccname, 1);
-
- retval = krb5_cc_resolve(context, ccname, ccache);
- if (retval)
- goto cleanup;
-
- retval = krb5_cc_initialize(context, *ccache, ticket->enc_part2->client);
- if (retval)
- goto cleanup;
-
- retval = krb5_cc_store_cred(context, *ccache, *creds);
- if (retval)
- goto cleanup;
-
-cleanup:
- krb5_free_creds(context, *creds);
- return retval;
-}
-
-#endif /* KERBEROS */
diff --git a/src/appl/bsd/getdtablesize.c b/src/appl/bsd/getdtablesize.c
deleted file mode 100644
index 244616cc99..0000000000
--- a/src/appl/bsd/getdtablesize.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <limits.h>
-
-#ifdef _SC_OPEN_MAX
-int getdtablesize() {
- return sysconf(_SC_OPEN_MAX);
-}
-#else
-#include <sys/resource.h>
-/* Placed in the Public Domain by Mark Eichin, Cygnus Support 1994 */
-
-int getdtablesize() {
- struct rlimit rl;
- getrlimit(RLIMIT_NOFILE, &rl);
- return rl.rlim_cur;
-}
-#endif
diff --git a/src/appl/bsd/kcmd.c b/src/appl/bsd/kcmd.c
deleted file mode 100644
index 276c7038f3..0000000000
--- a/src/appl/bsd/kcmd.c
+++ /dev/null
@@ -1,1035 +0,0 @@
-/*
- * appl/bsd/kcmd.c
- */
-
-/*
- * Copyright (c) 1983 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.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * 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.
- */
-
-/* derived from @(#)rcmd.c 5.17 (Berkeley) 6/27/88 */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <pwd.h>
-#include <sys/param.h>
-#ifndef _TYPES_
-#include <sys/types.h>
-#define _TYPES_
-#endif
-#include <fcntl.h>
-
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 1024
-#endif
-#include <signal.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#ifdef _AIX
-#include <sys/select.h>
-#endif
-
-#ifndef POSIX_SIGNALS
-#ifndef sigmask
-#define sigmask(m) (1 << ((m)-1))
-#endif
-#endif
-
-#ifndef roundup
-#define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
-#endif
-
-#include <netinet/in.h>
-#include <netdb.h>
-
-#include <errno.h>
-#include "k5-int.h"
-
-#include "defines.h"
-
-extern krb5_context bsd_context;
-
-
-#define START_PORT 5120 /* arbitrary */
-char *default_service = "host";
-
-#define KCMD_KEYUSAGE 1026 /* Key usage used with 3des or any old-protocol enctype*/
-/* New protocol enctypes that use cipher state have keyusage defined later*/
-
-#ifndef GETSOCKNAME_ARG3_TYPE
-#define GETSOCKNAME_ARG3_TYPE int
-#endif
-
-/*
- * Note that the encrypted rlogin packets take the form of a four-byte
- * length followed by encrypted data. On writing the data out, a significant
- * performance penalty is suffered (at least one RTT per character, two if we
- * are waiting for a shell to echo) by writing the data separately from the
- * length. So, unlike the input buffer, which just contains the output
- * data, the output buffer represents the entire packet.
- */
-
-static char des_inbuf[2*RCMD_BUFSIZ]; /* needs to be > largest read size */
-static char des_outpkt[2*RCMD_BUFSIZ+4]; /* needs to be > largest write size */
-static krb5_data desinbuf;
-static krb5_data desoutbuf;
-
-/* XXX Overloaded: use_ivecs!=0 -> new protocol, inband signalling, etc. */
-static int use_ivecs;
-static krb5_keyusage enc_keyusage_i[2], enc_keyusage_o[2];
-static krb5_data encivec_i[2], encivec_o[2];
-
-static krb5_keyblock *keyblock; /* key for encrypt/decrypt */
-static int (*input)(int, char *, size_t, int);
-static int (*output)(int, char *, size_t, int);
-static char storage[2*RCMD_BUFSIZ]; /* storage for the decryption */
-static size_t nstored = 0;
-static char *store_ptr = storage;
-static int twrite(int, char *, size_t, int);
-static int v5_des_read(int, char *, size_t, int),
- v5_des_write(int, char *, size_t, int);
-static int do_lencheck;
-
-#ifdef POSIX_SIGNALS
-typedef sigset_t masktype;
-#else
-typedef sigmasktype masktype;
-#endif
-
-static void
-block_urgent (masktype *oldmask)
-{
-#ifdef POSIX_SIGNALS
- sigset_t urgmask;
-
- sigemptyset(&urgmask);
- sigaddset(&urgmask, SIGURG);
- sigprocmask(SIG_BLOCK, &urgmask, oldmask);
-#else
- *oldmask = sigblock(sigmask(SIGURG));
-#endif /* POSIX_SIGNALS */
-}
-
-static void
-restore_sigs (masktype *oldmask)
-{
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0);
-#else
- sigsetmask(*oldmask);
-#endif /* POSIX_SIGNALS */
-}
-
-static int
-kcmd_connect (int *sp, int *addrfamilyp, struct sockaddr_in *sockinp,
- char *hname, char **host_save, unsigned int rport, int *lportp,
- struct sockaddr_in *laddrp)
-{
- int s, aierr;
- struct addrinfo *ap, *ap2, aihints;
- char rport_buf[10];
- GETSOCKNAME_ARG3_TYPE sin_len;
-
- if (rport == 0) {
- fprintf(stderr, "can't connect to %s port 0\n", hname);
- return -1;
- }
- snprintf(rport_buf, sizeof(rport_buf), "%d", ntohs(rport));
- memset(&aihints, 0, sizeof(aihints));
- aihints.ai_socktype = SOCK_STREAM;
- aihints.ai_flags = AI_CANONNAME;
- aihints.ai_family = *addrfamilyp;
- aierr = getaddrinfo(hname, rport_buf, &aihints, &ap);
- if (aierr) {
- const char *msg;
- /* We want to customize some messages. */
- switch (aierr) {
- case EAI_NONAME:
- msg = "host unknown";
- break;
- default:
- fprintf(stderr, "foo\n");
- msg = gai_strerror(aierr);
- break;
- }
- fprintf(stderr, "%s: %s\n", hname, msg);
- return -1;
- }
- if (ap == 0) {
- fprintf(stderr, "%s: no addresses?\n", hname);
- return -1;
- }
-
- *host_save = strdup(ap->ai_canonname ? ap->ai_canonname : hname);
-
- for (ap2 = ap; ap; ap = ap->ai_next) {
- char hostbuf[NI_MAXHOST];
- char portbuf[NI_MAXSERV];
- int oerrno;
- int af = ap->ai_family;
-
- /* @@ Debugging. Yuck. */
- switch (af) {
- case AF_INET:
- if (((struct sockaddr_in *)ap->ai_addr)->sin_port == 0) {
- fprintf(stderr, "internal error: got ipv4 address but port zero?\n");
- continue;
- }
- break;
-#ifdef KRB5_USE_INET6
- case AF_INET6:
- if (((struct sockaddr_in6 *)ap->ai_addr)->sin6_port == 0) {
- fprintf(stderr, "internal error: got ipv6 address but port zero?\n");
- continue;
- }
- break;
-#endif
- }
-
- for (;;) {
- s = getport(lportp, &af);
- if (s < 0) {
- if (errno == EAGAIN)
- fprintf(stderr, "socket: All ports in use\n");
- else
- perror("kcmd: socket");
- return -1;
- }
- if (connect(s, ap->ai_addr, ap->ai_addrlen) >= 0)
- goto connected;
- (void) close(s);
- if (errno != EADDRINUSE)
- break;
- if (lportp)
- (*lportp)--;
- }
-
- oerrno = errno;
- aierr = getnameinfo(ap->ai_addr, ap->ai_addrlen,
- hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (aierr)
- fprintf(stderr, "connect to <error formatting address: %s>: ",
- gai_strerror (aierr));
- else
- fprintf(stderr, "connect to address %s port %s: ", hostbuf,
- portbuf);
- errno = oerrno;
- perror(0);
-
- if (ap->ai_next)
- fprintf(stderr, "Trying next address...\n");
- }
- freeaddrinfo(ap2);
- return -1;
-
-connected:
- sin_len = sizeof(struct sockaddr_in);
- if (getsockname(s, (struct sockaddr *)laddrp, &sin_len) < 0) {
- perror("getsockname");
- close(s);
- return -1;
- }
-
- *sp = s;
- *sockinp = *(struct sockaddr_in *) ap->ai_addr;
- *addrfamilyp = ap->ai_family;
- freeaddrinfo(ap2);
- return 0;
-}
-
-static int
-setup_secondary_channel (int s, int *fd2p, int *lportp, int *addrfamilyp,
- struct sockaddr_in *fromp, int anyport)
-{
- if (fd2p == 0) {
- write(s, "", 1);
- *lportp = 0;
- } else {
- char num[8];
- socklen_t len = sizeof (*fromp);
- size_t slen;
- int s2 = getport(lportp, addrfamilyp), s3;
- fd_set rfds, xfds;
- struct timeval waitlen;
- int n;
-
- *fd2p = -1;
- if (s2 < 0)
- return -1;
- FD_ZERO(&rfds);
- FD_ZERO(&xfds);
- FD_SET(s, &rfds);
- FD_SET(s, &xfds);
- listen(s2, 1);
- FD_SET(s2, &rfds);
- (void) snprintf(num, sizeof(num), "%d", *lportp);
- slen = strlen(num)+1;
- if (write(s, num, slen) != slen) {
- perror("write: setting up stderr");
- (void) close(s2);
- return -1;
- }
- waitlen.tv_sec = 600; /* long, but better than infinite */
- waitlen.tv_usec = 0;
- n = (s < s2) ? s2 : s;
- n = select(n+1, &rfds, 0, &xfds, &waitlen);
- if (n <= 0) {
- /* timeout or error */
- fprintf(stderr, "timeout in circuit setup\n");
- close(s2);
- *fd2p = -1;
- return -1;
- } else {
- if (FD_ISSET(s, &rfds) || FD_ISSET(s, &xfds)) {
- fprintf(stderr, "socket: protocol error or closed connection in circuit setup\n");
- close(s2);
- *fd2p = -1;
- return -1;
- }
- /* ready to accept a connection; yay! */
- }
- s3 = accept(s2, (struct sockaddr *)fromp, &len);
- (void) close(s2);
- if (s3 < 0) {
- perror("accept");
- *lportp = 0;
- return -1;
- }
- *fd2p = s3;
- fromp->sin_port = ntohs(fromp->sin_port);
- /* This check adds nothing when using Kerberos. */
- if (! anyport &&
- (fromp->sin_family != AF_INET ||
- fromp->sin_port >= IPPORT_RESERVED)) {
- fprintf(stderr, "socket: protocol failure in circuit setup.\n");
- close(s3);
- *fd2p = -1;
- return -1;
- }
- }
- return 0;
-}
-
-int
-kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm,
- cred, seqno, server_seqno, laddr, faddr, authconp, authopts, anyport,
- suppress_err, protonump)
- int *sock;
- char **ahost;
- u_short rport;
- char *locuser, *remuser, *cmd;
- int *fd2p;
- char *service;
- char *realm;
- krb5_creds **cred; /* output only */
- krb5_int32 *seqno;
- krb5_int32 *server_seqno;
- struct sockaddr_in *laddr, *faddr;
- krb5_auth_context *authconp;
- krb5_flags authopts;
- int anyport;
- int suppress_err; /* Don't print if authentication fails */
- enum kcmd_proto *protonump;
-{
- int s;
- masktype oldmask;
- struct sockaddr_in sockin, from, local_laddr;
- krb5_creds *get_cred = 0, *ret_cred = 0;
- char c;
- int lport;
- int rc;
- char *host_save;
- krb5_error_code status;
- krb5_ap_rep_enc_part *rep_ret;
- krb5_error *error = 0;
- krb5_ccache cc;
- krb5_data outbuf;
- krb5_flags options = authopts;
- krb5_auth_context auth_context = NULL;
- char *cksumbuf;
- krb5_data cksumdat;
- char *kcmd_version;
- enum kcmd_proto protonum = *protonump;
- int addrfamily = /* AF_INET */0;
-
- if (asprintf(&cksumbuf, "%u:%s%s", ntohs(rport), cmd, remuser) < 0) {
- fprintf(stderr, "Unable to allocate memory for checksum buffer.\n");
- return(-1);
- }
- cksumdat.data = cksumbuf;
- cksumdat.length = strlen(cksumbuf);
-
- block_urgent(&oldmask);
-
- if (!laddr) laddr = &local_laddr;
- if (kcmd_connect(&s, &addrfamily, &sockin, *ahost, &host_save, rport, 0, laddr) == -1) {
- restore_sigs(&oldmask);
- return -1;
- }
- *ahost = host_save;
- /* If no service is given set to the default service */
- if (!service) service = default_service;
-
- if (!(get_cred = (krb5_creds *)calloc(1, sizeof(krb5_creds)))) {
- fprintf(stderr,"kcmd: no memory\n");
- return(-1);
- }
- status = krb5_sname_to_principal(bsd_context, host_save, service,
- KRB5_NT_SRV_HST, &get_cred->server);
- if (status) {
- fprintf(stderr, "kcmd: krb5_sname_to_principal failed: %s\n",
- error_message(status));
- return(-1);
- }
-
- if (realm && *realm) {
- status = krb5_set_principal_realm(bsd_context, get_cred->server,
- realm);
- if (status) {
- fprintf(stderr, "kcmd: krb5_set_principal_realm failed %s\n",
- error_message(status));
- return(-1);
- }
- }
- status = setup_secondary_channel(s, fd2p, &lport, &addrfamily, &from,
- anyport);
- if (status)
- goto bad;
-
- if (faddr)
- *faddr = sockin;
-
- status = krb5_cc_default(bsd_context, &cc);
- if (status)
- goto bad2;
-
- status = krb5_cc_get_principal(bsd_context, cc, &get_cred->client);
- if (status) {
- (void) krb5_cc_close(bsd_context, cc);
- goto bad2;
- }
-
- /* Get ticket from credentials cache or kdc */
- status = krb5_get_credentials(bsd_context, 0, cc, get_cred, &ret_cred);
- krb5_free_creds(bsd_context, get_cred);
- (void) krb5_cc_close(bsd_context, cc);
- if (status) {
- fprintf (stderr, "error getting credentials: %s\n",
- error_message (status));
- goto bad2;
- }
-
- /* Reset internal flags; these should not be sent. */
- authopts &= (~OPTS_FORWARD_CREDS);
- authopts &= (~OPTS_FORWARDABLE_CREDS);
-
- if (krb5_auth_con_init(bsd_context, &auth_context))
- goto bad2;
-
- if (krb5_auth_con_set_req_cksumtype(bsd_context, auth_context, CKSUMTYPE_RSA_MD5) !=0 )
- goto bad2;
- if (krb5_auth_con_setflags(bsd_context, auth_context,
- KRB5_AUTH_CONTEXT_RET_TIME))
- goto bad2;
-
- /* Only need local address for mk_cred() to send to krlogind */
- status = krb5_auth_con_genaddrs(bsd_context, auth_context, s,
- KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
- if (status)
- goto bad2;
-
- if (protonum == KCMD_PROTOCOL_COMPAT_HACK) {
- krb5_boolean is_des;
- status = krb5_c_enctype_compare (bsd_context, ENCTYPE_DES_CBC_CRC,
- ret_cred->keyblock.enctype, &is_des);
- if (status)
- goto bad2;
- protonum = is_des ? KCMD_OLD_PROTOCOL : KCMD_NEW_PROTOCOL;
- }
-
- switch (protonum) {
- case KCMD_NEW_PROTOCOL:
- authopts |= AP_OPTS_USE_SUBKEY;
- kcmd_version = "KCMDV0.2";
- break;
- case KCMD_OLD_PROTOCOL:
- kcmd_version = "KCMDV0.1";
- break;
- default:
- status = EINVAL;
- goto bad2;
- }
-
- /* Call Kerberos library routine to obtain an authenticator,
- pass it over the socket to the server, and obtain mutual
- authentication. */
- status = krb5_sendauth(bsd_context, &auth_context, (krb5_pointer) &s,
- kcmd_version, ret_cred->client, ret_cred->server,
- authopts, &cksumdat, ret_cred, 0,
- &error, &rep_ret, NULL);
- free(cksumbuf);
- if (status) {
- if (!suppress_err)
- fprintf(stderr, "Couldn't authenticate to server: %s\n",
- error_message(status));
- if (error) {
- if (!suppress_err) {
- fprintf(stderr, "Server returned error code %d (%s)\n",
- error->error,
- error_message(ERROR_TABLE_BASE_krb5 +
- (int) error->error));
- if (error->text.length) {
- fprintf(stderr, "Error text sent from server: %s\n",
- error->text.data);
- }
- }
- krb5_free_error(bsd_context, error);
- error = 0;
- }
- }
- if (status) goto bad2;
- if (rep_ret && server_seqno) {
- *server_seqno = rep_ret->seq_number;
- krb5_free_ap_rep_enc_part(bsd_context, rep_ret);
- }
-
- (void) write(s, remuser, strlen(remuser)+1);
- (void) write(s, cmd, strlen(cmd)+1);
- (void) write(s, locuser, strlen(locuser)+1);
-
- if (options & OPTS_FORWARD_CREDS) { /* Forward credentials */
- status = krb5_fwd_tgt_creds(bsd_context, auth_context,
- host_save,
- ret_cred->client, ret_cred->server,
- 0, options & OPTS_FORWARDABLE_CREDS,
- &outbuf);
- if (status) {
- fprintf(stderr, "kcmd: Error getting forwarded creds: %s\n",
- error_message(status));
- goto bad2;
- }
-
- /* Send forwarded credentials */
- status = krb5_write_message(bsd_context, (krb5_pointer)&s, &outbuf);
- if (status)
- goto bad2;
- }
- else { /* Dummy write to signal no forwarding */
- outbuf.length = 0;
- status = krb5_write_message(bsd_context, (krb5_pointer)&s, &outbuf);
- if (status)
- goto bad2;
- }
-
- if ((rc=read(s, &c, 1)) != 1) {
- if (rc==-1) {
- perror(*ahost);
- } else {
- fprintf(stderr,"kcmd: bad connection with remote host\n");
- }
- status = -1;
- goto bad2;
- }
- if (c != 0) {
- while (read(s, &c, 1) == 1) {
- (void) write(2, &c, 1);
- if (c == '\n')
- break;
- }
- status = -1;
- goto bad2;
- }
- restore_sigs(&oldmask);
- *sock = s;
- *protonump = protonum;
-
- /* pass back credentials if wanted */
- if (cred) krb5_copy_creds(bsd_context, ret_cred, cred);
- krb5_free_creds(bsd_context, ret_cred);
- if (authconp)
- *authconp = auth_context;
-
- return (0);
- bad2:
- if (lport)
- (void) close(*fd2p);
- bad:
- (void) close(s);
- restore_sigs(&oldmask);
- if (ret_cred)
- krb5_free_creds(bsd_context, ret_cred);
- return (status);
-}
-
-
-static int
-setup_socket (struct sockaddr *sa, GETSOCKNAME_ARG3_TYPE len)
-{
- int s;
-
- s = socket(sa->sa_family, SOCK_STREAM, 0);
- if (s < 0)
- return -1;
-
- if (bind(s, sa, len) < 0)
- return -1;
- if (getsockname(s, sa, &len) < 0) {
- close(s);
- return -1;
- }
- return s;
-}
-
-
-int
-getport(alport, family)
- int *alport, *family;
-{
- int s;
-
- if (*family == 0) {
-#ifdef KRB5_USE_INET6
- *family = AF_INET6;
- s = getport (alport, family);
- if (s >= 0)
- return s;
-#endif
- *family = AF_INET;
- }
-
-#ifdef KRB5_USE_INET6
- if (*family == AF_INET6) {
- struct sockaddr_in6 sockin6;
-
- memset(&sockin6, 0, sizeof(sockin6));
- sockin6.sin6_family = AF_INET6;
- sockin6.sin6_addr = in6addr_any;
-
- s = setup_socket((struct sockaddr *)&sockin6, sizeof (sockin6));
- if (s >= 0 && alport)
- *alport = ntohs(sockin6.sin6_port);
- return s;
- }
-#endif
-
- if (*family == AF_INET) {
- struct sockaddr_in sockin;
-
- memset(&sockin, 0, sizeof(sockin));
- sockin.sin_family = AF_INET;
- sockin.sin_addr.s_addr = INADDR_ANY;
-
- s = setup_socket((struct sockaddr *)&sockin, sizeof (sockin));
- if (s >= 0 && alport)
- *alport = ntohs(sockin.sin_port);
- return s;
- }
-
- return -1;
-}
-
-static int
-normal_read (int fd, char *buf, size_t len, int secondary)
-{
- return read (fd, buf, len);
-}
-
-void rcmd_stream_init_normal()
-{
- input = normal_read;
- output = twrite;
-}
-
-void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client,
- protonum)
- krb5_keyblock *in_keyblock;
- int encrypt_flag;
- int lencheck;
- int am_client;
- enum kcmd_proto protonum;
-{
- krb5_error_code status;
- size_t blocksize;
- int i;
- krb5_error_code ret;
-
- if (!encrypt_flag) {
- rcmd_stream_init_normal();
- return;
- }
- desinbuf.data = des_inbuf;
- desoutbuf.data = des_outpkt+4; /* Set up des buffers */
- keyblock = in_keyblock;
-
- do_lencheck = lencheck;
- input = v5_des_read;
- output = v5_des_write;
- enc_keyusage_i[0] = KCMD_KEYUSAGE;
- enc_keyusage_i[1] = KCMD_KEYUSAGE;
- enc_keyusage_o[0] = KCMD_KEYUSAGE;
- enc_keyusage_o[1] = KCMD_KEYUSAGE;
-
- if (protonum == KCMD_OLD_PROTOCOL) {
- use_ivecs = 0;
- return;
- }
-
- use_ivecs = 1;
- switch (in_keyblock->enctype) {
- /*
- * For the DES-based enctypes and the 3DES enctype we want to use
- * a non-zero IV because that's what we did. In the future we
- * use different keyusage for each channel and direction and a fresh
- * cipher state
- */
- case ENCTYPE_DES_CBC_CRC:
- case ENCTYPE_DES_CBC_MD4:
- case ENCTYPE_DES_CBC_MD5:
- case ENCTYPE_DES3_CBC_SHA1:
-
- status = krb5_c_block_size(bsd_context, keyblock->enctype,
- &blocksize);
- if (status) {
- /* XXX what do I do? */
- abort();
- }
-
- encivec_i[0].length = encivec_i[1].length = encivec_o[0].length
- = encivec_o[1].length = blocksize;
-
- if ((encivec_i[0].data = malloc(encivec_i[0].length * 4)) == NULL) {
- /* XXX what do I do? */
- abort();
- }
- encivec_i[1].data = encivec_i[0].data + encivec_i[0].length;
- encivec_o[0].data = encivec_i[1].data + encivec_i[0].length;
- encivec_o[1].data = encivec_o[0].data + encivec_i[0].length;
-
- /* is there a better way to initialize this? */
- memset(encivec_i[0].data, am_client, blocksize);
- memset(encivec_o[0].data, 1 - am_client, blocksize);
- memset(encivec_i[1].data, 2 | am_client, blocksize);
- memset(encivec_o[1].data, 2 | (1 - am_client), blocksize);
- break;
- default:
- if (am_client) {
- enc_keyusage_i[0] = 1028;
- enc_keyusage_i[1] = 1030;
- enc_keyusage_o[0] = 1032;
- enc_keyusage_o[1] = 1034;
- } else { /*am_client*/
- enc_keyusage_i[0] = 1032;
- enc_keyusage_i[1] = 1034;
- enc_keyusage_o[0] = 1028;
- enc_keyusage_o[1] = 1030;
- }
- for (i = 0; i < 2; i++) {
- ret = krb5_c_init_state (bsd_context, in_keyblock, enc_keyusage_i[i],
- &encivec_i[i]);
- if (ret)
- goto fail;
- ret = krb5_c_init_state (bsd_context, in_keyblock, enc_keyusage_o[i],
- &encivec_o[i]);
- if (ret)
- goto fail;
- }
- break;
- }
- return;
- fail:
- com_err ("kcmd", ret, "Initializing cipher state");
- abort();
- }
-
-int rcmd_stream_read(fd, buf, len, sec)
- int fd;
- register char *buf;
- size_t len;
- int sec;
-{
- return (*input)(fd, buf, len, sec);
-}
-
-int rcmd_stream_write(fd, buf, len, sec)
- int fd;
- register char *buf;
- size_t len;
- int sec;
-{
- return (*output)(fd, buf, len, sec);
-}
-
-/* Because of rcp lossage, translate fd 0 to 1 when writing. */
-static int twrite(fd, buf, len, secondary)
- int fd;
- char *buf;
- size_t len;
- int secondary;
-{
- return write((fd == 0) ? 1 : fd, buf, len);
-}
-
-static int v5_des_read(fd, buf, len, secondary)
- int fd;
- char *buf;
- size_t len;
- int secondary;
-{
- int nreturned = 0;
- size_t net_len,rd_len;
- int cc;
- unsigned char c;
- krb5_error_code ret;
- krb5_data plain;
- krb5_enc_data cipher;
-
- if (nstored >= len) {
- memcpy(buf, store_ptr, len);
- store_ptr += len;
- nstored -= len;
- return(len);
- } else if (nstored) {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- buf += nstored;
- len -= nstored;
- nstored = 0;
- }
-
- while (1) {
- cc = krb5_net_read(bsd_context, fd, &c, 1);
- /* we should check for non-blocking here, but we'd have
- to make it save partial reads as well. */
- if (cc <= 0) return cc; /* read error */
- if (cc == 1) {
- if (c == 0 || !do_lencheck) break;
- }
- }
-
- rd_len = c;
- if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
- if ((cc = krb5_net_read(bsd_context, fd, &c, 1)) != 1) return 0;
- rd_len = (rd_len << 8) | c;
-
- ret = krb5_c_encrypt_length(bsd_context, keyblock->enctype,
- use_ivecs ? rd_len + 4 : rd_len,
- &net_len);
- if (ret) {
- errno = ret;
- return(-1);
- }
-
- if ((net_len <= 0) || (net_len > sizeof(des_inbuf))) {
- /* preposterous length, probably out of sync */
- errno = EIO;
- return(-1);
- }
- if ((cc = krb5_net_read(bsd_context, fd, desinbuf.data, net_len)) != net_len) {
- /* probably out of sync */
- errno = EIO;
- return(-1);
- }
-
- cipher.enctype = ENCTYPE_UNKNOWN;
- cipher.ciphertext.length = net_len;
- cipher.ciphertext.data = desinbuf.data;
- plain.length = sizeof(storage);
- plain.data = storage;
-
- /* decrypt info */
- ret = krb5_c_decrypt(bsd_context, keyblock, enc_keyusage_i[secondary],
- use_ivecs ? encivec_i + secondary : 0,
- &cipher, &plain);
- if (ret) {
- /* probably out of sync */
- errno = EIO;
- return(-1);
- }
- store_ptr = storage;
- nstored = rd_len;
- if (use_ivecs) {
- int rd_len2;
- rd_len2 = storage[0] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[1] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[2] & 0xff;
- rd_len2 <<= 8; rd_len2 |= storage[3] & 0xff;
- if (rd_len2 != rd_len) {
- /* cleartext length trashed? */
- errno = EIO;
- return -1;
- }
- store_ptr += 4;
- }
- if (nstored > len) {
- memcpy(buf, store_ptr, len);
- nreturned += len;
- store_ptr += len;
- nstored -= len;
- } else {
- memcpy(buf, store_ptr, nstored);
- nreturned += nstored;
- nstored = 0;
- }
-
- return(nreturned);
-}
-
-
-
-static int v5_des_write(fd, buf, len, secondary)
- int fd;
- char *buf;
- size_t len;
- int secondary;
-{
- krb5_data plain;
- krb5_enc_data cipher;
- char tmpbuf[2*RCMD_BUFSIZ+8];
- unsigned char *len_buf = (unsigned char *) tmpbuf;
-
- if (use_ivecs) {
- unsigned char *lenbuf2 = (unsigned char *) tmpbuf;
- if (len + 4 > sizeof(tmpbuf))
- abort ();
- lenbuf2[0] = (len & 0xff000000) >> 24;
- lenbuf2[1] = (len & 0xff0000) >> 16;
- lenbuf2[2] = (len & 0xff00) >> 8;
- lenbuf2[3] = (len & 0xff);
- memcpy (tmpbuf + 4, buf, len);
-
- plain.data = tmpbuf;
- plain.length = len + 4;
- } else {
- plain.data = buf;
- plain.length = len;
- }
-
- cipher.ciphertext.length = sizeof(des_outpkt)-4;
- cipher.ciphertext.data = desoutbuf.data;
-
- if (krb5_c_encrypt(bsd_context, keyblock, enc_keyusage_o[secondary],
- use_ivecs ? encivec_o + secondary : 0,
- &plain, &cipher)) {
- errno = EIO;
- return(-1);
- }
-
- desoutbuf.length = cipher.ciphertext.length;
-
- len_buf = (unsigned char *) des_outpkt;
- len_buf[0] = (len & 0xff000000) >> 24;
- len_buf[1] = (len & 0xff0000) >> 16;
- len_buf[2] = (len & 0xff00) >> 8;
- len_buf[3] = (len & 0xff);
-
- if (write(fd, des_outpkt,desoutbuf.length+4) != desoutbuf.length+4){
- errno = EIO;
- return(-1);
- }
-
- else return(len);
-}
-
-
-#ifndef HAVE_STRSAVE
-/* Strsave was a routine in the version 4 krb library: we put it here
- for compatablilty with version 5 krb library, since kcmd.o is linked
- into all programs. */
-
-char *
-strsave(sp)
- const char *sp;
-{
- register char *ret;
-
- if((ret = strdup(sp)) == NULL) {
- fprintf(stderr, "no memory for saving args\n");
- exit(1);
- }
- return(ret);
-}
-#endif
-
-/* Server side authentication, etc */
-
-int princ_maps_to_lname(principal, luser)
- krb5_principal principal;
- char *luser;
-{
- char kuser[10];
- if (!(krb5_aname_to_localname(bsd_context, principal,
- sizeof(kuser), kuser))
- && (strcmp(kuser, luser) == 0)) {
- return 1;
- }
- return 0;
-}
-
-int default_realm(principal)
- krb5_principal principal;
-{
- char *def_realm;
- int retval;
-
- if ((retval = krb5_get_default_realm(bsd_context, &def_realm))) {
- return 0;
- }
-
- if (!data_eq_string(*krb5_princ_realm(bsd_context, principal),
- def_realm)) {
- free(def_realm);
- return 0;
- }
- free(def_realm);
- return 1;
-}
diff --git a/src/appl/bsd/klogind.M b/src/appl/bsd/klogind.M
deleted file mode 100644
index 574ae67b17..0000000000
--- a/src/appl/bsd/klogind.M
+++ /dev/null
@@ -1,174 +0,0 @@
-.\" Copyright (c) 1983 Regents of the University of California.
-.\" All rights reserved. The Berkeley software License Agreement
-.\" specifies the terms and conditions for redistribution.
-.\"
-.\" @(#)rlogind.8 6.3 (Berkeley) 5/24/86
-.\"
-.TH KLOGIND 8
-.SH NAME
-klogind \- remote login server
-.SH SYNOPSIS
-.B klogind
-[
-.B \-rcpPef
-]
-[[ \fB\-w\fP[\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP ]] ]
-[ \fB\-D\fP \fIport\fP ]
-.SH DESCRIPTION
-.I Klogind
-is the server for the
-.IR rlogin (1)
-program. The server is
-based on rlogind(8) but uses Kerberos authentication.
-.PP
-The
-.I klogind
-server is invoked by \fIinetd(8)\fP when it receives a connection on
-the port indicated in /etc/inetd.conf. A typical /etc/inetd.conf
-configuration line for \fIklogind\fP might be:
-
-klogin stream tcp nowait root /usr/cygnus/sbin/klogind klogind -e5c
-
-When a service request is received, the following protocol is initiated:
-
-.IP 1)
-Check authentication.
-.IP 2)
-Check authorization via the access-control files \fI.k5login\fP and
-\fI.klogin\fP in the user's home directory.
-.IP 3)
-Prompt for password if any checks fail and the \fI-p\fP option was supplied.
-.PP
-If the authentication succeeds, login the user by calling the accompanying
-login.krb5.
-.PP
-klogind allows Kerberos V5 authentication with the \fI.k5login\fP
-access control file to be trusted. If this authorization check is
-passed, then the user is allowed to log in. If the user has no
-\fI.k5login\fP file, the login will be authorized if the results of
-krb5_aname_to_localname conversion matches the account name. Unless
-special rules are configured, this will be true if and only if the
-Kerberos principal of the connecting user is in the default local
-realm and the principal portion matches the account name.
-.PP
-The configuration of \fIklogind\fP is done
-by command line arguments passed by inetd. The options are:
-
-.IP \fB\-P\fP
-Prompt the user for a password.
-If the -P option is passed, then the password is verified in addition
-to all other checks.
-
-.IP \fB\-e\fP
-Create an encrypted session.
-
-.IP \fB\-c\fP
-Require Kerberos V5 clients to present a cryptographic checksum of
-initial connection information like the name of the user that the
-client is trying to access in the initial authenticator. This
-checksum provides additionl security by preventing an attacker from
-changing the initial connection information. If this option is
-specified, older Kerberos V5 clients that do not send a checksum in
-the authenticator will not be able to authenticate to this server.
-This option is mutually exclusive with the \fB-i\fP option.
-
- If neither the \fB-c\fP or \fB-i\fP options are specified,then
-checksums are validated if presented. Since it is difficult to remove
-a checksum from an authenticator without making the authenticator
-invalid, this default mode is almost as significant of a security
-improvement as \fB-c\fP if new clients are used. It has the additional
-advantage of backwards compatability with some clients.
-Unfortunately, clients before Kerberos V5, Beta5, generate invalid
-checksums; if these clients are used, the \fB-i\fP option must be
-used.
-
-.IP \fB\-i\fP
-Ignore authenticator checksums if provided. This option
-ignore authenticator checksusm presented by current Kerberos clients
-to protect initial connection information; it is the opposite of
-\fB-c\fP. This option is provided because some older
-clients--particularly clients predating the release of Kerberos V5
-Beta5 (May 1995)--present bogus checksums that prevent Kerberos
-authentication from succeeding in the default mode.
-
-.PP
-The parent of the login process manipulates the master side of the
-pseduo terminal, operating as an intermediary between the login
-process and the client instance of the
-.I rlogin(1)
-program. In normal operation, the packet protocol described in
-.IR pty (4)
-is invoked to provide ^S/^Q type facilities and propagate interrupt
-signals to the remote programs. The login process propagates the
-client terminal's baud rate and terminal type, as found in the
-environment variable, ``TERM''; see
-.IR environ (7).
-The screen or
-window size of the terminal is requested from the client, and window
-size changes from the client are propagated to the pseudo terminal.
-
-.PP
-.I Klogind
-supports the following options to control the form of the hostname
-passed to login(1):
-
-.TP
-\fB\-w \fP[\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]
-Controls the form of the remote hostname passed to login(1).
-Specifying \fBip\fP results in the numeric IP address always being
-passed to login(1). Specifying a number, \fImaxhostlen\fP, sets the
-maximum length of the hostname passed to login(1) before it will be
-passed as a numeric IP address. If \fImaxhostlen\fP is 0, then the
-system default, as determined by the utmp or utmpx structures, is
-used. The \fBnostriplocal\fP and \fBstriplocal\fP options, which must
-be preceded by a comma, control whether or not the local host domain
-is stripped from the remote hostname. By default, the equivalent of
-\fBstriplocal\fP is in effect.
-
-.PP
-.I Klogind
-supports five options which are used for testing
-purposes:
-
-.IP \fB\-S\ keytab\fP 10
-Set the \fIkeytab\fP file to use.
-
-.IP \fB\-M\ realm\fP
-Set the Kerberos realm to use.
-
-.IP \fB\-L\ login\fP
-Set the login program to use. This option only has an effect if
-DO_NOT_USE_K_LOGIN was not defined when
-.I klogind
-was compiled.
-
-.IP \fB\-D\ port\fP
-Run in standalone mode, listening on \fBport\fP. The daemon will exit
-after one connection and will not background itself.
-
-.IP \fB\-f\fP
-Allows for standalone daemon operation. A new child is started for
-each incoming connection and waits for it to finish before accepting
-the next connection. This automagically figures out which port to bind
-to if no port is specified.
-
-.SH DIAGNOSTICS
-All diagnostic messages are returned on the connection
-associated with the
-.BR stderr ,
-after which any network connections are closed.
-An error is indicated by a leading byte with a value of 1.
-.PP
-.B ``Try again.''
-.br
-A
-.I fork
-by the server failed.
-.PP
-.B ``/bin/sh: ...''
-.br
-The user's login shell could not be started.
-.SH SEE ALSO
-rlogind(8), rlogin(1)
-.SH BUGS
-A more extensible protocol should be used.
diff --git a/src/appl/bsd/krcp.c b/src/appl/bsd/krcp.c
deleted file mode 100644
index 0d9089a476..0000000000
--- a/src/appl/bsd/krcp.c
+++ /dev/null
@@ -1,1363 +0,0 @@
-/*
- * appl/bsd/krcp.c
- */
-
-/*
- * Copyright (c) 1983 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.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rcp.c 5.10 (Berkeley) 9/20/88 */
-
- /*
- * rcp
- */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <sys/param.h>
-#ifndef _TYPES_
-#include <sys/types.h>
-#define _TYPES_
-#endif
-#include <sys/file.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/ioctl.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <signal.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <netdb.h>
-#include <errno.h>
-#include <string.h>
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
-#endif
-#include <stdarg.h>
-#include <sys/wait.h>
-
-#ifdef KERBEROS
-#include "k5-int.h"
-#include <k5-util.h>
-#include <com_err.h>
-
-#include "defines.h"
-
-#define RCP_BUFSIZ 4096
-
-int sock;
-char *krb_realm = NULL;
-char *krb_cache = NULL;
-char *krb_config = NULL;
-krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */
-krb5_context bsd_context;
-
-void try_normal(char **);
-char **save_argv(int, char **);
-#ifndef HAVE_STRSAVE
-char *strsave();
-#endif
-int rcmd_stream_write(), rcmd_stream_read();
-void usage(void), sink(int, char **),
- source(int, char **), rsource(char *, struct stat *), verifydir(char *),
- answer_auth(char *, char *);
-int response(void), hosteq(char *, char *), okname(char *),
- susystem(char *);
-int encryptflag = 0;
-
-#ifndef UCB_RCP
-#define UCB_RCP "/bin/rcp"
-#endif
-
-#endif /* KERBEROS */
-
-int rem;
-char *colon(char *);
-int errs;
-krb5_sigtype lostconn(int);
-int iamremote, targetshouldbedirectory;
-int iamrecursive;
-int pflag;
-int forcenet;
-struct passwd *pwd;
-int userid;
-int port = 0;
-
-struct buffer {
- unsigned int cnt;
- char *buf;
-};
-
-struct buffer *allocbuf(struct buffer *, int, int);
-
-#define NULLBUF (struct buffer *) 0
-
-void error (char *fmt, ...)
-#if !defined (__cplusplus) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
- __attribute__ ((__format__ (__printf__, 1, 2)))
-#endif
- ;
-
-#define ga() (void) rcmd_stream_write(rem, "", 1, 0)
-
-int main(argc, argv)
- int argc;
- char **argv;
-{
- char *targ, *host, *src;
- char *suser, *tuser, *thost;
- int i;
- char buf[RCP_BUFSIZ], cmdbuf[30];
- char *cmd = cmdbuf;
- struct servent *sp;
- static char curhost[256];
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-#ifdef KERBEROS
- krb5_flags authopts;
- krb5_error_code status;
- int euid;
- char **orig_argv = save_argv(argc, argv);
- krb5_auth_context auth_context;
- enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
-
- status = krb5_init_context(&bsd_context);
- if (status) {
- com_err(argv[0], status, "while initializing krb5");
- exit(1);
- }
-#endif
-
- pwd = getpwuid(userid = getuid());
- if (pwd == 0) {
- fprintf(stderr, "who are you?\n");
- exit(1);
- }
-
- for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
- (*argv)++;
- while (**argv) switch (*(*argv)++) {
-
- case 'r':
- iamrecursive++;
- break;
-
- case 'p': /* preserve mtimes and atimes */
- pflag++;
- break;
-
- case 'D':
- argc--, argv++;
- if (argc == 0)
- usage();
- port = htons(atoi(*argv));
- goto next_arg;
-
- case 'N':
- forcenet++;
- break;
-
-#ifdef KERBEROS
- case 'x':
- encryptflag++;
- break;
- case 'k': /* Change kerberos realm */
- argc--, argv++;
- if (argc == 0)
- usage();
- if(!(krb_realm = strdup(*argv))){
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
- goto next_arg;
- case 'c': /* Change default ccache file */
- argc--, argv++;
- if (argc == 0)
- usage();
- if(!(krb_cache = strdup(*argv))){
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
- goto next_arg;
- case 'C': /* Change default config file */
- argc--, argv++;
- if (argc == 0)
- usage();
- if(!(krb_config = strdup(*argv))){
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
- goto next_arg;
- case 'P':
- if (!strcmp (*argv, "O"))
- kcmd_proto = KCMD_OLD_PROTOCOL;
- else if (!strcmp (*argv, "N"))
- kcmd_proto = KCMD_NEW_PROTOCOL;
- else
- usage ();
- goto next_arg;
-#endif /* KERBEROS */
- /* The rest of these are not for users. */
- case 'd':
- targetshouldbedirectory = 1;
- break;
-
- case 'f': /* "from" */
- iamremote = 1;
- rcmd_stream_init_normal();
-#if defined(KERBEROS)
- if (encryptflag)
- answer_auth(krb_config, krb_cache);
-#endif /* KERBEROS */
-
- (void) response();
- source(--argc, ++argv);
- exit(errs);
-
- case 't': /* "to" */
- iamremote = 1;
- rcmd_stream_init_normal();
-#if defined(KERBEROS)
- if (encryptflag)
- answer_auth(krb_config, krb_cache);
-#endif /* KERBEROS */
-
- sink(--argc, ++argv);
- exit(errs);
-
- default:
- usage();
- }
- next_arg: ;
- }
-
- if (argc < 2)
- usage();
- if (argc > 2)
- targetshouldbedirectory = 1;
- rem = -1;
-
-
- if (port == 0) {
-#ifdef KERBEROS
- sp = getservbyname("kshell", "tcp");
-#else
- sp = getservbyname("shell", "tcp");
-#endif /* KERBEROS */
-
- if (sp == NULL) {
-#ifdef KERBEROS
- fprintf(stderr, "rcp: kshell/tcp: unknown service\n");
- try_normal(orig_argv);
-#else
- fprintf(stderr, "rcp: shell/tcp: unknown service\n");
- exit(1);
-#endif /* KERBEROS */
- }
- port = sp->s_port;
- }
-
-#ifdef KERBEROS
- if (asprintf(&cmd, "%srcp %s%s%s%s%s%s%s%s%s",
- encryptflag ? "-x " : "",
-
- iamrecursive ? " -r" : "", pflag ? " -p" : "",
- targetshouldbedirectory ? " -d" : "",
- krb_realm != NULL ? " -k " : "",
- krb_realm != NULL ? krb_realm : "",
- krb_cache != NULL ? " -c " : "",
- krb_cache != NULL ? krb_cache : "",
- krb_config != NULL ? " -C " : "",
- krb_config != NULL ? krb_config : "") < 0) {
- fprintf(stderr, "rcp: Cannot malloc.\n");
- exit(1);
- }
-
-#else /* !KERBEROS */
- (void) snprintf(cmd, sizeof(cmdbuf), "rcp%s%s%s",
- iamrecursive ? " -r" : "", pflag ? " -p" : "",
- targetshouldbedirectory ? " -d" : "");
-#endif /* KERBEROS */
-
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = lostconn;
- (void) sigaction(SIGPIPE, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGPIPE, lostconn);
-#endif
- targ = colon(argv[argc - 1]);
-
- /* Check if target machine is the current machine. */
-
- gethostname(curhost, sizeof(curhost));
- if (targ) { /* ... to remote */
- *targ++ = 0;
- if (hosteq(argv[argc - 1], curhost)) {
-
- /* If so, pretend there wasn't even one given
- * check for an argument of just "host:", it
- * should become "."
- */
-
- if (*targ == 0) {
- targ = ".";
- argv[argc - 1] = targ;
- }
- else
- argv[argc - 1] = targ;
- targ = 0;
- }
- }
- if (targ) {
- /* Target machine is some remote machine */
- if (*targ == 0)
- targ = ".";
- thost = strchr(argv[argc - 1], '@');
- if (thost) {
- *thost++ = 0;
- tuser = argv[argc - 1];
- if (*tuser == '\0')
- tuser = NULL;
- else if (!okname(tuser))
- exit(1);
- } else {
- thost = argv[argc - 1];
- tuser = NULL;
- }
- for (i = 0; i < argc - 1; i++) {
- src = colon(argv[i]);
- if (src) { /* remote to remote */
- *src++ = 0;
- if (*src == 0)
- src = ".";
- host = strchr(argv[i], '@');
- if (host) {
- *host++ = 0;
- suser = argv[i];
- if (*suser == '\0')
- suser = pwd->pw_name;
- else if (!okname(suser))
- continue;
- (void) snprintf(buf, sizeof(buf),
-#if defined(hpux) || defined(__hpux)
- "remsh %s -l %s -n %s %s '%s%s%s:%s'",
-#else
- "rsh %s -l %s -n %s %s '%s%s%s:%s'",
-#endif
- host, suser, cmd, src,
- tuser ? tuser : "",
- tuser ? "@" : "",
- thost, targ);
- } else
- (void) snprintf(buf, sizeof(buf),
-#if defined(hpux) || defined(__hpux)
- "remsh %s -n %s %s '%s%s%s:%s'",
-#else
- "rsh %s -n %s %s '%s%s%s:%s'",
-#endif
- argv[i], cmd, src,
- tuser ? tuser : "",
- tuser ? "@" : "",
- thost, targ);
- (void) susystem(buf);
- } else { /* local to remote */
- krb5_creds *cred;
- if (rem == -1) {
- (void) snprintf(buf, sizeof(buf), "%s -t %s",
- cmd, targ);
- host = thost;
-#ifdef KERBEROS
- authopts = AP_OPTS_MUTUAL_REQUIRED;
- status = kcmd(&sock, &host,
- port,
- pwd->pw_name,
- tuser ? tuser :
- pwd->pw_name,
- buf,
- 0,
- "host",
- krb_realm,
- &cred,
- 0, /* No seq # */
- 0, /* No server seq # */
- (struct sockaddr_in *) 0,
- (struct sockaddr_in *) 0,
- &auth_context, authopts,
- 0, /* Not any port # */
- 0,
- &kcmd_proto);
- if (status) {
- if (kcmd_proto == KCMD_NEW_PROTOCOL)
- /* Don't fall back to less safe methods. */
- exit (1);
- try_normal(orig_argv);
- }
- else {
- krb5_boolean similar;
- krb5_keyblock *key = &cred->keyblock;
-
- status = krb5_c_enctype_compare(bsd_context,
- ENCTYPE_DES_CBC_CRC,
- cred->keyblock.enctype,
- &similar);
- if (status)
- try_normal(orig_argv); /* doesn't return */
-
- if (!similar) {
- status = krb5_auth_con_getsendsubkey (bsd_context,
- auth_context,
- &key);
- if ((status || !key) && encryptflag)
- try_normal(orig_argv);
- }
- if (key == 0)
- key = &cred->keyblock;
-
- rcmd_stream_init_krb5(key, encryptflag, 0, 1,
- kcmd_proto);
- }
- rem = sock;
-#else
- rem = rcmd(&host, port, pwd->pw_name,
- tuser ? tuser : pwd->pw_name,
- buf, 0);
- if (rem < 0)
- exit(1);
-#endif /* KERBEROS */
- if (response() < 0)
- exit(1);
- }
- source(1, argv+i);
- }
- }
- } else { /* ... to local */
- if (targetshouldbedirectory)
- verifydir(argv[argc - 1]);
- for (i = 0; i < argc - 1; i++) {
- src = colon(argv[i]);
- /* Check if source machine is current machine */
- if (src) {
- *src++ = 0;
- if (hosteq(argv[i], curhost)) {
-
- /* If so, pretend src machine never given */
-
- if (*src == 0) {
- error("rcp: no path given in arg: %s:\n",
- argv[i]);
- errs++;
- continue;
- }
- argv[i] = src;
- src = 0;
- } else {
- /* not equiv, return colon */
- *(--src) = ':';
- }
- }
- if (src == 0) { /* local to local */
- (void) snprintf(buf, sizeof(buf), "/bin/cp%s%s %s %s",
- iamrecursive ? " -r" : "",
- pflag ? " -p" : "",
- argv[i], argv[argc - 1]);
- (void) susystem(buf);
- } else { /* remote to local */
- krb5_creds *cred;
- *src++ = 0;
- if (*src == 0)
- src = ".";
- host = strchr(argv[i], '@');
- if (host) {
- *host++ = 0;
- suser = argv[i];
- if (*suser == '\0')
- suser = pwd->pw_name;
- else if (!okname(suser))
- continue;
- } else {
- host = argv[i];
- suser = pwd->pw_name;
- }
- (void) snprintf(buf, sizeof(buf), "%s -f %s", cmd, src);
-#ifdef KERBEROS
- authopts = AP_OPTS_MUTUAL_REQUIRED;
- status = kcmd(&sock, &host,
- port,
- pwd->pw_name, suser,
- buf,
- 0,
- "host",
- krb_realm,
- &cred,
- 0, /* No seq # */
- 0, /* No server seq # */
- (struct sockaddr_in *) 0,
- (struct sockaddr_in *) 0,
- &auth_context, authopts,
- 0, /* Not any port # */
- 0,
- &kcmd_proto);
- if (status) {
- if (kcmd_proto == KCMD_NEW_PROTOCOL)
- /* Don't fall back to less safe methods. */
- exit (1);
- try_normal(orig_argv);
- } else {
- krb5_keyblock *key = &cred->keyblock;
-
- if (kcmd_proto == KCMD_NEW_PROTOCOL) {
- status = krb5_auth_con_getsendsubkey (bsd_context,
- auth_context,
- &key);
- if (status) {
- com_err (argv[0], status,
- "determining subkey for session");
- exit (1);
- }
- if (!key) {
- com_err (argv[0], 0,
- "no subkey negotiated for connection");
- exit (1);
- }
- }
-
- rcmd_stream_init_krb5(key, encryptflag, 0, 1, kcmd_proto);
- }
- rem = sock;
-
- euid = geteuid();
- if (euid == 0) {
- if (setuid(0)) {
- perror("rcp setuid 0"); errs++; exit(errs);
- }
- if(krb5_seteuid(userid)) {
- perror("rcp seteuid user"); errs++; exit(errs);
- }
- }
- sink(1, argv+argc-1);
- if (euid == 0) {
- if(krb5_seteuid(0)) {
- perror("rcp seteuid 0"); errs++; exit(errs);
- }
- }
-#else
- rem = rcmd(&host, port, pwd->pw_name, suser,
- buf, 0);
- if (rem < 0)
- continue;
- rcmd_stream_init_normal();
-#ifdef HAVE_SETREUID
- if (setreuid(0, userid)) {
- perror("rcp setreuid 0,user"); errs++; exit(errs);
- }
- sink(1, argv+argc-1);
- if (setreuid(userid, 0)) {
- perror("rcp setreuid user,0"); errs++; exit(errs);
- }
-#else
- if (setuid(0)) {
- perror("rcp setuid 0"); errs++; exit(errs);
- }
- if(seteuid(userid)) {
- perror("rcp seteuid user"); errs++; exit(errs);
- }
- sink(1, argv+argc-1);
- if(seteuid(0)) {
- perror("rcp seteuid 0"); errs++; exit(errs);
- }
-#endif
-#endif /* KERBEROS */
- (void) close(rem);
- rem = -1;
- }
- }
- }
- exit(errs);
-}
-
-
-
-void verifydir(cp)
- char *cp;
-{
- struct stat stb;
-
- if (stat(cp, &stb) >= 0) {
- if ((stb.st_mode & S_IFMT) == S_IFDIR)
- return;
- errno = ENOTDIR;
- }
- error("rcp: %s: %s.\n", cp, error_message(errno));
- exit(1);
-}
-
-
-
-char *colon(cp)
- char *cp;
-{
-
- while (*cp) {
- if (*cp == ':')
- return (cp);
- if (*cp == '/')
- return (0);
- cp++;
- }
- return (0);
-}
-
-
-
-int okname(cp0)
- char *cp0;
-{
- register char *cp = cp0;
- register int c;
-
- do {
- c = *cp;
- if (c & 0200)
- goto bad;
- if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
- goto bad;
- cp++;
- } while (*cp);
- return (1);
- bad:
- fprintf(stderr, "rcp: invalid user name %s\n", cp0);
- return (0);
-}
-
-
-
-int susystem(s)
- char *s;
-{
- int status;
- pid_t pid, w;
-#ifdef POSIX_SIGNALS
- struct sigaction sa, isa, qsa;
-#else
- register krb5_sigtype (bsd_context, *istat)(), (*qstat)();
-#endif
-
- if ((pid = vfork()) == 0) {
- execl("/bin/sh", "sh", "-c", s, (char *)0);
- _exit(127);
- }
-
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGINT, &sa, &isa);
- (void) sigaction(SIGQUIT, &sa, &qsa);
-#else
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
-#endif
-
-#ifdef HAVE_WAITPID
- w = waitpid(pid, &status, 0);
-#else
- while ((w = wait(&status)) != pid && w != -1) /*void*/ ;
-#endif
- if (w == (pid_t)-1)
- status = -1;
-
-#ifdef POSIX_SIGNALS
- (void) sigaction(SIGINT, &isa, (struct sigaction *)0);
- (void) sigaction(SIGQUIT, &qsa, (struct sigaction *)0);
-#else
- (void) signal(SIGINT, istat);
- (void) signal(SIGQUIT, qstat);
-#endif
-
- return (status);
-}
-
-void source(argc, argv)
- int argc;
- char **argv;
-{
- char *last, *name;
- struct stat stb;
- static struct buffer buffer;
- struct buffer *bp;
- int x, readerr, f;
- unsigned int amt;
- off_t i;
- char buf[RCP_BUFSIZ];
-
- for (x = 0; x < argc; x++) {
- name = argv[x];
- if ((f = open(name, 0)) < 0) {
- error("rcp: %s: %s\n", name, error_message(errno));
- continue;
- }
- if (fstat(f, &stb) < 0)
- goto notreg;
- switch (stb.st_mode&S_IFMT) {
-
- case S_IFREG:
- break;
-
- case S_IFDIR:
- if (iamrecursive) {
- (void) close(f);
- rsource(name, &stb);
- continue;
- }
- /* fall into ... */
- default:
- notreg:
- (void) close(f);
- error("rcp: %s: not a plain file\n", name);
- continue;
- }
- last = strrchr(name, '/');
- if (last == 0)
- last = name;
- else
- last++;
- if (pflag) {
- /*
- * Make it compatible with possible future
- * versions expecting microseconds.
- */
- (void) snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
- stb.st_mtime, stb.st_atime);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- (void) close(f);
- continue;
- }
- }
- (void) snprintf(buf, sizeof(buf), "C%04o %ld %s\n",
- (int) stb.st_mode&07777, (long ) stb.st_size, last);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- (void) close(f);
- continue;
- }
- if ((bp = allocbuf(&buffer, f, RCP_BUFSIZ)) == NULLBUF) {
- (void) close(f);
- continue;
- }
- readerr = 0;
- for (i = 0; i < stb.st_size; i += bp->cnt) {
- amt = bp->cnt;
- if (i + amt > stb.st_size)
- amt = stb.st_size - i;
- if (readerr == 0 && read(f, bp->buf, amt) != amt)
- readerr = errno;
- (void) rcmd_stream_write(rem, bp->buf, amt, 0);
- }
- (void) close(f);
- if (readerr == 0)
- ga();
- else
- error("rcp: %s: %s\n", name, error_message(readerr));
- (void) response();
- }
-}
-
-
-
-#ifndef USE_DIRENT_H
-#include <sys/dir.h>
-#else
-#include <dirent.h>
-#endif
-
-void rsource(name, statp)
- char *name;
- struct stat *statp;
-{
- DIR *d = opendir(name);
- char *last;
-#ifdef USE_DIRENT_H
- struct dirent *dp;
-#else
- struct direct *dp;
-#endif
- char buf[RCP_BUFSIZ];
- char *bufv[1];
-
- if (d == 0) {
- error("rcp: %s: %s\n", name, error_message(errno));
- return;
- }
- last = strrchr(name, '/');
- if (last == 0)
- last = name;
- else
- last++;
- if (pflag) {
- (void) snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n",
- statp->st_mtime, statp->st_atime);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- closedir(d);
- return;
- }
- }
- (void) snprintf(buf, sizeof(buf), "D%04lo %d %s\n",
- (long) statp->st_mode&07777, 0, last);
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- if (response() < 0) {
- closedir(d);
- return;
- }
- while ((dp = readdir(d)) != NULL) {
- if (dp->d_ino == 0)
- continue;
- if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
- continue;
- if (strlen(name) + 1 + strlen(dp->d_name) >= RCP_BUFSIZ - 1) {
- error("%s/%s: Name too long.\n", name, dp->d_name);
- continue;
- }
- (void) snprintf(buf, sizeof(buf), "%s/%s", name, dp->d_name);
- bufv[0] = buf;
- source(1, bufv);
- }
- closedir(d);
- (void) rcmd_stream_write(rem, "E\n", 2, 0);
- (void) response();
-}
-
-
-
-int response()
-{
- char resp, c, rbuf[RCP_BUFSIZ], *cp = rbuf;
- if (rcmd_stream_read(rem, &resp, 1, 0) != 1)
- lostconn(0);
- switch (resp) {
-
- case 0: /* ok */
- return (0);
-
- default:
- *cp++ = resp;
- /* fall into... */
- case 1: /* error, followed by err msg */
- case 2: /* fatal error, "" */
- do {
- if (rcmd_stream_read(rem, &c, 1, 0) != 1)
- lostconn(0);
- *cp++ = c;
- } while (cp < &rbuf[RCP_BUFSIZ] && c != '\n');
- if (iamremote == 0)
- (void) write(2, rbuf, (unsigned) (cp - rbuf));
- errs++;
- if (resp == 1)
- return (-1);
- exit(1);
- }
- /*NOTREACHED*/
-}
-
-
-
-krb5_sigtype
- lostconn(signumber)
- int signumber;
-{
- if (iamremote == 0)
- fprintf(stderr, "rcp: lost connection\n");
- exit(1);
-}
-
-
-#if !defined(HAVE_UTIMES)
-#include <utime.h>
-#include <sys/time.h>
-
-/*
- * We emulate utimes() instead of utime() as necessary because
- * utimes() is more powerful than utime(), and rcp actually tries to
- * set the microsecond values; we don't want to take away
- * functionality unnecessarily.
- */
-int utimes(file, tvp)
-const char *file;
-struct timeval *tvp;
-{
- struct utimbuf times;
-
- times.actime = tvp[0].tv_sec;
- times.modtime = tvp[1].tv_sec;
- return(utime(file, &times));
-}
-#endif
-
-
-void sink(argc, argv)
- int argc;
- char **argv;
-{
- mode_t mode;
- mode_t mask = umask(0);
- off_t i, j;
- char *targ, *whopp, *cp;
- int of, wrerr, exists, first;
- off_t size;
- unsigned int amt, count;
- struct buffer *bp;
- static struct buffer buffer;
- struct stat stb;
- int targisdir = 0;
- char *myargv[1];
- char cmdbuf[RCP_BUFSIZ], nambuf[RCP_BUFSIZ];
- int setimes = 0;
- struct timeval tv[2];
-#define atime tv[0]
-#define mtime tv[1]
-#define SCREWUP(str) { whopp = str; goto screwup; }
-
- if (!pflag)
- (void) umask(mask);
- if (argc != 1) {
- error("rcp: ambiguous target\n");
- exit(1);
- }
- targ = *argv;
- if (targetshouldbedirectory)
- verifydir(targ);
- ga();
- if (stat(targ, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR)
- targisdir = 1;
- for (first = 1; ; first = 0) {
- cp = cmdbuf;
- if (rcmd_stream_read(rem, cp, 1, 0) <= 0)
- return;
- if (*cp++ == '\n')
- SCREWUP("unexpected '\\n'");
- do {
- if (rcmd_stream_read(rem, cp, 1, 0) != 1)
- SCREWUP("lost connection");
- } while (*cp++ != '\n');
- *cp = 0;
- if (cmdbuf[0] == '\01' || cmdbuf[0] == '\02') {
- if (iamremote == 0)
- (void) write(2, cmdbuf+1, strlen(cmdbuf+1));
- if (cmdbuf[0] == '\02')
- exit(1);
- errs++;
- continue;
- }
- *--cp = 0;
- cp = cmdbuf;
- if (*cp == 'E') {
- ga();
- return;
- }
-
-#define getnum(t) (t) = 0; while (isdigit((int) *cp)) (t) = (t) * 10 + (*cp++ - '0');
- if (*cp == 'T') {
- setimes++;
- cp++;
- getnum(mtime.tv_sec);
- if (*cp++ != ' ')
- SCREWUP("mtime.sec not delimited");
- getnum(mtime.tv_usec);
- if (*cp++ != ' ')
- SCREWUP("mtime.usec not delimited");
- getnum(atime.tv_sec);
- if (*cp++ != ' ')
- SCREWUP("atime.sec not delimited");
- getnum(atime.tv_usec);
- if (*cp++ != '\0')
- SCREWUP("atime.usec not delimited");
- ga();
- continue;
- }
- if (*cp != 'C' && *cp != 'D') {
- /*
- * Check for the case "rcp remote:foo\* local:bar".
- * In this case, the line "No match." can be returned
- * by the shell before the rcp command on the remote is
- * executed so the ^Aerror_message convention isn't
- * followed.
- */
- if (first) {
- error("%s\n", cp);
- exit(1);
- }
- SCREWUP("expected control record");
- }
- cp++;
- mode = 0;
- for (; cp < cmdbuf+5; cp++) {
- if (*cp < '0' || *cp > '7')
- SCREWUP("bad mode");
- mode = (mode << 3) | (*cp - '0');
- }
- if (*cp++ != ' ')
- SCREWUP("mode not delimited");
- size = 0;
- while (isdigit((int) *cp))
- size = size * 10 + (*cp++ - '0');
- if (*cp++ != ' ')
- SCREWUP("size not delimited");
- if (targisdir) {
- if(strlen(targ) + strlen(cp) + 2 >= sizeof(nambuf))
- SCREWUP("target name too long");
- (void) snprintf(nambuf, sizeof(nambuf), "%s%s%s", targ,
- *targ ? "/" : "", cp);
- } else {
- if (strlen(targ) + 1 >= sizeof (nambuf))
- SCREWUP("target name too long");
- (void) strncpy(nambuf, targ, sizeof(nambuf) - 1);
- }
- nambuf[sizeof(nambuf) - 1] = '\0';
- exists = stat(nambuf, &stb) == 0;
- if (cmdbuf[0] == 'D') {
- if (exists) {
- if ((stb.st_mode&S_IFMT) != S_IFDIR) {
- errno = ENOTDIR;
- goto bad;
- }
- if (pflag)
- (void) chmod(nambuf, mode);
- } else if (mkdir(nambuf, mode) < 0)
- goto bad;
- myargv[0] = nambuf;
- sink(1, myargv);
- if (setimes) {
- setimes = 0;
- if (utimes(nambuf, tv) < 0)
- error("rcp: can't set times on %s: %s\n",
- nambuf, error_message(errno));
- }
- continue;
- }
- if ((of = open(nambuf, O_WRONLY|O_CREAT, mode)) < 0) {
- bad:
- error("rcp: %s: %s\n", nambuf, error_message(errno));
- continue;
- }
- if (exists && pflag) {
-#ifdef NOFCHMOD
- (void) chmod(nambuf, mode);
-#else
- (void) fchmod(of, mode);
-#endif
- }
- ga();
- if ((bp = allocbuf(&buffer, of, RCP_BUFSIZ)) == NULLBUF) {
- (void) close(of);
- continue;
- }
- cp = bp->buf;
- count = 0;
- wrerr = 0;
- for (i = 0; i < size; i += RCP_BUFSIZ) {
- amt = RCP_BUFSIZ;
- if (i + amt > size)
- amt = size - i;
- count += amt;
- do {
- j = rcmd_stream_read(rem, cp, amt, 0);
- if (j <= 0) {
- if (j == 0)
- error("rcp: dropped connection");
- else
- error("rcp: %s\n", error_message(errno));
- exit(1);
- }
- amt -= j;
- cp += j;
- } while (amt > 0);
- if (count == bp->cnt) {
- if (wrerr == 0 &&
- write(of, bp->buf, count) != count)
- wrerr++;
- count = 0;
- cp = bp->buf;
- }
- }
- if (count != 0 && wrerr == 0 &&
- write(of, bp->buf, count) != count)
- wrerr++;
- if (ftruncate(of, size))
- error("rcp: can't truncate %s: %s\n", nambuf, error_message(errno));
- if (close(of) != 0)
- error("rcp: error closing %s: %s\n", nambuf, error_message(errno));
- (void) response();
- if (setimes) {
- setimes = 0;
- if (utimes(nambuf, tv) < 0)
- error("rcp: can't set times on %s: %s\n",
- nambuf, error_message(errno));
- }
- if (wrerr)
- error("rcp: %s: %s\n", nambuf, error_message(errno));
- else
- ga();
- }
- screwup:
- error("rcp: protocol screwup: %s\n", whopp);
- exit(1);
-}
-
-
-
-struct buffer *allocbuf(bp, fd, blksize)
- struct buffer *bp;
- int fd, blksize;
-{
- struct stat stb;
- int size;
-
- if (fstat(fd, &stb) < 0) {
- error("rcp: fstat: %s\n", error_message(errno));
- return (NULLBUF);
- }
-
- size = blksize;
- if (bp->cnt < size) {
- if (bp->buf != 0)
- free(bp->buf);
- bp->buf = (char *)malloc((unsigned) size);
- if (bp->buf == 0) {
- error("rcp: malloc: out of memory\n");
- return (NULLBUF);
- }
- }
- bp->cnt = size;
- return (bp);
-}
-
-void
-#ifdef HAVE_STDARG_H
-error(char *fmt, ...)
-#else
-/*VARARGS1*/
-error(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
- char buf[RCP_BUFSIZ], *cp = buf;
-
-#ifdef HAVE_STDARG_H
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
-
- errs++;
- *cp++ = 1;
- (void) vsnprintf(cp, sizeof(buf) - (cp - buf), fmt, ap);
- va_end(ap);
-
- if (iamremote)
- (void) rcmd_stream_write(rem, buf, strlen(buf), 0);
- else
- (void) write(2, buf+1, strlen(buf+1));
-}
-
-
-
-void usage()
-{
-#ifdef KERBEROS
- fprintf(stderr,
- "Usage: \trcp [-PN | -PO] [-p] [-x] [-k realm] f1 f2; or:\n\trcp [-PN | -PO] [-r] [-p] [-x] [-k realm] f1 ... fn d2\n");
-#else
- fputs("usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n", stderr);
-#endif
- exit(1);
-}
-
-
-
-int hosteq(h1, h2)
- char *h1, *h2;
-{
- struct hostent *h_ptr;
- char hname1[256];
-
- if (forcenet)
- return(0);
-
- /* get the official names for the two hosts */
-
- if ((h_ptr = gethostbyname(h1)) == NULL)
- return(0);
- strncpy(hname1, h_ptr->h_name, sizeof (hname1));
- hname1[sizeof (hname1) - 1] = '\0';
- if ((h_ptr = gethostbyname(h2)) == NULL)
- return(0);
-
- /*return if they are equal (strcmp returns 0 for equal - I return 1) */
-
- return(!strcmp(hname1, h_ptr->h_name));
-}
-
-
-
-#ifdef KERBEROS
-void try_normal(argv)
- char **argv;
-{
- register int i;
-#ifndef KRB5_ATHENA_COMPAT
- if (!encryptflag)
-#endif
- {
- fprintf(stderr,"trying normal rcp (%s)\n", UCB_RCP);
- fflush(stderr);
- /* close all but stdin, stdout, stderr */
- for (i = getdtablesize(); i > 2; i--)
- (void) close(i);
- execv(UCB_RCP, argv);
- perror("exec");
- }
- exit(1);
-}
-
-
-
-char **save_argv(argc, argv)
- int argc;
- char **argv;
-{
- register int i;
-
- char **local_argv = (char **)calloc((unsigned) argc+1,
- (unsigned) sizeof(char *));
- /* allocate an extra pointer, so that it is initialized to NULL
- and execv() will work */
- for (i = 0; i < argc; i++)
- local_argv[i] = strsave(argv[i]);
- return(local_argv);
-}
-
-
-
-#ifdef unicos61
-#define SIZEOF_INADDR SIZEOF_in_addr
-#else
-#define SIZEOF_INADDR sizeof(struct in_addr)
-#endif
-
-
-/* This function is mostly vestigial, since under normal operation
- * the -x flag doesn't get set for the server process for encrypted
- * rcp. It only gets called by beta clients attempting user-to-user
- * authentication. */
-void
- answer_auth(config_file, ccache_file)
- char *config_file;
- char *ccache_file;
-{
- krb5_data pname_data, msg;
- krb5_creds creds, *new_creds;
- krb5_ccache cc;
- krb5_error_code status;
- krb5_auth_context auth_context = NULL;
-
- if (config_file) {
- const char * filenames[2];
- filenames[1] = NULL;
- filenames[0] = config_file;
- if ((status = krb5_set_config_files(bsd_context, filenames)))
- exit(1);
- }
-
- memset (&creds, 0, sizeof(creds));
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer)&rem,
- &pname_data)))
- exit(1);
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer) &rem,
- &creds.second_ticket)))
- exit(1);
-
- if (ccache_file == NULL) {
- if ((status = krb5_cc_default(bsd_context, &cc)))
- exit(1);
- } else {
- if ((status = krb5_cc_resolve(bsd_context, ccache_file, &cc)))
- exit(1);
- }
-
- if ((status = krb5_cc_get_principal(bsd_context, cc, &creds.client)))
- exit(1);
-
- if ((status = krb5_parse_name(bsd_context, pname_data.data,
- &creds.server)) )
- exit(1);
-
- krb5_free_data_contents(bsd_context, &pname_data);
-
- if ((status = krb5_get_credentials(bsd_context, KRB5_GC_USER_USER, cc,
- &creds, &new_creds)))
- exit(1);
-
- if ((status = krb5_mk_req_extended(bsd_context, &auth_context,
- AP_OPTS_USE_SESSION_KEY,
- NULL, new_creds, &msg)))
- exit(1);
-
- if ((status = krb5_write_message(bsd_context, (krb5_pointer) &rem,
- &msg))) {
- krb5_free_data_contents(bsd_context, &msg);
- exit(1);
- }
-
- rcmd_stream_init_krb5(&new_creds->keyblock, encryptflag, 0, 0,
- KCMD_OLD_PROTOCOL);
-
- /* cleanup */
- krb5_free_cred_contents(bsd_context, &creds);
- krb5_free_creds(bsd_context, new_creds);
- krb5_free_data_contents(bsd_context, &msg);
-
- return;
-}
-
-
-
-char storage[2*RCP_BUFSIZ]; /* storage for the decryption */
-int nstored = 0;
-char *store_ptr = storage;
-
-#endif /* KERBEROS */
diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c
deleted file mode 100644
index 0a00e37e3d..0000000000
--- a/src/appl/bsd/krlogin.c
+++ /dev/null
@@ -1,1807 +0,0 @@
-/*
- * appl/bsd/krlogin.c
- */
-
-/*
- * Copyright (c) 1983 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.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * 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.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rlogin.c 5.12 (Berkeley) 9/19/88 */
-
-
- /*
- * rlogin - remote login
- */
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/errno.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <pwd.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <netdb.h>
-
-#ifdef HAVE_SYS_FILIO_H
-/* Solaris needs <sys/filio.h> for FIONREAD */
-#include <sys/filio.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef POSIX_TERMIOS
-#include <termios.h>
-#ifndef CNUL
-#define CNUL (char) 0
-#endif
-
-#else /* POSIX_TERMIOS */
-#include <sgtty.h>
-#endif /* POSIX_TERMIOS */
-
-#ifdef HAVE_SYS_SOCKIO_H
-/* for SIOCATMARK */
-#include <sys/sockio.h>
-#endif
-
-#ifdef HAVE_STREAMS
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#endif
-
-#ifdef __SCO__
-/* for TIOCPKT_* */
-#include <sys/spt.h>
-/* for struct winsize */
-#include <sys/ptem.h>
-#endif
-
-#ifdef HAVE_STREAMS
-#ifdef HAVE_SYS_PTYVAR_H
-#include <sys/tty.h>
-#include <sys/ttold.h>
-/* solaris actually uses packet mode, so the real macros are needed too */
-#include <sys/ptyvar.h>
-#endif
-#endif
-
-#ifndef TIOCPKT_NOSTOP
-/* These values are over-the-wire protocol, *not* local values */
-#define TIOCPKT_NOSTOP 0x10
-#define TIOCPKT_DOSTOP 0x20
-#define TIOCPKT_FLUSHWRITE 0x02
-#endif
-
-#ifdef HAVE_SYS_IOCTL_COMPAT_H
-#include <sys/ioctl_compat.h>
-#endif
-
-#ifdef CRAY
-#include <sys/ttold.h>
-#endif
-
-
-#ifdef KERBEROS
-#include <krb5.h>
-#include <com_err.h>
-#include "defines.h"
-
-#define RLOGIN_BUFSIZ 5120
-
-void try_normal();
-char *krb_realm = (char *)0;
-int encrypt_flag = 0;
-int fflag = 0, Fflag = 0;
-krb5_creds *cred;
-struct sockaddr_in local, foreign;
-krb5_context bsd_context;
-krb5_auth_context auth_context;
-
-#ifndef UCB_RLOGIN
-#define UCB_RLOGIN "/usr/ucb/rlogin"
-#endif
-
-#include "rpaths.h"
-#endif /* KERBEROS */
-
-# ifndef TIOCPKT_WINDOW
-# define TIOCPKT_WINDOW 0x80
-# endif /* TIOCPKT_WINDOW */
-
-#ifndef ONOCR
-#define ONOCR 0
-#endif
-
-#ifdef POSIX_TERMIOS
-struct termios deftty;
-#endif
-
-char *getenv();
-
-char *name;
-int rem = -1; /* Remote socket fd */
-int do_inband = 0;
-char cmdchar = '~';
-int eight = 1; /* Default to 8 bit transmission */
-int no_local_escape = 0;
-int null_local_username = 0;
-int flow = 1; /* Default is to allow flow
- control at the local terminal */
-int flowcontrol; /* Since emacs can alter the
- flow control characteristics
- of a session we need a
- variable to keep track of
- the original characteristics */
-int confirm = 0; /* ask if ~. is given before dying. */
-int litout;
-#if defined(hpux) || defined(__hpux)
-char *speeds[] =
-{ "0", "50", "75", "110", "134", "150", "200", "300", "600",
- "900", "1200", "1800", "2400", "3600", "4800", "7200", "9600",
- "19200", "38400", "EXTA", "EXTB" };
-#else
-/* Solaris note: There are higher values we could use. But Casper Dik
- <Casper.Dik@Holland.Sun.Com> mentions in article
- <casper.938167062@uk-usenet.uk.sun.com> in comp.protocols.kerberos
- on 1999-09-24 some problems in sending higher values to remote
- systems (for non-Kerberos rlogind?). So let's stick with this
- list. Even if our current klogind doesn't have the problems, older
- versions are likely to.
-
- Daniel S. Riley <dsr@mail.lns.cornell.edu> gives 57600, 76800,
- 115200, 153600, 230400, 307200, 460800 as the higher values.
- (article <sh6711s713.fsf@lnscu4.lns.cornell.edu> in
- comp.protocols.kerberos, 1999-09-23) */
-char *speeds[] =
-{ "0", "50", "75", "110", "134", "150", "200", "300",
- "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
-#endif
-char term[256] = "network";
-
-#ifndef POSIX_SIGNALS
-#ifndef sigmask
-#define sigmask(m) (1 << ((m)-1))
-#endif
-#endif /* POSIX_SIGNALS */
-
-#ifdef NO_WINSIZE
-struct winsize {
- unsigned short ws_row, ws_col;
- unsigned short ws_xpixel, ws_ypixel;
-};
-#endif /* NO_WINSIZE */
-int dosigwinch = 0;
-struct winsize winsize;
-
-char *host=0; /* external, so it can be
- reached from confirm_death() */
-
-krb5_sigtype sigwinch (int);
-int server_message (int);
-void oob (void);
-krb5_sigtype lostpeer (int);
-void setsignal (int sig, krb5_sigtype (*act)());
-static int read_wrapper(int fd, char *buf, int size, int *got_esc);
-static void prf(char *f);
-void try_normal(char **);
-static void mode(int);
-#ifdef POSIX_SIGNALS
-static int reader(sigset_t *);
-static void doit(sigset_t *);
-#else
-static int reader(int);
-static void doit(int);
-#endif
-static int control(char *, unsigned int);
-static void sendwindow(void);
-static void stop(int), echo(int);
-static void writer(void), done(int);
-static int confirm_death (void);
-
-
-/* to allow exits from signal handlers, without conflicting declarations */
-static krb5_sigtype exit_handler() {
- exit(1);
-}
-
-
-/*
- * The following routine provides compatibility (such as it is)
- * between 4.2BSD Suns and others. Suns have only a `ttysize',
- * so we convert it to a winsize.
- */
-#ifdef TIOCGWINSZ
-#define get_window_size(fd, wp) ioctl(fd, TIOCGWINSZ, wp)
-#else
-#ifdef SYSV
-#ifndef SIGWINCH
-#define SIGWINCH SIGWINDOW
-#endif
-struct ttysize {
- int ts_lines;
- int ts_cols;
-};
-#define DEFAULT_LINES 24
-#define DEFAULT_COLS 80
-#endif
-
-
-
-int
- get_window_size(fd, wp)
-int fd;
-struct winsize *wp;
-{
- struct ttysize ts;
- int error;
-#ifdef SYSV
- char *envbuf;
- ts.ts_lines = DEFAULT_LINES;
- ts.ts_cols = DEFAULT_COLS;
- if (( envbuf = getenv("LINES")) != (char *) 0)
- ts.ts_lines = atoi(envbuf);
- if (( envbuf = getenv("COLUMNS")) != (char *) 0)
- ts.ts_cols = atoi(envbuf);
-#else
- if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0)
- return (error);
-#endif
-
- wp->ws_row = ts.ts_lines;
- wp->ws_col = ts.ts_cols;
- wp->ws_xpixel = 0;
- wp->ws_ypixel = 0;
- return (0);
-}
-#endif /* TIOCGWINSZ */
-
-
-#ifdef POSIX_TERMIOS
-/* Globals for terminal modes and flow control */
-struct termios defmodes;
-struct termios ixon_state;
-#else
-#ifdef USE_TERMIO
-/* Globals for terminal modes and flow control */
-struct termio defmodes;
-struct termio ixon_state;
-#endif
-#endif
-
-
-int
-main(argc, argv)
- int argc;
- char **argv;
-{
- char *cp = (char *) NULL;
-#ifdef POSIX_TERMIOS
- struct termios ttyb;
-#else
-#ifdef USE_TERMIO
- struct termio ttyb;
-#else
- struct sgttyb ttyb;
-#endif
-#endif
- struct passwd *pwd;
- struct servent *sp;
- struct servent defaultservent;
- int uid, options = 0;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
- sigset_t *oldmask, omask, urgmask;
-#else
- int oldmask;
-#endif
- int on = 1;
-#ifdef KERBEROS
- char **orig_argv = argv;
- int sock;
- krb5_flags authopts;
- krb5_error_code status;
-#endif
- int port, debug_port = 0;
- enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
-
- memset(&defaultservent, 0, sizeof(struct servent));
- if (strrchr(argv[0], '/'))
- argv[0] = strrchr(argv[0], '/')+1;
-
- if ( argc < 2 ) goto usage;
- argc--;
- argv++;
-
- another:
- if (argc > 0 && host == 0 && strncmp(*argv, "-", 1)) {
- host = *argv;
- argv++, argc--;
- goto another;
- }
-
- if (argc > 0 && !strcmp(*argv, "-D")) {
- argv++; argc--;
- if (*argv == NULL) {
- fprintf (stderr,
- "rlogin: -D flag must be followed by the debug port.\n");
- exit (1);
- }
- debug_port = htons(atoi(*argv));
- argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-d")) {
- argv++, argc--;
- options |= SO_DEBUG;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-c")) {
- confirm = 1;
- argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-a")) { /* ask -- make remote */
- argv++; argc--; /* machine ask for password */
- null_local_username = 1; /* by giving null local user */
- goto another; /* id */
- }
- if (argc > 0 && !strcmp(*argv, "-t")) {
- argv++; argc--;
- if (argc == 0) goto usage;
- cp = *argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-n")) {
- no_local_escape = 1;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-7")) { /* Pass only 7 bits */
- eight = 0;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-noflow")) {
- flow = 0; /* Turn off local flow control so
- that ^S can be passed to emacs. */
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-l")) {
- argv++, argc--;
- if (argc == 0)
- goto usage;
- name = *argv++; argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-e", 2)) {
- cmdchar = argv[0][2];
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-8")) {
- eight = 1;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-L")) {
- litout = 1;
- argv++, argc--;
- goto another;
- }
-#ifdef KERBEROS
- if (argc > 0 && !strcmp(*argv, "-k")) {
- argv++, argc--;
- if (argc == 0) {
- fprintf(stderr,
- "rlogin: -k flag must be followed with a realm name.\n");
- exit (1);
- }
- if(!(krb_realm = strdup(*argv))){
- fprintf(stderr, "rlogin: Cannot malloc.\n");
- exit(1);
- }
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-x")) {
- encrypt_flag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-f")) {
- if (Fflag) {
- fprintf(stderr, "rlogin: Only one of -f and -F allowed\n");
- goto usage;
- }
- fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-F")) {
- if (fflag) {
- fprintf(stderr, "rlogin: Only one of -f and -F allowed\n");
- goto usage;
- }
- Fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PO")) {
- kcmd_proto = KCMD_OLD_PROTOCOL;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PN")) {
- kcmd_proto = KCMD_NEW_PROTOCOL;
- argv++, argc--;
- goto another;
- }
-#endif /* KERBEROS */
- if (host == 0)
- goto usage;
- if (argc > 0)
- goto usage;
- pwd = getpwuid(getuid());
- if (pwd == 0) {
- fprintf(stderr, "Who are you?\n");
- exit(1);
- }
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- com_err(argv[0], status, "while initializing krb5");
- exit(1);
- }
-#endif
-
-
- if (debug_port)
- port = debug_port;
- else {
-#ifdef KERBEROS
- /*
- * if there is an entry in /etc/services for Kerberos login,
- * attempt to login with Kerberos.
- * If we fail at any step, use the standard rlogin
- */
- if (encrypt_flag)
- sp = getservbyname("eklogin","tcp");
- else
- sp = getservbyname("klogin","tcp");
- if (sp == 0) {
- sp = &defaultservent; /* ANL */
- sp->s_port = encrypt_flag ? htons(2105) : htons(543);
- }
-#else
- sp = getservbyname("login", "tcp");
- if (sp == 0) {
- fprintf(stderr, "rlogin: login/tcp: unknown service\n");
- exit(2);
- }
-#endif /* KERBEROS */
-
- port = sp->s_port;
- }
-
-
- if (cp == (char *) NULL) cp = getenv("TERM");
- if (cp) {
- (void) strncpy(term, cp, sizeof (term));
- term[sizeof (term) - 1] = '\0';
- }
-#ifdef POSIX_TERMIOS
- if (tcgetattr(0, &ttyb) == 0) {
- int ospeed = cfgetospeed (&ttyb);
-
- term[sizeof(term) - 1] = '\0';
- (void) strncat(term, "/", sizeof(term) - 1 - strlen(term));
- if (ospeed >= 50)
- /* On some systems, ospeed is the baud rate itself,
- not a table index. */
- snprintf (term + strlen (term),
- sizeof(term) - strlen(term), "%d", ospeed);
- else if (ospeed >= sizeof(speeds)/sizeof(char*))
- /* Past end of table, but not high enough to
- look like a real speed. */
- (void) strncat (term, speeds[sizeof(speeds)/sizeof(char*) - 1], sizeof(term) - 1 - strlen(term));
- else {
- (void) strncat(term, speeds[ospeed], sizeof(term) - 1 - strlen(term));
- }
- term[sizeof (term) - 1] = '\0';
- }
-#else
- if (ioctl(0, TIOCGETP, &ttyb) == 0) {
- (void) strncat(term, "/", sizeof(term) - 1 - strlen(term));
- (void) strncat(term, speeds[ttyb.sg_ospeed], sizeof(term) - 1 - strlen(term));
- }
-#endif
- (void) get_window_size(0, &winsize);
-
-#ifdef POSIX_TERMIOS
- tcgetattr(0, &defmodes);
- tcgetattr(0, &ixon_state);
-#else
-#ifdef USE_TERMIO
- /**** moved before rcmd call so that if get a SIGPIPE in rcmd **/
- /**** we will have the defmodes set already. ***/
- (void)ioctl(fileno(stdin), TIOCGETP, &defmodes);
- (void)ioctl(fileno(stdin), TIOCGETP, &ixon_state);
-#endif
-#endif
-
- /* Catch SIGPIPE, as that means we lost the connection */
- /* will use SIGUSR1 for window size hack, so hold it off */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = lostpeer;
- (void) sigaction(SIGPIPE, &sa, (struct sigaction *)0);
-
- (void) sigemptyset(&urgmask);
- (void) sigaddset(&urgmask, SIGUSR1);
- oldmask = &omask;
- (void) sigprocmask(SIG_BLOCK, &urgmask, oldmask);
-#else
- (void) signal(SIGPIPE, lostpeer);
-#ifdef sgi
- oldmask = sigignore( sigmask(SIGUSR1));
-#else
- oldmask = sigblock( sigmask(SIGUSR1));
-#endif
-#endif /* POSIX_SIGNALS */
-
-#ifdef KERBEROS
- authopts = AP_OPTS_MUTUAL_REQUIRED;
-
- /* Piggy-back forwarding flags on top of authopts; */
- /* they will be reset in kcmd */
- if (fflag || Fflag)
- authopts |= OPTS_FORWARD_CREDS;
- if (Fflag)
- authopts |= OPTS_FORWARDABLE_CREDS;
-
- status = kcmd(&sock, &host, port,
- null_local_username ? "" : pwd->pw_name,
- name ? name : pwd->pw_name, term,
- 0, "host", krb_realm,
- &cred,
- 0, /* No need for sequence number */
- 0, /* No need for server seq # */
- &local, &foreign,
- &auth_context, authopts,
- 0, /* Not any port # */
- 0,
- &kcmd_proto);
- if (status) {
- if (kcmd_proto == KCMD_NEW_PROTOCOL && encrypt_flag)
- /* Don't fall back to something less secure. */
- exit (1);
- try_normal(orig_argv);
- } else {
- krb5_keyblock *key = 0;
-
- if (kcmd_proto == KCMD_NEW_PROTOCOL) {
- do_inband = 1;
-
- status = krb5_auth_con_getsendsubkey (bsd_context, auth_context,
- &key);
- if ((status || !key) && encrypt_flag)
- try_normal(orig_argv);
- }
- if (key == 0)
- key = &cred->keyblock;
-
- rcmd_stream_init_krb5(key, encrypt_flag, 1, 1, kcmd_proto);
- }
-
- rem = sock;
-
-#else
- rem = rcmd(&host, port,
- null_local_username ? "" : pwd->pw_name,
- name ? name : pwd->pw_name, term, 0);
-#endif /* KERBEROS */
-
- if (rem < 0)
- exit(1);
-
- if (options & SO_DEBUG &&
- setsockopt(rem, SOL_SOCKET, SO_DEBUG, (char*)&on, sizeof (on)) < 0)
- perror("rlogin: setsockopt (SO_DEBUG)");
- uid = getuid();
- if (setuid(uid) < 0) {
- perror("rlogin: setuid");
- exit(1);
- }
- flowcontrol = flow; /* Set up really correct non-volatile variable */
- doit(oldmask);
- /*NOTREACHED*/
- usage:
-#ifdef KERBEROS
- fprintf (stderr,
- "usage: rlogin host [-option] [-option...] [-k realm ] [-t ttytype] [-l username]\n");
- fprintf (stderr, " where option is e, 7, 8, noflow, n, a, x, f, F, c, PO, or PN\n");
-#else /* !KERBEROS */
- fprintf (stderr,
- "usage: rlogin host [-option] [-option...] [-t ttytype] [-l username]\n");
- fprintf (stderr, " where option is e, 7, 8, noflow, n, a, or c\n");
-#endif /* KERBEROS */
- exit(1);
-}
-
-
-
-static int confirm_death ()
-{
- char hostname[33];
- char input;
- int answer;
- if (!confirm) return (1); /* no confirm, just die */
-
- if (gethostname (hostname, sizeof(hostname)-1) != 0)
- strlcpy (hostname, "???", sizeof(hostname));
- else
- hostname[sizeof(hostname)-1] = '\0';
-
- fprintf (stderr, "\r\nKill session on %s from %s (y/n)? ",
- host, hostname);
- fflush (stderr);
- if (read(0, &input, 1) != 1)
- answer = EOF; /* read from stdin */
- else
- answer = (int) input;
- fprintf (stderr, "%c\r\n", answer);
- fflush (stderr);
- return (answer == 'y' || answer == 'Y' || answer == EOF ||
- answer == 4); /* control-D */
-}
-
-
-
-#define CRLF "\r\n"
-
-int child;
-krb5_sigtype catchild (int);
-krb5_sigtype writeroob (int);
-
-int defflags, tabflag;
-int deflflags;
-char deferase, defkill;
-
-#ifdef USE_TERMIO
-char defvtim, defvmin;
-#if defined(hpux) || defined(__hpux)
-#include <sys/bsdtty.h>
-#include <sys/ptyio.h>
-#endif
-struct tchars {
- char t_intrc; /* interrupt */
- char t_quitc; /* quit */
- char t_startc; /* start output */
- char t_stopc; /* stop output */
- char t_eofc; /* end-of-file */
- char t_brkc; /* input delimiter (like nl) */
-};
-#endif
-
-
-#ifndef POSIX_TERMIOS
-#ifdef TIOCGLTC
-/*
- * POSIX 1003.1-1988 does not define a 'suspend' character.
- * POSIX 1003.1-1990 does define an optional VSUSP but not a VDSUSP character.
- * Some termio implementations (A/UX, Ultrix 4.2) include both.
- *
- * However, since this is all derived from the BSD ioctl() and ltchars
- * concept, all these implementations generally also allow for the BSD-style
- * ioctl(). So we'll simplify the problem by only testing for the ioctl().
- */
-struct ltchars defltc;
-struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
-#endif
-struct tchars deftc;
-struct tchars notc = { -1, -1, -1, -1, -1, -1 };
-#endif
-
-static void doit(oldmask)
-#ifdef POSIX_SIGNALS
- sigset_t *oldmask;
-#else
- int oldmask;
-#endif
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
-#ifdef POSIX_TERMIOS
- (void) tcgetattr(0, &deftty);
-#ifdef VLNEXT
- /* there's a POSIX way of doing this, but do we need it general? */
- deftty.c_cc[VLNEXT] = 0;
-#endif
-#else
-#ifdef USE_TERMIO
- struct termio sb;
-#else
- struct sgttyb sb;
-#endif
-
- (void) ioctl(0, TIOCGETP, (char *)&sb);
- defflags = sb.sg_flags;
-#ifdef USE_TERMIO
- tabflag = sb.c_oflag & TABDLY;
- defflags |= ECHO;
- deferase = sb.c_cc[VERASE];
- defkill = sb.c_cc[VKILL];
- sb.c_cc[VMIN] = 1;
- sb.c_cc[VTIME] = 1;
- defvtim = sb.c_cc[VTIME];
- defvmin = sb.c_cc[VMIN];
- deftc.t_quitc = CQUIT;
- deftc.t_startc = CSTART;
- deftc.t_stopc = CSTOP ;
- deftc.t_eofc = CEOF;
- deftc.t_brkc = '\n';
-#else
- tabflag = defflags & TBDELAY;
- defflags &= ECHO | CRMOD;
- deferase = sb.sg_erase;
- defkill = sb.sg_kill;
- (void) ioctl(0, TIOCLGET, (char *)&deflflags);
- (void) ioctl(0, TIOCGETC, (char *)&deftc);
-#endif
-
- notc.t_startc = deftc.t_startc;
- notc.t_stopc = deftc.t_stopc;
- (void) ioctl(0, TIOCGLTC, (char *)&defltc);
-#endif
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGINT, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGINT, SIG_IGN);
-#endif
-
- setsignal(SIGHUP, exit_handler);
- setsignal(SIGQUIT, exit_handler);
-
- child = fork();
- if (child == -1) {
- perror("rlogin: fork");
- done(1);
- }
- if (child == 0) {
- mode(1);
- if (reader(oldmask) == 0) {
- prf("Connection closed.");
- exit(0);
- }
- sleep(1);
- prf("\007Connection closed.");
- exit(3);
- }
-
-#ifdef POSIX_SIGNALS
- /* "sa" has already been initialized above. */
-
- sa.sa_handler = writeroob;
- (void) sigaction(SIGUSR1, &sa, (struct sigaction *)0);
-
- sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0);
-
- sa.sa_handler = catchild;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGUSR1, writeroob);
-#ifndef sgi
- (void) sigsetmask(oldmask);
-#endif
- (void) signal(SIGCHLD, catchild);
-#endif /* POSIX_SIGNALS */
- writer();
- prf("Closed connection.");
- done(0);
-}
-
-
-
-/*
- * Trap a signal, unless it is being ignored.
- */
-void
-setsignal(sig, act)
- int sig;
- krb5_sigtype (*act)();
-{
-#ifdef POSIX_SIGNALS
- sigset_t omask, igmask;
- struct sigaction sa;
-
- sigemptyset(&igmask);
- sigaddset(&igmask, sig);
- sigprocmask(SIG_BLOCK, &igmask, &omask);
-#else
-#ifdef sgi
- int omask = sigignore(sigmask(sig));
-#else
- int omask = sigblock(sigmask(sig));
-#endif
-#endif /* POSIX_SIGNALS */
-
-#ifdef POSIX_SIGNALS
- (void) sigaction(sig, (struct sigaction *)0, &sa);
- if (sa.sa_handler != SIG_IGN) {
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = act;
- (void) sigaction(sig, &sa, (struct sigaction *)0);
- }
- sigprocmask(SIG_SETMASK, &omask, (sigset_t*)0);
-#else
- if (signal(sig, act) == SIG_IGN)
- (void) signal(sig, SIG_IGN);
-#ifndef sgi
- (void) sigsetmask(omask);
-#endif
-#endif
-}
-
-
-
-static void
-done(status)
- int status;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-#ifndef HAVE_WAITPID
- pid_t w;
-#endif
-
- mode(0);
- if (child > 0) {
- /* make sure catchild does not snap it up */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_DFL;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGCHLD, SIG_DFL);
-#endif
-
- if (kill(child, SIGKILL) >= 0) {
-#ifdef HAVE_WAITPID
- (void) waitpid(child, 0, 0);
-#else
- while ((w = wait(0)) > 0 && w != child)
- /*void*/;
-#endif
- }
- }
- exit(status);
-}
-
-
-
-
-
-
-/*
- * This is called when the reader process gets the out-of-band (urgent)
- * request to turn on the window-changing protocol.
- */
-krb5_sigtype
- writeroob(signo)
-int signo;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
- if (dosigwinch == 0) {
- sendwindow();
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = sigwinch;
- (void) sigaction(SIGWINCH, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGWINCH, sigwinch);
-#endif
- }
- dosigwinch = 1;
-}
-
-
-
-krb5_sigtype
- catchild(signo)
-int signo;
-{
-#ifdef WAIT_USES_INT
- int status;
-#else
- union wait status;
-#endif
- int pid;
-
- again:
-#ifdef HAVE_WAITPID
- pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
-#else
- pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
-#endif
- if (pid == 0)
- return;
- /*
- * if the child (reader) dies, just quit
- */
-#ifdef WAIT_USES_INT
- if (pid < 0 || (pid == child && !WIFSTOPPED(status)))
- done(status);
-#else
- if ((pid < 0) || ((pid == child) && (!WIFSTOPPED(status))))
- done((int)(status.w_termsig | status.w_retcode));
-#endif
- goto again;
-}
-
-
-
-/*
- * writer: write to remote: 0 -> line.
- * ~. terminate
- * ~^Z suspend rlogin process.
- * ~^Y suspend rlogin process, but leave reader alone.
- */
-static void writer()
-{
- int n_read;
- char buf[1024];
- int got_esc; /* set to true by read_wrapper if an escape char
- was encountered */
- char c;
-
-#ifdef ultrix
- fd_set waitread;
- register n;
-
- /* we need to wait until the reader() has set up the terminal, else
- the read() below may block and not unblock when the terminal
- state is reset.
- */
- for (;;) {
- FD_ZERO(&waitread);
- FD_SET(0, &waitread);
- n = select(1, &waitread, 0, 0, 0, 0);
- if (n < 0 && errno == EINTR)
- continue;
- if (n > 0)
- break;
- else
- if (n < 0) {
- perror("select");
- break;
- }
- }
-#endif /* ultrix */
-
- /* This loop works as follows. Call read_wrapper to get data until
- we would block or until we read a cmdchar at the beginning of a line.
- If got_esc is false, we just send everything we got back. If got_esc
- is true, we send everything except the cmdchar at the end and look at
- the next char. If its a "." we break out of the loop and terminate.
- If its ^Z or ^Y we call stop with the value of the char and continue.
- If its none of those, we send the cmdchar and then send the char we
- just read, unless that char is also the cmdchar (in which case we are
- only supposed to send one of them). When this loop ends, so does the
- program.
- */
-
- for (;;) {
-
- /* read until we would block or we get a cmdchar */
- n_read = read_wrapper(0,buf,sizeof(buf),&got_esc);
-
- /* if read returns an error or 0 bytes, just quit */
- if (n_read <= 0) {
- break;
- }
-
- if (!got_esc) {
- if (rcmd_stream_write(rem, buf, (unsigned) n_read, 0) == 0) {
- prf("line gone");
- break;
- }
- continue;
- }
- else {
- /* This next test is necessary to avoid sending 0 bytes of data
- in the event that we got just a cmdchar */
- if (n_read > 1) {
- if (rcmd_stream_write(rem, buf, (unsigned) (n_read-1), 0) == 0) {
- prf("line gone");
- break;
- }
- }
- if (read_wrapper(0,&c,1,&got_esc) <= 0) {
- break;
- }
-
-#ifdef POSIX_TERMIOS
- if (c == '.' || c == deftty.c_cc[VEOF])
-#else
- if (c == '.' || c == deftc.t_eofc)
-#endif
- {
- if (confirm_death()) {
- echo(c);
- break;
- }
- }
-
-#ifdef POSIX_TERMIOS
- if ( (
- (c == deftty.c_cc[VSUSP])
-#ifdef VDSUSP
- || (c == deftty.c_cc[VDSUSP])
-#endif
- )
- && !no_local_escape) {
- echo(c);
- stop(c);
- continue;
- }
-#else /*POSIX_TERMIOS*/
-#ifdef TIOCGLTC
- if ((c == defltc.t_suspc || c == defltc.t_dsuspc)
- && !no_local_escape) {
- echo(c);
- stop(c);
- continue;
- }
-#endif /*TIOCGLTC*/
-#endif
-
-
- if (c != cmdchar) {
- rcmd_stream_write(rem, &cmdchar, 1, 0);
- }
-
- if (rcmd_stream_write(rem,&c,1,0) == 0) {
- prf("line gone");
- break;
- }
- }
- }
-}
-
-/* This function reads up to size bytes from file desciptor fd into buf.
- It will copy as much data as it can without blocking, but will never
- copy more than size bytes. In addition, if it encounters a cmdchar
- at the beginning of a line, it will copy everything up to and including
- the cmdchar, but nothing after that. In this instance *esc_char is set
- to true and any remaining data is buffered and copied on a subsequent
- call. Otherwise, *esc_char will be set to false and the minimum of size,
- 1024, and the number of bytes that can be read without blocking will
- be copied. In all cases, a non-negative return value indicates the number
- of bytes actually copied and a return value of -1 indicates that there
- was a read error (other than EINTR) and errno is set appropriately.
-*/
-
-static int read_wrapper(fd,buf,size,got_esc)
- int fd;
- char *buf;
- int size;
- int *got_esc;
-{
- static char tbuf[1024];
- static char *data_start = tbuf;
- static char *data_end = tbuf;
- static int bol = 1;
- unsigned int return_length = 0;
- char c;
-
- /* if we have no data buffered, get more */
- if (data_start == data_end) {
- int n_read;
- while ((n_read = read(fd, tbuf, sizeof(tbuf))) <= 0) {
- if (n_read < 0 && errno == EINTR)
- continue;
- return n_read;
- }
- data_start = tbuf;
- data_end = tbuf+n_read;
- }
-
- *got_esc = 0;
-
- /* We stop when we've fully checked the buffer or have checked size
- bytes. We break out and set *got_esc if we encounter a cmdchar
- at the beginning of a line.
- */
-
- while (data_start+return_length < data_end && return_length < size) {
-
- c = *(data_start+return_length);
- return_length++;
-
- if (bol == 1 && c == cmdchar) {
- bol = 0;
- *got_esc = 1;
- break;
- }
-
-#ifdef POSIX_TERMIOS
- bol = (c == deftty.c_cc[VKILL] ||
- c == deftty.c_cc[VINTR] ||
- c == '\r' || c == '\n');
-
-#else /* !POSIX_TERMIOS */
- bol = c == defkill || c == deftc.t_eofc ||
- c == deftc.t_intrc || c == defltc.t_suspc ||
- c == '\r' || c == '\n';
-#endif
- }
-
- memcpy(buf, data_start, return_length);
- data_start = data_start + return_length;
- return return_length;
-}
-
-static void echo(c)
- register char c;
-{
- char buf[8];
- register char *p = buf;
-
- c &= 0177;
- *p++ = cmdchar;
- if (c < ' ') {
- *p++ = '^';
- *p++ = c + '@';
- } else if (c == 0177) {
- *p++ = '^';
- *p++ = '?';
- } else
- *p++ = c;
- *p++ = '\r';
- *p++ = '\n';
- (void) write(1, buf, (unsigned) (p - buf));
-}
-
-
-
-static void stop(cmdc)
- char cmdc;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
- mode(0);
-
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGCHLD, SIG_IGN);
-#endif
-
-#ifdef POSIX_TERMIOS
- (void) kill(cmdc == deftty.c_cc[VSUSP] ? 0 : getpid(), SIGTSTP);
-#else
-#ifdef TIOCGLTC
- (void) kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
-#endif
-#endif
-#ifdef POSIX_SIGNALS
- sa.sa_handler = catchild;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGCHLD, catchild);
-#endif
-
- mode(1);
- sigwinch(SIGWINCH); /* check for size changes */
-}
-
-
-
-krb5_sigtype
- sigwinch(signo)
-int signo;
-{
- struct winsize ws;
-
- if (dosigwinch && get_window_size(0, &ws) == 0 &&
- memcmp(&winsize, &ws, sizeof (ws))) {
- winsize = ws;
- sendwindow();
- }
-}
-
-
-
-/*
- * Send the window size to the server via the magic escape
- */
-static void sendwindow()
-{
- char obuf[4 + sizeof (struct winsize)];
- struct winsize *wp = (struct winsize *)(void *)(obuf+4);
-
- obuf[0] = 0377;
- obuf[1] = 0377;
- obuf[2] = 's';
- obuf[3] = 's';
- wp->ws_row = htons(winsize.ws_row);
- wp->ws_col = htons(winsize.ws_col);
- wp->ws_xpixel = htons(winsize.ws_xpixel);
- wp->ws_ypixel = htons(winsize.ws_ypixel);
- (void) rcmd_stream_write(rem, obuf, sizeof(obuf), 0);
-}
-
-
-
-/*
- * reader: read from remote: line -> 1
- */
-#define READING 1
-#define WRITING 2
-
-char rcvbuf[8 * 1024];
-int rcvcnt;
-int rcvstate;
-int ppid;
-
-/* returns 1 if flush, 0 otherwise */
-
-int server_message(mark)
- int mark;
-{
-#ifndef POSIX_TERMIOS
- int out = FWRITE;
-#endif
-#ifdef POSIX_TERMIOS
- struct termios tty;
-#else
-#ifdef USE_TERMIO
- struct termio sb;
-#else
- struct sgttyb sb;
-#endif
-#endif
-
- if (mark & TIOCPKT_WINDOW) {
- /*
- * Let server know about window size changes
- */
- (void) kill(ppid, SIGUSR1);
- }
-#ifdef POSIX_TERMIOS
- if (!eight && (mark & TIOCPKT_NOSTOP)) {
- (void) tcgetattr(0, &tty);
- tty.c_iflag &= ~IXON;
- (void) tcsetattr(0, TCSADRAIN, &tty);
- }
- if (!eight && (mark & TIOCPKT_DOSTOP)) {
- (void) tcgetattr(0, &tty);
- tty.c_iflag |= IXON;
- (void) tcsetattr(0, TCSADRAIN, &tty);
- }
-#else
- if (!eight && (mark & TIOCPKT_NOSTOP)) {
- (void) ioctl(0, TIOCGETP, (char *)&sb);
-#ifdef USE_TERMIO
- sb.c_iflag |= IXOFF;
- sb.sg_flags &= ~ICANON;
-#else
- sb.sg_flags &= ~CBREAK;
- sb.sg_flags |= RAW;
- notc.t_stopc = -1;
- notc.t_startc = -1;
- (void) ioctl(0, TIOCSETC, (char *)&notc);
-#endif
- (void) ioctl(0, TIOCSETN, (char *)&sb);
- }
- if (!eight && (mark & TIOCPKT_DOSTOP)) {
- (void) ioctl(0, TIOCGETP, (char *)&sb);
-#ifdef USE_TERMIO
- sb.sg_flags |= ICANON;
- sb.c_iflag |= IXON;
-#else
- sb.sg_flags &= ~RAW;
- sb.sg_flags |= CBREAK;
- notc.t_stopc = deftc.t_stopc;
- notc.t_startc = deftc.t_startc;
- (void) ioctl(0, TIOCSETC, (char *)&notc);
-#endif
- (void) ioctl(0, TIOCSETN, (char *)&sb);
- }
-#endif
- if (mark & TIOCPKT_FLUSHWRITE) {
-#ifdef POSIX_TERMIOS
- (void) tcflush(1, TCOFLUSH);
-#else
-#ifdef TIOCFLUSH
- (void) ioctl(1, TIOCFLUSH, (char *)&out);
-#else
- (void) ioctl(1, TCFLSH, 1);
-#endif
-#endif
- return(1);
- }
-
- return(0);
-}
-
-void oob()
-{
- char mark;
- static char waste[RLOGIN_BUFSIZ];
- int atmark, n;
-
- mark = 0;
-
- recv(rem, &mark, 1, MSG_OOB);
-
- if (server_message(mark)) {
- for (;;) {
- if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
- perror("ioctl");
- return;
- }
- if (atmark)
- break;
- n = read(rem, waste, sizeof (waste));
- if (n <= 0)
- break;
- }
- }
-}
-
-/* two control messages are defined:
-
- a double flag byte of 'o' indicates a one-byte message which is
- identical to what was once carried out of band.
-
- a double flag byte of 'q' indicates a zero-byte message. This
- message is interpreted as two \377 data bytes. This is just a
- quote rule so that binary data from the server does not confuse the
- client. */
-
-static int control(cp, n)
- char *cp;
- unsigned int n;
-{
- if ((n >= 5) && (cp[2] == 'o') && (cp[3] == 'o')) {
- if (server_message(cp[4]))
- return(-5);
- return(5);
- } else if ((n >= 4) && (cp[2] == 'q') && (cp[3] == 'q')) {
- /* this is somewhat of a hack */
- cp[2] = '\377';
- cp[3] = '\377';
- return(2);
- }
-
- return(0);
-}
-
-/*
- * reader: read from remote: line -> 1
- */
-static int
-reader(oldmask)
-#ifdef POSIX_SIGNALS
- sigset_t *oldmask;
-#else
- int oldmask;
-#endif
-{
- fd_set readset, excset, writeset;
- int n, remaining;
- unsigned int left;
- char *bufp = rcvbuf;
- char *cp;
-
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
-
-#else
- (void) signal(SIGTTOU, SIG_IGN);
-#endif
-
- ppid = getppid();
- FD_ZERO(&readset);
- FD_ZERO(&excset);
- FD_ZERO(&writeset);
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0);
-#else
-#ifndef sgi
- (void) sigsetmask(oldmask);
-#endif
-#endif /* POSIX_SIGNALS */
-
- for (;;) {
- if ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
- FD_SET(1,&writeset);
- rcvstate = WRITING;
- FD_CLR(rem, &readset);
- } else {
- bufp = rcvbuf;
- rcvcnt = 0;
- rcvstate = READING;
- FD_SET(rem,&readset);
- FD_CLR(1,&writeset);
- }
- if (!do_inband)
- FD_SET(rem,&excset);
- if (select(rem+1, &readset, &writeset, &excset, 0) > 0 ) {
- if (!do_inband)
- if (FD_ISSET(rem, &excset))
- oob();
- if (FD_ISSET(1,&writeset)) {
- n = write(1, bufp, remaining);
- if (n < 0) {
- if (errno != EINTR)
- return (-1);
- continue;
- }
- bufp += n;
- }
- if (FD_ISSET(rem, &readset)) {
- rcvcnt = rcmd_stream_read(rem, rcvbuf, sizeof (rcvbuf), 0);
- if (rcvcnt == 0)
- return (0);
- if (rcvcnt < 0)
- goto error;
-
- if (do_inband) {
- for (cp = rcvbuf; cp < rcvbuf+rcvcnt-1; cp++) {
- if (cp[0] == '\377' &&
- cp[1] == '\377') {
- left = (rcvbuf+rcvcnt) - cp;
- n = control(cp, left);
- /* |n| <= left */
- if (n < 0) {
- left -= (-n);
- rcvcnt = 0;
- /* flush before, and (-n) bytes */
- if (left > 0)
- memmove(rcvbuf, cp+(-n), left);
- cp = rcvbuf-1;
- } else if (n) {
- left -= n;
- rcvcnt -= n;
- if (left > 0)
- memmove(cp, cp+n, left);
- cp--;
- }
- }
- }
- }
- }
- } else
-error:
- {
- if (errno == EINTR)
- continue;
- perror("read");
- return (-1);
- }
- }
-}
-
-
-
-static void mode(f)
-int f;
-{
-#ifdef POSIX_TERMIOS
- struct termios newtty;
-#ifndef IEXTEN
-#define IEXTEN 0 /* No effect*/
-#endif
-#ifndef _POSIX_VDISABLE
-#define _POSIX_VDISABLE 0 /*A good guess at the disable-this-character character*/
-#endif
-
- switch(f) {
- case 0:
- (void) tcsetattr(0, TCSADRAIN, &deftty);
- break;
- case 1:
- (void) tcgetattr(0, &newtty);
- /* was __svr4__ */
-#ifdef VLNEXT
- /* there's a POSIX way of doing this, but do we need it general? */
- newtty.c_cc[VLNEXT] = _POSIX_VDISABLE;
-#endif
-
- newtty.c_lflag &= ~(ICANON|ISIG|ECHO|IEXTEN);
- newtty.c_iflag &= ~(ISTRIP|INLCR|ICRNL);
-
- if (!flow) {
- newtty.c_iflag &= ~(BRKINT|IXON|IXANY);
- newtty.c_oflag &= ~(OPOST);
- } else {
- /* XXX - should we set ixon ? */
- newtty.c_iflag &= ~(IXON|IXANY);
- newtty.c_iflag |= (BRKINT);
- newtty.c_oflag &= ~(ONLCR|ONOCR);
- newtty.c_oflag |= (OPOST);
- }
-#ifdef TABDLY
- /* preserve tab delays, but turn off XTABS */
- if ((newtty.c_oflag & TABDLY) == TAB3)
- newtty.c_oflag &= ~TABDLY;
-#endif
- if (!eight)
- newtty.c_iflag |= ISTRIP;
- if (litout)
- newtty.c_oflag &= ~OPOST;
-
- newtty.c_cc[VMIN] = 1;
- newtty.c_cc[VTIME] = 0;
- (void) tcsetattr(0, TCSADRAIN, &newtty);
- break;
- default:
- return;
- /* NOTREACHED */
- }
-#else
- struct ltchars *ltc;
-#ifdef USE_TERMIO
- struct termio sb;
-#else
- struct tchars *tc;
- struct sgttyb sb;
- int lflags;
- (void) ioctl(0, TIOCLGET, (char *)&lflags);
-#endif
-
- (void) ioctl(0, TIOCGETP, (char *)&sb);
- switch (f) {
-
- case 0:
-#ifdef USE_TERMIO
- /*
- ** remember whether IXON was set, so it can be restored
- ** when mode(1) is next done
- */
- (void) ioctl(fileno(stdin), TIOCGETP, &ixon_state);
- /*
- ** copy the initial modes we saved into sb; this is
- ** for restoring to the initial state
- */
- sb = defmodes;
-#else
- sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
- sb.sg_flags |= defflags|tabflag;
- sb.sg_kill = defkill;
- sb.sg_erase = deferase;
- lflags = deflflags;
- tc = &deftc;
-#endif
- ltc = &defltc;
- break;
-
- case 1:
-#ifdef USE_TERMIO
- /*
- ** turn off output mappings
- */
- sb.c_oflag &= ~(ONLCR|OCRNL);
- /*
- ** turn off canonical processing and character echo;
- ** also turn off signal checking -- ICANON might be
- ** enough to do this, but we're being careful
- */
- sb.c_lflag &= ~(ECHO|ICANON|ISIG);
- sb.c_cc[VTIME] = 1;
- sb.c_cc[VMIN] = 1;
- if (eight)
- sb.c_iflag &= ~(ISTRIP);
-#ifdef TABDLY
- /* preserve tab delays, but turn off tab-to-space expansion */
- if ((sb.c_oflag & TABDLY) == TAB3)
- sb.c_oflag &= ~TAB3;
-#endif
- /*
- ** restore current flow control state
- */
- if ((ixon_state.c_iflag & IXON) && flow ) {
- sb.c_iflag |= IXON;
- } else {
- sb.c_iflag &= ~IXON;
- }
-#else /* ! USE_TERMIO */
- sb.sg_flags &= ~(CBREAK|RAW);
- sb.sg_flags |= (!flow ? RAW : CBREAK);
- /* preserve tab delays, but turn off XTABS */
- if ((sb.sg_flags & TBDELAY) == XTABS)
- sb.sg_flags &= ~TBDELAY;
- sb.sg_kill = sb.sg_erase = -1;
-#ifdef LLITOUT
- if (litout)
- lflags |= LLITOUT;
-#endif
-#ifdef LPASS8
- if (eight)
- lflags |= LPASS8;
-#endif /* LPASS8 */
- tc = &notc;
- sb.sg_flags &= ~defflags;
-#endif /* USE_TERMIO */
-
- ltc = &noltc;
- break;
-
- default:
- return;
- }
- (void) ioctl(0, TIOCSLTC, (char *)ltc);
-#ifndef USE_TERMIO
- (void) ioctl(0, TIOCSETC, (char *)tc);
- (void) ioctl(0, TIOCLSET, (char *)&lflags);
-#endif
- (void) ioctl(0, TIOCSETN, (char *)&sb);
-#endif /* !POSIX_TERMIOS */
-}
-
-
-
-static void
-prf(f)
- char *f;
-{
- fprintf(stderr, "%s", f);
- fprintf(stderr, CRLF);
-}
-
-
-
-#ifdef KERBEROS
-void try_normal(argv)
- char **argv;
-{
- register char *nhost;
-#ifdef POSIX_SIGNALS
- sigset_t mask;
-#endif
-
-#ifndef KRB5_ATHENA_COMPAT
- if (encrypt_flag)
- exit(1);
-#endif
- fprintf(stderr,"trying normal rlogin (%s)\n",
- UCB_RLOGIN);
- fflush(stderr);
-
- nhost = strrchr(argv[0], '/');
- if (nhost)
- nhost++;
- else
- nhost = argv[0];
- if (!strcmp(nhost, "rlogin") || !strcmp(nhost, "rsh"))
- argv[0] = UCB_RLOGIN;
-
-#ifdef POSIX_SIGNALS
- sigemptyset(&mask);
- sigprocmask(SIG_SETMASK, &mask, NULL);
-#endif
-
- execv(UCB_RLOGIN, argv);
- perror("exec");
- exit(1);
-}
-#endif
-
-
-
-krb5_sigtype lostpeer(signo)
- int signo;
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGPIPE, &sa, (struct sigaction *)0);
-#else
- (void) signal(SIGPIPE, SIG_IGN);
-#endif
-
- prf("\007Connection closed.");
- done(1);
-}
diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c
deleted file mode 100644
index cc7acad643..0000000000
--- a/src/appl/bsd/krlogind.c
+++ /dev/null
@@ -1,1430 +0,0 @@
-/*
- * appl/bsd/krlogind.c
- */
-
-/*
- * Copyright (c) 1983 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.
- */
-
-/*
- * Copyright (C) 1998 by the FundsXpress, INC.
- *
- * All rights reserved.
- *
- * Export of this software from the United States of America may require
- * a specific license from the United States Government. It is the
- * responsibility of any person or organization contemplating export to
- * obtain such a license before exporting.
- *
- * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- * distribute this software and its documentation for any purpose and
- * without fee is hereby granted, provided that the above copyright
- * notice appear in all copies and that both that copyright notice and
- * this permission notice appear in supporting documentation, and that
- * the name of FundsXpress. not be used in advertising or publicity pertaining
- * to distribution of the software without specific, written prior
- * permission. FundsXpress makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * 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.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rlogind.c 5.17 (Berkeley) 8/31/88 */
-
- /*
- * remote login server:
- * remuser\0
- * locuser\0
- * terminal info\0
- * data
- */
-
-/*
- * This is the rlogin daemon. The very basic protocol for checking
- * authentication and authorization is:
- * 1) Check authentication.
- * 2) Check authorization via the access-control files:
- * ~/.k5login (using krb5_kuserok) and/or
- * 3) Prompt for password if any checks fail, or if so configured.
- * Allow login if all goes well either by calling the accompanying
- * login.krb5 or /bin/login, according to the definition of
- * DO_NOT_USE_K_LOGIN.l
- *
- * The configuration is done either by command-line arguments passed by
- * inetd, or by the name of the daemon. If command-line arguments are
- * present, they take priority. The options are:
- * -k means trust krb5
- * -p and -P means prompt for password.
- * If the -P option is passed, then the password is verified in
- * addition to all other checks. If -p is not passed with -k or -r,
- * and both checks fail, then login permission is denied.
- * - -e means use encryption.
- *
- * If no command-line arguments are present, then the presence of the
- * letters kKrRexpP in the program-name before "logind" determine the
- * behaviour of the program exactly as with the command-line arguments.
- *
- * If the ruserok check is to be used, then the client should connect
- * from a privileged port, else deny permission.
- */
-
-/* DEFINES:
- * KERBEROS - Define this if application is to be kerberised.
- * CRYPT - Define this if encryption is to be an option.
- * DO_NOT_USE_K_LOGIN - Define this if you want to use /bin/login
- * instead of the accompanying login.krb5.
- * LOG_ALL_LOGINS - Define this if you want to log all logins.
- * LOG_OTHER_USERS - Define this if you want to log all principals
- * that do not map onto the local user.
- * LOG_REMOTE_REALM - Define this if you want to log all principals from
- * remote realms.
- * Note: Root logins are always logged.
- */
-
-/*
- * This is usually done in the Makefile. Actually, these sources may
- * not work without the KERBEROS #defined.
- *
- * #define KERBEROS
- */
-#define LOG_REMOTE_REALM
-#define CRYPT
-#define USE_LOGIN_F
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef __SCO__
-#include <sys/unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifndef KERBEROS
-/* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
-#include <sys/socket.h>
-#endif
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#include <sys/file.h>
-#include <sys/time.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <pwd.h>
-
-#ifdef HAVE_SYS_LABEL_H
-/* only SunOS 4? */
-#include <sys/label.h>
-#include <sys/audit.h>
-#include <pwdadj.h>
-#endif
-
-#include <signal.h>
-
-#if defined(hpux) || defined(__hpux)
-#include <sys/ptyio.h>
-#endif
-#ifdef sysvimp
-#include <compat.h>
-#endif
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_STREAMS
-#include <sys/stream.h>
-#include <sys/stropts.h>
-#endif
-
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
-#include <termios.h>
-#else
-#include <sgtty.h>
-#endif
-
-#ifndef KERBEROS
-/* Ultrix doesn't protect it vs multiple inclusion, and krb.h includes it */
-#include <netdb.h>
-#endif
-#include <syslog.h>
-#include <string.h>
-#include <sys/param.h>
-
-#ifdef HAVE_STREAMS
-/* krlogin doesn't test sys/tty... */
-#ifdef HAVE_SYS_TTY_H
-#include <sys/tty.h>
-#endif
-
-#ifdef HAVE_SYS_PTYVAR_H
-/* Solaris actually uses packet mode, so the real macros are needed too */
-#include <sys/ptyvar.h>
-#endif
-#endif
-
-
-#ifndef TIOCPKT_NOSTOP
-/* These values are over-the-wire protocol, *not* local values */
-#define TIOCPKT_NOSTOP 0x10
-#define TIOCPKT_DOSTOP 0x20
-#define TIOCPKT_FLUSHWRITE 0x02
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
-/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
-#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;
- unsigned short ws_xpixel, ws_ypixel;
-};
-#endif /* NO_WINSIZE */
-
-#ifndef roundup
-#define roundup(x,y) ((((x)+(y)-1)/(y))*(y))
-#endif
-
-#include "fake-addrinfo.h"
-
-#ifdef KERBEROS
-
-#include "k5-int.h"
-#include <libpty.h>
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#include <k5-util.h>
-#endif
-
-int non_privileged = 0; /* set when connection is seen to be from */
- /* a non-privileged port */
-
-#include "com_err.h"
-#include "defines.h"
-
-#define SECURE_MESSAGE "This rlogin session is encrypting all data transmissions.\r\n"
-
-krb5_authenticator *kdata;
-krb5_ticket *ticket = 0;
-krb5_context bsd_context;
-krb5_ccache ccache = NULL;
-
-krb5_keytab keytab = NULL;
-
-#define ARGSTR "k5ciepPD:S:M:L:fw:?"
-#else /* !KERBEROS */
-#define ARGSTR "rpPD:f?"
-#endif /* KERBEROS */
-
-#ifndef LOGIN_PROGRAM
-#ifdef DO_NOT_USE_K_LOGIN
-#ifdef sysvimp
-#define LOGIN_PROGRAM "/bin/remlogin"
-#else
-#define LOGIN_PROGRAM "/bin/login"
-#endif
-#else /* DO_NOT_USE_K_LOGIN */
-#define LOGIN_PROGRAM KRB5_PATH_LOGIN
-#endif /* DO_NOT_USE_K_LOGIN */
-#endif /* LOGIN_PROGRAM */
-
-char *login_program = LOGIN_PROGRAM;
-
-#define MAXRETRIES 4
-#define MAX_PROG_NAME 16
-
-#ifndef UT_NAMESIZE /* linux defines it directly in <utmp.h> */
-#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
-#endif
-
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-
-#ifndef MAXDNAME
-#define MAXDNAME 256 /*per the rfc*/
-#endif
-
-char lusername[UT_NAMESIZE+1];
-char rusername[UT_NAMESIZE+1];
-char *krusername = 0;
-char term[64];
-char rhost_name[MAXDNAME];
-char rhost_addra[16];
-krb5_principal client;
-int do_inband = 0;
-
-int reapchild();
-char *progname;
-
-static int Pfd;
-
-#if defined(NEED_DAEMON_PROTO)
-extern int daemon(int, int);
-#endif
-
-#if (defined(_AIX) && defined(i386)) || defined(ibm032) || (defined(vax) && !defined(ultrix)) || (defined(SunOS) && SunOS > 40) || defined(solaris20)
-#define VHANG_FIRST
-#endif
-
-#if defined(ultrix)
-#define VHANG_LAST /* vhangup must occur on close, not open */
-#endif
-
-void fatal(int, const char *), fatalperror(int, const char *), doit(int, struct sockaddr *), usage(void), do_krb_login(char *, char *), getstr(int, char *, int, char *);
-void protocol(int, int);
-int princ_maps_to_lname(krb5_principal, char *), default_realm(krb5_principal);
-krb5_sigtype cleanup(int);
-krb5_error_code recvauth(int *);
-
-int do_encrypt = 0, passwd_req = 0;
-int checksum_required = 0, checksum_ignored = 0;
-
-int stripdomain = 1;
-int maxhostlen = 0;
-int always_ip = 0;
-
-int main(argc, argv)
- int argc;
- char **argv;
-{
- extern int opterr, optind;
- extern char * optarg;
- int on = 1, ch;
- socklen_t fromlen;
- struct sockaddr_storage from;
- int debug_port = 0;
- int fd;
- int do_fork = 0;
-#ifdef KERBEROS
- krb5_error_code status;
-#endif
-
- progname = *argv;
-
- pty_init();
-
-#ifndef LOG_NDELAY
-#define LOG_NDELAY 0
-#endif
-
-#ifndef LOG_AUTH /* 4.2 syslog */
- openlog(progname, LOG_PID | LOG_NDELAY);
-#else
- openlog(progname, LOG_PID | LOG_NDELAY, LOG_AUTH);
-#endif /* 4.2 syslog */
-
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- syslog(LOG_ERR, "Error initializing krb5: %s",
- error_message(status));
- exit(1);
- }
-#endif
-
- /* Analyse parameters. */
- opterr = 0;
- while ((ch = getopt(argc, argv, ARGSTR)) != -1)
- switch (ch) {
-#ifdef KERBEROS
- case 'k':
- break;
-
- case '5':
- break;
- case 'c':
- checksum_required = 1;
- break;
- case 'i':
- checksum_ignored = 1;
- break;
-
-#ifdef CRYPT
- case 'x': /* Use encryption. */
- case 'X':
- case 'e':
- case 'E':
- do_encrypt = 1;
- break;
-#endif
- case 'S':
- if ((status = krb5_kt_resolve(bsd_context, optarg, &keytab))) {
- com_err(progname, status, "while resolving srvtab file %s",
- optarg);
- exit(2);
- }
- break;
- case 'M':
- krb5_set_default_realm(bsd_context, optarg);
- break;
-#endif
- case 'p':
- break;
- case 'P': /* passwd is a must */
- passwd_req = 1;
- break;
- case 'D':
- debug_port = atoi(optarg);
- break;
- case 'L':
- login_program = optarg;
- break;
- case 'f':
- do_fork = 1;
- break;
- case 'w':
- if (!strcmp(optarg, "ip"))
- always_ip = 1;
- else {
- char *cp;
- cp = strchr(optarg, ',');
- if (cp == NULL)
- maxhostlen = atoi(optarg);
- else if (*(++cp)) {
- if (!strcmp(cp, "striplocal"))
- stripdomain = 1;
- else if (!strcmp(cp, "nostriplocal"))
- stripdomain = 0;
- else {
- usage();
- exit(1);
- }
- *(--cp) = '\0';
- maxhostlen = atoi(optarg);
- }
- }
- break;
- case '?':
- default:
- usage();
- exit(1);
- break;
- }
- argc -= optind;
- argv += optind;
-
- fromlen = sizeof (from);
-
- if (debug_port || do_fork) {
- int s;
- struct servent *ent;
- struct sockaddr_in sock_in;
-
- if (!debug_port) {
- if (do_encrypt) {
- ent = getservbyname("eklogin", "tcp");
- if (ent == NULL)
- debug_port = 2105;
- else
- debug_port = ent->s_port;
- } else {
- ent = getservbyname("klogin", "tcp");
- if (ent == NULL)
- debug_port = 543;
- else
- debug_port = ent->s_port;
- }
- }
- if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
- fprintf(stderr, "Error in socket: %s\n", strerror(errno));
- exit(2);
- }
- memset(&sock_in, 0,sizeof(sock_in));
- sock_in.sin_family = AF_INET;
- sock_in.sin_port = htons(debug_port);
- sock_in.sin_addr.s_addr = INADDR_ANY;
-
- if (!do_fork)
- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on));
-
- if ((bind(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) < 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 (do_fork) {
- if (daemon(0, 0)) {
- fprintf(stderr, "daemon() failed\n");
- exit(2);
- }
- while (1) {
- int child_pid;
-
- fd = accept(s, (struct sockaddr *) &from, &fromlen);
- if (fd < 0) {
- if (errno != EINTR)
- syslog(LOG_ERR, "accept: %s", error_message(errno));
- continue;
- }
- child_pid = fork();
- switch (child_pid) {
- case -1:
- syslog(LOG_ERR, "fork: %s", error_message(errno));
- case 0:
- (void) close(s);
- doit(fd, (struct sockaddr *) &from);
- close(fd);
- exit(0);
- default:
- wait(0);
- close(fd);
- }
- }
- }
-
- if ((fd = accept(s, (struct sockaddr *) &from, &fromlen)) < 0) {
- fprintf(stderr, "Error in accept: %s\n", strerror(errno));
- exit(2);
- }
-
- close(s);
- } else { /* !do_fork && !debug_port */
- 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");
-#else
- fatal(2, "Can't get peer name of remote host");
-#endif
- }
- fd = 0;
- }
-
- doit(fd, (struct sockaddr *) &from);
- return 0;
-}
-
-
-
-#ifndef LOG_AUTH
-#define LOG_AUTH 0
-#endif
-
-int child;
-int netf;
-char line[MAXPATHLEN];
-extern char *inet_ntoa();
-
-#ifdef TIOCSWINSZ
-struct winsize win = { 0, 0, 0, 0 };
-#endif
-
-int pid; /* child process id */
-
-void doit(f, fromp)
- int f;
- struct sockaddr *fromp;
-{
- int p, t, on = 1;
- char c;
- char hname[NI_MAXHOST];
- char buferror[255];
- struct passwd *pwd;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
- int retval;
- char *rhost_sane;
- int syncpipe[2];
-
- netf = -1;
- if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE,
- (const char *) &on, sizeof (on)) < 0)
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
-
- if (checksum_required&&checksum_ignored) {
- syslog( LOG_CRIT, "Checksums are required and ignored; these options are mutually exclusive--check the documentation.");
- fatal(f, "Configuration error: mutually exclusive options specified");
- }
-
- alarm(60);
- read(f, &c, 1);
-
- if (c != 0){
- exit(1);
- }
-
- alarm(0);
- /* Initialize syncpipe */
- if (pipe( syncpipe ) < 0 )
- fatalperror ( f , "");
-
-
-#ifdef POSIX_SIGNALS
- /* Initialize "sa" structure. */
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
-#endif
-
- retval = getnameinfo(fromp, socklen(fromp), hname, sizeof(hname), 0, 0,
- NI_NUMERICHOST);
- if (retval)
- fatal(f, gai_strerror(retval));
- strncpy(rhost_addra, hname, sizeof(rhost_addra));
- rhost_addra[sizeof (rhost_addra) -1] = '\0';
-
- retval = getnameinfo(fromp, socklen(fromp), hname, sizeof(hname), 0, 0, 0);
- if (retval)
- fatal(f, gai_strerror(retval));
- strncpy(rhost_name, hname, sizeof(rhost_name));
- rhost_name[sizeof (rhost_name) - 1] = '\0';
-
-#ifndef KERBEROS
- if (fromp->sin_family != AF_INET)
- /* Not a real problem, we just haven't bothered to update
- the port number checking code to handle ipv6. */
- fatal(f, "Permission denied - Malformed from address\n");
-
- if (fromp->sin_port >= IPPORT_RESERVED ||
- fromp->sin_port < IPPORT_RESERVED/2)
- fatal(f, "Permission denied - Connection from bad port");
-#endif /* KERBEROS */
-
- /* Set global netf to f now : we may need to drop everything
- in do_krb_login. */
- netf = f;
-
-#if defined(KERBEROS)
- /* All validation, and authorization goes through do_krb_login() */
- do_krb_login(rhost_addra, rhost_name);
-#else
- getstr(f, rusername, sizeof(rusername), "remuser");
- getstr(f, lusername, sizeof(lusername), "locuser");
- getstr(f, term, sizeof(term), "Terminal type");
- rcmd_stream_init_normal();
-#endif
-
- write(f, "", 1);
- if ((retval = pty_getpty(&p,line, sizeof(line)))) {
- com_err(progname, retval, "while getting master pty");
- exit(2);
- }
-
- Pfd = p;
-#ifdef TIOCSWINSZ
- (void) ioctl(p, TIOCSWINSZ, &win);
-#endif
-
-#ifdef POSIX_SIGNALS
- sa.sa_handler = cleanup;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
- (void) sigaction(SIGTERM, &sa, (struct sigaction *)0);
-#else
- signal(SIGCHLD, cleanup);
- signal(SIGTERM, cleanup);
-#endif
- pid = fork();
- if (pid < 0)
- fatalperror(f, "");
- if (pid == 0) {
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
- struct termios new_termio;
-#else
- struct sgttyb b;
-#endif /* POSIX_TERMIOS */
- if ((retval = pty_open_slave(line, &t))) {
- fatal(f, error_message(retval));
- exit(1);
- }
-
-
-#if defined(POSIX_TERMIOS) && !defined(ultrix)
- tcgetattr(t,&new_termio);
-#if !defined(USE_LOGIN_F)
- new_termio.c_lflag &= ~(ICANON|ECHO|ISIG|IEXTEN);
- new_termio.c_iflag &= ~(IXON|IXANY|BRKINT|INLCR|ICRNL);
-#else
- new_termio.c_lflag |= (ICANON|ECHO|ISIG|IEXTEN);
- new_termio.c_oflag |= (ONLCR|OPOST);
- new_termio.c_iflag |= (IXON|IXANY|BRKINT|INLCR|ICRNL);
-#endif /*Do we need binary stream?*/
- new_termio.c_iflag &= ~(ISTRIP);
- /* new_termio.c_iflag = 0; */
- /* new_termio.c_oflag = 0; */
- new_termio.c_cc[VMIN] = 1;
- new_termio.c_cc[VTIME] = 0;
- tcsetattr(t,TCSANOW,&new_termio);
-#else
- (void)ioctl(t, TIOCGETP, &b);
- b.sg_flags = RAW|ANYP;
- (void)ioctl(t, TIOCSETP, &b);
-#endif /* POSIX_TERMIOS */
-
- pid = 0; /*reset pid incase exec fails*/
-
- /*
- ** signal the parent that we have turned off echo
- ** on the slave side of the pty ... he's waiting
- ** because otherwise the rlogin protocol junk gets
- ** echo'd to the user (locuser^@remuser^@term/baud)
- ** and we don't get the right tty affiliation, and
- ** other kinds of hell breaks loose ...
- */
- (void) write(syncpipe[1], &c, 1);
- (void) close(syncpipe[1]);
- (void) close(syncpipe[0]);
-
- close(f), close(p);
- dup2(t, 0), dup2(t, 1), dup2(t, 2);
- if (t > 2)
- close(t);
-
-#if defined(sysvimp)
- setcompat (COMPAT_CLRPGROUP | (getcompat() & ~COMPAT_BSDTTY));
-#endif
-
- /* Log access to account */
- pwd = (struct passwd *) getpwnam(lusername);
- if (pwd && (pwd->pw_uid == 0)) {
- if (passwd_req)
- syslog(LOG_NOTICE, "ROOT login by %s (%s@%s (%s)) forcing password access",
- krusername ? krusername : "",
- rusername, rhost_addra, rhost_name);
- else
- syslog(LOG_NOTICE, "ROOT login by %s (%s@%s (%s))",
- krusername ? krusername : "",
- rusername, rhost_addra, rhost_name);
- }
-#ifdef KERBEROS
-#if defined(LOG_REMOTE_REALM) && !defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal is from a remote realm */
- else if (client && !default_realm(client))
-#endif /* LOG_REMOTE_REALM */
-
-#if defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal name does not map to local username */
- else if (client && !princ_maps_to_lname(client, lusername))
-#endif /* LOG_OTHER_USERS */
-
-#if defined(LOG_ALL_LOGINS)
- else
-#endif /* LOG_ALL_LOGINS */
-
-#if defined(LOG_REMOTE_REALM) || defined(LOG_OTHER_USERS) || defined(LOG_ALL_LOGINS)
- {
- if (passwd_req)
- syslog(LOG_NOTICE,
- "login by %s (%s@%s (%s)) as %s forcing password access",
- krusername ? krusername : "", rusername,
- rhost_addra, rhost_name, lusername);
- else
- syslog(LOG_NOTICE,
- "login by %s (%s@%s (%s)) as %s",
- krusername ? krusername : "", rusername,
- rhost_addra, rhost_name, lusername);
- }
-#endif /* LOG_REMOTE_REALM || LOG_OTHER_USERS || LOG_ALL_LOGINS */
-#endif /* KERBEROS */
-
-#ifndef NO_UT_PID
- {
-
- pty_update_utmp(PTY_LOGIN_PROCESS, getpid(), "rlogin", line,
- ""/*host*/, PTY_TTYSLOT_USABLE);
- }
-#endif
-
-#ifdef USE_LOGIN_F
-/* use the vendors login, which has -p and -f. Tested on
- * AIX 4.1.4 and HPUX 10
- */
- {
- char *cp;
- if ((cp = strchr(term,'/')))
- *cp = '\0';
- setenv("TERM",term, 1);
- }
-
- retval = pty_make_sane_hostname((struct sockaddr *) fromp, maxhostlen,
- stripdomain, always_ip,
- &rhost_sane);
- if (retval)
- fatalperror(f, "failed make_sane_hostname");
- if (passwd_req)
- execl(login_program, "login", "-p", "-h", rhost_sane,
- lusername, (char *)NULL);
- else
- execl(login_program, "login", "-p", "-h", rhost_sane,
- "-f", lusername, (char *)NULL);
-#else /* USE_LOGIN_F */
- execl(login_program, "login", "-r", rhost_sane, (char *)NULL);
-#endif /* USE_LOGIN_F */
- syslog(LOG_ERR, "failed exec of %s: %s",
- login_program, error_message(errno));
- fatalperror(f, login_program);
- /*NOTREACHED*/
- } /* if (pid == 0) */
-
- /*
- ** wait for child to start ... read one byte
- ** -- see the child, who writes one byte after
- ** turning off echo on the slave side ...
- ** The master blocks here until it reads a byte.
- */
-
-(void) close(syncpipe[1]);
- if (read(syncpipe[0], &c, 1) != 1) {
- /*
- * Problems read failed ...
- */
- snprintf(buferror, sizeof(buferror), "Cannot read slave pty %s ",line);
- fatalperror(p,buferror);
- }
- close(syncpipe[0]);
-
-
-#if defined(KERBEROS)
- if (do_encrypt) {
- if (rcmd_stream_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE), 0) < 0){
- snprintf(buferror, sizeof(buferror),
- "Cannot encrypt-write network.");
- fatal(p,buferror);
- }
- }
- else
- /*
- * if encrypting, don't turn on NBIO, else the read/write routines
- * will fail to work properly
- */
-#endif /* KERBEROS */
- ioctl(f, FIONBIO, &on);
- ioctl(p, FIONBIO, &on);
-
- /* FIONBIO doesn't always work on ptys, use fcntl to set O_NDELAY? */
- (void) fcntl(p,F_SETFL,fcntl(p,F_GETFL,0) | O_NDELAY);
-
-#ifdef POSIX_SIGNALS
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTSTP, &sa, (struct sigaction *)0);
-#else
- signal(SIGTSTP, SIG_IGN);
-#endif
-
-
-#if !defined(USE_LOGIN_F)
- /* Pass down rusername and lusername to login. */
- (void) write(p, rusername, strlen(rusername) +1);
- (void) write(p, lusername, strlen(lusername) +1);
- /* stuff term info down to login */
- if ((write(p, term, strlen(term)+1) != (int) strlen(term)+1)) {
- /*
- * Problems write failed ...
- */
- snprintf(buferror, sizeof(buferror), "Cannot write slave pty %s ",
- line);
- fatalperror(f,buferror);
- }
-
-#endif
- protocol(f, p);
- signal(SIGCHLD, SIG_IGN);
- cleanup(0);
-}
-
-unsigned char magic[2] = { 0377, 0377 };
-#ifdef TIOCSWINSZ
-#ifndef TIOCPKT_WINDOW
-#define TIOCPKT_WINDOW 0x80
-#endif
-unsigned char oobdata[] = {TIOCPKT_WINDOW};
-#else
-char oobdata[] = {0};
-#endif
-
-static
-void sendoob(fd, byte)
- int fd;
- char *byte;
-{
- char message[5];
- int cc;
-
- if (do_inband) {
- message[0] = '\377';
- message[1] = '\377';
- message[2] = 'o';
- message[3] = 'o';
- message[4] = *byte;
-
- cc = rcmd_stream_write(fd, message, sizeof(message), 0);
- while (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- /* also shouldn't happen */
- sleep(5);
- cc = rcmd_stream_write(fd, message, sizeof(message), 0);
- }
- } else {
- send(fd, byte, 1, MSG_OOB);
- }
-}
-
-/*
- * Handle a "control" request (signaled by magic being present)
- * in the data stream. For now, we are only willing to handle
- * window size changes.
- */
-static int control(pty, cp, n)
- int pty;
- unsigned char *cp;
- int n;
-{
- struct winsize w;
- int pgrp, got_pgrp;
-
- if (n < (int) 4+sizeof (w) || cp[2] != 's' || cp[3] != 's')
- return (0);
-#ifdef TIOCSWINSZ
- oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */
- memcpy(&w, cp+4, sizeof(w));
- w.ws_row = ntohs(w.ws_row);
- w.ws_col = ntohs(w.ws_col);
- w.ws_xpixel = ntohs(w.ws_xpixel);
- w.ws_ypixel = ntohs(w.ws_ypixel);
- (void)ioctl(pty, TIOCSWINSZ, &w);
-#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));
-}
-
-
-
-/*
- * rlogin "protocol" machine.
- */
-void protocol(f, p)
- int f, p;
-{
- unsigned char pibuf[BUFSIZ], qpibuf[BUFSIZ*2], fibuf[BUFSIZ], *pbp=0, *fbp=0;
- register int pcc = 0, fcc = 0;
- int cc;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-#ifdef TIOCPKT
- register int tiocpkt_on = 0;
- int on = 1;
-#endif
-
-#if defined(TIOCPKT) && !(defined(__svr4__) || defined(HAVE_STREAMS)) \
- || defined(solaris20)
- /* 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;
-#endif
-
- /*
- * Must ignore SIGTTOU, otherwise we'll stop
- * when we try and set slave pty's window shape
- * (our controlling tty is the master pty).
- */
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0);
-#else
- signal(SIGTTOU, SIG_IGN);
-#endif
-#ifdef TIOCSWINSZ
- sendoob(f, oobdata);
-#endif
- for (;;) {
- fd_set ibits, obits, ebits;
-
- FD_ZERO(&ibits);
- FD_ZERO(&obits);
- FD_ZERO(&ebits);
-
- if (fcc)
- FD_SET(p, &obits);
- else
- FD_SET(f, &ibits);
- if (pcc >= 0) {
- if (pcc) {
- FD_SET(f, &obits);
- } else {
- FD_SET(p, &ibits);
- }
- }
-
- if (select(((p > f) ? p : f) + 1, &ibits, &obits, &ebits, 0) < 0) {
- if (errno == EINTR)
- continue;
- fatalperror(f, "select");
- }
-#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
- if (FD_ISSET(f, &ibits)) {
- fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf), 0);
- if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- fcc = 0;
- } else {
- register unsigned char *cp;
- int n;
- size_t left;
-
- if (fcc <= 0)
- break;
- fbp = fibuf;
-
- for (cp = fibuf; cp < fibuf+fcc-1; cp++) {
- if (cp[0] == magic[0] &&
- cp[1] == magic[1]) {
- left = (fibuf+fcc) - cp;
- n = control(p, cp, left);
- if (n) {
- left -= n;
- fcc -= n;
- if (left > 0)
- memmove(cp, cp+n, left);
- cp--;
- }
- }
- }
- }
- }
-
- if (FD_ISSET(p, &obits) && fcc > 0) {
- cc = write(p, fbp, fcc);
- if (cc > 0) {
- fcc -= cc;
- fbp += cc;
- }
- }
-
- if (FD_ISSET(p, &ibits)) {
- pcc = read(p, pibuf, sizeof (pibuf));
- pbp = pibuf;
- if (pcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- pcc = 0;
- } else if (pcc <= 0) {
- break;
- }
-#ifdef TIOCPKT
- else if (tiocpkt_on) {
- if (pibuf[0] == 0) {
- pbp++, pcc--;
- } else {
- if (pkcontrol(pibuf[0])) {
- pibuf[0] |= oobdata[0];
- sendoob(f, pibuf);
- }
- pcc = 0;
- }
- }
-#endif
-
- /* quote any double-\377's if necessary */
-
- if (do_inband) {
- unsigned char *qpbp;
- int qpcc, i;
-
- qpbp = qpibuf;
- qpcc = 0;
-
- for (i=0; i<pcc;) {
- if (pbp[i] == 0377u && (i+1)<pcc && pbp[i+1] == 0377u) {
- qpbp[qpcc] = '\377';
- qpbp[qpcc+1] = '\377';
- qpbp[qpcc+2] = 'q';
- qpbp[qpcc+3] = 'q';
- i += 2;
- qpcc += 4;
- } else {
- qpbp[qpcc] = pbp[i];
- i++;
- qpcc++;
- }
- }
-
- pbp = qpbp;
- pcc = qpcc;
- }
- }
-
- if (FD_ISSET(f, &obits) && pcc > 0) {
- cc = rcmd_stream_write(f, pbp, pcc, 0);
- if (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) {
- /* also shouldn't happen */
- sleep(5);
- continue;
- }
- if (cc > 0) {
- pcc -= cc;
- pbp += cc;
- }
- }
- }
-}
-
-
-
-krb5_sigtype cleanup(signumber)
- int signumber;
-{
- pty_cleanup (line, pid, 1);
- shutdown(netf, 2);
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- exit(1);
-}
-
-
-void fatal(f, msg)
- int f;
- const char *msg;
-{
- char buf[512];
- int out = 1 ; /* Output queue of f */
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
- buf[0] = '\01'; /* error indicator */
- (void) snprintf(buf + 1, sizeof(buf) - 1, "%s: %s.\r\n", progname, msg);
- if ((f == netf) && (pid > 0))
- (void) rcmd_stream_write(f, buf, strlen(buf), 0);
- else
- (void) write(f, buf, strlen(buf));
- syslog(LOG_ERR,"%s\n",msg);
- if (pid > 0) {
-#ifdef POSIX_SIGNALS
- (void) sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- signal(SIGCHLD,SIG_IGN);
-#endif
- kill(pid,SIGKILL);
-#ifdef TIOCFLUSH
- (void) ioctl(f, TIOCFLUSH, (char *)&out);
-#else
- (void) ioctl(f, TCFLSH, out);
-#endif
- cleanup(0);
- }
- exit(1);
-}
-
-
-
-void fatalperror(f, msg)
- int f;
- const char *msg;
-{
- char buf[512];
-
- (void) snprintf(buf, sizeof(buf), "%s: %s", msg, error_message(errno));
- fatal(f, buf);
-}
-
-#ifdef KERBEROS
-
-void
-do_krb_login(host_addr, hostname)
- char *host_addr, *hostname;
-{
- krb5_error_code status;
- char *msg_fail = NULL;
- int valid_checksum;
-
- if (getuid()) {
- exit(1);
- }
-
- /* Check authentication. */
- if ((status = recvauth(&valid_checksum))) {
- if (ticket)
- krb5_free_ticket(bsd_context, ticket);
- if (status != 255)
- syslog(LOG_ERR,
- "Authentication failed from %s (%s): %s\n",host_addr,
- hostname,error_message(status));
- fatal(netf, "Kerberos authentication failed");
- return;
- }
-
- /* OK we have authenticated this user - now check authorization. */
- /* The Kerberos authenticated programs must use krb5_kuserok or kuserok*/
-
- /* krb5_kuserok returns 1 if OK */
- if (!client || !krb5_kuserok(bsd_context, client, lusername)) {
- if (asprintf(&msg_fail,
- "User %s is not authorized to login to account %s",
- krusername, lusername) >= 0)
- fatal(netf, msg_fail);
- else
- fatal(netf,
- "User is not authorized to login to specified account");
- }
-
- if (checksum_required && !valid_checksum) {
- syslog(LOG_WARNING, "Client did not supply required checksum--connection rejected.");
-
- fatal(netf, "You are using an old Kerberos5 without initial connection support; only newer clients are authorized.");
- }
-}
-
-#endif /* KERBEROS */
-
-
-
-void 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) {
- printf("%s too long\r\n", err);
- exit(1);
- }
- *buf++ = c;
- } while (c != 0);
-}
-
-
-
-void usage()
-{
-#ifdef KERBEROS
- syslog(LOG_ERR,
- "usage: klogind [-ePf] [-D port] [-w[ip|maxhostlen[,[no]striplocal]]] or [r/R][k/K][x/e][p/P]logind");
-#else
- syslog(LOG_ERR,
- "usage: rlogind [-rPf] [-D port] or [r/R][p/P]logind");
-#endif
-}
-
-
-
-#ifdef KERBEROS
-
-#ifndef KRB_SENDAUTH_VLEN
-#define KRB_SENDAUTH_VLEN 8 /* length for version strings */
-#endif
-
-#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
- chars */
-
-krb5_error_code
-recvauth(valid_checksum)
- int *valid_checksum;
-{
- krb5_auth_context auth_context = NULL;
- krb5_error_code status;
- struct sockaddr_storage peersin, laddr;
- socklen_t len;
- krb5_data inbuf;
- krb5_data version;
- krb5_authenticator *authenticator;
- krb5_rcache rcache;
- enum kcmd_proto kcmd_proto;
- krb5_keyblock *key;
-
- *valid_checksum = 0;
- len = sizeof(laddr);
- if (getsockname(netf, (struct sockaddr *)&laddr, &len)) {
- exit(1);
- }
-
- len = sizeof(peersin);
- if (getpeername(netf, (struct sockaddr *)&peersin, &len)) {
- syslog(LOG_ERR, "get peer name failed %d", netf);
- exit(1);
- }
-
- if ((status = krb5_auth_con_init(bsd_context, &auth_context)))
- return status;
-
- /* Only need remote address for rd_cred() to verify client */
- if ((status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)))
- return status;
-
- status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
- if (status) return status;
-
- if (! rcache) {
- krb5_principal server;
-
- status = krb5_sname_to_principal(bsd_context, 0, 0,
- KRB5_NT_SRV_HST, &server);
- if (status) return status;
-
- status = krb5_get_server_rcache(bsd_context,
- krb5_princ_component(bsd_context, server, 0),
- &rcache);
- krb5_free_principal(bsd_context, server);
- if (status) return status;
-
- status = krb5_auth_con_setrcache(bsd_context, auth_context, rcache);
- if (status) return status;
- }
-
- status = krb5_recvauth_version(bsd_context, &auth_context, &netf,
- NULL, 0, keytab, &ticket, &version);
- if (status) {
- /*
- * clean up before exiting
- */
- getstr(netf, lusername, sizeof (lusername), "locuser");
- getstr(netf, term, sizeof(term), "Terminal type");
- getstr(netf, rusername, sizeof(rusername), "remuser");
- return status;
- }
-
- getstr(netf, lusername, sizeof (lusername), "locuser");
- getstr(netf, term, sizeof(term), "Terminal type");
-
- kcmd_proto = KCMD_UNKNOWN_PROTOCOL;
- if (version.length != 9) {
- fatal (netf, "bad application version length");
- }
- if (!memcmp (version.data, "KCMDV0.1", 9))
- kcmd_proto = KCMD_OLD_PROTOCOL;
- else if (!memcmp (version.data, "KCMDV0.2", 9))
- kcmd_proto = KCMD_NEW_PROTOCOL;
-
- if (!(checksum_ignored && kcmd_proto == KCMD_OLD_PROTOCOL)) {
-
- if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context,
- &authenticator)))
- return status;
-
- if (authenticator->checksum) {
- struct sockaddr_in adr;
- socklen_t adr_length = sizeof(adr);
- krb5_data chksumbuf;
- krb5_boolean valid = 0;
-
- chksumbuf.data = NULL;
- if (getsockname(netf, (struct sockaddr *) &adr, &adr_length) != 0)
- goto error_cleanup;
- if (asprintf(&chksumbuf.data, "%u:%s%s", ntohs(adr.sin_port), term, lusername) < 0)
- goto error_cleanup;
-
- chksumbuf.length = strlen(chksumbuf.data);
- status = krb5_c_verify_checksum(bsd_context,
- ticket->enc_part2->session,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &chksumbuf, authenticator->checksum,
- &valid);
- if (status == 0 && !valid) status = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-
- error_cleanup:
- if (chksumbuf.data)
- free(chksumbuf.data);
- if (status) {
- krb5_free_authenticator(bsd_context, authenticator);
- return status;
- }
- *valid_checksum = 1;
- }
- krb5_free_authenticator(bsd_context, authenticator);
- }
-
- if ((status = krb5_copy_principal(bsd_context, ticket->enc_part2->client,
- &client)))
- return status;
-
- key = 0;
- status = krb5_auth_con_getrecvsubkey (bsd_context, auth_context, &key);
- if (status)
- fatal (netf, "Server can't get session subkey");
- if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
- fatal (netf, "No session subkey sent");
- if (key && kcmd_proto == KCMD_OLD_PROTOCOL) {
-#ifdef HEIMDAL_FRIENDLY
- key = 0;
-#else
- fatal (netf, "Session subkey not permitted under old kcmd protocol");
-#endif
- }
- if (key == 0)
- key = ticket->enc_part2->session;
-
- rcmd_stream_init_krb5 (key, do_encrypt, 1, 0, kcmd_proto);
-
- do_inband = (kcmd_proto == KCMD_NEW_PROTOCOL);
-
- getstr(netf, rusername, sizeof(rusername), "remuser");
-
- if ((status = krb5_unparse_name(bsd_context, client, &krusername)))
- return status;
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer)&netf, &inbuf)))
- fatal(netf, "Error reading message");
-
- if ((inbuf.length) && /* Forwarding being done, read creds */
- (status = rd_and_store_for_creds(bsd_context, auth_context, &inbuf,
- ticket, &ccache))) {
- fatal(netf, "Can't get forwarded credentials");
- }
- return 0;
-}
-
-#endif /* KERBEROS */
diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c
deleted file mode 100644
index 028d3dd62b..0000000000
--- a/src/appl/bsd/krsh.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * appl/bsd/krsh.c
- */
-
-/*
- * Copyright (c) 1983 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.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rsh.c 5.7 (Berkeley) 9/20/88 */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <sys/time.h>
-
-#include <netinet/in.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-#include <pwd.h>
-#include <netdb.h>
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
-/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
-#include <sys/filio.h>
-#endif
-
-#ifdef KERBEROS
-#include <krb5.h>
-#include <com_err.h>
-#include "defines.h"
-#endif /* KERBEROS */
-
-/*
- * rsh - remote shell
- */
-#define SECURE_MESSAGE "This rsh session is encrypting input/output data transmissions.\r\n"
-
-int error();
-
-int options;
-int rfd2;
-int nflag;
-krb5_sigtype sendsig(int);
-
-#ifdef KERBEROS
-
-#ifndef UCB_RSH
-#define UCB_RSH "/usr/ucb/rsh"
-#endif
-
-krb5_context bsd_context;
-krb5_creds *cred;
-
-int encrypt_flag = 0;
-char *krb_realm = (char *)0;
-void try_normal(char **);
-
-#endif /* KERBEROS */
-
-#ifndef RLOGIN_PROGRAM
-#ifdef KERBEROS
-#define RLOGIN_PROGRAM KRB5_PATH_RLOGIN
-#else /* KERBEROS */
-#ifndef UCB_RLOGIN
-#define UCB_RLOGIN "/usr/ucb/rlogin"
-#endif
-#define RLOGIN_PROGRAM UCB_RLOGIN
-#endif /* KERBEROS */
-#endif /* !RLOGIN_PROGRAM */
-
-#ifndef POSIX_SIGNALS
-#define mask(s) (1 << ((s) - 1))
-#endif /* POSIX_SIGNALS */
-
-int
-main(argc, argv0)
- int argc;
- char **argv0;
-{
- int rem, pid = 0;
- char *host=0, **ap, buf[RCMD_BUFSIZ], *args, **argv = argv0, *user = 0;
- register int cc;
- struct passwd *pwd;
- fd_set readfrom, ready;
- int one = 1;
- struct servent *sp;
- struct servent defaultservent;
- struct sockaddr_in local, foreign;
- int suppress = 0;
-
-#ifdef POSIX_SIGNALS
- sigset_t omask, igmask;
- struct sigaction sa, osa;
-#else
- int omask;
-#endif
-#ifdef KERBEROS
- krb5_flags authopts;
- krb5_error_code status;
- krb5_auth_context auth_context;
- int fflag = 0, Fflag = 0;
-#endif /* KERBEROS */
- int debug_port = 0;
- enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK;
-
- memset(&defaultservent, 0, sizeof(struct servent));
- if (strrchr(argv[0], '/'))
- argv[0] = strrchr(argv[0], '/')+1;
-
- if ( argc < 2 ) goto usage;
- argc--;
- argv++;
-
- another:
- if (argc > 0 && host == 0 && strncmp(*argv, "-", 1)) {
- host = *argv;
- argv++, argc--;
- goto another;
- }
-
- if (argc > 0 && !strcmp(*argv, "-D")) {
- argv++; argc--;
- debug_port = htons(atoi(*argv));
- argv++; argc--;
- goto another;
- }
-
- if (argc > 0 && !strcmp(*argv, "-l")) {
- argv++, argc--;
- if (argc > 0)
- user = *argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-n")) {
- argv++, argc--;
- nflag++;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-d")) {
- argv++, argc--;
- options |= SO_DEBUG;
- goto another;
- }
-#ifdef KERBEROS
- if (argc > 0 && !strcmp(*argv, "-k")) {
- argv++, argc--;
- if (argc == 0) {
- fprintf(stderr, "rsh(kerberos): -k flag must have a realm after it.\n");
- exit (1);
- }
- if(!(krb_realm = strdup(*argv))){
- fprintf(stderr, "rsh(kerberos): Cannot malloc.\n");
- exit(1);
- }
- argv++, argc--;
- goto another;
- }
- /*
- * Ignore -x from kerberos rlogin
- */
- if (argc > 0 && !strncmp(*argv, "-x", 2)) {
- argv++, argc--;
- encrypt_flag++;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-f", 2)) {
- if (Fflag) {
- fprintf(stderr, "rsh: Only one of -f and -F allowed\n");
- goto usage;
- }
- fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-F", 2)) {
- if (fflag) {
- fprintf(stderr, "rsh: Only one of -f and -F allowed\n");
- goto usage;
- }
- Fflag++;
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-A", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PO")) {
- argv++, argc--;
- kcmd_proto = KCMD_OLD_PROTOCOL;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-PN")) {
- argv++, argc--;
- kcmd_proto = KCMD_NEW_PROTOCOL;
- goto another;
- }
-#endif /* KERBEROS */
- /*
- * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin
- * to work
- *
- * There must be a better way to do this! -jmb
- */
- if (argc > 0 && !strncmp(*argv, "-L", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-w", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-e", 2)) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strncmp(*argv, "-8", 2)) {
- argv++, argc--;
- goto another;
- }
-#ifdef ATHENA
- /* additional Athena flags to be ignored */
- if (argc > 0 && !strcmp(*argv, "-noflow")) { /* No local flow control option for rlogin */
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-7")) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-c")) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-a")) {
- argv++, argc--;
- goto another;
- }
- if (argc > 0 && !strcmp(*argv, "-n")) {
- argv++, argc--;
- goto another;
- }
- /*
- ** Also ignore -t ttytype
- */
- if (argc > 0 && !strcmp(*argv, "-t")) {
- argv++; argv++; argc--; argc--;
- goto another;
- }
-#endif /* ATHENA */
- if (host == 0)
- goto usage;
- if (argv[0] == 0) {
- execv(RLOGIN_PROGRAM, argv0);
- perror(RLOGIN_PROGRAM);
- exit(1);
- }
-
- pwd = getpwuid(getuid());
- if (pwd == 0) {
- fprintf(stderr, "who are you?\n");
- exit(1);
- }
- cc = 0;
- for (ap = argv; *ap; ap++)
- cc += strlen(*ap) + 1;
- if (encrypt_flag)
- cc += 3;
- args = (char *) malloc((unsigned) cc);
- *args = '\0';
- if (encrypt_flag)
- strlcpy(args, "-x ", cc);
- for (ap = argv; *ap; ap++) {
- (void) strlcat(args, *ap, cc);
- if (ap[1])
- strlcat(args, " ", cc);
- }
-
- if(debug_port == 0) {
-#ifdef KERBEROS
- sp = getservbyname("kshell", "tcp");
-#else
- sp = getservbyname("shell", "tcp");
-#endif /* KERBEROS */
- if (sp == 0) {
-#ifdef KERBEROS
- sp = &defaultservent;
- sp->s_port = htons(544);
-#else
- fprintf(stderr, "rsh: shell/tcp: unknown service\n");
- exit(1);
-#endif /* KERBEROS */
- }
-
- debug_port = sp->s_port;
- }
-
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- com_err(argv[0], status, "while initializing krb5");
- exit(1);
- }
- authopts = AP_OPTS_MUTUAL_REQUIRED;
-
- /* Piggy-back forwarding flags on top of authopts; */
- /* they will be reset in kcmd */
- if (fflag || Fflag)
- authopts |= OPTS_FORWARD_CREDS;
- if (Fflag)
- authopts |= OPTS_FORWARDABLE_CREDS;
-#ifdef HAVE_ISATTY
- suppress = !isatty(fileno(stderr));
-#endif
- status = kcmd(&rem, &host, debug_port,
- pwd->pw_name,
- user ? user : pwd->pw_name,
- args, &rfd2, "host", krb_realm,
- &cred,
- 0, /* No need for sequence number */
- 0, /* No need for server seq # */
- &local, &foreign,
- &auth_context, authopts,
- 1, /* Always set anyport, there is no need not to. --proven */
- suppress,
- &kcmd_proto);
- if (status) {
- /* If new protocol requested, don't fall back to less secure
- ones. */
- if (kcmd_proto == KCMD_NEW_PROTOCOL)
- exit (1);
- try_normal(argv0);
- } else {
- krb5_keyblock *key = &cred->keyblock;
-
- if (kcmd_proto == KCMD_NEW_PROTOCOL) {
- status = krb5_auth_con_getsendsubkey (bsd_context, auth_context,
- &key);
- if (status) {
- com_err (argv[0], status, "determining subkey for session");
- exit (1);
- }
- if (!key) {
- com_err (argv[0], 0, "no subkey negotiated for connection");
- exit (1);
- }
- }
-
- rcmd_stream_init_krb5(key, encrypt_flag, 0, 1, kcmd_proto);
- }
-
-#ifdef HAVE_ISATTY
- if(encrypt_flag&&isatty(2)) {
- write(2,SECURE_MESSAGE, strlen(SECURE_MESSAGE));
- }
-#endif
-
-#else /* !KERBEROS */
- rem = rcmd(&host, debug_port, pwd->pw_name,
- user ? user : pwd->pw_name, args, &rfd2);
- if (rem < 0)
- exit(1);
-#endif /* KERBEROS */
- if (rfd2 < 0) {
- fprintf(stderr, "rsh: can't establish stderr\n");
- exit(2);
- }
- if (options & SO_DEBUG) {
- if (setsockopt(rem, SOL_SOCKET, SO_DEBUG,
- (const char *) &one, sizeof (one)) < 0)
- perror("setsockopt (stdin)");
- if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG,
- (const char *) &one, sizeof (one)) < 0)
- perror("setsockopt (stderr)");
- }
- (void) setuid(getuid());
-#ifdef POSIX_SIGNALS
- sigemptyset(&igmask);
- sigaddset(&igmask, SIGINT);
- sigaddset(&igmask, SIGQUIT);
- sigaddset(&igmask, SIGTERM);
- sigprocmask(SIG_BLOCK, &igmask, &omask);
-
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = sendsig;
-
- (void)sigaction(SIGINT, (struct sigaction *)0, &osa);
- if (osa.sa_handler != SIG_IGN)
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
-
- (void)sigaction(SIGQUIT, (struct sigaction *)0, &osa);
- if (osa.sa_handler != SIG_IGN)
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
-
- (void)sigaction(SIGTERM, (struct sigaction *)0, &osa);
- if (osa.sa_handler != SIG_IGN)
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
-#else
-#ifdef sgi
- omask = sigignore(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
-#else
- omask = sigblock(mask(SIGINT)|mask(SIGQUIT)|mask(SIGTERM));
-#endif
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- signal(SIGINT, sendsig);
- if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
- signal(SIGQUIT, sendsig);
- if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
- signal(SIGTERM, sendsig);
-#endif /* POSIX_SIGNALS */
- if (nflag == 0) {
- pid = fork();
- if (pid < 0) {
- perror("fork");
- exit(1);
- }
- }
- if (!encrypt_flag) {
- ioctl(rfd2, FIONBIO, &one);
- ioctl(rem, FIONBIO, &one);
- }
- if (nflag == 0 && pid == 0) {
- char *bp;
- int wc;
- fd_set rembits;
-
- (void) close(rfd2);
- reread:
- errno = 0;
- cc = read(0, buf, sizeof buf);
- if (cc <= 0)
- goto done;
- bp = buf;
- rewrite:
- FD_ZERO(&rembits);
- FD_SET(rem, &rembits);
- if (select(rem + 1, 0, &rembits, 0, 0) < 0) {
- if (errno != EINTR) {
- perror("select");
- exit(1);
- }
- goto rewrite;
- }
- if (FD_ISSET(rem, &rembits) == 0)
- goto rewrite;
- wc = rcmd_stream_write(rem, bp, cc, 0);
- if (wc < 0) {
- if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
- goto rewrite;
- goto done;
- }
- cc -= wc; bp += wc;
- if (cc == 0)
- goto reread;
- goto rewrite;
- done:
- (void) shutdown(rem, 1);
-#ifdef KERBEROS
- krb5_free_context(bsd_context);
-#endif
- exit(0);
- }
-#ifdef POSIX_SIGNALS
- sigprocmask(SIG_SETMASK, &omask, (sigset_t*)0);
-#else
-#ifndef sgi
- sigsetmask(omask);
-#endif
-#endif /* POSIX_SIGNALS */
- FD_ZERO(&readfrom);
- FD_SET(rfd2, &readfrom);
- FD_SET(rem, &readfrom);
- do {
- ready = readfrom;
- if (select(((rfd2 > rem) ? rfd2 : rem) + 1, &ready, 0, 0, 0) < 0) {
- if (errno != EINTR) {
- perror("select");
- exit(1);
- }
- continue;
- }
- if (FD_ISSET(rfd2, &ready)) {
- errno = 0;
- cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1);
- if (cc <= 0) {
- if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
- FD_CLR(rfd2, &readfrom);
- } else
- (void) write(2, buf, (unsigned) cc);
- }
- if (FD_ISSET(rem, &ready)) {
- errno = 0;
- cc = rcmd_stream_read(rem, buf, sizeof buf, 0);
- if (cc <= 0) {
- if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
- FD_CLR(rem, &readfrom);
- } else
- (void) write(1, buf, (unsigned) cc);
- }
- } while (FD_ISSET(rem, &readfrom) || FD_ISSET(rfd2, &readfrom));
- if (nflag == 0)
- (void) kill(pid, SIGKILL);
-#ifdef KERBEROS
- krb5_free_context(bsd_context);
-#endif
- exit(0);
- usage:
- fprintf(stderr,
- "usage: \trsh host [ -PN / -PO ] [ -l login ] [ -n ] [ -x ] [ -f / -F] command\n");
- fprintf(stderr,
- "OR \trsh [ -PN / -PO ] [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n");
- exit(1);
-}
-
-
-
-krb5_sigtype sendsig(signo)
- char signo;
-{
- (void) rcmd_stream_write(rfd2, &signo, 1, 1);
-}
-
-
-
-#ifdef KERBEROS
-void try_normal(argv)
- char **argv;
-{
- char *host;
-
-#ifndef KRB5_ATHENA_COMPAT
- if (encrypt_flag)
- exit(1);
-#endif
- /*
- * if we were invoked as 'rsh host mumble', strip off the rsh
- * from arglist.
- *
- * We always want to call the Berkeley rsh as 'host mumble'
- */
- host = strrchr(argv[0], '/');
- if (host)
- host++;
- else
- host = argv[0];
-
- if (!strcmp(host, "rsh"))
- argv++;
-
- fprintf(stderr,"trying normal rsh (%s)\n",
- UCB_RSH);
- fflush(stderr);
- execv(UCB_RSH, argv);
- perror("exec");
- exit(1);
-}
-#endif /* KERBEROS */
diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c
deleted file mode 100644
index d491e6e35a..0000000000
--- a/src/appl/bsd/krshd.c
+++ /dev/null
@@ -1,2047 +0,0 @@
-/*
- * appl/bsd/krshd.c
- */
-
-/*
- * Copyright (c) 1983 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.
- */
-
-#ifndef lint
-char copyright[] =
- "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)rshd.c 5.12 (Berkeley) 9/12/88 */
-
- /*
- * remote shell server:
- * remuser\0
- * locuser\0
- * command\0
- * data
- */
-
-/*
- * This is the rshell daemon. The very basic protocol for checking
- * authentication and authorization is:
- * 1) Check authentication.
- * 2) Check authorization via the access-control files:
- * ~/.k5login (using krb5_kuserok)
- * Execute command if configured authoriztion checks pass, else deny
- * permission.
- */
-
-/* DEFINES:
- * KERBEROS - Define this if application is to be kerberised.
- * LOG_ALL_LOGINS - Define this if you want to log all logins.
- * LOG_OTHER_USERS - Define this if you want to log all principals that do
- * not map onto the local user.
- * LOG_REMOTE_REALM - Define this if you want to log all principals from
- * remote realms.
- * LOG_CMD - Define this if you want to log not only the user but also the
- * command executed. This only decides the type of information
- * logged. Whether or not to log is still decided by the above
- * three DEFINES.
- * Note: Root account access is always logged.
- */
-
-#define SERVE_NON_KRB
-#define LOG_REMOTE_REALM
-#define LOG_CMD
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef __SCO__
-#include <sys/unistd.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <fcntl.h>
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <stdio.h>
-#include <grp.h>
-#include <errno.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <string.h>
-#include <libpty.h>
-#include <sys/wait.h>
-
-#ifdef HAVE_SYS_LABEL_H
-/* only SunOS 4? */
-#include <sys/label.h>
-#include <sys/audit.h>
-#include <pwdadj.h>
-#endif
-#include <stdarg.h>
-
-#include <signal.h>
-#include <netdb.h>
-
-#ifdef CRAY
-#ifndef NO_UDB
-#include <udb.h>
-#endif /* !NO_UDB */
-#include <sys/category.h>
-#include <netinet/ip.h>
-#include <sys/tfm.h>
-#include <sys/nal.h>
-#include <sys/secparm.h>
-#include <sys/usrv.h>
-#include <sys/utsname.h>
-#include <sys/sysv.h>
-#include <sys/slrec.h>
-#include <sys/unistd.h>
-#include <path.h>
-#endif /* CRAY */
-
-#include <syslog.h>
-
-#ifdef POSIX_TERMIOS
-#include <termios.h>
-#endif
-
-#ifdef HAVE_SYS_FILIO_H
-/* get FIONBIO from sys/filio.h, so what if it is a compatibility feature */
-#include <sys/filio.h>
-#endif
-
-#ifdef KERBEROS
-#include "k5-int.h"
-#include <com_err.h>
-#include "loginpaths.h"
-#include <k5-util.h>
-#include <k5-platform.h>
-
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
-#if defined(_PATH_NOLOGIN)
-#define NOLOGIN _PATH_NOLOGIN
-#else
-#define NOLOGIN "/etc/nologin"
-#endif
-
-#include "defines.h"
-
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-
-#ifndef MAXDNAME
-#define MAXDNAME 256 /*per the rfc*/
-#endif
-
-#define ARGSTR "ek5ciD:S:M:AP:?L:w:"
-
-
-
-
-#define MAXRETRIES 4
-
-krb5_context bsd_context;
-char *srvtab = NULL;
-krb5_keytab keytab = NULL;
-krb5_ccache ccache = NULL;
-
-void fatal(int, const char *);
-
-int require_encrypt = 0;
-int do_encrypt = 0;
-int anyport = 0;
-char *kprogdir = KPROGDIR;
-int netf;
-int maxhostlen = 0;
-int stripdomain = 1;
-int always_ip = 0;
-
-static krb5_error_code recvauth(int netfd, struct sockaddr *peersin,
- int *valid_checksum);
-
-#else /* !KERBEROS */
-
-#define ARGSTR "RD:?"
-
-#endif /* KERBEROS */
-
-static int accept_a_connection (int debug_port, struct sockaddr *from,
- socklen_t *fromlenp);
-
-#ifndef HAVE_KILLPG
-#define killpg(pid, sig) kill(-(pid), (sig))
-#endif
-
-int checksum_required = 0, checksum_ignored = 0;
-char *progname;
-
-#define MAX_PROG_NAME 10
-
-/* Leave room for 4 environment variables to be passed */
-#define MAXENV 4
-#define SAVEENVPAD 0,0,0,0 /* padding for envinit slots */
-char *save_env[MAXENV];
-int num_env = 0;
-
-#ifdef CRAY
-int secflag;
-extern
-#endif /* CRAY */
-
-void error (char *fmt, ...)
-#if !defined (__cplusplus) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
- __attribute__ ((__format__ (__printf__, 1, 2)))
-#endif
- ;
-
-void usage(void), getstr(int, char *, int, char *),
- doit(int, struct sockaddr *);
-
-#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);
-}
-#endif
-
-
-int main(argc, argv)
- int argc;
- char **argv;
-{
-#if defined(BSD) && BSD+0 >= 43
- struct linger linger;
-#endif
- int on = 1;
- socklen_t fromlen;
- struct sockaddr_storage from;
- extern int opterr, optind;
- extern char *optarg;
- int ch;
- int fd;
- int debug_port = 0;
-#ifdef KERBEROS
- krb5_error_code status;
-#endif
-
-#ifdef CRAY
- secflag = sysconf(_SC_CRAY_SECURE_SYS);
-#endif
-
- progname = strrchr (*argv, '/');
- progname = progname ? progname + 1 : *argv;
-
-#ifndef LOG_ODELAY /* 4.2 syslog */
- openlog(progname, LOG_PID);
-#else
-#ifndef LOG_AUTH
-#define LOG_AUTH 0
-#endif
- openlog(progname, LOG_PID | LOG_ODELAY, LOG_AUTH);
-#endif /* 4.2 syslog */
-
-#ifdef KERBEROS
- status = krb5_init_context(&bsd_context);
- if (status) {
- syslog(LOG_ERR, "Error initializing krb5: %s",
- error_message(status));
- exit(1);
- }
-#endif
-
- /* Analyze parameters. */
- opterr = 0;
- while ((ch = getopt(argc, argv, ARGSTR)) != -1)
- switch (ch) {
-#ifdef KERBEROS
- case 'k':
- break;
-
- case '5':
- break;
- case 'c':
- checksum_required = 1;
- break;
- case 'i':
- checksum_ignored = 1;
- break;
-
- case 'e':
- require_encrypt = 1;
- break;
-
- case 'S':
- if ((status = krb5_kt_resolve(bsd_context, optarg, &keytab))) {
- com_err(progname, status, "while resolving srvtab file %s",
- optarg);
- exit(2);
- }
- break;
-
- case 'M':
- krb5_set_default_realm(bsd_context, optarg);
- break;
-
- case 'A':
- anyport = 1;
- break;
-
- case 'P':
- kprogdir = optarg;
- break;
-
- case 'L':
- if (num_env < MAXENV) {
- save_env[num_env] = strdup(optarg);
- if(!save_env[num_env++]) {
- com_err(progname, ENOMEM, "in saving environment");
- exit(2);
- }
- } else {
- fprintf(stderr, "%s: Only %d -L arguments allowed\n",
- progname, MAXENV);
- exit(2);
- }
- break;
-#endif
- case 'D':
- debug_port = atoi(optarg);
- break;
- case 'w':
- if (!strcmp(optarg, "ip"))
- always_ip = 1;
- else {
- char *cp;
- cp = strchr(optarg, ',');
- if (cp == NULL)
- maxhostlen = atoi(optarg);
- else if (*(++cp)) {
- if (!strcmp(cp, "striplocal"))
- stripdomain = 1;
- else if (!strcmp(cp, "nostriplocal"))
- stripdomain = 0;
- else {
- usage();
- exit(1);
- }
- *(--cp) = '\0';
- maxhostlen = atoi(optarg);
- }
- }
- break;
- case '?':
- default:
- usage();
- exit(1);
- break;
- }
-
- if (optind == 0) {
- usage();
- exit(1);
- }
-
- argc -= optind;
- argv += optind;
-
- fromlen = sizeof (from);
-
- if (debug_port)
- fd = accept_a_connection(debug_port, (struct sockaddr *)&from,
- &fromlen);
- else {
- if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
- fprintf(stderr, "%s: ", progname);
- perror("getpeername");
- _exit(1);
- }
-
- fd = 0;
- }
-
-/*
- * AIX passes an IPv4-mapped IPv6 address back from getpeername, but if
- * that address is later used in connect(), it returns an error. Convert
- * IPv4-mapped IPv6 addresses to simple IPv4 addresses on AIX (but don't
- * do this everywhere since it isn't always the right thing to do, just
- * the least wrong on AIX).
- */
-#if defined(_AIX) && defined(KRB5_USE_INET6)
- if (((struct sockaddr*)&from)->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa2sin6(&from)->sin6_addr)) {
- sa2sin(&from)->sin_len = sizeof(struct sockaddr_in);
- sa2sin(&from)->sin_family = AF_INET;
- sa2sin(&from)->sin_port = sa2sin6(&from)->sin6_port;
- memmove(&(sa2sin(&from)->sin_addr.s_addr), &(sa2sin6(&from)->sin6_addr.u6_addr.u6_addr8[12]), 4);
- }
-#endif
-
- if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
- sizeof (on)) < 0)
- syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
-#if defined(BSD) && BSD+0 >= 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
-
- if (checksum_required&&checksum_ignored) {
- syslog(LOG_CRIT, "Checksums are required and ignored; these options are mutually exclusive--check the documentation.");
- fatal(fd, "Configuration error: mutually exclusive options specified");
- }
-
- doit(dup(fd), (struct sockaddr *) &from);
- return 0;
-}
-
-#ifdef CRAY
-char username[32] = "LOGNAME=";
-#include <tmpdir.h>
-char tmpdir[64] = "TMPDIR=";
-#else
-char username[20] = "USER=";
-#endif
-
-char homedir[64] = "HOME=";
-char shell[64] = "SHELL=";
-char term[64] = "TERM=network";
-char path_rest[] = RPATH;
-
-char remote_addr[64+NI_MAXHOST]; /* = "KRB5REMOTEADDR=" */
-char remote_port[64+NI_MAXSERV]; /* = "KRB5REMOTEPORT=" */
-char local_addr[64+NI_MAXHOST]; /* = "KRB5LOCALADDR=" */
-char local_port[64+NI_MAXSERV]; /* = "KRB5LOCALPORT=" */
-#define ADDRPAD 0,0,0,0
-#define KRBPAD 0 /* KRB5CCNAME, optional */
-
-/* The following include extra space for TZ and MAXENV pointers... */
-#define COMMONVARS homedir, shell, 0/*path*/, username, term
-#ifdef CRAY
-char *envinit[] =
-{COMMONVARS, "TZ=GMT0", tmpdir, SAVEENVPAD, KRBPAD, ADDRPAD, 0};
-#define TMPDIRENV 6
-char *getenv();
-#else /* CRAY */
-#ifdef KERBEROS
-char *envinit[] =
-{COMMONVARS, 0/*tz*/, SAVEENVPAD, KRBPAD, ADDRPAD, 0};
-#else /* KERBEROS */
-char *envinit[] =
-{COMMONVARS, 0/*tz*/, SAVEENVPAD, ADDRPAD, 0};
-#endif /* KERBEROS */
-#endif /* CRAY */
-
-#define TZENV 5
-#define PATHENV 2
-
-extern char **environ;
-char ttyn[12]; /* Line string for wtmp entries */
-
-#ifdef CRAY
-#define SIZEOF_INADDR SIZEOF_in_addr
-int maxlogs;
-#else
-#define SIZEOF_INADDR sizeof(struct in_addr)
-#endif
-
-#ifndef NCARGS
-/* linux doesn't seem to have it... */
-#define NCARGS 1024
-#endif
-
-#define NMAX 16
-
-int pid;
-char locuser[NMAX+1];
-char remuser[NMAX +1];
-char cmdbuf[NCARGS+1];
-char *kremuser;
-krb5_principal client;
-krb5_authenticator *kdata;
-
-static void
-ignore_signals()
-{
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_IGN;
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
- (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
- (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
-
- (void)kill(-pid, SIGTERM);
-#else
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
-
- killpg(pid, SIGTERM);
-#endif
-}
-
-static krb5_sigtype
-cleanup(signumber)
- int signumber;
-{
- ignore_signals();
- wait(0);
-
- pty_logwtmp(ttyn,"","");
- syslog(LOG_INFO ,"Daemon terminated via signal %d.", signumber);
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- exit(0);
-}
-
-
-void doit(f, fromp)
- int f;
- struct sockaddr *fromp;
-{
- char *cp;
-#ifdef KERBEROS
- krb5_error_code status;
-#endif
- int valid_checksum;
- int cnt;
- char *crypt();
- struct passwd *pwd;
- char *path;
-#ifdef CRAY
-#ifndef NO_UDB
- struct udb *ue;
- struct udb ue_static;
- extern struct udb *getudbnam();
-#endif
- extern struct passwd *getpwnam(), *getpwuid();
- static int jid;
- int error();
- int paddr;
- struct nal nal;
- int nal_error;
- struct usrv usrv;
- struct sysv sysv;
- char *makejtmp(), *jtmpnam = 0;
- int packet_level; /* Packet classification level */
- long packet_compart; /* Packet compartments */
-#endif /* CRAY */
-
- int s = -1;
- char hostname[NI_MAXHOST];
- char *sane_host;
- char hostaddra[NI_MAXHOST];
- int aierr;
- short port;
- int pv[2], pw[2], px[2], cc;
- fd_set ready, readfrom;
- char buf[RCMD_BUFSIZ], sig;
- struct sockaddr_storage localaddr;
-#ifdef POSIX_SIGNALS
- struct sigaction sa;
-#endif
-
-#ifdef IP_TOS
-/* solaris has IP_TOS, but only IPTOS_* values */
-#ifdef HAVE_GETTOSBYNAME
- struct tosent *tp;
-
-
- if ((tp = gettosbyname("interactive", "tcp")) &&
- (setsockopt(f, IPPROTO_IP, IP_TOS, &tp->t_tos, sizeof(int)) < 0))
-#ifdef TOS_WARN
- syslog(LOG_NOTICE, "setsockopt (IP_TOS): %m");
-#else
- ; /* silently ignore TOS errors in 6E */
-#endif
-#endif
-#endif /* IP_TOS */
-
- {
- socklen_t sin_len = sizeof (localaddr);
- if (getsockname(f, (struct sockaddr*)&localaddr, &sin_len) < 0) {
- perror("getsockname");
- exit(1);
- }
- }
-
-#ifdef POSIX_SIGNALS
- (void)sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_DFL;
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
-#else
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
-#endif
-#ifdef DEBUG
- { int t = open("/dev/tty", 2);
- if (t >= 0) {
- ioctl(t, TIOCNOTTY, (char *)0);
- (void) close(t);
- }
- }
-#endif
- if (fromp->sa_family != AF_INET
-#if defined(KRB5_USE_INET6) && defined(KERBEROS)
- && fromp->sa_family != AF_INET6
-#endif
- ) {
- syslog(LOG_ERR , "malformed from address\n");
- exit(1);
- }
-#ifdef KERBEROS
- netf = f;
-#else
- {
- struct sockaddr_in *frompin = sa2sin(fromp);
- frompin->sin_port = ntohs((u_short)frompin->sin_port);
- if (frompin->sin_port >= IPPORT_RESERVED ||
- frompin->sin_port < IPPORT_RESERVED/2) {
- syslog(LOG_ERR , "connection from bad port\n");
- exit(1);
- }
- }
-#endif /* KERBEROS */
-
-#ifdef CRAY
-
- /* If this is a secure system then get the packet classification
- of f. ( Note IP_SECURITY is checked in get_packet_classification:
- if it's not set then the user's (root) default
- classification level and compartments are returned. )
- Then set this process to that level/compart so that the stderr
- connection will be labeled appropriately.
- */
- if (secflag) {
- if (get_packet_classification(f,getuid(),
- &packet_level,&packet_compart) < 0) {
- syslog(LOG_ERR, "cannot get ip packet level\n");
- exit(1);
- }
- if(secflag == TFM_UDB_5) {
- if(setucmp(packet_compart, C_PROC) != 0) {
- error("Unable to setucmp.\n");
- exit(1);
- }
- } else if(secflag == TFM_UDB_6) {
- if(setulvl(packet_level,C_PROC) != 0) {
- error("Unable to setulvl.\n");
- exit(1);
- }
- if(setucmp(packet_compart, C_PROC) != 0) {
- error("Unable to setucmp.\n");
- exit(1);
- }
- }
-
- }
-#endif /* CRAY */
-
- (void) alarm(60);
- port = 0;
- for (;;) {
- char c;
- if ((cc = read(f, &c, 1)) != 1) {
- if (cc < 0)
- syslog(LOG_NOTICE , "read: %m");
- shutdown(f, 1+1);
- exit(1);
- }
- if (c == 0)
- break;
- port = port * 10 + c - '0';
- }
- (void) alarm(0);
- if (port != 0) {
- if (anyport) {
- int addrfamily = fromp->sa_family;
- s = getport(0, &addrfamily);
- } else {
- int lport = IPPORT_RESERVED - 1;
-#ifdef HAVE_RRESVPORT_AF
- s = rresvport_af(&lport, fromp->sa_family);
-#else
- s = rresvport(&lport);
-#endif
- }
- if (s < 0) {
- syslog(LOG_ERR ,
- "can't get stderr port: %m");
- exit(1);
- }
-#ifndef KERBEROS
- if (port >= IPPORT_RESERVED) {
- syslog(LOG_ERR , "2nd port not reserved\n");
- exit(1);
- }
-#endif /* KERBEROS */
- switch (fromp->sa_family) {
- case AF_INET:
- sa2sin(fromp)->sin_port = htons((u_short)port);
- break;
-#ifdef KRB5_USE_INET6
- case AF_INET6:
- sa2sin6(fromp)->sin6_port = htons((u_short)port);
- break;
-#endif
- }
- if (connect(s, (struct sockaddr *)fromp, socklen(fromp)) < 0) {
- syslog(LOG_INFO ,
- "connect second port: %m");
- exit(1);
- }
- }
- dup2(f, 0);
- dup2(f, 1);
- dup2(f, 2);
- aierr = getnameinfo(fromp, socklen(fromp), hostname, sizeof(hostname),
- 0, 0, 0);
- if (aierr) {
- error("failed to get remote host address: %s", gai_strerror(aierr));
- exit(1);
- }
- aierr = getnameinfo(fromp, socklen(fromp), hostaddra, sizeof(hostaddra),
- 0, 0, NI_NUMERICHOST);
- if (aierr) {
- error("failed to get remote host address: %s", gai_strerror(aierr));
- exit(1);
- }
-
-#ifdef KERBEROS
- status = pty_make_sane_hostname((struct sockaddr *) fromp, maxhostlen,
- stripdomain, always_ip, &sane_host);
- if (status) {
- error("failed make_sane_hostname: %s\n", error_message(status));
- exit(1);
- }
-
- if ((status = recvauth(f, fromp, &valid_checksum))) {
- error("Authentication failed: %s\n", error_message(status));
- exit(1);
- }
-#else
- getstr(f, remuser, sizeof(remuser), "remuser");
- getstr(f, locuser, sizeof(locuser), "locuser");
- getstr(f, cmdbuf, sizeof(cmdbuf), "command");
- rcmd_stream_init_normal();
-#endif /* KERBEROS */
-
-#ifdef CRAY
- paddr = inet_addr(inet_ntoa(fromp->sin_addr));
- if(secflag){
- /*
- * check network authorization list
- */
- if (fetchnal(paddr,&nal) < 0) {
- /*
- * NAL file inaccessible, abort connection.
- */
- error("Permission denied.\n");
- exit(1);
- }
- }
-#endif /* CRAY */
-
- pwd = getpwnam(locuser);
- if (pwd == (struct passwd *) 0 ) {
- syslog(LOG_ERR ,
- "Principal %s (%s@%s (%s)) for local user %s has no account.\n",
- kremuser, remuser, hostaddra, hostname,
- locuser); /* xxx sprintf buffer in syslog*/
- error("Login incorrect.\n");
- exit(1);
- }
-
-#ifdef CRAY
- /* Setup job entry, and validate udb entry.
- ( against packet level also ) */
- if ((jid = setjob(pwd->pw_uid, 0)) < 0) {
- error("Unable to create new job.\n");
- exit(1);
- }
- if ((jtmpnam = makejtmp(pwd->pw_uid, pwd->pw_gid, jid))) {
- register int pid, tpid;
- int status;
- switch(pid = fork()) {
- case -1:
- cleanjtmp(locuser, jtmpnam);
- envinit[TMPDIRENV] = 0;
- break;
- case 0:
- break;
- default:
- close(0);
- close(1);
- close(2);
- close(f);
- if (port)
- close(s);
- while ((tpid = wait(&status)) != pid) {
- if (tpid < 0)
- break;
- }
- cleanjtmp(locuser, jtmpnam);
- exit(status>>8);
- /* NOTREACHED */
- }
- } else {
- envinit[TMPDIRENV] = 0;
- }
-#ifndef NO_UDB
- (void)getsysudb();
-
- if ((ue = getudbnam(pwd->pw_name)) == (struct udb *)NULL) {
- error("Unable to fetch account id.\n");
- exit(1);
- }
- ue_static = *ue; /* save from setlimits call */
- endudb();
- if (secflag) {
- if(getsysv(&sysv, sizeof(struct sysv)) != 0) {
- loglogin(sane_host, SLG_LLERR, 0, ue);
- error("Permission denied.\n");
- exit(1);
- }
- if ((packet_level != ue->ue_deflvl) ||
- ((packet_compart & ue->ue_comparts) != packet_compart )){
- loglogin(sane_host, SLG_LLERR, 0, ue);
- error("Permission denied.\n");
- exit(1);
- }
- if (ue->ue_disabled != 0) {
- loglogin(sane_host,SLG_LOCK,ue->ue_logfails,ue);
- error("Permission denied.\n");
- exit(1);
- }
- maxlogs = sysv.sy_maxlogs;
- }
- if (acctid(getpid(), ue->ue_acids[0]) == -1) {
- error("Unable to set account id.\n");
- exit(1);
- }
- if (setshares(pwd->pw_uid, acctid(0, -1), error, 1, 0)) {
- error("Unable to set shares.\n");
- exit(1);
- }
- if (setlimits(pwd->pw_name, C_PROC, getpid(), UDBRC_INTER)) {
- error("Unable to set limits.\n");
- exit(1);
- }
- if (setlimits(pwd->pw_name, C_JOB, jid, UDBRC_INTER)) {
- error("Unable to set limits.\n");
- exit(1);
- }
- ue = &ue_static; /* restore after setlimits call */
- endudb(); /* setlimits opens udb and leaves it
- open so close it here. */
-#endif /* !NO_UDB */
-#endif /*CRAY*/
-
- /* Setup wtmp entry : we do it here so that if this is a CRAY
- the Process Id is correct and we have not lost our trusted
- privileges. */
- if (port) {
- /* Place entry into wtmp */
- snprintf(ttyn,sizeof(ttyn),"krsh%ld",(long) (getpid() % 9999999));
- pty_logwtmp(ttyn,locuser,sane_host);
- }
- /* We are simply execing a program over rshd : log entry into wtmp,
- as kexe(pid), then finish out the session right after that.
- Syslog should have the information as to what was exec'd */
- else {
- pty_logwtmp(ttyn,locuser,sane_host);
- }
-
-#ifdef CRAY
-
- /* If we are a secure system then we need to get rid of our
- trusted facility, so that MAC on the chdir we work. Before we
- do this make an entry into wtmp, and any other audit recording. */
-
- if (secflag) {
- if (getusrv(&usrv)){
- syslog(LOG_ERR,"Cannot getusrv");
- error("Permission denied.\n");
- loglogin(sane_host, SLG_LVERR, ue->ue_logfails,ue);
- goto signout_please;
- }
- /*
- * 6.0 no longer allows any form ofTRUSTED_PROCESS logins.
- */
- if((ue->ue_valcat & TFM_TRUSTED) ||
- (sysv.sy_oldtfm &&
- ((ue->ue_comparts & TRUSTED_SUBJECT) == TRUSTED_SUBJECT))) {
- loglogin(sane_host, SLG_TRSUB, ue->ue_logfails,ue);
- error("Permission denied.\n");
- goto signout_please;
- }
-
- loglogin(sane_host, SLG_OKLOG, ue->ue_logfails,ue);
-
- /* Setup usrv structure with user udb info and
- packet_level and packet_compart. */
- usrv.sv_actlvl = packet_level;
- usrv.sv_actcmp = packet_compart; /*Note get_packet_level sets
- compartment to users default
- compartments....*/
- usrv.sv_permit = ue->ue_permits;
- usrv.sv_intcls = ue->ue_intcls;
- usrv.sv_maxcls = ue->ue_maxcls;
- usrv.sv_intcat = ue->ue_intcat;
- usrv.sv_valcat = ue->ue_valcat;
- usrv.sv_savcmp = 0;
- usrv.sv_savlvl = 0;
-
- /*
- * Set user values to workstation boundaries
- */
-#ifdef MIN
-#undef MIN
-#endif
-#ifdef MAX
-#undef MAX
-#endif
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
- nal_error = 0;
-
- if (nal.na_sort) {
- if ((ue->ue_minlvl > nal.na_smax) ||
- (ue->ue_maxlvl < nal.na_smin))
- nal_error++;
- else {
- usrv.sv_minlvl=MAX(ue->ue_minlvl, nal.na_smin);
- usrv.sv_maxlvl=MIN(ue->ue_maxlvl, nal.na_smax);
-
-#ifndef IP_SECURITY
-
- if (usrv.sv_actlvl < usrv.sv_minlvl)
- usrv.sv_actlvl = usrv.sv_minlvl;
- if (usrv.sv_actlvl > usrv.sv_maxlvl)
- usrv.sv_actlvl = usrv.sv_maxlvl;
-
-#else /*IP_SECURITY*/
- if (usrv.sv_actlvl < usrv.sv_minlvl)
- nal_error++;
- if (usrv.sv_actlvl > usrv.sv_maxlvl)
- nal_error++;
- if (usrv.sv_actlvl != ue->ue_deflvl)
- nal_error++;
-
- usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
- usrv.sv_actcmp &= nal.na_scmp;
-#endif /*IP_SECURITY*/
- usrv.sv_valcmp = ue->ue_comparts & nal.na_scmp;
- usrv.sv_actcmp = (usrv.sv_valcmp &
- ue->ue_defcomps);
- }
- } else {
- /*
- * If the user's minimum level is greater than
- * zero, they cannot log on from this (ie. an
- * unclassified) host.
- */
- if (ue->ue_minlvl > 0)
- nal_error++;
- /*
- * Address not in NAL, if EXEMPT_NAL is not
- * true, then even an unclassified user is
- * not allowed.
- */
- if (!EXEMPT_NAL)
- nal_error++;
- else {
- usrv.sv_minlvl = 0;
- usrv.sv_maxlvl = 0;
- usrv.sv_valcmp = 0;
- usrv.sv_actcmp = 0;
- usrv.sv_actlvl = 0;
- }
- }
- if (nal_error) {
- loglogin(sane_host, SLG_LVERR, ue->ue_logfails,ue);
- error("Permission denied.\n");
- goto signout_please;
- }
-#undef MIN
-#undef MAX
- /* Before the setusrv is done then do a sethost for paddr */
- sethost(paddr);
-
- if (setusrv(&usrv) == -1) {
- loglogin(sane_host, SLG_LVERR, ue->ue_logfails,ue);
- error("Permission denied.\n");
- goto signout_please;
- }
- if (getusrv(&usrv) == -1) {
- error("Getusrv Permission denied.\n");
- goto signout_please;
- }
-
- }
-#endif /*CRAY*/
-
- if (chdir(pwd->pw_dir) < 0) {
- if(chdir("/") < 0) {
- error("No remote directory.\n");
- goto signout_please;
- }
- pwd->pw_dir = "/";
- }
-
-#ifdef KERBEROS
- /* krb5_kuserok returns 1 if OK */
- if (!krb5_kuserok(bsd_context, client, locuser)){
- syslog(LOG_ERR ,
- "Principal %s (%s@%s (%s)) for local user %s failed krb5_kuserok.\n",
- kremuser, remuser, hostaddra, hostname, locuser);
- error("Permission denied.\n");
- goto signout_please;
- }
-#else
- if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
- ruserok(hostname[0] ? hostname : hostaddra,
- pwd->pw_uid == 0, remuser, locuser) < 0) {
- error("Permission denied.\n");
- goto signout_please;
- }
-#endif /* KERBEROS */
-
-
- if (checksum_required && !valid_checksum) {
- syslog(LOG_WARNING, "Client did not supply required checksum--connection rejected.");
- error( "You are using an old Kerberos5 client without checksum support; only newer clients are authorized.\n");
- goto signout_please;
- }
- if (require_encrypt&&(!do_encrypt)) {
- error("You must use encryption.\n");
- goto signout_please;
- }
-
- if (pwd->pw_uid && !access(NOLOGIN, F_OK)) {
- error("Logins currently disabled.\n");
- goto signout_please;
- }
-
- /* Log access to account */
- pwd = (struct passwd *) getpwnam(locuser);
- if (pwd && (pwd->pw_uid == 0)) {
-#ifdef LOG_CMD
- syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s (%s)) as ROOT",
- cmdbuf, kremuser, remuser, hostaddra, hostname);
-#else
- syslog(LOG_NOTICE ,"Access as ROOT by principal %s (%s@%s (%s))",
- kremuser, remuser, hostaddra, hostname);
-#endif
- }
-#if defined(KERBEROS) && defined(LOG_REMOTE_REALM) && !defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal is from a remote realm */
- else if (client && !default_realm(client))
-#endif
-
-#if defined(KERBEROS) && defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS)
- /* Log if principal name does not map to local username */
- else if (client && !princ_maps_to_lname(client, locuser))
-#endif /* LOG_OTHER_USERS */
-
-#ifdef LOG_ALL_LOGINS /* Log everything */
- else
-#endif
-
-#if defined(LOG_REMOTE_REALM) || defined(LOG_OTHER_USERS) || defined(LOG_ALL_LOGINS)
- {
-#ifdef LOG_CMD
- syslog(LOG_NOTICE, "Executing %s for principal %s (%s@%s (%s)) as local user %s",
- cmdbuf, kremuser, remuser, hostaddra, hostname, locuser);
-#else
- syslog(LOG_NOTICE ,"Access as %s by principal %s (%s@%s (%s))",
- locuser, kremuser, remuser, hostaddra, hostname);
-#endif
- }
-#endif
-
- (void) write(2, "", 1);
-
- if (port||do_encrypt) {
- if (port&&(pipe(pv) < 0)) {
- error("Can't make pipe.\n");
- goto signout_please;
- }
- if (pipe(pw) < 0) {
- error("Can't make pipe 2.\n");
- goto signout_please;
- }
- if (pipe(px) < 0) {
- error("Can't make pipe 3.\n");
- goto signout_please;
- }
- pid = fork();
- if (pid == -1) {
- error("Fork failed.\n");
- goto signout_please;
- }
- if (pid) {
- int maxfd;
-#ifdef POSIX_SIGNALS
- sa.sa_handler = cleanup;
- (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
- (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
- (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
-
- sa.sa_handler = SIG_IGN;
- /* SIGPIPE is a crutch that we don't need if we check
- the exit status of write. */
- (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
- (void)sigaction(SIGCHLD, &sa, (struct sigaction *)0);
-#else
- signal(SIGINT, cleanup);
- signal(SIGQUIT, cleanup);
- signal(SIGTERM, cleanup);
- signal(SIGHUP, cleanup);
- /* SIGPIPE is a crutch that we don't need if we check
- the exit status of write. */
- signal(SIGPIPE, SIG_IGN);
- signal(SIGCHLD,SIG_IGN);
-#endif
-
- (void) close(0); (void) close(1); (void) close(2);
- if(port)
- (void) close(pv[1]);
- (void) close(pw[1]);
- (void) close(px[0]);
-
-
-
- FD_ZERO(&readfrom);
- FD_SET(f, &readfrom);
- maxfd = f;
- if(port) {
- FD_SET(s, &readfrom);
- if (s > maxfd)
- maxfd = s;
- FD_SET(pv[0], &readfrom);
- if (pv[0] > maxfd)
- maxfd = pv[0];
- }
- FD_SET(pw[0], &readfrom);
- if (pw[0] > maxfd)
- maxfd = pw[0];
-
- /* read from f, write to px[1] -- child stdin */
- /* read from s, signal child */
- /* read from pv[0], write to s -- child stderr */
- /* read from pw[0], write to f -- child stdout */
-
- do {
- ready = readfrom;
- if (select(maxfd + 1, &ready, (fd_set *)0,
- (fd_set *)0, (struct timeval *)0) < 0) {
- if (errno == EINTR) {
- continue;
- } else {
- break;
- }
- }
-
- if (port&&FD_ISSET(pv[0], &ready)) {
- /* read from the child stderr, write to the net */
- errno = 0;
- cc = read(pv[0], buf, sizeof (buf));
- if (cc <= 0) {
- shutdown(s, 1+1);
- FD_CLR(pv[0], &readfrom);
- } else {
- (void) rcmd_stream_write(s, buf, (unsigned) cc, 1);
- }
- }
- if (FD_ISSET(pw[0], &ready)) {
- /* read from the child stdout, write to the net */
- errno = 0;
- cc = read(pw[0], buf, sizeof (buf));
- if (cc <= 0) {
- shutdown(f, 1+1);
- FD_CLR(pw[0], &readfrom);
- } else {
- (void) rcmd_stream_write(f, buf, (unsigned) cc, 0);
- }
- }
- if (port&&FD_ISSET(s, &ready)) {
- /* read from the alternate channel, signal the child */
- if (rcmd_stream_read(s, &sig, 1, 1) <= 0) {
- FD_CLR(s, &readfrom);
- } else {
-#ifdef POSIX_SIGNALS
- sa.sa_handler = cleanup;
- (void)sigaction(sig, &sa, (struct sigaction *)0);
- kill(-pid, sig);
-#else
- signal(sig, cleanup);
- killpg(pid, sig);
-#endif
- }
- }
- if (FD_ISSET(f, &ready)) {
- /* read from the net, write to child stdin */
- errno = 0;
- cc = rcmd_stream_read(f, buf, sizeof(buf), 0);
- if (cc <= 0) {
- (void) close(px[1]);
- FD_CLR(f, &readfrom);
- } else {
- int wcc;
- wcc = write(px[1], buf, (unsigned) cc);
- if (wcc == -1) {
- /* pipe closed, don't read any more */
- /* might check for EPIPE */
- (void) close(px[1]);
- FD_CLR(f, &readfrom);
- } else if (wcc != cc) {
- syslog(LOG_INFO, "only wrote %d/%d to child",
- wcc, cc);
- }
- }
- }
- } while ((port&&FD_ISSET(s, &readfrom)) ||
- FD_ISSET(f, &readfrom) ||
- (port&&FD_ISSET(pv[0], &readfrom) )||
- FD_ISSET(pw[0], &readfrom));
- ignore_signals();
-#ifdef KERBEROS
- syslog(LOG_INFO ,
- "Shell process completed.");
-#endif
- /* Finish session in wmtp */
- pty_logwtmp(ttyn,"","");
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- exit(0);
- }
-#if defined(HAVE_SETSID)&&(!defined(ULTRIX))
- setsid();
-#else
-#ifdef SETPGRP_TWOARG
- setpgrp(0, getpid());
-#else
- setpgrp();
-#endif /*setpgrp_twoarg*/
-#endif /*HAVE_SETSID*/
- (void) close(s);
- (void) close(f);
- (void) close(pw[0]);
- if (port)
- (void) close(pv[0]);
- (void) close(px[1]);
-
- (void) dup2(px[0], 0);
- (void) dup2(pw[1], 1);
- if(port)
- (void) dup2(pv[1], 2);
- else dup2(pw[1], 2);
-
- (void) close(px[0]);
- (void) close(pw[1]);
- if(port)
- (void) close(pv[1]);
- }
-
- /* We are simply execing a program over rshd : log entry into wtmp,
- as kexe(pid), then finish out the session right after that.
- Syslog should have the information as to what was exec'd */
- else {
- pty_logwtmp(ttyn,"","");
- }
-
- if (*pwd->pw_shell == '\0')
- pwd->pw_shell = "/bin/sh";
- (void) close(f);
- (void) setgid((gid_t)pwd->pw_gid);
-#ifndef sgi
- if (getuid() == 0 || getuid() != pwd->pw_uid) {
- /* For testing purposes, we don't call initgroups if we
- already have the right uid, and it is not root. This is
- because on some systems initgroups outputs an error message
- if not called by root. */
- initgroups(pwd->pw_name, pwd->pw_gid);
- }
-#endif
-#ifdef HAVE_SETLUID
- /*
- * If we're on a system which keeps track of login uids, then
- * set the login uid.
- */
- if (setluid((uid_t) pwd->pw_uid) < 0) {
- perror("setluid");
- _exit(1);
- }
-#endif /* HAVE_SETLUID */
- if (setuid((uid_t)pwd->pw_uid) < 0) {
- perror("setuid");
- _exit(1);
- }
- /* if TZ is set in the parent, drag it in */
- {
- char **findtz = environ;
- while(*findtz) {
- if(!strncmp(*findtz,"TZ=",3)) {
- envinit[TZENV] = *findtz;
- break;
- }
- findtz++;
- }
- }
- strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
- strncat(shell, pwd->pw_shell, sizeof(shell)-7);
- strncat(username, pwd->pw_name, sizeof(username)-6);
- if (asprintf(&path, "PATH=%s:%s", kprogdir, path_rest) < 0) {
- perror("malloc");
- _exit(1);
- }
- envinit[PATHENV] = path;
-
- /* If we have KRB5CCNAME set, then copy into the
- * child's environment. This can't really have
- * a fixed position because tz may or may not be set.
- */
- if (getenv("KRB5CCNAME")) {
- int i;
- char *buf2;
- if (asprintf(&buf2, "KRB5CCNAME=%s",getenv("KRB5CCNAME")) >= 0) {
-
- for (i = 0; envinit[i]; i++);
- envinit[i] = buf2;
- }
- }
-
- {
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- int i;
- /* these four are covered by ADDRPAD */
-
- for (i = 0; envinit[i]; i++);
-
- aierr = getnameinfo((struct sockaddr *)&localaddr,
- socklen((struct sockaddr *)&localaddr),
- hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (aierr)
- goto skip_localaddr_env;
- snprintf(local_addr, sizeof(local_addr), "KRB5LOCALADDR=%s", hbuf);
- envinit[i++] =local_addr;
-
- snprintf(local_port, sizeof(local_port), "KRB5LOCALPORT=%s", sbuf);
- envinit[i++] =local_port;
- skip_localaddr_env:
-
- aierr = getnameinfo(fromp, socklen(fromp),
- hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (aierr)
- goto skip_remoteaddr_env;
- snprintf(remote_addr, sizeof(remote_addr), "KRB5REMOTEADDR=%s", hbuf);
- envinit[i++] =remote_addr;
-
- snprintf(remote_port, sizeof(remote_port), "KRB5REMOTEPORT=%s", sbuf);
- envinit[i++] =remote_port;
-
- skip_remoteaddr_env:
- ;
- }
-
- /* If we do anything else, make sure there is space in the array. */
-
- for(cnt=0; cnt < num_env; cnt++) {
- int i;
- char *buf2;
-
- if(getenv(save_env[cnt])) {
- if (asprintf(&buf2, "%s=%s", save_env[cnt],
- getenv(save_env[cnt])) >= 0) {
- for (i = 0; envinit[i]; i++);
- envinit[i] = buf2;
- }
- }
- }
-
- /* XXX - If we do anything else, make sure there is space in the array. */
-
- environ = envinit;
-
-#ifdef KERBEROS
- /* To make Kerberos rcp work correctly, we must ensure that we
- invoke Kerberos rcp on this end, not normal rcp, even if the
- shell startup files change PATH. */
- if (!strncmp(cmdbuf, "rcp ", 4) ||
- (do_encrypt && !strncmp(cmdbuf, "-x rcp ", 7))) {
- char *copy;
- struct stat s2;
- int offst = 0;
-
- copy = strdup(cmdbuf);
- if (copy == NULL) {
- perror("malloc");
- _exit(1);
- }
- if (do_encrypt && !strncmp(cmdbuf, "-x ", 3)) {
- offst = 3;
- }
-
- strlcpy(cmdbuf + offst, kprogdir, sizeof(cmdbuf) - offst);
- cp = copy + 3 + offst;
-
- strlcat(cmdbuf, "/rcp", sizeof(cmdbuf));
-
- if (stat((char *)cmdbuf + offst, &s2) >= 0)
- strlcat(cmdbuf, cp, sizeof(cmdbuf));
- else
- strlcpy(cmdbuf, copy, sizeof(cmdbuf));
- free(copy);
- }
-#endif
-
- cp = strrchr(pwd->pw_shell, '/');
- if (cp)
- cp++;
- else
- cp = pwd->pw_shell;
-
- if (do_encrypt && !strncmp(cmdbuf, "-x ", 3)) {
- execl(pwd->pw_shell, cp, "-c", (char *)cmdbuf + 3, (char *)NULL);
- }
- else {
- execl(pwd->pw_shell, cp, "-c", cmdbuf, (char *)NULL);
- }
- perror(pwd->pw_shell);
- perror(cp);
- exit(1);
-
- signout_please:
- if (ccache)
- krb5_cc_destroy(bsd_context, ccache);
- ccache = NULL;
- pty_logwtmp(ttyn,"","");
- exit(1);
-}
-
-
-void
-#ifdef HAVE_STDARG_H
-error(char *fmt, ...)
-#else
-/*VARARGS1*/
-error(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
- char buf[RCMD_BUFSIZ], *cp = buf;
-
-#ifdef HAVE_STDARG_H
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
-
- *cp++ = 1;
- (void) snprintf(cp, sizeof(buf) - (cp - buf), "%s: ", progname);
- (void) vsnprintf(buf+strlen(buf), sizeof(buf) - strlen(buf), fmt, ap);
- va_end(ap);
- (void) write(2, buf, strlen(buf));
- syslog(LOG_ERR ,"%s",buf+1);
-}
-
-
-void getstr(fd, buf, cnt, err)
- int fd;
- char *buf;
- int cnt;
- char *err;
-{
- char c;
-
- do {
- if (read(fd, &c, 1) != 1)
- exit(1);
- *buf++ = c;
- if (--cnt == 0) {
- error("%s too long\n", err);
- exit(1);
- }
- } while (c != 0);
-}
-
-#ifdef CRAY
-char *makejtmp(uid, gid, jid)
- register int uid, gid, jid;
-{
- register char *endc, *tdp = &tmpdir[strlen(tmpdir)];
- register int i;
-
- snprintf(tdp, sizeof(tmpdir) - (tdp - tmpdir), "%s/jtmp.%06d",
- JTMPDIR, jid);
- endc = &tmpdir[strlen(tmpdir)];
-
- endc[1] = '\0';
- for (i = 0; i < 26; i++) {
- endc[0] = 'a' + i;
- if (mkdir(tdp, JTMPMODE) != -1) {
- chown(tdp, uid, gid);
- return (tdp);
- } else if (errno != EEXIST)
- break;
- }
- return(NULL);
-}
-
-
-
-cleanjtmp(user, tpath)
- register char *user, *tpath;
-{
- switch(fork()) {
- case -1:
- break;
- case 0:
- if (secflag) {
- execl("/bin/rm", "rm", "-rf", tpath, 0);
- error("exec of %s failed; errno = %d\n",
- "/bin/rm", errno);
- } else {
- execl(CLEANTMPCMD, CLEANTMPCMD, user, tpath, 0);
- error("exec of %s failed; errno = %d\n",
- CLEANTMPCMD, errno);
- }
- exit(1);
- break;
- default:
- /*
- * Just forget about the child, let init will pick it
- * up after we exit.
- */
- break;
- }
-}
-
-
-
-/***get_packet_classification
- *
- *
- * int get_packet_classification():
- * Obtain packet level and compartments from passed fd...
- *
- * Returns:
- * -1: If could not get user defaults.
- * 0: success
- */
-#ifdef IP_SECURITY
-static int get_packet_classification(fd,useruid,level,comp)
- int fd;
- uid_t useruid;
- int *level;
- long *comp;
-{
- struct socket_security pkt_sec;
- struct udb *udb;
- int retval;
- int sockoptlen;
-
- retval = 0;
- getsysudb ();
- udb = getudbuid ((int) useruid);
- endudb ();
- if (udb == (struct udb *) 0) return(-1);
- /* Get packet IP packet label */
- sockoptlen = SIZEOF_sec;
- if ( getsockopt(fd,SOL_SOCKET,SO_SECURITY,
- (char *) &pkt_sec,&sockoptlen)){ /* Failed */
- return(-2);
- }
- *level = pkt_sec.sec_level;
- *comp = udb->ue_defcomps;
- return(0);
-}
-
-#else /* If no IP_SECURITY set level to users default */
-
-static int get_packet_classification(fd,useruid,level,comp)
- int fd;
- uid_t useruid;
- int *level;
- long *comp;
-{
- struct udb *udb;
- getsysudb ();
- udb = getudbuid ((int) useruid);
- endudb ();
- if (udb == (struct udb *) 0) return(-1);
- *level = udb->ue_deflvl;
- *comp = udb->ue_defcomps;
- return(0);
-}
-
-#endif /* IP_SECURITY */
-
-
-
-/*
- * Make a security log entry for the login attempt.
- * host = pointer to host id
- * flag = status of login
- * failures = current losing streak in login attempts
- */
-/* Make a security log entry for the login attempt.
- * host = pointer to host id
- * flag = status of login
- * failures = current losing streak in login attempts
- */
-
-loglogin(host, flag, failures, ue)
- char *host;
- int flag;
- int failures;
- struct udb * ue;
-{
- char urec[sizeof(struct slghdr) + sizeof(struct slglogin)];
- struct slghdr *uhdr = (struct slghdr *)urec;
- struct slglogin *ulogin=(struct slglogin *)&urec[sizeof(struct slghdr)];
-
- strncpy(ulogin->sl_line, ttyn, sizeof(ulogin->sl_line));
- strncpy(ulogin->sl_host, host, sizeof(ulogin->sl_host));
- ulogin->sl_failures = failures;
- if ( maxlogs && (failures >= maxlogs))
- flag |= SLG_DSABL;
- ulogin->sl_result = flag;
- uhdr->sl_uid = ue->ue_uid;
- uhdr->sl_ruid = ue->ue_uid;
- uhdr->sl_juid = ue->ue_uid;
- uhdr->sl_gid = ue->ue_gids[0];
- uhdr->sl_rgid = ue->ue_gids[0];
- uhdr->sl_slvl = ue->ue_deflvl;
- /* uhdr->sl_scls = ue->ue_defcls; enable for integrity policy */
- uhdr->sl_olvl = 0;
- uhdr->sl_len = sizeof(urec);
-
-#ifdef CRAY2
- slgentry(SLG_LOGN, (word *)urec);
-#else /* ! CRAY2 */
- slgentry(SLG_LOGN, (waddr_t)urec);
-#endif
- return;
-}
-
-#endif /* CRAY */
-
-
-
-void usage()
-{
-#ifdef KERBEROS
- syslog(LOG_ERR, "usage: kshd [-eciK] ");
-#else
- syslog(LOG_ERR, "usage: rshd");
-#endif
-}
-
-
-#ifdef KERBEROS
-
-#ifndef KRB_SENDAUTH_VLEN
-#define KRB_SENDAUTH_VLEN 8 /* length for version strings */
-#endif
-
-#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN
- chars */
-
-static krb5_error_code
-recvauth(netfd, peersin, valid_checksum)
- int netfd;
- struct sockaddr *peersin;
- int *valid_checksum;
-{
- krb5_auth_context auth_context = NULL;
- krb5_error_code status;
- struct sockaddr_in laddr;
- socklen_t len;
- krb5_data inbuf;
- krb5_authenticator *authenticator;
- krb5_ticket *ticket;
- krb5_rcache rcache;
- struct passwd *pwd;
- uid_t uid;
- gid_t gid;
- enum kcmd_proto kcmd_proto;
- krb5_data version;
-
- *valid_checksum = 0;
- len = sizeof(laddr);
- if (getsockname(netfd, (struct sockaddr *)&laddr, &len)) {
- exit(1);
- }
-
-#ifdef unicos61
-#define SIZEOF_INADDR SIZEOF_in_addr
-#else
-#define SIZEOF_INADDR sizeof(struct in_addr)
-#endif
-
- status = krb5_auth_con_init(bsd_context, &auth_context);
- if (status)
- return status;
-
- status = krb5_auth_con_genaddrs(bsd_context, auth_context, netfd,
- KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR);
- if (status)
- return status;
-
- status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
- if (status) return status;
-
- if (! rcache) {
- krb5_principal server;
-
- status = krb5_sname_to_principal(bsd_context, 0, 0,
- KRB5_NT_SRV_HST, &server);
- if (status) return status;
-
- status = krb5_get_server_rcache(bsd_context,
- krb5_princ_component(bsd_context, server, 0),
- &rcache);
- krb5_free_principal(bsd_context, server);
- if (status) return status;
-
- status = krb5_auth_con_setrcache(bsd_context, auth_context, rcache);
- if (status) return status;
- }
-
- status = krb5_recvauth_version(bsd_context, &auth_context, &netfd,
- NULL, /* daemon principal */
- 0, /* no flags */
- keytab, /* normally NULL to use v5srvtab */
- &ticket, /* return ticket */
- &version); /* application version string */
- if (status) {
- /*
- * clean up before exiting
- */
- getstr(netfd, locuser, sizeof(locuser), "locuser");
- getstr(netfd, cmdbuf, sizeof(cmdbuf), "command");
- getstr(netfd, remuser, sizeof(locuser), "remuser");
- return status;
- }
-
- getstr(netfd, locuser, sizeof(locuser), "locuser");
- getstr(netfd, cmdbuf, sizeof(cmdbuf), "command");
-
- /* Must be V5 */
-
- kcmd_proto = KCMD_UNKNOWN_PROTOCOL;
- if (version.length != 9)
- fatal (netfd, "bad application version length");
- if (!memcmp (version.data, "KCMDV0.1", 9))
- kcmd_proto = KCMD_OLD_PROTOCOL;
- if (!memcmp (version.data, "KCMDV0.2", 9))
- kcmd_proto = KCMD_NEW_PROTOCOL;
-
- getstr(netfd, remuser, sizeof(locuser), "remuser");
-
- if ((status = krb5_unparse_name(bsd_context, ticket->enc_part2->client,
- &kremuser)))
- return status;
-
- if ((status = krb5_copy_principal(bsd_context, ticket->enc_part2->client,
- &client)))
- return status;
- if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context,
- &authenticator)))
- return status;
-
- if (authenticator->checksum && !checksum_ignored) {
- struct sockaddr_storage adr;
- unsigned int adr_length = sizeof(adr);
- int e;
- char namebuf[32];
- krb5_boolean valid = 0;
- krb5_data chksumbuf;
-
- chksumbuf.data = NULL;
- if (getsockname(netfd, (struct sockaddr *) &adr, &adr_length) != 0)
- goto error_cleanup;
-
- e = getnameinfo((struct sockaddr *)&adr, adr_length, 0, 0,
- namebuf, sizeof(namebuf), NI_NUMERICSERV);
- if (e)
- fatal(netfd, "local error: can't examine port number");
- if (asprintf(&chksumbuf.data, "%s:%s%s", namebuf, cmdbuf, locuser) < 0)
- goto error_cleanup;
-
- chksumbuf.length = strlen(chksumbuf.data);
- status = krb5_c_verify_checksum(bsd_context,
- ticket->enc_part2->session,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &chksumbuf, authenticator->checksum,
- &valid);
- if (status == 0 && !valid) status = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-
- error_cleanup:
- if (chksumbuf.data)
- free(chksumbuf.data);
- if (status) {
- krb5_free_authenticator(bsd_context, authenticator);
- return status;
- }
- *valid_checksum = 1;
- }
- krb5_free_authenticator(bsd_context, authenticator);
-
-
- if (!strncmp(cmdbuf, "-x ", 3))
- do_encrypt = 1;
-
- {
- krb5_keyblock *key;
- status = krb5_auth_con_getrecvsubkey (bsd_context, auth_context,
- &key);
- if (status)
- fatal (netfd, "Server can't get session subkey");
- if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL)
- fatal (netfd, "No session subkey sent");
- if (key && kcmd_proto == KCMD_OLD_PROTOCOL) {
-#ifdef HEIMDAL_FRIENDLY
- key = 0;
-#else
- fatal (netfd, "Session subkey not allowed in old kcmd protocol");
-#endif
- }
- if (key == 0)
- key = ticket->enc_part2->session;
- rcmd_stream_init_krb5 (key, do_encrypt, 0, 0, kcmd_proto);
- }
-
- /* Null out the "session" because kcmd.c references the session
- * key here, and we do not want krb5_free_ticket() to destroy it. */
- ticket->enc_part2->session = 0;
-
- if ((status = krb5_read_message(bsd_context, (krb5_pointer)&netfd,
- &inbuf))) {
- error("Error reading message: %s\n", error_message(status));
- exit(1);
- }
-
- if (inbuf.length) { /* Forwarding being done, read creds */
- pwd = getpwnam(locuser);
- if (!pwd) {
- error("Login incorrect.\n");
- exit(1);
- }
- uid = pwd->pw_uid;
- gid = pwd->pw_gid;
- if ((status = rd_and_store_for_creds(bsd_context, auth_context, &inbuf,
- ticket, &ccache))) {
- error("Can't get forwarded credentials: %s\n",
- error_message(status));
- exit(1);
- }
- if (chown(krb5_cc_get_name(bsd_context, ccache), uid, gid) == -1) {
- error("Can't chown forwarded credentials: %s\n",
- error_message(errno));
- exit(1);
- }
- }
- krb5_free_ticket(bsd_context, ticket);
- return 0;
-}
-#endif /* KERBEROS */
-
-
-
-void fatal(f, msg)
- int f;
- const char *msg;
-{
- char buf[512];
-#ifndef POSIX_TERMIOS
- int out = 1 ; /* Output queue of f */
-#endif
-
- buf[0] = '\01'; /* error indicator */
- (void) snprintf(buf + 1, sizeof(buf) - 1, "%s: %s.\r\n",progname, msg);
- if ((f == netf) && (pid > 0))
- (void) rcmd_stream_write(f, buf, strlen(buf), 0);
- else
- (void) write(f, buf, strlen(buf));
- syslog(LOG_ERR,"%s\n",msg);
- if (pid > 0) {
- signal(SIGCHLD,SIG_IGN);
- kill(pid,SIGKILL);
-#ifdef POSIX_TERMIOS
- (void) tcflush(1, TCOFLUSH);
-#else
- (void) ioctl(f, TIOCFLUSH, (char *)&out);
-#endif
- cleanup(-1);
- }
- exit(1);
-}
-
-static int
-accept_a_connection (int debug_port, struct sockaddr *from,
- socklen_t *fromlenp)
-{
- int n, s, fd, s4 = -1, s6 = -1, on = 1;
- fd_set sockets;
-
- FD_ZERO(&sockets);
-
-#ifdef KRB5_USE_INET6
- {
- struct sockaddr_in6 sock_in6;
-
- if ((s = socket(AF_INET6, SOCK_STREAM, PF_UNSPEC)) < 0) {
- if ((errno == EPROTONOSUPPORT) || (errno == EAFNOSUPPORT))
- goto skip_ipv6;
- fprintf(stderr, "Error in socket(INET6): %s\n", strerror(errno));
- exit(2);
- }
-
- memset(&sock_in6, 0,sizeof(sock_in6));
- sock_in6.sin6_family = AF_INET6;
- sock_in6.sin6_port = htons(debug_port);
- sock_in6.sin6_addr = in6addr_any;
-
- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on));
-
- if ((bind(s, (struct sockaddr *) &sock_in6, sizeof(sock_in6))) < 0) {
- fprintf(stderr, "Error in bind(INET6): %s\n", strerror(errno));
- exit(2);
- }
-
- if ((listen(s, 5)) < 0) {
- fprintf(stderr, "Error in listen(INET6): %s\n", strerror(errno));
- exit(2);
- }
- s6 = s;
- FD_SET(s, &sockets);
- skip_ipv6:
- ;
- }
-#endif
-
- {
- struct sockaddr_in sock_in;
-
- if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
- fprintf(stderr, "Error in socket: %s\n", strerror(errno));
- exit(2);
- }
-
- memset(&sock_in, 0,sizeof(sock_in));
- sock_in.sin_family = AF_INET;
- sock_in.sin_port = htons(debug_port);
- sock_in.sin_addr.s_addr = INADDR_ANY;
-
- (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
- (char *)&on, sizeof(on));
-
- if ((bind(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) < 0) {
- if (s6 >= 0 && errno == EADDRINUSE)
- goto try_ipv6_only;
- 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);
- }
- s4 = s;
- FD_SET(s, &sockets);
- try_ipv6_only:
- ;
- }
- if (s4 == -1 && s6 == -1) {
- fprintf(stderr, "No valid sockets established, exiting\n");
- exit(2);
- }
- n = select(((s4 < s6) ? s6 : s4) + 1, &sockets, 0, 0, 0);
- if (n < 0) {
- fprintf(stderr, "select error: %s\n", strerror(errno));
- exit(2);
- } else if (n == 0) {
- fprintf(stderr, "internal error? select returns 0\n");
- exit(2);
- }
- if (s6 != -1 && FD_ISSET(s6, &sockets)) {
- if (s4 != -1)
- close(s4);
- s = s6;
- } else if (FD_ISSET(s4, &sockets)) {
- if (s6 != -1)
- close(s6);
- s = s4;
- } else {
- fprintf(stderr,
- "internal error? select returns positive, "
- "but neither fd available\n");
- exit(2);
- }
-
- if ((fd = accept(s, from, fromlenp)) < 0) {
- fprintf(stderr, "Error in accept: %s\n", strerror(errno));
- exit(2);
- }
-
- close(s);
- return fd;
-}
diff --git a/src/appl/bsd/kshd.M b/src/appl/bsd/kshd.M
deleted file mode 100644
index b6d50390a7..0000000000
--- a/src/appl/bsd/kshd.M
+++ /dev/null
@@ -1,211 +0,0 @@
-.\" Copyright (c) 1983 Regents of the University of California.
-.\" All rights reserved. The Berkeley software License Agreement
-.\" specifies the terms and conditions for redistribution.
-.\"
-.\" @(#)rshd.8 6.3 (Berkeley) 5/24/86
-.\"
-.TH KRSHD 8
-.SH NAME
-kshd \- kerberized remote shell server
-.SH SYNOPSIS
-.B /usr/local/sbin/kshd
-[
-.B \-kr45ec
-]
-[\fB\-D\fP \fIport\fP]
-[\fB\-L\fP \fIvariable\fP]
-.SH DESCRIPTION
-.I Krshd
-is the server for the
-.IR rcmd (3)
-routine and, consequently, for the
-.IR rsh (1)
-program. The server provides remote execution facilities
-with authentication based on privileged port numbers from trusted hosts or
-the Kerberos authentication system.
-.PP
-The
-.I kshd
-server is invoked by \fIinetd(8c)\fP when it receives a connection
-on the port indicated in /etc/inetd.conf. A typical /etc/inetd.conf
-configuration line for \fIkrshd\fP might be:
-
-kshell stream tcp nowait root /usr/local/sbin/kshd kshd -5c
-
-When a service request is received, the following protocol is initiated:
-
-.IP 1)
-Authentication is checked
-.IP 2)
-Check authorization via the access-control files \fI.k5login\fP and
-\fI.klogin\fP in the user's home directory.
-.IP 3)
-A null byte is returned on the initial socket
-and the command line is passed to the normal login
-shell of the user. The
-shell inherits the network connections established
-by
-.IR krshd .
-
-\fIKrshd\fP can be configured by command-line arguments passed
-by \fIinetd(8)\fP.
- The options are:
-
-.IP \fB\-5\fP 10
-Allow Kerberos5 authentication with the \fI.k5login\fP access control file
-to be trusted. If this authentication system is used by the client and
-the authorization check is passed, then the user is allowed to log in. If
-the user has no \fI.k5login\fP file, the login will be authorized if the
-results of krb5_aname_to_localname conversion matches the account name.
-Unless special rules are configured, this will be true if and only if the
-Kerberos principal of the connecting user is in the default local realm
-and the principal portion matches the account name.
-
-.IP \fB\-4\fP
-Allow Kerberos4 authentication with the \fI.klogin\fP access control file
-to be trusted. If this authentication system is used by the client and the
-authorization check is passed, then the user is allowed to log in.
-
-.IP \fB\-k\fP
-Allow Kerberos5 and Kerberos4 as acceptable authentication
-mechanisms. This is the same as including \fB\-4\fP and \fB\-5\fP.
-
-.IP \fB\-e\fP
-Require the client to encrypt the connection. Only Kerberos5 clients
-support encryption.
-
-.IP \fB\-L\ variable\fP
-Carry through the current value of the specified variable into the
-environment of the child. This option can be used to preserve up to
-four variables.
-
-
-.IP \fB\-c\fP
-Require Kerberos5 clients to present a cryptographic
-checksum of initial connection information like the name of the user
-that the client is trying to access in the initial authenticator.
-This checksum provides additionl security by preventing an attacker
-from changing the initial connection information. To benefit from
-this security, only Kerberos5 should be trusted; Kerberos4 and rhosts
-authentication do not include this checksum. If this option is
-specified, older Kerberos5 clients that do not send a checksum in the
-authenticator will not be able to authenticate to this server. This
-option is mutually exclusive with the \fB-i\fP option.
-
- If neither the \fB-c\fP or \fB-i\fP options are specified,then
-checksums are validated if presented. Since it is difficult to remove
-a checksum from an authenticator without making the authenticator
-invalid, this default mode is almost as significant of a security
-improvement as \fB-c\fP if new clients are used. It has the additional
-advantage of backwards compatability with some clients.
-Unfortunately, clients before Kerberos V5, Beta5, generate invalid
-checksums; if these clients are used, the \fB-i\fP option must be
-used.
-
-.IP \fB\-i\fP
-Ignore authenticator checksums if provided. This option
-ignore authenticator checksusm presented by current Kerberos clients
-to protect initial connection information; it is the opposite of
-\fB-c\fP. This option is provided because some older
-clients--particularly clients predating the release of Kerberos V5
-Beta5 (May 1995)--present bogus checksums that prevent Kerberos
-authentication from succeeding in the default mode.
-
-
-.PP
-\fIKrshd\fP supports six options which may be used for testing:
-
-.IP \fB\-S\ keytab\fP 10
-Set the \fIkeytab\fP file to use.
-
-.IP \fB\-M\ realm\fP
-Set the Kerberos realm to use.
-
-.IP \fB\-A\fP
-Don't allocate a reserved port for the stderr connection.
-
-.IP \fB\-P\ path\fP
-Use the argument to find the Kerberos binaries. Normally a compiled
-in argument is used.
-
-.IP \fB\-D\ port\fP
-Run in standalone mode, listening on \fBport\fP. The daemon will exit
-after one connection and will not background itself.
-
-.TP
-\fB\-w \fP[\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]
-Controls the form of the remote hostname passed to login(1).
-Specifying \fBip\fP results in the numeric IP address always being
-passed to login(1). Specifying a number, \fImaxhostlen\fP, sets the
-maximum length of the hostname passed to login(1) before it will be
-passed as a numeric IP address. If \fImaxhostlen\fP is 0, then the
-system default, as determined by the utmp or utmpx structures, is
-used. The \fBnostriplocal\fP and \fBstriplocal\fP options, which must
-be preceded by a comma, control whether or not the local host domain
-is stripped from the remote hostname. By default, the equivalent of
-\fBstriplocal\fP is in effect.
-
-.SH DIAGNOSTICS
-Except for the last one listed below,
-all diagnostic messages
-are returned on the initial socket,
-after which any network connections are closed.
-An error is indicated by a leading byte with a value of
-1 (0 is returned in step 3 above upon successful completion
-of all the steps prior to the execution of the login shell).
-.PP
-.B ``locuser too long''
-.br
-The name of the user on the client's machine is
-longer than 16 characters.
-.PP
-.B ``remuser too long''
-.br
-The name of the user on the remote machine is
-longer than 16 characters.
-.PP
-.B ``command too long ''
-.br
-The command line passed exceeds the size of the argument
-list (as configured into the system).
-.PP
-.B ``Login incorrect.''
-.br
-No password file entry for the user name existed.
-.PP
-.B ``No remote directory.''
-.br
-The
-.I chdir
-command to the home directory failed.
-.PP
-.B ``Permission denied.''
-.br
-The authentication procedure described above failed.
-.PP
-.B ``Can't make pipe.''
-.br
-The pipe needed for the
-.BR stderr ,
-wasn't created.
-.PP
-.B ``Try again.''
-.br
-A
-.I fork
-by the server failed.
-.PP
-.B ``<shellname>: ...''
-.br
-The user's login shell could not be started. This message is returned
-on the connection associated with the
-.BR stderr ,
-and is not preceded by a flag byte.
-.SH SEE ALSO
-rshd(8), rsh(1),
-rcmd(3)
-.SH BUGS
-A facility to allow all data exchanges to be encrypted should be
-present.
-.PP
-A more extensible protocol should be used.
diff --git a/src/appl/bsd/login.M b/src/appl/bsd/login.M
deleted file mode 100644
index 3a1b05b4b1..0000000000
--- a/src/appl/bsd/login.M
+++ /dev/null
@@ -1,77 +0,0 @@
-.\" login.1
-.\"
-.TH LOGIN 8
-.SH NAME
-login.krb5 \- kerberos enhanced login program
-.SH SYNOPSIS
-.B login.krb5
-[\fB\-p\fP] [\fB\-fFe\fP \fIusername\fP]
-[\fB\-r | \-k | \-K | \-h \fP\fIhostname\fP]
-.SH DESCRIPTION
-.I login.krb5
-is a modification of the BSD login program which is used for two
-functions. It is the sub-process used by krlogind and telnetd to
-initiate a user session and it is a replacement for the command-line
-login program which, when invoked with a password, acquires Kerberos
-tickets for the user.
-.PP
-.I login.krb5
-will prompt for a username, or take one on the command line, as
-.I login.krb5 username
-and will then prompt for a password. This password will be used to
-acquire Kerberos Version 5 tickets (if possible.) It will also attempt
-to run
-.I aklog
-to get \fIAFS\fP tokens for the user. The version 5 tickets will be
-tested against a local
-.I krb5.keytab
-if it is available, in order to verify the tickets, before letting the
-user in. However, if the password matches the entry in
-\fI/etc/passwd\fP the user will be unconditionally allowed (permitting
-use of the machine in case of network failure.)
-.SH OPTIONS
-.TP
-\fB\-p\fP
-preserve the current environment
-.TP
-\fB\-r\fP \fIhostname\fP
-pass hostname to rlogind. Must be the last argument.
-.TP
-\fB\-h\fP \fIhostname\fP
-pass hostname to telnetd, etc. Must be the last argument.
-.TP
-\fB\-f\fP \fIname\fP
-Perform pre-authenticated login, e.g., datakit, xterm, etc.;
-allows preauthenticated login as root.
-.TP
-\fB\-F\fP \fIname\fP
-Perform pre-authenticated login, e.g., datakit, xterm, etc.; allows
-preauthenticated login as root.
-.TP
-\fB\-e\fP \fIname\fP
-Perform pre-authenticated, encrypted login. Must do term negotiation.
-.SH CONFIGURATION
-.I login.krb5
-is also configured via
-.I krb5.conf
-using the
-.I login
-stanza. A collection of options dealing with initial authentication are
-provided:
-.IP krb5_get_tickets
-Use password to get V5 tickets. Default value true.
-.IP krb_run_aklog
-Attempt to run aklog. Default value false.
-.IP aklog_path
-Where to find it [not yet implemented.] Default value
-.I $(prefix)/bin/aklog.
-.IP accept_passwd
-Don't accept plaintext passwords [not yet implemented]. Default value false.
-
-.SH DIAGNOSTICS
-All diagnostic messages are returned on the connection or tty
-associated with
-.BR stderr.
-.PP
-.SH SEE ALSO
-rlogind(8), rlogin(1), telnetd(8)
diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c
deleted file mode 100644
index fc6198c148..0000000000
--- a/src/appl/bsd/login.c
+++ /dev/null
@@ -1,1930 +0,0 @@
-/*
- * appl/bsd/login.c
- */
-
-/*
- * Copyright (c) 1980, 1987, 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.
- */
-
-#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\
- All rights reserved.\n";
-#endif /* not lint */
-
-/* based on @(#)login.c 5.25 (Berkeley) 1/6/89 */
-
-/* The configuration, with defaults as listed, is of the form:
- [login]
- # login stanza
- krb5_get_tickets = 1
- # use password to get v5 tickets
- krb_run_aklog = 0
- # 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;
-
-#define KRB_RUN_AKLOG
-int login_krb_run_aklog = 0;
-
-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.,
- * does 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)
- *
- * only one of: -r -f -e -k -K -F
- * only one of: -r -h -k -K
- */
-
-#include <libpty.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#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 <fcntl.h>
-
-#include <utmp.h>
-#include <signal.h>
-
-#include <assert.h>
-
-#ifdef HAVE_LASTLOG_H
-#include <lastlog.h>
-#endif
-
-#ifdef linux
-/* linux has V* but not C* in headers. Perhaps we shouldn't be
- * initializing these values anyway -- tcgetattr *should* give
- * them reasonable defaults... */
-#define NO_INIT_CC
-#endif
-
-#include <errno.h>
-#ifdef HAVE_TTYENT_H
-#include <ttyent.h>
-#endif
-#include <syslog.h>
-#include <stdio.h>
-#include <grp.h>
-#include <pwd.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 "com_err.h"
-#include "osconf.h"
-#endif /* KRB5_GET_TICKETS */
-
-#ifndef __STDC__
-#ifndef volatile
-#define volatile
-#endif
-#endif
-
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif
-
-#include "loginpaths.h"
-
-#ifdef POSIX_TERMIOS
-#include <termios.h>
-#ifndef CNUL
-#define CNUL (char) 0
-#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
-
-#if !defined(TAB3)
-#define TAB3 0
-#endif
-
-#define TTYGRPNAME "tty" /* name of group to own ttys */
-
-#if defined(_PATH_MAILDIR)
-#define MAILDIR _PATH_MAILDIR
-#else
-#define MAILDIR "/usr/spool/mail"
-#endif
-#if defined(_PATH_NOLOGIN)
-#define NOLOGIN _PATH_NOLOGIN
-#else
-#define NOLOGIN "/etc/nologin"
-#endif
-#if defined(_PATH_LASTLOG)
-#define LASTLOG _PATH_LASTLOG
-#else
-#define LASTLOG "/usr/adm/lastlog"
-#endif
-#if defined(_PATH_BSHELL)
-#define BSHELL _PATH_BSHELL
-#else
-#define BSHELL "/bin/sh"
-#endif
-
-#if (defined(BSD) && (BSD >= 199103)) /* no /usr/ucb */
-#define QUOTAWARN "/usr/bin/quota"
-#endif
-
-#define MOTDFILE "/etc/motd"
-#define HUSHLOGIN ".hushlogin"
-
-#if !defined(OQUOTA) && !defined(QUOTAWARN)
-#define QUOTAWARN "/usr/ucb/quota" /* warn user about quotas */
-#endif
-
-#ifndef NO_UT_HOST
-#ifndef UT_HOSTSIZE
-/* linux defines it directly in <utmp.h> */
-#define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host)
-#endif /* UT_HOSTSIZE */
-#endif
-#ifndef UT_NAMESIZE
-/* linux defines it directly in <utmp.h> */
-#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
-
-#ifdef NEED_SETENV
-extern int setenv(char *, char *, int);
-#endif
-
-/*
- * 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;
-
-#if 0
-char term[64], *hostname, *username;
-#else
-char term[64], *username;
-#endif
-
-
-
-#ifdef KRB5_GET_TICKETS
-#define MAXPWSIZE 128 /* Biggest string accepted for KRB5
- passsword */
-#endif
-
-#if defined(__SVR4) || defined(sgi)
-#define NO_MOTD
-#define NO_MAILCHECK
-#endif
-
-char *getenv();
-void dofork(void);
-
-char *stypeof(char *);
-void term_init(int);
-int doremotelogin(char *), do_krb_login(char *, int), rootterm(char *);
-void lgetstr(char *, int, char *), getloginname(void), checknologin(void);
-void dolastlog(char *, int, char *), motd(void), check_mail(void);
-void sleepexit(int);
-
-#ifndef HAVE_STRSAVE
-char * strsave(char *);
-#endif
-
-typedef krb5_sigtype sigtype;
-
-sigtype timedout(int);
-
-
-#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
-
-static struct login_confs {
- char *flagname;
- int *flag;
-} login_conf_set[] = {
-#ifdef KRB5_GET_TICKETS
- {"krb5_get_tickets", &login_krb5_get_tickets},
- {"krb_run_aklog", &login_krb_run_aklog},
-#endif
-};
-
-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;
-}
-
-#ifdef KRB5_GET_TICKETS
-krb5_data tgtname = {
- 0,
- KRB5_TGS_NAME_SIZE,
- KRB5_TGS_NAME
-};
-#endif
-
-/* get flags (listed above) from the profile */
-static 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 && *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;
- }
- }
- }
-}
-
-/* UNIX password support */
-
-struct passwd *pwd;
-static char *salt;
-
-#ifdef HAVE_SHADOW
-struct spwd *spwd;
-#endif
-
-static 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
-}
-
-static 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;
-}
-
-static 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[sizeof(user_pwcopy) - 1]='\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;
-krb5_creds my_creds;
-static int got_v5_tickets, forwarded_v5_tickets;
-char ccfile[MAXPATHLEN+6]; /* FILE:path+\0 */
-int krbflag; /* set if tickets have been obtained */
-#endif /* KRB5_GET_TICKETS */
-
-void k_init (ttyn)
- char *ttyn;
-{
-#ifdef KRB5_GET_TICKETS
- krb5_error_code retval;
-
- retval = krb5_init_secure_context(&kcontext);
- if (retval) {
- com_err("login", retval, "while initializing krb5");
- exit(1);
- }
-
- login_get_kconf(kcontext);
-
- /* Set up the credential cache environment variable */
- if (!getenv(KRB5_ENV_CCNAME)) {
- snprintf(ccfile, sizeof(ccfile), "FILE:/tmp/krb5cc_p%ld",
- (long) getpid());
- setenv(KRB5_ENV_CCNAME, ccfile, 1);
- krb5_cc_set_default_name(kcontext, ccfile);
- unlink(ccfile+strlen("FILE:"));
- } else {
- /* note it correctly */
- strncpy(ccfile, getenv(KRB5_ENV_CCNAME), sizeof(ccfile));
- ccfile[sizeof(ccfile) - 1] = '\0';
- }
-#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 */
-}
-
-#ifdef KRB5_GET_TICKETS
-static int k5_get_password (user_pwstring, pwsize)
- char *user_pwstring;
- unsigned int pwsize;
-{
- krb5_error_code code;
- char prompt[255];
- snprintf(prompt, sizeof(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;
-}
-
-static int try_krb5 (me_p, pass)
- krb5_principal *me_p;
- char *pass;
-{
- krb5_error_code code;
- krb5_principal me;
-
- code = krb5_parse_name(kcontext, username, &me);
- if (code) {
- com_err ("login", code, "when parsing name %s",username);
- return 0;
- }
-
- *me_p = me;
-
- code = krb5_get_init_creds_password(kcontext, &my_creds, me, pass,
- krb5_prompter_posix, NULL,
- 0, NULL, NULL);
- 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");
- return 0;
- }
-
- krbflag = got_v5_tickets = 1;
-
- return 1;
-}
-
-static 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;
-}
-#endif /* KRB5_GET_TICKETS */
-
-/* Kerberos ticket-handling routines */
-
-static void destroy_tickets()
-{
-#ifdef KRB5_GET_TICKETS
- krb5_ccache cache;
-
- if (login_krb5_get_tickets) {
- if(!krb5_cc_default(kcontext, &cache))
- krb5_cc_destroy (kcontext, cache);
- }
-#endif
-}
-
-/* AFS support routines */
-#ifdef SETPAG
-
-int pagflag = 0; /* true if setpag() has been called */
-
-/* This doesn't seem to be declared in the AFS header files. */
-extern ktc_ForgetAllTokens (), setpag ();
-
-#ifdef SIGSYS
-static sigjmp_buf setpag_buf;
-
-static sigtype sigsys ()
-{
- siglongjmp(setpag_buf, 1);
-}
-
-static int try_afscall (scall)
- int (*scall)();
-{
- handler sa, osa;
- volatile int retval = 0;
-
- (void) &retval;
- handler_init (sa, sigsys);
- handler_swap (SIGSYS, sa, osa);
- if (sigsetjmp(setpag_buf, 1) == 0) {
- (*scall)();
- retval = 1;
- }
- handler_set (SIGSYS, osa);
- return retval;
-}
-
-#define try_setpag() try_afscall(setpag)
-#define try_unlog() try_afscall(ktc_ForgetAllTokens)
-#else
-#define try_setpag() (setpag() == 0)
-#define try_unlog() (ktc_ForgetAllTokens() == 0)
-#endif /* SIGSYS */
-#endif /* SETPAG */
-
-static void
-afs_login ()
-{
-#if defined(SETPAG)
- if (login_krb5_get_tickets && pwd->pw_uid) {
- /* Only reset the pag for non-root users. */
- /* This allows root to become anything. */
- pagflag = try_setpag ();
- }
-#endif
-#ifdef KRB_RUN_AKLOG
- if (got_v5_tickets && login_krb_run_aklog) {
- /* KPROGDIR is $(prefix)/bin */
- char aklog_path[MAXPATHLEN];
- struct stat st;
- /* construct the name */
- /* get this from profile later */
- aklog_path[sizeof(aklog_path) - 1] = '\0';
- strncpy (aklog_path, KPROGDIR, sizeof(aklog_path) - 1);
- strncat (aklog_path, "/aklog", sizeof(aklog_path) - 1 - strlen(aklog_path));
- /* only run it if we can find it */
- if (stat (aklog_path, &st) == 0) {
- system(aklog_path);
- }
- }
-#endif /* KRB_RUN_AKLOG */
-}
-
-static void
-afs_cleanup ()
-{
-#ifdef SETPAG
- if (pagflag)
- try_unlog ();
-#endif
-}
-
-/* Main routines */
-#define EXCL_AUTH_TEST if (rflag || kflag || Kflag || eflag || fflag ) { \
- fprintf(stderr, \
- "login: only one of -r, -k, -K, -e, -F, 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); \
-}
-
-#if defined(HAVE_ETC_ENVIRONMENT) || defined(HAVE_ETC_TIMEZONE)
-static void
-read_env_vars_from_file (filename)
- char *filename;
-{
- FILE *fp;
- char *p, *eq;
- char tbuf[MAXPATHLEN+2];
-
- if ((fp = fopen(filename, "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);
- }
-}
-#endif
-
-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;
- char **argv;
-{
- extern int optind;
- extern char *optarg, **environ;
- struct group *gr;
- int ch;
- char *p;
- int fflag, hflag, pflag, rflag, cnt;
- int kflag, Kflag, eflag;
- int quietlog, passwd_req, ioctlval;
- char *domain, **envinit, *ttyn, *tty;
- char tbuf[MAXPATHLEN + 2];
- char *ttyname(), *crypt(), *getpass();
- time_t login_time;
- int retval;
- int rewrite_ccache = 1; /*try to write out ccache*/
-#ifdef KRB5_GET_TICKETS
- krb5_principal me;
- krb5_creds save_v5creds;
- krb5_ccache xtra_creds = NULL;
-#endif
- char *ccname = 0; /* name of forwarded cache */
- char *tz = 0;
- char *hostname = 0;
-
- off_t lseek();
- handler sa;
-
- handler_init (sa, timedout);
- handler_set (SIGALRM, sa);
- (void)alarm((u_int)timeout);
-
- 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
-
- /*
- * -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
- * -F is used to skip a second login authentication, allows login as root
- * -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
- */
- (void)gethostname(tbuf, sizeof(tbuf));
- domain = strchr(tbuf, '.');
-
- fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0;
- passwd_req = 1;
- while ((ch = getopt(argc, argv, "Ffeh:pr:k:K:")) != -1)
- switch (ch) {
- case 'f':
- EXCL_AUTH_TEST;
- fflag = 1;
- break;
- 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 = strchr(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 = strchr(optarg, '.')) && !strcmp(p, domain))
- *p = '\0';
- hostname = optarg;
- break;
- 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;
- /* Throw away too-long names, they can't be usernames. */
- if (*argv) {
- if (strlen (*argv) <= UT_NAMESIZE)
- username = *argv;
- else
- fprintf (stderr, "login name '%s' too long\n", *argv);
- }
-
-#if !defined(POSIX_TERMIOS) && defined(TIOCLSET)
- ioctlval = 0;
- /* Only do this we we're not using POSIX_TERMIOS */
- (void)ioctl(0, TIOCLSET, (char *)&ioctlval);
-#endif
-
-#ifdef TIOCNXCL
- (void)ioctl(0, TIOCNXCL, (char *)0);
-#endif
-
- ioctlval = fcntl(0, F_GETFL);
-#ifdef O_NONBLOCK
- ioctlval &= ~O_NONBLOCK;
-#endif
-#ifdef O_NDELAY
- ioctlval &= ~O_NDELAY;
-#endif
- (void)fcntl(0, F_SETFL, ioctlval);
-
- /*
- * If talking to an rlogin process, propagate the terminal type and
- * baud rate across the network.
- */
- if (eflag) {
- lgetstr(term, sizeof(term), "Terminal type");
- } else if (!(kflag || Kflag)) {/* Preserve terminal if not read over net */
- if (getenv("TERM")) {
- strncpy(term, getenv("TERM"), sizeof(term));
- term[sizeof(term) - 1] = '\0';
- }
- }
-
- term_init (rflag || kflag || Kflag || eflag);
-
- 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 = strchr(ttyn, '/')) && (tty = strchr(tty+1, '/')))
- ++tty;
- else
- tty = ttyn;
-
-#ifndef LOG_ODELAY /* 4.2 syslog ... */
- openlog("login", 0);
-#else
- 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 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.
- */
-
- k_init (ttyn);
-
- for (cnt = 0;; username = NULL) {
-#ifdef KRB5_GET_TICKETS
- int kpass_ok, lpass_ok;
- char user_pwstring[MAXPWSIZE];
-#endif /* KRB5_GET_TICKETS */
-
- if (username == NULL) {
- fflag = 0;
- getloginname();
- }
-
- lookup_user(username); /* sets pwd */
-
- /* if user not super-user, check for disabled logins */
- if (pwd == NULL || pwd->pw_uid)
- checknologin();
-
- /*
- * Allows automatic login by root.
- * If not invoked by root, disallow if the uid's differ.
- */
-
- if (fflag && pwd) {
- int uid = (int) getuid();
- passwd_req = (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)
- break;
-
- if (!unix_needs_passwd())
- break;
-
-#ifdef KRB5_GET_TICKETS
- if (login_krb5_get_tickets) {
- /* rename these to something more verbose */
- kpass_ok = 0;
- lpass_ok = 0;
-
- setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
- if (! k5_get_password(user_pwstring, sizeof (user_pwstring))) {
- goto bad_login;
- }
-
- /* 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);
-
- if (pwd->pw_uid != 0) { /* Don't get tickets for root */
- try_krb5(&me, user_pwstring);
-
- krbflag = got_v5_tickets;
- memset (user_pwstring, 0, sizeof(user_pwstring));
- /* password wiped, so we can relax */
- setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
- } else {
- memset(user_pwstring, 0, sizeof(user_pwstring));
- 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;
-
- if (got_v5_tickets) {
- retval = krb5_verify_init_creds(kcontext, &my_creds, NULL,
- NULL, &xtra_creds,
- NULL);
- if (retval) {
- com_err("login", retval, "while verifying initial ticket");
-#ifndef SYSLOG42
- syslog(LOG_NOTICE|LOG_AUTH,
- "can't verify v5 ticket: %s\n",
- error_message(retval));
-#endif
- } else {
- break; /* we're ok */
- }
- }
-
- 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) {
- 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);
-
- /*
- * 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) {
-#ifdef UT_HOSTSIZE
- syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s",
- tty, UT_HOSTSIZE, hostname);
-#else
- syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s",
- tty, hostname);
-#endif
- } 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;
-
- login_time = time(&utmp.ut_time);
- if ((retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username,
- ttyn, hostname,
- PTY_TTYSLOT_USABLE)) < 0)
- com_err (argv[0], retval, "while updating utmp");
- }
-
- quietlog = access(HUSHLOGIN, F_OK) == 0;
- dolastlog(hostname, quietlog, tty);
-
- (void)chown(ttyn, pwd->pw_uid,
- (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
-
- (void)chmod(ttyn, 0620);
-
-#ifdef KRB5_GET_TICKETS
- /* Maybe telnetd got tickets for us? */
- if (!got_v5_tickets && have_v5_tickets (&me))
- forwarded_v5_tickets = 1;
-#endif /* KRB5_GET_TICKETS */
-
-#ifdef KRB5_GET_TICKETS
- if (login_krb5_get_tickets)
- dofork();
-#endif
-
-/* 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
- to match, otherwise stray signals may be delivered to login.krb5 or
- telnetd or rlogind if they don't properly detach from their
- controlling tty, which is the case (under SunOS at least.) */
-
- {
- int pid = getpid();
- struct sigaction sa2, osa;
-
- /* this will set the PGID to the PID. */
-#ifdef HAVE_SETPGID
- if (setpgid(pid,pid) < 0)
- perror("login.krb5: setpgid");
-#elif defined(SETPGRP_TWOARG)
- if (setpgrp(pid,pid) < 0)
- perror("login.krb5: setpgrp");
-#else
- if (setpgrp() < 0)
- perror("login.krb5: setpgrp");
-#endif
-
- /* 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. */
-
- sa2.sa_flags = 0;
- sa2.sa_handler = SIG_IGN;
- sigemptyset(&(sa2.sa_mask));
-
- if (sigaction(SIGTTOU, &sa2, &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, pid) < 0)
- perror("login.krb5: tcsetpgrp");
-#else
- if (ioctl(0, TIOCSPGRP, &pid) < 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);
-
- /*
- * The V5 ccache is created as root. It needs to be owned by the
- * user, and chown (a) assumes they are stored in a file and (b)
- * allows a race condition in which a user can delete the file (if
- * the directory sticky bit is not set) and make it a symlink to
- * somewhere else; on some platforms, chown() on a symlink
- * actually changes the owner of the pointed-to file. This is
- * Bad.
- *
- * So, we suck the V5 krbtgt into memory here, destroy the
- * ccache/ticket file, and recreate them later after the setuid.
- *
- * With the new v5 api, v5 tickets are kept in memory until written
- * out after the setuid. However, forwarded tickets still
- * need to be read in and recreated later
- */
-#ifdef KRB5_GET_TICKETS
- if (forwarded_v5_tickets) {
- krb5_creds mcreds;
-
- memset(&mcreds, 0, sizeof(mcreds));
- memset(&save_v5creds, 0, sizeof(save_v5creds));
-
- mcreds.client = me;
- retval =
- krb5_build_principal_ext(kcontext, &mcreds.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 (retval) {
- syslog(LOG_ERR,
- "%s while creating V5 krbtgt principal",
- error_message(retval));
- rewrite_ccache = 0;
- } else {
- mcreds.ticket_flags = 0;
-
- retval = krb5_cc_retrieve_cred(kcontext, ccache, 0,
- &mcreds, &save_v5creds);
- if (retval) {
- syslog(LOG_ERR,
- "%s while retrieiving V5 initial ticket for copy",
- error_message(retval));
- rewrite_ccache = 0;
- }
- }
-
- krb5_free_principal(kcontext, mcreds.server);
- }
-#endif /* KRB5_GET_TICKETS */
-
-#ifdef KRB5_GET_TICKETS
- if (forwarded_v5_tickets)
- destroy_tickets();
-#endif
-
-#ifdef OQUOTA
- quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
-#endif
-#ifdef HAVE_SETLOGIN
- if (setlogin(pwd->pw_name) < 0)
- syslog(LOG_ERR, "setlogin() failure %d",errno);
-#endif
-
-#ifdef HAVE_SETLUID
- /*
- * If we're on a system which keeps track of login uids, then
- * set the login uid. If this fails this opens up a problem on DEC OSF
- * with C2 enabled.
- */
- if (setluid((uid_t) pwd->pw_uid) < 0) {
- perror("setuid");
- sleepexit(1);
- }
-#endif /* HAVE_SETLUID */
-#ifdef _IBMR2
- if (setuidx(ID_LOGIN, pwd->pw_uid) < 0) {
- perror("setuidx");
- sleepexit(1);
- };
-#endif
-
- /* This call MUST succeed */
- if (setuid((uid_t) pwd->pw_uid) < 0) {
- perror("setuid");
- sleepexit(1);
- }
-
- /*
- * We are the user now. Re-create the destroyed ccache and
- * ticket file.
- */
-
-#ifdef KRB5_GET_TICKETS
- if (got_v5_tickets) {
- /* set up credential cache -- obeying KRB5_ENV_CCNAME
- set earlier */
- /* (KRB5_ENV_CCNAME == "KRB5CCNAME" via osconf.h) */
- if ((retval = krb5_cc_default(kcontext, &ccache))) {
- com_err(argv[0], retval, "while getting default ccache");
- } else if ((retval = krb5_cc_initialize(kcontext, ccache, me))) {
- com_err(argv[0], retval, "when initializing cache");
- } else if ((retval = krb5_cc_store_cred(kcontext, ccache,
- &my_creds))) {
- com_err(argv[0], retval, "while storing credentials");
- } else if (xtra_creds &&
- (retval = krb5_cc_copy_creds(kcontext, xtra_creds,
- ccache))) {
- com_err(argv[0], retval, "while storing credentials");
- }
-
- if (xtra_creds)
- krb5_cc_destroy(kcontext, xtra_creds);
- } else if (forwarded_v5_tickets && rewrite_ccache) {
- if ((retval = krb5_cc_initialize (kcontext, ccache, me))) {
- syslog(LOG_ERR,
- "%s while re-initializing V5 ccache as user",
- error_message(retval));
- } else if ((retval = krb5_cc_store_cred(kcontext, ccache,
- &save_v5creds))) {
- syslog(LOG_ERR,
- "%s while re-storing V5 credentials as user",
- error_message(retval));
-
- }
- krb5_free_cred_contents(kcontext, &save_v5creds);
- }
-#endif /* KRB5_GET_TICKETS */
-
- if (*pwd->pw_shell == '\0')
- pwd->pw_shell = BSHELL;
-
-#if defined(NTTYDISC) && defined(TIOCSETD)
- /* turn on new line discipline for all shells */
- 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 */
- 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;
- }
-
- setenv ("LOGNAME", pwd->pw_name, 1);
- setenv ("LOGIN", pwd->pw_name, 1);
-
- /* read the /etc/environment file on AIX */
-#ifdef HAVE_ETC_ENVIRONMENT
- read_env_vars_from_file ("/etc/environment");
-#endif
-
- /* 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, 1);
-#endif
-
- if (ccname)
- setenv("KRB5CCNAME", ccname, 1);
-
- setenv("HOME", pwd->pw_dir, 1);
- setenv("PATH", LPATH, 0);
- setenv("USER", pwd->pw_name, 1);
- setenv("SHELL", pwd->pw_shell, 1);
-
- if (term[0] == '\0') {
- (void) strncpy(term, stypeof(tty), sizeof(term));
- term[sizeof(term) - 1] = '\0';
- }
- if (term[0])
- (void)setenv("TERM", term, 0);
-
-#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);
- krb5_cc_set_default_name(kcontext, ccfile);
- }
-#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 UT_HOSTSIZE
- syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
- tty, UT_HOSTSIZE, hostname);
-#else
- syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s",
- tty, hostname);
-#endif
- } else {
- syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
- }
- }
-
- afs_login();
-
- if (!quietlog) {
- motd();
- check_mail();
- }
-
-#ifndef OQUOTA
- if (! access( QUOTAWARN, X_OK))
- (void) system(QUOTAWARN);
-#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] = '-';
- p = strrchr(pwd->pw_shell, '/');
- (void) strncpy(tbuf+1, p?(p+1):pwd->pw_shell, sizeof(tbuf) - 1);
- tbuf[sizeof(tbuf) - 1] = '\0';
-
- execlp(pwd->pw_shell, tbuf, (char *)NULL);
- fprintf(stderr, "login: no shell: ");
- perror(pwd->pw_shell);
- 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
-
-void
-term_init (do_rlogin)
-int 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;
- 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(signumber)
- int signumber;
-{
- fprintf(stderr, "Login timed out after %d seconds\n", timeout);
- exit(0);
-}
-
-#ifndef HAVE_TTYENT_H
-int root_tty_security = 1;
-#endif
-
-int rootterm(tty)
- char *tty;
-{
-#ifndef HAVE_TTYENT_H
- return(root_tty_security);
-#else
- struct ttyent *t;
-
- return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
-#endif /* HAVE_TTYENT_H */
-}
-
-#ifndef NO_MOTD
-sigjmp_buf motdinterrupt;
-
-static sigtype
-sigint(signum)
- int signum;
-{
- siglongjmp(motdinterrupt, 1);
-}
-
-void motd()
-{
- register int fd, nchars;
- char tbuf[8192];
- handler sa, osa;
-
- if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
- return;
- 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);
- handler_set (SIGINT, osa);
- (void)close(fd);
-}
-#else
-void motd()
-{
-}
-#endif
-
-#ifndef NO_MAILCHECK
-void check_mail()
-{
- char tbuf[MAXPATHLEN+2];
- struct stat st;
- (void)snprintf(tbuf, sizeof(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 " : "");
-}
-#else
-void check_mail()
-{
-}
-#endif
-
-void 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, (unsigned) nchars);
- sleepexit(0);
- }
-}
-
-void dolastlog(hostname, quiet, tty)
- char *hostname;
- int quiet;
- char *tty;
-{
-#if defined(HAVE_LASTLOG_H) || (defined(BSD) && (BSD >= 199103))
- struct lastlog ll;
- time_t lltime;
- int fd;
-
- if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
- (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
- if (!quiet) {
- if ((read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll)) &&
- (ll.ll_time != 0)) {
-
- /* .ll_time may not be a time_t. */
- lltime = ll.ll_time;
- printf("Last login: %.*s ", 24-5, (char *)ctime(&lltime));
-
- if (*ll.ll_host != '\0')
- printf("from %.*s\n", (int) sizeof(ll.ll_host),
- ll.ll_host);
- else
- printf("on %.*s\n", (int) sizeof(ll.ll_line), ll.ll_line);
- }
- (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
- }
- (void) time(&lltime);
- ll.ll_time = lltime;
-
- (void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
- ll.ll_line[sizeof(ll.ll_line) - 1] = '\0';
-
- if (hostname) {
- (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
- ll.ll_host[sizeof(ll.ll_host) - 1] = '\0';
- } else {
- (void) memset(ll.ll_host, 0, sizeof(ll.ll_host));
- }
-
- (void)write(fd, (char *)&ll, sizeof(ll));
- (void)close(fd);
- }
-#endif
-}
-
-#undef UNKNOWN
-#ifdef __hpux
-#define UNKNOWN 0
-#else
-#define UNKNOWN "su"
-#endif
-
-char *
-stypeof(ttyid)
- char *ttyid;
-{
- char *cp = getenv("term");
-
-#ifndef HAVE_TTYENT_H
- if (cp)
- return cp;
- else
- return(UNKNOWN);
-#else
- struct ttyent *t;
- if (cp)
- return cp;
- else
- return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
-#endif
-}
-
-int 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));
-}
-
-void 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);
-}
-
-void sleepexit(eval)
- int eval;
-{
- sleep((u_int)5);
- exit(eval);
-}
-
-#ifdef KRB5_GET_TICKETS
-static int hungup = 0;
-
-static sigtype
-sighup() {
- hungup = 1;
-}
-
-/* call already conditionalized on login_krb5_get_tickets */
-/*
- * This routine handles cleanup stuff, and the like.
- * It exits only in the child process.
- */
-#include <sys/wait.h>
-void
-dofork()
-{
- int child,pid;
- handler sa;
- int syncpipe[2];
- char c;
- int n;
-
-#ifdef _IBMR2
- update_ref_count(1);
-#endif
- if (pipe(syncpipe) < 0) {
- perror("login: dofork: setting up syncpipe");
- exit(1);
- }
- if (!(child=fork())) {
- close(syncpipe[1]);
- while ((n = read(syncpipe[0], &c, 1)) < 0) {
- if (errno != EINTR) {
- perror("login: dofork: waiting for sync from parent");
- exit(1);
- }
- }
- if (n == 0) {
- fprintf(stderr, "login: dofork: unexpected EOF waiting for sync\n");
- exit(1);
- }
- close(syncpipe[0]);
- return; /* Child process returns */
- }
-
- /* The parent continues here */
-
- /* On receipt of SIGHUP, pass that along to child's process group. */
- handler_init (sa, sighup);
- handler_set (SIGHUP, sa);
- /* Tell child we're ready. */
- close(syncpipe[0]);
- write(syncpipe[1], "", 1);
- close(syncpipe[1]);
-
- /* 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 (1) {
-#ifdef HAVE_WAITPID
- pid = waitpid(child, 0, 0);
-#elif defined(WAIT_USES_INT)
- pid = wait((int *)0);
-#else
- pid = wait((union wait *)0);
-#endif
-
- if (hungup) {
-#ifdef HAVE_KILLPG
- killpg(child, SIGHUP);
-#else
- kill(-child, SIGHUP);
-#endif
- }
-
- if (pid == child)
- break;
- }
-
- /* Cleanup stuff */
- /* Run destroy_tickets to destroy tickets */
- (void) destroy_tickets(); /* If this fails, we lose quietly */
- afs_cleanup ();
-#ifdef _IBMR2
- update_ref_count(-1);
-#endif
-
- /* Leave */
- exit(0);
-}
-#endif /* KRB5_GET_TICKETS */
-
-
-#ifndef HAVE_STRSAVE
-/* Strsave was a routine in the version 4 krb library: we put it here
- for compatablilty with version 5 krb library, since kcmd.o is linked
- into all programs. */
-
-char *strsave(sp)
- char *sp;
-{
- register char *ret;
-
- if ((ret = strdup(sp)) == NULL) {
- fprintf(stderr, "no memory for saving args\n");
- exit(1);
- }
- return(ret);
-}
-#endif
-
-#ifdef _IBMR2
-update_ref_count(int adj)
-{
- struct passwd *save_pwd;
- static char *empty = "\0";
- char *grp;
- int i;
-
- /* save pwd before calling getuserattr() */
- save_pwd = (struct passwd *)malloc(sizeof(struct passwd));
- save_pwd->pw_name = strdup(pwd->pw_name);
- save_pwd->pw_passwd = strdup(pwd->pw_passwd);
- save_pwd->pw_uid = pwd->pw_uid;
- save_pwd->pw_gid = pwd->pw_gid;
- save_pwd->pw_gecos = strdup(pwd->pw_gecos);
- save_pwd->pw_dir = strdup(pwd->pw_dir);
- save_pwd->pw_shell = strdup(pwd->pw_shell);
- pwd = save_pwd;
-
- /* 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);
-#ifdef HAVE_RMUFILE /* pre-4.3.0 AIX */
- putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
- rmufile(grp, 0, GROUP_TABLE);
-#else
- putgroupattr(grp, (char *)0, (void *)0, SEC_DELETE);
- putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
-#endif
- }
- }
- while (*grp) grp++;
- grp++;
- }
- }
- enduserdb();
-}
-#endif
diff --git a/src/appl/bsd/loginpaths.h b/src/appl/bsd/loginpaths.h
deleted file mode 100644
index 8124e1abe9..0000000000
--- a/src/appl/bsd/loginpaths.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* here are actual path values from each operating system supported. */
-/* LPATH is from rlogin, for login.c; RPATH is from rsh, for rshd.c */
-#ifdef sun
-#ifdef __SVR4
-#define RPATH "/usr/bin"
-#define LPATH "/usr/bin"
-#else
-/* sun3 and sun4 */
-#define LPATH "/usr/ucb:/bin:/usr/bin"
-#define RPATH "/usr/ucb:/bin:/usr/bin"
-#endif
-#endif
-
-#ifdef __ultrix
-#define LPATH "/usr/ucb:/bin:/usr/bin"
-#define RPATH "/usr/ucb:/bin:/usr/bin"
-#endif
-
-#ifdef hpux
-/* 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
-#define LPATH "/usr/ucb:/bin:/usr/bin:/usr/local/bin"
-#define RPATH "/bin:/usr/ucb:/usr/bin"
-#endif
-
-#ifdef _IBMR2
-/* 3.2.0 */
-#define LPATH "/usr/bin:/usr/ucb:/usr/bin/X11"
-#define RPATH "/usr/bin:/usr/ucb:/usr/bin/X11"
-#endif
-
-#ifdef __SCO__
-#define LPATH "/bin:/usr/bin:/usr/dbin:/usr/ldbin"
-#define RPATH "/bin:/usr/bin:/usr/local/bin"
-#endif
-
-#ifdef sgi
-#define LPATH "/usr/sbin:/usr/bsd:/usr/bin:/bin:/usr/bin/X11"
-#define RPATH "/usr/sbin:/usr/bsd:/usr/bin:/bin:/usr/bin/X11"
-#endif
-
-#ifdef linux
-#define LPATH "/local/bin:/usr/bin:/bin:/usr/local/bin:/usr/bin/X11:."
-#define RPATH "/local/bin:/usr/bin:/bin:/usr/local/bin:/usr/bin/X11:."
-#endif
-
-#ifdef __386BSD__
-#define LPATH "/usr/bin:/bin"
-#define RPATH "/usr/bin:/bin"
-#endif
-
-#ifdef __alpha
-#ifdef __osf__
-#define LPATH "/usr/bin:."
-#define RPATH "/usr/bin:/bin"
-#endif
-#endif
-
-#ifdef __pyrsoft
-#ifdef MIPSEB
-#define RPATH "/bin:/usr/bin"
-#define LPATH "/usr/bin:/usr/ccs/bin:/usr/ucb:."
-#endif
-#endif
-
-#ifdef __DGUX
-#ifdef __m88k__
-#define RPATH "/usr/bin"
-#define LPATH "/usr/bin"
-#endif
-#endif
-
-#ifndef LPATH
-#ifdef __svr4__
-/* taken from unixware, sirius... */
-#define RPATH "/bin:/usr/bin:/usr/X/bin"
-#define LPATH "/usr/bin:/usr/dbin:/usr/dbin"
-#endif
-#endif
-
-#ifndef LPATH
-#ifdef __NetBSD__
-#define LPATH "/usr/bin:/bin"
-#define RPATH "/usr/bin:/bin"
-#endif
-#endif
-
-#ifdef _PATH_DEFPATH
-#undef LPATH
-#define LPATH _PATH_DEFPATH
-#undef RPATH
-#define RPATH _PATH_DEFPATH
-#endif
-
-/* catch-all entries for operating systems we haven't looked up
- hardcoded paths for */
-#ifndef LPATH
-#define LPATH "/usr/bin:/bin"
-#endif
-
-#ifndef RPATH
-#define RPATH "/usr/bin:/bin"
-#endif
diff --git a/src/appl/bsd/rcp.M b/src/appl/bsd/rcp.M
deleted file mode 100644
index a388e80ed9..0000000000
--- a/src/appl/bsd/rcp.M
+++ /dev/null
@@ -1,160 +0,0 @@
-.\" appl/bsd/rcp.M
-.\"
-.\" Copyright (c) 1983 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.
-.\"
-.\" @(#)rcp.1 6.6 (Berkeley) 9/20/88
-.\"
-.TH RCP 1
-.SH NAME
-rcp \- remote file copy
-.SH SYNOPSIS
-.B rcp
-[\fB\-p\fP] [\fB\-x\fP] [\fB\-k\fP \fIrealm\fP ] [\fB-c\fP \fIccachefile\fP] [\fB-C\fP \fIconfigfile\fP] [\fB\-D\fP \fIport\fP]
-[\fB\-N\fP]
-[\fB\-PN | \-PO\fP]
-.I file1 file2
-.sp
-.B rcp
-[\fB\-p\fB] [\fB\-x\fP] [\fP\-k\fP \fIrealm\fP] [\fB\-r\fP] [\fB\-D\fP
-\fIport\fP] [\fB\-N\fP]
-[\fB\-PN | \-PO\fP]
-.I file ... directory
-.sp
-.B rcp
-[\fB\-f | \-t\fP]
-.I ...
-.SH DESCRIPTION
-.B Rcp
-copies files between machines. Each
-.I file
-or
-.I directory
-argument is either a remote file name of the form ``rhost:path'', or a
-local file name (containing no `:' characters, or a `/' before any
-`:'s).
-.PP
-By default, the mode and owner of
-.I file2
-are preserved if it already existed; otherwise the mode of the source
-file modified by the
-.IR umask (2)
-on the destination host is used.
-.PP
-If
-.I path
-is not a full path name, it is interpreted relative to your login
-directory on
-.IR rhost .
-A
-.I path
-on a remote host may be quoted (using \e, ", or \(aa) so that the
-metacharacters are interpreted remotely.
-.PP
-.B Rcp
-does not prompt for passwords; it uses Kerberos authentication when
-connecting to
-.IR rhost .
-Each user may have a private authorization list in a file \&.k5login in
-his login directory. Each line in this file should contain a Kerberos
-principal name of the form
-.IR principal/instance@realm .
-If there is a ~/.k5login file, then access is granted to the account if
-and only if the originater user is authenticated to one of the
-principals named in the ~/.k5login file. Otherwise, the originating
-user will be granted access to the account if and only if the
-authenticated principal name of the user can be mapped to the local
-account name using the aname -> lname mapping rules (see
-.IR krb5_anadd (8)
-for more details).
-.SH OPTIONS
-.TP
-.B \-p
-attempt to preserve (duplicate) the modification times and modes of the
-source files in the copies, ignoring the
-.IR umask .
-.TP
-\fB\-x\fP
-encrypt all information transferring between hosts.
-.TP
-\fB\-k\fP \fIrealm\fP
-obtain tickets for the remote host in
-.I realm
-instead of the remote host's realm as determined by
-.IR krb_realmofhost (3).
-.TP
-\fB\-c\fP \fIccachefile\fP
-change the default credentials cache file to
-.I ccachefile
-.TP
-\fB\-C\fP \fIconfigfile\fP
-change the default configuation file to
-.I configfile
-.TP
-.B \-r
-if any of the source files are directories, copy each subtree rooted at
-that name; in this case the destination must be a directory.
-.TP
-\fB-PN\fP
-.TP
-\fB-PO\fP
-Explicitly request new or old version of the Kerberos ``rcmd''
-protocol. The new protocol avoids many security problems found in the
-old one, but is not interoperable with older servers. (An
-"input/output error" and a closed connection is the most likely result
-of attempting this combination.) If neither option is specified, some
-simple heuristics are used to guess which to try.
-.TP
-\fB\-D\fP \fIport\fP
-connect to port
-.I port
-on the remote machine.
-.TP
-.B \-N
-use a network connection, even when copying files on the local machine
-(used for testing purposes).
-.TP
-.B \-f \-t
-These options are for internal use only. They tell the
-remotely-running rcp process (started via the Kerberos remote shell
-daemon) which direction files are being sent. These options should
-not be used by the user. In particular, \fB-f\fP does \fBnot\fP mean
-that the user's Kerberos ticket should be forwarded!
-.PP
-.B Rcp
-handles third party copies, where neither source nor target files are on
-the current machine. Hostnames may also take the form ``rname@rhost''
-to use
-.I rname
-rather than the current user name on the remote host.
-.SH FILES
-.TP "\w'~/.k5login\ \ 'u"
-~/.k5login
-(on remote host) - file containing Kerberos principals that are allowed
-access.
-.SH SEE ALSO
-cp(1), ftp(1), rsh(1), rlogin(1), kerberos(3), krb_getrealm(3), kshd(8), rcp(1)
-[UCB version]
-.SH BUGS
-.B Rcp
-doesn't detect all cases where the target of a copy might be a file in
-cases where only a directory should be legal.
-.PP
-.B Rcp
-is confused by any output generated by commands in a \&.login,
-\&.profile, or \&.cshrc file on the remote host.
-.PP
-Kerberos is only used for the first connection of a third-party copy;
-the second connection uses the standard Berkeley rcp protocol.
diff --git a/src/appl/bsd/rlogin.M b/src/appl/bsd/rlogin.M
deleted file mode 100644
index 5958842804..0000000000
--- a/src/appl/bsd/rlogin.M
+++ /dev/null
@@ -1,157 +0,0 @@
-.\" appl/bsd/rlogin.M
-.\"
-.\" Copyright (c) 1983 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.
-.\"
-.\" @(#)rlogin.1 6.9 (Berkeley) 9/19/88
-.\" "
-.TH RLOGIN 1
-.SH NAME
-rlogin \- remote login
-.SH SYNOPSIS
-.B rlogin
-.I rhost
-[\fB\-e\fP\fI\|c\fP] [\fB\-8\fP] [\fB\-c\fP] [ \fB\-a\fP] [\fB\-f\fP]
-[\fB\-F\fP] [\fB\-t\fP \fItermtype\fP] [\fB\-n\fP] [\fB\-7\fP]
-[\fB\-PN | \-PO\fP]
-[\fB\-d\fP] [\fB\-k\fP \fIrealm\fP] [\fB\-x\fP] [\fB\-L\fP] [\fB\-l\fP
-\fIusername\fP]
-.PP
-.SH DESCRIPTION
-.I Rlogin
-connects your terminal on the current local host system
-.I lhost
-to the remote host system
-.I rhost.
-.PP
-The version built to use Kerberos authentication is very similar to the
-standard Berkeley rlogin(1), except that instead of the \fIrhosts\fP
-mechanism, it uses Kerberos authentication to determine the
-authorization to use a remote account.
-.PP
-Each user may have a private authorization list in a file \&.k5login in
-his login directory. Each line in this file should contain a Kerberos
-principal name of the form
-.IR principal/instance@realm .
-If the originating user is authenticated to one of the principals named
-in \&.k5login, access is granted to the account. If there is no
-/.k5login file, the principal will be granted access to the account
-according to the aname\->lname mapping rules. (See
-.IR krb5_anadd(8)
-for more details.) Otherwise a login and password will be prompted for
-on the remote machine as in
-.IR login (1).
-To avoid some security problems, the \&.k5login file must be owned by
-the remote user.
-.PP
-If there is some problem in marshaling the Kerberos authentication
-information, an error message is printed and the standard UCB rlogin is
-executed in place of the Kerberos rlogin.
-.PP
-A line of the form ``~.'' disconnects from the remote host, where ``~''
-is the escape character. Similarly, the line ``~^Z'' (where ^Z,
-control-Z, is the suspend character) will suspend the rlogin session.
-Substitution of the delayed-suspend character (normally ^Y) for the
-suspend character suspends the send portion of the rlogin, but allows
-output from the remote system.
-.PP
-The remote terminal type is the same as your local terminal type (as
-given in your environment TERM variable), unless the
-.B \-t
-option is specified (see below). The terminal or window size is also
-copied to the remote system if the server supports the option, and
-changes in size are reflected as well.
-.PP
-All echoing takes place at the remote site, so that (except for delays)
-the rlogin is transparent. Flow control via ^S and ^Q and flushing of
-input and output on interrupts are handled properly.
-.SH OPTIONS
-.TP
-.B \-8
-allows an eight-bit input data path at all times; otherwise parity bits
-are stripped except when the remote side's stop and start characters are
-other than ^S/^Q. Eight-bit mode is the default.
-.TP
-.B \-L
-allows the rlogin session to be run in litout mode.
-.TP
-\fB\-e\fP\fIc\fP
-sets the escape character to
-.IR c .
-There is no space separating this option flag and the new escape
-character.
-.TP
-.B \-c
-require confirmation before disconnecting via ``~.''
-.TP
-.B \-a
-force the remote machine to ask for a password by sending a null local
-username. This option has no effect unless the standard UCB rlogin is
-executed in place of the Kerberos rlogin (see above).
-.TP
-\fB\-f\fP
-forward a copy of the local credentials to the remote system.
-.TP
-\fB\-F\fP
-forward a
-.I forwardable
-copy of the local credentials to the remote system.
-.TP
-\fB\-t\fP \fItermtype\fP
-replace the terminal type passed to the remote host with
-.IR termtype .
-.TP
-.B \-n
-prevent suspension of rlogin via ``~^Z'' or ``~^Y''.
-.TP
-.B \-7
-force seven-bit transmissions.
-.TP
-.B \-d
-turn on socket debugging (via
-.IR setsockopt (2))
-on the TCP sockets used for communication with the remote host.
-.TP
-.B \-k
-request rlogin to obtain tickets for the remote host in realm
-.I realm
-instead of the remote host's realm as determined by
-.IR krb_realmofhost (3).
-.TP
-\fB\-x\fP
-turn on DES encryption for data passed via the rlogin session. This
-applies only to input and output streams, so the username is sent
-unencrypted. This significantly reduces response time and
-significantly increases CPU utilization.
-.TP
-\fB-PN\fP
-.TP
-\fB-PO\fP
-Explicitly request new or old version of the Kerberos ``rcmd''
-protocol. The new protocol avoids many security problems found in the
-old one, but is not interoperable with older servers. (An
-"input/output error" and a closed connection is the most likely result
-of attempting this combination.) If neither option is specified, some
-simple heuristics are used to guess which to try.
-.SH SEE ALSO
-rsh(1), kerberos(1), krb_sendauth(3), krb_realmofhost(3), rlogin(1) [UCB
-version], klogind(8)
-.SH FILES
-.TP "\w'~/\&.k5login\ \ 'u"
-~/\&.k5login
-(on remote host) - file containing Kerberos principals that are allowed
-access.
-.SH BUGS
-More of the environment should be propagated.
diff --git a/src/appl/bsd/rpaths.h b/src/appl/bsd/rpaths.h
deleted file mode 100644
index b3946772c7..0000000000
--- a/src/appl/bsd/rpaths.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* fallback pathnames */
-
-#ifdef RPROGS_IN_USR_UCB
-#define UCB_RLOGIN "/usr/ucb/rlogin"
-#define UCB_RCP "/usr/ucb/rcp"
-#define UCB_RSH "/usr/ucb/rsh"
-/* all in /usr/ucb/, don't look for /bin/rcp */
-#endif
-
-#ifdef RPROGS_IN_USR_BIN
-#define UCB_RLOGIN "/usr/bin/rlogin"
-#define UCB_RCP "/usr/bin/rcp"
-#define UCB_RSH "/usr/bin/rsh"
-#endif
-
-#ifdef RPROGS_IN_USR_BSD
-#define UCB_RLOGIN "/usr/bsd/rlogin"
-#define UCB_RCP "/usr/bsd/rcp"
-#define UCB_RSH "/usr/bsd/rsh"
-#endif
-
-#ifdef RSH_IS_RCMD
-#undef UCB_RSH
-#define UCB_RSH "/usr/bin/rcmd"
-#endif
-
-#ifdef RSH_IS_REMSH
-#undef UCB_RSH
-#define UCB_RSH "/usr/bin/remsh"
-#endif
diff --git a/src/appl/bsd/rsh.M b/src/appl/bsd/rsh.M
deleted file mode 100644
index ce0ebfb203..0000000000
--- a/src/appl/bsd/rsh.M
+++ /dev/null
@@ -1,173 +0,0 @@
-.\" appl/bsd/rsh.M
-.\"
-.\" Copyright (c) 1983 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.
-.\"
-.\" @(#)rsh.1 6.2 (Berkeley) 9/20/88
-.\" "
-.TH RSH 1
-.SH NAME
-rsh \- remote shell
-.SH SYNOPSIS
-.B rsh
-.I host
-[\fB\-l\fP \fIusername\fP] [\fB\-n\fP] [\fB\-d\fP] [\fB\-k\fP
-\fIrealm\fP] [\fB\-f\fP | \fB\-F\fP] [\fB\-x\fP]
-[\fB\-PN | \-PO\fP]
-.I command
-.SH DESCRIPTION
-.B Rsh
-connects to the specified
-.I host,
-and executes the specified \fIcommand\fR.
-.B Rsh
-copies its standard input to the remote command, the standard output of
-the remote command to its standard output, and the standard error of the
-remote command to its standard error. This implementation of
-.B rsh
-will accept any port for the standard error stream. Interrupt, quit and
-terminate signals are propagated to the remote command; \fIrsh\fP
-normally terminates when the remote command does.
-.PP
-Each user may have a private authorization list in a file \&.k5login in
-his login directory. Each line in this file should contain a Kerberos
-principal name of the form
-.IR principal/instance@realm .
-If there is a ~/.k5login file, then access is granted to the account if
-and only if the originater user is authenticated to one of the
-princiapls named in the ~/.k5login file. Otherwise, the originating
-user will be granted access to the account if and only if the
-authenticated principal name of the user can be mapped to the local
-account name using the aname -> lname mapping rules (see
-.IR krb5_anadd (8)
-for more details).
-.SH OPTIONS
-.TP
-\fB\-l\fP \fIusername\fP
-sets the remote username to
-.IR username .
-Otherwise, the remote username will be the same as the local username.
-.TP
-\fB\-x\fP
-causes the network session traffic to be encrypted. This applies only
-to the input and output streams, and not the command line.
-.TP
-\fB\-f\fP
-cause nonforwardable Kerberos credentials to be forwarded to the remote
-machine for use by the specified
-.IR command .
-They will be removed when
-.I command
-finishes. This option is mutually exclusive with the
-.B \-F
-option.
-.TP
-\fB\-F\fP
-cause
-.I forwardable
-Kerberos credentials to be forwarded to the remote machine for use by
-the specified
-.IR command .
-They will be removed when
-.I command
-finishes. This option is mutually exclusive with the
-.B \-f
-option.
-.TP
-\fB\-k\fP \fIrealm\fP
-causes
-.I rsh
-to obtain tickets for the remote host in
-.I realm
-instead of the remote host's realm as determined by
-.IR krb_realmofhost (3).
-.TP
-.B \-d
-turns on socket debugging (via
-.IR setsockopt (2))
-on the TCP sockets used for communication with the remote host.
-.TP
-.B \-n
-redirects input from the special device
-.I /dev/null
-(see the BUGS section below).
-.TP
-\fB-PN\fP
-.TP
-\fB-PO\fP
-Explicitly request new or old version of the Kerberos ``rcmd''
-protocol. The new protocol avoids many security problems found in the
-old one, but is not interoperable with older servers. (An
-"input/output error" and a closed connection is the most likely result
-of attempting this combination.) If neither option is specified, some
-simple heuristics are used to guess which to try.
-.PP
-If you omit
-.IR command ,
-then instead of executing a single command, you will be logged in on the
-remote host using
-.IR rlogin (1).
-.PP
-Shell metacharacters which are not quoted are interpreted on the local
-machine, while quoted metacharacters are interpreted on the remote
-machine. Thus the command
-.PP
-\ \ \ rsh otherhost cat remotefile >> localfile
-.PP
-appends the remote file
-.I remotefile
-to the local file
-.IR localfile ,
-while
-.PP
-\ \ \ rsh otherhost cat remotefile ">>" otherremotefile
-.PP
-appends
-.I remotefile
-to
-.IR otherremotefile .
-.SH FILES
-.TP "\w'~/.k5login\ \ 'u"
-/etc/hosts
-.sp -1v
-.TP
-~/\&.k5login
-(on remote host) - file containing Kerberos principals that are allowed
-access.
-.SH SEE ALSO
-rlogin(1), kerberos(3), krb_sendauth(3), krb_realmofhost(3), kshd(8)
-.SH BUGS
-If you are using
-.IR csh (1)
-and put a
-.IR rsh (1)
-in the background without redirecting its input away from the terminal,
-it will block even if no reads are posted by the remote command. If no
-input is desired you should redirect the input of
-.I rsh
-to /dev/null using the
-.B \-n
-option.
-.PP
-You cannot run an interactive command (like
-.IR rogue (6)
-or
-.IR vi (1));
-use
-.IR rlogin (1).
-.PP
-Stop signals stop the local \fIrsh\fP process only; this is arguably
-wrong, but currently hard to fix for reasons too complicated to explain
-here.
diff --git a/src/appl/bsd/setenv.c b/src/appl/bsd/setenv.c
deleted file mode 100644
index 0191d9c8c0..0000000000
--- a/src/appl/bsd/setenv.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 1987 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.
- */
-
-/* based on @(#)setenv.c 5.2 (Berkeley) 6/27/88 */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef NEED_SETENV
-extern int setenv(char *, char *, int);
-extern void unsetenv(char *);
-#endif
-
-static char *_findenv(char *, int*);
-/*
- * setenv --
- * Set the value of the environmental variable "name" to be
- * "value". If rewrite is set, replace any current value.
- */
-int
-setenv(name, value, rewrite)
- register char *name, *value;
- int rewrite;
-{
- extern char **environ;
- static int alloced; /* if allocated space before */
- register char *C;
- int l_value, offset;
-
- if (*value == '=') /* no `=' in value */
- ++value;
- l_value = strlen(value);
- if ((C = _findenv(name, &offset))) { /* find if already exists */
- if (!rewrite)
- return(0);
- if (strlen(C) >= l_value) { /* old larger; copy over */
- while ((*C++ = *value++));
- return(0);
- }
- }
- else { /* create new slot */
- register int cnt;
- register char **P;
-
- for (P = environ, cnt = 0; *P; ++P, ++cnt);
- if (alloced) { /* just increase size */
- environ = (char **)realloc((char *)environ,
- (u_int)(sizeof(char *) * (cnt + 2)));
- if (!environ)
- return(-1);
- }
- else { /* get new space */
- alloced = 1; /* copy old entries into it */
- P = (char **)malloc((u_int)(sizeof(char *) *
- (cnt + 2)));
- if (!P)
- return(-1);
- memcpy(P, environ, cnt * sizeof(char *));
- environ = P;
- }
- environ[cnt + 1] = NULL;
- offset = cnt;
- }
- for (C = name; *C && *C != '='; ++C); /* no `=' in name */
- if (!(environ[offset] = /* name + `=' + value */
- malloc((u_int)((int)(C - name) + l_value + 2))))
- return(-1);
- for (C = environ[offset]; (*C = *name++) &&( *C != '='); ++C);
- for (*C++ = '='; (*C++ = *value++););
- return(0);
-}
-
-/*
- * unsetenv(name) --
- * Delete environmental variable "name".
- */
-void
-unsetenv(name)
- char *name;
-{
- extern char **environ;
- register char **P;
- int offset;
-
- while (_findenv(name, &offset)) /* if set multiple times */
- for (P = &environ[offset];; ++P)
- if (!(*P = *(P + 1)))
- break;
-}
-/*
- * Copyright (c) 1987 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.
- */
-
-/* based on @(#)getenv.c 5.5 (Berkeley) 6/27/88 */
-
-#ifndef HAVE_GETENV
-/*
- * getenv --
- * Returns ptr to value associated with name, if any, else NULL.
- */
-char *
-getenv(name)
- char *name;
-{
- int offset;
-
- return(_findenv(name, &offset));
-}
-#endif
-
-/*
- * _findenv --
- * Returns pointer to value associated with name, if any, else NULL.
- * Sets offset to be the offset of the name/value combination in the
- * environmental array, for use by setenv(3) and unsetenv(3).
- * Explicitly removes '=' in argument name.
- *
- * This routine *should* be a static; don't use it.
- */
-static char *
-_findenv(name, offset)
- register char *name;
- int *offset;
-{
- extern char **environ;
- register unsigned int len;
- register char **P, *C;
-
- for (C = name, len = 0; *C && *C != '='; ++C, ++len);
- for (P = environ; *P; ++P)
- if (!strncmp(*P, name, len))
- if (*(C = *P + len) == '=') {
- *offset = P - environ;
- return(++C);
- }
- return(NULL);
-}