|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)sliplogin.c 5.3 (Berkeley) 7/1/90";
28: #endif /* not lint */
29:
30: /*
31: * sliplogin.c
32: * [MUST BE RUN SUID, SLOPEN DOES A SUSER()!]
33: *
34: * This program initializes its own tty port to be an async TCP/IP interface.
35: * It sets the line discipline to slip, invokes a shell script to initialize
36: * the network interface, then pauses forever waiting for hangup.
37: *
38: * It is a remote descendant of several similar programs with incestuous ties:
39: * - Kirk Smith's slipconf, modified by Richard Johnsson @ DEC WRL.
40: * - slattach, probably by Rick Adams but touched by countless hordes.
41: * - the original sliplogin for 4.2bsd, Doug Kingston the mover behind it.
42: *
43: * There are two forms of usage:
44: *
45: * "sliplogin"
46: * Invoked simply as "sliplogin" and a realuid != 0, the program looks up
47: * the uid in /etc/passwd, and then the username in the file /etc/hosts.slip.
48: * If and entry is found, the line on fd0 is configured for SLIP operation
49: * as specified in the file.
50: *
51: * "sliplogin IPhost1 </dev/ttyb"
52: * Invoked by root with a username, the name is looked up in the
53: * /etc/hosts.slip file and if found fd0 is configured as in case 1.
54: */
55:
56: #include <sys/param.h>
57: #include <sys/socket.h>
58: #include <sys/ioctl.h>
59: #include <sys/signal.h>
60: #include <sys/file.h>
61: #include <sys/syslog.h>
62: #include <netdb.h>
63:
64: #if defined(BSD4_4)
65: #define TERMIOS
66: #endif
67: #ifdef TERMIOS
68: #include <sys/termios.h>
69: #include <ttyent.h>
70: #endif
71: #include <netinet/in.h>
72: #include <net/if.h>
73: #include <net/if_slvar.h>
74:
75: #include <stdio.h>
76: #include <errno.h>
77: #include <ctype.h>
78: #include <string.h>
79: #include "pathnames.h"
80:
81: int unit;
82: int slip_mode;
83: int speed;
84: char loginargs[BUFSIZ];
85: char loginfile[BUFSIZ];
86: char logoutfile[BUFSIZ];
87: char loginname[BUFSIZ];
88:
89: struct slip_modes {
90: char *sm_name;
91: int sm_value;
92: } modes[] = {
93: "normal", 0,
94: "compress", SC_COMPRESS,
95: "noicmp", SC_NOICMP,
96: "autocomp", SC_AUTOCOMP
97: };
98:
99: void
100: findid(name)
101: char *name;
102: {
103: FILE *fp;
104: static char slopt[5][16];
105: static char laddr[16];
106: static char raddr[16];
107: static char mask[16];
108: char user[16];
109: int i, j, n;
110:
111: (void)strcpy(loginname, name);
112: if ((fp = fopen(_PATH_ACCESS, "r")) == NULL) {
113: (void)fprintf(stderr, "sliplogin: %s: %s\n",
114: _PATH_ACCESS, strerror(errno));
115: syslog(LOG_ERR, "%s: %m\n", _PATH_ACCESS);
116: exit(1);
117: }
118: while (fgets(loginargs, sizeof(loginargs) - 1, fp)) {
119: if (ferror(fp))
120: break;
121: n = sscanf(loginargs, "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
122: user, laddr, raddr, mask, slopt[0], slopt[1],
123: slopt[2], slopt[3], slopt[4]);
124: if (user[0] == '#' || isspace(user[0]))
125: continue;
126: if (strcmp(user, name) != 0)
127: continue;
128:
129: slip_mode = 0;
130: for (i = 0; i < n - 4; i++) {
131: for (j = 0; j < sizeof(modes)/sizeof(struct slip_modes);
132: j++) {
133: if (strcmp(modes[j].sm_name, slopt[i]) == 0) {
134: slip_mode |= modes[j].sm_value;
135: break;
136: }
137: }
138: }
139:
140: /*
141: * we've found the guy we're looking for -- see if
142: * there's a login file we can use. First check for
143: * one specific to this host. If none found, try for
144: * a generic one.
145: */
146: (void)sprintf(loginfile, "%s.%s", _PATH_LOGIN, name);
147: if (access(loginfile, R_OK|X_OK)) {
148: (void)strcpy(loginfile, _PATH_LOGIN);
149: (void)strcpy(logoutfile, _PATH_LOGOUT);
150: if (access(loginfile, R_OK|X_OK)) {
151: fputs("access denied - no login file\n",
152: stderr);
153: syslog(LOG_ERR,
154: "access denied for %s - no %s\n",
155: name, _PATH_LOGIN);
156: exit(5);
157: }
158: } else
159: (void)sprintf(logoutfile, "%s.%s", _PATH_LOGOUT, name);
160:
161: (void) fclose(fp);
162: return;
163: }
164: (void)fprintf(stderr, "SLIP access denied for %s\n", name);
165: syslog(LOG_ERR, "SLIP access denied for %s\n", name);
166: exit(4);
167: /* NOTREACHED */
168: }
169:
170: char *
171: sigstr(s)
172: int s;
173: {
174: static char buf[32];
175:
176: switch (s) {
177: case SIGHUP: return("HUP");
178: case SIGINT: return("INT");
179: case SIGQUIT: return("QUIT");
180: case SIGILL: return("ILL");
181: case SIGTRAP: return("TRAP");
182: case SIGIOT: return("IOT");
183: case SIGEMT: return("EMT");
184: case SIGFPE: return("FPE");
185: case SIGKILL: return("KILL");
186: case SIGBUS: return("BUS");
187: case SIGSEGV: return("SEGV");
188: case SIGSYS: return("SYS");
189: case SIGPIPE: return("PIPE");
190: case SIGALRM: return("ALRM");
191: case SIGTERM: return("TERM");
192: case SIGURG: return("URG");
193: case SIGSTOP: return("STOP");
194: case SIGTSTP: return("TSTP");
195: case SIGCONT: return("CONT");
196: case SIGCHLD: return("CHLD");
197: case SIGTTIN: return("TTIN");
198: case SIGTTOU: return("TTOU");
199: case SIGIO: return("IO");
200: case SIGXCPU: return("XCPU");
201: case SIGXFSZ: return("XFSZ");
202: case SIGVTALRM: return("VTALRM");
203: case SIGPROF: return("PROF");
204: case SIGWINCH: return("WINCH");
205: #ifdef SIGLOST
206: case SIGLOST: return("LOST");
207: #endif
208: case SIGUSR1: return("USR1");
209: case SIGUSR2: return("USR2");
210: }
211: (void)sprintf(buf, "sig %d", s);
212: return(buf);
213: }
214:
215: int
216: hup_handler(s)
217: int s;
218: {
219: if (access(logoutfile, R_OK|X_OK) == 0) {
220: char logincmd[2*BUFSIZ+32];
221:
222: (void)sprintf(logincmd, "%s %d %d %s", logoutfile, unit, speed,
223: loginargs);
224: (void)system(logincmd);
225: }
226: (void)close(0);
227: syslog(LOG_INFO, "closed %s slip unit %d (%s)\n", loginname, unit,
228: sigstr(s));
229: exit(1);
230: /* NOTREACHED */
231: }
232:
233: main(argc, argv)
234: int argc;
235: char *argv[];
236: {
237: int fd, s, ldisc, odisc;
238: char *name;
239: #ifdef TERMIOS
240: struct termios tios, otios;
241: #else
242: struct sgttyb tty, otty;
243: #endif
244: char logincmd[2*BUFSIZ+32];
245: extern uid_t getuid();
246:
247: if ((name = strrchr(argv[0], '/')) == NULL)
248: name = argv[0];
249: s = getdtablesize();
250: for (fd = 3 ; fd < s ; fd++)
251: (void) close(fd);
252: openlog(name, LOG_PID, LOG_DAEMON);
253: if (argc > 1) {
254: if (argc > 2) {
255: (void)fprintf(stderr, "Usage: %s loginname\n", argv[0]);
256: exit(1);
257: }
258: findid(argv[1]);
259:
260: /*
261: * Disassociate from current controlling terminal, if any,
262: * and ensure that the slip line is our controlling terminal.
263: */
264: #ifdef TERMIOS
265: (void) setsid();
266: (void) ioctl(0, TIOCSCTTY, (caddr_t)0);
267: #else
268: if ((fd = open("/dev/tty", O_RDONLY, 0)) >= 0) {
269: extern char *ttyname();
270:
271: (void) ioctl(fd, TIOCNOTTY, (caddr_t)0);
272: (void) close(fd);
273: /* open slip tty again to acquire as controlling tty? */
274: fd = open(ttyname(0), O_RDWR, 0);
275: if (fd >= 0)
276: (void) close(fd);
277: }
278: (void) setpgrp(0, getpid());
279: #endif
280: } else {
281: extern char *getenv();
282:
283: if ((name = getenv("USER")) == NULL) {
284: (void) fprintf(stderr, "access denied - no username\n");
285: syslog(LOG_ERR, "access denied - no username\n");
286: exit(1);
287: }
288: findid(name);
289: }
290: (void) fchmod(0, 0600);
291: (void) fprintf(stderr, "starting slip login for %s\n", loginname);
292: #ifdef TERMIOS
293: /* set up the line parameters */
294: if (ioctl(0, TIOCGETA, (caddr_t)&tios) < 0) {
295: syslog(LOG_ERR, "ioctl (TIOCGETA): %m");
296: exit(1);
297: }
298: otios = tios;
299: tios.c_cflag = CS8|CREAD|HUPCL;
300: tios.c_iflag = IGNBRK;
301: tios.c_oflag = tios.c_lflag = 0;
302: if (ioctl(0, TIOCSETA, (caddr_t)&tios) < 0) {
303: syslog(LOG_ERR, "ioctl (TIOCSETA) (1): %m");
304: exit(1);
305: }
306: #else
307: /* set up the line parameters */
308: if (ioctl(0, TIOCGETP, (caddr_t)&tty) < 0) {
309: syslog(LOG_ERR, "ioctl (TIOCGETP): %m");
310: exit(1);
311: }
312: otty = tty;
313: speed = tty.sg_ispeed;
314: tty.sg_flags = RAW | ANYP;
315: if (ioctl(0, TIOCSETP, (caddr_t)&tty) < 0) {
316: syslog(LOG_ERR, "ioctl (TIOCSETP): %m");
317: exit(1);
318: }
319: #endif
320: /* find out what ldisc we started with */
321: if (ioctl(0, TIOCGETD, (caddr_t)&odisc) < 0) {
322: syslog(LOG_ERR, "ioctl(TIOCGETD) (1): %m");
323: exit(1);
324: }
325: ldisc = SLIPDISC;
326: if (ioctl(0, TIOCSETD, (caddr_t)&ldisc) < 0) {
327: syslog(LOG_ERR, "ioctl(TIOCSETD): %m");
328: exit(1);
329: }
330: /* find out what unit number we were assigned */
331: if (ioctl(0, TIOCGETD, (caddr_t)&unit) < 0) {
332: syslog(LOG_ERR, "ioctl (TIOCGETD) (2): %m");
333: exit(1);
334: }
335: (void) signal(SIGHUP, hup_handler);
336: (void) signal(SIGTERM, hup_handler);
337:
338: syslog(LOG_INFO, "attaching slip unit %d for %s\n", unit, loginname);
339: (void)sprintf(logincmd, "%s %d %d %s", loginfile, unit, speed,
340: loginargs);
341: /*
342: * aim stdout and errout at /dev/null so logincmd output won't
343: * babble into the slip tty line.
344: */
345: (void)close(1);
346: if ((fd = open("/dev/null", O_WRONLY, 0)) != 1) {
347: if (fd < 0) {
348: syslog(LOG_ERR, "open /dev/null: %m");
349: exit(1);
350: }
351: (void)dup2(fd, 1);
352: (void)close(fd);
353: }
354: (void)dup2(1,2);
355: if (s = system(logincmd)) {
356: syslog(LOG_ERR, "%s login failed: exit status %d from %s",
357: loginname, s, loginfile);
358: (void) ioctl(0, TIOCSETD, (caddr_t)&odisc);
359: exit(6);
360: }
361: if (ioctl(0, SLIOCSFLAGS, (caddr_t)&slip_mode) < 0) {
362: syslog(LOG_ERR, "ioctl (SLIOCSFLAGS): %m");
363: exit(1);
364: }
365:
366: /* twiddle thumbs until we get a signal */
367: while (1)
368: sigpause(0);
369:
370: /* NOTREACHED */
371: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.