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