386BSD 0.0 development
[unix-history] / usr / src / libexec / rshd / rshd.c
index 1f1b1ba..b926772 100644 (file)
@@ -1,26 +1,53 @@
-/*
- * Copyright (c) 1983, 1988, 1989 The Regents of the University of California.
+/*-
+ * Copyright (c) 1988, 1989 The Regents of the University of California.
  * All rights reserved.
  *
  * All rights reserved.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #ifndef lint
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1983, 1988, 1089 The Regents of the University of California.\n\
+"@(#) Copyright (c) 1988, 1989 The Regents of the University of California.\n\
  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)rshd.c     5.31 (Berkeley) %G%";
+static char sccsid[] = "@(#)rshd.c     5.38 (Berkeley) 3/2/91";
 #endif /* not lint */
 
 #endif /* not lint */
 
-/* From:
+/*
+ * From:
  *     $Source: /mit/kerberos/ucb/mit/rshd/RCS/rshd.c,v $
  *     $Source: /mit/kerberos/ucb/mit/rshd/RCS/rshd.c,v $
- *     $Header: /mit/kerberos/ucb/mit/rshd/RCS/rshd.c,v 5.2 89/07/31 19:30:04 kfall Exp $
+ *     $Header: /mit/kerberos/ucb/mit/rshd/RCS/rshd.c,v 
+ *             5.2 89/07/31 19:30:04 kfall Exp $
  */
 
  */
 
-
 /*
  * remote shell server:
  *     [port]\0
 /*
  * remote shell server:
  *     [port]\0
@@ -31,40 +58,50 @@ static char sccsid[] = "@(#)rshd.c  5.31 (Berkeley) %G%";
  */
 #include <sys/param.h>
 #include <sys/ioctl.h>
  */
 #include <sys/param.h>
 #include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/signal.h>
-#include <sys/signal.h>
 #include <sys/time.h>
 #include <sys/time.h>
+#include <fcntl.h>
+#include <signal.h>
 
 
+#include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/in.h>
-
 #include <arpa/inet.h>
 #include <arpa/inet.h>
+#include <netdb.h>
 
 
-#include <stdio.h>
-#include <errno.h>
 #include <pwd.h>
 #include <pwd.h>
-#include <netdb.h>
 #include <syslog.h>
 #include <syslog.h>
-#include "pathnames.h"
-#include "pathnames.h"
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
 
 
-int    errno;
 int    keepalive = 1;
 int    check_all = 0;
 int    keepalive = 1;
 int    check_all = 0;
-int    check_all = 0;
 char   *index(), *rindex(), *strncat();
 /*VARARGS1*/
 int    error();
 int    sent_null;
 char   *index(), *rindex(), *strncat();
 /*VARARGS1*/
 int    error();
 int    sent_null;
