|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)rexecd.c 5.5 (Berkeley) 10/22/87";
15: #endif not lint
16:
17: #include <sys/ioctl.h>
18: #include <sys/param.h>
19: #include <sys/socket.h>
20: #include <sys/time.h>
21:
22: #include <netinet/in.h>
23:
24: #include <stdio.h>
25: #include <errno.h>
26: #include <pwd.h>
27: #include <signal.h>
28: #include <netdb.h>
29:
30: extern errno;
31: struct passwd *getpwnam();
32: char *crypt(), *rindex(), *strncat();
33: /*VARARGS1*/
34: int error();
35:
36: /*
37: * remote execute server:
38: * username\0
39: * password\0
40: * command\0
41: * data
42: */
43: /*ARGSUSED*/
44: main(argc, argv)
45: int argc;
46: char **argv;
47: {
48: struct sockaddr_in from;
49: int fromlen;
50:
51: fromlen = sizeof (from);
52: if (getpeername(0, &from, &fromlen) < 0) {
53: fprintf(stderr, "%s: ", argv[0]);
54: perror("getpeername");
55: exit(1);
56: }
57: doit(0, &from);
58: }
59:
60: char username[20] = "USER=";
61: char homedir[64] = "HOME=";
62: char shell[64] = "SHELL=";
63: char *envinit[] =
64: {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", username, 0};
65: char **environ;
66:
67: struct sockaddr_in asin = { AF_INET };
68:
69: doit(f, fromp)
70: int f;
71: struct sockaddr_in *fromp;
72: {
73: char cmdbuf[NCARGS+1], *cp, *namep;
74: char user[16], pass[16];
75: struct passwd *pwd;
76: int s;
77: short port;
78: int pv[2], pid, ready, readfrom, cc;
79: char buf[BUFSIZ], sig;
80: int one = 1;
81:
82: (void) signal(SIGINT, SIG_DFL);
83: (void) signal(SIGQUIT, SIG_DFL);
84: (void) signal(SIGTERM, SIG_DFL);
85: #ifdef DEBUG
86: { int t = open("/dev/tty", 2);
87: if (t >= 0) {
88: ioctl(t, TIOCNOTTY, (char *)0);
89: (void) close(t);
90: }
91: }
92: #endif
93: dup2(f, 0);
94: dup2(f, 1);
95: dup2(f, 2);
96: (void) alarm(60);
97: port = 0;
98: for (;;) {
99: char c;
100: if (read(f, &c, 1) != 1)
101: exit(1);
102: if (c == 0)
103: break;
104: port = port * 10 + c - '0';
105: }
106: (void) alarm(0);
107: if (port != 0) {
108: s = socket(AF_INET, SOCK_STREAM, 0);
109: if (s < 0)
110: exit(1);
111: if (bind(s, &asin, sizeof (asin)) < 0)
112: exit(1);
113: (void) alarm(60);
114: fromp->sin_port = htons((u_short)port);
115: if (connect(s, fromp, sizeof (*fromp)) < 0)
116: exit(1);
117: (void) alarm(0);
118: }
119: getstr(user, sizeof(user), "username");
120: getstr(pass, sizeof(pass), "password");
121: getstr(cmdbuf, sizeof(cmdbuf), "command");
122: setpwent();
123: pwd = getpwnam(user);
124: if (pwd == NULL) {
125: error("Login incorrect.\n");
126: exit(1);
127: }
128: endpwent();
129: if (*pwd->pw_passwd != '\0') {
130: namep = crypt(pass, pwd->pw_passwd);
131: if (strcmp(namep, pwd->pw_passwd)) {
132: error("Password incorrect.\n");
133: exit(1);
134: }
135: }
136: if (chdir(pwd->pw_dir) < 0) {
137: error("No remote directory.\n");
138: exit(1);
139: }
140: (void) write(2, "\0", 1);
141: if (port) {
142: (void) pipe(pv);
143: pid = fork();
144: if (pid == -1) {
145: error("Try again.\n");
146: exit(1);
147: }
148: if (pid) {
149: (void) close(0); (void) close(1); (void) close(2);
150: (void) close(f); (void) close(pv[1]);
151: readfrom = (1<<s) | (1<<pv[0]);
152: ioctl(pv[1], FIONBIO, (char *)&one);
153: /* should set s nbio! */
154: do {
155: ready = readfrom;
156: (void) select(16, &ready, (fd_set *)0,
157: (fd_set *)0, (struct timeval *)0);
158: if (ready & (1<<s)) {
159: if (read(s, &sig, 1) <= 0)
160: readfrom &= ~(1<<s);
161: else
162: killpg(pid, sig);
163: }
164: if (ready & (1<<pv[0])) {
165: cc = read(pv[0], buf, sizeof (buf));
166: if (cc <= 0) {
167: shutdown(s, 1+1);
168: readfrom &= ~(1<<pv[0]);
169: } else
170: (void) write(s, buf, cc);
171: }
172: } while (readfrom);
173: exit(0);
174: }
175: setpgrp(0, getpid());
176: (void) close(s); (void)close(pv[0]);
177: dup2(pv[1], 2);
178: }
179: if (*pwd->pw_shell == '\0')
180: pwd->pw_shell = "/bin/sh";
181: if (f > 2)
182: (void) close(f);
183: (void) setgid((gid_t)pwd->pw_gid);
184: initgroups(pwd->pw_name, pwd->pw_gid);
185: (void) setuid((uid_t)pwd->pw_uid);
186: environ = envinit;
187: strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
188: strncat(shell, pwd->pw_shell, sizeof(shell)-7);
189: strncat(username, pwd->pw_name, sizeof(username)-6);
190: cp = rindex(pwd->pw_shell, '/');
191: if (cp)
192: cp++;
193: else
194: cp = pwd->pw_shell;
195: execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
196: perror(pwd->pw_shell);
197: exit(1);
198: }
199:
200: /*VARARGS1*/
201: error(fmt, a1, a2, a3)
202: char *fmt;
203: int a1, a2, a3;
204: {
205: char buf[BUFSIZ];
206:
207: buf[0] = 1;
208: (void) sprintf(buf+1, fmt, a1, a2, a3);
209: (void) write(2, buf, strlen(buf));
210: }
211:
212: getstr(buf, cnt, err)
213: char *buf;
214: int cnt;
215: char *err;
216: {
217: char c;
218:
219: do {
220: if (read(0, &c, 1) != 1)
221: exit(1);
222: *buf++ = c;
223: if (--cnt == 0) {
224: error("%s too long\n", err);
225: exit(1);
226: }
227: } while (c != 0);
228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.