diff options
author | Jeremie Le Hen <jlh@FreeBSD.org> | 2017-10-06 08:43:14 +0000 |
---|---|---|
committer | Jeremie Le Hen <jlh@FreeBSD.org> | 2017-10-06 08:43:14 +0000 |
commit | e415aa284663746c8babbba2d3871d26980a8b8a (patch) | |
tree | 99adf8549d7fb6aaa4ee39278ce7861a12002115 /libexec | |
parent | ac63ac6859873627940b3583904083f9716c564d (diff) | |
download | src-e415aa284663746c8babbba2d3871d26980a8b8a.tar.gz src-e415aa284663746c8babbba2d3871d26980a8b8a.zip |
Remove rcmds.
If they are still needed, you can find them in the net/bsdrcmds port.
This was proposed June, 20th and approved by various committers [1].
They have been marked as deprecated on CURRENT in r320644 [2] on July, 4th.
Both stable/11 and release/11.1 contain the deprecation notice (thanks to
allanjude@).
Note that ruptime(1)/rwho(1)/rwhod(8) were initially thought to be part of
rcmds but this was a mistake and those are therefore NOT removed.
[1] https://lists.freebsd.org/pipermail/freebsd-arch/2017-June/018239.html
[2] https://svnweb.freebsd.org/base?view=revision&revision=320644
Reviewed by: bapt, brooks
Differential Revision: https://reviews.freebsd.org/D12573
Notes
Notes:
svn path=/head/; revision=324351
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/Makefile | 5 | ||||
-rw-r--r-- | libexec/rlogind/Makefile | 23 | ||||
-rw-r--r-- | libexec/rlogind/Makefile.depend | 22 | ||||
-rw-r--r-- | libexec/rlogind/rlogind.8 | 202 | ||||
-rw-r--r-- | libexec/rlogind/rlogind.c | 583 | ||||
-rw-r--r-- | libexec/rshd/Makefile | 24 | ||||
-rw-r--r-- | libexec/rshd/Makefile.depend | 23 | ||||
-rw-r--r-- | libexec/rshd/rshd.8 | 277 | ||||
-rw-r--r-- | libexec/rshd/rshd.c | 617 |
9 files changed, 0 insertions, 1776 deletions
diff --git a/libexec/Makefile b/libexec/Makefile index 5c6130a18db6..37983f2069d0 100644 --- a/libexec/Makefile +++ b/libexec/Makefile @@ -79,11 +79,6 @@ _rtld-elf= rtld-elf SUBDIR+= rbootd .endif -.if ${MK_RCMDS} != "no" -_rlogind= rlogind -_rshd= rshd -.endif - .if ${MK_SENDMAIL} != "no" _mail.local= mail.local _smrsh= smrsh diff --git a/libexec/rlogind/Makefile b/libexec/rlogind/Makefile deleted file mode 100644 index 626b2e7457dd..000000000000 --- a/libexec/rlogind/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/4/93 -# $FreeBSD$ - -.include <src.opts.mk> - -PACKAGE=rcmds -PROG= rlogind -MAN= rlogind.8 -PACKAGE=rcmds -LIBADD= util -WARNS?= 2 - -.if ${MK_INET6_SUPPORT} != "no" -CFLAGS+= -DINET6 -.endif - -.if ${MK_BLACKLIST_SUPPORT} != "no" -CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include -LIBADD+= blacklist -LDFLAGS+=-L${LIBBLACKLISTDIR} -.endif - -.include <bsd.prog.mk> diff --git a/libexec/rlogind/Makefile.depend b/libexec/rlogind/Makefile.depend deleted file mode 100644 index 5ac9545f6f12..000000000000 --- a/libexec/rlogind/Makefile.depend +++ /dev/null @@ -1,22 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - include \ - include/arpa \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libblacklist \ - lib/libc \ - lib/libcompiler_rt \ - lib/libthr \ - lib/libutil \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/libexec/rlogind/rlogind.8 b/libexec/rlogind/rlogind.8 deleted file mode 100644 index 09ec8b5000a3..000000000000 --- a/libexec/rlogind/rlogind.8 +++ /dev/null @@ -1,202 +0,0 @@ -.\" Copyright (c) 1983, 1989, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)rlogind.8 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD$ -.\" -.Dd July 3, 2017 -.Dt RLOGIND 8 -.Os -.Sh NAME -.Nm rlogind -.Nd remote login server -.Sh SYNOPSIS -.Nm -.Op Fl Daln -.Sh DEPRECATION NOTICE -.Nm -is deprecated and will be removed from future versions of the -.Fx -base system. -If -.Nm -is still required, it can be installed from ports or packages -(net/bsdrcmds). -.Sh DESCRIPTION -The -.Nm -utility is the server for the -.Xr rlogin 1 -program. -The server provides a remote login facility -with authentication based on privileged port numbers from trusted hosts. -.Pp -Options supported by -.Nm : -.Bl -tag -width indent -.It Fl D -Set TCP_NODELAY socket option. -This improves responsiveness at the expense of -some additional network traffic. -.It Fl a -Ask hostname for verification. -.It Fl l -Prevent any authentication based on the user's -.Dq Pa .rhosts -file, unless the user is logging in as the superuser. -.It Fl n -Disable keep-alive messages. -.El -.Pp -The -.Nm -utility listens for service requests at the port indicated in -the -.Dq login -service specification; see -.Xr services 5 . -When a service request is received the following protocol -is initiated: -.Bl -enum -.It -The server checks the client's source port. -If the port is not in the range 512-1023, the server -aborts the connection. -.It -The server checks the client's source address -and requests the corresponding host name (see -.Xr gethostbyaddr 3 , -.Xr hosts 5 -and -.Xr named 8 ) . -If the hostname cannot be determined, -the dot-notation representation of the host address is used. -If the hostname is in the same domain as the server (according to -the last two components of the domain name), -or if the -.Fl a -option is given, -the addresses for the hostname are requested, -verifying that the name and address correspond. -Normal authentication is bypassed if the address verification fails. -.El -.Pp -Once the source port and address have been checked, -.Nm -proceeds with the authentication process described in -.Xr rshd 8 . -It then allocates a pseudo terminal (see -.Xr pty 4 ) , -and manipulates file descriptors so that the slave -half of the pseudo terminal becomes the -.Em stdin , -.Em stdout , -and -.Em stderr -for a login process. -The login process is an instance of the -.Xr login 1 -program, invoked with the -.Fl f -option if authentication has succeeded. -If automatic authentication fails, the user is -prompted to log in as if on a standard terminal line. -.Pp -The parent of the login process manipulates the master side of -the pseudo terminal, operating as an intermediary -between the login process and the client instance of the -.Xr rlogin 1 -program. -In normal operation, the packet protocol described -in -.Xr pty 4 -is invoked to provide -.Ql ^S/^Q -type facilities and propagate -interrupt signals to the remote programs. -The login process -propagates the client terminal's baud rate and terminal type, -as found in the environment variable, -.Ev TERM ; -see -.Xr environ 7 . -The screen or window size of the terminal is requested from the client, -and window size changes from the client are propagated to the pseudo terminal. -.Pp -Transport-level keepalive messages are enabled unless the -.Fl n -option is present. -The use of keepalive messages allows sessions to be timed out -if the client crashes or becomes unreachable. -.Sh FILES -.Bl -tag -width /etc/hostsxxxxxxxx -compact -.It Pa /etc/hosts -.It Pa /etc/hosts.equiv -.It Ev $HOME Ns Pa /.rhosts -.It Pa /var/run/nologin -.El -.Sh DIAGNOSTICS -All initial diagnostic messages are indicated -by a leading byte with a value of 1, -after which any network connections are closed. -If there are no errors before -.Xr login 1 -is invoked, a null byte is returned as in indication of success. -.Bl -tag -width Ds -.It Sy Try again. -A -.Xr fork 2 -by the server failed. -.El -.Sh SEE ALSO -.Xr login 1 , -.Xr ruserok 3 , -.Xr hosts 5 , -.Xr hosts.equiv 5 , -.Xr login.conf 5 , -.Xr nologin 5 , -.Xr services 5 , -.Xr rshd 8 -.Sh HISTORY -The -.Nm -utility appeared in -.Bx 4.2 . -.Pp -IPv6 support was added by WIDE/KAME project. -.Sh BUGS -The authentication procedure used here assumes the integrity -of each client machine and the connecting medium. -This is -insecure, but is useful in an -.Dq open -environment. -.Pp -A facility to allow all data exchanges to be encrypted should be -present. -.Pp -A more extensible protocol should be used. diff --git a/libexec/rlogind/rlogind.c b/libexec/rlogind/rlogind.c deleted file mode 100644 index 7ddcfe2a180c..000000000000 --- a/libexec/rlogind/rlogind.c +++ /dev/null @@ -1,583 +0,0 @@ -/*- - * Copyright (c) 1983, 1988, 1989, 1993 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2002 Networks Associates Technology, Inc. - * All rights reserved. - * - * Portions of this software were developed for the FreeBSD Project by - * ThinkSec AS and NAI Labs, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 - * ("CBOSS"), as part of the DARPA CHATS research program. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if 0 -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1983, 1988, 1989, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static const char sccsid[] = "@(#)rlogind.c 8.1 (Berkeley) 6/4/93"; -#endif /* not lint */ -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * remote login server: - * \0 - * remuser\0 - * locuser\0 - * terminal_type/speed\0 - * data - */ - -#define FD_SETSIZE 16 /* don't need many bits for select */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <signal.h> -#include <termios.h> - -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <netdb.h> - -#include <errno.h> -#include <libutil.h> -#include <paths.h> -#include <poll.h> -#include <pwd.h> -#include <syslog.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#ifdef USE_BLACKLIST -#include <blacklist.h> -#endif - -#ifndef TIOCPKT_WINDOW -#define TIOCPKT_WINDOW 0x80 -#endif - -#define ARGSTR "Daln" - -char *env[2]; -#define NMAX 30 -char lusername[NMAX+1], rusername[NMAX+1]; -static char term[64] = "TERM="; -#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */ -int keepalive = 1; -int check_all = 0; -int no_delay; - -struct passwd *pwd; - -union sockunion { - struct sockinet { - u_char si_len; - u_char si_family; - u_short si_port; - } su_si; - struct sockaddr_in su_sin; - struct sockaddr_in6 su_sin6; -}; -#define su_len su_si.si_len -#define su_family su_si.si_family -#define su_port su_si.si_port - -void doit(int, union sockunion *); -int control(int, char *, int); -void protocol(int, int); -void cleanup(int); -void fatal(int, char *, int); -int do_rlogin(union sockunion *); -void getstr(char *, int, char *); -void setup_term(int); -int do_krb_login(struct sockaddr_in *); -void usage(void); - - -int -main(int argc, char *argv[]) -{ - extern int __check_rhosts_file; - union sockunion from; - socklen_t fromlen; - int ch, on; - - openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH); - - opterr = 0; - while ((ch = getopt(argc, argv, ARGSTR)) != -1) - switch (ch) { - case 'D': - no_delay = 1; - break; - case 'a': - check_all = 1; - break; - case 'l': - __check_rhosts_file = 0; - break; - case 'n': - keepalive = 0; - break; - case '?': - default: - usage(); - break; - } - argc -= optind; - argv += optind; - - fromlen = sizeof (from); - if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { - syslog(LOG_ERR,"Can't get peer name of remote host: %m"); - fatal(STDERR_FILENO, "Can't get peer name of remote host", 1); - } - on = 1; - if (keepalive && - setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) - syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); - if (no_delay && - setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) - syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m"); - if (from.su_family == AF_INET) - { - on = IPTOS_LOWDELAY; - if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); - } - - doit(0, &from); - return 0; -} - -int child; -int netf; -char line[MAXPATHLEN]; -int confirmed; - -struct winsize win = { 0, 0, 0, 0 }; - - -void -doit(int f, union sockunion *fromp) -{ - int master, pid, on = 1; - int authenticated = 0; - char hostname[2 * MAXHOSTNAMELEN + 1]; - char nameinfo[2 * INET6_ADDRSTRLEN + 1]; - char c; - - alarm(60); - read(f, &c, 1); - - if (c != 0) - exit(1); - - alarm(0); - - realhostname_sa(hostname, sizeof(hostname) - 1, - (struct sockaddr *)fromp, fromp->su_len); - /* error check ? */ - fromp->su_port = ntohs((u_short)fromp->su_port); - hostname[sizeof(hostname) - 1] = '\0'; - - { - if ((fromp->su_family != AF_INET -#ifdef INET6 - && fromp->su_family != AF_INET6 -#endif - ) || - fromp->su_port >= IPPORT_RESERVED || - fromp->su_port < IPPORT_RESERVED/2) { - getnameinfo((struct sockaddr *)fromp, - fromp->su_len, - nameinfo, sizeof(nameinfo), NULL, 0, - NI_NUMERICHOST); - /* error check ? */ - syslog(LOG_NOTICE, "Connection from %s on illegal port", - nameinfo); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "illegal port"); -#endif - fatal(f, "Permission denied", 0); - } -#ifdef IP_OPTIONS - if (fromp->su_family == AF_INET) - { - u_char optbuf[BUFSIZ/3]; - socklen_t optsize = sizeof(optbuf); - int ipproto, i; - struct protoent *ip; - - if ((ip = getprotobyname("ip")) != NULL) - ipproto = ip->p_proto; - else - ipproto = IPPROTO_IP; - if (getsockopt(0, ipproto, IP_OPTIONS, (char *)optbuf, - &optsize) == 0 && optsize != 0) { - for (i = 0; i < optsize; ) { - u_char c = optbuf[i]; - if (c == IPOPT_LSRR || c == IPOPT_SSRR) { - syslog(LOG_NOTICE, - "Connection refused from %s with IP option %s", - inet_ntoa(fromp->su_sin.sin_addr), - c == IPOPT_LSRR ? "LSRR" : "SSRR"); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "source routing present"); -#endif - exit(1); - } - if (c == IPOPT_EOL) - break; - i += (c == IPOPT_NOP) ? 1 : optbuf[i+1]; - } - } - } -#endif - if (do_rlogin(fromp) == 0) - authenticated++; - } - if (confirmed == 0) { - write(f, "", 1); - confirmed = 1; /* we sent the null! */ - } - netf = f; - - pid = forkpty(&master, line, NULL, &win); - if (pid < 0) { - if (errno == ENOENT) - fatal(f, "Out of ptys", 0); - else - fatal(f, "Forkpty", 1); - } - if (pid == 0) { - if (f > 2) /* f should always be 0, but... */ - (void) close(f); - setup_term(0); - if (*lusername=='-') { - syslog(LOG_ERR, "tried to pass user \"%s\" to login", - lusername); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "invalid user"); -#endif - fatal(STDERR_FILENO, "invalid user", 0); - } -#ifdef USE_BLACKLIST - blacklist(0, STDIN_FILENO, "success"); -#endif - if (authenticated) { - execl(_PATH_LOGIN, "login", "-p", - "-h", hostname, "-f", lusername, (char *)NULL); - } else - execl(_PATH_LOGIN, "login", "-p", - "-h", hostname, lusername, (char *)NULL); - fatal(STDERR_FILENO, _PATH_LOGIN, 1); - /*NOTREACHED*/ - } - ioctl(f, FIONBIO, &on); - ioctl(master, FIONBIO, &on); - ioctl(master, TIOCPKT, &on); - signal(SIGCHLD, cleanup); - protocol(f, master); - signal(SIGCHLD, SIG_IGN); - cleanup(0); -} - -char magic[2] = { 0377, 0377 }; -char oobdata[] = {TIOCPKT_WINDOW}; - -/* - * Handle a "control" request (signaled by magic being present) - * in the data stream. For now, we are only willing to handle - * window size changes. - */ -int -control(int pty, char *cp, int n) -{ - struct winsize w; - - if (n < 4 + (int)sizeof(w) || cp[2] != 's' || cp[3] != 's') - return (0); - oobdata[0] &= ~TIOCPKT_WINDOW; /* we know he heard */ - bcopy(cp+4, (char *)&w, sizeof(w)); - w.ws_row = ntohs(w.ws_row); - w.ws_col = ntohs(w.ws_col); - w.ws_xpixel = ntohs(w.ws_xpixel); - w.ws_ypixel = ntohs(w.ws_ypixel); - (void)ioctl(pty, TIOCSWINSZ, &w); - return (4+sizeof (w)); -} - -/* - * rlogin "protocol" machine. - */ -void -protocol(int f, int p) -{ - char pibuf[1024+1], fibuf[1024], *pbp = NULL, *fbp = NULL; - int pcc = 0, fcc = 0; - int cc, nfd, n; - char cntl; - - /* - * Must ignore SIGTTOU, otherwise we'll stop - * when we try and set slave pty's window shape - * (our controlling tty is the master pty). - */ - (void) signal(SIGTTOU, SIG_IGN); - send(f, oobdata, 1, MSG_OOB); /* indicate new rlogin */ - if (f > p) - nfd = f + 1; - else - nfd = p + 1; - for (;;) { - struct pollfd set[2]; - - set[0].fd = p; - set[0].events = POLLPRI; - set[1].fd = f; - set[1].events = 0; - if (fcc) - set[0].events |= POLLOUT; - else - set[1].events |= POLLIN; - if (pcc >= 0) { - if (pcc) - set[1].events |= POLLOUT; - else - set[0].events |= POLLIN; - } - if ((n = poll(set, 2, INFTIM)) < 0) { - if (errno == EINTR) - continue; - fatal(f, "poll", 1); - } - if (n == 0) { - /* shouldn't happen... */ - sleep(5); - continue; - } -#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) - if (set[0].revents & POLLPRI) { - 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; - } - } - if (set[1].revents & POLLIN) { - fcc = read(f, fibuf, sizeof(fibuf)); - if (fcc < 0 && errno == EWOULDBLOCK) - fcc = 0; - else { - 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 */ - } - } - } - } - - if (set[0].revents & POLLOUT && fcc > 0) { - cc = write(p, fbp, fcc); - if (cc > 0) { - fcc -= cc; - fbp += cc; - } - } - - if (set[0].revents & POLLIN) { - 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--; - } else { - if (pkcontrol(pibuf[0])) { - pibuf[0] |= oobdata[0]; - send(f, &pibuf[0], 1, MSG_OOB); - } - pcc = 0; - } - } - if (set[1].revents & POLLOUT && pcc > 0) { - cc = write(f, pbp, pcc); - if (cc > 0) { - pcc -= cc; - pbp += cc; - } - } - } -} - -void -cleanup(int signo __unused) -{ - - shutdown(netf, SHUT_RDWR); - exit(1); -} - -void -fatal(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 = snprintf(bp, sizeof(buf), "rlogind: %s: %s.\r\n", - msg, strerror(errno)); - else - len = snprintf(bp, sizeof(buf), "rlogind: %s.\r\n", msg); - if (len < 0) - len = 0; - (void) write(f, buf, bp + len - buf); - exit(1); -} - -int -do_rlogin(union sockunion *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); - /* XXX why don't we syslog() failure? */ - - return (iruserok_sa(dest, dest->su_len, pwd->pw_uid == 0, rusername, - lusername)); -} - -void -getstr(char *buf, int cnt, char *errmsg) -{ - char c; - - do { - if (read(STDIN_FILENO, &c, 1) != 1) - exit(1); - if (--cnt < 0) { -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "buffer overflow"); -#endif - fatal(STDOUT_FILENO, errmsg, 0); - } - *buf++ = c; - } while (c != 0); -} - -extern char **environ; - -void -setup_term(int fd) -{ - char *cp; - char *speed; - struct termios tt, def; - - cp = strchr(term + ENVSIZE, '/'); -#ifndef notyet - tcgetattr(fd, &tt); - if (cp) { - *cp++ = '\0'; - speed = cp; - cp = strchr(speed, '/'); - if (cp) - *cp++ = '\0'; - cfsetspeed(&tt, atoi(speed)); - } - - cfmakesane(&def); - tt.c_iflag = def.c_iflag; - tt.c_oflag = def.c_oflag; - tt.c_lflag = def.c_lflag; - tcsetattr(fd, TCSAFLUSH, &tt); -#else - if (cp) { - *cp++ = '\0'; - speed = cp; - cp = strchr(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; -} - -void -usage(void) -{ - syslog(LOG_ERR, "usage: rlogind [-" ARGSTR "]"); -} diff --git a/libexec/rshd/Makefile b/libexec/rshd/Makefile deleted file mode 100644 index 924f2eff81b7..000000000000 --- a/libexec/rshd/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# From: @(#)Makefile 8.1 (Berkeley) 6/4/93 -# $FreeBSD$ - -PACKAGE=rcmds - -.include <src.opts.mk> - -PROG= rshd -MAN= rshd.8 - -PACKAGE=rcmds - -WARNS?= 3 -WFORMAT=0 - -LIBADD= util pam - -.if ${MK_BLACKLIST_SUPPORT} != "no" -CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include -LIBADD+= blacklist -LDFLAGS+=-L${LIBBLACKLISTDIR} -.endif - -.include <bsd.prog.mk> diff --git a/libexec/rshd/Makefile.depend b/libexec/rshd/Makefile.depend deleted file mode 100644 index 289484837f9a..000000000000 --- a/libexec/rshd/Makefile.depend +++ /dev/null @@ -1,23 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - include \ - include/arpa \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libblacklist \ - lib/libc \ - lib/libcompiler_rt \ - lib/libpam/libpam \ - lib/libthr \ - lib/libutil \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/libexec/rshd/rshd.8 b/libexec/rshd/rshd.8 deleted file mode 100644 index 700c2ed0b59c..000000000000 --- a/libexec/rshd/rshd.8 +++ /dev/null @@ -1,277 +0,0 @@ -.\" Copyright (c) 1983, 1989, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)rshd.8 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD$ -.\" -.Dd July 3, 2017 -.Dt RSHD 8 -.Os -.Sh NAME -.Nm rshd -.Nd remote shell server -.Sh SYNOPSIS -.Nm -.Op Fl aDLln -.Sh DEPRECATION NOTICE -.Nm -is deprecated and will be removed from future versions of the -.Fx -base system. -If -.Nm -is still required, it can be installed from ports or packages -(net/bsdrcmds). -.Sh DESCRIPTION -The -.Nm -utility -is the server for the -.Xr rcmd 3 -routine and, consequently, for the -.Xr rsh 1 -utility. -The server provides remote execution facilities -with authentication based on privileged port numbers from trusted hosts. -.Pp -The -.Nm -utility listens for service requests at the port indicated in -the -.Dq cmd -service specification; see -.Xr services 5 . -When a service request is received the following protocol -is initiated: -.Bl -enum -.It -The server checks the client's source port. -If the port is not in the range 512-1023, the server -aborts the connection. -.It -The server reads characters from the socket up -to a -.Tn NUL -(`\e0') byte. -The resultant string is -interpreted as an -.Tn ASCII -number, base 10. -.It -If the number received in step 2 is non-zero, -it is interpreted as the port number of a secondary -stream to be used for the -.Em stderr . -A second connection is then created to the specified -port on the client's machine. -The source port of this -second connection is also in the range 512-1023. -.It -The server checks the client's source address -and requests the corresponding host name (see -.Xr gethostbyaddr 3 , -.Xr hosts 5 -and -.Xr named 8 ) . -If the hostname cannot be determined or the hostname and address do -not match after verification, -the dot-notation representation of the host address is used. -.It -A null terminated user name of at most 16 characters -is retrieved on the initial socket. -This user name -is interpreted as the user identity on the -.Em client Ns 's -machine. -.It -A null terminated user name of at most 16 characters -is retrieved on the initial socket. -This user name -is interpreted as a user identity to use on the -.Em server Ns 's -machine. -.It -A null terminated command to be passed to a -shell is retrieved on the initial socket. -The length of -the command is limited by the upper bound on the size of -the system's argument list. -.It -The -.Nm -utility then validates the user using -.Xr ruserok 3 , -which uses the file -.Pa /etc/hosts.equiv -and the -.Pa .rhosts -file found in the user's home directory. -The -.Fl l -option prevents -.Xr ruserok 3 -from doing any validation based on the user's -.Pa .rhosts -file, -unless the user is the superuser. -.It -A -.Tn NUL -byte is returned on the initial socket -and the command line is passed to the normal login -shell of the user. -The -shell inherits the network connections established -by -.Nm . -.El -.Pp -The options are as follows: -.Bl -tag -width indent -.It Fl a -This flag is ignored, and is present for compatibility purposes. -.It Fl D -Sets the TCP_NODELAY socket option, which improves the performance -of small back-to-back writes at the expense of additional network -traffic. -.It Fl L -Causes all successful accesses to be logged to -.Xr syslogd 8 -as -.Li auth.info -messages. -.It Fl l -Do not use the user's -.Pa .rhosts -file for authentication, unless the user is the superuser. -.It Fl n -Turn off transport level keepalive messages. -This will prevent sessions -from timing out if the client crashes or becomes unreachable. -.El -.Sh FILES -.Bl -tag -width /var/run/nologin -compact -.It Pa /etc/hosts -.It Pa /etc/hosts.equiv -.It Pa /etc/login.conf -.It Ev $HOME Ns Pa /.rhosts -.Pp -.It Pa /etc/pam.conf -.Nm -uses -.Pa /etc/pam.conf -entries with service name -.Dq rsh . -Authentication modules requiring passwords (such as -.Nm pam_unix ) -are not supported. -.El -.Sh DIAGNOSTICS -Except for the last one listed below, -all diagnostic messages -are returned on the initial socket, -after which any network connections are closed. -An error is indicated by a leading byte with a value of -1 (0 is returned in step 10 above upon successful completion -of all the steps prior to the execution of the login shell). -.Bl -tag -width indent -.It Sy Locuser too long. -The name of the user on the client's machine is -longer than 16 characters. -.It Sy Ruser too long. -The name of the user on the remote machine is -longer than 16 characters. -.It Sy Command too long. -The command line passed exceeds the size of the argument -list (as configured into the system). -.It Sy Login incorrect. -No password file entry for the user name existed -or the authentication procedure described above failed. -.It Sy Remote directory. -The -.Xr chdir 2 -function to the home directory failed. -.It Sy Logins not available right now. -The -.Xr rsh 1 -utility was attempted outside the allowed hours defined in -.Pa /etc/login.conf -for the local user's login class. -.It Sy Can't make pipe. -The pipe needed for the -.Em stderr , -was not created. -.It Sy Can't fork; try again. -A -.Xr fork 2 -by the server failed. -.It Sy <shellname>: ... -The user's login shell could not be started. -This message is returned -on the connection associated with the -.Em stderr , -and is not preceded by a flag byte. -.El -.Sh SEE ALSO -.Xr rlogin 1 , -.Xr rsh 1 , -.Xr gethostbyaddr 3 , -.Xr rcmd 3 , -.Xr ruserok 3 , -.Xr hosts 5 , -.Xr hosts.equiv 5 , -.Xr login.conf 5 , -.Xr services 5 , -.Xr named 8 , -.Xr rlogind 8 , -.Xr syslogd 8 -.Sh HISTORY -IPv6 support was added by WIDE/KAME project. -.Sh BUGS -The authentication procedure used here assumes the integrity -of each client machine and the connecting medium. -This is -insecure, but is useful in an -.Dq open -environment. -.Pp -A facility to allow all data exchanges to be encrypted should be -present. -.Pp -Post-PAM, -.Fx -also needs the following patch applied besides properly configuring -.Pa .rhosts : -.Bd -literal -offset indent ---- etc/pam.d/rsh.orig Wed Dec 17 14:36:20 2003 -+++ etc/pam.d/rsh Wed Dec 17 14:30:43 2003 -@@ -9 +9 @@ --auth required pam_rhosts.so no_warn -+auth required pam_rhosts.so no_warn allow_root -.Ed -.Pp -A more extensible protocol (such as Telnet) should be used. diff --git a/libexec/rshd/rshd.c b/libexec/rshd/rshd.c deleted file mode 100644 index 3dcdea80a955..000000000000 --- a/libexec/rshd/rshd.c +++ /dev/null @@ -1,617 +0,0 @@ -/*- - * Copyright (c) 1988, 1989, 1992, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * Copyright (c) 2002 Networks Associates Technology, Inc. - * All rights reserved. - * - * Portions of this software were developed for the FreeBSD Project by - * ThinkSec AS and NAI Labs, the Security Research Division of Network - * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 - * ("CBOSS"), as part of the DARPA CHATS research program. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1988, 1989, 1992, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)rshd.c 8.2 (Berkeley) 4/6/94"; -#endif -#endif /* not lint */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * remote shell server: - * [port]\0 - * ruser\0 - * luser\0 - * command\0 - * data - */ -#include <sys/param.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <sys/socket.h> - -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <netdb.h> - -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <libutil.h> -#include <paths.h> -#include <pwd.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <login_cap.h> - -#include <security/pam_appl.h> -#include <security/openpam.h> -#include <sys/wait.h> - -#ifdef USE_BLACKLIST -#include <blacklist.h> -#endif - -static struct pam_conv pamc = { openpam_nullconv, NULL }; -static pam_handle_t *pamh; -static int pam_err; - -#define PAM_END { \ - if ((pam_err = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) \ - syslog(LOG_ERR|LOG_AUTH, "pam_setcred(): %s", pam_strerror(pamh, pam_err)); \ - if ((pam_err = pam_close_session(pamh,0)) != PAM_SUCCESS) \ - syslog(LOG_ERR|LOG_AUTH, "pam_close_session(): %s", pam_strerror(pamh, pam_err)); \ - if ((pam_err = pam_end(pamh, pam_err)) != PAM_SUCCESS) \ - syslog(LOG_ERR|LOG_AUTH, "pam_end(): %s", pam_strerror(pamh, pam_err)); \ -} - -int keepalive = 1; -int log_success; /* If TRUE, log all successful accesses */ -int sent_null; -int no_delay; - -void doit(struct sockaddr *); -static void rshd_errx(int, const char *, ...) __printf0like(2, 3); -void getstr(char *, int, const char *); -int local_domain(char *); -char *topdomain(char *); -void usage(void); - -char slash[] = "/"; -char bshell[] = _PATH_BSHELL; - -#define OPTIONS "aDLln" - -int -main(int argc, char *argv[]) -{ - extern int __check_rhosts_file; - struct linger linger; - socklen_t fromlen; - int ch, on = 1; - struct sockaddr_storage from; - - openlog("rshd", LOG_PID, LOG_DAEMON); - - opterr = 0; - while ((ch = getopt(argc, argv, OPTIONS)) != -1) - switch (ch) { - case 'a': - /* ignored for compatibility */ - break; - case 'l': - __check_rhosts_file = 0; - break; - case 'n': - keepalive = 0; - break; - case 'D': - no_delay = 1; - break; - case 'L': - log_success = 1; - break; - case '?': - default: - usage(); - break; - } - - argc -= optind; - argv += optind; - - fromlen = sizeof (from); - if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { - syslog(LOG_ERR, "getpeername: %m"); - exit(1); - } - if (keepalive && - setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, - sizeof(on)) < 0) - syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); - linger.l_onoff = 1; - linger.l_linger = 60; /* XXX */ - if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger, - sizeof (linger)) < 0) - syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m"); - if (no_delay && - setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) - syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m"); - doit((struct sockaddr *)&from); - /* NOTREACHED */ - return(0); -} - -extern char **environ; - -void -doit(struct sockaddr *fromp) -{ - extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */ - struct passwd *pwd; - u_short port; - fd_set ready, readfrom; - int cc, nfd, pv[2], pid, s; - int one = 1; - const char *cp, *errorstr; - char sig, buf[BUFSIZ]; - char *cmdbuf, luser[16], ruser[16]; - char rhost[2 * MAXHOSTNAMELEN + 1]; - char numericname[INET6_ADDRSTRLEN]; - int af, srcport; - int maxcmdlen; - login_cap_t *lc; - - maxcmdlen = (int)sysconf(_SC_ARG_MAX); - if (maxcmdlen <= 0 || (cmdbuf = malloc(maxcmdlen)) == NULL) - exit(1); - - (void) signal(SIGINT, SIG_DFL); - (void) signal(SIGQUIT, SIG_DFL); - (void) signal(SIGTERM, SIG_DFL); - af = fromp->sa_family; - srcport = ntohs(*((in_port_t *)&fromp->sa_data)); - if (af == AF_INET) { - inet_ntop(af, &((struct sockaddr_in *)fromp)->sin_addr, - numericname, sizeof numericname); - } else if (af == AF_INET6) { - inet_ntop(af, &((struct sockaddr_in6 *)fromp)->sin6_addr, - numericname, sizeof numericname); - } else { - syslog(LOG_ERR, "malformed \"from\" address (af %d)", af); - exit(1); - } -#ifdef IP_OPTIONS - if (af == AF_INET) { - u_char optbuf[BUFSIZ/3]; - socklen_t optsize = sizeof(optbuf), ipproto, i; - struct protoent *ip; - - if ((ip = getprotobyname("ip")) != NULL) - ipproto = ip->p_proto; - else - ipproto = IPPROTO_IP; - if (!getsockopt(0, ipproto, IP_OPTIONS, optbuf, &optsize) && - optsize != 0) { - for (i = 0; i < optsize; ) { - u_char c = optbuf[i]; - if (c == IPOPT_LSRR || c == IPOPT_SSRR) { - syslog(LOG_NOTICE, - "connection refused from %s with IP option %s", - numericname, - c == IPOPT_LSRR ? "LSRR" : "SSRR"); - exit(1); - } - if (c == IPOPT_EOL) - break; - i += (c == IPOPT_NOP) ? 1 : optbuf[i+1]; - } - } - } -#endif - - if (srcport >= IPPORT_RESERVED || - srcport < IPPORT_RESERVED/2) { - syslog(LOG_NOTICE|LOG_AUTH, - "connection from %s on illegal port %u", - numericname, - srcport); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "illegal port"); -#endif - exit(1); - } - - (void) alarm(60); - port = 0; - s = 0; /* not set or used if port == 0 */ - for (;;) { - char c; - if ((cc = read(STDIN_FILENO, &c, 1)) != 1) { - if (cc < 0) - syslog(LOG_NOTICE, "read: %m"); - shutdown(0, SHUT_RDWR); - exit(1); - } - if (c == 0) - break; - port = port * 10 + c - '0'; - } - - (void) alarm(0); - if (port != 0) { - int lport = IPPORT_RESERVED - 1; - s = rresvport_af(&lport, af); - if (s < 0) { - syslog(LOG_ERR, "can't get stderr port: %m"); - exit(1); - } - if (port >= IPPORT_RESERVED || - port < IPPORT_RESERVED/2) { - syslog(LOG_NOTICE|LOG_AUTH, - "2nd socket from %s on unreserved port %u", - numericname, - port); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "unreserved port"); -#endif - exit(1); - } - *((in_port_t *)&fromp->sa_data) = htons(port); - if (connect(s, fromp, fromp->sa_len) < 0) { - syslog(LOG_INFO, "connect second port %d: %m", port); - exit(1); - } - } - - errorstr = NULL; - realhostname_sa(rhost, sizeof(rhost) - 1, fromp, fromp->sa_len); - rhost[sizeof(rhost) - 1] = '\0'; - /* XXX truncation! */ - - (void) alarm(60); - getstr(ruser, sizeof(ruser), "ruser"); - getstr(luser, sizeof(luser), "luser"); - getstr(cmdbuf, maxcmdlen, "command"); - (void) alarm(0); - - pam_err = pam_start("rsh", luser, &pamc, &pamh); - if (pam_err != PAM_SUCCESS) { - syslog(LOG_ERR|LOG_AUTH, "pam_start(): %s", - pam_strerror(pamh, pam_err)); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "login incorrect"); -#endif - rshd_errx(1, "Login incorrect."); - } - - if ((pam_err = pam_set_item(pamh, PAM_RUSER, ruser)) != PAM_SUCCESS || - (pam_err = pam_set_item(pamh, PAM_RHOST, rhost)) != PAM_SUCCESS) { - syslog(LOG_ERR|LOG_AUTH, "pam_set_item(): %s", - pam_strerror(pamh, pam_err)); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "login incorrect"); -#endif - rshd_errx(1, "Login incorrect."); - } - - pam_err = pam_authenticate(pamh, 0); - if (pam_err == PAM_SUCCESS) { - if ((pam_err = pam_get_user(pamh, &cp, NULL)) == PAM_SUCCESS) { - strlcpy(luser, cp, sizeof(luser)); - /* XXX truncation! */ - } - pam_err = pam_acct_mgmt(pamh, 0); - } - if (pam_err != PAM_SUCCESS) { - syslog(LOG_INFO|LOG_AUTH, - "%s@%s as %s: permission denied (%s). cmd='%.80s'", - ruser, rhost, luser, pam_strerror(pamh, pam_err), cmdbuf); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "permission denied"); -#endif - rshd_errx(1, "Login incorrect."); - } - - setpwent(); - pwd = getpwnam(luser); - if (pwd == NULL) { - syslog(LOG_INFO|LOG_AUTH, - "%s@%s as %s: unknown login. cmd='%.80s'", - ruser, rhost, luser, cmdbuf); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "unknown login"); -#endif - if (errorstr == NULL) - errorstr = "Login incorrect."; - rshd_errx(1, errorstr, rhost); - } - - lc = login_getpwclass(pwd); - if (pwd->pw_uid) - auth_checknologin(lc); - - if (chdir(pwd->pw_dir) < 0) { - if (chdir("/") < 0 || - login_getcapbool(lc, "requirehome", !!pwd->pw_uid)) { - syslog(LOG_INFO|LOG_AUTH, - "%s@%s as %s: no home directory. cmd='%.80s'", - ruser, rhost, luser, cmdbuf); - rshd_errx(0, "No remote home directory."); - } - pwd->pw_dir = slash; - } - - if (lc != NULL && fromp->sa_family == AF_INET) { /*XXX*/ - char remote_ip[MAXHOSTNAMELEN]; - - strlcpy(remote_ip, numericname, sizeof(remote_ip)); - /* XXX truncation! */ - if (!auth_hostok(lc, rhost, remote_ip)) { - syslog(LOG_INFO|LOG_AUTH, - "%s@%s as %s: permission denied (%s). cmd='%.80s'", - ruser, rhost, luser, __rcmd_errstr, - cmdbuf); -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "permission denied"); -#endif - rshd_errx(1, "Login incorrect."); - } - if (!auth_timeok(lc, time(NULL))) - rshd_errx(1, "Logins not available right now"); - } - - /* - * PAM modules might add supplementary groups in - * pam_setcred(), so initialize them first. - * But we need to open the session as root. - */ - if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) != 0) { - syslog(LOG_ERR, "setusercontext: %m"); - exit(1); - } - - if ((pam_err = pam_open_session(pamh, 0)) != PAM_SUCCESS) { - syslog(LOG_ERR, "pam_open_session: %s", pam_strerror(pamh, pam_err)); - } else if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) { - syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, pam_err)); - } - - (void) write(STDERR_FILENO, "\0", 1); - sent_null = 1; - - if (port) { - if (pipe(pv) < 0) - rshd_errx(1, "Can't make pipe."); - pid = fork(); - if (pid == -1) - rshd_errx(1, "Can't fork; try again."); - if (pid) { - (void) close(0); - (void) close(1); - (void) close(2); - (void) close(pv[1]); - - FD_ZERO(&readfrom); - FD_SET(s, &readfrom); - FD_SET(pv[0], &readfrom); - if (pv[0] > s) - nfd = pv[0]; - else - nfd = s; - ioctl(pv[0], FIONBIO, (char *)&one); - - /* should set s nbio! */ - nfd++; - do { - ready = readfrom; - if (select(nfd, &ready, (fd_set *)0, - (fd_set *)0, (struct timeval *)0) < 0) - break; - if (FD_ISSET(s, &ready)) { - int ret; - ret = read(s, &sig, 1); - if (ret <= 0) - FD_CLR(s, &readfrom); - else - killpg(pid, sig); - } - if (FD_ISSET(pv[0], &ready)) { - errno = 0; - cc = read(pv[0], buf, sizeof(buf)); - if (cc <= 0) { - shutdown(s, SHUT_RDWR); - FD_CLR(pv[0], &readfrom); - } else { - (void)write(s, buf, cc); - } - } - - } while (FD_ISSET(s, &readfrom) || - FD_ISSET(pv[0], &readfrom)); - PAM_END; - exit(0); - } - (void) close(s); - (void) close(pv[0]); - dup2(pv[1], 2); - close(pv[1]); - } - else { - pid = fork(); - if (pid == -1) - rshd_errx(1, "Can't fork; try again."); - if (pid) { - /* Parent. */ - while (wait(NULL) > 0 || errno == EINTR) - /* nothing */ ; - PAM_END; - exit(0); - } - } - -#ifdef USE_BLACKLIST - blacklist(0, STDIN_FILENO, "success"); -#endif - closefrom(3); - if (setsid() == -1) - syslog(LOG_ERR, "setsid() failed: %m"); - if (setlogin(pwd->pw_name) < 0) - syslog(LOG_ERR, "setlogin() failed: %m"); - - if (*pwd->pw_shell == '\0') - pwd->pw_shell = bshell; - (void) pam_setenv(pamh, "HOME", pwd->pw_dir, 1); - (void) pam_setenv(pamh, "SHELL", pwd->pw_shell, 1); - (void) pam_setenv(pamh, "USER", pwd->pw_name, 1); - (void) pam_setenv(pamh, "PATH", _PATH_DEFPATH, 1); - environ = pam_getenvlist(pamh); - (void) pam_end(pamh, pam_err); - cp = strrchr(pwd->pw_shell, '/'); - if (cp) - cp++; - else - cp = pwd->pw_shell; - - if (setusercontext(lc, pwd, pwd->pw_uid, - LOGIN_SETALL & ~LOGIN_SETGROUP) < 0) { - syslog(LOG_ERR, "setusercontext(): %m"); - exit(1); - } - login_close(lc); - endpwent(); - if (log_success || pwd->pw_uid == 0) { - syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'", - ruser, rhost, luser, cmdbuf); - } - execl(pwd->pw_shell, cp, "-c", cmdbuf, (char *)NULL); - err(1, "%s", pwd->pw_shell); - exit(1); -} - -/* - * Report error to client. Note: can't be used until second socket has - * connected to client, or older clients will hang waiting for that - * connection first. - */ - -static void -rshd_errx(int errcode, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - - if (sent_null == 0) - write(STDERR_FILENO, "\1", 1); - - verrx(errcode, fmt, ap); - /* NOTREACHED */ -} - -void -getstr(char *buf, int cnt, const char *error) -{ - char c; - - do { - if (read(STDIN_FILENO, &c, 1) != 1) - exit(1); - *buf++ = c; - if (--cnt == 0) { -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "buffer overflow"); -#endif - rshd_errx(1, "%s too long", error); - } - } while (c != 0); -} - -/* - * 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. - */ -int -local_domain(char *h) -{ - char localhost[MAXHOSTNAMELEN]; - char *p1, *p2; - - localhost[0] = 0; - (void) gethostname(localhost, sizeof(localhost) - 1); - localhost[sizeof(localhost) - 1] = '\0'; - /* XXX truncation! */ - p1 = topdomain(localhost); - p2 = topdomain(h); - if (p1 == NULL || p2 == NULL || !strcasecmp(p1, p2)) - return (1); - return (0); -} - -char * -topdomain(char *h) -{ - char *p, *maybe = NULL; - int dots = 0; - - for (p = h + strlen(h); p >= h; p--) { - if (*p == '.') { - if (++dots == 2) - return (p); - maybe = p; - } - } - return (maybe); -} - -void -usage(void) -{ - - syslog(LOG_ERR, "usage: rshd [-%s]", OPTIONS); - exit(2); -} |