|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)rshd.c 4.18 83/07/01";
3: #endif
4:
5: #include <stdio.h>
6: #include <sys/param.h>
7: #include <sys/types.h>
8: #include <sys/stat.h>
9:
10:
11: #include <errno.h>
12: #include <pwd.h>
13: #include <signal.h>
14: #include <sgtty.h>
15: #include <stdio.h>
16: #include <sys/inet/in.h>
17: #include <wait.h>
18: #include "config.h"
19:
20: extern errno;
21: int reapchild();
22: int alrmcatch();
23: struct passwd *getpwnam();
24: struct passwd *pwd;
25: struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" };
26: char *crypt(), *rindex(), *index(), *malloc();
27: extern char **environ;
28: static char *envinit[] = {
29: 0
30: };
31: char cmd[1024];
32:
33: /*
34: * remote shell server:
35: * remuser\0
36: * locuser\0
37: * command\0
38: * data
39: */
40: main(argc, argv)
41: int argc;
42: char **argv;
43: {
44: int f, dev;
45: unsigned long faddr;
46: int myport, fport;
47: struct in_service *sp;
48:
49: sp = in_service("shell");
50: if(sp == 0){
51: fprintf(stderr, "rshd: tcp/rsh: unknown service\n");
52: exit(1);
53: }
54: myport = sp->port;
55: signal(SIGPIPE, SIG_IGN);
56: signal(SIGHUP, SIG_IGN);
57: close(3);
58:
59: f = tcp_sock();
60: if (f < 0) {
61: perror("rshd: socket");
62: exit(1);
63: }
64: signal(SIGCHLD, reapchild);
65: signal(SIGALRM, alrmcatch);
66: tcp_listen(f, myport, 0, 0);
67: for (;;) {
68: int s;
69:
70: s = tcp_accept(f, &faddr, &fport, &dev);
71: if (s < 0) {
72: if (errno == EINTR)
73: continue;
74: perror("rshd: accept");
75: continue;
76: }
77: doit(s, faddr, fport, dev);
78: close(s);
79: }
80: }
81:
82: reapchild()
83: {
84: union wait status;
85: int pid;
86:
87: signal(SIGCHLD, SIG_IGN);
88: while((pid = wait3(&status, WNOHANG, 0)) > 0)
89: rmut(pid);
90: signal(SIGCHLD, reapchild);
91: }
92:
93: char rusername[32], lusername[32];
94: char buf[BUFSIZ];
95: int child;
96: int cleanup();
97: int netf;
98: extern errno;
99:
100: doit(f, faddr, fport, dev)
101: int f;
102: unsigned long faddr;
103: {
104: extern tty_ld;
105: extern char *ttyname();
106: char c;
107: int i, pid, ret, port, s;
108: char *host, line[32];
109:
110: sprintf(line, "/dev/tcp%02d", dev);
111:
112: alarm(20);
113: port = 0;
114: for(;;){
115: if(read(f, &c, 1) != 1){
116: perror("rshd: port read");
117: fprintf(stderr, " line %s\n", line);
118: return;
119: }
120: if(c == 0)
121: break;
122: port = port * 10 + c - '0';
123: }
124: alarm(0);
125: if(port >= 1024){
126: fprintf(stderr, "rshd: 2nd port not reserved\n");
127: return;
128: }
129: if(port){
130: s = tcp_sock();
131: if(s < 0){
132: perror("rshd: can't get stderr port");
133: return;
134: }
135: if(tcp_connect(s, 0, faddr, port) < 0){
136: perror("rshd: 2nd connect");
137: close(s);
138: return;
139: }
140: }
141:
142:
143: host = (char *)in_host(faddr);
144: if (host == 0) {
145: msg(f, "Don't know your host name\n");
146: return;
147: }
148: if(fport >= 1024){
149: msg(f, "Permission denied\n");
150: return;
151: }
152: if(access(line, 0) < 0){
153: msg(f, "No tty\n");
154: return;
155: }
156: pid = fork();
157: if (pid < 0){
158: msg(f, "Fork problem\n");
159: close(s);
160: return;
161: }
162: if (pid) {
163: close(s);
164: record(pid, line);
165: return;
166: }
167:
168:
169: signal(SIGCHLD, SIG_IGN);
170: signal(SIGHUP, SIG_DFL);
171: signal(SIGALRM, SIG_DFL);
172:
173: dup2(f, 0);
174: dup2(f, 1);
175: if(port){
176: dup2(s, 2);
177: close(s);
178: } else {
179: dup2(f, 2);
180: }
181: close(f);
182: ioctl(0, TIOCSPGRP, 0);
183: dup2(0, 3);
184:
185: environ = envinit;
186:
187: ret = doremotelogin(host);
188: if(ret < 0){
189: msg(1, "Sorry\n");
190: exit(1);
191: } else {
192: write(1, "", 1);
193: execl(LOGIN, "login", "-f", pwd->pw_name, cmd, 0);
194: printf("%s not found\n", LOGIN);
195: exit(1);
196: }
197: /*NOTREACHED*/
198: }
199:
200:
201:
202: struct foo{
203: int pid;
204: char line[16];
205: };
206: #define NFOO 50
207: struct foo foo[NFOO];
208:
209: record(pid, line)
210: char *line;
211: {
212: int i;
213:
214: for(i = 0; i < NFOO; i++){
215: if(foo[i].pid == 0){
216: foo[i].pid = pid;
217: strncpy(foo[i].line, line+5, 8);
218: return;
219: }
220: }
221: }
222:
223: #include <utmp.h>
224:
225: struct utmp wtmp;
226: char wtmpf[] = "/usr/adm/wtmp";
227: char utmp[] = UTMP;
228: #define SCPYN(a, b) strncpy(a, b, sizeof(a))
229: #define SCMPN(a, b) strncmp(a, b, sizeof(a))
230:
231: rmut(pid)
232: {
233: register f;
234: int found = 0;
235: char *line;
236: int i;
237: char file[32];
238:
239: for(i = 0; i < NFOO; i++){
240: if(pid == foo[i].pid){
241: line = foo[i].line;
242: foo[i].pid = 0;
243: break;
244: }
245: }
246: if(i >= NFOO)
247: return;
248: f = open(utmp, 2);
249: if (f >= 0) {
250: while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
251: if (SCMPN(wtmp.ut_line, line) || wtmp.ut_name[0]==0)
252: continue;
253: lseek(f, -(long)sizeof(wtmp), 1);
254: SCPYN(wtmp.ut_name, "");
255: time(&wtmp.ut_time);
256: write(f, (char *)&wtmp, sizeof(wtmp));
257: found++;
258: }
259: close(f);
260: }
261: if (found) {
262: f = open(wtmpf, 1);
263: if (f >= 0) {
264: SCPYN(wtmp.ut_line, line+5);
265: SCPYN(wtmp.ut_name, "");
266: time(&wtmp.ut_time);
267: lseek(f, (long)0, 2);
268: write(f, (char *)&wtmp, sizeof(wtmp));
269: close(f);
270: }
271: }
272: sprintf(file, "/dev/%s", line);
273: chmod(file, 0600);
274: chown(file, 0, 0);
275: }
276:
277: msg(fd, s)
278: char *s;
279: {
280: write(fd, "\001", 1);
281: write(fd, s, strlen(s));
282: }
283:
284: alrmcatch()
285: {
286: signal(SIGALRM, alrmcatch);
287: return(-1);
288: }
289:
290: sttyek(fd)
291: {
292: struct sgttyb vec;
293:
294: gtty(fd, &vec);
295: vec.sg_erase = '#';
296: vec.sg_kill = '@';
297: vec.sg_flags |= XTABS;
298: stty(fd, &vec);
299: }
300:
301: doremotelogin(host)
302: char *host;
303: {
304: FILE *hostf;
305: int first = 1;
306: char *p;
307:
308: getstr(rusername, sizeof (rusername), "remuser");
309: getstr(lusername, sizeof (lusername), "locuser");
310: getstr(cmd, sizeof(cmd), "command");
311:
312: if (getuid()) {
313: pwd = &nouser;
314: goto bad;
315: }
316: setpwent();
317: pwd = getpwnam(lusername);
318: endpwent();
319: if (pwd == NULL) {
320: pwd = &nouser;
321: goto bad;
322: }
323: hostf = pwd->pw_uid ? fopen(EQUIV, "r") : 0;
324: again:
325: if (hostf) {
326: char ahost[32];
327:
328: while (fgets(ahost, sizeof (ahost), hostf)) {
329: char *user;
330:
331: if ((user = index(ahost, '\n')) != 0)
332: *user++ = '\0';
333: if ((user = index(ahost, ' ')) != 0)
334: *user++ = '\0';
335: if (!strcmp(host, ahost) &&
336: !strcmp(rusername, user ? user : lusername)) {
337: fclose(hostf);
338: return (1);
339: }
340: }
341: fclose(hostf);
342: }
343: if (first == 1) {
344: char *rhosts = ".rhosts";
345: struct stat sbuf;
346:
347: first = 0;
348: if (chdir(pwd->pw_dir) < 0)
349: goto again;
350: if (lstat(rhosts, &sbuf) < 0)
351: goto again;
352: if ((sbuf.st_mode & S_IFMT) == S_IFLNK) {
353: printf("login: .rhosts is a soft link.\r\n");
354: goto bad;
355: }
356: hostf = fopen(rhosts, "r");
357: fstat(fileno(hostf), &sbuf);
358: if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
359: printf("login: Bad .rhosts ownership.\r\n");
360: fclose(hostf);
361: goto bad;
362: }
363: goto again;
364: }
365: bad:
366: return (-1);
367: }
368:
369: getstr(buf, cnt, err)
370: char *buf;
371: int cnt;
372: char *err;
373: {
374: char c;
375:
376: do {
377: if (read(0, &c, 1) != 1)
378: exit(1);
379: if (--cnt < 0) {
380: printf("%s too long\r\n", err);
381: exit(1);
382: }
383: *buf++ = c;
384: } while (c != 0);
385: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.