home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / xinetd21 / part27 < prev    next >
Encoding:
Text File  |  1993-06-26  |  19.5 KB  |  801 lines

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i271: xinetd-2.1.1 - inetd replacement with access control and logging, Part27/31
  4. Sender: unix-sources-moderator@gw.home.vix.com
  5. Approved: vixie@gw.home.vix.com
  6.  
  7. Submitted-By: panos@cs.colorado.edu (Panos Tsirigotis)
  8. Posting-Number: Volume 26, Issue 271
  9. Archive-Name: xinetd-2.1.1/part27
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 27 (of 31)."
  18. # Contents:  xinetd/service.c
  19. # Wrapped by panos@mystique on Mon Jun 21 14:51:28 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'xinetd/service.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'xinetd/service.c'\"
  23. else
  24. echo shar: Extracting \"'xinetd/service.c'\" \(17419 characters\)
  25. sed "s/^X//" >'xinetd/service.c' <<'END_OF_FILE'
  26. X/*
  27. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  28. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  29. X * and conditions for redistribution.
  30. X */
  31. X
  32. Xstatic char RCSid[] = "$Id: service.c,v 6.12 1993/06/13 01:46:35 panos Exp $" ;
  33. X
  34. X#include <sys/types.h>
  35. X#include <sys/socket.h>
  36. X#include <netinet/in.h>
  37. X#include <netdb.h>
  38. X#include <syslog.h>
  39. X#include <fcntl.h>
  40. X
  41. X#include "sio.h"
  42. X
  43. X#include "options.h"
  44. X
  45. X#include "access.h"
  46. X#include "attr.h"
  47. X#include "service.h"
  48. X#include "server.h"
  49. X#include "state.h"
  50. X#include "config.h"
  51. X#include "connection.h"
  52. X
  53. X#define NEW_SVC()                    NEW( struct service )
  54. X#define FREE_SVC( sp )            FREE( sp )
  55. X
  56. X#define SUSPEND( sp )            (sp)->svc_state = SVC_SUSPENDED
  57. X#define RESUME( sp )                (sp)->svc_state = SVC_ACTIVE
  58. X#define DISABLE( sp )            (sp)->svc_state = SVC_DISABLED
  59. X
  60. X
  61. Xvoid msg() ;
  62. Xvoid out_of_memory() ;
  63. X
  64. Xtime_t time() ;
  65. Xchar *malloc() ;
  66. X
  67. Xstatic struct name_value service_states[] =
  68. X   {
  69. X      { "Not started",        (int) SVC_NOT_STARTED   },
  70. X      { "Active",             (int) SVC_ACTIVE        },
  71. X      { "Disabled",           (int) SVC_DISABLED      },
  72. X        { "Suspended",                (int) SVC_SUSPENDED        },
  73. X      { NULL,                 1                       },
  74. X        { "BAD STATE",                0                                }
  75. X   } ;
  76. X
  77. X
  78. X
  79. X/*
  80. X * Allocate a new struct service and initialize it from scp 
  81. X */
  82. Xstruct service *svc_new( scp )
  83. X    struct service_config *scp ;
  84. X{
  85. X    struct service *sp ;
  86. X    char *func = "svc_new" ;
  87. X
  88. X    sp = NEW_SVC() ;
  89. X   if ( sp == NULL )
  90. X   {
  91. X      out_of_memory( func ) ;
  92. X      return( NULL ) ;
  93. X   }
  94. X    CLEAR( *sp ) ;
  95. X
  96. X    sp->svc_conf = scp ;
  97. X    return( sp ) ;
  98. X}
  99. X
  100. X
  101. Xstruct service *svc_make_special( scp, handler )
  102. X    struct service_config    *scp ;
  103. X    statfunc                        handler ;
  104. X{
  105. X    struct service        *sp ;
  106. X    char                    *func = "svc_make_special" ;
  107. X
  108. X    if ( ( sp = svc_new( scp ) ) == NULL )
  109. X    {
  110. X        out_of_memory( func ) ;
  111. X        return( NULL ) ;
  112. X    }
  113. X
  114. X    sp->svc_handler_func = handler ;
  115. X    sp->svc_log = ps.rws.program_log ;
  116. X
  117. X    sp->svc_ref_count = 1 ;
  118. X    sp->svc_state = SVC_ACTIVE ;
  119. X    return( sp ) ;
  120. X}
  121. X
  122. X
  123. Xvoid svc_free( sp )
  124. X   struct service *sp ;
  125. X{
  126. X   sc_free( sp->svc_conf ) ;
  127. X    FREE_SVC( sp ) ;
  128. X}
  129. X
  130. X
  131. X/*
  132. X * Currently, address control works by looking at the fields 
  133. X * only_from/no_access of struct service.
  134. X * In order to enable address control, we copy to these fields either
  135. X * the explicitly specified values (which come from the service_config)
  136. X * or the default ones (if there are any).
  137. X */
  138. Xvoid svc_setup_address_control( sp )
  139. X    register struct service *sp ;
  140. X{
  141. X    register struct service_config *scp = SVC_CONF( sp ) ;
  142. X
  143. X    if ( SC_IS_PRESENT( scp, A_ONLY_FROM ) )
  144. X        sp->svc_only_from = SC_ONLY_FROM( scp ) ;
  145. X    else if ( SC_SPECIFIED( DEFAULTS( ps ), A_ONLY_FROM ) )
  146. X        sp->svc_only_from = SC_ONLY_FROM( DEFAULTS( ps ) ) ;
  147. X    else
  148. X        sp->svc_only_from = NULL ;
  149. X
  150. X    if ( SC_IS_PRESENT( scp, A_NO_ACCESS ) )
  151. X        sp->svc_no_access = SC_NO_ACCESS( scp ) ;
  152. X    else if ( SC_SPECIFIED( DEFAULTS( ps ), A_NO_ACCESS ) )
  153. X        sp->svc_no_access = SC_NO_ACCESS( DEFAULTS( ps ) ) ;
  154. X    else
  155. X        sp->svc_no_access = NULL ;
  156. X}
  157. X
  158. X
  159. XPRIVATE status_e set_fd_modes( sp )
  160. X    register struct service *sp ;
  161. X{
  162. X    int sd = SVC_FD( sp ) ;
  163. X    char *func = "set_fd_modes" ;
  164. X
  165. X   /*
  166. X    * There is a possibility of blocking on a send/write if
  167. X    *
  168. X     *        the service does not require forking (==> is internal) AND
  169. X    *    it does not accept connections
  170. X    *
  171. X    * To avoid this, we put the descriptor in FNDELAY mode.
  172. X    * (if the service accepts connections, we still need to put the
  173. X    * 'accepted' connection in FNDELAY mode but this is done elsewhere)
  174. X    */
  175. X    if ( ! SVC_FORKS( sp ) && ! SVC_ACCEPTS_CONNECTIONS( sp ) &&
  176. X                              fcntl( sd, F_SETFL, FNDELAY ) == -1 )
  177. X   {
  178. X      msg( LOG_ERR, func,
  179. X         "fcntl failed (%m) for FNDELAY. service = %s", SVC_ID( sp ) ) ;
  180. X        return( FAILED ) ;
  181. X   }
  182. X
  183. X   /*
  184. X    * Always set the close-on-exec flag
  185. X    */
  186. X   if ( fcntl( sd, F_SETFD, 1 ) == -1 )
  187. X   {
  188. X      msg( LOG_ERR, func,
  189. X         "fcntl failed (%m) for close-on-exec. service = %s", SVC_ID( sp ) ) ;
  190. X      return( FAILED ) ;
  191. X   }
  192. X    return( OK ) ;
  193. X}
  194. X
  195. X
  196. X#ifndef NO_RPC
  197. X
  198. XPRIVATE status_e activate_rpc( sp )
  199. X   register struct service *sp ;
  200. X{
  201. X    struct sockaddr_in        sin ;
  202. X    int                            sin_len ;
  203. X    unsigned long                vers ;
  204. X    struct service_config    *scp                        = SVC_CONF( sp ) ;
  205. X    struct rpc_data            *rdp                        = SC_RPCDATA( scp ) ;
  206. X    char                            *sid                        = SC_ID( scp ) ;
  207. X    unsigned                        registered_versions    = 0 ;
  208. X    int                            sd                            = SVC_FD( sp ) ;
  209. X    char                            *func                        = "activate_rpc" ;
  210. X
  211. X    CLEAR( sin ) ;
  212. X
  213. X    sin.sin_family = AF_INET ;
  214. X    sin.sin_addr.s_addr = htonl( INADDR_ANY ) ;
  215. X    sin.sin_port = 0 ;         /* let the system give us a port */
  216. X    if ( bind( sd, SA( &sin ), sizeof( sin ) ) == -1 )
  217. X    {
  218. X        msg( LOG_ERR, func, "bind failed (%m). service = %s", sid ) ;
  219. X        return( FAILED ) ;
  220. X    }
  221. X
  222. X    /*
  223. X     * Find the port number that was assigned to the socket
  224. X     */
  225. X    sin_len = sizeof( sin ) ;
  226. X    if ( getsockname( sd, SA( &sin ), &sin_len ) == -1 )
  227. X    {
  228. X        msg( LOG_ERR, func,
  229. X                "getsockname failed (%m). service = %s", sid ) ;
  230. X        return( FAILED ) ;
  231. X    }
  232. X    sc_set_port( scp, ntohs( sin.sin_port ) ) ;
  233. X
  234. X    /*
  235. X     * Try to register as many versions as possible
  236. X     */
  237. X    for ( vers = RD_MINVERS( rdp ) ; vers <= RD_MAXVERS( rdp ) ; vers++ )
  238. X        if ( pmap_set( RD_PROGNUM( rdp ), vers,
  239. X                                        SC_PROTOVAL( scp ), SC_PORT( scp ) ) )
  240. X            registered_versions++ ;
  241. X        else
  242. X            msg( LOG_ERR, func,
  243. X                "pmap_set failed. service=%s program=%ld version=%ld",
  244. X                    sid, RD_PROGNUM( rdp ), vers ) ;
  245. X
  246. X    if ( debug.on )
  247. X        msg( LOG_DEBUG, func,
  248. X                "Registered %d versions of %s", registered_versions, sid ) ;
  249. X
  250. X    return( ( registered_versions == 0 ) ? FAILED : OK ) ;
  251. X}
  252. X
  253. X#endif    /* ! NO_RPC */
  254. X
  255. X
  256. XPRIVATE status_e activate_normal( sp )
  257. X   register struct service *sp ;
  258. X{
  259. X    struct sockaddr_in        sin ;
  260. X    int                            sd                    = SVC_FD( sp ) ;
  261. X    struct service_config    *scp                = SVC_CONF( sp ) ;
  262. X    unsigned short                service_port    = SC_PORT( scp ) ;
  263. X    char                            *sid                = SC_ID( scp ) ;
  264. X    char                            *func                = "activate_normal" ;
  265. X
  266. X    CLEAR( sin ) ;
  267. X
  268. X    sin.sin_family = AF_INET ;
  269. X    sin.sin_addr.s_addr = htonl( INADDR_ANY ) ;
  270. X    sin.sin_port = htons( service_port ) ;
  271. X
  272. X    if ( reuse_option || SC_REUSE_ADDRESS( scp ) )
  273. X    {
  274. X        int on = 1 ;
  275. X
  276. X        if ( setsockopt( sd, SOL_SOCKET,
  277. X                        SO_REUSEADDR, (char *) &on, sizeof( on ) ) == -1 )
  278. X            msg( LOG_WARNING, func,
  279. X             "setsockopt SO_REUSEADDR failed (%m). service = %s", sid ) ;
  280. X    }
  281. X
  282. X    if ( bind( sd, SA( &sin ), sizeof( sin ) ) == -1 )
  283. X    {
  284. X        msg( LOG_ERR, func, "bind failed (%m). service = %s", sid ) ;
  285. X        return( FAILED ) ;
  286. X    }
  287. X    return( OK ) ;
  288. X}
  289. X
  290. X
  291. X/*
  292. X * Activate a service. 
  293. X */
  294. Xstatus_e svc_activate( sp )
  295. X   register struct service *sp ;
  296. X{
  297. X    struct service_config    *scp = SVC_CONF( sp ) ;
  298. X    status_e                        status ;
  299. X   char                            *func = "svc_activate" ;
  300. X    voidfunc                        get_shutdown_by_name() ;
  301. X    PRIVATE status_e            svc_generic_handler() ;
  302. X    PRIVATE void                deactivate() ;
  303. X
  304. X    sp->svc_fd = socket( AF_INET, 
  305. X                                SC_SOCKET_TYPE( scp ), SC_PROTOVAL( scp ) ) ;
  306. X
  307. X   if ( sp->svc_fd == -1 )
  308. X   {
  309. X      msg( LOG_ERR, func,
  310. X                        "socket creation failed (%m). service = %s", SC_ID( scp ) ) ;
  311. X        return( FAILED ) ;
  312. X   }
  313. X
  314. X    if ( set_fd_modes( sp ) == FAILED )
  315. X    {
  316. X        (void) close( sp->svc_fd ) ;
  317. X        return( FAILED ) ;
  318. X    }
  319. X
  320. X#ifndef NO_RPC
  321. X   if ( SC_IS_RPC( scp ) )
  322. X        status = activate_rpc( sp ) ;
  323. X   else
  324. X#endif   /* ! NO_RPC */
  325. X        status = activate_normal( sp ) ;
  326. X    
  327. X    if ( status == FAILED )
  328. X    {
  329. X        (void) close( sp->svc_fd ) ;
  330. X        return( FAILED ) ;
  331. X    }
  332. X
  333. X    if ( log_start( sp, &sp->svc_log ) == FAILED )
  334. X    {
  335. X        deactivate( sp ) ;
  336. X        return( FAILED ) ;
  337. X    }
  338. X
  339. X    /*
  340. X     * Initialize the service data
  341. X     */
  342. X    sp->svc_running_servers    = sp->svc_retry_servers = 0 ;
  343. X    sp->svc_shutdown_func    = get_shutdown_by_name( SC_NAME( scp ) ) ;
  344. X    sp->svc_handler_func        = svc_generic_handler ;
  345. X    svc_setup_address_control( sp ) ;
  346. X
  347. X   if ( SC_MUST_LISTEN( scp ) )
  348. X      (void) listen( sp->svc_fd, LISTEN_BACKLOG ) ;
  349. X
  350. X   ps.rws.descriptors_free-- ;
  351. X
  352. X    sp->svc_state = SVC_ACTIVE ;
  353. X
  354. X    FD_SET( sp->svc_fd, &ps.rws.socket_mask ) ;
  355. X    if ( sp->svc_fd > ps.rws.mask_max )
  356. X        ps.rws.mask_max = sp->svc_fd ;
  357. X
  358. X    ps.rws.active_services++ ;
  359. X    ps.rws.available_services++ ;
  360. X
  361. X   return( OK ) ;
  362. X}
  363. X
  364. X
  365. XPRIVATE void deactivate( sp )
  366. X    register struct service *sp ;
  367. X{
  368. X    (void) close( SVC_FD( sp ) ) ;
  369. X
  370. X#ifndef NO_RPC
  371. X    if ( SC_IS_RPC( SVC_CONF( sp ) ) )
  372. X    {
  373. X        register unsigned long vers ;
  374. X        register struct rpc_data *rdp = SC_RPCDATA( SVC_CONF( sp ) ) ;
  375. X
  376. X        for ( vers = RD_MINVERS( rdp ) ; vers <= RD_MAXVERS( rdp ) ; vers++ )
  377. X            (void) pmap_unset( RD_PROGNUM( rdp ), vers ) ;
  378. X    }
  379. X#endif    /* ! NO_RPC */
  380. X}
  381. X
  382. X
  383. X/*
  384. X * Close the service descriptor.
  385. X * If this is an RPC service, deregister it.
  386. X * Close the log.
  387. X */
  388. Xvoid svc_deactivate( sp )
  389. X   register struct service *sp ;
  390. X{
  391. X    if ( ! SVC_IS_AVAILABLE( sp ) )
  392. X        return ;
  393. X
  394. X    deactivate( sp ) ;
  395. X   ps.rws.descriptors_free++ ;
  396. X
  397. X    if ( sp->svc_log )
  398. X        log_end( SC_LOG( SVC_CONF( sp ) ), sp->svc_log ) ;
  399. X
  400. X    if ( SVC_IS_ACTIVE( sp ) )
  401. X    {
  402. X        FD_CLR( SVC_FD( sp ), &ps.rws.socket_mask ) ;
  403. X        ps.rws.active_services-- ;
  404. X    }
  405. X
  406. X    ps.rws.available_services-- ;
  407. X
  408. X    DISABLE( sp ) ;
  409. X}
  410. X
  411. X
  412. X
  413. X/*
  414. X * Suspend a service
  415. X */
  416. Xvoid svc_suspend( sp )
  417. X    register struct service *sp ;
  418. X{
  419. X    char *func = "svc_suspend" ;
  420. X
  421. X    if ( ! SVC_IS_ACTIVE( sp ) )
  422. X    {
  423. X        msg( LOG_ERR, func, "service %s is not active", SVC_ID( sp ) ) ;
  424. X        return ;
  425. X    }
  426. X
  427. X    FD_CLR( SVC_FD( sp ), &ps.rws.socket_mask ) ;
  428. X    ps.rws.active_services-- ;
  429. X    if ( debug.on )
  430. X        msg( LOG_DEBUG, func, "Suspended service %s", SVC_ID( sp ) ) ;
  431. X    
  432. X    SUSPEND( sp ) ;
  433. X}
  434. X
  435. X
  436. X/*
  437. X * Resume a suspended service.
  438. X */
  439. Xvoid svc_resume( sp )
  440. X    register struct service *sp ;
  441. X{
  442. X    char *func = "svc_resume" ;
  443. X
  444. X    FD_SET( SVC_FD( sp ), &ps.rws.socket_mask ) ;
  445. X    ps.rws.active_services++ ;
  446. X    if ( debug.on )
  447. X        msg( LOG_DEBUG, func, "Resumed service %s", SVC_ID( sp ) ) ;
  448. X    RESUME( sp ) ;
  449. X}
  450. X
  451. X
  452. X/*
  453. X * Steps:
  454. X *        1. Deactivate the service
  455. X *        2. Free all memory used by the service and free the service itself
  456. X *
  457. X * Since this function may free all memory associated with the service as
  458. X * well as the memory pointed by sp, only the value of sp should be used
  459. X * after this call if the return value is 0 (i.e. no dereferencing of sp).
  460. X *
  461. X * Special services are never deactivated.
  462. X */
  463. Xint svc_release( sp )
  464. X   register struct service *sp ;
  465. X{
  466. X    char *sid = SVC_ID( sp ) ;
  467. X    char *func = "svc_release" ;
  468. X
  469. X    if ( sp->svc_ref_count == 0 )
  470. X    {
  471. X        msg( LOG_ERR, func, "%s: svc_release with 0 count", sid ) ;
  472. X        return( 0 ) ;
  473. X    }
  474. X    
  475. X    sp->svc_ref_count-- ;
  476. X    if ( sp->svc_ref_count == 0 )
  477. X    {
  478. X        if ( debug.on )
  479. X            msg( LOG_DEBUG, func, "ref count of service %s dropped to 0", sid ) ;
  480. X        if ( ! SC_IS_SPECIAL( SVC_CONF( sp ) ) )
  481. X        {
  482. X            svc_deactivate( sp ) ;
  483. X            svc_free( sp ) ;
  484. X        }
  485. X        else        /* this shouldn't happen */
  486. X            msg( LOG_WARNING, func,
  487. X                "ref count of special service %s dropped to 0", sid ) ;
  488. X        return( 0 ) ;
  489. X    }
  490. X    else
  491. X        return( sp->svc_ref_count ) ;
  492. X}
  493. X
  494. X
  495. X
  496. Xvoid svc_dump( sp, fd )
  497. X    register struct service *sp ;
  498. X    int fd ;
  499. X{
  500. X    char *get_shutdown_by_addr() ;
  501. X    void tabprint() ;
  502. X
  503. X    tabprint( fd, 0, "Service = %s\n", SC_NAME( SVC_CONF( sp ) ) ) ;
  504. X    tabprint( fd, 1, "State = %s\n",
  505. X                                nv_get_name( service_states, (int) sp->svc_state ) ) ;
  506. X
  507. X    sc_dump( SVC_CONF( sp ), fd, 1, FALSE ) ;
  508. X
  509. X    if ( sp->svc_state == SVC_ACTIVE )
  510. X    {
  511. X        tabprint( fd, 1, "running servers = %d\n", sp->svc_running_servers ) ;
  512. X        tabprint( fd, 1, "retry servers = %d\n", sp->svc_retry_servers ) ;
  513. X        tabprint( fd, 1, "attempts = %d\n", sp->svc_attempts ) ;
  514. X        tabprint( fd, 1, "service fd = %d\n", sp->svc_fd ) ;
  515. X        tabprint( fd, 1, "shutdown function = %s\n",
  516. X                            get_shutdown_by_addr( sp->svc_shutdown_func ) ) ;
  517. X    }
  518. X    Sputchar( fd, '\n' ) ;
  519. X}
  520. X
  521. X
  522. X/*
  523. X * Returns TRUE if the server instantiation rate is over the limit
  524. X */
  525. Xbool_int svc_looping( sp )
  526. X    register struct service *sp ;
  527. X{
  528. X    time_t                current_time ;
  529. X    register time_t    time_diff ;
  530. X    char                    *func = "svc_looping" ;
  531. X
  532. X    (void) time( ¤t_time ) ;
  533. X
  534. X    if ( sp->svc_attempts == 0 )
  535. X    {
  536. X        sp->svc_attempts++ ;
  537. X        sp->svc_start_time = current_time ;
  538. X        return( FALSE ) ;
  539. X    }
  540. X
  541. X    time_diff = current_time - sp->svc_start_time ;
  542. X    if ( time_diff <= LOOP_INTERVAL )
  543. X    {
  544. X        sp->svc_attempts++ ;
  545. X        if ( time_diff == 0 )
  546. X            time_diff = 1 ;
  547. X        if ( sp->svc_attempts/time_diff > ps.ros.loop_rate )
  548. X        {
  549. X            FD_CLR( SVC_FD( sp ), &ps.rws.socket_mask ) ;
  550. X            svc_deactivate( sp ) ;
  551. X            msg( LOG_ERR, func,
  552. X                "%s service was deactivated because of looping", SVC_ID( sp ) ) ;
  553. X            return( TRUE ) ;
  554. X        }
  555. X    }
  556. X    else
  557. X    {
  558. X        sp->svc_start_time = current_time ;
  559. X        sp->svc_attempts = 1 ;
  560. X    }
  561. X    return( FALSE ) ;
  562. X}
  563. X
  564. X
  565. X
  566. Xvoid svc_request( sp )
  567. X    register struct service *sp ;
  568. X{
  569. X    register connection_s *cp ;
  570. X
  571. X    cp = conn_new( sp ) ;
  572. X    if ( cp == CONN_NULL )
  573. X        return ;
  574. X
  575. X    if ( svc_handle( sp, cp ) == OK )
  576. X        return ;
  577. X    else
  578. X    {
  579. X        conn_cleanup( cp ) ;
  580. X        if ( conn_start_alternative( cp ) == FAILED )
  581. X            conn_free( cp ) ;
  582. X    }
  583. X}
  584. X
  585. X
  586. X
  587. XPRIVATE status_e svc_generic_handler( sp, cp )
  588. X    register struct service        *sp ;
  589. X    register connection_s        *cp ;
  590. X{
  591. X    register struct service_config *scp = SVC_CONF( sp ) ;
  592. X
  593. X   /*
  594. X    * There is no loop check for services that accept connections because
  595. X    * the connections are accepted by xinetd, therefore the queue will get
  596. X    * empty eventually even if the server is faulty.
  597. X    * Services for which no fork(2) occurs are not checked because
  598. X    *    a) they are internal and we assume they are not faulty
  599. X    *    b) we have no way of determining if something is going wrong
  600. X    *       for example, UDP discard can do its job very quickly
  601. X    */
  602. X    if ( !SC_ACCEPTS_CONNECTIONS( scp ) && SVC_FORKS( sp ) && svc_looping( sp ) )
  603. X        return( FAILED ) ;
  604. X
  605. X    if ( svc_access_control( sp, cp ) == OK )
  606. X        return( server_run( sp, cp ) ) ;
  607. X
  608. X    /*
  609. X     * Add alternative services to handle the connection attempt.
  610. X     * The services must be added in the proper order because they
  611. X     * are invoked in that order:
  612. X     *            logging
  613. X     *            shutdown
  614. X     */
  615. X
  616. X    if ( SVC_LOGS_USERID_ON_FAILURE( sp ) )
  617. X        (void) conn_add_alternative( cp, LOG_SERVICE( ps ) ) ;
  618. X
  619. X    if ( sp->svc_shutdown_func != NULL )
  620. X    {
  621. X        if ( ! SVC_RECORDS( sp ) || 
  622. X                    conn_add_alternative( cp, SHUTDOWN_SERVICE( ps ) ) == FAILED )
  623. X            conn_shutdown( cp ) ;
  624. X    }
  625. X
  626. X    return( FAILED ) ;
  627. X}
  628. X
  629. X
  630. Xstatus_e svc_access_control( sp, cp )
  631. X    register struct service        *sp ;
  632. X    connection_s                    *cp ;
  633. X{
  634. X    access_e result ;
  635. X
  636. X    result = access_control( sp, cp, MASK_NULL ) ;
  637. X    if ( result != AC_OK )
  638. X    {
  639. X        bool_int report_failure = TRUE ;
  640. X
  641. X        /*
  642. X         * Try to avoid reporting multiple times a failed attempt to access
  643. X         * a datagram-based service from a bad address. We do this because
  644. X         * the clients of such services usually send multiple datagrams 
  645. X         * before reporting a timeout (we have no way of telling them that
  646. X         * their request has been denied).
  647. X         */
  648. X        if ( result == AC_ADDRESS && SVC_SOCKET_TYPE( sp ) == SOCK_DGRAM )
  649. X        {
  650. X            register struct sockaddr_in *sinp = conn_address( cp ) ;
  651. X            register struct sockaddr_in *last = &sp->svc_last_dgram_addr ;
  652. X            time_t current_time ;
  653. X
  654. X            (void) time( ¤t_time ) ;
  655. X
  656. X            if ( sinp->sin_addr.s_addr == last->sin_addr.s_addr &&
  657. X                                                        sinp->sin_port == last->sin_port )
  658. X            {
  659. X                if ( current_time - sp->svc_last_dgram_time <= DGRAM_IGNORE_TIME )
  660. X                    report_failure = FALSE ;
  661. X                else
  662. X                    sp->svc_last_dgram_time = current_time ;
  663. X            }
  664. X            else
  665. X            {
  666. X                sp->svc_last_dgram_addr = *sinp ;
  667. X                sp->svc_last_dgram_time = current_time ;
  668. X            }
  669. X        }
  670. X
  671. X        if ( report_failure )
  672. X            svc_log_failure( sp, cp, result ) ;
  673. X        return( FAILED ) ;
  674. X    }
  675. X    return( OK ) ;
  676. X}
  677. X
  678. X
  679. X/*
  680. X * Implement shutdown protocol (usually sends an error indication).
  681. X */
  682. Xvoid svc_shutdown( sp, cp, msgp )
  683. X    register struct service        *sp ;
  684. X    register connection_s        *cp ;
  685. X    char                                **msgp ;
  686. X{
  687. X    int                        old_flags ;
  688. X    register bool_int        no_block ;
  689. X    int                        fd        = CONN_DESCRIPTOR( cp ) ;
  690. X    char                        *func = "svc_shutdown" ;
  691. X
  692. X#ifdef DEBUG
  693. X    if ( sp != CONN_SERVICE( cp ) )
  694. X    {
  695. X        msg( LOG_CRIT, func, "service = %s, service of connection = %s",
  696. X            SVC_ID( sp ), SVC_ID( CONN_SERVICE( cp ) ) ) ;
  697. X        return ;
  698. X    }
  699. X#endif
  700. X
  701. X    if ( sp->svc_shutdown_func == NULL )
  702. X        return ;
  703. X
  704. X    no_block = ( msgp == NULL ) ;
  705. X
  706. X    /*
  707. X     * Ensure that we won't block in the shutdown function
  708. X     */
  709. X    if ( no_block )
  710. X    {
  711. X        if ( ( old_flags = fcntl( fd, F_GETFL, 0 ) ) == -1 )
  712. X        {
  713. X            msg( LOG_ERR, func, "fcntl-getflags failed: %m" ) ;
  714. X            return ;
  715. X        }
  716. X
  717. X        if ( fcntl( fd, F_SETFL, FNDELAY ) == -1 )
  718. X        {
  719. X            msg( LOG_ERR, func, "fcntl-setflags failed: %m" ) ;
  720. X            return ;
  721. X        }
  722. X    }
  723. X
  724. X    (*sp->svc_shutdown_func)( fd, msgp ) ;
  725. X
  726. X    /*
  727. X     * Don't bother with restoring the flags if this is a new descriptor
  728. X     */
  729. X    if ( no_block && SC_ACCEPTS_CONNECTIONS( SVC_CONF( sp ) ) )
  730. X        (void) fcntl( fd, F_SETFL, old_flags ) ;
  731. X}
  732. X
  733. X
  734. X/*
  735. X * Invoked when a server of the specified service dies
  736. X */
  737. Xvoid svc_postmortem( sp, serp )
  738. X    register struct service        *sp ;
  739. X    register struct server        *serp ;
  740. X{
  741. X    struct service                *co_sp    = SERVER_CONNSERVICE( serp ) ;
  742. X    register connection_s    *cp        = SERVER_CONNECTION( serp ) ;
  743. X    char                            *func        = "svc_postmortem" ;
  744. X
  745. X    svc_dec_running_servers( sp ) ;
  746. X
  747. X    /*
  748. X     * Log information about the server that died
  749. X     */
  750. X    if ( SVC_IS_LOGGING( sp ) )
  751. X    {
  752. X        if ( serp->svr_writes_to_log )
  753. X        {
  754. X            if ( debug.on )
  755. X                msg( LOG_DEBUG, func,
  756. X                                "Checking log size of %s service", SVC_ID( sp ) ) ;
  757. X            xlog_control( SVC_LOG( sp ), XLOG_SIZECHECK ) ;
  758. X        }
  759. X        svc_log_exit( sp, serp ) ;
  760. X    }
  761. X
  762. X    /*
  763. X     * Check for alternative services to handle this connection
  764. X     */
  765. X    if ( conn_start_alternative( cp ) == OK )
  766. X        return ;
  767. X    
  768. X    /*
  769. X     * Now check if we have to check the log size of the service that owns
  770. X     * the connection
  771. X     */
  772. X    if ( co_sp != sp && SVC_IS_LOGGING( co_sp ) )
  773. X        xlog_control( SVC_LOG( co_sp ), XLOG_SIZECHECK ) ;
  774. X
  775. X    conn_free( cp ) ;
  776. X}
  777. X
  778. END_OF_FILE
  779. if test 17419 -ne `wc -c <'xinetd/service.c'`; then
  780.     echo shar: \"'xinetd/service.c'\" unpacked with wrong size!
  781. fi
  782. # end of 'xinetd/service.c'
  783. fi
  784. echo shar: End of archive 27 \(of 31\).
  785. cp /dev/null ark27isdone
  786. MISSING=""
  787. 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
  788.     if test ! -f ark${I}isdone ; then
  789.     MISSING="${MISSING} ${I}"
  790.     fi
  791. done
  792. if test "${MISSING}" = "" ; then
  793.     echo You have unpacked all 31 archives.
  794.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  795. else
  796.     echo You still need to unpack the following archives:
  797.     echo "        " ${MISSING}
  798. fi
  799. ##  End of shell archive.
  800. exit 0
  801.