hybrid version of van's & old sliplogin (major cleanup)
authorTrent Hein <trent@ucbvax.Berkeley.EDU>
Mon, 2 Jul 1990 02:29:38 +0000 (18:29 -0800)
committerTrent Hein <trent@ucbvax.Berkeley.EDU>
Mon, 2 Jul 1990 02:29:38 +0000 (18:29 -0800)
SCCS-vsn: usr.sbin/sliplogin/sliplogin.c 5.2
SCCS-vsn: usr.sbin/sliplogin/sliplogin.8 5.2

usr/src/usr.sbin/sliplogin/sliplogin.8
usr/src/usr.sbin/sliplogin/sliplogin.c

index 9ed47bc..5c075e5 100644 (file)
 .\"
 .\" %sccs.include.redist.man%
 .\"
 .\"
 .\" %sccs.include.redist.man%
 .\"
-.\"    @(#)sliplogin.8 5.1 (Berkeley) %G%
+.\"    @(#)sliplogin.8 5.2 (Berkeley) %G%
 .\"
 .TH SLIPLOGIN 8 ""
 .\"
 .TH SLIPLOGIN 8 ""
-.UC 7
 .SH NAME
 sliplogin \- attach a serial line network interface
 .SH SYNOPSIS
 .B sliplogin
 .SH NAME
 sliplogin \- attach a serial line network interface
 .SH SYNOPSIS
 .B sliplogin
-[ {
-.I loginname
-|
-.I local
-.I remote
 [
 [
-.I mask
-] } ]
+.I loginname
+]
 .SH DESCRIPTION
 .B sliplogin
 .SH DESCRIPTION
 .B sliplogin
-is used to turn the terminal line on the standard input of the process into
-a Serial Line IP link to a remote host.  In order to do this, the program
-needs to know the local interface address of the link, the remote interface
-address, and the applicable (sub)net mask.  There are three ways it may
-determine this information:
-.IP -
-If run by a non-root user id, the program will ignore any arguments and
-instead search a table (the
-.B /etc/hosts.slip
-file) for an entry matching that user id's login name, and set the parameters
-it needs from the contents of the matching entry.  This would be the typical
-usage when sliplogin is the shell for a remote site connecting via dialup
-SLIP.
-.IP -
-If run by root with a single argument, the described search procedure will
-be performed using the argument as a key.
-.IP -
-If run by root with two or three arguments, they are assumed to set the
-needed parameters explicitly.  A missing
-.I mask
-will cause the default network mask for that class network to be used.
-.PP
-The parameters may be specified either by name (which will be looked up
-using
-.BR gethostbyname (3N)
-and
-.BR getnetbyname (3N)),
-or as a dotted quad that the
-.BR inet_addr (3N)
-function can interpret.
+is used to turn the terminal line on standard input into
+a Serial Line IP (SLIP) link to a remote host.  To do this, the program
+searches the file
+.B /etc/slip.hosts
+for an entry matching
+.I loginname
+(which defaults to the current login name if omitted).
+If a matching entry is found, the line is configured appropriately
+for slip (8-bit transparent i/o) and converted to SLIP line
+discipline.  Then a shell script is invoked to initialize the slip
+interface with the appropriate local and remote IP address,
+netmask, etc.
 .PP
 .PP
-The line speed is unchanged, but other terminal line parameters are
-initialized properly for the purpose.
+The usual initialization script is
+.B /etc/slip.login
+but, if particular hosts need special initialization, the file
+.BI /etc/slip.login. loginname
+will be executed instead if it exists.
+The script is invoked with the parameters
+.TP
+.I slipunit
+The unit number of the slip interface assigned to this line.  E.g.,
+.B 0
+for
+.BR sl0 .
+.TP
+.I speed
+The speed of the line.
+.TP
+.I args
+The arguments from the
+.B /etc/slip.hosts
+entry, in order starting with
+.IR loginname .
 .PP
 Only the super-user may attach a network interface.  The interface is
 .PP
 Only the super-user may attach a network interface.  The interface is
-automatically detached when the
+automatically detached when the other end hangs up or the
 .B sliplogin
 .B sliplogin
-process dies.  If the kernel
-.B slip
+process dies.  If the kernel slip
 module has been configured for it, all routes through that interface will
 module has been configured for it, all routes through that interface will
