|
|
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.4 (Berkeley) 5/9/86"; ! 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(), *sprintf(); ! 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.