xref: /csrg-svn/libexec/uucpd/uucpd.c (revision 18625)
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