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