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 * 836093Sbostic * Redistribution and use in source and binary forms are permitted 936093Sbostic * provided that the above copyright notice and this paragraph are 1036093Sbostic * duplicated in all such forms and that any documentation, 1136093Sbostic * advertising materials, and other materials related to such 1236093Sbostic * distribution and use acknowledge that the software was developed 1336093Sbostic * by the University of California, Berkeley. The name of the 1436093Sbostic * University may not be used to endorse or promote products derived 1536093Sbostic * from this software without specific prior written permission. 1636093Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1736093Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1836093Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1936093Sbostic */ 2036093Sbostic 2117144Sralph #ifndef lint 2236093Sbostic char copyright[] = 2336093Sbostic "@(#) Copyright (c) 1985 The Regents of the University of California.\n\ 2436093Sbostic All rights reserved.\n"; 2536093Sbostic #endif /* not lint */ 2617144Sralph 2736093Sbostic #ifndef lint 28*37931Sbostic static char sccsid[] = "@(#)uucpd.c 5.7 (Berkeley) 05/11/89"; 2936093Sbostic #endif /* not lint */ 3036093Sbostic 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> 45*37931Sbostic #include "pathnames.h" 4617144Sralph 4717843Sralph struct sockaddr_in hisctladdr; 4817843Sralph int hisaddrlen = sizeof hisctladdr; 4917843Sralph struct sockaddr_in myctladdr; 5017843Sralph int mypid; 5117144Sralph 5223682Sbloom char Username[64]; 5323682Sbloom char *nenv[] = { 5423682Sbloom Username, 5523682Sbloom NULL, 5623682Sbloom }; 5723682Sbloom extern char **environ; 5823682Sbloom 5917144Sralph main(argc, argv) 6017843Sralph int argc; 6117843Sralph char **argv; 6217144Sralph { 6318625Sralph #ifndef BSDINETD 6417843Sralph register int s, tcp_socket; 6517843Sralph struct servent *sp; 6618625Sralph #endif !BSDINETD 6717843Sralph extern int errno; 6817843Sralph int dologout(); 6917144Sralph 7023682Sbloom environ = nenv; 7117843Sralph #ifdef BSDINETD 7217843Sralph close(1); close(2); 7317843Sralph dup(0); dup(0); 7417843Sralph hisaddrlen = sizeof (hisctladdr); 7517843Sralph if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { 7617144Sralph fprintf(stderr, "%s: ", argv[0]); 7717144Sralph perror("getpeername"); 7817144Sralph _exit(1); 7917144Sralph } 8017843Sralph if (fork() == 0) 8117843Sralph doit(&hisctladdr); 8217843Sralph dologout(); 8317843Sralph exit(1); 8417843Sralph #else !BSDINETD 8517843Sralph sp = getservbyname("uucp", "tcp"); 8617843Sralph if (sp == NULL){ 8717843Sralph perror("uucpd: getservbyname"); 8817843Sralph exit(1); 8917843Sralph } 9023682Sbloom if (fork()) 9123682Sbloom exit(0); 92*37931Sbostic if ((s=open(_PATH_TTY, 2)) >= 0){ 9317843Sralph ioctl(s, TIOCNOTTY, (char *)0); 9417843Sralph close(s); 9517843Sralph } 9617144Sralph 9717843Sralph bzero((char *)&myctladdr, sizeof (myctladdr)); 9823682Sbloom myctladdr.sin_family = AF_INET; 9923682Sbloom myctladdr.sin_port = sp->s_port; 10023682Sbloom #ifdef BSD4_2 10123682Sbloom tcp_socket = socket(AF_INET, SOCK_STREAM, 0); 10223682Sbloom if (tcp_socket < 0) { 10317843Sralph perror("uucpd: socket"); 10417843Sralph exit(1); 10517843Sralph } 10623682Sbloom if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { 10717843Sralph perror("uucpd: bind"); 10817843Sralph exit(1); 10917843Sralph } 11023682Sbloom listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ 11117843Sralph signal(SIGCHLD, dologout); 11217843Sralph 11317843Sralph for(;;) { 11417843Sralph s = accept(tcp_socket, &hisctladdr, &hisaddrlen); 11517843Sralph if (s < 0){ 11623682Sbloom if (errno == EINTR) 11717843Sralph continue; 11817843Sralph perror("uucpd: accept"); 11917843Sralph exit(1); 12017843Sralph } 12123682Sbloom if (fork() == 0) { 12217843Sralph close(0); close(1); close(2); 12317843Sralph dup(s); dup(s); dup(s); 12423682Sbloom close(tcp_socket); close(s); 12517843Sralph doit(&hisctladdr); 12617843Sralph exit(1); 12717843Sralph } 12817843Sralph close(s); 12917843Sralph } 13023682Sbloom #endif BSD4_2 13123682Sbloom 13223682Sbloom #endif !BSDINETD 13317144Sralph } 13417843Sralph 13517843Sralph doit(sinp) 13617843Sralph struct sockaddr_in *sinp; 13717843Sralph { 13823682Sbloom char user[64], passwd[64]; 13917843Sralph char *xpasswd, *crypt(); 14017843Sralph struct passwd *pw, *getpwnam(); 14117843Sralph 14217843Sralph alarm(60); 14318625Sralph printf("login: "); fflush(stdout); 14417843Sralph if (readline(user, sizeof user) < 0) { 14517843Sralph fprintf(stderr, "user read\n"); 14617843Sralph return; 14717843Sralph } 14817843Sralph /* truncate username to 8 characters */ 14917843Sralph user[8] = '\0'; 15017843Sralph pw = getpwnam(user); 15117843Sralph if (pw == NULL) { 15217843Sralph fprintf(stderr, "user unknown\n"); 15317843Sralph return; 15417843Sralph } 15517843Sralph if (strcmp(pw->pw_shell, UUCICO)) { 15617843Sralph fprintf(stderr, "Login incorrect."); 15717843Sralph return; 15817843Sralph } 15917843Sralph if (pw->pw_passwd && *pw->pw_passwd != '\0') { 16018625Sralph printf("Password: "); fflush(stdout); 16117843Sralph if (readline(passwd, sizeof passwd) < 0) { 16217843Sralph fprintf(stderr, "passwd read\n"); 16317843Sralph return; 16417843Sralph } 16517843Sralph xpasswd = crypt(passwd, pw->pw_passwd); 16617843Sralph if (strcmp(xpasswd, pw->pw_passwd)) { 16717843Sralph fprintf(stderr, "Login incorrect."); 16817843Sralph return; 16917843Sralph } 17017843Sralph } 17117843Sralph alarm(0); 17223682Sbloom sprintf(Username, "USER=%s", user); 17317843Sralph dologin(pw, sinp); 17423682Sbloom setgid(pw->pw_gid); 17523682Sbloom #ifdef BSD4_2 17617843Sralph initgroups(pw->pw_name, pw->pw_gid); 17723682Sbloom #endif BSD4_2 17817843Sralph chdir(pw->pw_dir); 17923682Sbloom setuid(pw->pw_uid); 18023682Sbloom #ifdef BSD4_2 18117843Sralph execl(UUCICO, "uucico", (char *)0); 18223682Sbloom #endif BSD4_2 18317843Sralph perror("uucico server: execl"); 18417843Sralph } 18517843Sralph 18617843Sralph readline(p, n) 18718625Sralph register char *p; 18818625Sralph register int n; 18917843Sralph { 19017843Sralph char c; 19117843Sralph 19217843Sralph while (n-- > 0) { 19317843Sralph if (read(0, &c, 1) <= 0) 19417843Sralph return(-1); 19517843Sralph c &= 0177; 19617843Sralph if (c == '\n' || c == '\r') { 19717843Sralph *p = '\0'; 19817843Sralph return(0); 19917843Sralph } 20017843Sralph *p++ = c; 20117843Sralph } 20217843Sralph return(-1); 20317843Sralph } 20417843Sralph 20517843Sralph #include <utmp.h> 20623682Sbloom #ifdef BSD4_2 20717843Sralph #include <fcntl.h> 20823682Sbloom #endif BSD4_2 20917843Sralph 21017843Sralph #define SCPYN(a, b) strncpy(a, b, sizeof (a)) 21117843Sralph 21217843Sralph struct utmp utmp; 21317843Sralph 21417843Sralph dologout() 21517843Sralph { 21617843Sralph union wait status; 21717843Sralph int pid, wtmp; 21817843Sralph 21917843Sralph #ifdef BSDINETD 22023682Sbloom while ((pid=wait(&status)) > 0) { 22117843Sralph #else !BSDINETD 22223682Sbloom while ((pid=wait3(&status,WNOHANG,0)) > 0) { 22317843Sralph #endif !BSDINETD 224*37931Sbostic wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); 22517843Sralph if (wtmp >= 0) { 22617843Sralph sprintf(utmp.ut_line, "uucp%.4d", pid); 22717843Sralph SCPYN(utmp.ut_name, ""); 22817843Sralph SCPYN(utmp.ut_host, ""); 22923682Sbloom (void) time(&utmp.ut_time); 23017843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 23117843Sralph (void) close(wtmp); 23217843Sralph } 23317843Sralph } 23417843Sralph } 23517843Sralph 23617843Sralph /* 23717843Sralph * Record login in wtmp file. 23817843Sralph */ 23917843Sralph dologin(pw, sin) 24017843Sralph struct passwd *pw; 24117843Sralph struct sockaddr_in *sin; 24217843Sralph { 24317843Sralph char line[32]; 24417843Sralph char remotehost[32]; 24517843Sralph int wtmp, f; 24617843Sralph struct hostent *hp = gethostbyaddr(&sin->sin_addr, 24717843Sralph sizeof (struct in_addr), AF_INET); 24817843Sralph 24917843Sralph if (hp) { 25017843Sralph strncpy(remotehost, hp->h_name, sizeof (remotehost)); 25117843Sralph endhostent(); 25217843Sralph } else 25317843Sralph strncpy(remotehost, inet_ntoa(sin->sin_addr), 25417843Sralph sizeof (remotehost)); 255*37931Sbostic wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); 25617843Sralph if (wtmp >= 0) { 25717843Sralph /* hack, but must be unique and no tty line */ 25817843Sralph sprintf(line, "uucp%.4d", getpid()); 25917843Sralph SCPYN(utmp.ut_line, line); 26017843Sralph SCPYN(utmp.ut_name, pw->pw_name); 26117843Sralph SCPYN(utmp.ut_host, remotehost); 26223682Sbloom time(&utmp.ut_time); 26317843Sralph (void) write(wtmp, (char *)&utmp, sizeof (utmp)); 26417843Sralph (void) close(wtmp); 26517843Sralph } 266*37931Sbostic if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) { 26717843Sralph struct lastlog ll; 26817843Sralph 26917843Sralph time(&ll.ll_time); 27017843Sralph lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); 27117843Sralph strcpy(line, remotehost); 27217843Sralph SCPYN(ll.ll_line, line); 27317843Sralph SCPYN(ll.ll_host, remotehost); 27417843Sralph (void) write(f, (char *) &ll, sizeof ll); 27517843Sralph (void) close(f); 27617843Sralph } 27717843Sralph } 278