Patch by Dave King (dhking@cse.psu.edu) Documentation: This patch implements an new yes/no option for xinetd services, 'secsock_adopt'. It is meant to be used in conjunction with labelled connections in IPSec; if a service's secsock_adopt option is set to 'yes', then the security context of service is set to that of the socket which triggered its launch. (By default, this is set to 'no'.) -- Makefile.in | 6 ++--- xinetd/Makefile.in | 2 - xinetd/attr.h | 1 xinetd/child.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ xinetd/child.h | 2 + xinetd/parse.c | 1 xinetd/parsers.c | 18 +++++++++++++++ xinetd/parsers.h | 1 xinetd/sconf.h | 3 ++ 9 files changed, 90 insertions(+), 4 deletions(-) diff -puN xinetd/child.h~xinetd-fork-context xinetd/child.h --- xinetd-2.3.14/xinetd/child.h~xinetd-fork-context 2006-03-20 16:44:09.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/child.h 2006-03-20 16:44:31.000000000 -0500 @@ -17,5 +17,7 @@ void child_exit(void); __attribute__ ((noreturn)) #endif void exec_server( const struct server *serp ); +int set_exec_context_from_socket( int fd ); +int get_context_from_socket(int fd, char* buffer, unsigned int* buflen); #endif diff -puN xinetd/child.c~xinetd-fork-context xinetd/child.c --- xinetd-2.3.14/xinetd/child.c~xinetd-fork-context 2006-03-20 16:44:09.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/child.c 2006-03-21 10:04:10.000000000 -0500 @@ -31,6 +31,7 @@ #ifdef HAVE_NETDB_H #include #endif +#include #include "str.h" #include "child.h" @@ -143,6 +144,15 @@ void exec_server( const struct server *s } #endif + /* + only take on the security context if the configuration option has been set as such + */ + + if (SC_ADOPTS_SECSOCK(scp)) + { + set_exec_context_from_socket( descriptor ); + } + (void) Sclose( descriptor ) ; #ifndef solaris @@ -461,3 +471,53 @@ void child_exit(void) } } +int set_exec_context_from_socket( int fd ) +{ + const char *func = "set_exec_context_from_socket" ; + + char buffer[255]; + unsigned int buflen = 255; + + get_context_from_socket(fd, buffer, &buflen); + + int retval = setexeccon(buffer); + + if (debug.on) + { + security_context_t current_exec_context; + getexeccon( ¤t_exec_context ); + + msg( LOG_DEBUG, func, + "current security exec context now: %s", + current_exec_context); + + freecon( current_exec_context ); + } + + return retval; +} + +int get_context_from_socket(int fd, char* buffer, unsigned int* buflen) +{ + const char *func = "get_context_from_socket" ; + + int retval = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buffer, buflen); + + if ( debug.on ) + { + if (retval) + { + msg( LOG_DEBUG, func, + "error getting context for socket %d: %s (%d)", + fd, strerror(errno), errno); + } + else + { + msg( LOG_DEBUG, func, + "got context for socket %d: %s", + fd, buffer); + } + } + + return retval; +} diff -puN Makefile.in~xinetd-fork-context Makefile.in --- xinetd-2.3.14/Makefile.in~xinetd-fork-context 2006-03-20 16:44:09.000000000 -0500 +++ xinetd-2.3.14-root/Makefile.in 2006-03-20 16:44:31.000000000 -0500 @@ -12,7 +12,7 @@ DAEMONDIR = @sbindir@ MANDIR = @mandir@ topdir = @top_srcdir@ -LIBS = -lsio -lstr -lmisc -lxlog -lportable -lpset @LIBS@ +LIBS = -lsio -lstr -lmisc -lxlog -lportable -lpset -lselinux @LIBS@ CFLAGS += @CFLAGS@ DCFLAGS = -Wall -Wredundant-decls -W -Wfloat-equal -Wundef -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Wmissing-format-attribute -Wshadow -Wpointer-arith -g @@ -30,8 +30,8 @@ PROGMAKEDEFS = CC='$(CC)' CFLAGS='$(CFLA DEBUGLIBMAKEDEFS = CC='$(CC)' CFLAGS='$(DCFLAGS) -I../../include' DEBUGMAKEDEFS = CC='$(CC)' CFLAGS='$(DCFLAGS) -I../libs/include' LDFLAGS='$(LDFLAGS) -L../libs/lib' -MANDATORY_LIBS = portable sio str misc xlog pset -ALL_LIBS = portable sio str misc xlog pset +MANDATORY_LIBS = portable sio str misc xlog pset selinux +ALL_LIBS = portable sio str misc xlog pset selinux build: makelibs makeprog diff -puN xinetd/Makefile.in~xinetd-fork-context xinetd/Makefile.in --- xinetd-2.3.14/xinetd/Makefile.in~xinetd-fork-context 2006-03-20 16:44:09.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/Makefile.in 2006-03-20 16:44:31.000000000 -0500 @@ -40,7 +40,7 @@ PREFIX = @prefix@ INSTALL_CMD = @INSTALL@ -LIBS = -lsio -lmisc -lxlog -lportable -lstr -lpset @LIBS@ +LIBS = -lsio -lmisc -lxlog -lportable -lstr -lpset -lselinux @LIBS@ INCLUDEDIR = -I../libs/include LIBDIR = -L../libs/lib diff -puN xinetd/parse.c~xinetd-fork-context xinetd/parse.c --- xinetd-2.3.14/xinetd/parse.c~xinetd-fork-context 2006-03-20 16:52:30.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/parse.c 2006-03-20 17:44:33.000000000 -0500 @@ -107,6 +107,7 @@ static const struct attribute service_at #ifdef LIBWRAP { "libwrap", A_LIBWRAP, 1, libwrap_parser }, #endif + { "secsock_adopt", A_SECSOCK_ADOPT, 1, secsock_adopt_parser }, { NULL, A_NONE, -1, NULL } } ; diff -puN xinetd/attr.h~xinetd-fork-context xinetd/attr.h --- xinetd-2.3.14/xinetd/attr.h~xinetd-fork-context 2006-03-20 16:52:30.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/attr.h 2006-03-20 17:02:32.000000000 -0500 @@ -61,6 +61,7 @@ #define A_DISABLED 43 #define A_MDNS 44 #define A_LIBWRAP 45 +#define A_SECSOCK_ADOPT 46 /* * SERVICE_ATTRIBUTES is the number of service attributes and also diff -puN xinetd/parsers.h~xinetd-fork-context xinetd/parsers.h --- xinetd-2.3.14/xinetd/parsers.h~xinetd-fork-context 2006-03-20 17:09:07.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/parsers.h 2006-03-20 17:44:01.000000000 -0500 @@ -70,5 +70,6 @@ status_e mdns_parser(pset_h, struct serv #ifdef LIBWRAP status_e libwrap_parser(pset_h, struct service_config *, enum assign_op) ; #endif +status_e secsock_adopt_parser(pset_h, struct service_config *, enum assign_op) ; #endif diff -puN xinetd/parsers.c~xinetd-fork-context xinetd/parsers.c --- xinetd-2.3.14/xinetd/parsers.c~xinetd-fork-context 2006-03-20 17:09:08.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/parsers.c 2006-03-20 17:20:59.000000000 -0500 @@ -1513,3 +1513,21 @@ status_e libwrap_parser( pset_h values, } #endif +status_e secsock_adopt_parser( pset_h values, + struct service_config *scp, + enum assign_op op ) +{ + char *val = (char *) pset_pointer( values, 0 ) ; + const char *func = "secsock_adopt_parser" ; + + if ( EQ( val, "yes" ) ) + SC_SECSOCK_ADOPT(scp) = YES ; + else if ( EQ( val, "no" ) ) + SC_SECSOCK_ADOPT(scp) = NO ; + else + { + parsemsg( LOG_ERR, func, "Bad value for secsock_adopt: %s", val ) ; + return( FAILED ); + } + return( OK ) ; +} diff -puN xinetd/sconf.h~xinetd-fork-context xinetd/sconf.h --- xinetd-2.3.14/xinetd/sconf.h~xinetd-fork-context 2006-03-20 17:18:50.000000000 -0500 +++ xinetd-2.3.14-root/xinetd/sconf.h 2006-03-20 17:42:48.000000000 -0500 @@ -157,6 +157,7 @@ struct service_config #ifdef LIBWRAP char *sc_libwrap; #endif + boolean_e sc_secsock_adopt ; /* if YES, take on security context before launching child */ } ; #define SCP( p ) ((struct service_config *)(p)) @@ -218,6 +219,7 @@ struct service_config #define SC_MDNS( scp ) (scp)->sc_mdns #define SC_PER_SOURCE( scp ) (scp)->sc_per_source #define SC_LIBWRAP( scp ) (scp)->sc_libwrap +#define SC_SECSOCK_ADOPT( scp ) (scp)->sc_secsock_adopt /* * Field set macros */ @@ -253,6 +255,7 @@ struct service_config #define SC_IS_TCPMUX( scp ) ( (scp)->sc_builtin && \ (BUILTIN_HANDLER( (scp)->sc_builtin ) == \ (void *)tcpmux_handler ) ) +#define SC_ADOPTS_SECSOCK( scp ) ( (scp)->sc_secsock_adopt == YES ) #define LOGS_USERID( scp, flags ) \ ( M_IS_SET( (scp)->flags, LO_USERID ) && SC_ACCEPTS_CONNECTIONS( scp ) ) _