confparse.c (xinetd-2.3.15) | : | confparse.c (xinetd-2.3.15.4.tar.xz) | ||
---|---|---|---|---|
skipping to change at line 16 | skipping to change at line 16 | |||
*/ | */ | |||
#include "config.h" | #include "config.h" | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#include <syslog.h> | #include <syslog.h> | |||
#include <string.h> | #include <string.h> | |||
#include <netinet/in.h> | #include <netinet/in.h> | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <fcntl.h> | #include <fcntl.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#ifndef NO_RPC | ||||
#ifdef HAVE_RPC_RPC_H | ||||
#include <rpc/rpc.h> | #include <rpc/rpc.h> | |||
#endif | #ifdef HAVE_RPCENT_H | |||
#ifdef HAVE_RPC_RPCENT_H | ||||
#include <rpc/rpcent.h> | #include <rpc/rpcent.h> | |||
#endif | #endif | |||
#ifdef HAVE_NETDB_H | ||||
#include <netdb.h> | ||||
#endif | #endif | |||
#include <netdb.h> | ||||
#include "str.h" | #include "str.h" | |||
#include "sio.h" | #include "sio.h" | |||
#include "confparse.h" | #include "confparse.h" | |||
#include "msg.h" | #include "msg.h" | |||
#include "xconfig.h" | #include "xconfig.h" | |||
#include "parse.h" | #include "parse.h" | |||
#include "special.h" | #include "special.h" | |||
#include "sconst.h" | #include "sconst.h" | |||
#include "env.h" | #include "env.h" | |||
skipping to change at line 168 | skipping to change at line 163 | |||
SC_SPECIFY( scp, A_UMASK ); | SC_SPECIFY( scp, A_UMASK ); | |||
} | } | |||
if ( ! SC_SPECIFIED( scp, A_PER_SOURCE ) ) | if ( ! SC_SPECIFIED( scp, A_PER_SOURCE ) ) | |||
{ | { | |||
SC_PER_SOURCE(scp) = SC_SPECIFIED( def, A_PER_SOURCE ) ? | SC_PER_SOURCE(scp) = SC_SPECIFIED( def, A_PER_SOURCE ) ? | |||
SC_PER_SOURCE(def) : DEFAULT_INSTANCE_LIMIT ; | SC_PER_SOURCE(def) : DEFAULT_INSTANCE_LIMIT ; | |||
SC_SPECIFY( scp, A_PER_SOURCE ) ; | SC_SPECIFY( scp, A_PER_SOURCE ) ; | |||
} | } | |||
#ifdef HAVE_MDNS | ||||
if ( ! SC_SPECIFIED( scp, A_MDNS ) ) | ||||
{ | ||||
SC_MDNS(scp) = SC_SPECIFIED( def, A_MDNS ) ? SC_MDNS(def) : YES; | ||||
SC_SPECIFY( scp, A_MDNS ); | ||||
} | ||||
#endif | ||||
if ( ! SC_SPECIFIED( scp, A_GROUPS ) ) | if ( ! SC_SPECIFIED( scp, A_GROUPS ) ) | |||
{ | { | |||
SC_GROUPS(scp) = SC_SPECIFIED( def, A_GROUPS ) ? SC_GROUPS(def) : NO; | SC_GROUPS(scp) = SC_SPECIFIED( def, A_GROUPS ) ? SC_GROUPS(def) : NO; | |||
SC_SPECIFY( scp, A_GROUPS ); | SC_SPECIFY( scp, A_GROUPS ); | |||
} | } | |||
if ( ! SC_SPECIFIED( scp, A_CPS ) ) | if ( ! SC_SPECIFIED( scp, A_CPS ) ) | |||
{ | { | |||
SC_TIME_CONN_MAX(scp) = SC_SPECIFIED( def, A_CPS ) ? | SC_TIME_CONN_MAX(scp) = SC_SPECIFIED( def, A_CPS ) ? | |||
SC_TIME_CONN_MAX(def) : DEFAULT_LOOP_RATE; | SC_TIME_CONN_MAX(def) : DEFAULT_LOOP_RATE; | |||
skipping to change at line 246 | skipping to change at line 233 | |||
* available. If not, then use default. | * available. If not, then use default. | |||
*/ | */ | |||
if ( SC_SPECIFIED( scp, A_BIND ) && !SC_ORIG_BIND_ADDR(scp) ) | if ( SC_SPECIFIED( scp, A_BIND ) && !SC_ORIG_BIND_ADDR(scp) ) | |||
{ | { | |||
if ( SAIN(SC_BIND_ADDR(scp))->sin_family == AF_INET ) | if ( SAIN(SC_BIND_ADDR(scp))->sin_family == AF_INET ) | |||
M_SET(SC_XFLAGS(scp), SF_IPV4); | M_SET(SC_XFLAGS(scp), SF_IPV4); | |||
else | else | |||
M_SET(SC_XFLAGS(scp), SF_IPV6); | M_SET(SC_XFLAGS(scp), SF_IPV6); | |||
} | } | |||
else | else | |||
M_SET(SC_XFLAGS(scp), SF_IPV4); | M_SET(SC_XFLAGS(scp), SF_IPV6); /*try bind IPv6 by default*/ | |||
} | } | |||
if (SC_ORIG_BIND_ADDR(scp)) | if (SC_ORIG_BIND_ADDR(scp)) | |||
{ | { | |||
/* | /* | |||
* If we are here, we have a dual stack machine with multiple | * If we are here, we have a dual stack machine with multiple | |||
* entries for a domain name. We can finally use the flags for | * entries for a domain name. We can finally use the flags for | |||
* a hint to see which one to use. | * a hint to see which one to use. | |||
*/ | */ | |||
struct addrinfo hints, *res; | struct addrinfo hints, *res; | |||
skipping to change at line 529 | skipping to change at line 516 | |||
if ( SC_IS_UNLISTED( scp ) ) /* rpc_number */ | if ( SC_IS_UNLISTED( scp ) ) /* rpc_number */ | |||
M_OR( must_specify, must_specify, NECESSARY_ATTRS_RPC_UNLISTED ) ; | M_OR( must_specify, must_specify, NECESSARY_ATTRS_RPC_UNLISTED ) ; | |||
} | } | |||
else | else | |||
{ | { | |||
if ( SC_SPECIFIED( scp, A_REDIR ) ) | if ( SC_SPECIFIED( scp, A_REDIR ) ) | |||
M_CLEAR( must_specify, A_SERVER ); /* server isn't used */ | M_CLEAR( must_specify, A_SERVER ); /* server isn't used */ | |||
} | } | |||
if( SC_IPV4( scp ) && SC_IPV6( scp ) ) { | if( SC_IPV4( scp ) && SC_IPV6( scp ) ) { | |||
msg( LOG_ERR, func, | msg( LOG_INFO, func, | |||
"Service %s specified as both IPv4 and IPv6 - DISABLING", | "Service %s will use IPv6 or fallback to IPv4", | |||
SC_NAME(scp)); | SC_NAME(scp)); | |||
return FAILED ; | // we only need ipv6 defined and fallback to ipv4 if needed | |||
// so clean it up for now | ||||
M_CLEAR(SC_XFLAGS(scp), SF_IPV4); | ||||
} | } | |||
/* | /* | |||
* Check if all necessary attributes have been specified | * Check if all necessary attributes have been specified | |||
* | * | |||
* NOTE: None of the necessary attributes can belong to "defaults" | * NOTE: None of the necessary attributes can belong to "defaults" | |||
* This is why we use the sc_attributes_specified mask instead | * This is why we use the sc_attributes_specified mask instead | |||
* of the sc_attributes_present mask. | * of the sc_attributes_present mask. | |||
*/ | */ | |||
skipping to change at line 629 | skipping to change at line 618 | |||
} | } | |||
if( SC_IS_DISABLED( tmp_scp ) || | if( SC_IS_DISABLED( tmp_scp ) || | |||
SC_IS_DISABLED(scp) ) | SC_IS_DISABLED(scp) ) | |||
{ | { | |||
/* | /* | |||
* Allow multiple configs, as long as all but one are | * Allow multiple configs, as long as all but one are | |||
* disabled. | * disabled. | |||
*/ | */ | |||
continue; | continue; | |||
} | } | |||
#if defined(HAVE_RPC_RPCENT_H) || defined(HAVE_NETDB_H) | ||||
if ( SC_IS_RPC( scp ) && SC_IS_RPC ( tmp_scp ) ) | if ( SC_IS_RPC( scp ) && SC_IS_RPC ( tmp_scp ) ) | |||
{ | { | |||
const struct rpc_data *rdp1 = SC_RPCDATA( scp ) ; | const struct rpc_data *rdp1 = SC_RPCDATA( scp ) ; | |||
const struct rpc_data *rdp2 = SC_RPCDATA( tmp_scp ) ; | const struct rpc_data *rdp2 = SC_RPCDATA( tmp_scp ) ; | |||
if ( rdp1->rd_program_number != rdp2->rd_program_number ) | if ( rdp1->rd_program_number != rdp2->rd_program_number ) | |||
continue; | continue; | |||
if ( rdp1->rd_min_version > rdp2->rd_max_version || | if ( rdp1->rd_min_version > rdp2->rd_max_version || | |||
rdp1->rd_max_version < rdp2->rd_min_version ) | rdp1->rd_max_version < rdp2->rd_min_version ) | |||
continue; | continue; | |||
} | } | |||
#endif | ||||
if (diff) | if (diff) | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"service: %s id: %s is unique but its identical to " | "service: %s id: %s is unique but its identical to " | |||
"service: %s id: %s - DISABLING", | "service: %s id: %s - DISABLING", | |||
SC_NAME(scp), SC_ID(scp), SC_NAME(tmp_scp), SC_ID(tmp_scp) ) ; | SC_NAME(scp), SC_ID(scp), SC_NAME(tmp_scp), SC_ID(tmp_scp) ) ; | |||
else | else | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"service: %s id: %s not unique or is a duplicate - DISABLING", | "service: %s id: %s not unique or is a duplicate - DISABLING", | |||
SC_NAME(scp), SC_ID(scp) ) ; | SC_NAME(scp), SC_ID(scp) ) ; | |||
return FAILED ; | return FAILED ; | |||
skipping to change at line 742 | skipping to change at line 729 | |||
if (!EQ("tcp", SC_PROTONAME(scp))) | if (!EQ("tcp", SC_PROTONAME(scp))) | |||
{ | { | |||
msg(LOG_ERR, func, | msg(LOG_ERR, func, | |||
"Service: %s (tcpmux) should have tcp in protocol.", | "Service: %s (tcpmux) should have tcp in protocol.", | |||
SC_NAME(scp)); | SC_NAME(scp)); | |||
return( FAILED ); | return( FAILED ); | |||
} | } | |||
} | } | |||
/* #ifndef NO_RPC */ | #ifndef NO_RPC | |||
#if defined(HAVE_RPC_RPCENT_H) || defined(HAVE_NETDB_H) | ||||
if ( SC_IS_RPC( scp ) && !SC_IS_UNLISTED( scp ) ) | if ( SC_IS_RPC( scp ) && !SC_IS_UNLISTED( scp ) ) | |||
{ | { | |||
struct rpcent *rep = (struct rpcent *)getrpcbyname( SC_NAME(scp) ) ; | struct rpcent *rep = (struct rpcent *)getrpcbyname( SC_NAME(scp) ) ; | |||
if ( rep == NULL ) | if ( rep == NULL ) | |||
{ | { | |||
msg( LOG_ERR, func, "unknown RPC service: %s", SC_NAME(scp) ) ; | msg( LOG_ERR, func, "unknown RPC service: %s", SC_NAME(scp) ) ; | |||
return( FAILED ) ; | return( FAILED ) ; | |||
} | } | |||
SC_RPCDATA( scp )->rd_program_number = rep->r_number ; | SC_RPCDATA( scp )->rd_program_number = rep->r_number ; | |||
} | } | |||
else | else | |||
#endif /* ! NO_RPC */ | #endif | |||
{ | { | |||
if ( !SC_IS_UNLISTED( scp ) ) | if ( !SC_IS_UNLISTED( scp ) ) | |||
{ | { | |||
uint16_t service_port ; | uint16_t service_port ; | |||
struct servent *sep ; | struct servent *sep ; | |||
/* | /* | |||
* Check if a protocol was specified. Based on the code in | * Check if a protocol was specified. Based on the code in | |||
* service_fill, if either socket_type or protocol is specified, | * service_fill, if either socket_type or protocol is specified, | |||
* the other one is filled in. Protocol should therefore always | * the other one is filled in. Protocol should therefore always | |||
* be filled in unless they made a mistake. Then verify it is the | * be filled in unless they made a mistake. Then verify it is the | |||
* proper protocol for the given service. | * proper protocol for the given service. | |||
* We don't need to check MUXCLIENTs - they aren't in /etc/services. | * We don't need to check MUXCLIENTs - they aren't in /etc/services. | |||
*/ | */ | |||
if ( SC_SPECIFIED( scp, A_PROTOCOL ) ) | if ( SC_SPECIFIED( scp, A_PROTOCOL ) ) | |||
{ | { | |||
sep = getservbyname( SC_NAME(scp), SC_PROTONAME(scp) ) ; | sep = getservbyname( SC_NAME(scp), SC_PROTONAME(scp) ) ; | |||
if ( (sep == NULL) ) | if ( sep == NULL ) | |||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"service/protocol combination not in /etc/services: %s/%s", | "service/protocol combination not in /etc/services: %s/%s", | |||
SC_NAME(scp), SC_PROTONAME(scp) ) ; | SC_NAME(scp), SC_PROTONAME(scp) ) ; | |||
return( FAILED ) ; | return( FAILED ) ; | |||
} | } | |||
} | } | |||
else | else | |||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
skipping to change at line 857 | skipping to change at line 843 | |||
} | } | |||
else if (!SC_SPECIFIED( scp, A_SERVER_ARGS) ) | else if (!SC_SPECIFIED( scp, A_SERVER_ARGS) ) | |||
{ | { | |||
msg( LOG_ERR, func, | msg( LOG_ERR, func, | |||
"Service %s has NAMEINARGS flag set and no server_args", | "Service %s has NAMEINARGS flag set and no server_args", | |||
SC_NAME(scp) ); | SC_NAME(scp) ); | |||
return FAILED; | return FAILED; | |||
} | } | |||
} | } | |||
if ( SC_SOCKET_TYPE(scp) == SOCK_DGRAM && !SC_WAITS(scp) ) | ||||
{ | ||||
msg( LOG_ERR, func, | ||||
"Service %s has socket_type dgram, but does not wait", | ||||
SC_NAME(scp) ); | ||||
return FAILED; | ||||
} | ||||
if ( service_attr_check( scp ) == FAILED ) | if ( service_attr_check( scp ) == FAILED ) | |||
return( FAILED ) ; | return( FAILED ) ; | |||
return( OK ) ; | return( OK ) ; | |||
} | } | |||
/* | /* | |||
* Get a configuration from the specified file. | * Get a configuration from the specified file. | |||
*/ | */ | |||
static status_e get_conf( int fd, struct configuration *confp ) | static status_e get_conf( int fd, struct configuration *confp ) | |||
skipping to change at line 888 | skipping to change at line 882 | |||
M_CLEAR( mask, LO_USERID ) ; \ | M_CLEAR( mask, LO_USERID ) ; \ | |||
} | } | |||
/* | /* | |||
* Get a configuration by reading the configuration file. | * Get a configuration by reading the configuration file. | |||
*/ | */ | |||
status_e cnf_get( struct configuration *confp ) | status_e cnf_get( struct configuration *confp ) | |||
{ | { | |||
int config_fd ; | int config_fd ; | |||
struct service_config *scp ; | struct service_config *scp ; | |||
const char *func = "get_configuration" ; | const char *func = "cnf_get" ; | |||
if ( cnf_init( confp, &config_fd, &iter ) == FAILED ) | if ( cnf_init( confp, &config_fd, &iter ) == FAILED ) | |||
return( FAILED ) ; | return( FAILED ) ; | |||
else if ( get_conf( config_fd, confp ) == FAILED ) | else if ( get_conf( config_fd, confp ) == FAILED ) | |||
{ | { | |||
Sclose( config_fd ) ; | Sclose( config_fd ) ; | |||
cnf_free( confp ) ; | cnf_free( confp ) ; | |||
psi_destroy( iter ) ; | psi_destroy( iter ) ; | |||
return( FAILED ) ; | return( FAILED ) ; | |||
End of changes. 14 change blocks. | ||||
28 lines changed or deleted | 22 lines changed or added |