|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)uucpd.c 5.4 (Berkeley) 6/23/85"; ! 3: #endif ! 4: ! 5: /* ! 6: * 4.2BSD or 2.9BSD TCP/IP server for uucico ! 7: * uucico's TCP channel causes this server to be run at the remote end. ! 8: */ ! 9: ! 10: #include "uucp.h" ! 11: #include <netdb.h> ! 12: #ifdef BSD2_9 ! 13: #include <sys/localopts.h> ! 14: #include <sys/file.h> ! 15: #endif BSD2_9 ! 16: #include <signal.h> ! 17: #include <errno.h> ! 18: #include <sys/socket.h> ! 19: #include <netinet/in.h> ! 20: #include <sys/wait.h> ! 21: #include <sys/ioctl.h> ! 22: #include <pwd.h> ! 23: #include <lastlog.h> ! 24: ! 25: #if !defined(BSD4_2) && !defined(BSD2_9) ! 26: --- You must have either BSD4_2 or BSD2_9 defined for this to work ! 27: #endif !BSD4_2 && !BSD2_9 ! 28: #if defined(BSD4_2) && defined(BSD2_9) ! 29: --- You may not have both BSD4_2 and BSD2_9 defined for this to work ! 30: #endif /* check for stupidity */ ! 31: ! 32: char lastlog[] = "/usr/adm/lastlog"; ! 33: struct sockaddr_in hisctladdr; ! 34: int hisaddrlen = sizeof hisctladdr; ! 35: struct sockaddr_in myctladdr; ! 36: int mypid; ! 37: ! 38: char Username[64]; ! 39: char *nenv[] = { ! 40: Username, ! 41: NULL, ! 42: }; ! 43: extern char **environ; ! 44: ! 45: main(argc, argv) ! 46: int argc; ! 47: char **argv; ! 48: { ! 49: #ifndef BSDINETD ! 50: register int s, tcp_socket; ! 51: struct servent *sp; ! 52: #endif !BSDINETD ! 53: extern int errno; ! 54: int dologout(); ! 55: ! 56: environ = nenv; ! 57: #ifdef BSDINETD ! 58: close(1); close(2); ! 59: dup(0); dup(0); ! 60: hisaddrlen = sizeof (hisctladdr); ! 61: if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { ! 62: fprintf(stderr, "%s: ", argv[0]); ! 63: perror("getpeername"); ! 64: _exit(1); ! 65: } ! 66: if (fork() == 0) ! 67: doit(&hisctladdr); ! 68: dologout(); ! 69: exit(1); ! 70: #else !BSDINETD ! 71: sp = getservbyname("uucp", "tcp"); ! 72: if (sp == NULL){ ! 73: perror("uucpd: getservbyname"); ! 74: exit(1); ! 75: } ! 76: if (fork()) ! 77: exit(0); ! 78: if ((s=open("/dev/tty", 2)) >= 0){ ! 79: ioctl(s, TIOCNOTTY, (char *)0); ! 80: close(s); ! 81: } ! 82: ! 83: bzero((char *)&myctladdr, sizeof (myctladdr)); ! 84: myctladdr.sin_family = AF_INET; ! 85: myctladdr.sin_port = sp->s_port; ! 86: #ifdef BSD4_2 ! 87: tcp_socket = socket(AF_INET, SOCK_STREAM, 0); ! 88: if (tcp_socket < 0) { ! 89: perror("uucpd: socket"); ! 90: exit(1); ! 91: } ! 92: if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { ! 93: perror("uucpd: bind"); ! 94: exit(1); ! 95: } ! 96: listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ ! 97: signal(SIGCHLD, dologout); ! 98: ! 99: for(;;) { ! 100: s = accept(tcp_socket, &hisctladdr, &hisaddrlen); ! 101: if (s < 0){ ! 102: if (errno == EINTR) ! 103: continue; ! 104: perror("uucpd: accept"); ! 105: exit(1); ! 106: } ! 107: if (fork() == 0) { ! 108: close(0); close(1); close(2); ! 109: dup(s); dup(s); dup(s); ! 110: close(tcp_socket); close(s); ! 111: doit(&hisctladdr); ! 112: exit(1); ! 113: } ! 114: close(s); ! 115: } ! 116: #endif BSD4_2 ! 117: ! 118: #ifdef BSD2_9 ! 119: for(;;) { ! 120: signal(SIGCHLD, dologout); ! 121: s = socket(SOCK_STREAM, 0, &myctladdr, ! 122: SO_ACCEPTCONN|SO_KEEPALIVE); ! 123: if (s < 0) { ! 124: perror("uucpd: socket"); ! 125: exit(1); ! 126: } ! 127: if (accept(s, &hisctladdr) < 0) { ! 128: if (errno == EINTR) { ! 129: close(s); ! 130: continue; ! 131: } ! 132: perror("uucpd: accept"); ! 133: exit(1); ! 134: } ! 135: if (fork() == 0) { ! 136: close(0); close(1); close(2); ! 137: dup(s); dup(s); dup(s); ! 138: close(s); ! 139: doit(&hisctladdr); ! 140: exit(1); ! 141: } ! 142: } ! 143: #endif BSD2_9 ! 144: #endif !BSDINETD ! 145: } ! 146: ! 147: doit(sinp) ! 148: struct sockaddr_in *sinp; ! 149: { ! 150: char user[64], passwd[64]; ! 151: char *xpasswd, *crypt(); ! 152: struct passwd *pw, *getpwnam(); ! 153: ! 154: alarm(60); ! 155: printf("login: "); fflush(stdout); ! 156: if (readline(user, sizeof user) < 0) { ! 157: fprintf(stderr, "user read\n"); ! 158: return; ! 159: } ! 160: /* truncate username to 8 characters */ ! 161: user[8] = '\0'; ! 162: pw = getpwnam(user); ! 163: if (pw == NULL) { ! 164: fprintf(stderr, "user unknown\n"); ! 165: return; ! 166: } ! 167: if (strcmp(pw->pw_shell, UUCICO)) { ! 168: fprintf(stderr, "Login incorrect."); ! 169: return; ! 170: } ! 171: if (pw->pw_passwd && *pw->pw_passwd != '\0') { ! 172: printf("Password: "); fflush(stdout); ! 173: if (readline(passwd, sizeof passwd) < 0) { ! 174: fprintf(stderr, "passwd read\n"); ! 175: return; ! 176: } ! 177: xpasswd = crypt(passwd, pw->pw_passwd); ! 178: if (strcmp(xpasswd, pw->pw_passwd)) { ! 179: fprintf(stderr, "Login incorrect."); ! 180: return; ! 181: } ! 182: } ! 183: alarm(0); ! 184: sprintf(Username, "USER=%s", user); ! 185: dologin(pw, sinp); ! 186: setgid(pw->pw_gid); ! 187: #ifdef BSD4_2 ! 188: initgroups(pw->pw_name, pw->pw_gid); ! 189: #endif BSD4_2 ! 190: chdir(pw->pw_dir); ! 191: setuid(pw->pw_uid); ! 192: #ifdef BSD4_2 ! 193: execl(UUCICO, "uucico", (char *)0); ! 194: #endif BSD4_2 ! 195: #ifdef BSD2_9 ! 196: sprintf(passwd, "-h%s", inet_ntoa(sinp->sin_addr)); ! 197: execl(UUCICO, "uucico", passwd, (char *)0); ! 198: #endif BSD2_9 ! 199: perror("uucico server: execl"); ! 200: } ! 201: ! 202: readline(p, n) ! 203: register char *p; ! 204: register int n; ! 205: { ! 206: char c; ! 207: ! 208: while (n-- > 0) { ! 209: if (read(0, &c, 1) <= 0) ! 210: return(-1); ! 211: c &= 0177; ! 212: if (c == '\n' || c == '\r') { ! 213: *p = '\0'; ! 214: return(0); ! 215: } ! 216: *p++ = c; ! 217: } ! 218: return(-1); ! 219: } ! 220: ! 221: #include <utmp.h> ! 222: #ifdef BSD4_2 ! 223: #include <fcntl.h> ! 224: #endif BSD4_2 ! 225: ! 226: #ifdef BSD2_9 ! 227: #define O_APPEND 0 /* kludge */ ! 228: #define wait3(a,b,c) wait2(a,b) ! 229: #endif BSD2_9 ! 230: ! 231: #define SCPYN(a, b) strncpy(a, b, sizeof (a)) ! 232: ! 233: struct utmp utmp; ! 234: ! 235: dologout() ! 236: { ! 237: union wait status; ! 238: int pid, wtmp; ! 239: ! 240: #ifdef BSDINETD ! 241: while ((pid=wait(&status)) > 0) { ! 242: #else !BSDINETD ! 243: while ((pid=wait3(&status,WNOHANG,0)) > 0) { ! 244: #endif !BSDINETD ! 245: wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); ! 246: if (wtmp >= 0) { ! 247: sprintf(utmp.ut_line, "uucp%.4d", pid); ! 248: SCPYN(utmp.ut_name, ""); ! 249: SCPYN(utmp.ut_host, ""); ! 250: (void) time(&utmp.ut_time); ! 251: #ifdef BSD2_9 ! 252: (void) lseek(wtmp, 0L, 2); ! 253: #endif BSD2_9 ! 254: (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! 255: (void) close(wtmp); ! 256: } ! 257: } ! 258: } ! 259: ! 260: /* ! 261: * Record login in wtmp file. ! 262: */ ! 263: dologin(pw, sin) ! 264: struct passwd *pw; ! 265: struct sockaddr_in *sin; ! 266: { ! 267: char line[32]; ! 268: char remotehost[32]; ! 269: int wtmp, f; ! 270: struct hostent *hp = gethostbyaddr(&sin->sin_addr, ! 271: sizeof (struct in_addr), AF_INET); ! 272: ! 273: if (hp) { ! 274: strncpy(remotehost, hp->h_name, sizeof (remotehost)); ! 275: endhostent(); ! 276: } else ! 277: strncpy(remotehost, inet_ntoa(sin->sin_addr), ! 278: sizeof (remotehost)); ! 279: wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); ! 280: if (wtmp >= 0) { ! 281: /* hack, but must be unique and no tty line */ ! 282: sprintf(line, "uucp%.4d", getpid()); ! 283: SCPYN(utmp.ut_line, line); ! 284: SCPYN(utmp.ut_name, pw->pw_name); ! 285: SCPYN(utmp.ut_host, remotehost); ! 286: time(&utmp.ut_time); ! 287: #ifdef BSD2_9 ! 288: (void) lseek(wtmp, 0L, 2); ! 289: #endif BSD2_9 ! 290: (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! 291: (void) close(wtmp); ! 292: } ! 293: if ((f = open(lastlog, 2)) >= 0) { ! 294: struct lastlog ll; ! 295: ! 296: time(&ll.ll_time); ! 297: lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); ! 298: strcpy(line, remotehost); ! 299: SCPYN(ll.ll_line, line); ! 300: SCPYN(ll.ll_host, remotehost); ! 301: (void) write(f, (char *) &ll, sizeof ll); ! 302: (void) close(f); ! 303: } ! 304: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.