|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)rshd.c 4.18 83/07/01"; ! 3: #endif ! 4: ! 5: #include <stdio.h> ! 6: #include <sys/param.h> ! 7: #include <sys/types.h> ! 8: #include <sys/stat.h> ! 9: ! 10: ! 11: #include <errno.h> ! 12: #include <pwd.h> ! 13: #include <signal.h> ! 14: #include <sgtty.h> ! 15: #include <stdio.h> ! 16: #include <sys/inet/in.h> ! 17: #include <sys/inet/tcp_user.h> ! 18: #include <wait.h> ! 19: #include "config.h" ! 20: ! 21: extern errno; ! 22: int reapchild(); ! 23: int alrmcatch(); ! 24: struct passwd *getpwnam(); ! 25: struct passwd *pwd; ! 26: struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" }; ! 27: char *crypt(), *rindex(), *index(), *malloc(); ! 28: extern char **environ; ! 29: static char *envinit[] = { ! 30: 0 ! 31: }; ! 32: char cmd[1024]; ! 33: ! 34: /* ! 35: * remote shell server: ! 36: * remuser\0 ! 37: * locuser\0 ! 38: * command\0 ! 39: * data ! 40: */ ! 41: main(argc, argv) ! 42: int argc; ! 43: char **argv; ! 44: { ! 45: int f; ! 46: struct in_service *sp; ! 47: struct tcpuser tu; ! 48: ! 49: sp = in_service("shell"); ! 50: if(sp == 0){ ! 51: fprintf(stderr, "rshd: tcp/rsh: unknown service\n"); ! 52: exit(1); ! 53: } ! 54: tu.laddr = 0; ! 55: tu.lport = sp->port; ! 56: signal(SIGPIPE, SIG_IGN); ! 57: signal(SIGHUP, SIG_IGN); ! 58: close(3); ! 59: ! 60: f = tcp_sock(); ! 61: if (f < 0) { ! 62: perror("rshd: socket"); ! 63: exit(1); ! 64: } ! 65: signal(SIGCHLD, reapchild); ! 66: signal(SIGALRM, alrmcatch); ! 67: tu.fport = 0; ! 68: tu.faddr = 0; ! 69: tu.param = 0; ! 70: tcp_listen(f, &tu); ! 71: for (;;) { ! 72: int s; ! 73: ! 74: tu.lport = 0; ! 75: tu.laddr = 0; ! 76: tu.fport = 0; ! 77: tu.faddr = 0; ! 78: tu.param = 0; ! 79: s = tcp_accept(f, &tu); ! 80: if (s < 0) { ! 81: if (errno == EINTR) ! 82: continue; ! 83: perror("rshd: accept"); ! 84: continue; ! 85: } ! 86: doit(s, tu.faddr, tu.fport, tu.param); ! 87: close(s); ! 88: } ! 89: } ! 90: ! 91: reapchild() ! 92: { ! 93: union wait status; ! 94: int pid; ! 95: ! 96: signal(SIGCHLD, SIG_IGN); ! 97: while((pid = wait3(&status, WNOHANG, 0)) > 0) ! 98: rmut(pid); ! 99: signal(SIGCHLD, reapchild); ! 100: } ! 101: ! 102: char rusername[32], lusername[32]; ! 103: char buf[BUFSIZ]; ! 104: int child; ! 105: int cleanup(); ! 106: int netf; ! 107: extern errno; ! 108: ! 109: doit(f, faddr, fport, dev) ! 110: int f; ! 111: unsigned long faddr; ! 112: { ! 113: extern tty_ld; ! 114: extern char *ttyname(); ! 115: char c; ! 116: int i, pid, ret, port, s; ! 117: char *host, line[32]; ! 118: struct tcpuser tu; ! 119: ! 120: sprintf(line, "/dev/tcp%02d", dev); ! 121: ! 122: alarm(20); ! 123: port = 0; ! 124: for(;;){ ! 125: if(read(f, &c, 1) != 1){ ! 126: perror("rshd: port read"); ! 127: fprintf(stderr, " line %s\n", line); ! 128: return; ! 129: } ! 130: if(c == 0) ! 131: break; ! 132: port = port * 10 + c - '0'; ! 133: } ! 134: alarm(0); ! 135: if(port >= 1024){ ! 136: fprintf(stderr, "rshd: 2nd port not reserved\n"); ! 137: return; ! 138: } ! 139: if(port){ ! 140: s = tcp_sock(); ! 141: if(s < 0){ ! 142: perror("rshd: can't get stderr port"); ! 143: return; ! 144: } ! 145: tu.laddr = 0; ! 146: tu.lport = 0; ! 147: tu.faddr = faddr; ! 148: tu.fport = port; ! 149: tu.param = 0; ! 150: if(tcp_connect(s, &tu) < 0){ ! 151: perror("rshd: 2nd connect"); ! 152: close(s); ! 153: return; ! 154: } ! 155: } ! 156: ! 157: ! 158: host = (char *)in_host(faddr); ! 159: if (host == 0) { ! 160: msg(f, "Don't know your host name\n"); ! 161: return; ! 162: } ! 163: if(fport >= 1024){ ! 164: msg(f, "Permission denied\n"); ! 165: return; ! 166: } ! 167: if(access(line, 0) < 0){ ! 168: msg(f, "No tty\n"); ! 169: return; ! 170: } ! 171: pid = fork(); ! 172: if (pid < 0){ ! 173: msg(f, "Fork problem\n"); ! 174: close(s); ! 175: return; ! 176: } ! 177: if (pid) { ! 178: close(s); ! 179: record(pid, line); ! 180: return; ! 181: } ! 182: ! 183: ! 184: signal(SIGCHLD, SIG_IGN); ! 185: signal(SIGHUP, SIG_DFL); ! 186: signal(SIGALRM, SIG_DFL); ! 187: ! 188: dup2(f, 0); ! 189: dup2(f, 1); ! 190: if(port){ ! 191: dup2(s, 2); ! 192: close(s); ! 193: } else { ! 194: dup2(f, 2); ! 195: } ! 196: close(f); ! 197: ioctl(0, TIOCSPGRP, 0); ! 198: dup2(0, 3); ! 199: ! 200: environ = envinit; ! 201: ! 202: ret = doremotelogin(host); ! 203: if(ret < 0){ ! 204: msg(1, "Sorry\n"); ! 205: exit(1); ! 206: } else { ! 207: write(1, "", 1); ! 208: execl(LOGIN, "login", "-f", pwd->pw_name, cmd, 0); ! 209: printf("%s not found\n", LOGIN); ! 210: exit(1); ! 211: } ! 212: /*NOTREACHED*/ ! 213: } ! 214: ! 215: ! 216: ! 217: struct foo{ ! 218: int pid; ! 219: char line[16]; ! 220: }; ! 221: #define NFOO 50 ! 222: struct foo foo[NFOO]; ! 223: ! 224: record(pid, line) ! 225: char *line; ! 226: { ! 227: int i; ! 228: ! 229: for(i = 0; i < NFOO; i++){ ! 230: if(foo[i].pid == 0){ ! 231: foo[i].pid = pid; ! 232: strncpy(foo[i].line, line+5, 8); ! 233: return; ! 234: } ! 235: } ! 236: } ! 237: ! 238: #include <utmp.h> ! 239: ! 240: struct utmp wtmp; ! 241: char wtmpf[] = "/usr/adm/wtmp"; ! 242: char utmp[] = UTMP; ! 243: #define SCPYN(a, b) strncpy(a, b, sizeof(a)) ! 244: #define SCMPN(a, b) strncmp(a, b, sizeof(a)) ! 245: ! 246: rmut(pid) ! 247: { ! 248: register f; ! 249: int found = 0; ! 250: char *line; ! 251: int i; ! 252: char file[32]; ! 253: ! 254: for(i = 0; i < NFOO; i++){ ! 255: if(pid == foo[i].pid){ ! 256: line = foo[i].line; ! 257: foo[i].pid = 0; ! 258: break; ! 259: } ! 260: } ! 261: if(i >= NFOO) ! 262: return; ! 263: f = open(utmp, 2); ! 264: if (f >= 0) { ! 265: while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) { ! 266: if (SCMPN(wtmp.ut_line, line) || wtmp.ut_name[0]==0) ! 267: continue; ! 268: lseek(f, -(long)sizeof(wtmp), 1); ! 269: SCPYN(wtmp.ut_name, ""); ! 270: time(&wtmp.ut_time); ! 271: write(f, (char *)&wtmp, sizeof(wtmp)); ! 272: found++; ! 273: } ! 274: close(f); ! 275: } ! 276: if (found) { ! 277: f = open(wtmpf, 1); ! 278: if (f >= 0) { ! 279: SCPYN(wtmp.ut_line, line+5); ! 280: SCPYN(wtmp.ut_name, ""); ! 281: time(&wtmp.ut_time); ! 282: lseek(f, (long)0, 2); ! 283: write(f, (char *)&wtmp, sizeof(wtmp)); ! 284: close(f); ! 285: } ! 286: } ! 287: sprintf(file, "/dev/%s", line); ! 288: chmod(file, 0600); ! 289: chown(file, 0, 0); ! 290: } ! 291: ! 292: msg(fd, s) ! 293: char *s; ! 294: { ! 295: write(fd, "\001", 1); ! 296: write(fd, s, strlen(s)); ! 297: } ! 298: ! 299: alrmcatch() ! 300: { ! 301: signal(SIGALRM, alrmcatch); ! 302: return(-1); ! 303: } ! 304: ! 305: sttyek(fd) ! 306: { ! 307: struct sgttyb vec; ! 308: ! 309: gtty(fd, &vec); ! 310: vec.sg_erase = '#'; ! 311: vec.sg_kill = '@'; ! 312: vec.sg_flags |= XTABS; ! 313: stty(fd, &vec); ! 314: } ! 315: ! 316: doremotelogin(host) ! 317: char *host; ! 318: { ! 319: FILE *hostf; ! 320: int first = 1; ! 321: char *p; ! 322: ! 323: getstr(rusername, sizeof (rusername), "remuser"); ! 324: getstr(lusername, sizeof (lusername), "locuser"); ! 325: getstr(cmd, sizeof(cmd), "command"); ! 326: ! 327: if (getuid()) { ! 328: pwd = &nouser; ! 329: goto bad; ! 330: } ! 331: setpwent(); ! 332: pwd = getpwnam(lusername); ! 333: endpwent(); ! 334: if (pwd == NULL) { ! 335: pwd = &nouser; ! 336: goto bad; ! 337: } ! 338: hostf = pwd->pw_uid ? fopen(EQUIV, "r") : 0; ! 339: again: ! 340: if (hostf) { ! 341: char ahost[32]; ! 342: ! 343: while (fgets(ahost, sizeof (ahost), hostf)) { ! 344: char *user; ! 345: ! 346: if ((user = index(ahost, '\n')) != 0) ! 347: *user++ = '\0'; ! 348: if ((user = index(ahost, ' ')) != 0) ! 349: *user++ = '\0'; ! 350: if (!strcmp(host, ahost) && ! 351: !strcmp(rusername, user ? user : lusername)) { ! 352: fclose(hostf); ! 353: return (1); ! 354: } ! 355: } ! 356: fclose(hostf); ! 357: } ! 358: if (first == 1) { ! 359: char *rhosts = ".rhosts"; ! 360: struct stat sbuf; ! 361: ! 362: first = 0; ! 363: if (chdir(pwd->pw_dir) < 0) ! 364: goto again; ! 365: if (lstat(rhosts, &sbuf) < 0) ! 366: goto again; ! 367: if ((sbuf.st_mode & S_IFMT) == S_IFLNK) { ! 368: printf("login: .rhosts is a soft link.\r\n"); ! 369: goto bad; ! 370: } ! 371: hostf = fopen(rhosts, "r"); ! 372: fstat(fileno(hostf), &sbuf); ! 373: if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) { ! 374: printf("login: Bad .rhosts ownership.\r\n"); ! 375: fclose(hostf); ! 376: goto bad; ! 377: } ! 378: goto again; ! 379: } ! 380: bad: ! 381: return (-1); ! 382: } ! 383: ! 384: getstr(buf, cnt, err) ! 385: char *buf; ! 386: int cnt; ! 387: char *err; ! 388: { ! 389: char c; ! 390: ! 391: do { ! 392: if (read(0, &c, 1) != 1) ! 393: exit(1); ! 394: if (--cnt < 0) { ! 395: printf("%s too long\r\n", err); ! 396: exit(1); ! 397: } ! 398: *buf++ = c; ! 399: } while (c != 0); ! 400: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.