home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-26 | 29.8 KB | 1,266 lines |
- Newsgroups: comp.sources.unix
- From: panos@cs.colorado.edu (Panos Tsirigotis)
- Subject: v26i259: xinetd-2.1.1 - inetd replacement with access control and logging, Part15/31
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: panos@cs.colorado.edu (Panos Tsirigotis)
- Posting-Number: Volume 26, Issue 259
- Archive-Name: xinetd-2.1.1/part15
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 15 (of 31)."
- # Contents: libs/src/sio/sio.h libs/src/str/strs.c xinetd/child.c
- # xinetd/udpint.c
- # Wrapped by panos@mystique on Mon Jun 21 14:51:24 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'libs/src/sio/sio.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/sio/sio.h'\"
- else
- echo shar: Extracting \"'libs/src/sio/sio.h'\" \(6642 characters\)
- sed "s/^X//" >'libs/src/sio/sio.h' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- X/*
- X * $Id: sio.h,v 8.1 1993/03/13 01:13:58 panos Exp $
- X */
- X
- X#ifndef __SIO_H
- X#define __SIO_H
- X
- X#include <errno.h>
- X#include <varargs.h>
- X
- X/*
- X * Naming conventions:
- X * 1) SIO functions and macros have names starting with a capital S
- X * 2) SIO constants meant to be used by user programs have
- X * names starting with SIO_
- X * 3) Internal functions, struct identifiers, enum identifiers
- X * etc. have names starting with __sio
- X * 4) Internal constants and macros have names starting with __SIO
- X */
- X
- X
- X/*
- X * external constants
- X *
- X * SIO_FLUSH_ALL: flush all output streams
- X * SIO_EOF: eof on stream
- X * SIO_ERR: operation failed
- X */
- X#define SIO_FLUSH_ALL (-1)
- X#define SIO_EOF (-2)
- X#define SIO_ERR (-1)
- X
- X/*
- X * Undo types
- X */
- X#define SIO_UNDO_LINE 0
- X#define SIO_UNDO_CHAR 1
- X
- X/*
- X * Buffering types
- X */
- X#define SIO_FULLBUF 0
- X#define SIO_LINEBUF 1
- X#define SIO_NOBUF 2
- X
- X/*
- X * Descriptor for an input stream
- X */
- Xstruct __sio_input_descriptor
- X{
- X /*
- X * buf: points to the buffer area.
- X * When doing memory mapping, it is equal to the unit
- X * from which we are reading. When doing buffered I/O
- X * it points to the primary buffer.
- X */
- X char *buf ;
- X unsigned buffer_size ;
- X
- X char *start ; /* start of valid buffer contents */
- X char *end ; /* end of valid buffer contents + 1 */
- X char *nextb ; /* pointer to next byte to read/write */
- X /* Always: start <= nextb < end */
- X
- X unsigned line_length ;
- X int max_line_length ;
- X int tied_fd ;
- X
- X int memory_mapped ; /* flag to denote if we use */
- X /* memory mapping */
- X} ;
- X
- Xtypedef struct __sio_input_descriptor __sio_id_t ;
- X
- X
- X/*
- X * Descriptor for an output stream
- X */
- Xstruct __sio_output_descriptor
- X{
- X /*
- X * buf: points to the buffer area.
- X * buf_end: is equal to buf + buffer_size
- X */
- X char *buf ;
- X char *buf_end ;
- X
- X unsigned buffer_size ;
- X
- X char *start ; /* start of valid buffer contents */
- X /* (used by the R and W functions) */
- X char *nextb ; /* pointer to next byte to read/write */
- X /* Always: start <= nextb < buf_end */
- X int buftype ; /* type of buffering */
- X} ;
- X
- Xtypedef struct __sio_output_descriptor __sio_od_t ;
- X
- X
- X
- X/*
- X * Stream types
- X */
- Xenum __sio_stream { __SIO_INPUT_STREAM, __SIO_OUTPUT_STREAM } ;
- X
- X
- X/*
- X * General descriptor
- X */
- Xstruct __sio_descriptor
- X{
- X union
- X {
- X __sio_id_t input_descriptor ;
- X __sio_od_t output_descriptor ;
- X } descriptor ;
- X enum __sio_stream stream_type ;
- X int initialized ;
- X} ;
- X
- Xtypedef struct __sio_descriptor __sio_descriptor_t ;
- X
- X
- X/*
- X * The array of descriptors (as many as available file descriptors)
- X */
- Xextern __sio_descriptor_t *__sio_descriptors ;
- X
- Xextern int errno ;
- X
- X
- X/*
- X * Internally used macros
- X */
- X#define __SIO_FD_INITIALIZED( fd ) (__sio_descriptors[ fd ].initialized)
- X#define __SIO_ID( fd ) (__sio_descriptors[ fd ].descriptor.input_descriptor)
- X#define __SIO_OD( fd ) (__sio_descriptors[ fd ].descriptor.output_descriptor)
- X#define __SIO_MUST_FLUSH( od, ch ) \
- X ( (od).buftype != SIO_FULLBUF && \
- X ( (od).buftype == SIO_NOBUF || ch == '\n' ) )
- X
- X
- X/*
- X * SIO Macros:
- X *
- X * SIOLINELEN( fd )
- X * SIOMAXLINELEN( fd )
- X * Sputchar( fd, c )
- X * Sgetchar( fd )
- X *
- X * NOTE: The maximum line size depends on whether the descriptor
- X * was originally memory mapped. If it was, then the maximum
- X * line size will be the map_unit_size (a function of the system
- X * page size and PAGES_MAPPED). Otherwise, it will be either the
- X * optimal block size as reported by stat(2) or SIO_BUFFER_SIZE.
- X */
- X
- X#define SIOLINELEN( fd ) __SIO_ID( fd ).line_length
- X#define SIOMAXLINELEN( fd ) \
- X ( \
- X __SIO_FD_INITIALIZED( fd ) \
- X ? ( \
- X (__sio_descriptors[ fd ].stream_type == __SIO_INPUT_STREAM) \
- X ? __SIO_ID( fd ).max_line_length \
- X : ( errno = EBADF, SIO_ERR ) \
- X ) \
- X : ( /* not initialized; initialize it for input */ \
- X (__sio_init( &__sio_descriptors[ fd ], fd, __SIO_INPUT_STREAM ) \
- X == SIO_ERR) \
- X ? SIO_ERR \
- X : __SIO_ID( fd ).max_line_length \
- X ) \
- X )
- X
- X
- X
- X/*
- X * Adds a character to a buffer, returns the character or SIO_ERR
- X */
- X#define __SIO_ADDCHAR( od, fd, c ) \
- X ( od.buftype == SIO_FULLBUF ) \
- X ? (int) ( *(od.nextb)++ = (unsigned char) (c) ) \
- X : ( od.buftype == SIO_LINEBUF ) \
- X ? ( ( *(od.nextb) = (unsigned char) (c) ) != '\n' ) \
- X ? (int) *(od.nextb)++ \
- X : Sputc( fd, *(od.nextb) ) \
- X : Sputc( fd, c )
- X
- X
- X/*
- X * The Sgetchar/Sputchar macros depend on the fact that the fields
- X * nextb, buf_end, end
- X * are 0 if a stream descriptor is not being used or has not yet been
- X * initialized.
- X * This is true initially because of the static allocation of the
- X * descriptor array, and Sdone must make sure that it is true
- X * after I/O on a descriptor is over.
- X */
- X#define Sputchar( fd, c ) \
- X ( \
- X ( __SIO_OD( fd ).nextb < __SIO_OD( fd ).buf_end ) \
- X ? ( __SIO_ADDCHAR( __SIO_OD( fd ), fd, c ) ) \
- X : Sputc( fd, c ) \
- X )
- X
- X#define Sgetchar( fd ) \
- X ( \
- X ( __SIO_ID( fd ).nextb < __SIO_ID( fd ).end ) \
- X ? (int) *__SIO_ID( fd ).nextb++ \
- X : Sgetc( fd ) \
- X )
- X
- X
- X#ifdef __ARGS
- X#undef __ARGS
- X#endif
- X
- X#ifdef PROTOTYPES
- X# define __ARGS( s ) s
- X#else
- X# define __ARGS( s ) ()
- X#endif
- X
- X/*
- X * The Read functions
- X */
- Xint Sread __ARGS( ( int fd, char *buf, int nbytes ) ) ;
- Xint Sgetc __ARGS( ( int fd ) ) ;
- Xchar *Srdline __ARGS( ( int fd ) ) ;
- Xchar *Sfetch __ARGS( ( int fd, long *length ) ) ;
- X
- X/*
- X * The Write functions
- X */
- Xint Swrite __ARGS( ( int fd, char *buf, int nbytes ) ) ;
- Xint Sputc __ARGS( ( int fd, char c ) ) ;
- Xint Sprint __ARGS( ( int fd, char *format, ... ) ) ;
- Xint Sprintv __ARGS( ( int fd, char *format, va_list ) ) ;
- X
- X/*
- X * other functions
- X */
- Xint Sdone __ARGS( ( int fd ) ) ;
- Xint Sundo __ARGS( ( int fd, int type ) ) ;
- Xint Sflush __ARGS( ( int fd ) ) ;
- Xint Sclose __ARGS( ( int fd ) ) ;
- Xint Sbuftype __ARGS( ( int fd, int type ) ) ;
- X
- X#endif /* __SIO_H */
- X
- END_OF_FILE
- if test 6642 -ne `wc -c <'libs/src/sio/sio.h'`; then
- echo shar: \"'libs/src/sio/sio.h'\" unpacked with wrong size!
- fi
- # end of 'libs/src/sio/sio.h'
- fi
- if test -f 'libs/src/str/strs.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/str/strs.c'\"
- else
- echo shar: Extracting \"'libs/src/str/strs.c'\" \(6391 characters\)
- sed "s/^X//" >'libs/src/str/strs.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992, 1993 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- Xstatic char RCSid[] = "$Id: strs.c,v 3.1 1993/06/13 02:50:39 panos Exp $" ;
- X
- X#include <ctype.h>
- X#include <memory.h>
- X#include <varargs.h>
- X
- Xchar *malloc() ;
- X
- X#include "ss_impl.h"
- X
- X/*
- X * NOTE: The brute force method (with the __strs_bfops) must be always
- X * available so that we can switch to it if another method fails.
- X */
- Xextern struct ss_ops __strs_bfops ;
- Xextern struct ss_ops __strs_rkops ;
- Xextern struct ss_ops __strs_kmpops ;
- Xextern struct ss_ops __strs_sbmops ;
- Xextern struct ss_ops __strs_bmhops ;
- Xextern struct ss_ops __strs_soops ;
- X
- X/*
- X * NOTE: This table is arranged according to increasing method number.
- X * This allows quick indexing into it using the user-provided
- X * method as a hint:
- X * if ( selection_table[ user_method ].method == user_method )
- X * FOUND
- X * else
- X * DO SEQUENTIAL SEARCH
- X * This allows both quick access and a change of method numbers
- X * in the future without requiring recompilation of programs in
- X * order to work with new versions of the library.
- X */
- Xstatic struct ss_select selection_table[] =
- X {
- X { STRS_BF, &__strs_bfops },
- X { STRS_RK, &__strs_rkops },
- X { STRS_KMP, &__strs_kmpops },
- X { STRS_SBM, &__strs_sbmops },
- X { STRS_BMH, &__strs_bmhops },
- X { STRS_SO, &__strs_soops },
- X { 0, 0 }
- X } ;
- X
- Xstatic char identity_map[ ALPHABET_SIZE ] ;
- Xstatic char upper_to_lower_map[ ALPHABET_SIZE ] ;
- X
- Xstatic int tables_initialized ;
- X
- X/*
- X * This header is returned when an empty pattern is given to strs_setup.
- X * The rest of the functions check ss_patlen and do nothing if that is zero.
- X * ss_patlen in this header will be initialized to zero.
- X */
- Xstatic header_s empty_pattern_header ;
- X
- X
- XPRIVATE void initialize_tables()
- X{
- X int i ;
- X
- X for ( i = 0 ; i < sizeof( upper_to_lower_map ) ; i++ )
- X {
- X if ( isascii( i ) && isupper( i ) )
- X upper_to_lower_map[ i ] = i + 'a' - 'A' ;
- X else
- X upper_to_lower_map[ i ] = i ;
- X identity_map[ i ] = i ;
- X }
- X}
- X
- X
- X/*
- X * Initializes header
- X *
- X * Note that 'pattern' does not need to be a NUL-terminated string.
- X */
- XPRIVATE int init( hp, flags, pattern, patlen )
- X register header_s *hp ;
- X int flags ;
- X char *pattern ;
- X int patlen ;
- X{
- X int requested_method = SS_GETMETHOD( flags ) ;
- X register struct ss_select *selp ;
- X
- X if ( ! tables_initialized )
- X {
- X initialize_tables() ;
- X tables_initialized = TRUE ;
- X }
- X
- X /*
- X * Initialize header fields
- X */
- X SS_FLAGS( hp ) = SS_GETFLAGS( flags ) ;
- X SS_PATLEN( hp ) = patlen ;
- X if ( SS_SWITCH( hp ) && patlen < 4 )
- X SS_OPS( hp ) = &__strs_bfops ; /* brute force */
- X else
- X {
- X /*
- X * Determine ops
- X */
- X if ( selection_table[ requested_method ].sel_method == requested_method )
- X selp = &selection_table[ requested_method ] ;
- X else
- X for ( selp = &selection_table[ 0 ] ; selp->sel_ops ; selp++ )
- X if ( requested_method == selp->sel_method )
- X break ;
- X if ( selp->sel_ops )
- X SS_OPS( hp ) = selp->sel_ops ;
- X else if ( SS_SWITCH( hp ) )
- X SS_OPS( hp ) = &__strs_bfops ; /* brute force */
- X else
- X return( SS_ERR ) ;
- X }
- X
- X if ( SS_MALLOC( hp ) )
- X {
- X SS_PATTERN( hp ) = malloc( (unsigned)SS_PATLEN( hp ) ) ;
- X if ( SS_PATTERN( hp ) == CHAR_NULL )
- X {
- X (void) free( (char *)hp ) ;
- X return( SS_ERR ) ;
- X }
- X (void) memcpy( SS_PATTERN( hp ), pattern, (int)SS_PATLEN( hp ) ) ;
- X }
- X else
- X SS_PATTERN( hp ) = pattern ;
- X
- X /*
- X * If the user asked for case-insensitive search, we create our own
- X * copy of the pattern in lower case. If the pattern is malloc'ed
- X * we overwrite, otherwise we malloc some memory and clear the
- X * STRS_NOMALLOC flag.
- X */
- X if ( SS_IGNCASE( hp ) )
- X {
- X char *new_pattern ;
- X register int i ;
- X
- X SS_SETMAP( hp, upper_to_lower_map ) ;
- X
- X if ( SS_MALLOC( hp ) )
- X new_pattern = SS_PATTERN( hp ) ;
- X else
- X {
- X new_pattern = malloc( (unsigned)SS_PATLEN( hp ) + 1 ) ;
- X if ( new_pattern == CHAR_NULL )
- X return( SS_ERR ) ;
- X SS_SETMALLOC( hp ) ; /* clears the STRS_NOMALLOC flag */
- X }
- X for ( i = 0 ; i < SS_PATLEN( hp ) ; i++ )
- X new_pattern[ i ] = SS_MAP( hp, SS_PATTERN( hp )[ i ] ) ;
- X SS_PATTERN( hp ) = new_pattern ;
- X }
- X else
- X SS_SETMAP( hp, identity_map ) ;
- X
- X for ( ;; )
- X {
- X if ( SS_SETUP( hp ) == SS_OK )
- X return( SS_OK ) ;
- X else
- X {
- X if ( ! SS_SWITCH( hp ) || SS_OPS( hp ) == &__strs_bfops )
- X {
- X if ( SS_MALLOC( hp ) )
- X (void) free( (char *)hp ) ;
- X return( SS_ERR ) ;
- X }
- X SS_OPS( hp ) = &__strs_bfops ;
- X }
- X }
- X}
- X
- X
- X/*
- X * Finalize header
- X */
- XPRIVATE void fini( hp )
- X header_s *hp ;
- X{
- X SS_DONE( hp ) ;
- X if ( SS_MALLOC( hp ) )
- X (void) free( SS_PATTERN( hp ) ) ;
- X}
- X
- X
- X/*
- X * Create a search handle
- X */
- Xstrs_h strs_setup( flags, pattern, va_alist )
- X int flags ;
- X char *pattern ;
- X va_dcl
- X{
- X header_s *hp ;
- X int patlen ;
- X va_list ap ;
- X
- X hp = HP( malloc( sizeof( *hp ) ) ) ;
- X if ( hp == NULL )
- X return( NULL_HANDLE ) ;
- X
- X if ( flags & STRS_PATLEN )
- X {
- X va_start( ap ) ;
- X patlen = va_arg( ap, int ) ;
- X va_end( ap ) ;
- X }
- X else
- X patlen = strlen( pattern ) ;
- X
- X if ( patlen == 0 )
- X return( (strs_h) &empty_pattern_header ) ;
- X
- X if ( init( hp, flags, pattern, patlen ) == SS_OK )
- X return( (strs_h)hp ) ;
- X else
- X {
- X free( (char *)hp ) ;
- X return( NULL_HANDLE ) ;
- X }
- X}
- X
- X
- X/*
- X * Destroy a search handle
- X */
- Xvoid strs_done( handle )
- X strs_h handle ;
- X{
- X header_s *hp = HP( handle ) ;
- X
- X if ( SS_PATLEN( hp ) != 0 )
- X {
- X fini( hp ) ;
- X (void) free( (char *) handle ) ;
- X }
- X}
- X
- X
- Xchar *strs_match( handle, str, len )
- X strs_h handle ;
- X char *str ;
- X int len ;
- X{
- X register header_s *hp = HP( handle ) ;
- X
- X if ( SS_PATLEN( hp ) == 0 )
- X return( str ) ;
- X if ( SS_PATLEN( hp ) > len )
- X return( CHAR_NULL ) ;
- X return( SS_MATCH( hp, str, len ) ) ;
- X}
- X
- X
- X
- Xchar *strs_search( flags, str, len, pattern, va_alist )
- X int flags ;
- X char *str ;
- X int len ;
- X char *pattern ; /* NUL-terminated */
- X va_dcl
- X{
- X header_s t_header ;
- X char *p ;
- X int patlen ;
- X va_list ap ;
- X
- X if ( flags & STRS_PATLEN )
- X {
- X va_start( ap ) ;
- X patlen = va_arg( ap, int ) ;
- X va_end( ap ) ;
- X }
- X else
- X patlen = strlen( pattern ) ;
- X
- X if ( patlen == 0 )
- X return( str ) ;
- X
- X if ( patlen > len )
- X return( CHAR_NULL ) ;
- X
- X if ( init( &t_header, flags | STRS_NOMALLOC, pattern, patlen ) == SS_OK )
- X {
- X p = SS_MATCH( &t_header, str, len ) ;
- X fini( &t_header ) ;
- X return( p ) ;
- X }
- X else
- X return( CHAR_NULL ) ;
- X}
- X
- X
- END_OF_FILE
- if test 6391 -ne `wc -c <'libs/src/str/strs.c'`; then
- echo shar: \"'libs/src/str/strs.c'\" unpacked with wrong size!
- fi
- # end of 'libs/src/str/strs.c'
- fi
- if test -f 'xinetd/child.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/child.c'\"
- else
- echo shar: Extracting \"'xinetd/child.c'\" \(6363 characters\)
- sed "s/^X//" >'xinetd/child.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- Xstatic char RCSid[] = "$Id: child.c,v 6.6 1993/06/13 01:42:13 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X#include <sys/wait.h>
- X#include <netinet/in.h>
- X#include <syslog.h>
- X#include <errno.h>
- X
- X#include "str.h"
- X#include "pset.h"
- X
- X#include "options.h"
- X
- X#include "attr.h"
- X#include "server.h"
- X#include "state.h"
- X#include "sconst.h"
- X#include "config.h"
- X
- Xchar *inet_ntoa() ;
- X
- Xvoid msg() ;
- Xvoid msg_suspend() ;
- Xvoid msg_resume() ;
- X
- X
- X
- XPRIVATE void exec_server( serp )
- X struct server *serp ;
- X{
- X struct service_config *scp = SVC_CONF( SERVER_SERVICE( serp ) ) ;
- X int fd ;
- X int descriptor = SERVER_FD( serp ) ;
- X char *server = SC_SERVER( scp ) ;
- X char *func = "exec_server" ;
- X void no_control_tty() ;
- X
- X if ( debug.on )
- X msg( LOG_DEBUG, func, "duping %d", descriptor ) ;
- X
- X for ( fd = 0 ; fd <= MAX_PASS_FD ; fd++ )
- X if ( dup2( descriptor, fd ) == -1 )
- X {
- X msg( LOG_ERR, func,
- X "dup2( %d, %d ) failed: %m", descriptor, fd ) ;
- X _exit( 1 ) ;
- X }
- X
- X (void) close( descriptor ) ;
- X
- X if ( debug.on )
- X {
- X msg( LOG_DEBUG, func, "exec( %s ). no control terminal", server ) ;
- X no_control_tty() ;
- X }
- X
- X#ifdef RLIMIT_NOFILE
- X {
- X struct rlimit rl ;
- X
- X rl.rlim_cur = ps.ros.orig_max_descriptors ;
- X rl.rlim_max = ps.ros.max_descriptors ;
- X (void) setrlimit( RLIMIT_NOFILE, &rl ) ;
- X }
- X#endif
- X
- X msg_suspend() ;
- X
- X (void) execve( server, SC_SERVER_ARGV( scp ),
- X env_getvars( SC_ENV( scp )->env_handle ) ) ;
- X
- X /*
- X * The exec failed. Log the error and exit.
- X */
- X msg_resume() ;
- X msg( LOG_ERR, func, "execv( %s ) failed: %m", server ) ;
- X _exit( 0 ) ;
- X}
- X
- X
- X/*
- X * Rename this process by changing the ps.ros.Argv vector
- X * Try to put the name of the service in ps.ros.Argv[0], Argv[1]
- X * until either the service name is exhausted or we run out
- X * of ps.ros.Argv's.
- X * The rest of ps.ros.Argv is cleared to spaces
- X */
- XPRIVATE void rename_process( name )
- X char *name ;
- X{
- X register char *from = name ;
- X register char *to = ps.ros.Argv[ 0 ] ;
- X register int index = 1 ;
- X
- X while ( *from != NUL )
- X {
- X if ( *to != NUL )
- X *to++ = *from++ ;
- X else
- X if ( index < ps.ros.Argc )
- X to = ps.ros.Argv[ index++ ] ;
- X else
- X break ;
- X }
- X str_fill( to, ' ' ) ;
- X while ( index < ps.ros.Argc )
- X str_fill( ps.ros.Argv[ index++ ], ' ' ) ;
- X}
- X
- X
- XPRIVATE void set_credentials( scp )
- X register struct service_config *scp ;
- X{
- X char *func = "set_credentials" ;
- X
- X if ( SC_SPECIFIED( scp, A_GROUP ) || SC_SPECIFIED( scp, A_USER ) )
- X if ( ps.ros.is_superuser )
- X {
- X int gid = sc_getgid( scp ) ;
- X
- X if ( setgid( gid ) == -1 )
- X {
- X msg( LOG_ERR, func, "setgid failed: %m" ) ;
- X _exit( 1 ) ;
- X }
- X }
- X else
- X msg( LOG_WARNING, func, "can't change gid; not superuser" ) ;
- X
- X if ( SC_SPECIFIED( scp, A_USER ) )
- X if ( ps.ros.is_superuser )
- X {
- X if ( setuid( SC_UID( scp ) ) == -1 )
- X {
- X msg( LOG_ERR, func, "setuid failed: %m" ) ;
- X _exit( 1 ) ;
- X }
- X }
- X else
- X msg( LOG_WARNING, func, "can't change uid; not superuser" ) ;
- X}
- X
- X
- X
- X/*
- X * This function is invoked in a forked process to run a server.
- X * If the service is internal the appropriate function is invoked
- X * otherwise the server program is exec'ed.
- X * This function also logs the remote user id if appropriate
- X */
- Xvoid child_process( serp )
- X register struct server *serp ;
- X{
- X struct service *sp = SERVER_SERVICE( serp ) ;
- X register struct service_config *scp = SVC_CONF( sp ) ;
- X idresult_e log_remote_user() ;
- X char *idresult_explain() ;
- X void signal_default_state() ;
- X
- X#ifdef DEBUG_SERVER
- X if ( debug.on )
- X {
- X msg( LOG_DEBUG, "child_process", "Process %d is sleeping", getpid() ) ;
- X sleep( 10 ) ;
- X }
- X#endif
- X
- X if ( SERVER_LOGUSER( serp ) )
- X {
- X unsigned timeout ;
- X idresult_e result ;
- X
- X /*
- X * We use LOGUSER_SUCCESS_TIMEOUT unless the service requires
- X * identification, in which case we use an infinite timeout
- X */
- X timeout = SC_MUST_IDENTIFY( scp ) ? 0 : LOGUSER_SUCCESS_TIMEOUT ;
- X result = log_remote_user( serp, timeout ) ;
- X
- X if ( result != IDR_OK && SC_MUST_IDENTIFY( scp ) )
- X {
- X svc_logprint( sp, NOID_ENTRY, "%s %s",
- X conn_addrstr( SERVER_CONNECTION( serp ) ),
- X idresult_explain( result ) ) ;
- X _exit( 0 ) ;
- X }
- X }
- X
- X if ( ! SC_IS_INTERCEPTED( scp ) )
- X {
- X set_credentials( scp ) ;
- X signal_default_state() ;
- X if ( SC_SPECIFIED( scp, A_NICE ) )
- X (void) nice( SC_NICE( scp ) ) ;
- X }
- X
- X if ( ! SC_IS_INTERNAL( scp ) )
- X exec_server( serp ) ;
- X else
- X {
- X char name[ 180 ] ;
- X
- X /*
- X * We don't bother to disassociate from the controlling terminal
- X * (we have a controlling terminal only if debug.on is TRUE)
- X *
- X * Also, for interceptor processes, we give them the name:
- X * <program_name> <service-id> interceptor
- X */
- X if ( SC_IS_INTERCEPTED( scp ) )
- X strx_print( INT_NULL, name, sizeof( name ),
- X "%s %s interceptor", program_name, SC_ID( scp ) ) ;
- X else
- X {
- X int namelen = sizeof( name ) - 1 ; /* leave space for the NUL */
- X struct sockaddr_in *sinp = conn_address( SERVER_CONNECTION( serp ) ) ;
- X int len = strx_nprint( name, namelen,
- X "(%s service) %s", program_name, SC_ID( scp ) ) ;
- X
- X if ( SC_ACCEPTS_CONNECTIONS( scp ) && sinp != SOCKADDRIN_NULL )
- X strx_print( INT_NULL, &name[ len ], namelen - len,
- X " %s", inet_ntoa( sinp->sin_addr ) ) ;
- X }
- X rename_process( name ) ;
- X svc_internal( sp, serp ) ;
- X }
- X _exit( 0 ) ;
- X /* NOTREACHED */
- X}
- X
- X
- X/*
- X * This function is invoked when a SIGCLD is received
- X */
- Xvoid child_exit()
- X{
- X char *func = "child_exit" ;
- X
- X for ( ;; ) /* Find all children that exited */
- X {
- X int status ;
- X register int pid ;
- X struct server *serp ;
- X
- X#if defined( sun ) && defined( lint )
- X pid = wait3( (union wait *)&status, WNOHANG, RUSAGE_NULL ) ;
- X#else
- X pid = wait3( &status, WNOHANG, RUSAGE_NULL ) ;
- X#endif
- X
- X if ( debug.on )
- X msg( LOG_DEBUG, func, "wait3 returned = %d", pid ) ;
- X
- X if ( pid == -1 )
- X if ( errno == EINTR )
- X continue ;
- X else
- X break ;
- X
- X if ( pid == 0 )
- X break ;
- X
- X if ( ( serp = server_lookup( pid ) ) != NULL )
- X {
- X serp->svr_exit_status = status ;
- X server_end( serp ) ;
- X }
- X else
- X msg( LOG_NOTICE, func, "unknown child process %d %s", pid,
- X PROC_STOPPED( status ) ? "stopped" : "died" ) ;
- X }
- X}
- X
- END_OF_FILE
- if test 6363 -ne `wc -c <'xinetd/child.c'`; then
- echo shar: \"'xinetd/child.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/child.c'
- fi
- if test -f 'xinetd/udpint.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/udpint.c'\"
- else
- echo shar: Extracting \"'xinetd/udpint.c'\" \(6887 characters\)
- sed "s/^X//" >'xinetd/udpint.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1992 by Panagiotis Tsirigotis
- X * All rights reserved. The file named COPYRIGHT specifies the terms
- X * and conditions for redistribution.
- X */
- X
- Xstatic char RCSid[] = "$Id: udpint.c,v 6.4 1993/06/06 00:15:17 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <sys/time.h>
- X#include <syslog.h>
- X#include <errno.h>
- X
- X#include "access.h"
- X#include "defs.h"
- X#include "int.h"
- X
- X/*
- X * Datagrams greater than this will be truncated
- X */
- X#define MAX_DATAGRAM_SIZE ( 32 * 1024 )
- X
- Xchar *inet_ntoa() ;
- X
- Xvoid msg() ;
- X
- Xstruct packet
- X{
- X struct sockaddr_in from ;
- X char *data ;
- X int size ;
- X} ;
- X
- Xtypedef struct packet packet_s ;
- X
- X
- Xstruct idgram_private
- X{
- X unsigned received_packets ;
- X} ;
- X
- X#define IDP( p ) ((struct idgram_private *)(p))
- X
- X
- Xstatic struct idgram_private idgram ;
- X
- XPRIVATE void di_mux() ;
- XPRIVATE void di_exit() ;
- X
- Xstatic struct intercept_ops idgram_ops =
- X {
- X di_mux,
- X di_exit
- X } ;
- X
- X
- Xstatic struct intercept dgram_intercept_state ;
- X
- X
- Xstruct intercept *di_init( serp )
- X struct server *serp ;
- X{
- X register struct intercept *ip = &dgram_intercept_state ;
- X
- X ip->int_socket_type = SOCK_DGRAM ;
- X ip->int_priv = (void *) &idgram ;
- X ip->int_ops = &idgram_ops ;
- X int_init( ip, serp ) ;
- X return( ip ) ;
- X}
- X
- X
- XPRIVATE void di_exit()
- X{
- X register struct intercept *ip = &dgram_intercept_state ;
- X void drain() ;
- X
- X if ( IDP( ip->int_priv )->received_packets == 0 )
- X drain( INT_REMOTE( ip ) ) ;
- X int_exit( ip ) ;
- X}
- X
- X
- X/*
- X * Returns only if there is an I/O error while communicating with the server
- X */
- XPRIVATE void di_mux()
- X{
- X register struct intercept *ip = &dgram_intercept_state ;
- X fd_set socket_mask ;
- X int mask_max ;
- X PRIVATE void udp_remote_to_local() ;
- X PRIVATE status_e udp_local_to_remote() ;
- X
- X FD_ZERO( &socket_mask ) ;
- X FD_SET( INT_REMOTE( ip ), &socket_mask ) ;
- X mask_max = INT_REMOTE( ip ) ;
- X
- X for ( ;; )
- X {
- X register unsigned u ;
- X channel_s *chp ;
- X fd_set read_mask ;
- X int n_ready ;
- X
- X read_mask = socket_mask ;
- X n_ready = int_select( mask_max+1, &read_mask ) ;
- X
- X if ( n_ready == -1 )
- X return ;
- X
- X if ( FD_ISSET( INT_REMOTE( ip ), &read_mask ) )
- X {
- X udp_remote_to_local( ip, &chp ) ;
- X if ( chp != NULL )
- X {
- X FD_SET( chp->ch_local_socket, &socket_mask ) ;
- X if ( chp->ch_local_socket > mask_max )
- X mask_max = chp->ch_local_socket ;
- X }
- X if ( --n_ready == 0 )
- X continue ;
- X }
- X
- X for ( u = 0 ; u < pset_count( INT_CONNECTIONS( ip ) ) ; u++ )
- X {
- X chp = CHP( pset_pointer( INT_CONNECTIONS( ip ), u ) ) ;
- X
- X if ( FD_ISSET( chp->ch_local_socket, &read_mask ) )
- X {
- X if ( udp_local_to_remote( chp ) == FAILED )
- X return ;
- X if ( --n_ready == 0 )
- X break ;
- X }
- X }
- X }
- X}
- X
- X
- X/*
- X * Read data from the remote socket and send it to the appropriate local
- X * socket.
- X * If this is a new connection, insert it in the connection table and
- X * place its handle in *chpp.
- X */
- XPRIVATE void udp_remote_to_local( ip, chpp )
- X struct intercept *ip ;
- X channel_s **chpp ;
- X{
- X char buf[ MAX_DATAGRAM_SIZE ] ;
- X packet_s packet ;
- X channel_s *chp ;
- X bool_int addr_checked ;
- X PRIVATE void send_data() ;
- X PRIVATE status_e get_incoming_packet() ;
- X
- X *chpp = CHANNEL_NULL ;
- X
- X packet.data = buf ;
- X packet.size = sizeof( buf ) ;
- X if ( get_incoming_packet( ip, &packet ) == FAILED )
- X return ;
- X
- X chp = int_lookupconn( ip, &packet.from, &addr_checked ) ;
- X if ( chp == CHANNEL_NULL )
- X {
- X struct server *serp = INT_SERVER( ip ) ;
- X struct service *sp = SERVER_SERVICE( serp ) ;
- X connection_s *cop = SERVER_CONNECTION( serp ) ;
- X
- X if ( ( chp = int_newconn( ip, &packet.from, INT_REMOTE( ip ) ) ) == NULL )
- X return ;
- X
- X conn_setaddr( cop, &packet.from ) ; /* for logging */
- X
- X if ( INTERCEPT( ip ) )
- X {
- X mask_t check_mask ;
- X access_e result ;
- X
- X M_OR( check_mask, MASK( CF_ADDRESS ), MASK( CF_TIME ) ) ;
- X result = access_control( sp, cop, &check_mask ) ;
- X
- X if ( result != AC_OK )
- X {
- X svc_log_failure( sp, cop, result ) ;
- X chp->ch_state = BAD_CHANNEL ;
- X return ;
- X }
- X }
- X
- X /*
- X * Since we don't distinguish ports, there is no point to log
- X * another successful attempt from the same address
- X */
- X if ( ! addr_checked )
- X svc_log_success( sp, cop, SERVER_PID( serp ) ) ;
- X
- X *chpp = chp ;
- X }
- X else if ( chp->ch_state == BAD_CHANNEL )
- X return ;
- X
- X#ifdef DEBUG_UDPINT
- X if ( debug.on )
- X msg( LOG_DEBUG, "udp_remote_to_local",
- X "sending %d bytes to server on port %d",
- X packet.size, ntohs( INT_LOCALADDR( ip )->sin_port ) ) ;
- X#endif
- X
- X send_data( chp->ch_local_socket,
- X packet.data, packet.size, SOCKADDRIN_NULL ) ;
- X}
- X
- X
- X/*
- X * Send the data in buf to destination addr using the socket sd.
- X * If addr is NULL, use the default socket destination
- X */
- XPRIVATE void send_data( sd, buf, len, addr )
- X int sd ;
- X char *buf ;
- X int len ;
- X struct sockaddr_in *addr ;
- X{
- X char *p ;
- X int left ;
- X int cc ;
- X char *func = "send_data" ;
- X
- X for ( p = buf, left = len ; left > 0 ; left -= cc, p+= cc )
- X {
- X if ( addr == SOCKADDRIN_NULL )
- X cc = send( sd, p, left, 0 ) ;
- X else
- X cc = sendto( sd, p, left, 0, SA( addr ), sizeof( *addr ) ) ;
- X
- X if ( cc == -1 )
- X if ( errno == EINTR )
- X {
- X cc = 0 ;
- X continue ;
- X }
- X else
- X {
- X msg( LOG_ERR, func, "%s: %m", addr ? "sendto" : "send" ) ;
- X return ;
- X }
- X }
- X}
- X
- X
- XPRIVATE status_e get_incoming_packet( ip, pp )
- X struct intercept *ip ;
- X packet_s *pp ;
- X{
- X int from_len ;
- X char *func = "get_incoming_packet" ;
- X
- X for ( ;; )
- X {
- X int cc ;
- X
- X from_len = sizeof( pp->from ) ;
- X cc = recvfrom( INT_REMOTE( ip ), pp->data, pp->size,
- X 0, SA( &pp->from ), &from_len ) ;
- X if ( cc == -1 )
- X {
- X if ( errno != EINTR )
- X {
- X msg( LOG_ERR, func, "recvfrom error: %m" ) ;
- X return( FAILED ) ;
- X }
- X }
- X else if ( cc == 0 )
- X return( FAILED ) ;
- X else
- X {
- X pp->size = cc ;
- X IDP( ip->int_priv )->received_packets++ ;
- X break ;
- X }
- X }
- X
- X if ( from_len == 0 )
- X {
- X msg( LOG_ERR, func, "incoming packet had 0 length address" ) ;
- X return( FAILED ) ;
- X }
- X
- X#ifdef DEBUG_UDPINT
- X if ( debug.on )
- X msg( LOG_DEBUG, func, "Received %d bytes from address: %s,%d",
- X pp->size,
- X inet_ntoa( pp->from.sin_addr ), ntohs( pp->from.sin_port ) ) ;
- X#endif
- X
- X return( OK ) ;
- X}
- X
- X
- X
- XPRIVATE status_e udp_local_to_remote( chp )
- X channel_s *chp ;
- X{
- X char buf[ MAX_DATAGRAM_SIZE ] ;
- X int cc ;
- X char *func = "udp_local_to_remote" ;
- X
- X for ( ;; )
- X {
- X cc = recv( chp->ch_local_socket, buf, sizeof( buf ), 0 ) ;
- X
- X if ( cc == -1 )
- X {
- X if ( errno != EINTR )
- X {
- X msg( LOG_ERR, func, "recv from daemon: %m" ) ;
- X return( FAILED ) ;
- X }
- X }
- X else if ( cc == 0 )
- X return( FAILED ) ;
- X else
- X break ;
- X }
- X
- X#ifdef DEBUG_UDPINT
- X if ( debug.on )
- X msg( LOG_DEBUG, func, "sending %d bytes to address %s,%d",
- X cc, inet_ntoa( chp->ch_from.sin_addr ), ntohs( chp->ch_from.sin_port ) ) ;
- X#endif
- X
- X send_data( chp->ch_remote_socket, buf, cc, &chp->ch_from ) ;
- X return( OK ) ;
- X}
- X
- END_OF_FILE
- if test 6887 -ne `wc -c <'xinetd/udpint.c'`; then
- echo shar: \"'xinetd/udpint.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/udpint.c'
- fi
- echo shar: End of archive 15 \(of 31\).
- cp /dev/null ark15isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 31 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-