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