home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / xinetd.2.0.6 / special.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-22  |  5.4 KB  |  260 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. static char RCSid[] = "$Id: special.c,v 5.2 1992/11/10 08:18:25 panos Exp $" ;
  8.  
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <syslog.h>
  12. #include <signal.h>
  13.  
  14. #include "misc.h"
  15.  
  16. #include "options.h"
  17.  
  18. #include "attr.h"
  19. #include "conf.h"
  20. #include "server.h"
  21. #include "state.h"
  22. #include "config.h"
  23. #include "builtin.h"
  24. #include "connection.h"
  25.  
  26. void msg() ;
  27. void out_of_memory() ;
  28.  
  29. extern struct name_value socket_types[] ;
  30.  
  31. #define LOG_SERVICE_NAME                "logging"
  32. #define SHUTDOWN_SERVICE_NAME            "shutdown"
  33.  
  34. void stream_logging() ;
  35. void stream_shutdown() ;
  36. void intercept() ;
  37.  
  38. static struct builtin_service special_services[] =
  39.     {
  40.         { LOG_SERVICE_NAME,             SOCK_STREAM,    stream_logging,    FORK    },
  41.         { SHUTDOWN_SERVICE_NAME,    SOCK_STREAM,   stream_shutdown,  FORK  },
  42.         { INTERCEPT_SERVICE_NAME,    SOCK_STREAM,    intercept,            FORK    },
  43.         { INTERCEPT_SERVICE_NAME,    SOCK_DGRAM,        intercept,            FORK    },
  44.         { NULL }
  45.     } ;
  46.  
  47.  
  48.  
  49. /*
  50.  * Add the special services to the service table
  51.  */
  52. void include_special_services()
  53. {
  54.     int instances ;
  55.     struct service *setup_special_service() ;
  56.  
  57.     instances = logprocs_option ? logprocs_option_arg : DEFAULT_LOGPROCS ;
  58.     LOG_SERVICE( ps ) = setup_special_service(
  59.                                 LOG_SERVICE_NAME, SOCK_STREAM, instances ) ;
  60.  
  61.     instances = shutdownprocs_option ? shutdownprocs_option_arg
  62.                                                 : DEFAULT_SHUTDOWNPROCS ;
  63.     SHUTDOWN_SERVICE( ps ) = setup_special_service(
  64.                                         SHUTDOWN_SERVICE_NAME, SOCK_STREAM, instances ) ;
  65. }
  66.  
  67.  
  68. struct builtin_service *find_special_builtin( service_name, type )
  69.    char *service_name ;
  70.    int type ;
  71. {
  72.    register struct builtin_service *bsp ;
  73.     struct name_value *nvp ;
  74.     char *func = "find_special_builtin" ;
  75.  
  76.     if ( bsp = builtin_lookup( special_services, service_name, type ) )
  77.         return( bsp ) ;
  78.  
  79.     nvp = nv_find_name( socket_types, type ) ;
  80.     if ( nvp == NULL )
  81.     {
  82.         msg( LOG_ERR, func, "unknown socket type: %d", type ) ;
  83.         return( NULL ) ;
  84.     }
  85.  
  86.     msg( LOG_ERR, func,
  87.                 "special service %s,%s not supported", service_name, nvp->name ) ;
  88.    return( NULL ) ;
  89. }
  90.  
  91.  
  92. PRIVATE status_e special_service_handler( sp, cp )
  93.     struct service *sp ;
  94.     connection_s *cp ;
  95. {
  96.     if ( svc_access_control( sp, cp ) == FAILED ||
  97.                                             server_run( sp, cp ) == FAILED )
  98.     {
  99.         if ( sp == SHUTDOWN_SERVICE( ps ) )
  100.             conn_shutdown( cp ) ;
  101.         return( FAILED ) ;
  102.     }
  103.     return( OK ) ;
  104. }
  105.  
  106.  
  107. PRIVATE struct service *setup_special_service( name, socket_type, instances )
  108.     char *name ;
  109.     int socket_type ;
  110.     int instances ;
  111. {
  112.     struct builtin_service *bsp ;
  113.     struct service *sp ;
  114.     struct service_config sconf ;
  115.     status_e make_conf() ;
  116.     void special_postmortem() ;
  117.  
  118.     bsp = find_special_builtin( name, socket_type ) ;
  119.     if ( bsp == NULL )
  120.         return( NULL ) ;
  121.  
  122.     if ( make_conf( &sconf, name, instances ) == FAILED )
  123.         return( NULL ) ;
  124.  
  125.     sp = svc_new( &sconf ) ;
  126.     if ( sp == NULL )
  127.     {
  128.         sconf_free( &sconf ) ;
  129.         return( NULL ) ;
  130.     }
  131.  
  132.     sp->state = SVC_ACTIVE ;
  133.     sp->builtin = bsp ;
  134.     SDATA( sp )->postmortem = special_postmortem ;
  135.     SDATA( sp )->handler = special_service_handler ;
  136.     SDATA( sp )->log_handle = ps.rws.program_log ;
  137.     SVC_HOLD( sp ) ;
  138.     return( sp ) ;
  139. }
  140.  
  141.  
  142. PRIVATE status_e make_conf( scp, name, instances )
  143.     register struct service_config *scp ;
  144.     char *name ;
  145.     int instances ;
  146. {
  147.     char *func = "make_conf" ;
  148.  
  149.     CLEAR( *scp ) ;
  150.  
  151.     M_SET( scp->type, ST_INTERNAL ) ;
  152.     M_SET( scp->type, ST_SPECIAL ) ;
  153.     SPECIFY( scp, A_TYPE ) ;
  154.  
  155.     M_SET( scp->flags, SF_NORETRY ) ;
  156.     SPECIFY( scp, A_FLAGS ) ;
  157.  
  158.     scp->instances = instances ;
  159.     SPECIFY( scp, A_INSTANCES ) ;
  160.  
  161.     scp->name = make_string( 1, name ) ;
  162.     if ( scp->name == NULL )
  163.     {
  164.         out_of_memory( func ) ;
  165.         return( FAILED ) ;
  166.     }
  167.  
  168.     scp->id = make_string( 1, scp->name ) ;
  169.     if ( scp->id == NULL )
  170.     {
  171.         free( scp->name ) ;
  172.         out_of_memory( func ) ;
  173.         return( FAILED ) ;
  174.     }
  175.     SPECIFY( scp, A_ID ) ;
  176.  
  177.     scp->wait = NO ;
  178.     SPECIFY( scp, A_WAIT ) ;
  179.  
  180.     return( OK ) ;
  181. }
  182.  
  183.  
  184.  
  185. PRIVATE void stream_logging( serp )
  186.     struct server *serp ;
  187. {
  188.     void log_remote_user() ;
  189.  
  190. #ifdef DEBUG_LOGGING
  191.     if ( debug.on )
  192.     {
  193.         msg( LOG_DEBUG, "stream_logging", "%d is sleeping", getpid() ) ;
  194.         sleep( 10 ) ;
  195.     }
  196. #endif
  197.  
  198.     log_remote_user( serp ) ;
  199. }
  200.  
  201.  
  202.  
  203. PRIVATE void stream_shutdown( serp )
  204.     struct server *serp ;
  205. {
  206.     struct service *sp = SERVER_CONNECTION( serp )->sp ;
  207.    char *str = NULL ;
  208.     void logprint() ;
  209.     char *func = "stream_shutdown" ;
  210.  
  211.     if ( debug.on )
  212.         msg( LOG_DEBUG, func, "shutdown for service %s, (fd=%d)",
  213.             CONF( sp )->id, SERVER_FD( serp ) ) ;
  214.  
  215. #ifdef DEBUG_SHUTDOWN
  216.    /*
  217.     * The reason for the sleep is that single stepping through this
  218.     * code is impossible (at least on the Sun IPC I am using).
  219.     */
  220.    if ( debug.on )
  221.    {
  222.       msg( LOG_DEBUG, func, "%d is sleeping", getpid() ) ;
  223.       sleep( 10 ) ;
  224.    }
  225. #endif
  226.  
  227.    /*
  228.     * Everything must happen within 10 seconds.
  229.     * Since there is no alarm handler the process will be terminated if the
  230.     * timer runs out.
  231.     */
  232.    if ( ! debug.on )
  233.    {
  234.       (void) alarm( 10 ) ;
  235.       (void) signal( SIGALRM, SIG_DFL ) ;
  236.    }
  237.  
  238.    (*SDATA( sp )->shutdown)( SERVER_FD( serp ), &str ) ;
  239.  
  240.    (void) alarm( 0 ) ;
  241.  
  242.    if ( str != NULL )
  243.       logprint( sp, "DATA", "%s", str ) ;
  244. }
  245.  
  246.  
  247. PRIVATE void special_postmortem( serp )
  248.     struct server *serp ;
  249. {
  250.     connection_s *cp = SERVER_CONNECTION( serp ) ;
  251.  
  252.     if ( conn_start_alternative( cp ) == FAILED )
  253.     {
  254.         xlog_control(
  255.             SDATA( SERVER_SERVICE( serp ) )->log_handle, XLOG_SIZECHECK ) ;
  256.         conn_free( cp ) ;
  257.     }
  258. }
  259.  
  260.