-int    sent_null;
+
+#ifdef KERBEROS
+#include <kerberosIV/des.h>
+#include <kerberosIV/krb.h>
+#define        VERSION_SIZE    9
+#define SECURE_MESSAGE  "This rsh session is using DES encryption for all transmissions.\r\n"
+#define        OPTIONS         "alknvx"
+char   authbuf[sizeof(AUTH_DAT)];
+char   tickbuf[sizeof(KTEXT_ST)];
+int    doencrypt, use_kerberos, vacuous;
+Key_schedule   schedule;
+#else
+#define        OPTIONS "aln"
+#endif
 
 /*ARGSUSED*/
 main(argc, argv)
        int argc;
        char **argv;
 {
 
 /*ARGSUSED*/
 main(argc, argv)
        int argc;
        char **argv;
 {
-       
        extern int opterr, optind;
        extern int _check_rhosts_file;
        struct linger linger;
        extern int opterr, optind;
        extern int _check_rhosts_file;
        struct linger linger;
@@ -74,6 +111,7 @@ main(argc, argv)
        openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
 
        opterr = 0;
        openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
 
        opterr = 0;
+       while ((ch = getopt(argc, argv, OPTIONS)) != EOF)
                switch (ch) {
                case 'a':
                        check_all = 1;
                switch (ch) {
                case 'a':
                        check_all = 1;
@@ -84,6 +122,21 @@ main(argc, argv)
                case 'n':
                        keepalive = 0;
                        break;
                case 'n':
                        keepalive = 0;
                        break;
+#ifdef KERBEROS
+               case 'k':
+                       use_kerberos = 1;
+                       break;
+
+               case 'v':
+                       vacuous = 1;
+                       break;
+
+#ifdef CRYPT
+               case 'x':
+                       doencrypt = 1;
+                       break;
+#endif
+#endif
                case '?':
                default:
                        usage();
                case '?':
                default:
                        usage();
@@ -93,8 +146,21 @@ main(argc, argv)
        argc -= optind;
        argv += optind;
 
        argc -= optind;
        argv += optind;
 
+#ifdef KERBEROS
+       if (use_kerberos && vacuous) {
+               syslog(LOG_ERR, "only one of -k and -v allowed");
+               exit(2);
+       }
+#ifdef CRYPT
+       if (doencrypt && !use_kerberos) {
+               syslog(LOG_ERR, "-k is required for -x");
+               exit(2);
+       }
+#endif
+#endif
+
        fromlen = sizeof (from);
        fromlen = sizeof (from);
-       if (getpeername(0, &from, &fromlen) < 0) {
+       if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
                syslog(LOG_ERR, "getpeername: %m");
                _exit(1);
        }
                syslog(LOG_ERR, "getpeername: %m");
                _exit(1);
        }
@@ -113,8 +179,9 @@ main(argc, argv)
 char   username[20] = "USER=";
 char   homedir[64] = "HOME=";
 char   shell[64] = "SHELL=";
 char   username[20] = "USER=";
 char   homedir[64] = "HOME=";
 char   shell[64] = "SHELL=";
+char   path[100] = "PATH=";
 char   *envinit[] =
 char   *envinit[] =
-           {homedir, shell, _PATH_DEFPATH, username, 0};
+           {homedir, shell, path, username, 0};
 char   **environ;
 
 doit(fromp)
 char   **environ;
 
 doit(fromp)
@@ -126,7 +193,7 @@ doit(fromp)
        int s;
        struct hostent *hp;
        char *hostname, *errorstr = NULL, *errorhost;
        int s;
        struct hostent *hp;
        char *hostname, *errorstr = NULL, *errorhost;
-       short port;
+       u_short port;
        int pv[2], pid, cc;
        int nfd;
        fd_set ready, readfrom;
        int pv[2], pid, cc;
        int nfd;
        fd_set ready, readfrom;
@@ -134,6 +201,19 @@ doit(fromp)
        int one = 1;
        char remotehost[2 * MAXHOSTNAMELEN + 1];
 
        int one = 1;
        char remotehost[2 * MAXHOSTNAMELEN + 1];
 
+#ifdef KERBEROS
+       AUTH_DAT        *kdata = (AUTH_DAT *) NULL;
+       KTEXT           ticket = (KTEXT) NULL;
+       char            instance[INST_SZ], version[VERSION_SIZE];
+       struct          sockaddr_in     fromaddr;
+       int             rc;
+       long            authopts;
+       int             pv1[2], pv2[2];
+       fd_set          wready, writeto;
+
+       fromaddr = *fromp;
+#endif
+
        (void) signal(SIGINT, SIG_DFL);
        (void) signal(SIGQUIT, SIG_DFL);
        (void) signal(SIGTERM, SIG_DFL);
        (void) signal(SIGINT, SIG_DFL);
        (void) signal(SIGQUIT, SIG_DFL);
        (void) signal(SIGTERM, SIG_DFL);
@@ -151,12 +231,6 @@ doit(fromp)
                    fromp->sin_family);
                exit(1);
        }
                    fromp->sin_family);
                exit(1);
        }
