BSD 4_3_Net_2 release
[unix-history] / usr / src / usr.sbin / sliplogin / sliplogin.c
index 42afaf3..a4cf214 100644 (file)
@@ -2,19 +2,33 @@
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement:  ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * 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
  */
 
 #ifndef lint
@@ -24,7 +38,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)sliplogin.c        5.3 (Berkeley) 7/1/90";
+static char sccsid[] = "@(#)sliplogin.c        5.6 (Berkeley) 3/2/91";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -43,30 +57,32 @@ static char sccsid[] = "@(#)sliplogin.c     5.3 (Berkeley) 7/1/90";
  * There are two forms of usage:
  *
  * "sliplogin"
  * There are two forms of usage:
  *
  * "sliplogin"
- * Invoked simply as "sliplogin" and a realuid != 0, the program looks up
- * the uid in /etc/passwd, and then the username in the file /etc/hosts.slip.
- * If and entry is found, the line on fd0 is configured for SLIP operation
+ * Invoked simply as "sliplogin", the program looks up the username
+ * in the file /etc/slip.hosts.
+ * If an entry is found, the line on fd0 is configured for SLIP operation
  * as specified in the file.
  *
  * as specified in the file.
  *
- * "sliplogin IPhost1 </dev/ttyb"
+ * "sliplogin IPhostlogin </dev/ttyb"
  * Invoked by root with a username, the name is looked up in the
  * Invoked by root with a username, the name is looked up in the
- * /etc/hosts.slip file and if found fd0 is configured as in case 1.
+ * /etc/slip.hosts file and if found fd0 is configured as in case 1.
  */
 
 #include <sys/param.h>
 #include <sys/socket.h>
  */
 
 #include <sys/param.h>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
 #include <sys/signal.h>
 #include <sys/file.h>
 #include <sys/syslog.h>
 #include <netdb.h>
 
 #include <sys/signal.h>
 #include <sys/file.h>
 #include <sys/syslog.h>
 #include <netdb.h>
 
-#if defined(BSD4_4)
-#define TERMIOS
+#if BSD >= 199006
+#define POSIX
 #endif
 #endif
-#ifdef TERMIOS
+#ifdef POSIX
 #include <sys/termios.h>
 #include <sys/termios.h>
+#include <sys/ioctl.h>
 #include <ttyent.h>
 #include <ttyent.h>
+#else
+#include <sgtty.h>
 #endif
 #include <netinet/in.h>
 #include <net/if.h>
 #endif
 #include <netinet/in.h>
 #include <net/if.h>
@@ -81,9 +97,9 @@ static char sccsid[] = "@(#)sliplogin.c       5.3 (Berkeley) 7/1/90";
 int    unit;
 int    slip_mode;
 int    speed;
 int    unit;
 int    slip_mode;
 int    speed;
+int    uid;
 char   loginargs[BUFSIZ];
 char   loginargs[BUFSIZ];
-char   loginfile[BUFSIZ];
-char   logoutfile[BUFSIZ];
+char   loginfile[MAXPATHLEN];
 char   loginname[BUFSIZ];
 
 struct slip_modes {
 char   loginname[BUFSIZ];
 
 struct slip_modes {
@@ -144,9 +160,8 @@ findid(name)
                 * a generic one.
                 */
                (void)sprintf(loginfile, "%s.%s", _PATH_LOGIN, name);
                 * a generic one.
                 */
                (void)sprintf(loginfile, "%s.%s", _PATH_LOGIN, name);
-               if (access(loginfile, R_OK|X_OK)) {
+               if (access(loginfile, R_OK|X_OK) != 0) {
                        (void)strcpy(loginfile, _PATH_LOGIN);
                        (void)strcpy(loginfile, _PATH_LOGIN);
-                       (void)strcpy(logoutfile, _PATH_LOGOUT);
                        if (access(loginfile, R_OK|X_OK)) {
                                fputs("access denied - no login file\n",
                                      stderr);
                        if (access(loginfile, R_OK|X_OK)) {
                                fputs("access denied - no login file\n",
                                      stderr);
@@ -155,8 +170,7 @@ findid(name)
                                       name, _PATH_LOGIN);
                                exit(5);
                        }
                                       name, _PATH_LOGIN);
                                exit(5);
                        }
-               } else
-                       (void)sprintf(logoutfile, "%s.%s", _PATH_LOGOUT, name);
+               }
 
                (void) fclose(fp);
                return;
 
                (void) fclose(fp);
                return;
