Commit | Line | Data |
---|---|---|
7249390d KB |
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 | * | |
836fe169 | 8 | * %sccs.include.redist.c% |
7249390d KB |
9 | */ |
10 | ||
11 | #ifndef lint | |
12 | char copyright[] = | |
13 | "@(#) Copyright (c) 1985 The Regents of the University of California.\n\ | |
14 | All rights reserved.\n"; | |
15 | #endif /* not lint */ | |
16 | ||
cd56d176 | 17 | #ifndef lint |
836fe169 | 18 | static char sccsid[] = "@(#)uucpd.c 5.9 (Berkeley) %G%"; |
7249390d | 19 | #endif /* not lint */ |
cd56d176 RC |
20 | |
21 | /* | |
308f8b07 | 22 | * 4.2BSD TCP/IP server for uucico |
46b15d8a | 23 | * uucico's TCP channel causes this server to be run at the remote end. |
cd56d176 RC |
24 | */ |
25 | ||
17fed20b | 26 | #include <sys/types.h> |
cd56d176 | 27 | #include <sys/socket.h> |
46b15d8a | 28 | #include <sys/wait.h> |
79b62878 | 29 | #include <sys/ioctl.h> |
17fed20b KB |
30 | #include <sys/file.h> |
31 | #include <netinet/in.h> | |
32 | #include <netdb.h> | |
33 | #include <signal.h> | |
34 | #include <errno.h> | |
46b15d8a | 35 | #include <pwd.h> |
17fed20b | 36 | #include <stdio.h> |
c861cac9 | 37 | #include "pathnames.h" |
cd56d176 | 38 | |
46b15d8a RC |
39 | struct sockaddr_in hisctladdr; |
40 | int hisaddrlen = sizeof hisctladdr; | |
41 | struct sockaddr_in myctladdr; | |
42 | int mypid; | |
cd56d176 | 43 | |
79b62878 JB |
44 | char Username[64]; |
45 | char *nenv[] = { | |
46 | Username, | |
47 | NULL, | |
48 | }; | |
49 | extern char **environ; | |
50 | ||
cd56d176 | 51 | main(argc, argv) |
46b15d8a RC |
52 | int argc; |
53 | char **argv; | |
cd56d176 | 54 | { |
1a85e9d2 | 55 | #ifndef BSDINETD |
46b15d8a RC |
56 | register int s, tcp_socket; |
57 | struct servent *sp; | |
1a85e9d2 | 58 | #endif !BSDINETD |
46b15d8a RC |
59 | extern int errno; |
60 | int dologout(); | |
cd56d176 | 61 | |
79b62878 | 62 | environ = nenv; |
46b15d8a RC |
63 | #ifdef BSDINETD |
64 | close(1); close(2); | |
65 | dup(0); dup(0); | |
66 | hisaddrlen = sizeof (hisctladdr); | |
67 | if (getpeername(0, &hisctladdr, &hisaddrlen) < 0) { | |
cd56d176 RC |
68 | fprintf(stderr, "%s: ", argv[0]); |
69 | perror("getpeername"); | |
70 | _exit(1); | |
71 | } | |
46b15d8a RC |
72 | if (fork() == 0) |
73 | doit(&hisctladdr); | |
74 | dologout(); | |
cd56d176 | 75 | exit(1); |
46b15d8a RC |
76 | #else !BSDINETD |
77 | sp = getservbyname("uucp", "tcp"); | |
78 | if (sp == NULL){ | |
79 | perror("uucpd: getservbyname"); | |
80 | exit(1); | |
81 | } | |
79b62878 JB |
82 | if (fork()) |
83 | exit(0); | |
c861cac9 | 84 | if ((s=open(_PATH_TTY, 2)) >= 0){ |
46b15d8a RC |
85 | ioctl(s, TIOCNOTTY, (char *)0); |
86 | close(s); | |
87 | } | |
88 | ||
89 | bzero((char *)&myctladdr, sizeof (myctladdr)); | |
79b62878 JB |
90 | myctladdr.sin_family = AF_INET; |
91 | myctladdr.sin_port = sp->s_port; | |
92 | #ifdef BSD4_2 | |
93 | tcp_socket = socket(AF_INET, SOCK_STREAM, 0); | |
94 | if (tcp_socket < 0) { | |
46b15d8a RC |
95 | perror("uucpd: socket"); |
96 | exit(1); | |
97 | } | |
79b62878 | 98 | if (bind(tcp_socket, (char *)&myctladdr, sizeof (myctladdr)) < 0) { |
46b15d8a RC |
99 | perror("uucpd: bind"); |
100 | exit(1); | |
101 | } | |
79b62878 | 102 | listen(tcp_socket, 3); /* at most 3 simultaneuos uucp connections */ |
46b15d8a | 103 | signal(SIGCHLD, dologout); |
46b15d8a RC |
104 | |
105 | for(;;) { | |
106 | s = accept(tcp_socket, &hisctladdr, &hisaddrlen); | |
107 | if (s < 0){ | |
79b62878 | 108 | if (errno == EINTR) |
46b15d8a RC |
109 | continue; |
110 | perror("uucpd: accept"); | |
111 | exit(1); | |
112 | } | |
79b62878 | 113 | if (fork() == 0) { |
46b15d8a RC |
114 | close(0); close(1); close(2); |
115 | dup(s); dup(s); dup(s); | |
79b62878 | 116 | close(tcp_socket); close(s); |
46b15d8a RC |
117 | doit(&hisctladdr); |
118 | exit(1); | |
119 | } | |
120 | close(s); | |
121 | } | |
79b62878 JB |
122 | #endif BSD4_2 |
123 | ||
79b62878 | 124 | #endif !BSDINETD |
46b15d8a RC |
125 | } |
126 | ||
127 | doit(sinp) | |
128 | struct sockaddr_in *sinp; | |
129 | { | |
79b62878 | 130 | char user[64], passwd[64]; |
46b15d8a RC |
131 | char *xpasswd, *crypt(); |
132 | struct passwd *pw, *getpwnam(); | |
133 | ||
134 | alarm(60); | |
1a85e9d2 | 135 | printf("login: "); fflush(stdout); |
46b15d8a RC |
136 | if (readline(user, sizeof user) < 0) { |
137 | fprintf(stderr, "user read\n"); | |
138 | return; | |
139 | } | |
140 | /* truncate username to 8 characters */ | |
141 | user[8] = '\0'; | |
142 | pw = getpwnam(user); | |
143 | if (pw == NULL) { | |
144 | fprintf(stderr, "user unknown\n"); | |
145 | return; | |
146 | } | |
17fed20b | 147 | if (strcmp(pw->pw_shell, _PATH_UUCICO)) { |
46b15d8a RC |
148 | fprintf(stderr, "Login incorrect."); |
149 | return; | |
150 | } | |
151 | if (pw->pw_passwd && *pw->pw_passwd != '\0') { | |
1a85e9d2 | 152 | printf("Password: "); fflush(stdout); |
46b15d8a RC |
153 | if (readline(passwd, sizeof passwd) < 0) { |
154 | fprintf(stderr, "passwd read\n"); | |
155 | return; | |
156 | } | |
157 | xpasswd = crypt(passwd, pw->pw_passwd); | |
158 | if (strcmp(xpasswd, pw->pw_passwd)) { | |
159 | fprintf(stderr, "Login incorrect."); | |
160 | return; | |
161 | } | |
162 | } | |
163 | alarm(0); | |
79b62878 | 164 | sprintf(Username, "USER=%s", user); |
46b15d8a | 165 | dologin(pw, sinp); |
79b62878 JB |
166 | setgid(pw->pw_gid); |
167 | #ifdef BSD4_2 | |
46b15d8a | 168 | initgroups(pw->pw_name, pw->pw_gid); |
79b62878 | 169 | #endif BSD4_2 |
46b15d8a | 170 | chdir(pw->pw_dir); |
79b62878 JB |
171 | setuid(pw->pw_uid); |
172 | #ifdef BSD4_2 | |
46b15d8a | 173 | execl(UUCICO, "uucico", (char *)0); |
79b62878 | 174 | #endif BSD4_2 |
46b15d8a RC |
175 | perror("uucico server: execl"); |
176 | } | |
177 | ||
178 | readline(p, n) | |
1a85e9d2 RC |
179 | register char *p; |
180 | register int n; | |
46b15d8a RC |
181 | { |
182 | char c; | |
183 | ||
184 | while (n-- > 0) { | |
185 | if (read(0, &c, 1) <= 0) | |
186 | return(-1); | |
187 | c &= 0177; | |
188 | if (c == '\n' || c == '\r') { | |
189 | *p = '\0'; | |
190 | return(0); | |
191 | } | |
192 | *p++ = c; | |
193 | } | |
194 | return(-1); | |
195 | } | |
196 | ||
197 | #include <utmp.h> | |
79b62878 | 198 | #ifdef BSD4_2 |
46b15d8a | 199 | #include <fcntl.h> |
79b62878 JB |
200 | #endif BSD4_2 |
201 | ||
46b15d8a RC |
202 | #define SCPYN(a, b) strncpy(a, b, sizeof (a)) |
203 | ||
204 | struct utmp utmp; | |
205 | ||
206 | dologout() | |
207 | { | |
208 | union wait status; | |
209 | int pid, wtmp; | |
210 | ||
211 | #ifdef BSDINETD | |
79b62878 | 212 | while ((pid=wait(&status)) > 0) { |
46b15d8a | 213 | #else !BSDINETD |
79b62878 | 214 | while ((pid=wait3(&status,WNOHANG,0)) > 0) { |
46b15d8a | 215 | #endif !BSDINETD |
c861cac9 | 216 | wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); |
46b15d8a RC |
217 | if (wtmp >= 0) { |
218 | sprintf(utmp.ut_line, "uucp%.4d", pid); | |
219 | SCPYN(utmp.ut_name, ""); | |
220 | SCPYN(utmp.ut_host, ""); | |
79b62878 | 221 | (void) time(&utmp.ut_time); |
46b15d8a RC |
222 | (void) write(wtmp, (char *)&utmp, sizeof (utmp)); |
223 | (void) close(wtmp); | |
224 | } | |
225 | } | |
226 | } | |
227 | ||
228 | /* | |
229 | * Record login in wtmp file. | |
230 | */ | |
231 | dologin(pw, sin) | |
232 | struct passwd *pw; | |
233 | struct sockaddr_in *sin; | |
234 | { | |
235 | char line[32]; | |
236 | char remotehost[32]; | |
237 | int wtmp, f; | |
238 | struct hostent *hp = gethostbyaddr(&sin->sin_addr, | |
239 | sizeof (struct in_addr), AF_INET); | |
240 | ||
241 | if (hp) { | |
242 | strncpy(remotehost, hp->h_name, sizeof (remotehost)); | |
243 | endhostent(); | |
244 | } else | |
245 | strncpy(remotehost, inet_ntoa(sin->sin_addr), | |
246 | sizeof (remotehost)); | |
c861cac9 | 247 | wtmp = open(_PATH_WTMP, O_WRONLY|O_APPEND); |
46b15d8a RC |
248 | if (wtmp >= 0) { |
249 | /* hack, but must be unique and no tty line */ | |
250 | sprintf(line, "uucp%.4d", getpid()); | |
251 | SCPYN(utmp.ut_line, line); | |
252 | SCPYN(utmp.ut_name, pw->pw_name); | |
253 | SCPYN(utmp.ut_host, remotehost); | |
79b62878 | 254 | time(&utmp.ut_time); |
46b15d8a RC |
255 | (void) write(wtmp, (char *)&utmp, sizeof (utmp)); |
256 | (void) close(wtmp); | |
257 | } | |
c861cac9 | 258 | if ((f = open(_PATH_LASTLOG, O_RDWR)) >= 0) { |
46b15d8a RC |
259 | struct lastlog ll; |
260 | ||
261 | time(&ll.ll_time); | |
262 | lseek(f, (long)pw->pw_uid * sizeof(struct lastlog), 0); | |
263 | strcpy(line, remotehost); | |
264 | SCPYN(ll.ll_line, line); | |
265 | SCPYN(ll.ll_host, remotehost); | |
266 | (void) write(f, (char *) &ll, sizeof ll); | |
267 | (void) close(f); | |
268 | } | |
cd56d176 | 269 | } |