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