Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 82 additions & 4 deletions xinetd/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,64 @@ static void dgram_chargen( const struct server *serp )
(void) sendto( fd, buf, (size_t)(p-buf), 0, SA( &lsin ), sin_len ) ;
}

/* Handle a help request for the tcpmux service.
* It's helpful to remember here that we are now a child of the original
* xinetd process and were called after the first line of input was
* read from the tcpmux_server routine.
* Serp still points to an actual tcpmux 'server', or at least the
* service pointer of serp is valid.
*/

static void tcpmux_help( const struct server *serp )
{
char buff[ BUFFER_SIZE ] ;
int cc ;
int descriptor = SERVER_FD( serp ) ;
const struct service *svc = SERVER_SERVICE( serp ) ;
unsigned u;
struct service *sp = NULL;
struct server server, *nserp;
struct service_config *scp = NULL;

/* Search the services for the a match on name.
*/
for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
{
sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;

if ( ! SVC_IS_MUXCLIENT( sp ) )
{
if ( debug.on )
{
msg( LOG_DEBUG, "tcpmux_handler",
"help skipping non-tcpmux service: %s.",
SC_NAME( SVC_CONF ( sp ) ) );
continue;
}
}

/* only list tcpmux services with the TCPMUXHELP flag
*/
if ( ! SVC_MUXHELP( sp ) )
{
msg( LOG_DEBUG, "tcpmux_handler", "help skipping unpublished service: %s.", SC_NAME( SVC_CONF ( sp ) ) );
continue;
}

msg( LOG_DEBUG, "tcpmux_handler", "help listing: %s",
SC_NAME( SVC_CONF( sp ) ) );

strncpy( buff, SC_NAME( SVC_CONF( sp ) ), BUFFER_SIZE - 2 );
strcat( buff, TCPMUX_CRLF );
if ( Swrite( descriptor, buff, strlen( buff ) ) != strlen( buff ) )
{
msg(LOG_ERR, "tcpmux_handler", "write failed for help.");
exit(0);
}

continue;
}
}

/* Handle a request for a tcpmux service.
* It's helpful to remember here that we are now a child of the original
Expand Down Expand Up @@ -544,9 +602,19 @@ static void tcpmux_handler( const struct server *serp )
cc, svc_name);
}

/* Search the services for the a match on name.
/* RFC 1078: help is a reserved service name
*/
if ( strcasecmp( svc_name, "help" ) == 0 )
{
msg(LOG_DEBUG, "tcpmux_handler", "help requested");
tcpmux_help( serp );
Sflush( descriptor );
Sclose( descriptor );
exit(0);
}

