117144Sralph #ifndef lint 2*17843Sralph static char sccsid[] = "@(#)uucpd.c 5.2 (Berkeley) 01/22/85"; 317144Sralph #endif 417144Sralph 517144Sralph /* 6*17843Sralph * 4.2BSD TCP/IP server for uucico 7*17843Sralph * uucico's TCP channel causes this server to be run at the remote end. 817144Sralph */ 917144Sralph 10*17843Sralph #include "uucp.h" 11*17843Sralph #include <signal.h> 1217144Sralph #include <errno.h> 13*17843Sralph #include <sys/param.h> 1417144Sralph #include <sys/socket.h> 15*17843Sralph #include <sys/ioctl.h> 1617144Sralph #include <netinet/in.h> 17*17843Sralph #include <netdb.h> 18*17843Sralph #include <sys/wait.h> 19*17843Sralph #include <pwd.h> 20*17843Sralph #include <lastlog.h> 2117144Sralph 22*17843Sralph char lastlog[] = "/usr/adm/lastlog"; 23*17843Sralph struct sockaddr_in hisctladdr; 24*17843Sralph int hisaddrlen = sizeof hisctladdr; 25*17843Sralph struct sockaddr_in myctladdr; 26*17843Sralph int mypid; 2717144Sralph 2817144Sralph main(argc, argv) 29*17843Sralph int argc; 30*17843Sralph char **argv; 3117144Sralph { 32*17843Sralph register int s, tcp_socket; 33*17843Sralph struct servent *sp; 34*17843Sralph extern int errno; 35*17843Sralph int dologout(); 3617144Sralph 37*17843Sralph #ifdef BSDINETD 38*17843Sralph close(1); close(2); 39*17843Sralph dup(0); dup(0); 40*17843Sralph hisaddrlen = sizeof (hisctladdr); 41*17843Sralph if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { 4217144Sralph fprintf(stderr, "%s: ", argv[0]); 4317144Sralph perror("getpeername"); 4417144Sralph _exit(1); 4517144Sralph } 46*17843Sralph if (fork() == 0) 47*17843Sralph doit(&hisctladdr); 48*17843Sralph dologout(); 49*17843Sralph exit(1); 50*17843Sralph #else !BSDINETD 51*17843Sralph sp = getservbyname("uucp", "tcp"); 52*17843Sralph if (sp == NULL){ 53*17843Sralph perror("uucpd: getservbyname"); 54*17843Sralph exit(1); 55*17843Sralph } 56*17843Sralph if ((s=open("/dev/tty", 2)) >= 0){ 57*17843Sralph ioctl(s, TIOCNOTTY, (char *)0); 58*17843Sralph close(s); 59*17843Sralph } 6017144Sralph 61*17843Sralph bzero((char *)&myctladdr, sizeof (myctladdr)); 62*17843Sralph tcp_socket = socket(AF_INET, SOCK_STREAM, 0, 0); 63*17843Sralph if ( tcp_socket<0 ) { 64*17843Sralph perror("uucpd: socket"); 65*17843Sralph exit(1); 66*17843Sralph } 67*17843Sralph myctladdr.sin_port = sp->s_port; 68*17843Sralph if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr), 0) < 0) { 69*17843Sralph perror("uucpd: bind"); 70*17843Sralph exit(1); 71*17843Sralph } 72*17843Sralph signal(SIGCHLD, dologout); 73*17843Sralph listen(tcp_socket, 5); /* 5's as good as any */ 74*17843Sralph 75*17843Sralph for(;;) { 76*17843Sralph s = accept(tcp_socket, &hisctladdr, &hisaddrlen); 77*17843Sralph if (s < 0){ 78*17843Sralph if (errno == EINTR) 79*17843Sralph continue; 80*17843Sralph perror("uucpd: accept"); 81*17843Sralph exit(1); 82*17843Sralph } 83*17843Sralph if (fork()== 0) { 84*17843Sralph close(0); close(1); close(2); 85*17843Sralph dup(s); dup(s); dup(s); 86*17843Sralph close(tcp_socket);close(s); 87*17843Sralph doit(&hisctladdr); 88*17843Sralph exit(1); 89*17843Sralph } 90*17843Sralph close(s); 91*17843Sralph } 92*17843Sralph #endif 9317144Sralph } 94*17843Sralph 95*17843Sralph doit(sinp) 96*17843Sralph struct sockaddr_in *sinp; 97*17843Sralph { 98*17843Sralph char ebuf[32]; 99*17843Sralph char user[64]; 100*17843Sralph char passwd[64]; 101*17843Sralph char *xpasswd, *crypt(); 102*17843Sralph struct passwd *pw, *getpwnam(); 103*17843Sralph 104*17843Sralph alarm(60); 105*17843Sralph if (readline(user, sizeof user) < 0) { 106*17843Sralph fprintf(stderr, "user read\n"); 107*17843Sralph return; 108*17843Sralph } 109*17843Sralph /* truncate username to 8 characters */ 110*17843Sralph user[8] = '\0'; 111*17843Sralph pw = getpwnam(user); 112*17843Sralph if (pw == NULL) { 113*17843Sralph fprintf(stderr, "user unknown\n"); 114*17843Sralph return; 115*17843Sralph } 116*17843Sralph if (strcmp(pw->pw_shell, UUCICO)) { 117*17843Sralph fprintf(stderr, "Login incorrect."); 118*17843Sralph return; 119*17843Sralph } 120*17843Sralph if (pw->pw_passwd && *pw->pw_passwd != '\0') { 121*17843Sralph if (readline(passwd, sizeof passwd) < 0) { 122*17843Sralph fprintf(stderr, "passwd read\n"); 123*17843Sralph return; 124*17843Sralph } 125*17843Sralph xpasswd = crypt(passwd, pw->pw_passwd); 126*17843Sralph if (strcmp(xpasswd, pw->pw_passwd)) { 127*17843Sralph fprintf(stderr, "Login incorrect."); 128*17843Sralph return; 129*17843Sralph } 130*17843Sralph } 131*17843Sralph alarm(0); 132*17843Sralph dologin(pw, sinp); 133*17843Sralph setegid(pw->pw_gid); 134*17843Sralph initgroups(pw->pw_name, pw->pw_gid); 135*17843Sralph chdir(pw->pw_dir); 136*17843Sralph seteuid(pw->pw_uid); 137*17843Sralph execl(UUCICO, "uucico", (char *)0); 138*17843Sralph perror("uucico server: execl"); 139*17843Sralph } 140*17843Sralph 141*17843Sralph readline(p, n) 142*17843Sralph register char *p; 143*17843Sralph register int n; 144*17843Sralph { 145*17843Sralph char c; 146*17843Sralph 147*17843Sralph while (n-- > 0) { 148*17843Sralph if (read(0, &c, 1) <= 0) 149*17843Sralph return(-1); 150*17843Sralph c &= 0177; 151*17843Sralph if (c == '\n' || c == '\r') { 152*17843Sralph *p = '\0'; 153*17843Sralph return(0); 154*17843Sralph } 155*17843Sralph *p++ = c; 156*17843Sralph } 157*17843Sralph return(-1); 158*17843Sralph } 159*17843Sralph 160*17843Sralph #include <utmp.h> 161*17843Sralph #include <fcntl.h> 162*17843Sralph 163*17843Sralph #define SCPYN(a, b) strncpy(a, b, sizeof (a)) 164*17843Sralph 165*17843Sralph struct utmp utmp; 166*17843Sralph 167*17843Sralph dologout() 168*17843Sralph { 169*17843Sralph union wait status; 170*17843Sralph int pid, wtmp; 171*17843Sralph 172*17843Sralph #ifdef BSDINETD 173*17843Sralph while ((pid=wait(&status)) > 0 ) { 174*17843Sralph #else !BSDINETD 175*17843Sralph while ((pid=wait3(&status,WNOHANG,0)) > 0 ) { 176*17843Sralph #endif !BSDINETD 177*17843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 178*17843Sralph if (wtmp >= 0) { 179*17843Sralph sprintf(utmp.ut_line, "uucp%.4d", pid); 180*17843Sralph SCPYN(utmp.ut_name, ""); 181*17843Sralph SCPYN(utmp.ut_host, ""); 182*17843Sralph utmp.ut_time = time(0); 183*17843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 184*17843Sralph (void) close(wtmp); 185*17843Sralph } 186*17843Sralph } 187*17843Sralph } 188*17843Sralph 189*17843Sralph /* 190*17843Sralph * Record login in wtmp file. 191*17843Sralph */ 192*17843Sralph dologin(pw, sin) 193*17843Sralph struct passwd *pw; 194*17843Sralph struct sockaddr_in *sin; 195*17843Sralph { 196*17843Sralph char line[32]; 197*17843Sralph char remotehost[32]; 198*17843Sralph int wtmp, f; 199*17843Sralph struct hostent *hp = gethostbyaddr(&sin->sin_addr, 200*17843Sralph sizeof (struct in_addr), AF_INET); 201*17843Sralph 202*17843Sralph if (hp) { 203*17843Sralph strncpy(remotehost, hp->h_name, sizeof (remotehost)); 204*17843Sralph endhostent(); 205*17843Sralph } else 206*17843Sralph strncpy(remotehost, inet_ntoa(sin->sin_addr), 207*17843Sralph sizeof (remotehost)); 208*17843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 209*17843Sralph if (wtmp >= 0) { 210*17843Sralph /* hack, but must be unique and no tty line */ 211*17843Sralph sprintf(line, "uucp%.4d", getpid()); 212*17843Sralph SCPYN(utmp.ut_line, line); 213*17843Sralph SCPYN(utmp.ut_name, pw->pw_name); 214*17843Sralph SCPYN(utmp.ut_host, remotehost); 215*17843Sralph utmp.ut_time = time(0); 216*17843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 217*17843Sralph (void) close(wtmp); 218*17843Sralph } 219*17843Sralph if ((f = open(lastlog, 2)) >= 0) { 220*17843Sralph struct lastlog ll; 221*17843Sralph 222*17843Sralph time(&ll.ll_time); 223*17843Sralph lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); 224*17843Sralph strcpy(line, remotehost); 225*17843Sralph SCPYN(ll.ll_line, line); 226*17843Sralph SCPYN(ll.ll_host, remotehost); 227*17843Sralph (void) write(f, (char *) &ll, sizeof ll); 228*17843Sralph (void) close(f); 229*17843Sralph } 230*17843Sralph } 231