|
|
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.50.1.1 (Berkeley) 10/21/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: #endif ! 133: case '?': ! 134: default: ! 135: usage(); ! 136: break; ! 137: } ! 138: argc -= optind; ! 139: argv += optind; ! 140: ! 141: #ifdef KERBEROS ! 142: if (use_kerberos && vacuous) { ! 143: usage(); ! 144: fatal(STDERR_FILENO, "only one of -k and -v allowed", 0); ! 145: } ! 146: #endif ! 147: fromlen = sizeof (from); ! 148: if (getpeername(0, &from, &fromlen) < 0) { ! 149: syslog(LOG_ERR,"Can't get peer name of remote host: %m"); ! 150: fatal(STDERR_FILENO, "Can't get peer name of remote host", 1); ! 151: } ! 152: if (keepalive && ! 153: setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) ! 154: syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); ! 155: on = IPTOS_LOWDELAY; ! 156: if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) ! 157: syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); ! 158: doit(0, &from); ! 159: } ! 160: ! 161: int child; ! 162: int cleanup(); ! 163: int netf; ! 164: char line[MAXPATHLEN]; ! 165: int confirmed; ! 166: extern char *inet_ntoa(); ! 167: ! 168: struct winsize win = { 0, 0, 0, 0 }; ! 169: ! 170: ! 171: doit(f, fromp) ! 172: int f; ! 173: struct sockaddr_in *fromp; ! 174: { ! 175: int i, master, pid, on = 1; ! 176: int authenticated = 0, hostok = 0; ! 177: register struct hostent *hp; ! 178: char remotehost[2 * MAXHOSTNAMELEN + 1]; ! 179: struct hostent hostent; ! 180: char c; ! 181: ! 182: alarm(60); ! 183: read(f, &c, 1); ! 184: ! 185: if (c != 0) ! 186: exit(1); ! 187: #ifdef KERBEROS ! 188: if (vacuous) ! 189: fatal(f, "Remote host requires Kerberos authentication", 0); ! 190: #endif ! 191: ! 192: alarm(0); ! 193: fromp->sin_port = ntohs((u_short)fromp->sin_port); ! 194: hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr), ! 195: fromp->sin_family); ! 196: if (hp == 0) { ! 197: /* ! 198: * Only the name is used below. ! 199: */ ! 200: hp = &hostent; ! 201: hp->h_name = inet_ntoa(fromp->sin_addr); ! 202: hostok++; ! 203: } else if (check_all || local_domain(hp->h_name)) { ! 204: /* ! 205: * If name returned by gethostbyaddr is in our domain, ! 206: * attempt to verify that we haven't been fooled by someone ! 207: * in a remote net; look up the name and check that this ! 208: * address corresponds to the name. ! 209: */ ! 210: strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); ! 211: remotehost[sizeof(remotehost) - 1] = 0; ! 212: hp = gethostbyname(remotehost); ! 213: if (hp) ! 214: for (; hp->h_addr_list[0]; hp->h_addr_list++) ! 215: if (!bcmp(hp->h_addr_list[0], (caddr_t)&fromp->sin_addr, ! 216: sizeof(fromp->sin_addr))) { ! 217: hostok++; ! 218: break; ! 219: } ! 220: } else ! 221: hostok++; ! 222: ! 223: #ifdef KERBEROS ! 224: if (use_kerberos) { ! 225: if (!hostok) ! 226: fatal(f, "rlogind: Host address mismatch.", 0); ! 227: retval = do_krb_login(hp->h_name, fromp, encrypt); ! 228: if (retval == 0) ! 229: authenticated++; ! 230: else if (retval > 0) ! 231: fatal(f, krb_err_txt[retval], 0); ! 232: write(f, &c, 1); ! 233: confirmed = 1; /* we sent the null! */ ! 234: } else ! 235: #endif ! 236: { ! 237: if (fromp->sin_family != AF_INET || ! 238: fromp->sin_port >= IPPORT_RESERVED || ! 239: fromp->sin_port < IPPORT_RESERVED/2) { ! 240: syslog(LOG_NOTICE, "Connection from %s on illegal port", ! 241: inet_ntoa(fromp->sin_addr)); ! 242: fatal(f, "Permission denied", 0); ! 243: } ! 244: #ifdef IP_OPTIONS ! 245: { ! 246: u_char optbuf[BUFSIZ/3], *cp; ! 247: char lbuf[BUFSIZ], *lp; ! 248: int optsize = sizeof(optbuf), ipproto; ! 249: struct protoent *ip; ! 250: ! 251: if ((ip = getprotobyname("ip")) != NULL) ! 252: ipproto = ip->p_proto; ! 253: else ! 254: ipproto = IPPROTO_IP; ! 255: if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, ! 256: &optsize) == 0 && optsize != 0) { ! 257: lp = lbuf; ! 258: for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3) ! 259: sprintf(lp, " %2.2x", *cp); ! 260: syslog(LOG_NOTICE, ! 261: "Connection received using IP options (ignored):%s", ! 262: lbuf); ! 263: if (setsockopt(0, ipproto, IP_OPTIONS, ! 264: (char *)NULL, &optsize) != 0) { ! 265: syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m"); ! 266: exit(1); ! 267: } ! 268: } ! 269: } ! 270: #endif ! 271: if (do_rlogin(hp->h_name) == 0 && hostok) ! 272: authenticated++; ! 273: } ! 274: if (confirmed == 0) { ! 275: write(f, "", 1); ! 276: confirmed = 1; /* we sent the null! */ ! 277: } ! 278: #ifdef KERBEROS ! 279: if (use_kerberos == 0) ! 280: #endif ! 281: if (!authenticated && !hostok) ! 282: write(f, "rlogind: Host address mismatch.\r\n", ! 283: sizeof("rlogind: Host address mismatch.\r\n") - 1); ! 284: ! 285: netf = f; ! 286: ! 287: pid = forkpty(&master, line, NULL, &win); ! 288: if (pid < 0) { ! 289: if (errno == ENOENT) ! 290: fatal(f, "Out of ptys", 0); ! 291: else ! 292: fatal(f, "Forkpty", 1); ! 293: } ! 294: if (pid == 0) { ! 295: if (f > 2) /* f should always be 0, but... */ ! 296: (void) close(f); ! 297: setup_term(0); ! 298: if (authenticated) { ! 299: #ifdef KERBEROS ! 300: if (use_kerberos && (pwd->pw_uid == 0)) ! 301: syslog(LOG_INFO|LOG_AUTH, ! 302: "ROOT Kerberos login from %s.%s@%s on %s\n", ! 303: kdata->pname, kdata->pinst, kdata->prealm, ! 304: hp->h_name); ! 305: #endif ! 306: ! 307: execl(_PATH_LOGIN, "login", "-p", ! 308: "-h", hp->h_name, "-f", lusername, 0); ! 309: } else ! 310: execl(_PATH_LOGIN, "login", "-p", ! 311: "-h", hp->h_name, lusername, 0); ! 312: fatal(STDERR_FILENO, _PATH_LOGIN, 1); ! 313: /*NOTREACHED*/ ! 314: } ! 315: ioctl(f, FIONBIO, &on); ! 316: ioctl(master, FIONBIO, &on); ! 317: ioctl(master, TIOCPKT, &on); ! 318: signal(SIGCHLD, cleanup); ! 319: protocol(f, master); ! 320: signal(SIGCHLD, SIG_IGN); ! 321: cleanup(); ! 322: } ! 323: ! 324: char magic[2] = { 0377, 0377 }; ! 325: char oobdata[] = {TIOCPKT_WINDOW}; ! 326: ! 327: /* ! 328: * Handle a "control" request (signaled by magic being present) ! 329: * in the data stream. For now, we are only willing to handle ! 330: * window size changes. ! 331: */ ! 332: control(pty, cp, n) ! 333: int pty; ! 334: char *cp; ! 335: int n; ! 336: { ! 337: struct winsize w; ! 338: ! 339: if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's') ! 340: return (0); ! 341: oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ ! 342: bcopy(cp+4, (char *)&w, sizeof(w)); ! 343: w.ws_row = ntohs(w.ws_row); ! 344: w.ws_col = ntohs(w.ws_col); ! 345: w.ws_xpixel = ntohs(w.ws_xpixel); ! 346: w.ws_ypixel = ntohs(w.ws_ypixel); ! 347: (void)ioctl(pty, TIOCSWINSZ, &w); ! 348: return (4+sizeof (w)); ! 349: } ! 350: ! 351: /* ! 352: * rlogin "protocol" machine. ! 353: */ ! 354: protocol(f, p) ! 355: register int f, p; ! 356: { ! 357: char pibuf[1024+1], fibuf[1024], *pbp, *fbp; ! 358: register pcc = 0, fcc = 0; ! 359: int cc, nfd, n; ! 360: char cntl; ! 361: ! 362: /* ! 363: * Must ignore SIGTTOU, otherwise we'll stop ! 364: * when we try and set slave pty's window shape ! 365: * (our controlling tty is the master pty). ! 366: */ ! 367: (void) signal(SIGTTOU, SIG_IGN); ! 368: send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ ! 369: if (f > p) ! 370: nfd = f + 1; ! 371: else ! 372: nfd = p + 1; ! 373: if (nfd > FD_SETSIZE) { ! 374: syslog(LOG_ERR, "select mask too small, increase FD_SETSIZE"); ! 375: fatal(f, "internal error (select mask too small)", 0); ! 376: } ! 377: for (;;) { ! 378: fd_set ibits, obits, ebits, *omask; ! 379: ! 380: FD_ZERO(&ebits); ! 381: FD_ZERO(&ibits); ! 382: FD_ZERO(&obits); ! 383: omask = (fd_set *)NULL; ! 384: if (fcc) { ! 385: FD_SET(p, &obits); ! 386: omask = &obits; ! 387: } else ! 388: FD_SET(f, &ibits); ! 389: if (pcc >= 0) ! 390: if (pcc) { ! 391: FD_SET(f, &obits); ! 392: omask = &obits; ! 393: } else ! 394: FD_SET(p, &ibits); ! 395: FD_SET(p, &ebits); ! 396: if ((n = select(nfd, &ibits, omask, &ebits, 0)) < 0) { ! 397: if (errno == EINTR) ! 398: continue; ! 399: fatal(f, "select", 1); ! 400: } ! 401: if (n == 0) { ! 402: /* shouldn't happen... */ ! 403: sleep(5); ! 404: continue; ! 405: } ! 406: #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) ! 407: if (FD_ISSET(p, &ebits)) { ! 408: cc = read(p, &cntl, 1); ! 409: if (cc == 1 && pkcontrol(cntl)) { ! 410: cntl |= oobdata[0]; ! 411: send(f, &cntl, 1, MSG_OOB); ! 412: if (cntl & TIOCPKT_FLUSHWRITE) { ! 413: pcc = 0; ! 414: FD_CLR(p, &ibits); ! 415: } ! 416: } ! 417: } ! 418: if (FD_ISSET(f, &ibits)) { ! 419: fcc = read(f, fibuf, sizeof(fibuf)); ! 420: if (fcc < 0 && errno == EWOULDBLOCK) ! 421: fcc = 0; ! 422: else { ! 423: register char *cp; ! 424: int left, n; ! 425: ! 426: if (fcc <= 0) ! 427: break; ! 428: fbp = fibuf; ! 429: ! 430: top: ! 431: for (cp = fibuf; cp < fibuf+fcc-1; cp++) ! 432: if (cp[0] == magic[0] && ! 433: cp[1] == magic[1]) { ! 434: left = fcc - (cp-fibuf); ! 435: n = control(p, cp, left); ! 436: if (n) { ! 437: left -= n; ! 438: if (left > 0) ! 439: bcopy(cp+n, cp, left); ! 440: fcc -= n; ! 441: goto top; /* n^2 */ ! 442: } ! 443: } ! 444: FD_SET(p, &obits); /* try write */ ! 445: } ! 446: } ! 447: ! 448: if (FD_ISSET(p, &obits) && fcc > 0) { ! 449: cc = write(p, fbp, fcc); ! 450: if (cc > 0) { ! 451: fcc -= cc; ! 452: fbp += cc; ! 453: } ! 454: } ! 455: ! 456: if (FD_ISSET(p, &ibits)) { ! 457: pcc = read(p, pibuf, sizeof (pibuf)); ! 458: pbp = pibuf; ! 459: if (pcc < 0 && errno == EWOULDBLOCK) ! 460: pcc = 0; ! 461: else if (pcc <= 0) ! 462: break; ! 463: else if (pibuf[0] == 0) { ! 464: pbp++, pcc--; ! 465: FD_SET(f, &obits); /* try write */ ! 466: } else { ! 467: if (pkcontrol(pibuf[0])) { ! 468: pibuf[0] |= oobdata[0]; ! 469: send(f, &pibuf[0], 1, MSG_OOB); ! 470: } ! 471: pcc = 0; ! 472: } ! 473: } ! 474: if ((FD_ISSET(f, &obits)) && pcc > 0) { ! 475: cc = write(f, pbp, pcc); ! 476: if (cc < 0 && errno == EWOULDBLOCK) { ! 477: /* ! 478: * This happens when we try write after read ! 479: * from p, but some old kernels balk at large ! 480: * writes even when select returns true. ! 481: */ ! 482: if (!FD_ISSET(p, &ibits)) ! 483: sleep(5); ! 484: continue; ! 485: } ! 486: if (cc > 0) { ! 487: pcc -= cc; ! 488: pbp += cc; ! 489: } ! 490: } ! 491: } ! 492: } ! 493: ! 494: cleanup() ! 495: { ! 496: char *p; ! 497: ! 498: p = line + sizeof(_PATH_DEV) - 1; ! 499: if (logout(p)) ! 500: logwtmp(p, "", ""); ! 501: (void)chmod(line, 0666); ! 502: (void)chown(line, 0, 0); ! 503: *p = 'p'; ! 504: (void)chmod(line, 0666); ! 505: (void)chown(line, 0, 0); ! 506: shutdown(netf, 2); ! 507: exit(1); ! 508: } ! 509: ! 510: fatal(f, msg, syserr) ! 511: int f, syserr; ! 512: char *msg; ! 513: { ! 514: int len; ! 515: char buf[BUFSIZ], *bp = buf; ! 516: ! 517: /* ! 518: * Prepend binary one to message if we haven't sent ! 519: * the magic null as confirmation. ! 520: */ ! 521: if (!confirmed) ! 522: *bp++ = '\01'; /* error indicator */ ! 523: if (syserr) ! 524: len = sprintf(bp, "rlogind: %s: %s.\r\n", ! 525: msg, strerror(errno)); ! 526: else ! 527: len = sprintf(bp, "rlogind: %s.\r\n", msg); ! 528: (void) write(f, buf, bp + len - buf); ! 529: exit(1); ! 530: } ! 531: ! 532: do_rlogin(host) ! 533: char *host; ! 534: { ! 535: getstr(rusername, sizeof(rusername), "remuser too long"); ! 536: getstr(lusername, sizeof(lusername), "locuser too long"); ! 537: getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); ! 538: ! 539: pwd = getpwnam(lusername); ! 540: if (pwd == NULL) ! 541: return(-1); ! 542: if (pwd->pw_uid == 0) ! 543: return(-1); ! 544: return(ruserok(host, 0, rusername, lusername)); ! 545: } ! 546: ! 547: ! 548: getstr(buf, cnt, errmsg) ! 549: char *buf; ! 550: int cnt; ! 551: char *errmsg; ! 552: { ! 553: char c; ! 554: ! 555: do { ! 556: if (read(0, &c, 1) != 1) ! 557: exit(1); ! 558: if (--cnt < 0) ! 559: fatal(STDOUT_FILENO, errmsg, 0); ! 560: *buf++ = c; ! 561: } while (c != 0); ! 562: } ! 563: ! 564: extern char **environ; ! 565: ! 566: setup_term(fd) ! 567: int fd; ! 568: { ! 569: register char *cp = index(term+ENVSIZE, '/'); ! 570: char *speed; ! 571: struct termios tt; ! 572: ! 573: #ifndef notyet ! 574: tcgetattr(fd, &tt); ! 575: if (cp) { ! 576: *cp++ = '\0'; ! 577: speed = cp; ! 578: cp = index(speed, '/'); ! 579: if (cp) ! 580: *cp++ = '\0'; ! 581: cfsetspeed(&tt, atoi(speed)); ! 582: } ! 583: ! 584: tt.c_iflag = TTYDEF_IFLAG; ! 585: tt.c_oflag = TTYDEF_OFLAG; ! 586: tt.c_lflag = TTYDEF_LFLAG; ! 587: tcsetattr(fd, TCSAFLUSH, &tt); ! 588: #else ! 589: if (cp) { ! 590: *cp++ = '\0'; ! 591: speed = cp; ! 592: cp = index(speed, '/'); ! 593: if (cp) ! 594: *cp++ = '\0'; ! 595: tcgetattr(fd, &tt); ! 596: cfsetspeed(&tt, atoi(speed)); ! 597: tcsetattr(fd, TCSAFLUSH, &tt); ! 598: } ! 599: #endif ! 600: ! 601: env[0] = term; ! 602: env[1] = 0; ! 603: environ = env; ! 604: } ! 605: ! 606: #ifdef KERBEROS ! 607: #define VERSION_SIZE 9 ! 608: ! 609: /* ! 610: * Do the remote kerberos login to the named host with the ! 611: * given inet address ! 612: * ! 613: * Return 0 on valid authorization ! 614: * Return -1 on valid authentication, no authorization ! 615: * Return >0 for error conditions ! 616: */ ! 617: do_krb_login(host, dest, encrypt) ! 618: char *host; ! 619: struct sockaddr_in *dest; ! 620: int encrypt; ! 621: { ! 622: int rc; ! 623: char instance[INST_SZ], version[VERSION_SIZE]; ! 624: long authopts = 0L; /* !mutual */ ! 625: struct sockaddr_in faddr; ! 626: ! 627: kdata = (AUTH_DAT *) auth_buf; ! 628: ticket = (KTEXT) tick_buf; ! 629: ! 630: instance[0] = '*'; ! 631: instance[1] = '\0'; ! 632: ! 633: rc = krb_recvauth( ! 634: authopts, 0, ! 635: ticket, "rcmd", ! 636: instance, dest, (struct sockaddr_in *) 0, ! 637: kdata, "", (bit_64 *) 0, version); ! 638: ! 639: if (rc != KSUCCESS) ! 640: return(rc); ! 641: ! 642: getstr(lusername, sizeof(lusername), "locuser"); ! 643: /* get the "cmd" in the rcmd protocol */ ! 644: getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type"); ! 645: ! 646: pwd = getpwnam(lusername); ! 647: if (pwd == NULL) ! 648: return(-1); ! 649: ! 650: /* returns nonzero for no access */ ! 651: if (kuserok(kdata,lusername) != 0) ! 652: return(-1); ! 653: ! 654: return(0); ! 655: ! 656: } ! 657: #endif /* KERBEROS */ ! 658: ! 659: usage() ! 660: { ! 661: #ifdef KERBEROS ! 662: syslog(LOG_ERR, "usage: rlogind [-aln] [-k | -v]"); ! 663: #else ! 664: syslog(LOG_ERR, "usage: rlogind [-aln]"); ! 665: #endif ! 666: } ! 667: ! 668: /* ! 669: * Check whether host h is in our local domain, ! 670: * defined as sharing the last two components of the domain part, ! 671: * or the entire domain part if the local domain has only one component. ! 672: * If either name is unqualified (contains no '.'), ! 673: * assume that the host is local, as it will be ! 674: * interpreted as such. ! 675: */ ! 676: local_domain(h) ! 677: char *h; ! 678: { ! 679: char localhost[MAXHOSTNAMELEN]; ! 680: char *p1, *p2, *topdomain(); ! 681: ! 682: localhost[0] = 0; ! 683: (void) gethostname(localhost, sizeof(localhost)); ! 684: p1 = topdomain(localhost); ! 685: p2 = topdomain(h); ! 686: if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) ! 687: return(1); ! 688: return(0); ! 689: } ! 690: ! 691: char * ! 692: topdomain(h) ! 693: char *h; ! 694: { ! 695: register char *p; ! 696: char *maybe = NULL; ! 697: int dots = 0; ! 698: ! 699: for (p = h + strlen(h); p >= h; p--) { ! 700: if (*p == '.') { ! 701: if (++dots == 2) ! 702: return (p); ! 703: maybe = p; ! 704: } ! 705: } ! 706: return (maybe); ! 707: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.