Sun version and make install fixes
[unix-history] / usr / src / libexec / rexecd / rexecd.c
CommitLineData
f0d0adca
BJ
1#ifndef lint
2static char sccsid[] = "@(#)rexecd.c 4.1 82/04/02";
3#endif
4
5#include <stdio.h>
6#include <sys/ioctl.h>
7#include <sys/param.h>
8#include <sys/socket.h>
9#include <net/in.h>
10#include <errno.h>
11#include <pwd.h>
12#include <wait.h>
13#include <signal.h>
14
15extern errno;
16struct sockaddr_in sin = { AF_INET, IPPORT_EXECSERVER };
17struct passwd *getpwnam();
18char *crypt(), *rindex(), *sprintf();
19int options = SO_ACCEPTCONN|SO_KEEPALIVE;
20/* VARARGS 1 */
21int error();
22/*
23 * remote execute server:
24 * username\0
25 * password\0
26 * command\0
27 * data
28 */
29main(argc, argv)
30 int argc;
31 char **argv;
32{
33 union wait status;
34 int f;
35 struct sockaddr_in from;
36
37#ifndef DEBUG
38 if (fork())
39 exit(0);
40 for (f = 0; f < 10; f++)
41 (void) close(f);
42 (void) open("/", 0);
43 (void) dup2(0, 1);
44 (void) dup2(0, 2);
45 { int t = open("/dev/tty", 2);
46 if (t >= 0) {
47 ioctl(t, TIOCNOTTY, (char *)0);
48 (void) close(t);
49 }
50 }
51#endif
52#if vax
53 sin.sin_port = htons(sin.sin_port);
54#endif
55 argc--, argv++;
56 if (argc > 0 && !strcmp(argv[0], "-d"))
57 options |= SO_DEBUG;
58 for (;;) {
59 errno = 0;
60 f = socket(SOCK_STREAM, 0, &sin, options);
61 if (f < 0) {
62 perror("socket");
63 sleep(5);
64 continue;
65 }
66 if (accept(f, &from) < 0) {
67 perror("accept");
68 (void) close(f);
69 sleep(1);
70 continue;
71 }
72 if (fork() == 0)
73 doit(f, &from);
74 (void) close(f);
75 while(wait3(status, WNOHANG, 0) > 0)
76 continue;
77 }
78}
79
80char username[20] = "USER=";
81char homedir[64] = "HOME=";
82char shell[64] = "SHELL=";
83char *envinit[] =
84 {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", username, 0};
85char **environ;
86
87struct sockaddr_in asin = { AF_INET };
88
89doit(f, fromp)
90 int f;
91 struct sockaddr_in *fromp;
92{
93 char cmdbuf[NCARGS+1], *cp, *namep;
94 char user[16], pass[16];
95 struct passwd *pwd;
96 int s;
97 short port;
98 int pv[2], pid, ready, readfrom, cc;
99 char buf[BUFSIZ], sig;
100 int one = 1;
101
102 (void) signal(SIGINT, SIG_DFL);
103 (void) signal(SIGQUIT, SIG_DFL);
104 (void) signal(SIGTERM, SIG_DFL);
105#ifdef DEBUG
106 { int t = open("/dev/tty", 2);
107 if (t >= 0) {
108 ioctl(t, TIOCNOTTY, (char *)0);
109 (void) close(t);
110 }
111 }
112#endif
113 dup2(f, 0);
114 dup2(f, 1);
115 dup2(f, 2);
116#if vax
117 fromp->sin_port = ntohs((u_short)fromp->sin_port);
118#endif
119 (void) alarm(60);
120 port = 0;
121 for (;;) {
122 char c;
123 if (read(f, &c, 1) != 1)
124 exit(1);
125 if (c == 0)
126 break;
127 port = port * 10 + c - '0';
128 }
129 (void) alarm(0);
130 if (port != 0) {
131 s = socket(SOCK_STREAM, 0, &asin, 0);
132 if (s < 0)
133 exit(1);
134 (void) alarm(60);
135 fromp->sin_port = port;
136#if vax
137 fromp->sin_port = ntohs(fromp->sin_port);
138#endif
139 if (connect(s, fromp) < 0)
140 exit(1);
141 (void) alarm(0);
142 }
143 getstr(user, sizeof(user), "username");
144 getstr(pass, sizeof(pass), "password");
145 getstr(cmdbuf, sizeof(cmdbuf), "command");
146 setpwent();
147 pwd = getpwnam(user);
148 if (pwd == NULL) {
149 error("Login incorrect.\n");
150 exit(1);
151 }
152 endpwent();
153 if (*pwd->pw_passwd != '\0') {
154 namep = crypt(pass, pwd->pw_passwd);
155 if (strcmp(namep, pwd->pw_passwd)) {
156 error("Password incorrect.\n");
157 exit(1);
158 }
159 }
160 if (chdir(pwd->pw_dir) < 0) {
161 error("No remote directory.\n");
162 exit(1);
163 }
164 (void) write(2, "\0", 1);
165 if (port) {
166 (void) pipe(pv);
167 pid = fork();
168 if (pid == -1) {
169 error("Try again.\n");
170 exit(1);
171 }
172 if (pid) {
173 (void) close(0); (void) close(1); (void) close(2);
174 (void) close(f); (void) close(pv[1]);
175 readfrom = (1<<s) | (1<<pv[0]);
176 ioctl(pv[1], FIONBIO, (char *)&one);
177 /* should set s nbio! */
178 do {
179 ready = readfrom;
180 (void) select(32, &ready, 0, 1000000);
181 if (ready & (1<<s)) {
182 if (read(s, &sig, 1) <= 0)
183 readfrom &= ~(1<<s);
184 else
185 killpg(pid, sig);
186 }
187 if (ready & (1<<pv[0])) {
188 cc = read(pv[0], buf, sizeof (buf));
189 if (cc <= 0) {
190 int done = 1+1;
191 ioctl(s, SIOCDONE, (char *)&done);
192 readfrom &= ~(1<<pv[0]);
193 } else
194 (void) write(s, buf, cc);
195 }
196 } while (readfrom);
197 exit(0);
198 }
199 setpgrp(0, getpid());
200 (void) close(s); (void)close(pv[0]);
201 dup2(pv[1], 2);
202 }
203 if (*pwd->pw_shell == '\0')
204 pwd->pw_shell = "/bin/sh";
205 (void) close(f);
206 inigrp(pwd->pw_name, pwd->pw_gid);
207 (void) setuid(pwd->pw_uid);
208 (void) setgid(pwd->pw_gid);
209 environ = envinit;
210 strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
211 strncat(shell, pwd->pw_shell, sizeof(shell)-7);
212 strncat(username, pwd->pw_name, sizeof(username)-6);
213 cp = rindex(pwd->pw_shell, '/');
214 if (cp)
215 cp++;
216 else
217 cp = pwd->pw_shell;
218 execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
219 perror(pwd->pw_shell);
220 exit(1);
221}
222
223/* VARARGS 1 */
224error(fmt, a1, a2, a3)
225 char *fmt;
226 int a1, a2, a3;
227{
228 char buf[BUFSIZ];
229
230 buf[0] = 1;
231 (void) sprintf(buf+1, fmt, a1, a2, a3);
232 (void) write(2, buf, strlen(buf));
233}
234
235getstr(buf, cnt, err)
236 char *buf;
237 int cnt;
238 char *err;
239{
240 char c;
241
242 do {
243 if (read(0, &c, 1) != 1)
244 exit(1);
245 *buf++ = c;
246 if (--cnt == 0) {
247 error("%s too long\n", err);
248 exit(1);
249 }
250 } while (c != 0);
251}