1*36093Sbostic /* 2*36093Sbostic * Copyright (c) 1985 The Regents of the University of California. 3*36093Sbostic * All rights reserved. 4*36093Sbostic * 5*36093Sbostic * This code is derived from software contributed to Berkeley by 6*36093Sbostic * Rick Adams. 7*36093Sbostic * 8*36093Sbostic * Redistribution and use in source and binary forms are permitted 9*36093Sbostic * provided that the above copyright notice and this paragraph are 10*36093Sbostic * duplicated in all such forms and that any documentation, 11*36093Sbostic * advertising materials, and other materials related to such 12*36093Sbostic * distribution and use acknowledge that the software was developed 13*36093Sbostic * by the University of California, Berkeley. The name of the 14*36093Sbostic * University may not be used to endorse or promote products derived 15*36093Sbostic * from this software without specific prior written permission. 16*36093Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17*36093Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18*36093Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19*36093Sbostic */ 20*36093Sbostic 2117144Sralph #ifndef lint 22*36093Sbostic char copyright[] = 23*36093Sbostic "@(#) Copyright (c) 1985 The Regents of the University of California.\n\ 24*36093Sbostic All rights reserved.\n"; 25*36093Sbostic #endif /* not lint */ 2617144Sralph 27*36093Sbostic #ifndef lint 28*36093Sbostic static char sccsid[] = "@(#)uucpd.c 5.6 (Berkeley) 10/24/88"; 29*36093Sbostic #endif /* not lint */ 30*36093Sbostic 3117144Sralph /* 3233974Srick * 4.2BSD TCP/IP server for uucico 3317843Sralph * uucico's TCP channel causes this server to be run at the remote end. 3417144Sralph */ 3517144Sralph 3617843Sralph #include "uucp.h" 3723682Sbloom #include <netdb.h> 3817843Sralph #include <signal.h> 3917144Sralph #include <errno.h> 4017144Sralph #include <sys/socket.h> 4117144Sralph #include <netinet/in.h> 4217843Sralph #include <sys/wait.h> 4323682Sbloom #include <sys/ioctl.h> 4417843Sralph #include <pwd.h> 4517843Sralph #include <lastlog.h> 4617144Sralph 4717843Sralph char lastlog[] = "/usr/adm/lastlog"; 4817843Sralph struct sockaddr_in hisctladdr; 4917843Sralph int hisaddrlen = sizeof hisctladdr; 5017843Sralph struct sockaddr_in myctladdr; 5117843Sralph int mypid; 5217144Sralph 5323682Sbloom char Username[64]; 5423682Sbloom char *nenv[] = { 5523682Sbloom Username, 5623682Sbloom NULL, 5723682Sbloom }; 5823682Sbloom extern char **environ; 5923682Sbloom 6017144Sralph main(argc, argv) 6117843Sralph int argc; 6217843Sralph char **argv; 6317144Sralph { 6418625Sralph #ifndef BSDINETD 6517843Sralph register int s, tcp_socket; 6617843Sralph struct servent *sp; 6718625Sralph #endif !BSDINETD 6817843Sralph extern int errno; 6917843Sralph int dologout(); 7017144Sralph 7123682Sbloom environ = nenv; 7217843Sralph #ifdef BSDINETD 7317843Sralph close(1); close(2); 7417843Sralph dup(0); dup(0); 7517843Sralph hisaddrlen = sizeof (hisctladdr); 7617843Sralph if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { 7717144Sralph fprintf(stderr, "%s: ", argv[0]); 7817144Sralph perror("getpeername"); 7917144Sralph _exit(1); 8017144Sralph } 8117843Sralph if (fork() == 0) 8217843Sralph doit(&hisctladdr); 8317843Sralph dologout(); 8417843Sralph exit(1); 8517843Sralph #else !BSDINETD 8617843Sralph sp = getservbyname("uucp", "tcp"); 8717843Sralph if (sp == NULL){ 8817843Sralph perror("uucpd: getservbyname"); 8917843Sralph exit(1); 9017843Sralph } 9123682Sbloom if (fork()) 9223682Sbloom exit(0); 9317843Sralph if ((s=open("/dev/tty", 2)) >= 0){ 9417843Sralph ioctl(s, TIOCNOTTY, (char *)0); 9517843Sralph close(s); 9617843Sralph } 9717144Sralph 9817843Sralph bzero((char *)&myctladdr, sizeof (myctladdr)); 9923682Sbloom myctladdr.sin_family = AF_INET; 10023682Sbloom myctladdr.sin_port = sp->s_port; 10123682Sbloom #ifdef BSD4_2 10223682Sbloom tcp_socket = socket(AF_INET, SOCK_STREAM, 0); 10323682Sbloom if (tcp_socket < 0) { 10417843Sralph perror("uucpd: socket"); 10517843Sralph exit(1); 10617843Sralph } 10723682Sbloom if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { 10817843Sralph perror("uucpd: bind"); 10917843Sralph exit(1); 11017843Sralph } 11123682Sbloom listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ 11217843Sralph signal(SIGCHLD, dologout); 11317843Sralph 11417843Sralph for(;;) { 11517843Sralph s = accept(tcp_socket, &hisctladdr, &hisaddrlen); 11617843Sralph if (s < 0){ 11723682Sbloom if (errno == EINTR) 11817843Sralph continue; 11917843Sralph perror("uucpd: accept"); 12017843Sralph exit(1); 12117843Sralph } 12223682Sbloom if (fork() == 0) { 12317843Sralph close(0); close(1); close(2); 12417843Sralph dup(s); dup(s); dup(s); 12523682Sbloom close(tcp_socket); close(s); 12617843Sralph doit(&hisctladdr); 12717843Sralph exit(1); 12817843Sralph } 12917843Sralph close(s); 13017843Sralph } 13123682Sbloom #endif BSD4_2 13223682Sbloom 13323682Sbloom #endif !BSDINETD 13417144Sralph } 13517843Sralph 13617843Sralph doit(sinp) 13717843Sralph struct sockaddr_in *sinp; 13817843Sralph { 13923682Sbloom char user[64], passwd[64]; 14017843Sralph char *xpasswd, *crypt(); 14117843Sralph struct passwd *pw, *getpwnam(); 14217843Sralph 14317843Sralph alarm(60); 14418625Sralph printf("login: "); fflush(stdout); 14517843Sralph if (readline(user, sizeof user) < 0) { 14617843Sralph fprintf(stderr, "user read\n"); 14717843Sralph return; 14817843Sralph } 14917843Sralph /* truncate username to 8 characters */ 15017843Sralph user[8] = '\0'; 15117843Sralph pw = getpwnam(user); 15217843Sralph if (pw == NULL) { 15317843Sralph fprintf(stderr, "user unknown\n"); 15417843Sralph return; 15517843Sralph } 15617843Sralph if (strcmp(pw->pw_shell, UUCICO)) { 15717843Sralph fprintf(stderr, "Login incorrect."); 15817843Sralph return; 15917843Sralph } 16017843Sralph if (pw->pw_passwd && *pw->pw_passwd != '\0') { 16118625Sralph printf("Password: "); fflush(stdout); 16217843Sralph if (readline(passwd, sizeof passwd) < 0) { 16317843Sralph fprintf(stderr, "passwd read\n"); 16417843Sralph return; 16517843Sralph } 16617843Sralph xpasswd = crypt(passwd, pw->pw_passwd); 16717843Sralph if (strcmp(xpasswd, pw->pw_passwd)) { 16817843Sralph fprintf(stderr, "Login incorrect."); 16917843Sralph return; 17017843Sralph } 17117843Sralph } 17217843Sralph alarm(0); 17323682Sbloom sprintf(Username, "USER=%s", user); 17417843Sralph dologin(pw, sinp); 17523682Sbloom setgid(pw->pw_gid); 17623682Sbloom #ifdef BSD4_2 17717843Sralph initgroups(pw->pw_name, pw->pw_gid); 17823682Sbloom #endif BSD4_2 17917843Sralph chdir(pw->pw_dir); 18023682Sbloom setuid(pw->pw_uid); 18123682Sbloom #ifdef BSD4_2 18217843Sralph execl(UUCICO, "uucico", (char *)0); 18323682Sbloom #endif BSD4_2 18417843Sralph perror("uucico server: execl"); 18517843Sralph } 18617843Sralph 18717843Sralph readline(p, n) 18818625Sralph register char *p; 18918625Sralph register int n; 19017843Sralph { 19117843Sralph char c; 19217843Sralph 19317843Sralph while (n-- > 0) { 19417843Sralph if (read(0, &c, 1) <= 0) 19517843Sralph return(-1); 19617843Sralph c &= 0177; 19717843Sralph if (c == '\n' || c == '\r') { 19817843Sralph *p = '\0'; 19917843Sralph return(0); 20017843Sralph } 20117843Sralph *p++ = c; 20217843Sralph } 20317843Sralph return(-1); 20417843Sralph } 20517843Sralph 20617843Sralph #include <utmp.h> 20723682Sbloom #ifdef BSD4_2 20817843Sralph #include <fcntl.h> 20923682Sbloom #endif BSD4_2 21017843Sralph 21117843Sralph #define SCPYN(a, b) strncpy(a, b, sizeof (a)) 21217843Sralph 21317843Sralph struct utmp utmp; 21417843Sralph 21517843Sralph dologout() 21617843Sralph { 21717843Sralph union wait status; 21817843Sralph int pid, wtmp; 21917843Sralph 22017843Sralph #ifdef BSDINETD 22123682Sbloom while ((pid=wait(&status)) > 0) { 22217843Sralph #else !BSDINETD 22323682Sbloom while ((pid=wait3(&status,WNOHANG,0)) > 0) { 22417843Sralph #endif !BSDINETD 22517843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 22617843Sralph if (wtmp >= 0) { 22717843Sralph sprintf(utmp.ut_line, "uucp%.4d", pid); 22817843Sralph SCPYN(utmp.ut_name, ""); 22917843Sralph SCPYN(utmp.ut_host, ""); 23023682Sbloom (void) time(&utmp.ut_time); 23117843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 23217843Sralph (void) close(wtmp); 23317843Sralph } 23417843Sralph } 23517843Sralph } 23617843Sralph 23717843Sralph /* 23817843Sralph * Record login in wtmp file. 23917843Sralph */ 24017843Sralph dologin(pw, sin) 24117843Sralph struct passwd *pw; 24217843Sralph struct sockaddr_in *sin; 24317843Sralph { 24417843Sralph char line[32]; 24517843Sralph char remotehost[32]; 24617843Sralph int wtmp, f; 24717843Sralph struct hostent *hp = gethostbyaddr(&sin->sin_addr, 24817843Sralph sizeof (struct in_addr), AF_INET); 24917843Sralph 25017843Sralph if (hp) { 25117843Sralph strncpy(remotehost, hp->h_name, sizeof (remotehost)); 25217843Sralph endhostent(); 25317843Sralph } else 25417843Sralph strncpy(remotehost, inet_ntoa(sin->sin_addr), 25517843Sralph sizeof (remotehost)); 25617843Sralph wtmp = open("/usr/adm/wtmp", O_WRONLY|O_APPEND); 25717843Sralph if (wtmp >= 0) { 25817843Sralph /* hack, but must be unique and no tty line */ 25917843Sralph sprintf(line, "uucp%.4d", getpid()); 26017843Sralph SCPYN(utmp.ut_line, line); 26117843Sralph SCPYN(utmp.ut_name, pw->pw_name); 26217843Sralph SCPYN(utmp.ut_host, remotehost); 26323682Sbloom time(&utmp.ut_time); 26417843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 26517843Sralph (void) close(wtmp); 26617843Sralph } 26717843Sralph if ((f = open(lastlog, 2)) >= 0) { 26817843Sralph struct lastlog ll; 26917843Sralph 27017843Sralph time(&ll.ll_time); 27117843Sralph lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); 27217843Sralph strcpy(line, remotehost); 27317843Sralph SCPYN(ll.ll_line, line); 27417843Sralph SCPYN(ll.ll_host, remotehost); 27517843Sralph (void) write(f, (char *) &ll, sizeof ll); 27617843Sralph (void) close(f); 27717843Sralph } 27817843Sralph } 279