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