📄 rlogind.c
字号:
else nfd = p + 1; if (nfd > FD_SETSIZE) { syslog(LOG_ERR, "select mask too small, increase FD_SETSIZE"); fatal(f, "internal error (select mask too small)", 0); } for (;;) { fd_set ibits, obits, ebits, *omask; FD_ZERO(&ebits); FD_ZERO(&ibits); FD_ZERO(&obits); omask = (fd_set *)NULL; if (fcc) { FD_SET(p, &obits); omask = &obits; } else FD_SET(f, &ibits); if (pcc >= 0) if (pcc) { FD_SET(f, &obits); omask = &obits; } else FD_SET(p, &ibits); FD_SET(p, &ebits); if ((n = select(nfd, &ibits, omask, &ebits, 0)) < 0) { if (errno == EINTR) continue; fatal(f, "select", 1); } if (n == 0) { /* shouldn't happen... */ sleep(5); continue; }#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) if (FD_ISSET(p, &ebits)) { cc = read(p, &cntl, 1); if (cc == 1 && pkcontrol(cntl)) { cntl |= oobdata[0]; send(f, &cntl, 1, MSG_OOB); if (cntl & TIOCPKT_FLUSHWRITE) { pcc = 0; FD_CLR(p, &ibits); } } } if (FD_ISSET(f, &ibits)) {#ifdef CRYPT#ifdef KERBEROS if (doencrypt) fcc = des_read(f, fibuf, sizeof(fibuf)); else#endif#endif fcc = read(f, fibuf, sizeof(fibuf)); if (fcc < 0 && errno == EWOULDBLOCK) fcc = 0; else { register char *cp; int left, n; if (fcc <= 0) break; fbp = fibuf; top: for (cp = fibuf; cp < fibuf+fcc-1; cp++) if (cp[0] == magic[0] && cp[1] == magic[1]) { left = fcc - (cp-fibuf); n = control(p, cp, left); if (n) { left -= n; if (left > 0) bcopy(cp+n, cp, left); fcc -= n; goto top; /* n^2 */ } } FD_SET(p, &obits); /* try write */ } } if (FD_ISSET(p, &obits) && fcc > 0) { cc = write(p, fbp, fcc); if (cc > 0) { fcc -= cc; fbp += cc; } } if (FD_ISSET(p, &ibits)) { pcc = read(p, pibuf, sizeof (pibuf)); pbp = pibuf; if (pcc < 0 && errno == EWOULDBLOCK) pcc = 0; else if (pcc <= 0) break; else if (pibuf[0] == 0) { pbp++, pcc--;#ifdef CRYPT#ifdef KERBEROS if (!doencrypt)#endif#endif FD_SET(f, &obits); /* try write */ } else { if (pkcontrol(pibuf[0])) { pibuf[0] |= oobdata[0]; send(f, &pibuf[0], 1, MSG_OOB); } pcc = 0; } } if ((FD_ISSET(f, &obits)) && pcc > 0) {#ifdef CRYPT#ifdef KERBEROS if (doencrypt) cc = des_write(f, pbp, pcc); else#endif#endif cc = write(f, pbp, pcc); if (cc < 0 && errno == EWOULDBLOCK) { /* * This happens when we try write after read * from p, but some old kernels balk at large * writes even when select returns true. */ if (!FD_ISSET(p, &ibits)) sleep(5); continue; } if (cc > 0) { pcc -= cc; pbp += cc; } } }}voidcleanup(signo) int signo;{ char *p; p = line + sizeof(_PATH_DEV) - 1; if (logout(p)) logwtmp(p, "", ""); (void)chmod(line, 0666); (void)chown(line, 0, 0); *p = 'p'; (void)chmod(line, 0666); (void)chown(line, 0, 0); shutdown(netf, 2); exit(1);}voidfatal(f, msg, syserr) int f; char *msg; int syserr;{ int len; char buf[BUFSIZ], *bp = buf; /* * Prepend binary one to message if we haven't sent * the magic null as confirmation. */ if (!confirmed) *bp++ = '\01'; /* error indicator */ if (syserr) len = sprintf(bp, "rlogind: %s: %s.\r\n", msg, strerror(errno)); else len = sprintf(bp, "rlogind: %s.\r\n", msg); (void) write(f, buf, bp + len - buf); exit(1);}intdo_rlogin(dest) struct sockaddr_in *dest;{ getstr(rusername, sizeof(rusername), "remuser too long"); getstr(lusername, sizeof(lusername), "locuser too long"); getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long"); pwd = getpwnam(lusername); if (pwd == NULL) return (-1); if (pwd->pw_uid == 0) return (-1); /* XXX why don't we syslog() failure? */ return (iruserok(dest->sin_addr.s_addr, 0, rusername, lusername));}voidgetstr(buf, cnt, errmsg) char *buf; int cnt; char *errmsg;{ char c; do { if (read(0, &c, 1) != 1) exit(1); if (--cnt < 0) fatal(STDOUT_FILENO, errmsg, 0); *buf++ = c; } while (c != 0);}extern char **environ;voidsetup_term(fd) int fd;{ register char *cp = index(term+ENVSIZE, '/'); char *speed; struct termios tt;#ifndef notyet tcgetattr(fd, &tt); if (cp) { *cp++ = '\0'; speed = cp; cp = index(speed, '/'); if (cp) *cp++ = '\0'; cfsetspeed(&tt, atoi(speed)); } tt.c_iflag = TTYDEF_IFLAG; tt.c_oflag = TTYDEF_OFLAG; tt.c_lflag = TTYDEF_LFLAG; tcsetattr(fd, TCSAFLUSH, &tt);#else if (cp) { *cp++ = '\0'; speed = cp; cp = index(speed, '/'); if (cp) *cp++ = '\0'; tcgetattr(fd, &tt); cfsetspeed(&tt, atoi(speed)); tcsetattr(fd, TCSAFLUSH, &tt); }#endif env[0] = term; env[1] = 0; environ = env;}#ifdef KERBEROS#define VERSION_SIZE 9/* * Do the remote kerberos login to the named host with the * given inet address * * Return 0 on valid authorization * Return -1 on valid authentication, no authorization * Return >0 for error conditions */intdo_krb_login(dest) struct sockaddr_in *dest;{ int rc; char instance[INST_SZ], version[VERSION_SIZE]; long authopts = 0L; /* !mutual */ struct sockaddr_in faddr; kdata = (AUTH_DAT *) auth_buf; ticket = (KTEXT) tick_buf; instance[0] = '*'; instance[1] = '\0';#ifdef CRYPT if (doencrypt) { rc = sizeof(faddr); if (getsockname(0, (struct sockaddr *)&faddr, &rc)) return (-1); authopts = KOPT_DO_MUTUAL; rc = krb_recvauth( authopts, 0, ticket, "rcmd", instance, dest, &faddr, kdata, "", schedule, version); des_set_key(kdata->session, schedule); } else#endif rc = krb_recvauth( authopts, 0, ticket, "rcmd", instance, dest, (struct sockaddr_in *) 0, kdata, "", (bit_64 *) 0, version); if (rc != KSUCCESS) return (rc); getstr(lusername, sizeof(lusername), "locuser"); /* get the "cmd" in the rcmd protocol */ getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type"); pwd = getpwnam(lusername); if (pwd == NULL) return (-1); /* returns nonzero for no access */ if (kuserok(kdata, lusername) != 0) return (-1); return (0);}#endif /* KERBEROS */voidusage(){#ifdef KERBEROS syslog(LOG_ERR, "usage: rlogind [-aln] [-k | -v]");#else syslog(LOG_ERR, "usage: rlogind [-aln]");#endif}/* * Check whether host h is in our local domain, * defined as sharing the last two components of the domain part, * or the entire domain part if the local domain has only one component. * If either name is unqualified (contains no '.'), * assume that the host is local, as it will be * interpreted as such. */intlocal_domain(h) char *h;{ char localhost[MAXHOSTNAMELEN]; char *p1, *p2; localhost[0] = 0; (void) gethostname(localhost, sizeof(localhost)); p1 = topdomain(localhost); p2 = topdomain(h); if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) return (1); return (0);}char *topdomain(h) char *h;{ register char *p; char *maybe = NULL; int dots = 0; for (p = h + strlen(h); p >= h; p--) { if (*p == '.') { if (++dots == 2) return (p); maybe = p; } } return (maybe);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -