|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1985 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Rick Adams. ! 7: * ! 8: * Redistribution and use in source and binary forms are permitted ! 9: * provided that: (1) source distributions retain this entire copyright ! 10: * notice and comment, and (2) distributions including binaries display ! 11: * the following acknowledgement: ``This product includes software ! 12: * developed by the University of California, Berkeley and its contributors'' ! 13: * in the documentation or other materials provided with the distribution ! 14: * and in all advertising materials mentioning features or use of this ! 15: * software. Neither the name of the University nor the names of its ! 16: * contributors may be used to endorse or promote products derived ! 17: * from this software without specific prior written permission. ! 18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 21: */ ! 22: ! 23: #ifndef lint ! 24: char copyright[] = ! 25: "@(#) Copyright (c) 1985 The Regents of the University of California.\n\ ! 26: All rights reserved.\n"; ! 27: #endif /* not lint */ ! 28: ! 29: #ifndef lint ! 30: static char sccsid[] = "@(#)uucpd.c 5.9 (Berkeley) 6/1/90"; ! 31: #endif /* not lint */ ! 32: ! 33: /* ! 34: * 4.2BSD TCP/IP server for uucico ! 35: * uucico's TCP channel causes this server to be run at the remote end. ! 36: */ ! 37: ! 38: #include <sys/types.h> ! 39: #include <sys/socket.h> ! 40: #include <sys/wait.h> ! 41: #include <sys/ioctl.h> ! 42: #include <sys/file.h> ! 43: #include <netinet/in.h> ! 44: #include <netdb.h> ! 45: #include <signal.h> ! 46: #include <errno.h> ! 47: #include <pwd.h> ! 48: #include <stdio.h> ! 49: #include "pathnames.h" ! 50: ! 51: struct sockaddr_in hisctladdr; ! 52: int hisaddrlen = sizeof hisctladdr; ! 53: struct sockaddr_in myctladdr; ! 54: int mypid; ! 55: ! 56: char Username[64]; ! 57: char *nenv[] = { ! 58: Username, ! 59: NULL, ! 60: }; ! 61: extern char **environ; ! 62: ! 63: main(argc, argv) ! 64: int argc; ! 65: char **argv; ! 66: { ! 67: #ifndef BSDINETD ! 68: register int s, tcp_socket; ! 69: struct servent *sp; ! 70: #endif !BSDINETD ! 71: extern int errno; ! 72: int dologout(); ! 73: ! 74: environ = nenv; ! 75: #ifdef BSDINETD ! 76: close(1); close(2); ! 77: dup(0); dup(0); ! 78: hisaddrlen = sizeof (hisctladdr); ! 79: if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { ! 80: fprintf(stderr, "%s: ", argv[0]); ! 81: perror("getpeername"); ! 82: _exit(1); ! 83: } ! 84: if (fork() == 0) ! 85: doit(&hisctladdr); ! 86: dologout(); ! 87: exit(1); ! 88: #else !BSDINETD ! 89: sp = getservbyname("uucp", "tcp"); ! 90: if (sp == NULL){ ! 91: perror("uucpd: getservbyname"); ! 92: exit(1); ! 93: } ! 94: if (fork()) ! 95: exit(0); ! 96: if ((s=open(_PATH_TTY, 2)) >= 0){ ! 97: ioctl(s, TIOCNOTTY, (char *)0); ! 98: close(s); ! 99: } ! 100: ! 101: bzero((char *)&myctladdr, sizeof (myctladdr)); ! 102: myctladdr.sin_family = AF_INET; ! 103: myctladdr.sin_port = sp->s_port; ! 104: #ifdef BSD4_2 ! 105: tcp_socket = socket(AF_INET, SOCK_STREAM, 0); ! 106: if (tcp_socket < 0) { ! 107: perror("uucpd: socket"); ! 108: exit(1); ! 109: } ! 110: if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { ! 111: perror("uucpd: bind"); ! 112: exit(1); ! 113: } ! 114: listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ ! 115: signal(SIGCHLD, dologout); ! 116: ! 117: for(;;) { ! 118: s = accept(tcp_socket, &hisctladdr, &hisaddrlen); ! 119: if (s < 0){ ! 120: if (errno == EINTR) ! 121: continue; ! 122: perror("uucpd: accept"); ! 123: exit(1); ! 124: } ! 125: if (fork() == 0) { ! 126: close(0); close(1); close(2); ! 127: dup(s); dup(s); dup(s); ! 128: close(tcp_socket); close(s); ! 129: doit(&hisctladdr); ! 130: exit(1); ! 131: } ! 132: close(s); ! 133: } ! 134: #endif BSD4_2 ! 135: ! 136: #endif !BSDINETD ! 137: } ! 138: ! 139: doit(sinp) ! 140: struct sockaddr_in *sinp; ! 141: { ! 142: char user[64], passwd[64]; ! 143: char *xpasswd, *crypt(); ! 144: struct passwd *pw, *getpwnam(); ! 145: ! 146: alarm(60); ! 147: printf("login: "); fflush(stdout); ! 148: if (readline(user, sizeof user) < 0) { ! 149: fprintf(stderr, "user read\n"); ! 150: return; ! 151: } ! 152: /* truncate username to 8 characters */ ! 153: user[8] = '\0'; ! 154: pw = getpwnam(user); ! 155: if (pw == NULL) { ! 156: fprintf(stderr, "user unknown\n"); ! 157: return; ! 158: } ! 159: if (strcmp(pw->pw_shell, _PATH_UUCICO)) { ! 160: fprintf(stderr, "Login incorrect."); ! 161: return; ! 162: } ! 163: if (pw->pw_passwd && *pw->pw_passwd != '\0') { ! 164: printf("Password: "); fflush(stdout); ! 165: if (readline(passwd, sizeof passwd) < 0) { ! 166: fprintf(stderr, "passwd read\n"); ! 167: return; ! 168: } ! 169: xpasswd = crypt(passwd, pw->pw_passwd); ! 170: if (strcmp(xpasswd, pw->pw_passwd)) { ! 171: fprintf(stderr, "Login incorrect."); ! 172: return; ! 173: } ! 174: } ! 175: alarm(0); ! 176: sprintf(Username, "USER=%s", user); ! 177: dologin(pw, sinp); ! 178: setgid(pw->pw_gid); ! 179: #ifdef BSD4_2 ! 180: initgroups(pw->pw_name, pw->pw_gid); ! 181: #endif BSD4_2 ! 182: chdir(pw->pw_dir); ! 183: setuid(pw->pw_uid); ! 184: #ifdef BSD4_2 ! 185: execl(UUCICO, "uucico", (char *)0); ! 186: #endif BSD4_2 ! 187: perror("uucico server: execl"); ! 188: } ! 189: ! 190: readline(p, n) ! 191: register char *p; ! 192: register int n; ! 193: { ! 194: char c; ! 195: ! 196: while (n-- > 0) { ! 197: if (read(0, &c, 1) <= 0) ! 198: return(-1); ! 199: c &= 0177; ! 200: if (c == '\n' || c == '\r') { ! 201: *p = '\0'; ! 202: return(0); ! 203: } ! 204: *p++ = c; ! 205: } ! 206: return(-1); ! 207: } ! 208: ! 209: #include <utmp.h> ! 210: #ifdef BSD4_2 ! 211: #include <fcntl.h> ! 212: #endif BSD4_2 ! 213: ! 214: #define SCPYN(a, b) strncpy(a, b, sizeof (a)) ! 215: ! 216: struct utmp utmp; ! 217: ! 218: dologout() ! 219: { ! 220: union wait status; ! 221: int pid, wtmp; ! 222: ! 223: #ifdef BSDINETD ! 224: while ((pid=wait(&status)) > 0) { ! 225: #else !BSDINETD ! 226: while ((pid=wait3(&status,WNOHANG,0)) > 0) { ! 227: #endif !BSDINETD ! 228: wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); ! 229: if (wtmp >= 0) { ! 230: sprintf(utmp.ut_line, "uucp%.4d", pid); ! 231: SCPYN(utmp.ut_name, ""); ! 232: SCPYN(utmp.ut_host, ""); ! 233: (void) time(&utmp.ut_time); ! 234: (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! 235: (void) close(wtmp); ! 236: } ! 237: } ! 238: } ! 239: ! 240: /* ! 241: * Record login in wtmp file. ! 242: */ ! 243: dologin(pw, sin) ! 244: struct passwd *pw; ! 245: struct sockaddr_in *sin; ! 246: { ! 247: char line[32]; ! 248: char remotehost[32]; ! 249: int wtmp, f; ! 250: struct hostent *hp = gethostbyaddr(&sin->sin_addr, ! 251: sizeof (struct in_addr), AF_INET); ! 252: ! 253: if (hp) { ! 254: strncpy(remotehost, hp->h_name, sizeof (remotehost)); ! 255: endhostent(); ! 256: } else ! 257: strncpy(remotehost, inet_ntoa(sin->sin_addr), ! 258: sizeof (remotehost)); ! 259: wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); ! 260: if (wtmp >= 0) { ! 261: /* hack, but must be unique and no tty line */ ! 262: sprintf(line, "uucp%.4d", getpid()); ! 263: SCPYN(utmp.ut_line, line); ! 264: SCPYN(utmp.ut_name, pw->pw_name); ! 265: SCPYN(utmp.ut_host, remotehost); ! 266: time(&utmp.ut_time); ! 267: (void) write(wtmp, (char *)&utmp, sizeof (utmp)); ! 268: (void) close(wtmp); ! 269: } ! 270: if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) { ! 271: struct lastlog ll; ! 272: ! 273: time(&ll.ll_time); ! 274: lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); ! 275: strcpy(line, remotehost); ! 276: SCPYN(ll.ll_line, line); ! 277: SCPYN(ll.ll_host, remotehost); ! 278: (void) write(f, (char *) &ll, sizeof ll); ! 279: (void) close(f); ! 280: } ! 281: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.