diff options
Diffstat (limited to 'src/appl/bsd')
-rw-r--r-- | src/appl/bsd/Makefile.in | 84 | ||||
-rw-r--r-- | src/appl/bsd/configure.in | 159 | ||||
-rw-r--r-- | src/appl/bsd/defines.h | 85 | ||||
-rw-r--r-- | src/appl/bsd/deps | 82 | ||||
-rw-r--r-- | src/appl/bsd/forward.c | 76 | ||||
-rw-r--r-- | src/appl/bsd/getdtablesize.c | 19 | ||||
-rw-r--r-- | src/appl/bsd/kcmd.c | 1035 | ||||
-rw-r--r-- | src/appl/bsd/klogind.M | 174 | ||||
-rw-r--r-- | src/appl/bsd/krcp.c | 1363 | ||||
-rw-r--r-- | src/appl/bsd/krlogin.c | 1807 | ||||
-rw-r--r-- | src/appl/bsd/krlogind.c | 1430 | ||||
-rw-r--r-- | src/appl/bsd/krsh.c | 595 | ||||
-rw-r--r-- | src/appl/bsd/krshd.c | 2047 | ||||
-rw-r--r-- | src/appl/bsd/kshd.M | 211 | ||||
-rw-r--r-- | src/appl/bsd/login.M | 77 | ||||
-rw-r--r-- | src/appl/bsd/login.c | 1930 | ||||
-rw-r--r-- | src/appl/bsd/loginpaths.h | 113 | ||||
-rw-r--r-- | src/appl/bsd/rcp.M | 160 | ||||
-rw-r--r-- | src/appl/bsd/rlogin.M | 157 | ||||
-rw-r--r-- | src/appl/bsd/rpaths.h | 30 | ||||
-rw-r--r-- | src/appl/bsd/rsh.M | 173 | ||||
-rw-r--r-- | src/appl/bsd/setenv.c | 166 |
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, ×)); -} -#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 *)¬c); -#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 *)¬c); -#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 = ¬c; - 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 *)<c); - (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); -} |