summaryrefslogtreecommitdiffstats
path: root/src/appl/bsd
diff options
context:
space:
mode:
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 5ec3c950f..000000000
--- 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 330c87d51..000000000
--- 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 b565cd87d..000000000
--- 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 f83d52390..000000000
--- 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 ad0680cd7..000000000
--- 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 244616cc9..000000000
--- 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 276c7038f..000000000
--- 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 574ae67b1..000000000
--- 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 0d9089a47..000000000
--- 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 0a00e37e3..000000000
--- 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 cc7acad64..000000000
--- 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 028d3dd62..000000000
--- 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 d491e6e35..000000000
--- 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 b6d50390a..000000000
--- 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 3a1b05b4b..000000000
--- 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 fc6198c14..000000000
--- 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 8124e1abe..000000000
--- 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 a388e80ed..000000000
--- 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 595884280..000000000
--- 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 b3946772c..000000000
--- 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 ce0ebfb20..000000000
--- 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 0191d9c8c..000000000
--- 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);
-}