home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-26 | 32.7 KB | 1,280 lines |
- Newsgroups: comp.sources.unix
- From: panos@cs.colorado.edu (Panos Tsirigotis)
- Subject: v26i260: xinetd-2.1.1 - inetd replacement with access control and logging, Part16/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 260
- Archive-Name: xinetd-2.1.1/part16
-
- #! /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 16 (of 31)."
- # Contents: libs/src/xlog/xlog.3 xinetd/init.c xinetd/sconf.h
- # xinetd/server.c
- # Wrapped by panos@mystique on Mon Jun 21 14:51:25 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'libs/src/xlog/xlog.3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libs/src/xlog/xlog.3'\"
- else
- echo shar: Extracting \"'libs/src/xlog/xlog.3'\" \(7126 characters\)
- sed "s/^X//" >'libs/src/xlog/xlog.3' <<'END_OF_FILE'
- 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.\" $Id: xlog.3,v 2.3 1993/06/15 18:09:31 panos Exp $
- X.TH XLOG 3X "15 June 1993"
- Xxlog_parms, xlog_create, xlog_destroy, xlog_write, xlog_control -- general purpose logging facility
- X.SH SYNOPSIS
- X.LP
- X.nf
- X.ft B
- X#include "xlog.h"
- X.LP
- X.ft B
- Xxlog_h xlog_create( type, id, flags, ... )
- Xxlog_e type ;
- Xchar *id ;
- Xint flags ;
- X.LP
- X.ft B
- Xint xlog_parms( type, ... )
- Xxlog_e type ;
- X.LP
- X.ft B
- Xvoid xlog_destroy( xlog )
- Xxlog_h xlog ;
- X.LP
- X.ft B
- Xvoid xlog_write( xlog, buf, len, flags, ... )
- Xxlog_h xlog ;
- Xchar buf[] ;
- Xint len ;
- Xint flags ;
- X.LP
- X.ft B
- Xint xlog_control( xlog, cmd, ... )
- Xxlog_h xlog ;
- Xxlog_cmd_e cmd ;
- X.SH DESCRIPTION
- XThe purpose of this library is to provide a general purpose logging facility
- Xby providing
- X.I xlogs,
- Xlogging objects that may be connected to various existent logging facilities.
- XCurrently, the only logging facilities supported are
- X.I "syslog(3)"
- Xand logging to files.
- XLog entries are timestamped lines which may contain arbitrary information.
- X.\" ********************* xlog_create ***********************
- X.LP
- X.B xlog_create()
- Xcreates a new xlog of the specified
- X.I type.
- XPossible type values are:
- X.RS
- X.TP 20
- X.SB XLOG_SYSLOG
- XVarargs: \fIint facility, int priority\fP.
- XThe xlog will be connected to
- X.I "syslog(3)."
- X.I facility
- Xdetermines the syslog facility to use for logged messages and
- X.I priority
- Xis the default message priority.
- X.TP
- X.SB XLOG_FILELOG
- XVarargs: \fIchar *pathname, int flags [, int flags]\fP.
- XThe xlog will be connected to the file identified by
- X.I pathname.
- XThe variable part of the argument list has the same semantics as the
- Xargument list of the
- X.I "open(2)"
- Xsystem call.
- X.RE
- X.LP
- XAll xlogs have an id, specified by the
- X.I id
- Xargument. The
- X.I flags
- Xargument is formed by ORing one or more of the following constants:
- X.RS
- X.TP 20
- X.SB XLOG_NO_ERRNO
- Xdo not replace
- X.I "%m"
- Xwith an explanation of the current value of errno.
- X.TP
- X.SB XLOG_NO_SIZECHECK
- X.I "(XLOG_FILELOG only)"
- Xdo not perform size checks on the file.
- X.TP
- X.SB XLOG_PRINT_ID
- Xprecede each log entry with the xlog id
- X.TP
- X.SB XLOG_PRINT_PID
- Xprecede each log entry with the process id
- X(the process id will follow the xlog id)
- X.RE
- X.LP
- XFlags that do not apply to the xlog are ignored.
- XThe contant
- X.SM XLOG_NOFLAGS
- Xcan be used if you don't want to specify any flags.
- X.\" ********************* xlog_parms ***********************
- X.LP
- X.B xlog_parms()
- Xsets default parameters for the specified xlog
- X.I type:
- X.RS
- X.TP 20
- X.SB XLOG_SYSLOG
- X3 arguments are expected which correspond one-to-one to the arguments of
- X.I "openlog(3)."
- XThe defaults, in case this function is not used, are:
- X"XLOG", LOG_PID + LOG_NOWAIT, LOG_USER
- X.TP
- X.SB XLOG_FILELOG
- XNo action.
- X.RE
- X.LP
- X.B xlog_parms()
- Xshould be invoked before any xlogs of the specified type
- Xare created.
- X.\" ********************* xlog_destroy ***********************
- X.LP
- X.B xlog_destroy()
- Xdestroys an xlog. The action taken depends on the type of the xlog:
- X.RS
- X.TP 20
- X.SB XLOG_SYSLOG
- Xif this is the last xlog using syslog, then
- X.I "closelog(3)"
- Xis invoked.
- X.TP
- X.SB XLOG_FILELOG
- XThe file is closed.
- X.RE
- X.\" ********************* xlog_control ***********************
- X.LP
- X.B xlog_control()
- Xapplies control operations to an xlog. Certain operations are common to
- Xall xlogs while others are type-specific. The common ones are:
- X.RS
- X.TP 15
- X.SB XLOG_LINK
- XArgument list: \fIxlog_h link_to\fP.
- XLink the specified xlog to the one provided as argument.
- X(if the argument is
- X.SM NULL
- Xany existent link is severed).
- XLinking xlogs has the effect that if one finds an error it uses the
- Xother to report it.
- X.TP
- X.SB XLOG_CALLBACK
- XArgument list: \fIvoid (*callback)(), void *arg\fP.
- XThis function will be invoked in case of error while writing a log
- Xentry. It will be given
- X3 arguments: the xlog handle, an integer that indicates the type
- Xof error and the
- X.I arg
- Xspecified in this call. Possible errors include:
- X.RS
- X.TP 15
- X.SB XLOG_ENOMEM
- Xlack of memory
- X.TP
- X.SB XLOG_EOPEN
- X.I "open(2)"
- Xfailed
- X.TP
- X.SB XLOG_EFSTAT
- X.I "fstat(2)"
- Xfailed
- X.TP
- X.SB XLOG_ESIZE
- Xhard limit exceeded
- X.RE
- X.TP
- X.SB XLOG_SETFLAG
- XArgument list: \fIint flag, int *value\fP.
- XThe value of
- X.I flag
- X(one of those listed before) is set according to
- X.I "*value"
- Xwhich should be either 0 or 1.
- XThe old flag value is placed in
- X.I "*value."
- X.TP
- X.SB XLOG_GETFLAG
- XArgument list: \fIint flag, int *value\fP.
- XThe value of
- X.I flag
- X(one of those listed before) is placed in
- X.I "*value."
- X.RE
- X.LP
- XXlogs of type
- X.B XLOG_SYSLOG
- Xalso support the following operations:
- X.RS
- X.TP 15
- X.SB XLOG_FACILITY
- XArgument list: \fIint facility\fP.
- XSets the syslog facility to the specified value.
- X.TP
- X.SB XLOG_LEVEL
- XArgument list: \fIint level\fP.
- XSets the default syslog level for this xlog to the specified value.
- X.TP
- X.SB XLOG_PREEXEC
- XArgument list: \fIvoid\fP.
- XPrepares the xlog for an impending exec operation
- X.TP
- X.SB XLOG_POSTEXEC
- XArgument list: \fIvoid\fP.
- XInforms the xlog that the exec failed
- X.RE
- X.LP
- XXlogs of type
- X.B XLOG_FILELOG
- Xalso support the following operations:
- X.RS
- X.TP 15
- X.SB XLOG_LIMITS
- XArgument list: \fIunsigned soft_limit, unsigned hard_limit\fP.
- XSets soft and hard limits on the size of the file.
- XWhen any of the limits is exceeded a message is sent to the linked xlog.
- X(if there is no linked xlog, no message is sent)
- XWhen the soft limit is exceeded a warning message is sent to the linked xlog
- X(if the linked xlog is of the
- X.SB XLOG_SYSLOG
- Xtype, the message will be sent at the
- X.I LOG_ALERT
- Xlevel).
- XIf the exceeded limit is the hard limit, logging is terminated.
- XThe actual file size is checked every time this operation is applied to
- Xthe file.
- XIf logging was terminated because the hard limit was exceeded and
- Xthis operation increases the hard limit beyond the actual file size,
- Xlogging will be resumed.
- X.TP
- X.SB XLOG_SIZECHECK
- XArgument list: \fIvoid\fP.
- XChecks the actual file size.
- X.TP
- X.SB XLOG_GETFD
- XArgument list: \fIint *value\fP.
- XPlaces in
- X.I "*value"
- Xthe file descriptor of the log file.
- X.RE
- X.\" ********************* xlog_write ***********************
- X.LP
- X.B xlog_write()
- Xwrites a message to the specified xlog. A
- X.SM NEWLINE
- Xis always appended to the message.
- XThe first occurrence of "%m" in
- X.I buf
- Xis replaced by a string explaining the current value of
- X.I errno.
- XThe
- X.I flags
- Xargument is formed in the same way as in
- X.B xlog_create().
- XOne additional constant is available:
- X.RS
- X.TP 20
- X.SB XLOG_SET_LEVEL
- X.I "(XLOG_SYSLOG only)"
- Xthe next argument is an integer that should be used as the syslog level
- Xfor this message instead of the default level of the xlog.
- X.RE
- X.SH "RETURN VALUES"
- X.B xlog_create()
- Xreturns an xlog handle or
- X.SM NULL
- Xif it fails.
- X.LP
- X.B xlog_control()
- Xreturns an error code (it returns
- X.SM XLOG_ENOERROR
- Xif it is successful).
- X.LP
- X.B xlog_parms()
- Xreturns an error code (it returns
- X.SM XLOG_ENOERROR
- Xif it is successful).
- X.SH "SEE ALSO"
- Xopenlog(3), syslog(3), closelog(3)
- X.SH BUGS
- X.LP
- XOnly the first occurrence of
- X.I "%m"
- Xis replaced by an errno explanation.
- X.LP
- XThere is no check for cycles when linking xlogs. In particular it is
- Xpossible to link a xlog to itself.
- END_OF_FILE
- if test 7126 -ne `wc -c <'libs/src/xlog/xlog.3'`; then
- echo shar: \"'libs/src/xlog/xlog.3'\" unpacked with wrong size!
- fi
- # end of 'libs/src/xlog/xlog.3'
- fi
- if test -f 'xinetd/init.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/init.c'\"
- else
- echo shar: Extracting \"'xinetd/init.c'\" \(7287 characters\)
- sed "s/^X//" >'xinetd/init.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: init.c,v 6.11 1993/06/15 23:25:57 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X#include <syslog.h>
- X#include <fcntl.h>
- X
- X#include "sio.h"
- X#include "str.h"
- X#include "pset.h"
- X#include "xlog.h"
- X
- X#include "options.h"
- X
- X#include "state.h"
- X#include "defs.h"
- X#include "config.h"
- X#include "conf.h"
- X
- X
- Xstruct module
- X{
- X char *name ;
- X status_e (*initializer)() ;
- X} ;
- X
- X
- Xchar *msg_init() ;
- Xstatus_e signal_init() ;
- Xstatus_e initenv() ;
- Xstatus_e create_conf_timer() ;
- Xstatus_e create_retry_timer() ;
- Xstatus_e create_cc_timer() ;
- X
- Xstatic struct module program_modules[] =
- X {
- X { "signal", signal_init },
- X { "environment", initenv },
- X#ifndef NO_TIMERS
- X { "conf timer", create_conf_timer },
- X { "retry timer", create_retry_timer },
- X { "consistency check timer", create_cc_timer },
- X#endif
- X { CHAR_NULL }
- X } ;
- X
- X
- Xstatic bool_int have_stderr ;
- X
- Xextern int sys_nerr;
- Xextern char *sys_errlist[];
- Xextern int errno;
- X
- Xvoid msg() ;
- X
- Xvoid exit() ;
- X
- X#define STDERR_FD 2
- X
- X
- X/*
- X * This function is invoked when a system call fails during initialization.
- X * A message is printed to stderr, and the program is terminated
- X */
- XPRIVATE void syscall_failed( call )
- X char *call ;
- X{
- X char errno_buf[ 40 ] ;
- X char *err ;
- X
- X if ( have_stderr )
- X {
- X if ( errno < sys_nerr )
- X err = sys_errlist[ errno ] ;
- X else
- X err = strx_sprint( errno_buf, sizeof( errno_buf ),
- X "errno = %d", errno ) ;
- X Sprint( STDERR_FD, "%s: %s failed: %s\n", program_name, call, err ) ;
- X }
- X exit( 1 ) ;
- X}
- X
- X
- X
- X/*
- X * Close all descriptors except STDERR_FD. We need this to report
- X * errors and the process pid of the daemon.
- X * Open all descriptors in the range 0..MAX_PASS_FD (except STDERR_FD)
- X * to the root directory.
- X * STDERR_FD should not be 0.
- X */
- XPRIVATE void setup_file_descriptors()
- X{
- X int fd ;
- X int new ;
- X int root_fd ;
- X int n_descriptors = getdtablesize() ;
- X
- X /*
- X * Close all unneeded descriptors
- X */
- X for ( fd = 0 ; fd < n_descriptors ; fd++ )
- X if ( fd != STDERR_FD )
- X (void) close( fd ) ;
- X
- X /*
- X * Check if the STDERR_FD descriptor is open.
- X */
- X new = dup( STDERR_FD ) ;
- X if ( new != -1 )
- X {
- X have_stderr = TRUE ;
- X (void) close( new ) ;
- X }
- X
- X if ( ( root_fd = open( "/", O_RDONLY ) ) == -1 )
- X syscall_failed( "open of '/'" ) ;
- X
- X for ( fd = 0 ; fd <= MAX_PASS_FD ; fd++ )
- X {
- X if ( have_stderr && fd == STDERR_FD )
- X continue ;
- X if ( fd != root_fd && dup2( root_fd, fd ) == -1 )
- X syscall_failed( "dup2" ) ;
- X }
- X
- X if ( root_fd > MAX_PASS_FD )
- X (void) close( root_fd ) ;
- X}
- X
- X
- X
- XPRIVATE void set_fd_limit()
- X{
- X#ifdef RLIMIT_NOFILE
- X
- X struct rlimit rl ;
- X char *func = "set_fd_limit" ;
- X
- X /*
- X * Set the soft file descriptor limit to the hard limit.
- X */
- X if ( getrlimit( RLIMIT_NOFILE, &rl ) == -1 )
- X {
- X msg( LOG_CRIT, func, "getrlimit: %m" ) ;
- X exit( 1 ) ;
- X }
- X
- X ps.ros.orig_max_descriptors = rl.rlim_cur ;
- X ps.ros.max_descriptors = rl.rlim_max ;
- X
- X rl.rlim_cur = rl.rlim_max ;
- X if ( setrlimit( RLIMIT_NOFILE, &rl ) == -1 )
- X {
- X ps.ros.max_descriptors = ps.ros.orig_max_descriptors ;
- X return ;
- X }
- X
- X if ( Smorefds() == SIO_ERR )
- X {
- X msg( LOG_CRIT, func, "Smorefds: %m" ) ;
- X exit( 1 ) ;
- X }
- X
- X#else /* ! RLIMIT_NOFILE */
- X
- X ps.ros.max_descriptors = getdtablesize() ;
- X
- X#endif /* RLIMIT_NOFILE */
- X}
- X
- X
- XPRIVATE void init_common( argc, argv )
- X int argc ;
- X char *argv[] ;
- X{
- X struct module *mp ;
- X char *func = "init_common" ;
- X
- X /*
- X * Initialize the program state
- X */
- X set_fd_limit() ;
- X
- X ps.ros.Argv = argv ;
- X ps.ros.Argc = argc ;
- X ps.ros.config_file = f_option ? f_option_arg : DEFAULT_CONFIG_FILE ;
- X ps.ros.is_superuser = ( geteuid() == 0 ) ;
- X if ( limit_option )
- X ps.ros.process_limit = limit_option_arg ;
- X ps.ros.loop_rate = ( loop_option ) ? loop_option_arg : DEFAULT_LOOP_RATE ;
- X
- X /*
- X * Initialize the program modules
- X */
- X for ( mp = program_modules ; mp->name ; mp++ )
- X if ( (*mp->initializer)() == FAILED )
- X {
- X msg( LOG_CRIT, func,
- X "Initialization of %s facility failed. Exiting...", mp->name ) ;
- X exit( 1 ) ;
- X }
- X (void) umask( 0 ) ;
- X}
- X
- X
- X/*
- X * Become a daemon by forking a new process. The parent process exits.
- X */
- XPRIVATE void become_daemon()
- X{
- X int tries ;
- X int pid ;
- X char *func = "become_daemon" ;
- X void no_control_tty() ;
- X
- X /*
- X * First fork so that the parent will think we have exited
- X */
- X for ( tries = 0 ;; tries++ )
- X {
- X if ( tries == 5 )
- X {
- X msg( LOG_CRIT, func, "fork: %m. Exiting..." ) ;
- X exit( 0 ) ;
- X }
- X
- X pid = fork() ;
- X
- X if ( pid == -1 )
- X {
- X sleep( 1 ) ; /* wait for a second */
- X continue ; /* and then retry */
- X }
- X else if ( pid == 0 )
- X break ;
- X else
- X {
- X if ( pid_option && have_stderr )
- X Sprint( STDERR_FD, "%d\n", pid ) ;
- X#ifndef DEBUG_DAEMON
- X sleep( 3 ) ; /* give some time to the daemon to initialize */
- X#endif
- X exit( 0 ) ;
- X }
- X }
- X
- X (void) dup2( 0, STDERR_FD ) ;
- X no_control_tty() ;
- X
- X#ifdef DEBUG_DAEMON
- X sleep( 20 ) ; /* XXX: timers will probably not work after this */
- X#endif
- X}
- X
- X
- X
- XPRIVATE pset_h new_table( size )
- X unsigned size ;
- X{
- X char *func = "new_table" ;
- X pset_h tab = pset_create( size, 0 ) ;
- X
- X if ( tab == NULL )
- X {
- X msg( LOG_CRIT, func, "Failed to create table" ) ;
- X exit( 1 ) ;
- X }
- X return( tab ) ;
- X}
- X
- X
- X/*
- X * Create tables
- X */
- XPRIVATE void init_rw_state()
- X{
- X SERVERS( ps ) = new_table( 0 ) ;
- X RETRIES( ps ) = new_table( 0 ) ;
- X SERVICES( ps ) = new_table( 0 ) ;
- X
- X ps.rws.descriptors_free = ps.ros.max_descriptors - DESCRIPTORS_RESERVED ;
- X
- X FD_ZERO( &ps.rws.socket_mask ) ;
- X ps.rws.mask_max = 0 ;
- X
- X}
- X
- X
- X/*
- X * Perform all necessary initializations
- X */
- Xvoid init_daemon( argc, argv )
- X int argc ;
- X char *argv[] ;
- X{
- X char *fail ;
- X
- X setup_file_descriptors() ;
- X
- X (void) opt_recognize( argc, argv ) ;
- X debug.on = d_option ;
- X
- X /*
- X * XXX: we only use xlog_parms on XLOG_SYSLOG-type logs but in general
- X * we should do it for all types of xlog's we may use. We can get
- X * away with this now, because xlog_parms for XLOG_FILELOG is a noop.
- X */
- X (void) xlog_parms( XLOG_SYSLOG,
- X program_name, LOG_PID + LOG_NOWAIT, LOG_DAEMON ) ;
- X
- X /*
- X * Initialize the message facility; after this everything can use the
- X * msg() interface
- X */
- X if ( fail = msg_init() )
- X {
- X if ( have_stderr )
- X Sprint( STDERR_FD, "%s: msg_init failed: %s\n", program_name, fail ) ;
- X exit( 1 ) ;
- X }
- X
- X init_common( argc, argv ) ;
- X
- X if ( ! debug.on )
- X become_daemon() ;
- X
- X init_rw_state() ;
- X}
- X
- X
- X/*
- X * Initialize all services
- X *
- X * This function is either successful in starting some services
- X * or it terminates the program.
- X */
- Xvoid init_services()
- X{
- X struct configuration conf ;
- X char *func = "init_services" ;
- X void spec_include() ;
- X
- X if ( cnf_get( &conf, (long)0 ) == FAILED )
- X {
- X msg( LOG_CRIT, func, "couldn't get configuration. Exiting..." ) ;
- X exit( 1 ) ;
- X }
- X
- X DEFAULTS( ps ) = CNF_DEFAULTS( &conf ) ;
- X (void) cnf_start_services( &conf ) ;
- X CNF_DEFAULTS( &conf ) = NULL ; /* to avoid the free by cnf_free */
- X cnf_free( &conf ) ;
- X
- X /*
- X * The number of available/active services is kept by the service functions
- X */
- X if ( ps.rws.available_services == 0 )
- X {
- X msg( LOG_CRIT, func, "no services. Exiting..." ) ;
- X exit( 1 ) ;
- X }
- X
- X spec_include() ; /* include special services */
- X}
- X
- END_OF_FILE
- if test 7287 -ne `wc -c <'xinetd/init.c'`; then
- echo shar: \"'xinetd/init.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/init.c'
- fi
- if test -f 'xinetd/sconf.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/sconf.h'\"
- else
- echo shar: Extracting \"'xinetd/sconf.h'\" \(7383 characters\)
- sed "s/^X//" >'xinetd/sconf.h' <<'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
- X#ifndef SCONF_H
- X#define SCONF_H
- X
- X/*
- X * $Id: sconf.h,v 6.5 1993/06/01 22:56:06 panos Exp $
- X */
- X
- X#include "pset.h"
- X#include "env.h"
- X#include "sio.h"
- X
- X#include "defs.h"
- X#include "log.h"
- X#include "mask.h"
- X#include "builtin.h"
- X
- X/*
- X * Service types
- X */
- X#define ST_RPC 1
- X#define ST_INTERNAL 2
- X#define ST_UNLISTED 3
- X#define ST_SPECIAL 4
- X
- X/*
- X * Service flags
- X */
- X#define SF_INTERCEPT 1
- X#define SF_REUSE 2
- X#define SF_NORETRY 3
- X#define SF_IDONLY 4
- X
- X/*
- X * Values for log options
- X */
- X#define LO_HOST 1
- X#define LO_DURATION 3
- X#define LO_ATTEMPT 4
- X#define LO_EXIT 5
- X#define LO_RECORD 6
- X#define LO_PID 7
- X#define LO_START 8
- X#define LO_USERID 9
- X
- X
- X
- Xstruct rpc_data
- X{
- X unsigned long rd_min_version ;
- X unsigned long rd_max_version ;
- X unsigned long rd_program_number ;
- X} ;
- X
- X#define RD_MINVERS( rdp ) (rdp)->rd_min_version
- X#define RD_MAXVERS( rdp ) (rdp)->rd_max_version
- X#define RD_PROGNUM( rdp ) (rdp)->rd_program_number
- X
- Xtypedef enum { NO_ENV = 0, STD_ENV, DEF_ENV, CUSTOM_ENV } environ_e ;
- X
- Xstruct environment
- X{
- X environ_e env_type ;
- X env_h env_handle ;
- X} ;
- X
- X
- X/*
- X * NOTE: Clearing the structure will give all its fields their default values
- X */
- Xstruct service_config
- X{
- X mask_t sc_specified_attributes ; /* specified attributes */
- X mask_t sc_attributes_present ; /* includes those from defaults */
- X mask_t sc_type ; /* RPC, UNLISTED etc. */
- X mask_t sc_flags ; /* REUSE, INTERCEPT etc. */
- X char *sc_name ; /* e.g. "echo" */
- X char *sc_id ; /* e.g. "echo-stream" */
- X unsigned sc_port ; /* in host byte order */
- X int sc_socket_type ; /* e.g. SOCK_DGRAM */
- X struct name_value sc_protocol ; /* e.g. "TCP", IPPROTO_TCP */
- X boolean_e sc_wait ;
- X int sc_uid ;
- X int sc_user_gid ; /* gid corresponding to uid */
- X int sc_gid ; /* gid corresponding to group */
- X char *sc_server ;
- X char **sc_server_argv ;
- X int sc_instances ;
- X int sc_nice ; /* argument for nice(3) */
- X pset_h sc_env_var_defs ; /* list of env strings */
- X pset_h sc_pass_env_vars ; /* env vars to pass to server */
- X pset_h sc_access_times ;
- X pset_h sc_only_from ;
- X pset_h sc_no_access ;
- X mask_t sc_log_on_success ;
- X mask_t sc_log_on_failure ;
- X struct log sc_log ;
- X struct rpc_data sc_rd ;
- X pset_h sc_disabled ; /* used only by the default entry */
- X struct environment sc_environment ;
- X builtin_s *sc_builtin ;
- X} ;
- X
- X#define SCP( p ) ((struct service_config *)(p))
- X
- X/*
- X * Field access macros
- X */
- X#define SC_LOG( scp ) (&(scp)->sc_log)
- X#define SC_RPCDATA( scp ) (&(scp)->sc_rd)
- X#define SC_ENV( scp ) (&(scp)->sc_environment)
- X#define SC_BUILTIN( scp ) (scp)->sc_builtin
- X#define SC_PORT( scp ) (scp)->sc_port
- X#define SC_NICE( scp ) (scp)->sc_nice
- X#define SC_SOCKET_TYPE( scp ) (scp)->sc_socket_type
- X#define SC_ID( scp ) (scp)->sc_id
- X#define SC_NAME( scp ) (scp)->sc_name
- X#define SC_PROTOVAL( scp ) (scp)->sc_protocol.value
- X#define SC_PROTONAME( scp ) (scp)->sc_protocol.name
- X#define SC_INSTANCES( scp ) (scp)->sc_instances
- X#define SC_UID( scp ) (scp)->sc_uid
- X#define SC_SERVER( scp ) (scp)->sc_server
- X#define SC_SERVER_ARGV( scp ) (scp)->sc_server_argv
- X#define SC_ONLY_FROM( scp ) (scp)->sc_only_from
- X#define SC_NO_ACCESS( scp ) (scp)->sc_no_access
- X#define SC_ACCESS_TIMES( scp ) (scp)->sc_access_times
- X#define SC_LOG_ON_SUCCESS( scp ) (scp)->sc_log_on_success
- X#define SC_LOG_ON_FAILURE( scp ) (scp)->sc_log_on_failure
- X
- X/*
- X * Field set macros
- X */
- X#define sc_set_port( scp, port ) (scp)->sc_port = (port)
- X
- X/*
- X * Predicate checking macros
- X */
- X#define SC_FORKS( scp ) ( ! SC_IS_INTERNAL( scp ) || \
- X builtin_forks( (scp)->sc_builtin ) )
- X#define SC_WAITS( scp ) ( (scp)->sc_wait == YES )
- X#define SC_RETRY( scp ) ( M_IS_CLEAR( (scp)->sc_flags, SF_NORETRY ) )
- X#define SC_REUSE_ADDRESS( scp ) M_IS_SET( (scp)->sc_flags, SF_REUSE )
- X#define SC_MUST_IDENTIFY( scp ) M_IS_SET( (scp)->sc_flags, SF_IDONLY )
- X
- X#define SC_IS_RPC( scp ) ( M_IS_SET( (scp)->sc_type, ST_RPC ) )
- X#define SC_IS_INTERNAL( scp ) ( M_IS_SET( (scp)->sc_type, ST_INTERNAL ) )
- X#define SC_IS_SPECIAL( scp ) ( M_IS_SET( (scp)->sc_type, ST_SPECIAL ) )
- X#define SC_IS_UNLISTED( scp ) ( M_IS_SET( (scp)->sc_type, ST_UNLISTED ) )
- X#define SC_IS_INTERCEPTED( scp ) ( M_IS_SET( (scp)->sc_flags, SF_INTERCEPT ) )
- X
- X#define LOGS_USERID( scp, flags ) \
- X ( M_IS_SET( (scp)->flags, LO_USERID ) && SC_ACCEPTS_CONNECTIONS( scp ) )
- X
- X#define LOGS_ANY( scp, flags ) ( ! M_ARE_ALL_CLEAR( (scp)->flags ) )
- X
- X#define SC_LOGS_ON_SUCCESS( scp ) LOGS_ANY( scp, sc_log_on_success )
- X#define SC_LOGS_ON_FAILURE( scp ) LOGS_ANY( scp, sc_log_on_failure )
- X#define SC_LOGS_USERID_ON_FAILURE( scp ) LOGS_USERID( scp, sc_log_on_failure )
- X#define SC_LOGS_USERID_ON_SUCCESS( scp ) LOGS_USERID( scp, sc_log_on_success )
- X#define SC_LOGS_ON_EXIT( scp ) \
- X ( M_IS_SET( (scp)->sc_log_on_success, LO_DURATION ) || \
- X M_IS_SET( (scp)->sc_log_on_success, LO_EXIT ) )
- X#define SC_RECORDS( scp ) M_IS_SET( (scp)->sc_log_on_failure, LO_RECORD )
- X#define SC_LOGS_PID( scp ) M_IS_SET( (scp)->sc_log_on_success, LO_PID )
- X#define SC_LOGS_EXITS( scp ) M_IS_SET( (scp)->sc_log_on_success, LO_EXIT )
- X#define SC_LOGS_DURATION( scp ) \
- X M_IS_SET( (scp)->sc_log_on_success, LO_DURATION )
- X
- X
- X#define SC_MUST_LISTEN( scp ) ( (scp)->sc_socket_type == SOCK_STREAM )
- X
- X#define SC_ACCEPTS_CONNECTIONS( scp ) \
- X ( (scp)->sc_wait == NO && (scp)->sc_socket_type == SOCK_STREAM )
- X
- X#define SC_SPECIFIED( scp, attr ) \
- X M_IS_SET( (scp)->sc_specified_attributes, (attr) )
- X#define SC_SPECIFY( scp, attr ) \
- X { \
- X M_SET( (scp)->sc_specified_attributes, (attr) ) ; \
- X SC_PRESENT( (scp), (attr) ) ; \
- X }
- X#define SC_UNSPECIFY( scp, attr ) \
- X M_CLEAR( (scp)->sc_specified_attributes, (attr) )
- X
- X#define SC_IS_PRESENT( scp, attr ) \
- X M_IS_SET( (scp)->sc_attributes_present, (attr) )
- X#define SC_PRESENT( scp, attr ) \
- X M_SET( (scp)->sc_attributes_present, (attr) )
- X#define SC_ABSENT( scp, attr ) \
- X { \
- X M_CLEAR( (scp)->sc_attributes_present, (attr) ) ; \
- X SC_UNSPECIFY( (scp), (attr) ) ; \
- X }
- X
- X#define sc_getgid( scp ) ( SC_SPECIFIED( scp, A_GROUP ) \
- X ? (scp)->sc_gid : (scp)->sc_user_gid )
- X#define sc_internal( scp, serp ) builtin_invoke( (scp)->sc_builtin, serp )
- X#define sc_make_external( scp ) M_CLEAR( (scp)->sc_type, ST_INTERNAL )
- X
- Xstatus_e sc_init() ;
- Xstruct service_config *sc_alloc() ;
- Xvoid sc_free() ;
- Xvoid sc_dump() ;
- Xstruct service_config *sc_make_special() ;
- Xbool_int sc_different_confs() ;
- X
- X#endif /* SCONF_H */
- X
- END_OF_FILE
- if test 7383 -ne `wc -c <'xinetd/sconf.h'`; then
- echo shar: \"'xinetd/sconf.h'\" unpacked with wrong size!
- fi
- # end of 'xinetd/sconf.h'
- fi
- if test -f 'xinetd/server.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xinetd/server.c'\"
- else
- echo shar: Extracting \"'xinetd/server.c'\" \(7431 characters\)
- sed "s/^X//" >'xinetd/server.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: server.c,v 6.11 1993/06/15 23:25:57 panos Exp $" ;
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <syslog.h>
- X#include <fcntl.h>
- X#include <time.h>
- X
- X#include "sio.h"
- X
- X#include "state.h"
- X#include "access.h"
- X#include "connection.h"
- X#include "config.h"
- X#include "server.h"
- X
- X#define NEW_SERVER() NEW( struct server )
- X#define FREE_SERVER( serp ) FREE( serp )
- X
- X
- Xchar *inet_ntoa() ;
- Xtime_t time() ;
- Xchar *malloc() ;
- X
- Xvoid msg() ;
- Xvoid out_of_memory() ;
- X
- X#ifndef DEBUG_RETRY
- X#define do_fork() fork()
- X#else
- X#include <errno.h>
- Xextern int errno ;
- X
- X/*
- X * 3 out of 4 times the do_fork() will fail
- X */
- X#define do_fork() ( random() & 0x11 ) ? ( errno = EAGAIN, -1 ) : fork()
- X#endif /* DEBUG_RETRY */
- X
- X
- X/*
- X * Allocate a server, initialize it from init_serp, and insert it in stab
- X */
- XPRIVATE struct server *server_alloc( init_serp, stab )
- X struct server *init_serp ;
- X register pset_h stab ;
- X{
- X register struct server *serp ;
- X char *func = "server_alloc" ;
- X
- X serp = NEW_SERVER() ;
- X if ( serp == NULL )
- X {
- X out_of_memory( func ) ;
- X return( NULL ) ;
- X }
- X
- X if ( pset_add( stab, serp ) == NULL )
- X {
- X msg( LOG_CRIT, func, "couldn't insert server in server table" ) ;
- X FREE_SERVER( serp ) ;
- X return( NULL ) ;
- X }
- X
- X *serp = *init_serp ; /* initialize it */
- X SVC_HOLD( serp->svr_sp ) ;
- X
- X return( serp ) ;
- X}
- X
- X
- Xvoid server_release( serp )
- X register struct server *serp ;
- X{
- X struct service *sp = SERVER_SERVICE( serp ) ;
- X register int count = SVC_RELE( sp ) ;
- X
- X if ( count == 0 && ! SC_IS_SPECIAL( SVC_CONF( sp ) ) )
- X pset_remove( SERVICES( ps ), sp ) ;
- X
- X FREE_SERVER( serp ) ;
- X}
- X
- X
- X/*
- X * If a service is internal and does not require forking a process:
- X * - if it accepts connections, we put the accepted connection
- X * in non-blocking mode to avoid a possible block on
- X * the write(2).
- X * - the log flags that have to do with the server exiting are
- X * ignored (i.e. nothing is logged).
- X * - it can be identified in the log because the server pid is 0.
- X */
- XPRIVATE void server_internal( serp )
- X register struct server *serp ;
- X{
- X register struct service *sp = serp->svr_sp ;
- X char *func = "server_internal" ;
- X
- X serp->svr_pid = 0 ;
- X if ( SVC_ACCEPTS_CONNECTIONS( sp ) &&
- X fcntl( SERVER_FD( serp ), F_SETFL, FNDELAY ) == -1 )
- X {
- X msg( LOG_ERR, func, "%s: fcntl F_SETFL failed: %m", SVC_ID( sp ) ) ;
- X return ;
- X }
- X svc_log_success( sp, serp->svr_conn, serp->svr_pid ) ;
- X svc_internal( sp, serp ) ;
- X}
- X
- X
- X/*
- X * Attempt to start a server for service 'sp' to handle
- X * connection 'cp'.
- X * Return value:
- X * OK: if a server is started or a retry attempt
- X * is scheduled
- X * FAILED: otherwise (a log entry is also made)
- X */
- Xstatus_e server_run( sp, cp )
- X struct service *sp ;
- X connection_s *cp ;
- X{
- X struct server server ;
- X register struct server *serp ;
- X char *func = "server_run" ;
- X status_e schedule_retry() ;
- X
- X CLEAR( server ) ;
- X server.svr_sp = sp ;
- X server.svr_conn = cp ;
- X
- X /*
- X * Allocate a server struct only if we will fork a new process
- X */
- X if ( ! SVC_FORKS( sp ) )
- X {
- X server_internal( &server ) ;
- X conn_free( cp ) ;
- X return( OK ) ;
- X }
- X
- X /*
- X * Insert new struct server in server table first, to avoid the
- X * possibility of running out of memory *after* the fork.
- X */
- X serp = server_alloc( &server, SERVERS( ps ) ) ;
- X if ( serp == NULL )
- X return( FAILED ) ;
- X
- X if ( server_start( serp ) == OK )
- X {
- X conn_close( cp ) ;
- X return( OK ) ;
- X }
- X
- X /*
- X * Fork failed; remove the server from the server table
- X */
- X pset_remove( SERVERS( ps ), serp ) ;
- X
- X /*
- X * Currently, fork failures are the only reason for retrying.
- X * There is no retry if we exceed the max allowed number of fork failures
- X */
- X if ( ! SERVER_FORKLIMIT( serp ) && SVC_RETRY( sp ) )
- X {
- X if ( schedule_retry( serp ) == OK )
- X return( OK ) ;
- X else
- X msg( LOG_ERR, func, "Retry failure for %s service", SVC_ID( sp ) ) ;
- X }
- X else
- X svc_log_failure( sp, cp, AC_FORK ) ;
- X
- X server_release( serp ) ;
- X return( FAILED ) ;
- X}
- X
- X
- X/*
- X * Try to fork a server process
- X */
- Xstatus_e server_start( serp )
- X register struct server *serp ;
- X{
- X register struct service *sp = serp->svr_sp ;
- X char *func = "server_start" ;
- X void child_process() ;
- X
- X serp->svr_log_remote_user = SVC_LOGS_USERID_ON_SUCCESS( sp ) ;
- X
- X serp->svr_pid = do_fork() ;
- X
- X switch ( serp->svr_pid )
- X {
- X case 0:
- X ps.rws.env_is_valid = FALSE ;
- X
- X child_process( serp ) ;
- X
- X msg( LOG_ERR, func, "INTERNAL ERROR: child_process returned" ) ;
- X _exit( 0 ) ;
- X /* NOTREACHED */
- X
- X case -1:
- X msg( LOG_ERR, func, "%s: fork failed: %m", SVC_ID( sp ) ) ;
- X serp->svr_fork_failures++ ;
- X return( FAILED ) ;
- X
- X default:
- X (void) time( &serp->svr_start_time ) ;
- X svc_inc_running_servers( sp ) ;
- X
- X /*
- X * Log the start of another server (if it is not an interceptor).
- X * Determine if the server writes to the log (because in that case
- X * we will have to check the log size).
- X */
- X if ( ! SVC_IS_INTERCEPTED( sp ) )
- X svc_log_success( sp, serp->svr_conn, serp->svr_pid ) ;
- X else
- X serp->svr_writes_to_log = SVC_IS_LOGGING( sp ) ;
- X serp->svr_writes_to_log |= serp->svr_log_remote_user ;
- X return( OK ) ;
- X }
- X}
- X
- X
- Xvoid server_dump( serp, fd )
- X register struct server *serp ;
- X int fd ;
- X{
- X struct service *sp = serp->svr_sp ;
- X
- X Sprint( fd, "%s server\n", SVC_ID( sp ) ) ;
- X Sprint( fd, "pid = %d\n", serp->svr_pid ) ;
- X Sprint( fd, "start_time = %s", ctime( &serp->svr_start_time ) ) ;
- X Sprint( fd, "Connection info:\n" ) ;
- X conn_dump( serp->svr_conn, fd ) ;
- X if ( serp->svr_fork_failures )
- X Sprint( fd, "fork_failures = %d\n", serp->svr_fork_failures ) ;
- X Sprint( fd,
- X "log_remote_user = %s\n", serp->svr_log_remote_user ? "YES" : "NO" ) ;
- X Sprint( fd,
- X "writes_to_log = %s\n", serp->svr_writes_to_log ? "YES" : "NO" ) ;
- X Sputchar( fd, '\n' ) ;
- X Sflush( fd ) ;
- X}
- X
- X
- X/*
- X * Invoked when a server dies, either because of a signal or in case of
- X * a normal exit.
- X */
- Xvoid server_end( serp )
- X register struct server *serp ;
- X{
- X register struct service *sp = serp->svr_sp ;
- X char *func = "server_end" ;
- X
- X if ( PROC_EXITED( serp->svr_exit_status ) ||
- X PROC_SIGNALED( serp->svr_exit_status ) )
- X {
- X char *death_type = PROC_EXITED( serp->svr_exit_status ) ? "exited"
- X : "died" ;
- X if ( debug.on )
- X {
- X struct service *conn_sp = CONN_SERVICE( serp->svr_conn ) ;
- X
- X if ( conn_sp == sp )
- X msg( LOG_DEBUG, func,
- X "%s server %d %s", SVC_ID( sp ) , serp->svr_pid, death_type ) ;
- X else
- X msg( LOG_DEBUG, func,
- X "%s server %d running on behalf of service %s %s",
- X SVC_ID( sp ), serp->svr_pid, SVC_ID( conn_sp ), death_type ) ;
- X }
- X
- X svc_postmortem( sp, serp ) ;
- X pset_remove( SERVERS( ps ), serp ) ;
- X server_release( serp ) ;
- X }
- X else if ( PROC_STOPPED( serp->svr_exit_status ) )
- X msg( LOG_WARNING, func, "service %s: server with pid %d stopped",
- X SVC_ID( sp ), serp->svr_pid ) ;
- X}
- X
- X
- X/*
- X * Find the running server with the specified pid
- X */
- Xstruct server *server_lookup( pid )
- X register int pid ;
- X{
- X register unsigned u ;
- X
- X for ( u = 0 ; u < pset_count( SERVERS( ps ) ) ; u++ )
- X {
- X register struct server *serp ;
- X
- X serp = SERP( pset_pointer( SERVERS( ps ), u ) ) ;
- X if ( serp->svr_pid == pid )
- X return( serp ) ;
- X }
- X return( NULL ) ;
- X}
- X
- END_OF_FILE
- if test 7431 -ne `wc -c <'xinetd/server.c'`; then
- echo shar: \"'xinetd/server.c'\" unpacked with wrong size!
- fi
- # end of 'xinetd/server.c'
- fi
- echo shar: End of archive 16 \(of 31\).
- cp /dev/null ark16isdone
- 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
-