|
|
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.