static char sccsid
[] = "@(#)sliplogin.c 1.4 (Berkeley) %G%";
/* from static char *sccsid = "@(#)sliplogin.c 1.3 MS/ACF 89/04/18"; */
* [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 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:
* 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
* as specified in the file.
* "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 <net/if_slvar.h> /* XXX */
#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 timeleft
= DCD_CHECK_INTERVAL
;
#if defined(SIGDCD) && SIGDCD > 0
#if DCD_SETTLING_TIME > 0
timeleft
= alarm(DCD_SETTLING_TIME
);
#endif /* DCD_SETTLING_TIME */
#if DCD_CHECK_INTERVAL > 0
if (timeleft
> DCD_SETTLING_TIME
)
(void) alarm(timeleft
-DCD_SETTLING_TIME
);
(void) alarm(DCD_CHECK_INTERVAL
);
/* Use TIOCMGET to test if DCD is low on the port of the passed descriptor */
if (ioctl(fd
, TIOCMGET
, (caddr_t
)&mbits
) < 0)
return 1; /* port is dead, we die */
return !(mbits
& TIOCM_CAR
);
#endif /* DCD_CHECK_INTERVAL > 0 */
char *Accessfile
= "/etc/hosts.slip";
extern char *malloc(), *ttyname();
extern struct passwd
*getpwuid();
char *dstaddr
, *localaddr
, *netmask
;
"normal", 0, /* slip "standard" ala Rick Adams */
"compress", SC_COMPRESS
, /* Van Jacobsen's tcp header comp. */
"noicmp", SC_NOICMP
, /* Sam's(?) ICMP suppression */
"%s%d: connection closed: process aborted, sig %d, remote %s\n",
SLIPIFNAME
, unit
, s
, dstaddr
);
syslog(LOG_ERR
, "(hup) close: %m");
syslog(LOG_INFO
, "(hup) close completed");
struct termios tios
, otios
;
for (fd
= 3 ; fd
< s
; fd
++)
openlog("sliplogin", LOG_PID
, LOG_DAEMON
);
fprintf(stderr
, "Usage: %s loginname\n", argv
[0]);
fprintf(stderr
, " or: %s dstaddr localaddr [mask]\n",
fprintf(stderr
, "local %s remote %s mask %s\n",
localaddr
, dstaddr
, netmask
);
if (argc
< 3 || argc
> 4) {
"Usage: %s dstaddr localaddr [mask]\n",
* Disassociate from current controlling terminal, if any,
* and ensure that the slip line is our controlling terminal.
#if !defined(BSD) || BSD < 198810
if ((fd
= open("/dev/tty", O_RDONLY
, 0)) >= 0) {
(void) ioctl(fd
, TIOCNOTTY
, 0);
/* open slip tty again to acquire as controlling tty? */
fd
= open(ttyname(0), O_RDWR
, 0);
(void) setpgrp(0, getpid());
(void) ioctl(0, TIOCSCTTY
, 0); /* not sure this will work */
/* set up the line parameters */
if (ioctl(0, TIOCGETA
, (caddr_t
)&tios
) < 0) {
syslog(LOG_ERR
, "ioctl (TIOCGETA): %m");
tios
.c_cflag
= CS8
|CREAD
|HUPCL
;
tios
.c_oflag
= tios
.c_lflag
= 0;
if (ioctl(0, TIOCSETA
, (caddr_t
)&tios
) < 0) {
syslog(LOG_ERR
, "ioctl (TIOCSETA) (1): %m");
/* find out what ldisc we started with */
if (ioctl(0, TIOCGETD
, (caddr_t
)&odisc
) < 0) {
syslog(LOG_ERR
, "ioctl(TIOCGETD) (1): %m");
if (ioctl(0, TIOCSETD
, (caddr_t
)&ldisc
) < 0) {
syslog(LOG_ERR
, "ioctl(TIOCSETD): %m");
/* find out what unit number we were assigned */
if (ioctl(0, TIOCGETD
, (caddr_t
)&unit
) < 0) {
syslog(LOG_ERR
, "ioctl (TIOCGETD) (2): %m");
syslog(LOG_INFO
, "attaching %s%d: local %s remote %s mask %s\n",
SLIPIFNAME
, unit
, localaddr
, dstaddr
, netmask
);
/* 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) 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");
(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");
/* XXX -- give up for now and just invoke ifconfig XXX */
sprintf(cmd
, "/sbin/ifconfig %s%d inet %s %s netmask %s",
SLIPIFNAME
, unit
, localaddr
, dstaddr
, netmask
);
if (ioctl(0, SLIOCSFLAGS
, (caddr_t
)&slip_mode
) < 0) {
syslog(LOG_ERR
, "ioctl (SLIOCSFLAGS): %m");
/* set up signal handlers */
#if defined(SIGDCD) && SIGDCD > 0
(void) signal(SIGDCD
, dcd_handler
);
(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
);
/* twiddle thumbs until we get a signal */
#if DCD_CHECK_INTERVAL > 0
(void) sigblock(sigmask(SIGALRM
));
if (gotalarm
&& lowdcd(0))
#endif /* DCD_CHECK_INTERVAL > 0 */
"connection closed: loss of carrier %s%d: remote %s\n",
SLIPIFNAME
, unit
, dstaddr
);
if (ioctl(0, TIOCSETD
, (caddr_t
)&odisc
) < 0) {
syslog(LOG_ERR
, "ioctl(TIOCSETD) (2): %m");
if (ioctl(0, TIOCSETA
, (caddr_t
)&otios
) < 0) {
syslog(LOG_ERR
, "ioctl (TIOCSETA) (2): %m");
syslog(LOG_ERR
, "close: %m");
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());
if ((fp
= fopen(Accessfile
, "r")) == NULL
) {
syslog(LOG_ERR
, "%s: %m\n", Accessfile
);
while (fgets(buf
, sizeof(buf
) - 1, fp
)) {
n
= sscanf(buf
, "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
user
, mode
, laddr
, raddr
, mask
);
if (user
[0] == '#' || n
!= 5)
if (strcmp(user
, name
) == 0) {
char *p
,*q
; int val
, i
, domore
;
if(ispunct(*p
) || *p
== '\0') {
if(ispunct(*p
)) domore
= 1; else domore
= 0;
sizeof(modes
)/sizeof(struct slip_modes
)
if (strcmp(modes
[i
].sm_name
, q
) == 0) {
val
|= modes
[i
].sm_value
;
fputs("SLIP access denied\n", stderr
);
syslog(LOG_ERR
, "SLIP access denied for %s\n", name
);
in_getaddr(s
, saddr
, which
)
register struct sockaddr_in
*sin
= (struct sockaddr_in
*)saddr
;
extern struct in_addr
inet_makeaddr();
bzero((caddr_t
)saddr
, sizeof *saddr
);
sin
->sin_len
= sizeof (*sin
);
sin
->sin_family
= AF_INET
;
sin
->sin_addr
.s_addr
= val
;
sin
->sin_family
= hp
->h_addrtype
;
bcopy(hp
->h_addr
, (char *)&sin
->sin_addr
, hp
->h_length
);
sin
->sin_family
= np
->n_addrtype
;
sin
->sin_addr
= inet_makeaddr(np
->n_net
, INADDR_ANY
);
fprintf(stderr
, "sliplogin: %s: bad value\n", s
);
syslog(LOG_ERR
, "%s: bad value\n", s
);