117144Sralph #ifndef lint 2*33974Srick static char sccsid[] = "@(#)uucpd.c 5.5 (Berkeley) 04/05/88"; 317144Sralph #endif 417144Sralph 517144Sralph /* 6*33974Srick * 4.2BSD TCP/IP server for uucico 717843Sralph * uucico's TCP channel causes this server to be run at the remote end. 817144Sralph */ 917144Sralph 1017843Sralph #include "uucp.h" 1123682Sbloom #include <netdb.h> 1217843Sralph #include <signal.h> 1317144Sralph #include <errno.h> 1417144Sralph #include <sys/socket.h> 1517144Sralph #include <netinet/in.h> 1617843Sralph #include <sys/wait.h> 1723682Sbloom #include <sys/ioctl.h> 1817843Sralph #include <pwd.h> 1917843Sralph #include <lastlog.h> 2017144Sralph 2117843Sralph char lastlog[] = "/usr/adm/lastlog"; 2217843Sralph struct sockaddr_in hisctladdr; 2317843Sralph int hisaddrlen = sizeof hisctladdr; 2417843Sralph struct sockaddr_in myctladdr; 2517843Sralph int mypid; 2617144Sralph 2723682Sbloom char Username[64]; 2823682Sbloom char *nenv[] = { 2923682Sbloom Username, 3023682Sbloom NULL, 3123682Sbloom }; 3223682Sbloom extern char **environ; 3323682Sbloom 3417144Sralph main(argc, argv) 3517843Sralph int argc; 3617843Sralph char **argv; 3717144Sralph { 3818625Sralph #ifndef BSDINETD 3917843Sralph register int s, tcp_socket; 4017843Sralph struct servent *sp; 4118625Sralph #endif !BSDINETD 4217843Sralph extern int errno; 4317843Sralph int dologout(); 4417144Sralph 4523682Sbloom environ = nenv; 4617843Sralph #ifdef BSDINETD 4717843Sralph close(1); close(2); 4817843Sralph dup(0); dup(0); 4917843Sralph hisaddrlen = sizeof (hisctladdr); 5017843Sralph if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { 5117144Sralph fprintf(stderr, "%s: ", argv[0]); 5217144Sralph perror("getpeername"); 5317144Sralph _exit(1); 5417144Sralph } 5517843Sralph if (fork() == 0) 5617843Sralph doit(&hisctladdr); 5717843Sralph dologout(); 5817843Sralph exit(1); 5917843Sralph #else !BSDINETD 6017843Sralph sp = getservbyname("uucp", "tcp"); 6117843Sralph if (sp == NULL){ 6217843Sralph perror("uucpd: getservbyname"); 6317843Sralph exit(1); 6417843Sralph } 6523682Sbloom if (fork()) 6623682Sbloom exit(0); 6717843Sralph if ((s=open("/dev/tty", 2)) >= 0){ 6817843Sralph ioctl(s, TIOCNOTTY, (char *)0); 6917843Sralph close(s); 7017843Sralph } 7117144Sralph 7217843Sralph bzero((char *)&myctladdr, sizeof (myctladdr)); 7323682Sbloom myctladdr.sin_family = AF_INET; 7423682Sbloom myctladdr.sin_port = sp->s_port; 7523682Sbloom #ifdef BSD4_2 7623682Sbloom tcp_socket = socket(AF_INET, SOCK_STREAM, 0); 7723682Sbloom if (tcp_socket < 0) { 7817843Sralph perror("uucpd: socket"); 7917843Sralph exit(1); 8017843Sralph } 8123682Sbloom if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { 8217843Sralph perror("uucpd: bind"); 8317843Sralph exit(1); 8417843Sralph } 8523682Sbloom listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ 8617843Sralph signal(SIGCHLD, dologout); 8717843Sralph 8817843Sralph for(;;) { 8917843Sralph s = accept(tcp_socket, &hisctladdr, &hisaddrlen); 9017843Sralph if (s < 0){ 9123682Sbloom if (errno == EINTR) 9217843Sralph continue; 9317843Sralph perror("uucpd: accept"); 9417843Sralph exit(1); 9517843Sralph } 9623682Sbloom if (fork() == 0) { 9717843Sralph close(0); close(1); close(2); 9817843Sralph dup(s); dup(s); dup(s); 9923682Sbloom close(tcp_socket); close(s); 10017843Sralph doit(&hisctladdr); 10117843Sralph exit(1); 10217843Sralph } 10317843Sralph close(s); 10417843Sralph } 10523682Sbloom #endif BSD4_2 10623682Sbloom 10723682Sbloom #endif !BSDINETD 10817144Sralph } 10917843Sralph 11017843Sralph doit(sinp) 11117843Sralph struct sockaddr_in *sinp; 11217843Sralph { 11323682Sbloom char user[64], passwd[64]; 11417843Sralph char *xpasswd, *crypt(); 11517843Sralph struct passwd *pw, *getpwnam(); 11617843Sralph 11717843Sralph alarm(60); 11818625Sralph printf("login: "); fflush(stdout); 11917843Sralph if (readline(user, sizeof user) < 0) { 12017843Sralph fprintf(stderr, "user read\n"); 12117843Sralph return; 12217843Sralph } 12317843Sralph /* truncate username to 8 characters */ 12417843Sralph user[8] = '\0'; 12517843Sralph pw = getpwnam(user); 12617843Sralph if (pw == NULL) { 12717843Sralph fprintf(stderr, "user unknown\n"); 12817843Sralph return; 12917843Sralph } 13017843Sralph if (strcmp(pw->pw_shell, UUCICO)) { 13117843Sralph fprintf(stderr, "Login incorrect."); 13217843Sralph return; 13317843Sralph } 13417843Sralph if (pw->pw_passwd && *pw->pw_passwd != '\0') { 13518625Sralph printf("Password: "); fflush(stdout); 13617843Sralph if (readline(passwd, sizeof passwd) < 0) { 13717843Sralph fprintf(stderr, "passwd read\n"); 13817843Sralph return; 13917843Sralph } 14017843Sralph xpasswd = crypt(passwd, pw->pw_passwd); 14117843Sralph if (strcmp(xpasswd, pw->pw_passwd)) { 14217843Sralph fprintf(stderr, "Login incorrect."); 14317843Sralph return; 14417843Sralph } 14517843Sralph } 14617843Sralph alarm(0); 14723682Sbloom sprintf(Username, "USER=%s", user); 14817843Sralph dologin(pw, sinp); 14923682Sbloom setgid(pw->pw_gid); 15023682Sbloom #ifdef BSD4_2 15117843Sralph initgroups(pw->pw_name, pw->pw_gid); 15223682Sbloom #endif BSD4_2 15317843Sralph chdir(pw->pw_dir); 15423682Sbloom setuid(pw->pw_uid); 15523682Sbloom #ifdef BSD4_2 15617843Sralph execl(UUCICO, "uucico", (char *)0); 15723682Sbloom #endif BSD4_2 15817843Sralph perror("uucico server: execl"); 15917843Sralph } 16017843Sralph 16117843Sralph readline(p, n) 16218625Sralph register char *p; 16318625Sralph register int n; 16417843Sralph { 16517843Sralph char c; 16617843Sralph 16717843Sralph while (n-- > 0) { 16817843Sralph if (read(0, &c, 1) <= 0) 16917843Sralph return(-1); 17017843Sralph c &= 0177; 17117843Sralph if (c == '\n' || c == '\r') { 17217843Sralph *p = '\0'; 17317843Sralph return(0); 17417843Sralph } 17517843Sralph *p++ = c; 17617843Sralph } 17717843Sralph return(-1); 17817843Sralph } 17917843Sralph 18017843Sralph #include <utmp.h> 18123682Sbloom #ifdef BSD4_2 18217843Sralph #include <fcntl.h> 18323682Sbloom #endif BSD4_2 18417843Sralph 18517843Sralph #define SCPYN(a, b) strncpy(a, b, sizeof (a)) 18617843Sralph 18717843Sralph struct utmp utmp; 18817843Sralph 18917843Sralph dologout() 19017843Sralph { 19117843Sralph union wait status; 19217843Sralph int pid, wtmp; 19317843Sralph 19417843Sralph #ifdef BSDINETD 19523682Sbloom while ((pid=wait(&status)) > 0) { 19617843Sralph #else !BSDINETD 19723682Sbloom while ((pid=wait3(&status,WNOHANG,0)) > 0) { 19817843Sralph #endif !BSDINETD 19917843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 20017843Sralph if (wtmp >= 0) { 20117843Sralph sprintf(utmp.ut_line, "uucp%.4d", pid); 20217843Sralph SCPYN(utmp.ut_name, ""); 20317843Sralph SCPYN(utmp.ut_host, ""); 20423682Sbloom (void) time(&utmp.ut_time); 20517843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 20617843Sralph (void) close(wtmp); 20717843Sralph } 20817843Sralph } 20917843Sralph } 21017843Sralph 21117843Sralph /* 21217843Sralph * Record login in wtmp file. 21317843Sralph */ 21417843Sralph dologin(pw, sin) 21517843Sralph struct passwd *pw; 21617843Sralph struct sockaddr_in *sin; 21717843Sralph { 21817843Sralph char line[32]; 21917843Sralph char remotehost[32]; 22017843Sralph int wtmp, f; 22117843Sralph struct hostent *hp = gethostbyaddr(&sin->sin_addr, 22217843Sralph sizeof (struct in_addr), AF_INET); 22317843Sralph 22417843Sralph if (hp) { 22517843Sralph strncpy(remotehost, hp->h_name, sizeof (remotehost)); 22617843Sralph endhostent(); 22717843Sralph } else 22817843Sralph strncpy(remotehost, inet_ntoa(sin->sin_addr), 22917843Sralph sizeof (remotehost)); 23017843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 23117843Sralph if (wtmp >= 0) { 23217843Sralph /* hack, but must be unique and no tty line */ 23317843Sralph sprintf(line, "uucp%.4d", getpid()); 23417843Sralph SCPYN(utmp.ut_line, line); 23517843Sralph SCPYN(utmp.ut_name, pw->pw_name); 23617843Sralph SCPYN(utmp.ut_host, remotehost); 23723682Sbloom time(&utmp.ut_time); 23817843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 23917843Sralph (void) close(wtmp); 24017843Sralph } 24117843Sralph if ((f = open(lastlog, 2)) >= 0) { 24217843Sralph struct lastlog ll; 24317843Sralph 24417843Sralph time(&ll.ll_time); 24517843Sralph lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); 24617843Sralph strcpy(line, remotehost); 24717843Sralph SCPYN(ll.ll_line, line); 24817843Sralph SCPYN(ll.ll_host, remotehost); 24917843Sralph (void) write(f, (char *) &ll, sizeof ll); 25017843Sralph (void) close(f); 25117843Sralph } 25217843Sralph } 253