130ae0772Sdist /*
2*ce46c3ffSbostic * Copyright (c) 1983, 1993
3*ce46c3ffSbostic * The Regents of the University of California. All rights reserved.
4e188a54cSbostic *
5fac09079Sbostic * %sccs.include.redist.c%
630ae0772Sdist */
730ae0772Sdist
88badd300Swnj #ifndef lint
9*ce46c3ffSbostic static char copyright[] =
10*ce46c3ffSbostic "@(#) Copyright (c) 1983, 1993\n\
11*ce46c3ffSbostic The Regents of the University of California. All rights reserved.\n";
12e188a54cSbostic #endif /* not lint */
1330ae0772Sdist
1430ae0772Sdist #ifndef lint
15*ce46c3ffSbostic static char sccsid[] = "@(#)rexecd.c 8.1 (Berkeley) 06/04/93";
16e188a54cSbostic #endif /* not lint */
178badd300Swnj
188badd300Swnj #include <sys/param.h>
19f71c8376Sbostic #include <sys/ioctl.h>
208badd300Swnj #include <sys/socket.h>
21e2944021Slepreau #include <sys/time.h>
22c6ddb5f9Sbostic
23f9dd9d42Ssam #include <netinet/in.h>
24c6ddb5f9Sbostic
25f71c8376Sbostic #include <errno.h>
26c6ddb5f9Sbostic #include <netdb.h>
27c6ddb5f9Sbostic #include <paths.h>
28c6ddb5f9Sbostic #include <pwd.h>
29c6ddb5f9Sbostic #include <signal.h>
30f71c8376Sbostic #include <stdio.h>
31f71c8376Sbostic #include <stdlib.h>
32f71c8376Sbostic #include <string.h>
33c6ddb5f9Sbostic #include <unistd.h>
348badd300Swnj
358badd300Swnj /*VARARGS1*/
368badd300Swnj int error();
37e2944021Slepreau
388badd300Swnj /*
398badd300Swnj * remote execute server:
408badd300Swnj * username\0
418badd300Swnj * password\0
428badd300Swnj * command\0
438badd300Swnj * data
448badd300Swnj */
45e2944021Slepreau /*ARGSUSED*/
main(argc,argv)468badd300Swnj main(argc, argv)
478badd300Swnj int argc;
488badd300Swnj char **argv;
498badd300Swnj {
508badd300Swnj struct sockaddr_in from;
51bb6cbc71Skarels int fromlen;
528badd300Swnj
53bb6cbc71Skarels fromlen = sizeof (from);
54f71c8376Sbostic if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
55f71c8376Sbostic (void)fprintf(stderr,
56f71c8376Sbostic "rexecd: getpeername: %s\n", strerror(errno));
57f9dd9d42Ssam exit(1);
58f9dd9d42Ssam }
59bb6cbc71Skarels doit(0, &from);
608badd300Swnj }
618badd300Swnj
628badd300Swnj char username[20] = "USER=";
638badd300Swnj char homedir[64] = "HOME=";
648badd300Swnj char shell[64] = "SHELL=";
655ad567c6Sbostic char path[sizeof(_PATH_DEFPATH) + sizeof("PATH=")] = "PATH=";
668badd300Swnj char *envinit[] =
675ad567c6Sbostic {homedir, shell, path, username, 0};
688badd300Swnj char **environ;
698badd300Swnj
708badd300Swnj struct sockaddr_in asin = { AF_INET };
718badd300Swnj
doit(f,fromp)728badd300Swnj doit(f, fromp)
738badd300Swnj int f;
748badd300Swnj struct sockaddr_in *fromp;
758badd300Swnj {
768badd300Swnj char cmdbuf[NCARGS+1], *cp, *namep;
778badd300Swnj char user[16], pass[16];
788badd300Swnj struct passwd *pwd;
798badd300Swnj int s;
80ed20bae8Sbostic u_short port;
818badd300Swnj int pv[2], pid, ready, readfrom, cc;
828badd300Swnj char buf[BUFSIZ], sig;
838badd300Swnj int one = 1;
848badd300Swnj
858badd300Swnj (void) signal(SIGINT, SIG_DFL);
868badd300Swnj (void) signal(SIGQUIT, SIG_DFL);
878badd300Swnj (void) signal(SIGTERM, SIG_DFL);
888badd300Swnj #ifdef DEBUG
8942b80877Sbostic { int t = open(_PATH_TTY, 2);
908badd300Swnj if (t >= 0) {
918badd300Swnj ioctl(t, TIOCNOTTY, (char *)0);
928badd300Swnj (void) close(t);
938badd300Swnj }
948badd300Swnj }
958badd300Swnj #endif
968badd300Swnj dup2(f, 0);
978badd300Swnj dup2(f, 1);
988badd300Swnj dup2(f, 2);
998badd300Swnj (void) alarm(60);
1008badd300Swnj port = 0;
1018badd300Swnj for (;;) {
1028badd300Swnj char c;
1038badd300Swnj if (read(f, &c, 1) != 1)
1048badd300Swnj exit(1);
1058badd300Swnj if (c == 0)
1068badd300Swnj break;
1078badd300Swnj port = port * 10 + c - '0';
1088badd300Swnj }
1098badd300Swnj (void) alarm(0);
1108badd300Swnj if (port != 0) {
1119c06e5c6Sbloom s = socket(AF_INET, SOCK_STREAM, 0);
1128badd300Swnj if (s < 0)
1138badd300Swnj exit(1);
114f71c8376Sbostic if (bind(s, (struct sockaddr *)&asin, sizeof (asin)) < 0)
1151df21a87Ssam exit(1);
1168badd300Swnj (void) alarm(60);
117ed20bae8Sbostic fromp->sin_port = htons(port);
118f71c8376Sbostic if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0)
1198badd300Swnj exit(1);
1208badd300Swnj (void) alarm(0);
1218badd300Swnj }
1228badd300Swnj getstr(user, sizeof(user), "username");
1238badd300Swnj getstr(pass, sizeof(pass), "password");
1248badd300Swnj getstr(cmdbuf, sizeof(cmdbuf), "command");
1258badd300Swnj setpwent();
1268badd300Swnj pwd = getpwnam(user);
1278badd300Swnj if (pwd == NULL) {
1288badd300Swnj error("Login incorrect.\n");
1298badd300Swnj exit(1);
1308badd300Swnj }
1318badd300Swnj endpwent();
1328badd300Swnj if (*pwd->pw_passwd != '\0') {
1338badd300Swnj namep = crypt(pass, pwd->pw_passwd);
1348badd300Swnj if (strcmp(namep, pwd->pw_passwd)) {
1358badd300Swnj error("Password incorrect.\n");
1368badd300Swnj exit(1);
1378badd300Swnj }
1388badd300Swnj }
1398badd300Swnj if (chdir(pwd->pw_dir) < 0) {
1408badd300Swnj error("No remote directory.\n");
1418badd300Swnj exit(1);
1428badd300Swnj }
1438badd300Swnj (void) write(2, "\0", 1);
1448badd300Swnj if (port) {
1458badd300Swnj (void) pipe(pv);
1468badd300Swnj pid = fork();
1478badd300Swnj if (pid == -1) {
1488badd300Swnj error("Try again.\n");
1498badd300Swnj exit(1);
1508badd300Swnj }
1518badd300Swnj if (pid) {
1528badd300Swnj (void) close(0); (void) close(1); (void) close(2);
1538badd300Swnj (void) close(f); (void) close(pv[1]);
1548badd300Swnj readfrom = (1<<s) | (1<<pv[0]);
1558badd300Swnj ioctl(pv[1], FIONBIO, (char *)&one);
1568badd300Swnj /* should set s nbio! */
1578badd300Swnj do {
1588badd300Swnj ready = readfrom;
159f71c8376Sbostic (void) select(16, (fd_set *)&ready,
160f71c8376Sbostic (fd_set *)NULL, (fd_set *)NULL,
161f71c8376Sbostic (struct timeval *)NULL);
1628badd300Swnj if (ready & (1<<s)) {
1638badd300Swnj if (read(s, &sig, 1) <= 0)
1648badd300Swnj readfrom &= ~(1<<s);
1658badd300Swnj else
1668badd300Swnj killpg(pid, sig);
1678badd300Swnj }
1688badd300Swnj if (ready & (1<<pv[0])) {
1698badd300Swnj cc = read(pv[0], buf, sizeof (buf));
1708badd300Swnj if (cc <= 0) {
17169714268Ssam shutdown(s, 1+1);
1728badd300Swnj readfrom &= ~(1<<pv[0]);
1738badd300Swnj } else
1748badd300Swnj (void) write(s, buf, cc);
1758badd300Swnj }
1768badd300Swnj } while (readfrom);
1778badd300Swnj exit(0);
1788badd300Swnj }
1798badd300Swnj setpgrp(0, getpid());
1808badd300Swnj (void) close(s); (void)close(pv[0]);
1818badd300Swnj dup2(pv[1], 2);
1828badd300Swnj }
1838badd300Swnj if (*pwd->pw_shell == '\0')
184f1729804Sbostic pwd->pw_shell = _PATH_BSHELL;
185ef279f11Sralph if (f > 2)
1868badd300Swnj (void) close(f);
187e2944021Slepreau (void) setgid((gid_t)pwd->pw_gid);
188f9dd9d42Ssam initgroups(pwd->pw_name, pwd->pw_gid);
189e2944021Slepreau (void) setuid((uid_t)pwd->pw_uid);
1905ad567c6Sbostic (void)strcat(path, _PATH_DEFPATH);
1918badd300Swnj environ = envinit;
1928badd300Swnj strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
1938badd300Swnj strncat(shell, pwd->pw_shell, sizeof(shell)-7);
1948badd300Swnj strncat(username, pwd->pw_name, sizeof(username)-6);
195c6ddb5f9Sbostic cp = strrchr(pwd->pw_shell, '/');
1968badd300Swnj if (cp)
1978badd300Swnj cp++;
1988badd300Swnj else
1998badd300Swnj cp = pwd->pw_shell;
2008badd300Swnj execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
2018badd300Swnj perror(pwd->pw_shell);
2028badd300Swnj exit(1);
2038badd300Swnj }
2048badd300Swnj
2058badd300Swnj /*VARARGS1*/
error(fmt,a1,a2,a3)2068badd300Swnj error(fmt, a1, a2, a3)
2078badd300Swnj char *fmt;
2088badd300Swnj int a1, a2, a3;
2098badd300Swnj {
2108badd300Swnj char buf[BUFSIZ];
2118badd300Swnj
2128badd300Swnj buf[0] = 1;
2138badd300Swnj (void) sprintf(buf+1, fmt, a1, a2, a3);
2148badd300Swnj (void) write(2, buf, strlen(buf));
2158badd300Swnj }
2168badd300Swnj
getstr(buf,cnt,err)2178badd300Swnj getstr(buf, cnt, err)
2188badd300Swnj char *buf;
2198badd300Swnj int cnt;
2208badd300Swnj char *err;
2218badd300Swnj {
2228badd300Swnj char c;
2238badd300Swnj
2248badd300Swnj do {
2258badd300Swnj if (read(0, &c, 1) != 1)
2268badd300Swnj exit(1);
2278badd300Swnj *buf++ = c;
2288badd300Swnj if (--cnt == 0) {
2298badd300Swnj error("%s too long\n", err);
2308badd300Swnj exit(1);
2318badd300Swnj }
2328badd300Swnj } while (c != 0);
2338badd300Swnj }
234