Bring in handling of RPC services from 1.x

(Guess who forgot to replace his inetd until today ;-)
This commit is contained in:
csgr 1994-09-11 10:48:02 +00:00
parent 7c7e41add8
commit 88dbb490c7
2 changed files with 191 additions and 22 deletions

View File

@ -29,7 +29,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)inetd.8 8.3 (Berkeley) 4/13/94
.\" from: @(#)inetd.8 8.3 (Berkeley) 4/13/94
.\" $Id$
.\"
.Dd April 13, 1994
.Dt INETD 8
@ -97,6 +98,19 @@ server program
server program arguments
.Ed
.Pp
To specify a
.Em Sun-RPC
based service, the entry would contain these fields:
.Pp
.Bd -unfilled -offset indent -compact
service name/version
socket type
rpc/protocol
user
server program
server program arguments
.Ed
.Pp
There are two types of services that
.Nm inetd
can start: standard and TCPMUX.
@ -127,6 +141,17 @@ name
.Em must
be the official name of the service (that is, the first entry in
.Pa /etc/services ) .
When used to specify a
.Em Sun-RPC
based service, this field is a valid RPC service name in
the file
.Pa /etc/rpc .
The part on the right of the
.Dq /
is the RPC version number. This
can simply be a single numeric argument or a range of versions.
A range is bounded by the low version to the high version -
.Dq rusers/1-3 .
For TCPMUX services, the value of the
.Em service-name
field consists of the string
@ -163,6 +188,11 @@ Examples might be
.Dq tcp
or
.Dq udp .
Rpc based services are specified with the
.Dq rpc/tcp
or
.Dq rpc/udp
service type.
TCPMUX services must use
.Dq tcp .
.Pp
@ -305,10 +335,11 @@ to list TCPMUX services in
.Pp
Here are several example service entries for the various types of services:
.Bd -literal
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
ntalk dgram udp wait root /usr/libexec/ntalkd ntalkd
tcpmux/+date stream tcp nowait guest /bin/date date
ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
ntalk dgram udp wait root /usr/libexec/ntalkd ntalkd
tcpmux/+date stream tcp nowait guest /bin/date date
tcpmux/phonebook stream tcp nowait guest /usr/local/bin/phonebook phonebook
rstatd/1-3 dgram rpc/udp wait root /usr/libexec/rpc.rstatd rpc.rstatd
.Ed
.Sh "ERROR MESSAGES"
The
@ -366,10 +397,17 @@ is invalid.
.Xr rlogind 8 ,
.Xr rshd 8 ,
.Xr telnetd 8 ,
.Xr tftpd 8
.Xr tftpd 8 ,
.Xr portmap 8 ,
.Xr rpc 5
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.3 .
TCPMUX is based on code and documentation by Mark Lottor.
Support for
.Em Sun-RPC
based services is modelled after that
provided by
.Em SunOS 4.1 .

View File

