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