|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)rexecd.c 5.10 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/ioctl.h> ! 31: #include <sys/param.h> ! 32: #include <sys/socket.h> ! 33: #include <sys/time.h> ! 34: ! 35: #include <netinet/in.h> ! 36: ! 37: #include <stdio.h> ! 38: #include <errno.h> ! 39: #include <pwd.h> ! 40: #include <signal.h> ! 41: #include <netdb.h> ! 42: #include "pathnames.h" ! 43: ! 44: extern int errno; ! 45: struct passwd *getpwnam(); ! 46: char *crypt(), *rindex(), *strncat(); ! 47: /*VARARGS1*/ ! 48: int error(); ! 49: ! 50: /* ! 51: * remote execute server: ! 52: * username\0 ! 53: * password\0 ! 54: * command\0 ! 55: * data ! 56: */ ! 57: /*ARGSUSED*/ ! 58: main(argc, argv) ! 59: int argc; ! 60: char **argv; ! 61: { ! 62: struct sockaddr_in from; ! 63: int fromlen; ! 64: ! 65: fromlen = sizeof (from); ! 66: if (getpeername(0, &from, &fromlen) < 0) { ! 67: fprintf(stderr, "%s: ", argv[0]); ! 68: perror("getpeername"); ! 69: exit(1); ! 70: } ! 71: doit(0, &from); ! 72: } ! 73: ! 74: char username[20] = "USER="; ! 75: char homedir[64] = "HOME="; ! 76: char shell[64] = "SHELL="; ! 77: char *envinit[] = ! 78: {homedir, shell, _PATH_DEFPATH, username, 0}; ! 79: char **environ; ! 80: ! 81: struct sockaddr_in asin = { AF_INET }; ! 82: ! 83: doit(f, fromp) ! 84: int f; ! 85: struct sockaddr_in *fromp; ! 86: { ! 87: char cmdbuf[NCARGS+1], *cp, *namep; ! 88: char user[16], pass[16]; ! 89: struct passwd *pwd; ! 90: int s; ! 91: u_short port; ! 92: int pv[2], pid, ready, readfrom, cc; ! 93: char buf[BUFSIZ], sig; ! 94: int one = 1; ! 95: ! 96: (void) signal(SIGINT, SIG_DFL); ! 97: (void) signal(SIGQUIT, SIG_DFL); ! 98: (void) signal(SIGTERM, SIG_DFL); ! 99: #ifdef DEBUG ! 100: { int t = open(_PATH_TTY, 2); ! 101: if (t >= 0) { ! 102: ioctl(t, TIOCNOTTY, (char *)0); ! 103: (void) close(t); ! 104: } ! 105: } ! 106: #endif ! 107: dup2(f, 0); ! 108: dup2(f, 1); ! 109: dup2(f, 2); ! 110: (void) alarm(60); ! 111: port = 0; ! 112: for (;;) { ! 113: char c; ! 114: if (read(f, &c, 1) != 1) ! 115: exit(1); ! 116: if (c == 0) ! 117: break; ! 118: port = port * 10 + c - '0'; ! 119: } ! 120: (void) alarm(0); ! 121: if (port != 0) { ! 122: s = socket(AF_INET, SOCK_STREAM, 0); ! 123: if (s < 0) ! 124: exit(1); ! 125: if (bind(s, &asin, sizeof (asin)) < 0) ! 126: exit(1); ! 127: (void) alarm(60); ! 128: fromp->sin_port = htons(port); ! 129: if (connect(s, fromp, sizeof (*fromp)) < 0) ! 130: exit(1); ! 131: (void) alarm(0); ! 132: } ! 133: getstr(user, sizeof(user), "username"); ! 134: getstr(pass, sizeof(pass), "password"); ! 135: getstr(cmdbuf, sizeof(cmdbuf), "command"); ! 136: setpwent(); ! 137: pwd = getpwnam(user); ! 138: if (pwd == NULL) { ! 139: error("Login incorrect.\n"); ! 140: exit(1); ! 141: } ! 142: endpwent(); ! 143: if (*pwd->pw_passwd != '\0') { ! 144: namep = crypt(pass, pwd->pw_passwd); ! 145: if (strcmp(namep, pwd->pw_passwd)) { ! 146: error("Password incorrect.\n"); ! 147: exit(1); ! 148: } ! 149: } ! 150: if (chdir(pwd->pw_dir) < 0) { ! 151: error("No remote directory.\n"); ! 152: exit(1); ! 153: } ! 154: (void) write(2, "\0", 1); ! 155: if (port) { ! 156: (void) pipe(pv); ! 157: pid = fork(); ! 158: if (pid == -1) { ! 159: error("Try again.\n"); ! 160: exit(1); ! 161: } ! 162: if (pid) { ! 163: (void) close(0); (void) close(1); (void) close(2); ! 164: (void) close(f); (void) close(pv[1]); ! 165: readfrom = (1<<s) | (1<<pv[0]); ! 166: ioctl(pv[1], FIONBIO, (char *)&one); ! 167: /* should set s nbio! */ ! 168: do { ! 169: ready = readfrom; ! 170: (void) select(16, &ready, (fd_set *)0, ! 171: (fd_set *)0, (struct timeval *)0); ! 172: if (ready & (1<<s)) { ! 173: if (read(s, &sig, 1) <= 0) ! 174: readfrom &= ~(1<<s); ! 175: else ! 176: killpg(pid, sig); ! 177: } ! 178: if (ready & (1<<pv[0])) { ! 179: cc = read(pv[0], buf, sizeof (buf)); ! 180: if (cc <= 0) { ! 181: shutdown(s, 1+1); ! 182: readfrom &= ~(1<<pv[0]); ! 183: } else ! 184: (void) write(s, buf, cc); ! 185: } ! 186: } while (readfrom); ! 187: exit(0); ! 188: } ! 189: setpgrp(0, getpid()); ! 190: (void) close(s); (void)close(pv[0]); ! 191: dup2(pv[1], 2); ! 192: } ! 193: if (*pwd->pw_shell == '\0') ! 194: pwd->pw_shell = _PATH_BSHELL; ! 195: if (f > 2) ! 196: (void) close(f); ! 197: (void) setgid((gid_t)pwd->pw_gid); ! 198: initgroups(pwd->pw_name, pwd->pw_gid); ! 199: (void) setuid((uid_t)pwd->pw_uid); ! 200: environ = envinit; ! 201: strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); ! 202: strncat(shell, pwd->pw_shell, sizeof(shell)-7); ! 203: strncat(username, pwd->pw_name, sizeof(username)-6); ! 204: cp = rindex(pwd->pw_shell, '/'); ! 205: if (cp) ! 206: cp++; ! 207: else ! 208: cp = pwd->pw_shell; ! 209: execl(pwd->pw_shell, cp, "-c", cmdbuf, 0); ! 210: perror(pwd->pw_shell); ! 211: exit(1); ! 212: } ! 213: ! 214: /*VARARGS1*/ ! 215: error(fmt, a1, a2, a3) ! 216: char *fmt; ! 217: int a1, a2, a3; ! 218: { ! 219: char buf[BUFSIZ]; ! 220: ! 221: buf[0] = 1; ! 222: (void) sprintf(buf+1, fmt, a1, a2, a3); ! 223: (void) write(2, buf, strlen(buf)); ! 224: } ! 225: ! 226: getstr(buf, cnt, err) ! 227: char *buf; ! 228: int cnt; ! 229: char *err; ! 230: { ! 231: char c; ! 232: ! 233: do { ! 234: if (read(0, &c, 1) != 1) ! 235: exit(1); ! 236: *buf++ = c; ! 237: if (--cnt == 0) { ! 238: error("%s too long\n", err); ! 239: exit(1); ! 240: } ! 241: } while (c != 0); ! 242: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.