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