@ -38,7 +38,8 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94";
/* from: @(#)inetd.c 8.4 (Berkeley) 4/13/94"; */
static char RCSid[] = "$Id";
#endif /* not lint */
/*
@ -88,6 +89,15 @@ static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94";
* because they do not have a well-known port and hence cannot listen
* for new requests.
*
* For RPC services
* service name/version must be in /etc/rpc
* socket type stream/dgram/raw/rdm/seqpacket
* protocol must be in /etc/protocols
* wait/nowait single-threaded/multi-threaded
* user user to run daemon as
* server program full path name
* server program arguments maximum of MAXARGS
*
* Comment lines are indicated by a `#' in column 1.
*/
#include <sys/param.h>
@ -100,6 +110,7 @@ static char sccsid[] = "@(#)inetd.c 8.4 (Berkeley) 4/13/94";
#include <netinet/in.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <errno.h>
#include <fcntl.h>
@ -128,6 +139,7 @@ int options;
int timingout;
int toomany = TOOMANY;
struct servent *sp;
struct rpcent *rpc;
struct servtab {
char *se_service; /* name of service */
@ -143,6 +155,10 @@ struct servtab {
int se_fd; /* open descriptor */
int se_type; /* type */
struct sockaddr_in se_ctrladdr;/* bound address */
int se_rpc; /* ==1 if RPC service */
int se_rpc_prog; /* RPC program number */
u_int se_rpc_lowvers; /* RPC low version */
u_int se_rpc_highvers; /* RPC high version */
int se_count; /* number started since se_time */
struct timeval se_time; /* start of se_count */
struct servtab *se_next;
@ -183,6 +199,8 @@ char *sskip __P((char **));
char *skip __P((char **));
struct servtab *tcpmux __P((int));
void unregisterrpc __P((register struct servtab *sep));
struct biltin {
char *bi_service; /* internally provided service name */
int bi_socktype; /* type of socket supported */
@ -539,18 +557,38 @@ config(signo)
sep->se_fd = -1;
continue;
}
sp = getservbyname(sep->se_service, sep->se_proto);
if (sp == 0) {
syslog(LOG_ERR, "%s/%s: unknown service",
sep->se_service, sep->se_proto);
sep->se_checked = 0;
continue;
}
if (sp->s_port != sep->se_ctrladdr.sin_port) {
sep->se_ctrladdr.sin_family = AF_INET;
sep->se_ctrladdr.sin_port = sp->s_port;
if (sep->se_fd >= 0)
close_sep(sep);
if (!sep->se_rpc) {
sp = getservbyname(sep->se_service, sep->se_proto);
if (sp == 0) {
syslog(LOG_ERR, "%s/%s: unknown service",
sep->se_service, sep->se_proto);
sep->se_checked = 0;
continue;
}
if (sp->s_port != sep->se_ctrladdr.sin_port) {
sep->se_ctrladdr.sin_family = AF_INET;
sep->se_ctrladdr.sin_port = sp->s_port;
if (sep->se_fd >= 0)
close_sep(sep);
}
} else {
rpc = getrpcbyname(sep->se_service);
if (rpc == 0) {
syslog(LOG_ERR, "%s/%s unknown RPC service.",
sep->se_service, sep->se_proto);
if (sep->se_fd != -1)
(void) close(sep->se_fd);
sep->se_fd = -1;
continue;
}
if (rpc->r_number != sep->se_rpc_prog) {
if (sep->se_rpc_prog)
unregisterrpc(sep);
sep->se_rpc_prog = rpc->r_number;
if (sep->se_fd != -1)
(void) close(sep->se_fd);
sep->se_fd = -1;
}
}
if (sep->se_fd == -1)
setup(sep);
@ -571,12 +609,42 @@ config(signo)
close_sep(sep);
if (debug)
print_service("FREE", sep);
if (sep->se_rpc && sep->se_rpc_prog > 0)
unregisterrpc(sep);
freeconfig(sep);
free((char *)sep);
}
(void) sigsetmask(omask);
}
void
unregisterrpc(sep)
struct servtab *sep;
{
int i;
struct servtab *sepp;
long omask;
omask = sigblock(SIGBLOCK);
for (sepp = servtab; sepp; sepp = sepp->se_next) {
if (sepp == sep)
continue;
if (sep->se_checked == 0 ||
!sepp->se_rpc ||
sep->se_rpc_prog != sepp->se_rpc_prog)
continue;
return;
}
if (debug)
print_service("UNREG", sep);
for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++)
pmap_unset(sep->se_rpc_prog, i);
if (sep->se_fd != -1)
(void) close(sep->se_fd);
sep->se_fd = -1;
(void) sigsetmask(omask);
}
void
retry(signo)
int signo;
@ -628,6 +696,28 @@ setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on))
}
return;
}
if (sep->se_rpc) {
int i, len = sizeof(struct sockaddr);
if (getsockname(sep->se_fd,
(struct sockaddr*)&sep->se_ctrladdr, &len) < 0){
syslog(LOG_ERR, "%s/%s: getsockname: %m",
sep->se_service, sep->se_proto);
(void) close(sep->se_fd);
sep->se_fd = -1;
return;
}
if (debug)
print_service("REG ", sep);
for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) {
pmap_unset(sep->se_rpc_prog, i);
pmap_set(sep->se_rpc_prog, i,
(sep->se_socktype == SOCK_DGRAM)
? IPPROTO_UDP : IPPROTO_TCP,
ntohs(sep->se_ctrladdr.sin_port));
}
}
if (sep->se_socktype == SOCK_STREAM)
listen(sep->se_fd, 10);
FD_SET(sep->se_fd, &allsock);
@ -714,6 +804,7 @@ getconfigent()
struct servtab *sep = &serv;
int argc;
char *cp, *arg;
char *versp;
static char TCPMUX_TOKEN[] = "tcpmux/";
#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1)
@ -758,6 +849,38 @@ more:
else
sep->se_socktype = -1;
sep->se_proto = newstr(sskip(&cp));
if (strncmp(sep->se_proto, "rpc/", 4) == 0) {
sep->se_proto += 4;
sep->se_rpc = 1;
sep->se_rpc_prog = sep->se_rpc_lowvers =
sep->se_rpc_lowvers = 0;
sep->se_ctrladdr.sin_family = AF_INET;
sep->se_ctrladdr.sin_port = 0;
sep->se_ctrladdr.sin_addr.s_addr = htonl(INADDR_ANY);
if ((versp = rindex(sep->se_service, '/'))) {
*versp++ = '\0';
switch (sscanf(versp, "%d-%d",
&sep->se_rpc_lowvers,
&sep->se_rpc_highvers)) {
case 2:
break;
case 1:
sep->se_rpc_highvers =
sep->se_rpc_lowvers;
break;
default:
syslog(LOG_ERR,
"bad RPC version specifier; %s\n",
sep->se_service);
freeconfig(sep);
goto more;
}
}
else {
sep->se_rpc_lowvers =
sep->se_rpc_highvers = 1;
}
}
arg = sskip(&cp);
sep->se_wait = strcmp(arg, "wait") == 0;
if (ISMUX(sep)) {
@ -1167,10 +1290,18 @@ print_service(action, sep)
char *action;
struct servtab *sep;
{
fprintf(stderr,
"%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n",
action, sep->se_service, sep->se_proto,
sep->se_wait, sep->se_user, (int)sep->se_bi, sep->se_server);
if(sep->se_rpc)
fprintf(stderr,
"%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n",
action, sep->se_service, sep->se_proto,
sep->se_wait, sep->se_user, (int)sep->se_bi,
sep->se_server);
else
fprintf(stderr,
"%s: %s proto=%s, wait=%d, user=%s builtin=%x server=%s\n",
action, sep->se_service, sep->se_proto,
sep->se_wait, sep->se_user, (int)sep->se_bi,
sep->se_server);
}
/*