@@ -212,18 +226,23 @@ sigstr(s)
        return(buf);
 }
 
        return(buf);
 }
 
-int
+void
 hup_handler(s)
        int s;
 {
 hup_handler(s)
        int s;
 {
+       char logoutfile[MAXPATHLEN];
+
+       (void)sprintf(logoutfile, "%s.%s", _PATH_LOGOUT, loginname);
+       if (access(logoutfile, R_OK|X_OK) != 0)
+               (void)strcpy(logoutfile, _PATH_LOGOUT);
        if (access(logoutfile, R_OK|X_OK) == 0) {
        if (access(logoutfile, R_OK|X_OK) == 0) {
-               char logincmd[2*BUFSIZ+32];
+               char logincmd[2*MAXPATHLEN+32];
 
 
-               (void)sprintf(logincmd, "%s %d %d %s", logoutfile, unit, speed,
+               (void) sprintf(logincmd, "%s %d %d %s", logoutfile, unit, speed,
                              loginargs);
                              loginargs);
-               (void)system(logincmd);
+               (void) system(logincmd);
        }
        }
-       (void)close(0);
+       (void) close(0);
        syslog(LOG_INFO, "closed %s slip unit %d (%s)\n", loginname, unit,
               sigstr(s));
        exit(1);
        syslog(LOG_INFO, "closed %s slip unit %d (%s)\n", loginname, unit,
               sigstr(s));
        exit(1);
@@ -234,12 +253,12 @@ main(argc, argv)
        int argc;
        char *argv[];
 {
        int argc;
        char *argv[];
 {
-       int     fd, s, ldisc, odisc;
+       int fd, s, ldisc, odisc;
        char *name;
        char *name;
-#ifdef TERMIOS
-       struct  termios tios, otios;
+#ifdef POSIX
+       struct termios tios, otios;
 #else
 #else
-       struct  sgttyb tty, otty;
+       struct sgttyb tty, otty;
 #endif
        char logincmd[2*BUFSIZ+32];
        extern uid_t getuid();
 #endif
        char logincmd[2*BUFSIZ+32];
        extern uid_t getuid();
@@ -250,20 +269,19 @@ main(argc, argv)
        for (fd = 3 ; fd < s ; fd++)
                (void) close(fd);
        openlog(name, LOG_PID, LOG_DAEMON);
        for (fd = 3 ; fd < s ; fd++)
                (void) close(fd);
        openlog(name, LOG_PID, LOG_DAEMON);
+       uid = getuid();
        if (argc > 1) {
        if (argc > 1) {
-               if (argc > 2) {
-                       (void)fprintf(stderr, "Usage: %s loginname\n", argv[0]);
-                       exit(1);
-               }
                findid(argv[1]);
 
                /*
                 * Disassociate from current controlling terminal, if any,
                 * and ensure that the slip line is our controlling terminal.
                 */
                findid(argv[1]);
 
                /*
                 * Disassociate from current controlling terminal, if any,
                 * and ensure that the slip line is our controlling terminal.
                 */
-#ifdef TERMIOS
-               (void) setsid();
-               (void) ioctl(0, TIOCSCTTY, (caddr_t)0);
+#ifdef POSIX
+               if (fork() > 0)
+                       exit(0);
+               if (setsid() != 0)
+                       perror("setsid");
 #else
                if ((fd = open("/dev/tty", O_RDONLY, 0)) >= 0) {
                        extern char *ttyname();
 #else
                if ((fd = open("/dev/tty", O_RDONLY, 0)) >= 0) {
                        extern char *ttyname();
@@ -276,33 +294,46 @@ main(argc, argv)
                                (void) close(fd);
                }
                (void) setpgrp(0, getpid());
                                (void) close(fd);
                }
                (void) setpgrp(0, getpid());
+#endif
+               if (argc > 2) {
+                       if ((fd = open(argv[2], O_RDWR)) == -1) {
+                               perror(argv[2]);
+                               exit(2);
+                       }
+                       (void) dup2(fd, 0);
+                       if (fd > 2)
+                               close(fd);
+               }
+#ifdef TIOCSCTTY
+               if (ioctl(0, TIOCSCTTY, (caddr_t)0) != 0)
+                       perror("ioctl (TIOCSCTTY)");
 #endif
        } else {
 #endif
        } else {
-               extern char *getenv();
+               extern char *getlogin();
 
 
-               if ((name = getenv("USER")) == NULL) {
+               if ((name = getlogin()) == NULL) {
                        (void) fprintf(stderr, "access denied - no username\n");
                        (void) fprintf(stderr, "access denied - no username\n");
-                       syslog(LOG_ERR, "access denied - no username\n");
+                       syslog(LOG_ERR, "access denied - getlogin returned 0\n");
                        exit(1);
                }
                findid(name);
        }
        (void) fchmod(0, 0600);
        (void) fprintf(stderr, "starting slip login for %s\n", loginname);
                        exit(1);
                }
                findid(name);
        }
        (void) fchmod(0, 0600);
        (void) fprintf(stderr, "starting slip login for %s\n", loginname);
-#ifdef TERMIOS
+#ifdef POSIX
        /* set up the line parameters */
        /* set up the line parameters */
-       if (ioctl(0, TIOCGETA, (caddr_t)&tios) < 0) {
-               syslog(LOG_ERR, "ioctl (TIOCGETA): %m");
+       if (tcgetattr(0, &tios) < 0) {
+               syslog(LOG_ERR, "tcgetattr: %m");
                exit(1);
        }
        otios = tios;
                exit(1);
        }
        otios = tios;
-       tios.c_cflag = CS8|CREAD|HUPCL;
-       tios.c_iflag = IGNBRK;
-       tios.c_oflag = tios.c_lflag = 0;
-       if (ioctl(0, TIOCSETA, (caddr_t)&tios) < 0) {
-               syslog(LOG_ERR, "ioctl (TIOCSETA) (1): %m");
+       cfmakeraw(&tios);
+       tios.c_iflag &= ~IMAXBEL;
+       if (tcsetattr(0, TCSAFLUSH, &tios) < 0) {
+               syslog(LOG_ERR, "tcsetattr: %m");
                exit(1);
        }
                exit(1);
        }
+       speed = cfgetispeed(&tios);
 #else
        /* set up the line parameters */
        if (ioctl(0, TIOCGETP, (caddr_t)&tty) < 0) {
 #else
        /* set up the line parameters */
        if (ioctl(0, TIOCGETP, (caddr_t)&tty) < 0) {
@@ -328,8 +359,8 @@ main(argc, argv)
                exit(1);
        }
        /* find out what unit number we were assigned */
                exit(1);
        }
        /* find out what unit number we were assigned */
-       if (ioctl(0, TIOCGETD, (caddr_t)&unit) < 0) {
-               syslog(LOG_ERR, "ioctl (TIOCGETD) (2): %m");
+       if (ioctl(0, SLIOCGUNIT, (caddr_t)&unit) < 0) {
+               syslog(LOG_ERR, "ioctl (SLIOCGUNIT): %m");
                exit(1);
        }
        (void) signal(SIGHUP, hup_handler);
                exit(1);
        }
        (void) signal(SIGHUP, hup_handler);
@@ -342,16 +373,23 @@ main(argc, argv)
         * aim stdout and errout at /dev/null so logincmd output won't
         * babble into the slip tty line.
         */
         * aim stdout and errout at /dev/null so logincmd output won't
         * babble into the slip tty line.
         */
-       (void)close(1);
-       if ((fd = open("/dev/null", O_WRONLY, 0)) != 1) {
+       (void) close(1);
+       if ((fd = open(_PATH_DEVNULL, O_WRONLY)) != 1) {
                if (fd < 0) {
                        syslog(LOG_ERR, "open /dev/null: %m");
                        exit(1);
                }
                if (fd < 0) {
                        syslog(LOG_ERR, "open /dev/null: %m");
                        exit(1);
                }
-               (void)dup2(fd, 1);
-               (void)close(fd);
+               (void) dup2(fd, 1);
+               (void) close(fd);
        }
        }
-       (void)dup2(1,2);
+       (void) dup2(1, 2);
+
+       /*
+        * Run login and logout scripts as root (real and effective);
+        * current route(8) is setuid root, and checks the real uid
+        * to see whether changes are allowed (or just "route get").
+        */
+       (void) setuid(0);
        if (s = system(logincmd)) {
                syslog(LOG_ERR, "%s login failed: exit status %d from %s",
                       loginname, s, loginfile);
        if (s = system(logincmd)) {
                syslog(LOG_ERR, "%s login failed: exit status %d from %s",
                       loginname, s, loginfile);