1 /* $NetBSD: sliplogin.c,v 1.21 2004/10/30 15:44:04 dsl Exp $ */
4 * Copyright (c) 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
34 __COPYRIGHT("@(#) Copyright (c) 1990, 1993\
35 The Regents of the University of California. All rights reserved.");
40 static char sccsid
[] = "@(#)sliplogin.c 8.2 (Berkeley) 2/1/94";
42 __RCSID("$NetBSD: sliplogin.c,v 1.21 2004/10/30 15:44:04 dsl Exp $");
48 * [MUST BE RUN SUID, SLOPEN DOES A SUSER()!]
50 * This program initializes its own tty port to be an async TCP/IP interface.
51 * It sets the line discipline to slip, invokes a shell script to initialize
52 * the network interface, then pauses forever waiting for hangup.
54 * It is a remote descendant of several similar programs with incestuous ties:
55 * - Kirk Smith's slipconf, modified by Richard Johnsson @ DEC WRL.
56 * - slattach, probably by Rick Adams but touched by countless hordes.
57 * - the original sliplogin for 4.2bsd, Doug Kingston the mover behind it.
59 * There are two forms of usage:
62 * Invoked simply as "sliplogin", the program looks up the username
63 * in the file /etc/slip.hosts.
64 * If an entry is found, the line on fd0 is configured for SLIP operation
65 * as specified in the file.
67 * "sliplogin IPhostlogin </dev/ttyb"
68 * Invoked by root with a username, the name is looked up in the
69 * /etc/slip.hosts file and if found fd0 is configured as in case 1.
72 #include <sys/types.h>
74 #include <sys/param.h>
75 #include <sys/socket.h>
77 #include <sys/syslog.h>
84 #include <sys/ioctl.h>
101 #include "pathnames.h"
106 char loginargs
[BUFSIZ
];
107 char loginfile
[MAXPATHLEN
];
108 char loginname
[BUFSIZ
];
110 void findid
__P((char *));
111 void hup_handler
__P((int));
112 int main
__P((int, char **));
113 const char *sigstr
__P((int));
120 static char slopt
[5][16];
121 static char laddr
[16];
122 static char raddr
[16];
123 static char mask
[16];
127 (void)strlcpy(loginname
, name
, sizeof(loginname
));
128 if ((fp
= fopen(_PATH_ACCESS
, "r")) == NULL
) {
129 syslog(LOG_ERR
, "%s: %m\n", _PATH_ACCESS
);
130 err(1, "%s", _PATH_ACCESS
);
132 while (fgets(loginargs
, sizeof(loginargs
) - 1, fp
)) {
135 n
= sscanf(loginargs
, "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
136 user
, laddr
, raddr
, mask
, slopt
[0], slopt
[1],
137 slopt
[2], slopt
[3], slopt
[4]);
138 if (user
[0] == '#' || isspace((unsigned char)user
[0]))
140 if (strcmp(user
, name
) != 0)
144 * we've found the guy we're looking for -- see if
145 * there's a login file we can use. First check for
146 * one specific to this host. If none found, try for
149 (void)snprintf(loginfile
, sizeof loginfile
, "%s.%s",
151 if (access(loginfile
, R_OK
|X_OK
) != 0) {
152 (void)strlcpy(loginfile
, _PATH_LOGIN
, sizeof(loginfile
));
153 if (access(loginfile
, R_OK
|X_OK
)) {
154 fputs("access denied - no login file\n",
157 "access denied for %s - no %s\n",
166 syslog(LOG_ERR
, "SLIP access denied for %s\n", name
);
167 errx(1, "SLIP access denied for %s", name
);
176 if (s
> 0 && s
< NSIG
)
177 return (sys_signame
[s
]);
181 (void)snprintf(buf
, sizeof buf
, "sig %d", s
);
190 char logoutfile
[MAXPATHLEN
];
192 (void)snprintf(logoutfile
, sizeof logoutfile
, "%s.%s", _PATH_LOGOUT
,
194 if (access(logoutfile
, R_OK
|X_OK
) != 0)
195 (void)strlcpy(logoutfile
, _PATH_LOGOUT
, sizeof(logoutfile
));
196 if (access(logoutfile
, R_OK
|X_OK
) == 0) {
197 char logincmd
[2*MAXPATHLEN
+32];
199 (void)snprintf(logincmd
, sizeof logincmd
, "%s %d %d %s",
200 logoutfile
, unit
, speed
, loginargs
);
201 (void)system(logincmd
);
204 syslog(LOG_INFO
, "closed %s slip unit %d (%s)\n", loginname
, unit
,
215 int fd
, s
, ldisc
, odisc
;
218 struct termios tios
, otios
;
220 struct sgttyb tty
, otty
;
222 char logincmd
[2*BUFSIZ
+32];
224 if (strlen(argv
[0]) > MAXLOGNAME
)
225 errx(1, "login %s too long", argv
[0]);
226 if ((name
= strrchr(argv
[0], '/')) == NULL
)
231 for (fd
= 3 ; fd
< s
; fd
++)
233 openlog(name
, LOG_PID
, LOG_DAEMON
);
239 * Disassociate from current controlling terminal, if any,
240 * and ensure that the slip line is our controlling terminal.
246 syslog(LOG_ERR
, "could not fork: %m");
256 if ((fd
= open("/dev/tty", O_RDONLY
, 0)) >= 0) {
257 extern char *ttyname();
259 (void)ioctl(fd
, TIOCNOTTY
, (caddr_t
)0);
261 /* open slip tty again to acquire as controlling tty? */
262 fd
= open(ttyname(0), O_RDWR
, 0);
266 (void)setpgrp(0, getpid());
269 if ((fd
= open(argv
[2], O_RDWR
)) == -1) {
278 if (ioctl(STDIN_FILENO
, TIOCSCTTY
, (caddr_t
)0) != 0)
279 perror("ioctl (TIOCSCTTY)");
282 if ((name
= getlogin()) == NULL
) {
284 "access denied - getlogin returned 0\n");
285 errx(1, "access denied - no username");
289 if (!isatty(STDIN_FILENO
)) {
290 syslog(LOG_ERR
, "stdin not a tty");
291 errx(1, "stdin not a tty");
293 (void)fchmod(STDIN_FILENO
, 0600);
294 warnx("starting slip login for %s", loginname
);
296 /* set up the line parameters */
297 if (tcgetattr(STDIN_FILENO
, &tios
) < 0) {
298 syslog(LOG_ERR
, "tcgetattr: %m");
303 tios
.c_iflag
&= ~IMAXBEL
;
304 if (tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &tios
) < 0) {
305 syslog(LOG_ERR
, "tcsetattr: %m");
308 speed
= cfgetispeed(&tios
);
310 /* set up the line parameters */
311 if (ioctl(STDIN_FILENO
, TIOCGETP
, (caddr_t
)&tty
) < 0) {
312 syslog(LOG_ERR
, "ioctl (TIOCGETP): %m");
316 speed
= tty
.sg_ispeed
;
317 tty
.sg_flags
= RAW
| ANYP
;
318 if (ioctl(STDIN_FILENO
, TIOCSETP
, (caddr_t
)&tty
) < 0) {
319 syslog(LOG_ERR
, "ioctl (TIOCSETP): %m");
323 /* find out what ldisc we started with */
324 if (ioctl(STDIN_FILENO
, TIOCGETD
, (caddr_t
)&odisc
) < 0) {
325 syslog(LOG_ERR
, "ioctl(TIOCGETD) (1): %m");
329 if (ioctl(STDIN_FILENO
, TIOCSETD
, (caddr_t
)&ldisc
) < 0) {
330 syslog(LOG_ERR
, "ioctl(TIOCSETD): %m");
333 /* find out what unit number we were assigned */
334 if (ioctl(STDIN_FILENO
, SLIOCGUNIT
, (caddr_t
)&unit
) < 0) {
335 syslog(LOG_ERR
, "ioctl (SLIOCGUNIT): %m");
338 (void)signal(SIGHUP
, hup_handler
);
339 (void)signal(SIGTERM
, hup_handler
);
341 syslog(LOG_INFO
, "attaching slip unit %d for %s\n", unit
, loginname
);
342 (void)snprintf(logincmd
, sizeof logincmd
, "%s %d %d %s", loginfile
,
343 unit
, speed
, loginargs
);
345 * aim stdout and errout at /dev/null so logincmd output won't
346 * babble into the slip tty line.
349 if ((fd
= open(_PATH_DEVNULL
, O_WRONLY
)) != 1) {
351 syslog(LOG_ERR
, "open /dev/null: %m");
360 * Run login and logout scripts as root (real and effective);
361 * current route(8) is setuid root, and checks the real uid
362 * to see whether changes are allowed (or just "route get").
365 if ((s
= system(logincmd
)) != 0) {
366 syslog(LOG_ERR
, "%s login failed: exit status %d from %s",
367 loginname
, s
, loginfile
);
368 (void)ioctl(STDIN_FILENO
, TIOCSETD
, (caddr_t
)&odisc
);
370 (void)tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &otios
);
372 (void)ioctl(STDIN_FILENO
, TIOCSETP
, (caddr_t
)&otty
);
377 /* twiddle thumbs until we get a signal */