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