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 * 8*42673Sbostic * %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*42673Sbostic static char sccsid[] = "@(#)uucpd.c 5.9 (Berkeley) 06/01/90"; 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/socket.h> 2838030Sbostic #include <sys/wait.h> 2938030Sbostic #include <sys/ioctl.h> 3038030Sbostic #include <sys/file.h> 3138030Sbostic #include <netinet/in.h> 3223682Sbloom #include <netdb.h> 3317843Sralph #include <signal.h> 3417144Sralph #include <errno.h> 3517843Sralph #include <pwd.h> 3638030Sbostic #include <stdio.h> 3737931Sbostic #include "pathnames.h" 3817144Sralph 3917843Sralph struct sockaddr_in hisctladdr; 4017843Sralph int hisaddrlen = sizeof hisctladdr; 4117843Sralph struct sockaddr_in myctladdr; 4217843Sralph int mypid; 4317144Sralph 4423682Sbloom char Username[64]; 4523682Sbloom char *nenv[] = { 4623682Sbloom Username, 4723682Sbloom NULL, 4823682Sbloom }; 4923682Sbloom extern char **environ; 5023682Sbloom 5117144Sralph main(argc, argv) 5217843Sralph int argc; 5317843Sralph char **argv; 5417144Sralph { 5518625Sralph #ifndef BSDINETD 5617843Sralph register int s, tcp_socket; 5717843Sralph struct servent *sp; 5818625Sralph #endif !BSDINETD 5917843Sralph extern int errno; 6017843Sralph int dologout(); 6117144Sralph 6223682Sbloom environ = nenv; 6317843Sralph #ifdef BSDINETD 6417843Sralph close(1); close(2); 6517843Sralph dup(0); dup(0); 6617843Sralph hisaddrlen = sizeof (hisctladdr); 6717843Sralph if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { 6817144Sralph fprintf(stderr, "%s: ", argv[0]); 6917144Sralph perror("getpeername"); 7017144Sralph _exit(1); 7117144Sralph } 7217843Sralph if (fork() == 0) 7317843Sralph doit(&hisctladdr); 7417843Sralph dologout(); 7517843Sralph exit(1); 7617843Sralph #else !BSDINETD 7717843Sralph sp = getservbyname("uucp", "tcp"); 7817843Sralph if (sp == NULL){ 7917843Sralph perror("uucpd: getservbyname"); 8017843Sralph exit(1); 8117843Sralph } 8223682Sbloom if (fork()) 8323682Sbloom exit(0); 8437931Sbostic if ((s=open(_PATH_TTY, 2)) >= 0){ 8517843Sralph ioctl(s, TIOCNOTTY, (char *)0); 8617843Sralph close(s); 8717843Sralph } 8817144Sralph 8917843Sralph bzero((char *)&myctladdr, sizeof (myctladdr)); 9023682Sbloom myctladdr.sin_family = AF_INET; 9123682Sbloom myctladdr.sin_port = sp->s_port; 9223682Sbloom #ifdef BSD4_2 9323682Sbloom tcp_socket = socket(AF_INET, SOCK_STREAM, 0); 9423682Sbloom if (tcp_socket < 0) { 9517843Sralph perror("uucpd: socket"); 9617843Sralph exit(1); 9717843Sralph } 9823682Sbloom if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { 9917843Sralph perror("uucpd: bind"); 10017843Sralph exit(1); 10117843Sralph } 10223682Sbloom listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ 10317843Sralph signal(SIGCHLD, dologout); 10417843Sralph 10517843Sralph for(;;) { 10617843Sralph s = accept(tcp_socket, &hisctladdr, &hisaddrlen); 10717843Sralph if (s < 0){ 10823682Sbloom if (errno == EINTR) 10917843Sralph continue; 11017843Sralph perror("uucpd: accept"); 11117843Sralph exit(1); 11217843Sralph } 11323682Sbloom if (fork() == 0) { 11417843Sralph close(0); close(1); close(2); 11517843Sralph dup(s); dup(s); dup(s); 11623682Sbloom close(tcp_socket); close(s); 11717843Sralph doit(&hisctladdr); 11817843Sralph exit(1); 11917843Sralph } 12017843Sralph close(s); 12117843Sralph } 12223682Sbloom #endif BSD4_2 12323682Sbloom 12423682Sbloom #endif !BSDINETD 12517144Sralph } 12617843Sralph 12717843Sralph doit(sinp) 12817843Sralph struct sockaddr_in *sinp; 12917843Sralph { 13023682Sbloom char user[64], passwd[64]; 13117843Sralph char *xpasswd, *crypt(); 13217843Sralph struct passwd *pw, *getpwnam(); 13317843Sralph 13417843Sralph alarm(60); 13518625Sralph printf("login: "); fflush(stdout); 13617843Sralph if (readline(user, sizeof user) < 0) { 13717843Sralph fprintf(stderr, "user read\n"); 13817843Sralph return; 13917843Sralph } 14017843Sralph /* truncate username to 8 characters */ 14117843Sralph user[8] = '\0'; 14217843Sralph pw = getpwnam(user); 14317843Sralph if (pw == NULL) { 14417843Sralph fprintf(stderr, "user unknown\n"); 14517843Sralph return; 14617843Sralph } 14738030Sbostic if (strcmp(pw->pw_shell, _PATH_UUCICO)) { 14817843Sralph fprintf(stderr, "Login incorrect."); 14917843Sralph return; 15017843Sralph } 15117843Sralph if (pw->pw_passwd && *pw->pw_passwd != '\0') { 15218625Sralph printf("Password: "); fflush(stdout); 15317843Sralph if (readline(passwd, sizeof passwd) < 0) { 15417843Sralph fprintf(stderr, "passwd read\n"); 15517843Sralph return; 15617843Sralph } 15717843Sralph xpasswd = crypt(passwd, pw->pw_passwd); 15817843Sralph if (strcmp(xpasswd, pw->pw_passwd)) { 15917843Sralph fprintf(stderr, "Login incorrect."); 16017843Sralph return; 16117843Sralph } 16217843Sralph } 16317843Sralph alarm(0); 16423682Sbloom sprintf(Username, "USER=%s", user); 16517843Sralph dologin(pw, sinp); 16623682Sbloom setgid(pw->pw_gid); 16723682Sbloom #ifdef BSD4_2 16817843Sralph initgroups(pw->pw_name, pw->pw_gid); 16923682Sbloom #endif BSD4_2 17017843Sralph chdir(pw->pw_dir); 17123682Sbloom setuid(pw->pw_uid); 17223682Sbloom #ifdef BSD4_2 17317843Sralph execl(UUCICO, "uucico", (char *)0); 17423682Sbloom #endif BSD4_2 17517843Sralph perror("uucico server: execl"); 17617843Sralph } 17717843Sralph 17817843Sralph readline(p, n) 17918625Sralph register char *p; 18018625Sralph register int n; 18117843Sralph { 18217843Sralph char c; 18317843Sralph 18417843Sralph while (n-- > 0) { 18517843Sralph if (read(0, &c, 1) <= 0) 18617843Sralph return(-1); 18717843Sralph c &= 0177; 18817843Sralph if (c == '\n' || c == '\r') { 18917843Sralph *p = '\0'; 19017843Sralph return(0); 19117843Sralph } 19217843Sralph *p++ = c; 19317843Sralph } 19417843Sralph return(-1); 19517843Sralph } 19617843Sralph 19717843Sralph #include <utmp.h> 19823682Sbloom #ifdef BSD4_2 19917843Sralph #include <fcntl.h> 20023682Sbloom #endif BSD4_2 20117843Sralph 20217843Sralph #define SCPYN(a, b) strncpy(a, b, sizeof (a)) 20317843Sralph 20417843Sralph struct utmp utmp; 20517843Sralph 20617843Sralph dologout() 20717843Sralph { 20817843Sralph union wait status; 20917843Sralph int pid, wtmp; 21017843Sralph 21117843Sralph #ifdef BSDINETD 21223682Sbloom while ((pid=wait(&status)) > 0) { 21317843Sralph #else !BSDINETD 21423682Sbloom while ((pid=wait3(&status,WNOHANG,0)) > 0) { 21517843Sralph #endif !BSDINETD 21637931Sbostic wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); 21717843Sralph if (wtmp >= 0) { 21817843Sralph sprintf(utmp.ut_line, "uucp%.4d", pid); 21917843Sralph SCPYN(utmp.ut_name, ""); 22017843Sralph SCPYN(utmp.ut_host, ""); 22123682Sbloom (void) time(&utmp.ut_time); 22217843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 22317843Sralph (void) close(wtmp); 22417843Sralph } 22517843Sralph } 22617843Sralph } 22717843Sralph 22817843Sralph /* 22917843Sralph * Record login in wtmp file. 23017843Sralph */ 23117843Sralph dologin(pw, sin) 23217843Sralph struct passwd *pw; 23317843Sralph struct sockaddr_in *sin; 23417843Sralph { 23517843Sralph char line[32]; 23617843Sralph char remotehost[32]; 23717843Sralph int wtmp, f; 23817843Sralph struct hostent *hp = gethostbyaddr(&sin->sin_addr, 23917843Sralph sizeof (struct in_addr), AF_INET); 24017843Sralph 24117843Sralph if (hp) { 24217843Sralph strncpy(remotehost, hp->h_name, sizeof (remotehost)); 24317843Sralph endhostent(); 24417843Sralph } else 24517843Sralph strncpy(remotehost, inet_ntoa(sin->sin_addr), 24617843Sralph sizeof (remotehost)); 24737931Sbostic wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); 24817843Sralph if (wtmp >= 0) { 24917843Sralph /* hack, but must be unique and no tty line */ 25017843Sralph sprintf(line, "uucp%.4d", getpid()); 25117843Sralph SCPYN(utmp.ut_line, line); 25217843Sralph SCPYN(utmp.ut_name, pw->pw_name); 25317843Sralph SCPYN(utmp.ut_host, remotehost); 25423682Sbloom time(&utmp.ut_time); 25517843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 25617843Sralph (void) close(wtmp); 25717843Sralph } 25837931Sbostic if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) { 25917843Sralph struct lastlog ll; 26017843Sralph 26117843Sralph time(&ll.ll_time); 26217843Sralph lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); 26317843Sralph strcpy(line, remotehost); 26417843Sralph SCPYN(ll.ll_line, line); 26517843Sralph SCPYN(ll.ll_host, remotehost); 26617843Sralph (void) write(f, (char *) &ll, sizeof ll); 26717843Sralph (void) close(f); 26817843Sralph } 26917843Sralph } 270