136093Sbostic /* 236093Sbostic * Copyright (c) 1985 The Regents of the University of California. 336093Sbostic * All rights reserved. 436093Sbostic * 536093Sbostic * This code is derived from software contributed to Berkeley by 636093Sbostic * Rick Adams. 736093Sbostic * 842673Sbostic * %sccs.include.redist.c% 936093Sbostic */ 1036093Sbostic 1117144Sralph #ifndef lint 1236093Sbostic char copyright[] = 1336093Sbostic "@(#) Copyright (c) 1985 The Regents of the University of California.\n\ 1436093Sbostic All rights reserved.\n"; 1536093Sbostic #endif /* not lint */ 1617144Sralph 1736093Sbostic #ifndef lint 18*46688Sbostic static char sccsid[] = "@(#)uucpd.c 5.10 (Berkeley) 02/26/91"; 1936093Sbostic #endif /* not lint */ 2036093Sbostic 2117144Sralph /* 2233974Srick * 4.2BSD TCP/IP server for uucico 2317843Sralph * uucico's TCP channel causes this server to be run at the remote end. 2417144Sralph */ 2517144Sralph 2638030Sbostic #include <sys/types.h> 2738030Sbostic #include <sys/wait.h> 2838030Sbostic #include <sys/ioctl.h> 29*46688Sbostic #include <sys/socket.h> 3038030Sbostic #include <netinet/in.h> 31*46688Sbostic #include <arpa/inet.h> 3223682Sbloom #include <netdb.h> 3317843Sralph #include <signal.h> 34*46688Sbostic #include <fcntl.h> 35*46688Sbostic #include <time.h> 36*46688Sbostic #include <pwd.h> 37*46688Sbostic #include <unistd.h> 3817144Sralph #include <errno.h> 3938030Sbostic #include <stdio.h> 40*46688Sbostic #include <stdlib.h> 41*46688Sbostic #include <string.h> 4237931Sbostic #include "pathnames.h" 4317144Sralph 4417843Sralph struct sockaddr_in hisctladdr; 4517843Sralph int hisaddrlen = sizeof hisctladdr; 4617843Sralph struct sockaddr_in myctladdr; 4717843Sralph int mypid; 4817144Sralph 4923682Sbloom char Username[64]; 5023682Sbloom char *nenv[] = { 5123682Sbloom Username, 5223682Sbloom NULL, 5323682Sbloom }; 5423682Sbloom extern char **environ; 5523682Sbloom 5617144Sralph main(argc, argv) 5717843Sralph int argc; 5817843Sralph char **argv; 5917144Sralph { 6018625Sralph #ifndef BSDINETD 6117843Sralph register int s, tcp_socket; 6217843Sralph struct servent *sp; 6318625Sralph #endif !BSDINETD 6417843Sralph extern int errno; 6517843Sralph int dologout(); 6617144Sralph 6723682Sbloom environ = nenv; 6817843Sralph #ifdef BSDINETD 6917843Sralph close(1); close(2); 7017843Sralph dup(0); dup(0); 7117843Sralph hisaddrlen = sizeof (hisctladdr); 7217843Sralph if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { 7317144Sralph fprintf(stderr, "%s: ", argv[0]); 7417144Sralph perror("getpeername"); 7517144Sralph _exit(1); 7617144Sralph } 7717843Sralph if (fork() == 0) 7817843Sralph doit(&hisctladdr); 7917843Sralph dologout(); 8017843Sralph exit(1); 8117843Sralph #else !BSDINETD 8217843Sralph sp = getservbyname("uucp", "tcp"); 8317843Sralph if (sp == NULL){ 8417843Sralph perror("uucpd: getservbyname"); 8517843Sralph exit(1); 8617843Sralph } 8723682Sbloom if (fork()) 8823682Sbloom exit(0); 8937931Sbostic if ((s=open(_PATH_TTY, 2)) >= 0){ 9017843Sralph ioctl(s, TIOCNOTTY, (char *)0); 9117843Sralph close(s); 9217843Sralph } 9317144Sralph 9417843Sralph bzero((char *)&myctladdr, sizeof (myctladdr)); 9523682Sbloom myctladdr.sin_family = AF_INET; 9623682Sbloom myctladdr.sin_port = sp->s_port; 9723682Sbloom #ifdef BSD4_2 9823682Sbloom tcp_socket = socket(AF_INET, SOCK_STREAM, 0); 9923682Sbloom if (tcp_socket < 0) { 10017843Sralph perror("uucpd: socket"); 10117843Sralph exit(1); 10217843Sralph } 10323682Sbloom if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { 10417843Sralph perror("uucpd: bind"); 10517843Sralph exit(1); 10617843Sralph } 10723682Sbloom listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ 10817843Sralph signal(SIGCHLD, dologout); 10917843Sralph 11017843Sralph for(;;) { 11117843Sralph s = accept(tcp_socket, &hisctladdr, &hisaddrlen); 11217843Sralph if (s < 0){ 11323682Sbloom if (errno == EINTR) 11417843Sralph continue; 11517843Sralph perror("uucpd: accept"); 11617843Sralph exit(1); 11717843Sralph } 11823682Sbloom if (fork() == 0) { 11917843Sralph close(0); close(1); close(2); 12017843Sralph dup(s); dup(s); dup(s); 12123682Sbloom close(tcp_socket); close(s); 12217843Sralph doit(&hisctladdr); 12317843Sralph exit(1); 12417843Sralph } 12517843Sralph close(s); 12617843Sralph } 12723682Sbloom #endif BSD4_2 12823682Sbloom 12923682Sbloom #endif !BSDINETD 13017144Sralph } 13117843Sralph 13217843Sralph doit(sinp) 13317843Sralph struct sockaddr_in *sinp; 13417843Sralph { 13523682Sbloom char user[64], passwd[64]; 13617843Sralph char *xpasswd, *crypt(); 13717843Sralph struct passwd *pw, *getpwnam(); 13817843Sralph 13917843Sralph alarm(60); 14018625Sralph printf("login: "); fflush(stdout); 14117843Sralph if (readline(user, sizeof user) < 0) { 14217843Sralph fprintf(stderr, "user read\n"); 14317843Sralph return; 14417843Sralph } 14517843Sralph /* truncate username to 8 characters */ 14617843Sralph user[8] = '\0'; 14717843Sralph pw = getpwnam(user); 14817843Sralph if (pw == NULL) { 14917843Sralph fprintf(stderr, "user unknown\n"); 15017843Sralph return; 15117843Sralph } 15238030Sbostic if (strcmp(pw->pw_shell, _PATH_UUCICO)) { 15317843Sralph fprintf(stderr, "Login incorrect."); 15417843Sralph return; 15517843Sralph } 15617843Sralph if (pw->pw_passwd && *pw->pw_passwd != '\0') { 15718625Sralph printf("Password: "); fflush(stdout); 15817843Sralph if (readline(passwd, sizeof passwd) < 0) { 15917843Sralph fprintf(stderr, "passwd read\n"); 16017843Sralph return; 16117843Sralph } 16217843Sralph xpasswd = crypt(passwd, pw->pw_passwd); 16317843Sralph if (strcmp(xpasswd, pw->pw_passwd)) { 16417843Sralph fprintf(stderr, "Login incorrect."); 16517843Sralph return; 16617843Sralph } 16717843Sralph } 16817843Sralph alarm(0); 16923682Sbloom sprintf(Username, "USER=%s", user); 17017843Sralph dologin(pw, sinp); 17123682Sbloom setgid(pw->pw_gid); 17223682Sbloom #ifdef BSD4_2 17317843Sralph initgroups(pw->pw_name, pw->pw_gid); 17423682Sbloom #endif BSD4_2 17517843Sralph chdir(pw->pw_dir); 17623682Sbloom setuid(pw->pw_uid); 17723682Sbloom #ifdef BSD4_2 17817843Sralph execl(UUCICO, "uucico", (char *)0); 17923682Sbloom #endif BSD4_2 18017843Sralph perror("uucico server: execl"); 18117843Sralph } 18217843Sralph 18317843Sralph readline(p, n) 18418625Sralph register char *p; 18518625Sralph register int n; 18617843Sralph { 18717843Sralph char c; 18817843Sralph 18917843Sralph while (n-- > 0) { 19017843Sralph if (read(0, &c, 1) <= 0) 19117843Sralph return(-1); 19217843Sralph c &= 0177; 19317843Sralph if (c == '\n' || c == '\r') { 19417843Sralph *p = '\0'; 19517843Sralph return(0); 19617843Sralph } 19717843Sralph *p++ = c; 19817843Sralph } 19917843Sralph return(-1); 20017843Sralph } 20117843Sralph 20217843Sralph #include <utmp.h> 20323682Sbloom #ifdef BSD4_2 20417843Sralph #include <fcntl.h> 20523682Sbloom #endif BSD4_2 20617843Sralph 20717843Sralph #define SCPYN(a, b) strncpy(a, b, sizeof (a)) 20817843Sralph 20917843Sralph struct utmp utmp; 21017843Sralph 21117843Sralph dologout() 21217843Sralph { 21317843Sralph union wait status; 21417843Sralph int pid, wtmp; 21517843Sralph 21617843Sralph #ifdef BSDINETD 217*46688Sbostic while ((pid=wait((int *)&status)) > 0) { 21817843Sralph #else !BSDINETD 219*46688Sbostic while ((pid=wait3((int *)&status,WNOHANG,0)) > 0) { 22017843Sralph #endif !BSDINETD 22137931Sbostic wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); 22217843Sralph if (wtmp >= 0) { 22317843Sralph sprintf(utmp.ut_line, "uucp%.4d", pid); 22417843Sralph SCPYN(utmp.ut_name, ""); 22517843Sralph SCPYN(utmp.ut_host, ""); 22623682Sbloom (void) time(&utmp.ut_time); 22717843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 22817843Sralph (void) close(wtmp); 22917843Sralph } 23017843Sralph } 23117843Sralph } 23217843Sralph 23317843Sralph /* 23417843Sralph * Record login in wtmp file. 23517843Sralph */ 23617843Sralph dologin(pw, sin) 23717843Sralph struct passwd *pw; 23817843Sralph struct sockaddr_in *sin; 23917843Sralph { 24017843Sralph char line[32]; 24117843Sralph char remotehost[32]; 24217843Sralph int wtmp, f; 243*46688Sbostic struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr, 24417843Sralph sizeof (struct in_addr), AF_INET); 24517843Sralph 24617843Sralph if (hp) { 24717843Sralph strncpy(remotehost, hp->h_name, sizeof (remotehost)); 24817843Sralph endhostent(); 24917843Sralph } else 25017843Sralph strncpy(remotehost, inet_ntoa(sin->sin_addr), 25117843Sralph sizeof (remotehost)); 25237931Sbostic wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); 25317843Sralph if (wtmp >= 0) { 25417843Sralph /* hack, but must be unique and no tty line */ 25517843Sralph sprintf(line, "uucp%.4d", getpid()); 25617843Sralph SCPYN(utmp.ut_line, line); 25717843Sralph SCPYN(utmp.ut_name, pw->pw_name); 25817843Sralph SCPYN(utmp.ut_host, remotehost); 25923682Sbloom time(&utmp.ut_time); 26017843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 26117843Sralph (void) close(wtmp); 26217843Sralph } 26337931Sbostic if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) { 26417843Sralph struct lastlog ll; 26517843Sralph 26617843Sralph time(&ll.ll_time); 26717843Sralph lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); 26817843Sralph strcpy(line, remotehost); 26917843Sralph SCPYN(ll.ll_line, line); 27017843Sralph SCPYN(ll.ll_host, remotehost); 27117843Sralph (void) write(f, (char *) &ll, sizeof ll); 27217843Sralph (void) close(f); 27317843Sralph } 27417843Sralph } 275