117144Sralph #ifndef lint 2*18625Sralph static char sccsid[] = "@(#)uucpd.c 5.3 (Berkeley) 04/10/85"; 317144Sralph #endif 417144Sralph 517144Sralph /* 617843Sralph * 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" 1117843Sralph #include <signal.h> 1217144Sralph #include <errno.h> 1317144Sralph #include <sys/socket.h> 1417843Sralph #include <sys/ioctl.h> 1517144Sralph #include <netinet/in.h> 1617843Sralph #include <netdb.h> 1717843Sralph #include <sys/wait.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 2717144Sralph main(argc, argv) 2817843Sralph int argc; 2917843Sralph char **argv; 3017144Sralph { 31*18625Sralph #ifndef BSDINETD 3217843Sralph register int s, tcp_socket; 3317843Sralph struct servent *sp; 34*18625Sralph #endif !BSDINETD 3517843Sralph extern int errno; 3617843Sralph int dologout(); 3717144Sralph 3817843Sralph #ifdef BSDINETD 3917843Sralph close(1); close(2); 4017843Sralph dup(0); dup(0); 4117843Sralph hisaddrlen = sizeof (hisctladdr); 4217843Sralph if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { 4317144Sralph fprintf(stderr, "%s: ", argv[0]); 4417144Sralph perror("getpeername"); 4517144Sralph _exit(1); 4617144Sralph } 4717843Sralph if (fork() == 0) 4817843Sralph doit(&hisctladdr); 4917843Sralph dologout(); 5017843Sralph exit(1); 5117843Sralph #else !BSDINETD 5217843Sralph sp = getservbyname("uucp", "tcp"); 5317843Sralph if (sp == NULL){ 5417843Sralph perror("uucpd: getservbyname"); 5517843Sralph exit(1); 5617843Sralph } 5717843Sralph if ((s=open("/dev/tty", 2)) >= 0){ 5817843Sralph ioctl(s, TIOCNOTTY, (char *)0); 5917843Sralph close(s); 6017843Sralph } 6117144Sralph 6217843Sralph bzero((char *)&myctladdr, sizeof (myctladdr)); 6317843Sralph tcp_socket = socket(AF_INET, SOCK_STREAM, 0, 0); 6417843Sralph if ( tcp_socket<0 ) { 6517843Sralph perror("uucpd: socket"); 6617843Sralph exit(1); 6717843Sralph } 6817843Sralph myctladdr.sin_port = sp->s_port; 6917843Sralph if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr), 0) < 0) { 7017843Sralph perror("uucpd: bind"); 7117843Sralph exit(1); 7217843Sralph } 7317843Sralph signal(SIGCHLD, dologout); 7417843Sralph listen(tcp_socket, 5); /* 5's as good as any */ 7517843Sralph 7617843Sralph for(;;) { 7717843Sralph s = accept(tcp_socket, &hisctladdr, &hisaddrlen); 7817843Sralph if (s < 0){ 7917843Sralph if (errno == EINTR) 8017843Sralph continue; 8117843Sralph perror("uucpd: accept"); 8217843Sralph exit(1); 8317843Sralph } 8417843Sralph if (fork()== 0) { 8517843Sralph close(0); close(1); close(2); 8617843Sralph dup(s); dup(s); dup(s); 8717843Sralph close(tcp_socket);close(s); 8817843Sralph doit(&hisctladdr); 8917843Sralph exit(1); 9017843Sralph } 9117843Sralph close(s); 9217843Sralph } 9317843Sralph #endif 9417144Sralph } 9517843Sralph 9617843Sralph doit(sinp) 9717843Sralph struct sockaddr_in *sinp; 9817843Sralph { 9917843Sralph char user[64]; 10017843Sralph char passwd[64]; 10117843Sralph char *xpasswd, *crypt(); 10217843Sralph struct passwd *pw, *getpwnam(); 10317843Sralph 10417843Sralph alarm(60); 105*18625Sralph printf("login: "); fflush(stdout); 10617843Sralph if (readline(user, sizeof user) < 0) { 10717843Sralph fprintf(stderr, "user read\n"); 10817843Sralph return; 10917843Sralph } 11017843Sralph /* truncate username to 8 characters */ 11117843Sralph user[8] = '\0'; 11217843Sralph pw = getpwnam(user); 11317843Sralph if (pw == NULL) { 11417843Sralph fprintf(stderr, "user unknown\n"); 11517843Sralph return; 11617843Sralph } 11717843Sralph if (strcmp(pw->pw_shell, UUCICO)) { 11817843Sralph fprintf(stderr, "Login incorrect."); 11917843Sralph return; 12017843Sralph } 12117843Sralph if (pw->pw_passwd && *pw->pw_passwd != '\0') { 122*18625Sralph printf("Password: "); fflush(stdout); 12317843Sralph if (readline(passwd, sizeof passwd) < 0) { 12417843Sralph fprintf(stderr, "passwd read\n"); 12517843Sralph return; 12617843Sralph } 12717843Sralph xpasswd = crypt(passwd, pw->pw_passwd); 12817843Sralph if (strcmp(xpasswd, pw->pw_passwd)) { 12917843Sralph fprintf(stderr, "Login incorrect."); 13017843Sralph return; 13117843Sralph } 13217843Sralph } 13317843Sralph alarm(0); 13417843Sralph dologin(pw, sinp); 13517843Sralph setegid(pw->pw_gid); 13617843Sralph initgroups(pw->pw_name, pw->pw_gid); 13717843Sralph chdir(pw->pw_dir); 13817843Sralph seteuid(pw->pw_uid); 13917843Sralph execl(UUCICO, "uucico", (char *)0); 14017843Sralph perror("uucico server: execl"); 14117843Sralph } 14217843Sralph 14317843Sralph readline(p, n) 144*18625Sralph register char *p; 145*18625Sralph register int n; 14617843Sralph { 14717843Sralph char c; 14817843Sralph 14917843Sralph while (n-- > 0) { 15017843Sralph if (read(0, &c, 1) <= 0) 15117843Sralph return(-1); 15217843Sralph c &= 0177; 15317843Sralph if (c == '\n' || c == '\r') { 15417843Sralph *p = '\0'; 15517843Sralph return(0); 15617843Sralph } 15717843Sralph *p++ = c; 15817843Sralph } 15917843Sralph return(-1); 16017843Sralph } 16117843Sralph 16217843Sralph #include <utmp.h> 16317843Sralph #include <fcntl.h> 16417843Sralph 16517843Sralph #define SCPYN(a, b) strncpy(a, b, sizeof (a)) 16617843Sralph 16717843Sralph struct utmp utmp; 16817843Sralph 16917843Sralph dologout() 17017843Sralph { 17117843Sralph union wait status; 17217843Sralph int pid, wtmp; 17317843Sralph 17417843Sralph #ifdef BSDINETD 17517843Sralph while ((pid=wait(&status)) > 0 ) { 17617843Sralph #else !BSDINETD 17717843Sralph while ((pid=wait3(&status,WNOHANG,0)) > 0 ) { 17817843Sralph #endif !BSDINETD 17917843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 18017843Sralph if (wtmp >= 0) { 18117843Sralph sprintf(utmp.ut_line, "uucp%.4d", pid); 18217843Sralph SCPYN(utmp.ut_name, ""); 18317843Sralph SCPYN(utmp.ut_host, ""); 18417843Sralph utmp.ut_time = time(0); 18517843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 18617843Sralph (void) close(wtmp); 18717843Sralph } 18817843Sralph } 18917843Sralph } 19017843Sralph 19117843Sralph /* 19217843Sralph * Record login in wtmp file. 19317843Sralph */ 19417843Sralph dologin(pw, sin) 19517843Sralph struct passwd *pw; 19617843Sralph struct sockaddr_in *sin; 19717843Sralph { 19817843Sralph char line[32]; 19917843Sralph char remotehost[32]; 20017843Sralph int wtmp, f; 20117843Sralph struct hostent *hp = gethostbyaddr(&sin->sin_addr, 20217843Sralph sizeof (struct in_addr), AF_INET); 20317843Sralph 20417843Sralph if (hp) { 20517843Sralph strncpy(remotehost, hp->h_name, sizeof (remotehost)); 20617843Sralph endhostent(); 20717843Sralph } else 20817843Sralph strncpy(remotehost, inet_ntoa(sin->sin_addr), 20917843Sralph sizeof (remotehost)); 21017843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 21117843Sralph if (wtmp >= 0) { 21217843Sralph /* hack, but must be unique and no tty line */ 21317843Sralph sprintf(line, "uucp%.4d", getpid()); 21417843Sralph SCPYN(utmp.ut_line, line); 21517843Sralph SCPYN(utmp.ut_name, pw->pw_name); 21617843Sralph SCPYN(utmp.ut_host, remotehost); 21717843Sralph utmp.ut_time = time(0); 21817843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 21917843Sralph (void) close(wtmp); 22017843Sralph } 22117843Sralph if ((f = open(lastlog, 2)) >= 0) { 22217843Sralph struct lastlog ll; 22317843Sralph 22417843Sralph time(&ll.ll_time); 22517843Sralph lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); 22617843Sralph strcpy(line, remotehost); 22717843Sralph SCPYN(ll.ll_line, line); 22817843Sralph SCPYN(ll.ll_host, remotehost); 22917843Sralph (void) write(f, (char *) &ll, sizeof ll); 23017843Sralph (void) close(f); 23117843Sralph } 23217843Sralph } 233