/* Search the services for the a match on name.
*/
for ( u = 0 ; u < pset_count( SERVICES( ps ) ) ; u++ )
{
sp = SP( pset_pointer( SERVICES( ps ), u ) ) ;
Expand All @@ -557,7 +625,7 @@ static void tcpmux_handler( const struct server *serp )
*/
scp = SVC_CONF( sp );

if ( ! SVC_IS_MUXCLIENT( sp ) && ! SVC_IS_MUXPLUSCLIENT( sp ) )
if ( ! SVC_IS_MUXCLIENT( sp ) )
{
if ( debug.on )
{
Expand All @@ -569,7 +637,6 @@ static void tcpmux_handler( const struct server *serp )

/* Send the accept string if we're a PLUS (+) client.
*/

if ( SVC_IS_MUXPLUSCLIENT( sp ) )
{
if ( Swrite( descriptor, TCPMUX_ACK, sizeof( TCPMUX_ACK ) ) !=
Expand All @@ -585,6 +652,17 @@ static void tcpmux_handler( const struct server *serp )
continue; /* Keep looking */
}

/* Stop processing and shutdown if help was requested
*/
if ( strcasecmp( svc_name, "help" ) == 0 )
{
Sflush( descriptor );
Sclose( descriptor );
exit(0);
}

/* We were unable to find a matching service
*/
if ( u >= pset_count( SERVICES( ps ) ) )
{
if ( debug.on )
Expand Down Expand Up @@ -617,7 +695,7 @@ static void tcpmux_handler( const struct server *serp )
if( SC_IS_INTERNAL( scp ) ) {
SC_INTERNAL(scp, nserp);
} else {
exec_server(nserp);
child_process(nserp);
}
}

1 change: 1 addition & 0 deletions xinetd/nvlists.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const struct name_value service_flags[] =
{ "IPv4", SF_IPV4 },
{ "IPv6", SF_IPV6 },
{ "LABELED", SF_LABELED },
{ "PUBLISH", SF_TCPMUXHELP },
{ CHAR_NULL, 0 }
} ;

Expand Down
2 changes: 2 additions & 0 deletions xinetd/sconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#define SF_IPV4 10
#define SF_IPV6 11
#define SF_LABELED 12
#define SF_TCPMUXHELP 13

/*
* Values for log options
Expand Down Expand Up @@ -241,6 +242,7 @@ struct service_config
#define SC_IPV4( scp ) M_IS_SET( (scp)->sc_xflags, SF_IPV4 )
#define SC_IPV6( scp ) M_IS_SET( (scp)->sc_xflags, SF_IPV6 )
#define SC_LABELED_NET( scp ) M_IS_SET( (scp)->sc_xflags, SF_LABELED )
#define SC_MUXHELP( scp ) M_IS_SET( (scp)->sc_xflags, SF_TCPMUXHELP )

#define SC_IS_RPC( scp ) ( M_IS_SET( (scp)->sc_type, ST_RPC ) )
#define SC_IS_INTERNAL( scp ) ( M_IS_SET( (scp)->sc_type, ST_INTERNAL ) )
Expand Down
4 changes: 3 additions & 1 deletion xinetd/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@ struct service
#define SVC_IS_SUSPENDED( sp ) ( (sp)->svc_state == SVC_SUSPENDED )
#define SVC_IS_AVAILABLE( sp ) ( SVC_IS_ACTIVE(sp) || SVC_IS_SUSPENDED(sp) )
#define SVC_IS_DISABLED( sp ) ( (sp)->svc_state == SVC_DISABLED )
#define SVC_IS_MUXCLIENT( sp ) ( SC_IS_MUXCLIENT( SVC_CONF ( sp ) ) )
#define SVC_IS_MUXCLIENT( sp ) ( SC_IS_MUXCLIENT( SVC_CONF ( sp ) ) || SC_IS_MUXPLUSCLIENT( SVC_CONF ( sp ) ) )
#define SVC_IS_MUXPLUSCLIENT(sp) ( SC_IS_MUXPLUSCLIENT( SVC_CONF ( sp ) ) )
#define SVC_IS_TCPMUX( sp ) ( SC_IS_TCPMUX( SVC_CONF ( sp ) ) )
#define SVC_MUXHELP(sp) ( SC_MUXHELP( SVC_CONF ( sp ) ) )

#define TCPMUX_ACK "+Go\r\n"
#define TCPMUX_NOT_FOUND "-Service name not found\r\n"
#define TCPMUX_CRLF "\r\n"
/*
* Predicate checking macros
*/
Expand Down
52 changes: 45 additions & 7 deletions xinetd/xinetd.conf.man
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
.\"and conditions for redistribution.
.\"
.\" $Id$
.TH XINETD.CONF 5 "14 June 2001"
.TH XINETD.CONF 5 "12 September 2013"
.\" *************************** NAME *********************************
.SH NAME
xinetd.conf \- Extended Internet Services Daemon configuration file
Expand Down Expand Up @@ -148,6 +148,9 @@ Sets the service to be an IPv6 service (AF_INET6), if IPv6 is available on the s
.B LABELED
The LABELED flag will tell xinetd to change the child processes SE Linux context to match that of the incoming connection as it starts the service. This only works for external tcp non-waiting servers and is an error if applied to an internal, udp, or tcp-wait server.
.TP
.B PUBLISH
The PUBLISH flag will tell xinetd to list the service when the help command is issued to the TCPMUX server. Only TCPMUX services with the PUBLISH flag will be listed when the help command is issued to the internal TCPMUX server.
.TP
.B REUSE
The REUSE flag is deprecated. All services now implicitly use the REUSE flag.
.RE
Expand Down Expand Up @@ -777,12 +780,14 @@ have no limitation in the number of
.\" *********************** TCPMUX Services ****************************
.SH "TCPMUX Services"
.LP
\fBxinetd\fP supports TCPMUX services that conform to RFC 1078. These services
may not have a well-known port associated with them, and can be accessed via
the TCPMUX well-known port.
\fBxinetd\fP supports TCPMUX services that conform to RFC 1078. These
services may not have a well-known port associated with them, and can
be accessed via the TCPMUX well-known port. \fBxinetd\fP implements
the TCPMUX \fIhelp\fP command which will list only TCPMUX services
which also contain the \fBPUBLISH\fP flag.
.LP
For each service that is to be accessed via TCPMUX, a service entry in
\fB/etc/xinetd.conf\fP or in a configuration file in an \fBincludedir\fP
\fB/etc/xinetd.conf\fP or in a configuration file in an \fBincludedir\fP
directory must exist.
.LP
The \fIservice_name\fP field (as defined above for each service in any
Expand All @@ -799,6 +804,11 @@ handshake (as defined in RFC 1078) with the calling process before initiating
the service. If the type is \fBTCPMUX\fP, the server that is started is
responsible for performing the handshake.
.LP
The \fIflag\fP field should also include \fBPUBLISH\fP if the service
is to be listed when the help command is issued the TCPMUX server.
The default is not listing the service name when the help command
is given.
.LP
The \fItype\fP field should also include \fBUNLISTED\fP if the service is
not listed in a standard system file
(like
Expand Down Expand Up @@ -836,6 +846,34 @@ service myorg_server
}
.fi
.RE
.PD .1v
.RS
.nf

# this service is listed when help is called via tcpmux
service myorg_server
{
.RS
.IP disable 20
= no
.IP type
= TCPMUX
.IP socket_type
.IP flags
= PUBLISH
= stream
.IP protocol
= tcp
.IP wait
= no
.IP user
= root
.IP server
= /usr/etc/my_server_exec
.RE
}
.fi
.RE
.PD
.LP
Besides a service entry for each service that can be accessed
Expand All @@ -846,13 +884,13 @@ sample:
.RS
.nf

service tcpmux
service tcpmux-server
{
.RS
.IP type 20
= INTERNAL
.IP id
= tcpmux
= tcpmux-server
.IP socket_type
= stream
.IP protocol
Expand Down