-#ifdef IP_OPTIONS
-      {
-       u_char optbuf[BUFSIZ/3], *cp;
-       char lbuf[BUFSIZ], *lp;
-       int optsize = sizeof(optbuf), ipproto;
-       struct protoent *ip;
 #ifdef IP_OPTIONS
       {
        u_char optbuf[BUFSIZ/3], *cp;
 #ifdef IP_OPTIONS
       {
        u_char optbuf[BUFSIZ/3], *cp;
@@ -164,26 +238,6 @@ doit(fromp)
        int optsize = sizeof(optbuf), ipproto;
        struct protoent *ip;
 
        int optsize = sizeof(optbuf), ipproto;
        struct protoent *ip;
 
-       if ((ip = getprotobyname("ip")) != NULL)
-               ipproto = ip->p_proto;
-       else
-               ipproto = IPPROTO_IP;
-       if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, &optsize) == 0 &&
-           optsize != 0) {
-               lp = lbuf;
-               for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
-                       sprintf(lp, " %2.2x", *cp);
-               syslog(LOG_NOTICE,
-                   "Connection received using IP options (ignored):%s", lbuf);
-               if (setsockopt(0, ipproto, IP_OPTIONS,
-                   (char *)NULL, &optsize) != 0) {
-                       syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
-                       exit(1);
-               }
-       }
-      }
-#endif
-
        if ((ip = getprotobyname("ip")) != NULL)
                ipproto = ip->p_proto;
        else
        if ((ip = getprotobyname("ip")) != NULL)
                ipproto = ip->p_proto;
        else
@@ -197,7 +251,7 @@ doit(fromp)
                    "Connection received from %s using IP options (ignored):%s",
                    inet_ntoa(fromp->sin_addr), lbuf);
                if (setsockopt(0, ipproto, IP_OPTIONS,
                    "Connection received from %s using IP options (ignored):%s",
                    inet_ntoa(fromp->sin_addr), lbuf);
                if (setsockopt(0, ipproto, IP_OPTIONS,
-                   (char *)NULL, &optsize) != 0) {
+                   (char *)NULL, optsize) != 0) {
                        syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
                        exit(1);
                }
                        syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
                        exit(1);
                }
@@ -207,6 +261,14 @@ doit(fromp)
 
 #ifdef KERBEROS
        if (!use_kerberos)
 
 #ifdef KERBEROS
        if (!use_kerberos)
+#endif
+               if (fromp->sin_port >= IPPORT_RESERVED ||
+                   fromp->sin_port < IPPORT_RESERVED/2) {
+                       syslog(LOG_NOTICE|LOG_AUTH,
+                           "Connection from %s on illegal port",
+                           inet_ntoa(fromp->sin_addr));
+                       exit(1);
+               }
 
        (void) alarm(60);
        port = 0;
 
        (void) alarm(60);
        port = 0;
@@ -218,6 +280,8 @@ doit(fromp)
                        shutdown(0, 1+1);
                        exit(1);
                }
                        shutdown(0, 1+1);
                        exit(1);
                }
+               if (c== 0)
+                       break;
                port = port * 10 + c - '0';
        }
 
                port = port * 10 + c - '0';
        }
 
@@ -231,13 +295,25 @@ doit(fromp)
                }
 #ifdef KERBEROS
                if (!use_kerberos)
                }
 #ifdef KERBEROS
                if (!use_kerberos)
-               fromp->sin_port = htons((u_short)port);
-               if (connect(s, fromp, sizeof (*fromp)) < 0) {
+#endif
+                       if (port >= IPPORT_RESERVED) {
+                               syslog(LOG_ERR, "2nd port not reserved\n");
+                               exit(1);
+                       }
+               fromp->sin_port = htons(port);
+               if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) {
                        syslog(LOG_INFO, "connect second port: %m");
                        exit(1);
                }
        }
 
                        syslog(LOG_INFO, "connect second port: %m");
                        exit(1);
                }
        }
 
+#ifdef KERBEROS
+       if (vacuous) {
+               error("rshd: remote host requires Kerberos authentication\n");
+               exit(1);
+       }
+#endif
+
 #ifdef notdef
        /* from inetd, socket is already on 0, 1, 2 */
        dup2(f, 0);
 #ifdef notdef
        /* from inetd, socket is already on 0, 1, 2 */
        dup2(f, 0);
@@ -253,6 +329,7 @@ doit(fromp)
                 * in a remote net; look up the name and check that this
                 * address corresponds to the name.
                 */
                 * in a remote net; look up the name and check that this
                 * address corresponds to the name.
                 */
+               hostname = hp->h_name;
 #ifdef KERBEROS
                if (!use_kerberos)
 #endif
 #ifdef KERBEROS
                if (!use_kerberos)
 #endif
