|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983, 1988, 1989 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 the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1983, 1988, 1989 The Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)rlogind.c 5.48 (Berkeley) 6/27/90"; ! 26: #endif /* not lint */ ! 27: ! 28: #ifdef KERBEROS ! 29: /* From: ! 30: * $Source: /mit/kerberos/ucb/mit/rlogind/RCS/rlogind.c,v $ ! 31: * $Header: rlogind.c,v 5.0 89/06/26 18:31:01 kfall Locked $ ! 32: */ ! 33: #endif ! 34: ! 35: /* ! 36: * remote login server: ! 37: * \0 ! 38: * remuser\0 ! 39: * locuser\0 ! 40: * terminal_type/speed\0 ! 41: * data ! 42: */ ! 43: ! 44: #define FD_SETSIZE 16 /* don't need many bits for select */ ! 45: #include <sys/param.h> ! 46: #include <sys/stat.h> ! 47: #include <sys/socket.h> ! 48: #include <sys/wait.h> ! 49: #include <sys/file.h> ! 50: #include <sys/signal.h> ! 51: #include <sys/ioctl.h> ! 52: #include <sys/termios.h> ! 53: ! 54: #include <netinet/in.h> ! 55: #include <netinet/in_systm.h> ! 56: #include <netinet/ip.h> ! 57: ! 58: #include <errno.h> ! 59: #include <pwd.h> ! 60: #include <netdb.h> ! 61: #include <syslog.h> ! 62: #include <string.h> ! 63: #include <stdio.h> ! 64: #include <unistd.h> ! 65: #include "pathnames.h" ! 66: ! 67: #ifndef TIOCPKT_WINDOW ! 68: #define TIOCPKT_WINDOW 0x80 ! 69: #endif ! 70: ! 71: #ifdef KERBEROS ! 72: #include <kerberosIV/des.h> ! 73: #include <kerberosIV/krb.h> ! 74: #define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n" ! 75: ! 76: AUTH_DAT *kdata; ! 77: KTEXT ticket; ! 78: u_char auth_buf[sizeof(AUTH_DAT)]; ! 79: u_char tick_buf[sizeof(KTEXT_ST)]; ! 80: Key_schedule schedule; ! 81: int encrypt = 0, retval, use_kerberos = 0, vacuous = 0; ! 82: ! 83: #define ARGSTR "alnkvx" ! 84: #else ! 85: #define ARGSTR "aln" ! 86: #endif /* KERBEROS */ ! 87: ! 88: char *env[2]; ! 89: #define NMAX 30 ! 90: char lusername[NMAX+1], rusername[NMAX+1]; ! 91: static char term[64] = "TERM="; ! 92: #define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ ! 93: int keepalive = 1; ! 94: int check_all = 0; ! 95: ! 96: extern int errno; ! 97: int reapchild(); ! 98: struct passwd *getpwnam(), *pwd; ! 99: char *malloc(); ! 100: ! 101: main(argc, argv) ! 102: int argc; ! 103: char **argv; ! 104: { ! 105: extern int opterr, optind; ! 106: extern int _check_rhosts_file; ! 107: int ch; ! 108: int on = 1, fromlen; ! 109: struct sockaddr_in from; ! 110: ! 111: openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH); ! 112: ! 113: opterr = 0; ! 114: while ((ch = getopt(argc, argv, ARGSTR)) != EOF) ! 115: switch (ch) { ! 116: case 'a': ! 117: check_all = 1; ! 118: break; ! 119: case 'l': ! 120: _check_rhosts_file = 0; ! 121: break; ! 122: case 'n': ! 123: keepalive = 0; ! 124: break; ! 125: #ifdef KERBEROS ! 126: case 'k': ! 127: use_kerberos = 1; ! 128: break; ! 129: case 'v': ! 130: vacuous = 1; ! 131: break; ! 132: case 'x': ! 133: encrypt = 1; ! 134: break; ! 135: #endif ! 136: case '?': ! 137: default: ! 138: usage(); ! 139: break; ! 140: } ! 141: argc -= optind; ! 142: argv += optind; ! 143: ! 144: #ifdef KERBEROS ! 145: if (use_kerberos && vacuous) { ! 146: usage(); ! 147: fatal(STDERR_FILENO, "only one of -k and -v allowed", 0); ! 148: } ! 149: #endif ! 150: fromlen = sizeof (from); ! 151: if (getpeername(0, &from, &fromlen) < 0) { ! 152: syslog(LOG_ERR,"Can't get peer name of remote host: %m"); ! 153: fatal(STDERR_FILENO, "Can't get peer name of remote host", 1); ! 154: } ! 155: if (keepalive && ! 156: setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) ! 157: syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); ! 158: on = IPTOS_LOWDELAY; ! 159: if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) ! 160: syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); ! 161: doit(0, &from); ! 162: } ! 163: ! 164: int child; ! 165: int cleanup(); ! 166: int netf; ! 167: char line[MAXPATHLEN]; ! 168: int confirmed; ! 169: extern char *inet_ntoa(); ! 170: ! 171: struct winsize win = { 0, 0, 0, 0 }; ! 172: ! 173: ! 174: doit(f, fromp) ! 175: int f; ! 176: struct sockaddr_in *fromp; ! 177: { ! 178: int i, master, pid, on = 1; ! 179: int authenticated = 0, hostok = 0; ! 180: register struct hostent *hp; ! 181: char remotehost[2 * MAXHOSTNAMELEN + 1]; ! 182: struct hostent hostent; ! 183: char c; ! 184: ! 185: alarm(60); ! 186: read(f, &c, 1); ! 187: ! 188: if (c != 0) ! 189: exit(1); ! 190: #ifdef KERBEROS ! 191: if (vacuous) ! 192: fatal(f, "Remote host requires Kerberos authentication", 0); ! 193: #endif ! 194: ! 195: alarm(0); ! 196: fromp->sin_port = ntohs((u_short)fromp->sin_port); ! 197: hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), ! 198: fromp->sin_family); ! 199: if (hp == 0) { ! 200: /* ! 201: * Only the name is used below. ! 202: */ ! 203: hp = &hostent; ! 204: hp->h_name = inet_ntoa(fromp->sin_addr); ! 205: hostok++; ! 206: } else if (check_all || local_domain(hp->h_name)) { ! 207: /* ! 208: * If name returned by gethostbyaddr is in our domain, ! 209: * attempt to verify that we haven't been fooled by someone ! 210: * in a remote net; look up the name and check that this ! 211: * address corresponds to the name. ! 212: */ ! 213: strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); ! 214: remotehost[sizeof(remotehost) - 1] = 0; ! 215: hp = gethostbyname(remotehost); ! 216: if (hp) ! 217: for (; hp->h_addr_list[0]; hp->h_addr_list++) ! 218: if (!bcmp(hp->h_addr_list[0], (caddr_t)&fromp->sin_addr, ! 219: sizeof(fromp->sin_addr))) { ! 220: hostok++; ! 221: break; ! 222: } ! 223: } else ! 224: hostok++; ! 225: ! 226: #ifdef KERBEROS ! 227: if (use_kerberos) { ! 228: if (!hostok) ! 229: fatal(f, "rlogind: Host address mismatch.", 0); ! 230: retval = do_krb_login(hp->h_name, fromp, encrypt); ! 231: if (retval == 0) ! 232: authenticated++; ! 233: else if (retval > 0) ! 234: fatal(f, krb_err_txt[retval], 0); ! 235: write(f, &c, 1); ! 236: confirmed = 1; /* we sent the null! */ ! 237: } else ! 238: #endif ! 239: { ! 240: if (fromp->sin_family != AF_INET || ! 241: fromp->sin_port >= IPPORT_RESERVED || ! 242: fromp->sin_port < IPPORT_RESERVED/2) { ! 243: syslog(LOG_NOTICE, "Connection from %s on illegal port", ! 244: inet_ntoa(fromp->sin_addr)); ! 245: fatal(f, "Permission denied", 0); ! 246: } ! 247: #ifdef IP_OPTIONS ! 248: { ! 249: u_char optbuf[BUFSIZ/3], *cp; ! 250: char lbuf[BUFSIZ], *lp; ! 251: int optsize = sizeof(optbuf), ipproto; ! 252: struct protoent *ip; ! 253: ! 254: if ((ip = getprotobyname("ip")) != NULL) ! 255: ipproto = ip->p_proto; ! 256: else ! 257: ipproto = IPPROTO_IP; ! 258: if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, ! 259: &optsize) == 0 && optsize != 0) { ! 260: lp = lbuf; ! 261: for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3) ! 262: sprintf(lp, " %2.2x", *cp); ! 263: syslog(LOG_NOTICE, ! 264: "Connection received using IP options (ignored):%s", ! 265: lbuf); ! 266: if (setsockopt(0, ipproto, IP_OPTIONS, ! 267: (char *)NULL, &optsize) != 0) { ! 268: syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m"); ! 269: exit(1); ! 270: } ! 271: } ! 272: } ! 273: #endif ! 274: if (do_rlogin(hp->h_name) == 0 && hostok) ! 275: authenticated++; ! 276: } ! 277: if (confirmed == 0) { ! 278: write(f, "", 1); ! 279: confirmed = 1; /* we sent the null! */ ! 280: } ! 281: #ifdef KERBEROS ! 282: if (encrypt) ! 283: (void) des_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE)); ! 284: ! 285: if (use_kerberos == 0) ! 286: #endif ! 287: if (!authenticated && !hostok) ! 288: write(f, "rlogind: Host address mismatch.\r\n", ! 289: sizeof("rlogind: Host address mismatch.\r\n") - 1); ! 290: ! 291: netf = f; ! 292: ! 293: pid = forkpty(&master, line, NULL, &win); ! 294: if (pid < 0) { ! 295: if (errno == ENOENT) ! 296: fatal(f, "Out of ptys", 0); ! 297: else ! 298: fatal(f, "Forkpty", 1); ! 299: } ! 300: if (pid == 0) { ! 301: if (f > 2) /* f should always be 0, but... */ ! 302: (void) close(f); ! 303: setup_term(0); ! 304: if (authenticated) { ! 305: #ifdef KERBEROS ! 306: if (use_kerberos && (pwd->pw_uid == 0)) ! 307: syslog(LOG_INFO|LOG_AUTH, ! 308: "ROOT Kerberos login from %s.%s@%s on %s\n", ! 309: kdata->pname, kdata->pinst, kdata->prealm, ! 310: hp->h_name); ! 311: #endif ! 312: ! 313: execl(_PATH_LOGIN, "login", "-p", ! 314: "-h", hp->h_name, "-f", lusername, 0); ! 315: } else ! 316: execl(_PATH_LOGIN, "login", "-p", ! 317: "-h", hp->h_name, lusername, 0); ! 318: fatal(STDERR_FILENO, _PATH_LOGIN, 1); ! 319: /*NOTREACHED*/ ! 320: } ! 321: #ifdef KERBEROS ! 322: /* ! 323: * If encrypted, don't turn on NBIO or the des read/write ! 324: * routines will croak. ! 325: */ ! 326: ! 327: if (!encrypt) ! 328: #endif ! 329: ioctl(f, FIONBIO, &on); ! 330: ioctl(master, FIONBIO, &on); ! 331: ioctl(master, TIOCPKT, &on); ! 332: signal(SIGCHLD, cleanup); ! 333: protocol(f, master); ! 334: signal(SIGCHLD, SIG_IGN); ! 335: cleanup(); ! 336: } ! 337: ! 338: char magic[2] = { 0377, 0377 }; ! 339: char oobdata[] = {TIOCPKT_WINDOW}; ! 340: ! 341: /* ! 342: * Handle a "control" request (signaled by magic being present) ! 343: * in the data stream. For now, we are only willing to handle ! 344: * window size changes. ! 345: */ ! 346: control(pty, cp, n) ! 347: int pty; ! 348: char *cp; ! 349: int n; ! 350: { ! 351: struct winsize w; ! 352: ! 353: if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') ! 354: return (0); ! 355: oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ ! 356: bcopy(cp+4, (char *)&w, sizeof(w)); ! 357: w.ws_row = ntohs(w.ws_row); ! 358: w.ws_col = ntohs(w.ws_col); ! 359: w.ws_xpixel = ntohs(w.ws_xpixel); ! 360: w.ws_ypixel = ntohs(w.ws_ypixel); ! 361: (void)ioctl(pty, TIOCSWINSZ, &w); ! 362: return (4+sizeof (w)); ! 363: } ! 364: ! 365: /* ! 366: * rlogin "protocol" machine. ! 367: */ ! 368: protocol(f, p) ! 369: register int f, p; ! 370: { ! 371: char pibuf[1024+1], fibuf[1024], *pbp, *fbp; ! 372: register pcc = 0, fcc = 0; ! 373: int cc, nfd, n; ! 374: char cntl; ! 375: ! 376: /* ! 377: * Must ignore SIGTTOU, otherwise we'll stop ! 378: * when we try and set slave pty's window shape ! 379: * (our controlling tty is the master pty). ! 380: */ ! 381: (void) signal(SIGTTOU, SIG_IGN); ! 382: send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ ! 383: if (f > p) ! 384: nfd = f + 1; ! 385: else ! 386: nfd = p + 1; ! 387: if (nfd > FD_SETSIZE) { ! 388: syslog(LOG_ERR, "select mask too small, increase FD_SETSIZE"); ! 389: fatal(f, "internal error (select mask too small)", 0); ! 390: } ! 391: for (;;) { ! 392: fd_set ibits, obits, ebits, *omask; ! 393: ! 394: FD_ZERO(&ebits); ! 395: FD_ZERO(&ibits); ! 396: FD_ZERO(&obits); ! 397: omask = (fd_set *)NULL; ! 398: if (fcc) { ! 399: FD_SET(p, &obits); ! 400: omask = &obits; ! 401: } else ! 402: FD_SET(f, &ibits); ! 403: if (pcc >= 0) ! 404: if (pcc) { ! 405: FD_SET(f, &obits); ! 406: omask = &obits; ! 407: } else ! 408: FD_SET(p, &ibits); ! 409: FD_SET(p, &ebits); ! 410: if ((n = select(nfd, &ibits, omask, &ebits, 0)) < 0) { ! 411: if (errno == EINTR) ! 412: continue; ! 413: fatal(f, "select", 1); ! 414: } ! 415: if (n == 0) { ! 416: /* shouldn't happen... */ ! 417: sleep(5); ! 418: continue; ! 419: } ! 420: #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) ! 421: if (FD_ISSET(p, &ebits)) { ! 422: cc = read(p, &cntl, 1); ! 423: if (cc == 1 && pkcontrol(cntl)) { ! 424: cntl |= oobdata[0]; ! 425: send(f, &cntl, 1, MSG_OOB); ! 426: if (cntl & TIOCPKT_FLUSHWRITE) { ! 427: pcc = 0; ! 428: FD_CLR(p, &ibits); ! 429: } ! 430: } ! 431: } ! 432: if (FD_ISSET(f, &ibits)) { ! 433: #ifdef KERBEROS ! 434: if (encrypt) ! 435: fcc = des_read(f, fibuf, sizeof(fibuf)); ! 436: else ! 437: #endif ! 438: fcc = read(f, fibuf, sizeof(fibuf)); ! 439: if (fcc < 0 && errno == EWOULDBLOCK) ! 440: fcc = 0; ! 441: else { ! 442: register char *cp; ! 443: int left, n; ! 444: ! 445: if (fcc <= 0) ! 446: break; ! 447: fbp = fibuf; ! 448: ! 449: top: ! 450: for (cp = fibuf; cp < fibuf+fcc-1; cp++) ! 451: if (cp[0] == magic[0] && ! 452: cp[1] == magic[1]) { ! 453: left = fcc - (cp-fibuf); ! 454: n = control(p, cp, left); ! 455: if (n) { ! 456: left -= n; ! 457: if (left > 0) ! 458: bcopy(cp+n, cp, left); ! 459: fcc -= n; ! 460: goto top; /* n^2 */ ! 461: } ! 462: } ! 463: FD_SET(p, &obits); /* try write */ ! 464: } ! 465: } ! 466: ! 467: if (FD_ISSET(p, &obits) && fcc > 0) { ! 468: cc = write(p, fbp, fcc); ! 469: if (cc > 0) { ! 470: fcc -= cc; ! 471: fbp += cc; ! 472: } ! 473: } ! 474: ! 475: if (FD_ISSET(p, &ibits)) { ! 476: pcc = read(p, pibuf, sizeof (pibuf)); ! 477: pbp = pibuf; ! 478: if (pcc < 0 && errno == EWOULDBLOCK) ! 479: pcc = 0; ! 480: else if (pcc <= 0) ! 481: break; ! 482: else if (pibuf[0] == 0) { ! 483: pbp++, pcc--; ! 484: #ifdef KERBEROS ! 485: if (!encrypt) ! 486: #endif ! 487: FD_SET(f, &obits); /* try write */ ! 488: } else { ! 489: if (pkcontrol(pibuf[0])) { ! 490: pibuf[0] |= oobdata[0]; ! 491: send(f, &pibuf[0], 1, MSG_OOB); ! 492: } ! 493: pcc = 0; ! 494: } ! 495: } ! 496: if ((FD_ISSET(f, &obits)) && pcc > 0) { ! 497: #ifdef KERBEROS ! 498: if (encrypt) ! 499: cc = des_write(f, pbp, pcc); ! 500: else ! 501: #endif ! 502: cc = write(f, pbp, pcc); ! 503: if (cc < 0 && errno == EWOULDBLOCK) { ! 504: /* ! 505: * This happens when we try write after read ! 506: * from p, but some old kernels balk at large ! 507: * writes even when select returns true. ! 508: */ ! 509: if (!FD_ISSET(p, &ibits)) ! 510: sleep(5); ! 511: continue; ! 512: } ! 513: if (cc > 0) { ! 514: pcc -= cc; ! 515: pbp += cc; ! 516: } ! 517: } ! 518: } ! 519: } ! 520: ! 521: cleanup() ! 522: { ! 523: char *p; ! 524: ! 525: p = line + sizeof(_PATH_DEV) - 1; ! 526: if (logout(p)) ! 527: logwtmp(p, "", ""); ! 528: (void)chmod(line, 0666); ! 529: (void)chown(line, 0, 0); ! 530: *p = 'p'; ! 531: (void)chmod(line, 0666); ! 532: (void)chown(line, 0, 0); ! 533: shutdown(netf, 2); ! 534: exit(1); ! 535: } ! 536: ! 537: fatal(f, msg, syserr) ! 538: int f, syserr; ! 539: char *msg; ! 540: { ! 541: int len; ! 542: char buf[BUFSIZ], *bp = buf; ! 543: ! 544: /* ! 545: * Prepend binary one to message if we haven't sent ! 546: * the magic null as confirmation. ! 547: */ ! 548: if (!confirmed) ! 549: *bp++ = '\01'; /* error indicator */ ! 550: if (syserr) ! 551: len = sprintf(bp, "rlogind: %s: %s.\r\n", ! 552: msg, strerror(errno)); ! 553: else ! 554: len = sprintf(bp, "rlogind: %s.\r\n", msg); ! 555: (void) write(f, buf, bp + len - buf); ! 556: exit(1); ! 557: } ! 558: ! 559: do_rlogin(host) ! 560: char *host; ! 561: { ! 562: getstr(rusername, sizeof(rusername), "remuser too long"); ! 563: getstr(lusername, sizeof(lusername), "locuser too long"); ! 564: getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); ! 565: ! 566: pwd = getpwnam(lusername); ! 567: if (pwd == NULL) ! 568: return(-1); ! 569: if (pwd->pw_uid == 0) ! 570: return(-1); ! 571: return(ruserok(host, 0, rusername, lusername)); ! 572: } ! 573: ! 574: ! 575: getstr(buf, cnt, errmsg) ! 576: char *buf; ! 577: int cnt; ! 578: char *errmsg; ! 579: { ! 580: char c; ! 581: ! 582: do { ! 583: if (read(0, &c, 1) != 1) ! 584: exit(1); ! 585: if (--cnt < 0) ! 586: fatal(STDOUT_FILENO, errmsg, 0); ! 587: *buf++ = c; ! 588: } while (c != 0); ! 589: } ! 590: ! 591: extern char **environ; ! 592: ! 593: setup_term(fd) ! 594: int fd; ! 595: { ! 596: register char *cp = index(term+ENVSIZE, '/'); ! 597: char *speed; ! 598: struct termios tt; ! 599: ! 600: #ifndef notyet ! 601: tcgetattr(fd, &tt); ! 602: if (cp) { ! 603: *cp++ = '\0'; ! 604: speed = cp; ! 605: cp = index(speed, '/'); ! 606: if (cp) ! 607: *cp++ = '\0'; ! 608: cfsetspeed(&tt, atoi(speed)); ! 609: } ! 610: ! 611: tt.c_iflag = TTYDEF_IFLAG; ! 612: tt.c_oflag = TTYDEF_OFLAG; ! 613: tt.c_lflag = TTYDEF_LFLAG; ! 614: tcsetattr(fd, TCSAFLUSH, &tt); ! 615: #else ! 616: if (cp) { ! 617: *cp++ = '\0'; ! 618: speed = cp; ! 619: cp = index(speed, '/'); ! 620: if (cp) ! 621: *cp++ = '\0'; ! 622: tcgetattr(fd, &tt); ! 623: cfsetspeed(&tt, atoi(speed)); ! 624: tcsetattr(fd, TCSAFLUSH, &tt); ! 625: } ! 626: #endif ! 627: ! 628: env[0] = term; ! 629: env[1] = 0; ! 630: environ = env; ! 631: } ! 632: ! 633: #ifdef KERBEROS ! 634: #define VERSION_SIZE 9 ! 635: ! 636: /* ! 637: * Do the remote kerberos login to the named host with the ! 638: * given inet address ! 639: * ! 640: * Return 0 on valid authorization ! 641: * Return -1 on valid authentication, no authorization ! 642: * Return >0 for error conditions ! 643: */ ! 644: do_krb_login(host, dest, encrypt) ! 645: char *host; ! 646: struct sockaddr_in *dest; ! 647: int encrypt; ! 648: { ! 649: int rc; ! 650: char instance[INST_SZ], version[VERSION_SIZE]; ! 651: long authopts = 0L; /* !mutual */ ! 652: struct sockaddr_in faddr; ! 653: ! 654: kdata = (AUTH_DAT *) auth_buf; ! 655: ticket = (KTEXT) tick_buf; ! 656: ! 657: instance[0] = '*'; ! 658: instance[1] = '\0'; ! 659: ! 660: if (encrypt) { ! 661: rc = sizeof(faddr); ! 662: if (getsockname(0, &faddr, &rc)) ! 663: return(-1); ! 664: authopts = KOPT_DO_MUTUAL; ! 665: rc = krb_recvauth( ! 666: authopts, 0, ! 667: ticket, "rcmd", ! 668: instance, dest, &faddr, ! 669: kdata, "", schedule, version); ! 670: des_set_key(kdata->session, schedule); ! 671: ! 672: } else { ! 673: rc = krb_recvauth( ! 674: authopts, 0, ! 675: ticket, "rcmd", ! 676: instance, dest, (struct sockaddr_in *) 0, ! 677: kdata, "", (bit_64 *) 0, version); ! 678: } ! 679: ! 680: if (rc != KSUCCESS) ! 681: return(rc); ! 682: ! 683: getstr(lusername, sizeof(lusername), "locuser"); ! 684: /* get the "cmd" in the rcmd protocol */ ! 685: getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type"); ! 686: ! 687: pwd = getpwnam(lusername); ! 688: if (pwd == NULL) ! 689: return(-1); ! 690: ! 691: /* returns nonzero for no access */ ! 692: if (kuserok(kdata,lusername) != 0) ! 693: return(-1); ! 694: ! 695: return(0); ! 696: ! 697: } ! 698: #endif /* KERBEROS */ ! 699: ! 700: usage() ! 701: { ! 702: #ifdef KERBEROS ! 703: syslog(LOG_ERR, "usage: rlogind [-aln] [-k | -v]"); ! 704: #else ! 705: syslog(LOG_ERR, "usage: rlogind [-aln]"); ! 706: #endif ! 707: } ! 708: ! 709: /* ! 710: * Check whether host h is in our local domain, ! 711: * defined as sharing the last two components of the domain part, ! 712: * or the entire domain part if the local domain has only one component. ! 713: * If either name is unqualified (contains no '.'), ! 714: * assume that the host is local, as it will be ! 715: * interpreted as such. ! 716: */ ! 717: local_domain(h) ! 718: char *h; ! 719: { ! 720: char localhost[MAXHOSTNAMELEN]; ! 721: char *p1, *p2, *topdomain(); ! 722: ! 723: localhost[0] = 0; ! 724: (void) gethostname(localhost, sizeof(localhost)); ! 725: p1 = topdomain(localhost); ! 726: p2 = topdomain(h); ! 727: if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) ! 728: return(1); ! 729: return(0); ! 730: } ! 731: ! 732: char * ! 733: topdomain(h) ! 734: char *h; ! 735: { ! 736: register char *p; ! 737: char *maybe = NULL; ! 738: int dots = 0; ! 739: ! 740: for (p = h + strlen(h); p >= h; p--) { ! 741: if (*p == '.') { ! 742: if (++dots == 2) ! 743: return (p); ! 744: maybe = p; ! 745: } ! 746: } ! 747: return (maybe); ! 748: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.