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