@@ -265,12 +342,10 @@ doit(fromp)
                                syslog(LOG_INFO,
                                    "Couldn't look up address for %s",
                                    remotehost);
                                syslog(LOG_INFO,
                                    "Couldn't look up address for %s",
                                    remotehost);
-                               errorstr = 
+                               errorstr =
                                "Couldn't look up address for your host (%s)\n";
                                hostname = inet_ntoa(fromp->sin_addr);
                                "Couldn't look up address for your host (%s)\n";
                                hostname = inet_ntoa(fromp->sin_addr);
-                       }
-#ifdef h_addr  /* 4.2 hack */
-                       for (; ; hp->h_addr_list++) {
+                       } else for (; ; hp->h_addr_list++) {
                                if (hp->h_addr_list[0] == NULL) {
                                        syslog(LOG_NOTICE,
                                          "Host addr %s not listed for host %s",
                                if (hp->h_addr_list[0] == NULL) {
                                        syslog(LOG_NOTICE,
                                          "Host addr %s not listed for host %s",
@@ -288,22 +363,48 @@ doit(fromp)
                                        break;
                                }
                        }
                                        break;
                                }
                        }
-#else
-                       if (bcmp(hp->h_addr, (caddr_t)&fromp->sin_addr,
-                           sizeof(fromp->sin_addr))) {
-                               syslog(LOG_NOTICE,
-                                 "Host addr %s not listed for host %s",
-                                   inet_ntoa(fromp->sin_addr),
-                                   hp->h_name);
-                               error("Host address mismatch\n");
+               }
+       } else
+               errorhost = hostname = inet_ntoa(fromp->sin_addr);
+
+#ifdef KERBEROS
+       if (use_kerberos) {
+               kdata = (AUTH_DAT *) authbuf;
+               ticket = (KTEXT) tickbuf;
+               authopts = 0L;
+               strcpy(instance, "*");
+               version[VERSION_SIZE - 1] = '\0';
+#ifdef CRYPT
+               if (doencrypt) {
+                       struct sockaddr_in local_addr;
+                       rc = sizeof(local_addr);
+                       if (getsockname(0, (struct sockaddr *)&local_addr,
+                           &rc) < 0) {
+                               syslog(LOG_ERR, "getsockname: %m");
+                               error("rlogind: getsockname: %m");
                                exit(1);
                        }
                                exit(1);
                        }
+                       authopts = KOPT_DO_MUTUAL;
+                       rc = krb_recvauth(authopts, 0, ticket,
+                               "rcmd", instance, &fromaddr,
+                               &local_addr, kdata, "", schedule,
+                               version);
+                       des_set_key(kdata->session, schedule);
+               } else
 #endif
 #endif
+                       rc = krb_recvauth(authopts, 0, ticket, "rcmd",
+                               instance, &fromaddr,
+                               (struct sockaddr_in *) 0,
+                               kdata, "", (bit_64 *) 0, version);
+               if (rc != KSUCCESS) {
+                       error("Kerberos authentication failure: %s\n",
+                                 krb_err_txt[rc]);
+                       exit(1);
                }
        } else
                }
        } else
-               errorhost = hostname = inet_ntoa(fromp->sin_addr);
+#endif
+               getstr(remuser, sizeof(remuser), "remuser");
 
 
-       getstr(remuser, sizeof(remuser), "remuser");
        getstr(locuser, sizeof(locuser), "locuser");
        getstr(cmdbuf, sizeof(cmdbuf), "command");
        setpwent();
        getstr(locuser, sizeof(locuser), "locuser");
        getstr(cmdbuf, sizeof(cmdbuf), "command");
        setpwent();
@@ -321,11 +422,29 @@ doit(fromp)
 #endif
        }
 
 #endif
        }
 
