Patch from piero@strider.st.dsi.unimi.it to quiet compiler warning.
[unix-history] / libexec / uucpd / uucpd.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1985 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Adams.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#ifndef lint
38char copyright[] =
39"@(#) Copyright (c) 1985 The Regents of the University of California.\n\
40 All rights reserved.\n";
41#endif /* not lint */
42
43#ifndef lint
44static char sccsid[] = "@(#)uucpd.c 5.10 (Berkeley) 2/26/91";
45#endif /* not lint */
46
47/*
48 * 4.2BSD TCP/IP server for uucico
49 * uucico's TCP channel causes this server to be run at the remote end.
50 */
51
52#include <sys/types.h>
53#include <sys/wait.h>
54#include <sys/ioctl.h>
55#include <sys/socket.h>
56#include <netinet/in.h>
57#include <arpa/inet.h>
58#include <netdb.h>
59#include <signal.h>
60#include <fcntl.h>
61#include <time.h>
62#include <pwd.h>
63#include <unistd.h>
64#include <errno.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
68#include "pathnames.h"
69
70struct sockaddr_in hisctladdr;
71int hisaddrlen = sizeof hisctladdr;
72struct sockaddr_in myctladdr;
73int mypid;
74
75char Username[64];
76char *nenv[] = {
77 Username,
78 NULL,
79};
80extern char **environ;
81
82main(argc, argv)
83int argc;
84char **argv;
85{
86#ifndef BSDINETD
87 register int s, tcp_socket;
88 struct servent *sp;
89#endif !BSDINETD
90 extern int errno;
91 int dologout();
92
93 environ = nenv;
94#ifdef BSDINETD
95 close(1); close(2);
96 dup(0); dup(0);
97 hisaddrlen = sizeof (hisctladdr);
98 if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) {
99 fprintf(stderr, "%s: ", argv[0]);
100 perror("getpeername");
101 _exit(1);
102 }
103 if (fork() == 0)
104 doit(&hisctladdr);
105 dologout();
106 exit(1);
107#else !BSDINETD
108 sp = getservbyname("uucp", "tcp");
109 if (sp == NULL){
110 perror("uucpd: getservbyname");
111 exit(1);
112 }
113 if (fork())
114 exit(0);
115 if ((s=open(_PATH_TTY, 2)) >= 0){
116 ioctl(s, TIOCNOTTY, (char *)0);
117 close(s);
118 }
119
120 bzero((char *)&myctladdr, sizeof (myctladdr));
121 myctladdr.sin_family = AF_INET;
122 myctladdr.sin_port = sp->s_port;
123#ifdef BSD4_2
124 tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
125 if (tcp_socket < 0) {
126 perror("uucpd: socket");
127 exit(1);
128 }
129 if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) {
130 perror("uucpd: bind");
131 exit(1);
132 }
133 listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */
134 signal(SIGCHLD, dologout);
135
136 for(;;) {
137 s = accept(tcp_socket, &hisctladdr, &hisaddrlen);
138 if (s < 0){
139 if (errno == EINTR)
140 continue;
141 perror("uucpd: accept");
142 exit(1);
143 }
144 if (fork() == 0) {
145 close(0); close(1); close(2);
146 dup(s); dup(s); dup(s);
147 close(tcp_socket); close(s);
148 doit(&hisctladdr);
149 exit(1);
150 }
151 close(s);
152 }
153#endif BSD4_2
154
155#endif !BSDINETD
156}
157
158doit(sinp)
159struct sockaddr_in *sinp;
160{
161 char user[64], passwd[64];
162 char *xpasswd, *crypt();
163 struct passwd *pw, *getpwnam();
164
165 alarm(60);
166 printf("login: "); fflush(stdout);
167 if (readline(user, sizeof user) < 0) {
168 fprintf(stderr, "user read\n");
169 return;
170 }
171 /* truncate username to 8 characters */
172 user[8] = '\0';
173 pw = getpwnam(user);
174 if (pw == NULL) {
175 fprintf(stderr, "user unknown\n");
176 return;
177 }
178 if (strcmp(pw->pw_shell, _PATH_UUCICO)) {
179 fprintf(stderr, "Login incorrect.");
180 return;
181 }
182 if (pw->pw_passwd && *pw->pw_passwd != '\0') {
183 printf("Password: "); fflush(stdout);
184 if (readline(passwd, sizeof passwd) < 0) {
185 fprintf(stderr, "passwd read\n");
186 return;
187 }
188 xpasswd = crypt(passwd, pw->pw_passwd);
189 if (strcmp(xpasswd, pw->pw_passwd)) {
190 fprintf(stderr, "Login incorrect.");
191 return;
192 }
193 }
194 alarm(0);
195 sprintf(Username, "USER=%s", user);
196 dologin(pw, sinp);
197 setgid(pw->pw_gid);
198#ifdef BSD4_2
199 initgroups(pw->pw_name, pw->pw_gid);
200#endif BSD4_2
201 chdir(pw->pw_dir);
202 setuid(pw->pw_uid);
203#ifdef BSD4_2
204 execl(UUCICO, "uucico", (char *)0);
205#endif BSD4_2
206 perror("uucico server: execl");
207}
208
209readline(p, n)
210register char *p;
211register int n;
212{
213 char c;
214
215 while (n-- > 0) {
216 if (read(0, &c, 1) <= 0)
217 return(-1);
218 c &= 0177;
219 if (c == '\n' || c == '\r') {
220 *p = '\0';
221 return(0);
222 }
223 *p++ = c;
224 }
225 return(-1);
226}
227
228#include <utmp.h>
229#ifdef BSD4_2
230#include <fcntl.h>
231#endif BSD4_2
232
233#define SCPYN(a, b) strncpy(a, b, sizeof (a))
234
235struct utmp utmp;
236
237dologout()
238{
239 union wait status;
240 int pid, wtmp;
241
242#ifdef BSDINETD
243 while ((pid=wait((int *)&status)) > 0) {
244#else !BSDINETD
245 while ((pid=wait3((int *)&status,WNOHANG,0)) > 0) {
246#endif !BSDINETD
247 wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
248 if (wtmp >= 0) {
249 sprintf(utmp.ut_line, "uucp%.4d", pid);
250 SCPYN(utmp.ut_name, "");
251 SCPYN(utmp.ut_host, "");
252 (void) time(&utmp.ut_time);
253 (void) write(wtmp, (char *)&utmp, sizeof (utmp));
254 (void) close(wtmp);
255 }
256 }
257}
258
259/*
260 * Record login in wtmp file.
261 */
262dologin(pw, sin)
263struct passwd *pw;
264struct sockaddr_in *sin;
265{
266 char line[32];
267 char remotehost[32];
268 int wtmp, f;
269 struct hostent *hp = gethostbyaddr((char *)&sin->sin_addr,
270 sizeof (struct in_addr), AF_INET);
271
272 if (hp) {
273 strncpy(remotehost, hp->h_name, sizeof (remotehost));
274 endhostent();
275 } else
276 strncpy(remotehost, inet_ntoa(sin->sin_addr),
277 sizeof (remotehost));
278 wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND);
279 if (wtmp >= 0) {
280 /* hack, but must be unique and no tty line */
281 sprintf(line, "uucp%.4d", getpid());
282 SCPYN(utmp.ut_line, line);
283 SCPYN(utmp.ut_name, pw->pw_name);
284 SCPYN(utmp.ut_host, remotehost);
285 time(&utmp.ut_time);
286 (void) write(wtmp, (char *)&utmp, sizeof (utmp));
287 (void) close(wtmp);
288 }
289 if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
290 struct lastlog ll;
291
292 time(&ll.ll_time);
293 lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0);
294 strcpy(line, remotehost);
295 SCPYN(ll.ll_line, line);
296 SCPYN(ll.ll_host, remotehost);
297 (void) write(f, (char *) &ll, sizeof ll);
298 (void) close(f);
299 }
300}