-also disappear at the same time.
-.SH "TABLE FORMAT"
-The format of the
-.B /etc/hosts.slip
-file is as follows:
-.IP -
-blank lines and lines with a leading # are ignored.
-.IP -
-all other lines should have the form:
-.sp
-.br
-\fIname mode local-address remote-address netmask\fP
-.br
-.sp
-The
-.I name
-is usually the login name of a remote host that wishes to connect by
-dialup slip.  More generally it is any key you wish for the address
-and mask parameters specified on that line.  The
-.I mode
-is currently unused but must be specified.  Use
-.BR normal .
-The remaining parameters have been discussed.
+also disappear at the same time.  If there is other processing a site
+would like done on hangup, the file
+.B /etc/slip.logout
+or
+.BI /etc/slip.logout. loginname
+is executed if it exists.  It is given the same arguments as the login script.
+.SS Format of /etc/slip.hosts
+Comments (lines starting with a `#') and blank lines are ignored.
+Other lines must start with a
+.I loginname
+but the remaining arguments can be whatever is appropriate for the
+.B slip.login
+file that will be executed for that name.
+Arguments are separated by white space and follow normal
+.BR sh (1)
+quoting conventions (however,
+.I loginname
+cannot be quoted).
+Usually, lines have the form
+.RS
+.I
+loginname local-address remote-address netmask opt-args
+.RE
+where
+.I local-address
+and
+.I remote-address
+are the IP host names or addresses of the local and remote ends of the
+slip line and
+.I netmask
+is the appropriate IP netmask.  These arguments are passed
+directly to
+.BR ifconfig (8).
+.I Opt-args
+are optional arguments used to configure the line.
+.SH EXAMPLE
+The normal use of
+.B sliplogin
+is to create a
+.B /etc/passwd
+entry for each legal, remote slip site with
+.B sliplogin
+as the shell for that entry.  E.g.,
+.RS
+Sfoo:ikhuy6:2010:1:slip line to foo:/tmp:/etc/sliplogin
+.RE
+(Our convention is to name the account used by remote host
+.I hostname
+as
+.IR Shostname .)
+Then an entry is added to
+.B slip.hosts
+that looks like:
+.RS
+Sfoo   `hostname`      foo     netmask
+.RE
+where
+.I `hostname`
+will be evaluated by
+.B sh
+to the local host name and
+.I netmask
+is the local host IP netmask.
+.PP
+Note that
+.B sliplogin
+must be setuid to root and, while not a security hole, moral defectives
+can use it to place terminal lines in an unusable state and/or deny
+access to legitimate users of a remote slip line.  To prevent this,
+a site can create a group, say
+.IR slip ,
+that only the slip login accounts are put in then make sure that
+.B /etc/sliplogin
+is in group
+.I slip
+and mode 4550 (setuid root, only group
+.I slip
+can execute binary).
 .SH "DIAGNOSTICS"
 .B sliplogin
 logs various information to the system log daemon,
 .SH "DIAGNOSTICS"
 .B sliplogin
 logs various information to the system log daemon,
@@ -105,76 +154,22 @@ A
 .B ioctl
 to set the line parameters failed.
 .TP
 .B ioctl
 to set the line parameters failed.
 .TP
-.BI "ioctl (I_PUSH): " reason
-A
-.SB I_PUSH
-.B ioctl
-to push the
-.B slip
-streams module onto the line failed.
-.TP
-.BI "ioctl (SLIOGUNIT): " reason
-A
-.SB SLIOGUNIT
-.B ioctl
-to get the interface unit number failed.
-.TP
-.BI "ioctl (SIOCSIFNETMASK): " reason
-A
-.SB SIOCSIFNETMASK
-.B ioctl
-to set the network mask for the SLIP interface failed.
-.TP
-.BI "ioctl (SIOCSIFDSTADDR): " reason
-A
-.SB SIOCSIFDSTADDR
-.B ioctl
-to set the destination address for the SLIP interface failed.
-.TP
-.BI "ioctl (SIOCSIFADDR): " reason
-A
-.SB SIOCSIFADDR
-.B ioctl
-to set the source address for the SLIP interface failed.
-.TP
-.BI "UID (" uid ") is unknown"
-An attempt was made to run
-.B sliplogin
-with an effective user
-.SM ID
-not in the password file.
-.TP
-.BI "/etc/hosts.slip: " reason
+.BI "/etc/slip.hosts: " reason
 The
 The
-.B /etc/hosts.slip
+.B /etc/slip.hosts
 file could not be opened.
 .TP
 file could not be opened.
 .TP
-.BI "SLIP access denied for " user
-Access to SLIP logins was denied for the user
-.IR user .
-.TP
-.IB addr ": bad value"
-The address specification
-.I addr
-could not be converted to an Internet address.
+.BI "access denied for " user
+No entry for
+.I user
+was found in
+.BR /etc/slip.hosts .
 .SS Notice Severity
 .TP
 .SS Notice Severity
 .TP
-.BI "attaching slip" unit ": local " local " remote " remote " mask" mask
+.BI "attaching slip unit " unit " for " loginname
 SLIP unit
 .I unit
 SLIP unit
 .I unit
-was successfully attached, with a source address of
-.IR local ,
-a destination address of
-.IR remote ,
-and a netmask of
-.IR mask .
-.SH EXAMPLES
-.ta 8
-       sliplogin ip_utai < /dev/ttyb &
-.sp
-       sliplogin us-sl them-sl 255.255.255.0 < /dev/ttyb &
-.sp
-       sliplogin 192.12.174.1 192.12.174.2 < /dev/ttyb &
+was successfully attached.
 .SH "SEE ALSO"
 .SH "SEE ALSO"
-.BR slip (4M),
+.BR slattach (8),
 .BR syslogd (8)
 .BR syslogd (8)
index 0aeeb3a..af8f525 100644 (file)
@@ -12,26 +12,23 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)sliplogin.c        5.1 (Berkeley) %G%";
+static char sccsid[] = "@(#)sliplogin.c        5.2 (Berkeley) %G%";
 #endif /* not lint */
 
 #endif /* not lint */
 
-/* from static char *sccsid = "@(#)sliplogin.c 1.3     MS/ACF  89/04/18"; */
-
 /*
  * sliplogin.c
  * [MUST BE RUN SUID, SLOPEN DOES A SUSER()!]
  *
  * This program initializes its own tty port to be an async TCP/IP interface.
 /*
  * sliplogin.c
  * [MUST BE RUN SUID, SLOPEN DOES A SUSER()!]
  *
  * This program initializes its own tty port to be an async TCP/IP interface.
- * It merely sets up the SLIP module all by its lonesome on the STREAMS stack,
- * initializes the network interface, and pauses forever waiting for hangup.
+ * It sets the line discipline to slip, invokes a shell script to initialize
+ * the network interface, then pauses forever waiting for hangup.
  *
  * It is a remote descendant of several similar programs with incestuous ties:
  * - Kirk Smith's slipconf, modified by Richard Johnsson @ DEC WRL.
  * - slattach, probably by Rick Adams but touched by countless hordes.
  * - the original sliplogin for 4.2bsd, Doug Kingston the mover behind it.
  *
  * It is a remote descendant of several similar programs with incestuous ties:
  * - Kirk Smith's slipconf, modified by Richard Johnsson @ DEC WRL.
  * - slattach, probably by Rick Adams but touched by countless hordes.
  * - the original sliplogin for 4.2bsd, Doug Kingston the mover behind it.
- * - a simple slattach-like program used to test the STREAMS SLIP code.
  *
  *
- * There are three basic forms of usage:
+ * There are two forms of usage:
  *
  * "sliplogin"
  * Invoked simply as "sliplogin" and a realuid != 0, the program looks up
  *
  * "sliplogin"
  * Invoked simply as "sliplogin" and a realuid != 0, the program looks up
@@ -42,117 +39,190 @@ static char sccsid[] = "@(#)sliplogin.c   5.1 (Berkeley) %G%";
  * "sliplogin IPhost1 </dev/ttyb"
  * 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.
  * "sliplogin IPhost1 </dev/ttyb"
  * 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.
- *
- * "sliplogin 192.100.1.1 192.100.1.2 255.255.255.0 < /dev/ttyb"
- * Finally, if invoked with a remote addr, local addr, and optionally
- * a net mask, the line on fd0 is setup as specified if the user is root.
- *
- * Doug Kingston 8810??                - logging + first pass at adding I_STR ioctl's
- * Rayan Zachariassen 881011   - version for SunOS STREAMS SLIP
  */
 
 #include <sys/types.h>
  */
 
 #include <sys/types.h>
+#include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
-#include <sys/termios.h>
 #include <sys/ioctl.h>
 #include <sys/file.h>
 #include <sys/syslog.h>
 #include <sys/ioctl.h>
 #include <sys/file.h>
 #include <sys/syslog.h>
-
-#include <netinet/in.h>
-#include <net/if.h>
-#include <net/if_slvar.h>      /* XXX */
-
 #include <stdio.h>
 #include <errno.h>
 #include <ctype.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <errno.h>
 #include <ctype.h>
 #include <netdb.h>
-
 #include <signal.h>
 #include <signal.h>
-#include <strings.h>
-#include <pwd.h>
+#include <string.h>
+#if defined(BSD4_4)
+#define TERMIOS
+#endif
+#ifdef TERMIOS
+#include <sys/termios.h>
 #include <ttyent.h>
 #include <ttyent.h>
+#endif
+#include <netinet/in.h>
+#include <net/if.h>
+#include <net/if_slvar.h>
 
 
-#define        SLIPIFNAME      "sl"
-
-#define ADDR   1
-#define MASK   2
+#ifndef ACCESSFILE
+#define ACCESSFILE "/etc/slip.hosts"
+#endif
+#ifndef LOGINFILE
+#define LOGINFILE "/etc/slip.login"
+#define LOGOUTFILE "/etc/slip.logout"
+#endif
 
 
-#define        DCD_CHECK_INTERVAL 0    /* if > 0, time between automatic DCD checks */
-#define        DCD_SETTLING_TIME 1     /* time between DCD change and status check */
 
 
-int gotalarm = 0;
-int timeleft = DCD_CHECK_INTERVAL;
+int    unit;
+int     slip_mode;
+int    speed;
+char   loginargs[BUFSIZ];
+char   loginfile[BUFSIZ];
+char   logoutfile[BUFSIZ];
+char   loginname[BUFSIZ];
 
 
-#if    defined(SIGDCD) && SIGDCD > 0
-void
-dcd_handler()
-{
-#if    DCD_SETTLING_TIME > 0
-       timeleft = alarm(DCD_SETTLING_TIME);
-#else
-       gotalarm = 1;
-#endif /* DCD_SETTLING_TIME */
-}
-#endif
+struct slip_modes {
+       char    *sm_name;
+       int     sm_value;
+}       modes[] = {
+       "normal",       0,              
+       "compress",     SC_COMPRESS,   
+       "noicmp",       SC_NOICMP,
+       "autocomp",     SC_AUTOCOMP
+};
 
 
-#if DCD_CHECK_INTERVAL > 0
 void
 void
-alarm_handler()
+findid(name)
+       char *name;
 {
 {
-#ifdef SIGDCD
-       if (timeleft > DCD_SETTLING_TIME)
-               (void) alarm(timeleft-DCD_SETTLING_TIME);
-       else
-#endif /* SIGDCD */
-               (void) alarm(DCD_CHECK_INTERVAL);
-       gotalarm = 1;
-       timeleft = 0;
-}
-
-/* Use TIOCMGET to test if DCD is low on the port of the passed descriptor */
+       FILE *fp;
+       static char slopt[5][16];
+       static char laddr[16];
+       static char raddr[16];
+       static char mask[16];
+       char user[16];
+       int i, j, n;
 
 
-int
-lowdcd(fd)
-       int fd;
-{
-       int mbits;
+       (void)strcpy(loginname, name);
+       if ((fp = fopen(ACCESSFILE, "r")) == NULL) {
+               perror(ACCESSFILE);
+               syslog(LOG_ERR, "%s: %m\n", ACCESSFILE);
+               exit(3);
+       }
+       while (fgets(loginargs, sizeof(loginargs) - 1, fp)) {
 
 
-       if (ioctl(fd, TIOCMGET, (caddr_t)&mbits) < 0)
-               return 1;       /* port is dead, we die */
-       return !(mbits & TIOCM_CAR);
-}
-#endif /* DCD_CHECK_INTERVAL > 0 */
+               if (ferror(fp))
+                       break;
+               n = sscanf(loginargs, "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
+                        user, laddr, raddr, mask, slopt[0], slopt[1], 
+                       slopt[2], slopt[3], slopt[4]);
+               if (user[0] == '#' || isspace(user[0]))
+                       continue;
+               if (strcmp(user, name) != 0)
+                       continue;
 
 
-char   *Accessfile = "/etc/hosts.slip";
+               slip_mode = 0;
+               for (i = 0; i < n - 4; i++) {
+                       for (j = 0; j < sizeof(modes)/sizeof(struct slip_modes);
+                               j++) {
+                               if (strcmp(modes[j].sm_name, slopt[i]) == 0) {
+                                       slip_mode |= modes[j].sm_value;
+                                       break;
+                               }
+                       }
+               }
 
 
-extern char *malloc(), *ttyname();
-extern struct passwd *getpwuid();
+               /*
+                * we've found the guy we're looking for -- see if
+                * there's a login file we can use.  First check for
+                * one specific to this host.  If none found, try for
+                * a generic one.
+                */
+               (void)sprintf(loginfile, "%s.%s", LOGINFILE, name);
+               if (access(loginfile, R_OK|X_OK)) {
+                       (void)strcpy(loginfile, LOGINFILE);
+                       (void)strcpy(logoutfile, LOGOUTFILE);
+                       if (access(loginfile, R_OK|X_OK)) {
+                               fputs("access denied - no login file\n",
+                                     stderr);
+                               syslog(LOG_ERR,
+                                      "access denied for %s - no %s\n",
+                                      name, LOGINFILE);
+                               exit(5);
+                       }
+               } else
+                       (void)sprintf(logoutfile, "%s.%s", LOGOUTFILE, name);
 
 
-char   *dstaddr, *localaddr, *netmask;
-int    slip_mode, unit;
+               (void) fclose(fp);
+               return;
+       }
+       (void)fprintf(stderr, "SLIP access denied for %s\n", name);
+       syslog(LOG_ERR, "SLIP access denied for %s\n", name);
+       exit(4);
+       /* NOTREACHED */
+}
 
 
-struct slip_modes {
-       char    *sm_name;
-       int     sm_value;
-}       modes[] = {
-       "normal",       0,              /* slip "standard" ala Rick Adams */
-       "compress",     SC_COMPRESS,    /* Van Jacobsen's tcp header comp. */
-       "noicmp",       SC_NOICMP,      /* Sam's(?) ICMP suppression */
-} ;
+char *
+sigstr(s)
+       int s;
+{
+       static char buf[32];
+
+       switch (s) {
+       case SIGHUP:    return("HUP");
+       case SIGINT:    return("INT");
+       case SIGQUIT:   return("QUIT");
+       case SIGILL:    return("ILL");
+       case SIGTRAP:   return("TRAP");
+       case SIGIOT:    return("IOT");
+       case SIGEMT:    return("EMT");
+       case SIGFPE:    return("FPE");
+       case SIGKILL:   return("KILL");
+       case SIGBUS:    return("BUS");
+       case SIGSEGV:   return("SEGV");
+       case SIGSYS:    return("SYS");
+       case SIGPIPE:   return("PIPE");
+       case SIGALRM:   return("ALRM");
+       case SIGTERM:   return("TERM");
+       case SIGURG:    return("URG");
+       case SIGSTOP:   return("STOP");
+       case SIGTSTP:   return("TSTP");
+       case SIGCONT:   return("CONT");
+       case SIGCHLD:   return("CHLD");
+       case SIGTTIN:   return("TTIN");
+       case SIGTTOU:   return("TTOU");
+       case SIGIO:     return("IO");
+       case SIGXCPU:   return("XCPU");
+       case SIGXFSZ:   return("XFSZ");
+       case SIGVTALRM: return("VTALRM");
+       case SIGPROF:   return("PROF");
+       case SIGWINCH:  return("WINCH");
+#ifdef SIGLOST
+       case SIGLOST:   return("LOST");
+#endif
+       case SIGUSR1:   return("USR1");
+       case SIGUSR2:   return("USR2");
+       }
+       (void)sprintf(buf, "sig %d", s);
+       return(buf);
+}
 
 
-void
+int
 hup_handler(s)
        int s;
 {
 hup_handler(s)
        int s;
 {
+       if (access(logoutfile, R_OK|X_OK) == 0) {
+               char logincmd[2*BUFSIZ+32];
 
 
-       syslog(LOG_INFO,
-           "%s%d: connection closed: process aborted, sig %d, remote %s\n",
-           SLIPIFNAME, unit, s, dstaddr);
-       if (close(0) < 0)
-               syslog(LOG_ERR, "(hup) close: %m");
-       else
-               syslog(LOG_INFO, "(hup) close completed");
-       exit(1) ;
+               (void)sprintf(logincmd, "%s %d %d %s", logoutfile, unit, speed,
+                             loginargs);
+               (void)system(logincmd);
+       }
+       (void)close(0);
+       syslog(LOG_INFO, "closed %s slip unit %d (%s)\n", loginname, unit,
+              sigstr(s));
+       exit(1);
+       /* NOTREACHED */
 }
 
 main(argc, argv)
 }
 
 main(argc, argv)
@@ -160,44 +230,40 @@ main(argc, argv)
        char *argv[];
 {
        int     fd, s, ldisc, odisc;
        char *argv[];
 {
        int     fd, s, ldisc, odisc;
+       char *name;
+#ifdef TERMIOS
        struct  termios tios, otios;
        struct  termios tios, otios;
-       struct  ifreq ifr;
+#else
+       struct  sgttyb tty, otty;
+#endif
+       char logincmd[2*BUFSIZ+32];
+       extern uid_t getuid();
 
 
+       if ((name = strrchr(argv[0], '/')) == NULL)
+               name = argv[0];
        s = getdtablesize();
        for (fd = 3 ; fd < s ; fd++)
        s = getdtablesize();
        for (fd = 3 ; fd < s ; fd++)
-               close(fd);
-       openlog("sliplogin", LOG_PID, LOG_DAEMON);
-       if (getuid() == 0) {
-               if (argc <= 1) {
-                       fprintf(stderr, "Usage: %s loginname\n", argv[0]);
-                       fprintf(stderr, "   or: %s dstaddr localaddr [mask]\n",
-                                       argv[0]);
+               (void) close(fd);
+       openlog(name, LOG_PID, LOG_DAEMON);
+       if (argc > 1) {
+               if (argc > 2) {
+                       (void)fprintf(stderr, "Usage: %s loginname\n", argv[0]);
                        exit(1);
                        exit(1);
-               } else if (argc == 2) {
-                       findid(argv[1]);
-                       fprintf(stderr, "local %s remote %s mask %s\n",
-                               localaddr, dstaddr, netmask);
-               } if (argc > 2) {
-                       if (argc < 3 || argc > 4) {
-                               fprintf(stderr,
-                                       "Usage: %s dstaddr localaddr [mask]\n",
-                                       argv[0]);
-                               exit(1);
-                       }
-                       dstaddr = argv[1];
-                       localaddr = argv[2];
-                       if (argc == 4)
-                               netmask = argv[3];
-                       else
-                               netmask = "default";
                }
                }
+               findid(argv[1]);
+
                /*
                 * Disassociate from current controlling terminal, if any,
                 * and ensure that the slip line is our controlling terminal.
                 */
                /*
                 * Disassociate from current controlling terminal, if any,
                 * and ensure that the slip line is our controlling terminal.
                 */
-#if !defined(BSD) || BSD < 198810
+#ifdef TERMIOS
+               (void) setsid();
+               (void) ioctl(0, TIOCSCTTY, (caddr_t)0);
+#else
                if ((fd = open("/dev/tty", O_RDONLY, 0)) >= 0) {
                if ((fd = open("/dev/tty", O_RDONLY, 0)) >= 0) {
-                       (void) ioctl(fd, TIOCNOTTY, 0);
+                       extern char *ttyname();
+
+                       (void) ioctl(fd, TIOCNOTTY, (caddr_t)0);
                        (void) close(fd);
                        /* open slip tty again to acquire as controlling tty? */
                        fd = open(ttyname(0), O_RDWR, 0);
                        (void) close(fd);
                        /* open slip tty again to acquire as controlling tty? */
                        fd = open(ttyname(0), O_RDWR, 0);
@@ -205,13 +271,20 @@ main(argc, argv)
                                (void) close(fd);
                }
                (void) setpgrp(0, getpid());
                                (void) close(fd);
                }
                (void) setpgrp(0, getpid());
-#else
-               (void) setsid();
-               (void) ioctl(0, TIOCSCTTY, 0); /* not sure this will work */
 #endif
 #endif
-       } else
-               findid((char *)0);
-       fchmod(0, 0600);
+       } else {
+               extern char *getenv();
+
+               if ((name = getenv("USER")) == NULL) {
+                       (void) fprintf(stderr, "access denied - no username\n");
+                       syslog(LOG_ERR, "access denied - no username\n");
+                       exit(1);
+               }
+               findid(name);
+       }
+       (void) fchmod(0, 0600);
+       (void) fprintf(stderr, "starting slip login for %s\n", loginname);
+#ifdef TERMIOS
        /* set up the line parameters */
        if (ioctl(0, TIOCGETA, (caddr_t)&tios) < 0) {
                syslog(LOG_ERR, "ioctl (TIOCGETA): %m");
        /* set up the line parameters */
        if (ioctl(0, TIOCGETA, (caddr_t)&tios) < 0) {
                syslog(LOG_ERR, "ioctl (TIOCGETA): %m");
@@ -225,6 +298,20 @@ main(argc, argv)
                syslog(LOG_ERR, "ioctl (TIOCSETA) (1): %m");
                exit(1);
        }
                syslog(LOG_ERR, "ioctl (TIOCSETA) (1): %m");
                exit(1);
        }
+#else
+       /* set up the line parameters */
+       if (ioctl(0, TIOCGETP, (caddr_t)&tty) < 0) {
+               syslog(LOG_ERR, "ioctl (TIOCGETP): %m");
+               exit(1);
+       }
+       otty = tty;
+       speed = tty.sg_ispeed;
+       tty.sg_flags = RAW | ANYP;
+       if (ioctl(0, TIOCSETP, (caddr_t)&tty) < 0) {
+               syslog(LOG_ERR, "ioctl (TIOCSETP): %m");
+               exit(1);
+       }
+#endif
        /* find out what ldisc we started with */
        if (ioctl(0, TIOCGETD, (caddr_t)&odisc) < 0) {
                syslog(LOG_ERR, "ioctl(TIOCGETD) (1): %m");
        /* find out what ldisc we started with */
        if (ioctl(0, TIOCGETD, (caddr_t)&odisc) < 0) {
                syslog(LOG_ERR, "ioctl(TIOCGETD) (1): %m");
@@ -240,194 +327,40 @@ main(argc, argv)
                syslog(LOG_ERR, "ioctl (TIOCGETD) (2): %m");
                exit(1);
        }
                syslog(LOG_ERR, "ioctl (TIOCGETD) (2): %m");
                exit(1);
        }
-       syslog(LOG_INFO, "attaching %s%d: local %s remote %s mask %s\n",
-               SLIPIFNAME, unit, localaddr, dstaddr, netmask);
-#ifdef notdef
-       /* set the local and remote interface addresses */
-       s = socket(AF_INET, SOCK_DGRAM, 0);
-       if (getuid() != 0 || argc == 4) {
-               (void) sprintf(ifr.ifr_name, "%s%d", SLIPIFNAME, unit);
-               in_getaddr(netmask, &ifr.ifr_addr, MASK);
-               if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) {
-                       syslog(LOG_ERR, "ioctl (SIOCSIFNETMASK): %m");
+       (void) signal(SIGHUP, hup_handler);
+       (void) signal(SIGTERM, hup_handler);
+
+       syslog(LOG_INFO, "attaching slip unit %d for %s\n", unit, loginname);
+       (void)sprintf(logincmd, "%s %d %d %s", loginfile, unit, speed,
+                     loginargs);
+       /*
+        * 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) {
+               if (fd < 0) {
+                       syslog(LOG_ERR, "open /dev/null: %m");
                        exit(1);
                }
                        exit(1);
                }
+               (void)dup2(fd, 1);
+               (void)close(fd);
        }
        }
-       (void) sprintf(ifr.ifr_name, "%s%d", SLIPIFNAME, unit);
-       in_getaddr(dstaddr, &ifr.ifr_addr, ADDR);
-       if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
-               syslog(LOG_ERR, "ioctl (SIOCSIFDSTADDR): %m");
-               exit(1);
-       }
-       (void) sprintf(ifr.ifr_name, "%s%d", SLIPIFNAME, unit);
-       in_getaddr(localaddr, &ifr.ifr_addr, ADDR);
-       /* this has the side-effect of marking the interface up */
-       if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
-               syslog(LOG_ERR, "ioctl (SIOCSIFADDR): %m");
-               exit(1);
+       (void)dup2(1,2);
+       if (s = system(logincmd)) {
+               syslog(LOG_ERR, "%s login failed: exit status %d from %s",
+                      loginname, s, loginfile);
+               (void) ioctl(0, TIOCSETD, (caddr_t)&odisc);
+               exit(6);
        }
        }
-#else
-       /* XXX -- give up for now and just invoke ifconfig XXX */
-       { char cmd[256];
-         sprintf(cmd, "/sbin/ifconfig %s%d inet %s %s netmask %s",
-             SLIPIFNAME, unit, localaddr, dstaddr, netmask);
-         system(cmd);
-       }
-#endif
        if (ioctl(0, SLIOCSFLAGS, (caddr_t)&slip_mode) < 0) {
                syslog(LOG_ERR, "ioctl (SLIOCSFLAGS): %m");
                exit(1);
        }
 
        if (ioctl(0, SLIOCSFLAGS, (caddr_t)&slip_mode) < 0) {
                syslog(LOG_ERR, "ioctl (SLIOCSFLAGS): %m");
                exit(1);
        }
 
-       /* set up signal handlers */
-#if    defined(SIGDCD) && SIGDCD > 0
-       (void) signal(SIGDCD, dcd_handler);
-#endif
-       (void) sigblock(sigmask(SIGALRM));
-       (void) signal(SIGHUP, hup_handler);
-       (void) signal(SIGTERM, hup_handler);
-
-#if DCD_CHECK_INTERVAL > 0
-       /* timeleft = 60 * 60 * 24 * 365 ; (void) alarm(timeleft); */
-       (void) signal(SIGALRM, alarm_handler);
-       (void) alarm(DCD_CHECK_INTERVAL);
-#endif
-
        /* twiddle thumbs until we get a signal */
        /* twiddle thumbs until we get a signal */
-       while (1) {
+       while (1)
                sigpause(0);
                sigpause(0);
-#if DCD_CHECK_INTERVAL > 0
-               (void) sigblock(sigmask(SIGALRM));
-               if (gotalarm && lowdcd(0))
-                       break;
-               gotalarm = 0;
-#endif /* DCD_CHECK_INTERVAL > 0 */
-       }
-
-#ifdef notdef
-       if (lowdcd(0))
-               syslog(LOG_NOTICE,
-                       "connection closed: loss of carrier %s%d: remote %s\n",
-                       SLIPIFNAME, unit, dstaddr);
-#endif
-
-       if (ioctl(0, TIOCSETD, (caddr_t)&odisc) < 0) {
-               syslog(LOG_ERR, "ioctl(TIOCSETD) (2): %m");
-               exit(1);
-       }
-       if (ioctl(0, TIOCSETA, (caddr_t)&otios) < 0) {
-               syslog(LOG_ERR, "ioctl (TIOCSETA) (2): %m");
-               exit(1);
-       }
-       if (close(0) < 0) {
-               syslog(LOG_ERR, "close: %m");
-               exit(1);
-       }
-       exit(0);
-}
-
-findid(name)
-       char *name;
-{
-       char buf[BUFSIZ];
-       static char mode[16];
-       static char laddr[16];
-       static char raddr[16];
-       static char mask[16];
-       char user[16];
-       FILE *fp;
-       struct passwd *pw;
-       int n;
-
-       if (name == NULL && (pw = getpwuid(getuid())) == NULL) {
-               fprintf(stderr, "Your UID (%d) is unknown\n", getuid());
-               syslog(LOG_ERR, "UID (%d) is unknown\n", getuid());
-               exit(1);
-       } else if (name == NULL)
-               name = pw->pw_name;
-       if ((fp = fopen(Accessfile, "r")) == NULL) {
-               perror(Accessfile);
-               syslog(LOG_ERR, "%s: %m\n", Accessfile);
-               exit(3);
-       }
-       while (fgets(buf, sizeof(buf) - 1, fp)) {
-               if (ferror(fp))
-                       break;
-               n = sscanf(buf, "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
-                       user, mode, laddr, raddr, mask);
-               if (user[0] == '#' || n != 5)
-                       continue;
-               if (strcmp(user, name) == 0) {
-                       char *p,*q; int val, i, domore;
 
 
-                       p = q = mode;   val = 0;
-               loop:
-                       while (isalnum(*p)) p++;
-                       if(ispunct(*p) || *p == '\0') {
-                               if(ispunct(*p)) domore = 1; else domore = 0;
-                               *p++ = '\0' ; 
-                               for (i = 0; i <
-                                       sizeof(modes)/sizeof(struct slip_modes)
-                                        ; i++) {
-                                       if (strcmp(modes[i].sm_name, q) == 0) {
-                                               val |= modes[i].sm_value ;
-                                               break;
-                                       } ;
-}
-                               q = p;
-                               if(domore)goto loop;
-                       }
-
-                       slip_mode = val ;
-                       localaddr = laddr;
-                       dstaddr = raddr;
-                       netmask = mask;
-                       fclose(fp);
-                       return 0;
-               }
-               if (feof(fp))
-                       break;
-       }
-       fputs("SLIP access denied\n", stderr);
-       syslog(LOG_ERR, "SLIP access denied for %s\n", name);
-       exit(4);
-}
-
-in_getaddr(s, saddr, which)
-       char *s;
-       struct sockaddr *saddr;
-       int which;
-{
-       register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
-       struct hostent *hp;
-       struct netent *np;
-       int val;
-       extern struct in_addr inet_makeaddr();
-       bzero((caddr_t)saddr, sizeof *saddr);
-       if (which == ADDR) {
-               sin->sin_len = sizeof (*sin);
-               sin->sin_family = AF_INET;
-       } else
-               sin->sin_len = 8;
-       val = inet_addr(s);
-       if (val != -1) {
-               sin->sin_addr.s_addr = val;
-               return;
-       }
-       hp = gethostbyname(s);
-       if (hp) {
-               sin->sin_family = hp->h_addrtype;
-               bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
-               return;
-       }
-       np = getnetbyname(s);
-       if (np) {
-               sin->sin_family = np->n_addrtype;
-               sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
-               return;
-       }
-       fprintf(stderr, "sliplogin: %s: bad value\n", s);
-       syslog(LOG_ERR, "%s: bad value\n", s);
-       exit(1);
+       /* NOTREACHED */
 }
 }