-       if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
-           ruserok(hostname, pwd->pw_uid == 0, remuser, locuser) < 0) {
-               error("Permission denied.\n");
-               exit(1);
-       }
+#ifdef KERBEROS
+       if (use_kerberos) {
+               if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0') {
+                       if (kuserok(kdata, locuser) != 0) {
+                               syslog(LOG_NOTICE|LOG_AUTH,
+                                   "Kerberos rsh denied to %s.%s@%s",
+                                   kdata->pname, kdata->pinst, kdata->prealm);
+                               error("Permission denied.\n");
+                               exit(1);
+                       }
+               }
+       } else
+#endif
+
+               if (errorstr ||
+                   pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
+                   ruserok(hostname, pwd->pw_uid == 0, remuser, locuser) < 0) {
+fail:
+                       if (errorstr == NULL)
+                               errorstr = "Permission denied.\n";
+                       error(errorstr, errorhost);
+                       exit(1);
+               }
 
        if (pwd->pw_uid && !access(_PATH_NOLOGIN, F_OK)) {
                error("Logins currently disabled.\n");
 
        if (pwd->pw_uid && !access(_PATH_NOLOGIN, F_OK)) {
                error("Logins currently disabled.\n");
@@ -334,15 +453,15 @@ doit(fromp)
 
        (void) write(2, "\0", 1);
        sent_null = 1;
 
        (void) write(2, "\0", 1);
        sent_null = 1;
-       sent_null = 1;
 
        if (port) {
                if (pipe(pv) < 0) {
                        error("Can't make pipe.\n");
                        exit(1);
                }
 
        if (port) {
                if (pipe(pv) < 0) {
                        error("Can't make pipe.\n");
                        exit(1);
                }
-#ifdef KERBEROS
-               if (encrypt) {
+#ifdef CRYPT
+#ifdef KERBEROS
+               if (doencrypt) {
                        if (pipe(pv1) < 0) {
                                error("Can't make 2nd pipe.\n");
                                exit(1);
                        if (pipe(pv1) < 0) {
                                error("Can't make 2nd pipe.\n");
                                exit(1);
@@ -352,6 +471,7 @@ doit(fromp)
                                exit(1);
                        }
                }
                                exit(1);
                        }
                }
+#endif
 #endif
                pid = fork();
                if (pid == -1)  {
 #endif
                pid = fork();
                if (pid == -1)  {
@@ -359,14 +479,16 @@ doit(fromp)
                        exit(1);
                }
                if (pid) {
                        exit(1);
                }
                if (pid) {
-#ifdef KERBEROS
-                       if (encrypt) {
+#ifdef CRYPT
+#ifdef KERBEROS
+                       if (doencrypt) {
                                static char msg[] = SECURE_MESSAGE;
                                (void) close(pv1[1]);
                                (void) close(pv2[1]);
                                des_write(s, msg, sizeof(msg));
 
                        } else
                                static char msg[] = SECURE_MESSAGE;
                                (void) close(pv1[1]);
                                (void) close(pv2[1]);
                                des_write(s, msg, sizeof(msg));
 
                        } else
+#endif
 #endif
                        {
                                (void) close(0); (void) close(1);
 #endif
                        {
                                (void) close(0); (void) close(1);
@@ -380,8 +502,9 @@ doit(fromp)
                                nfd = pv[0];
                        else
                                nfd = s;
                                nfd = pv[0];
                        else
                                nfd = s;
-#ifdef KERBEROS
-                       if (encrypt) {
+#ifdef CRYPT
+#ifdef KERBEROS
+                       if (doencrypt) {
                                FD_ZERO(&writeto);
                                FD_SET(pv2[0], &writeto);
                                FD_SET(pv1[0], &readfrom);
                                FD_ZERO(&writeto);
                                FD_SET(pv2[0], &writeto);
                                FD_SET(pv1[0], &readfrom);
@@ -389,6 +512,7 @@ doit(fromp)
                                nfd = MAX(nfd, pv2[0]);
                                nfd = MAX(nfd, pv1[0]);
                        } else
                                nfd = MAX(nfd, pv2[0]);
                                nfd = MAX(nfd, pv1[0]);
                        } else
+#endif
 #endif
                                ioctl(pv[0], FIONBIO, (char *)&one);
 
 #endif
                                ioctl(pv[0], FIONBIO, (char *)&one);
 
@@ -396,24 +520,28 @@ doit(fromp)
                        nfd++;
                        do {
                                ready = readfrom;
                        nfd++;
                        do {
                                ready = readfrom;
-#ifdef KERBEROS
-                               if (encrypt) {
+#ifdef CRYPT
+#ifdef KERBEROS
+                               if (doencrypt) {
                                        wready = writeto;
                                        if (select(nfd, &ready,
                                            &wready, (fd_set *) 0,
                                            (struct timeval *) 0) < 0)
                                                break;
                                } else
                                        wready = writeto;
                                        if (select(nfd, &ready,
                                            &wready, (fd_set *) 0,
                                            (struct timeval *) 0) < 0)
                                                break;
                                } else
+#endif
 #endif
                                        if (select(nfd, &ready, (fd_set *)0,
 #endif
                                        if (select(nfd, &ready, (fd_set *)0,
-                                         (fd_set *)0, (struct timeval *)0) < 0)
+                                         (fd_set *)0, (struct timeval *)0) < 0)
                                                break;
                                if (FD_ISSET(s, &ready)) {
                                        int     ret;
                                                break;
                                if (FD_ISSET(s, &ready)) {
                                        int     ret;
-#ifdef KERBEROS
-                                       if (encrypt)
+#ifdef CRYPT
+#ifdef KERBEROS
+                                       if (doencrypt)
                                                ret = des_read(s, &sig, 1);
                                        else
                                                ret = des_read(s, &sig, 1);
                                        else
+#endif
 #endif
                                                ret = read(s, &sig, 1);
                                        if (ret <= 0)
 #endif
                                                ret = read(s, &sig, 1);
                                        if (ret <= 0)
@@ -428,19 +556,21 @@ doit(fromp)
                                                shutdown(s, 1+1);
                                                FD_CLR(pv[0], &readfrom);
                                        } else {
                                                shutdown(s, 1+1);
                                                FD_CLR(pv[0], &readfrom);
                                        } else {
-#ifdef KERBEROS
-                                               if (encrypt)
+#ifdef CRYPT
+#ifdef KERBEROS
+                                               if (doencrypt)
                                                        (void)
                                                          des_write(s, buf, cc);
                                                else
                                                        (void)
                                                          des_write(s, buf, cc);
                                                else
+#endif
 #endif
                                                        (void)
                                                          write(s, buf, cc);
                                        }
                                }
 #endif
                                                        (void)
                                                          write(s, buf, cc);
                                        }
                                }
-#ifdef KERBEROS
-
-                               if (encrypt && FD_ISSET(pv1[0], &ready)) {
+#ifdef CRYPT
+#ifdef KERBEROS
+                               if (doencrypt && FD_ISSET(pv1[0], &ready)) {
                                        errno = 0;
                                        cc = read(pv1[0], buf, sizeof(buf));
                                        if (cc <= 0) {
                                        errno = 0;
                                        cc = read(pv1[0], buf, sizeof(buf));
                                        if (cc <= 0) {
@@ -450,7 +580,7 @@ doit(fromp)
                                                (void) des_write(1, buf, cc);
                                }
 
                                                (void) des_write(1, buf, cc);
                                }
 
-                               if (encrypt && FD_ISSET(pv2[0], &wready)) {
+                               if (doencrypt && FD_ISSET(pv2[0], &wready)) {
                                        errno = 0;
                                        cc = des_read(0, buf, sizeof(buf));
                                        if (cc <= 0) {
                                        errno = 0;
                                        cc = des_read(0, buf, sizeof(buf));
                                        if (cc <= 0) {
@@ -459,29 +589,33 @@ doit(fromp)
                                        } else
                                                (void) write(pv2[0], buf, cc);
                                }
                                        } else
                                                (void) write(pv2[0], buf, cc);
                                }
+#endif
 #endif
 
                        } while (FD_ISSET(s, &readfrom) ||
 #endif
 
                        } while (FD_ISSET(s, &readfrom) ||
-#ifdef KERBEROS
-                           (encrypt && FD_ISSET(pv1[0], &readfrom)) ||
+#ifdef CRYPT
+#ifdef KERBEROS
+                           (doencrypt && FD_ISSET(pv1[0], &readfrom)) ||
+#endif
 #endif
                            FD_ISSET(pv[0], &readfrom));
                        exit(0);
                }
                setpgrp(0, getpid());
                (void) close(s); (void) close(pv[0]);
 #endif
                            FD_ISSET(pv[0], &readfrom));
                        exit(0);
                }
                setpgrp(0, getpid());
                (void) close(s); (void) close(pv[0]);
-#ifdef KERBEROS
-               if (encrypt) {
+#ifdef CRYPT
+#ifdef KERBEROS
+               if (doencrypt) {
                        close(pv1[0]); close(pv2[0]);
                        dup2(pv1[1], 1);
                        dup2(pv2[1], 0);
                        close(pv1[1]);
                        close(pv2[1]);
                }
                        close(pv1[0]); close(pv2[0]);
                        dup2(pv1[1], 1);
                        dup2(pv2[1], 0);
                        close(pv1[1]);
                        close(pv2[1]);
                }
+#endif
 #endif
                dup2(pv[1], 2);
                close(pv[1]);
 #endif
                dup2(pv[1], 2);
                close(pv[1]);
-               close(pv[1]);
        }
        if (*pwd->pw_shell == '\0')
                pwd->pw_shell = _PATH_BSHELL;
        }
        if (*pwd->pw_shell == '\0')
                pwd->pw_shell = _PATH_BSHELL;
@@ -494,6 +628,7 @@ doit(fromp)
        (void) setuid((uid_t)pwd->pw_uid);
        environ = envinit;
        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
        (void) setuid((uid_t)pwd->pw_uid);
        environ = envinit;
        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
+       strcat(path, _PATH_DEFPATH);
        strncat(shell, pwd->pw_shell, sizeof(shell)-7);
        strncat(username, pwd->pw_name, sizeof(username)-6);
        cp = rindex(pwd->pw_shell, '/');
        strncat(shell, pwd->pw_shell, sizeof(shell)-7);
        strncat(username, pwd->pw_name, sizeof(username)-6);
        cp = rindex(pwd->pw_shell, '/');
@@ -502,10 +637,6 @@ doit(fromp)
        else
                cp = pwd->pw_shell;
        endpwent();
        else
                cp = pwd->pw_shell;
        endpwent();
-       if (pwd->pw_uid == 0)
-               syslog(LOG_INFO|LOG_AUTH, "ROOT shell from %s@%s, comm: %s\n",
-                   remuser, hostname, cmdbuf);
-       endpwent();
        if (pwd->pw_uid == 0) {
 #ifdef KERBEROS
                if (use_kerberos)
        if (pwd->pw_uid == 0) {
 #ifdef KERBEROS
                if (use_kerberos)
@@ -524,12 +655,6 @@ doit(fromp)
        exit(1);
 }
 
        exit(1);
 }
 
-/*
- * Report error to client.
- * Note: can't be used until second socket has connected
- * to client, or older clients will hang waiting
- * for that connection first.
- */
 /*
  * Report error to client.
  * Note: can't be used until second socket has connected
 /*
  * Report error to client.
  * Note: can't be used until second socket has connected
@@ -581,7 +706,6 @@ local_domain(h)
        char localhost[MAXHOSTNAMELEN];
        char *p1, *p2, *topdomain();
 
        char localhost[MAXHOSTNAMELEN];
        char *p1, *p2, *topdomain();
 
-       localhost[0] = 0;
        localhost[0] = 0;
        (void) gethostname(localhost, sizeof(localhost));
        p1 = topdomain(localhost);
        localhost[0] = 0;
        (void) gethostname(localhost, sizeof(localhost));
        p1 = topdomain(localhost);
@@ -609,29 +733,7 @@ topdomain(h)
        return (maybe);
 }
 
        return (maybe);
 }
 
-char *
-topdomain(h)
-       char *h;
-{
-       register char *p;
-       char *maybe = NULL;
-       int dots = 0;
-
-       for (p = h + strlen(h); p >= h; p--) {
-               if (*p == '.') {
-                       if (++dots == 2)
-                               return (p);
-                       maybe = p;
-               }
-       }
-       return (maybe);
-}
-
 usage()
 {
 usage()
 {
-#ifdef KERBEROS
-       syslog(LOG_ERR, "usage: rshd [-aln]");
-#else
-       syslog(LOG_ERR, "usage: rshd [-alknvx]");
-#endif
+       syslog(LOG_ERR, "usage: rshd [-%s]", OPTIONS);
 }
 }