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

  1. Newsgroups: comp.sources.unix
  2. From: panos@cs.colorado.edu (Panos Tsirigotis)
  3. Subject: v26i264: xinetd-2.1.1 - inetd replacement with access control and logging, Part20/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 264
  9. Archive-Name: xinetd-2.1.1/part20
  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 20 (of 31)."
  18. # Contents:  xinetd/sconf.c xinetd/shutdown.c
  19. # Wrapped by panos@mystique on Mon Jun 21 14:51:26 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'xinetd/sconf.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'xinetd/sconf.c'\"
  23. else
  24. echo shar: Extracting \"'xinetd/sconf.c'\" \(11251 characters\)
  25. sed "s/^X//" >'xinetd/sconf.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: sconf.c,v 6.7 1993/06/15 23:25:57 panos Exp $" ;
  33. X
  34. X#include "misc.h"
  35. X
  36. X#include "state.h"
  37. X#include "defs.h"
  38. X#include "attr.h"
  39. X#include "sconf.h"
  40. X#include "addr.h"
  41. X
  42. Xchar *malloc() ;
  43. Xint free() ;
  44. X
  45. X#define NEW_SCONF()                    NEW( struct service_config )
  46. X#define FREE_SCONF( scp )            FREE( scp )
  47. X
  48. X/*
  49. X * Conditional free; checks if the pointer is NULL
  50. X */
  51. X#define COND_FREE( x )           if ( x )                   \
  52. X                                 {                          \
  53. X                                    free( (char *) x ) ;    \
  54. X                                    x = NULL ;              \
  55. X                                 }
  56. X
  57. Xextern struct name_value success_log_options[] ;
  58. Xextern struct name_value failure_log_options[] ;
  59. Xextern struct name_value service_types[] ;
  60. Xextern struct name_value service_flags[] ;
  61. Xextern struct name_value socket_types[] ;
  62. Xextern struct name_value syslog_facilities[] ;
  63. Xextern struct name_value syslog_levels[] ;
  64. X
  65. Xvoid tabprint() ;
  66. Xvoid out_of_memory() ;
  67. X
  68. X
  69. X/*
  70. X * Allocate a new service_config and initialize the service name field
  71. X * with 'name'; the rest of the fields are set to 0 which gives them
  72. X * their default values.
  73. X */
  74. Xstruct service_config *sc_alloc( name )
  75. X    char *name ;
  76. X{
  77. X    struct service_config *scp ;
  78. X    char *func = "sc_alloc" ;
  79. X
  80. X    scp = NEW_SCONF() ;
  81. X    if ( scp == NULL )
  82. X    {
  83. X        out_of_memory( func ) ;
  84. X        return( NULL ) ;
  85. X    }
  86. X    CLEAR( *scp ) ;
  87. X    scp->sc_name = name ;
  88. X    return( scp ) ;
  89. X}
  90. X
  91. X
  92. XPRIVATE void release_string_pset( pset )
  93. X    pset_h pset ;
  94. X{
  95. X    pset_apply( pset, free, NULL ) ;
  96. X    pset_destroy( pset ) ;
  97. X}
  98. X
  99. X
  100. X
  101. X/*
  102. X * Free all malloc'ed memory for the specified service
  103. X */
  104. Xvoid sc_free( scp )
  105. X   register struct service_config *scp ;
  106. X{
  107. X    void ti_free() ;
  108. X
  109. X   COND_FREE( scp->sc_name ) ;
  110. X   COND_FREE( scp->sc_id ) ;
  111. X   COND_FREE( scp->sc_protocol.name ) ;
  112. X   COND_FREE( scp->sc_server ) ;
  113. X   if ( scp->sc_server_argv )
  114. X   {
  115. X      register char **pp ;
  116. X
  117. X        /*
  118. X         * argv[ 0 ] is a special case because it may not have been allocated yet
  119. X         */
  120. X        if ( scp->sc_server_argv[ 0 ] != NULL)
  121. X            free( scp->sc_server_argv[ 0 ] ) ;
  122. X      for ( pp = &scp->sc_server_argv[ 1 ] ; *pp != NULL ; pp++ )
  123. X         free( *pp ) ;
  124. X      free( (char *) scp->sc_server_argv ) ;
  125. X   }
  126. X   COND_FREE( log_filelog( SC_LOG( scp ) )->fl_filename ) ;
  127. X
  128. X    if ( scp->sc_access_times != NULL )
  129. X    {
  130. X        ti_free( scp->sc_access_times ) ;
  131. X        pset_destroy( scp->sc_access_times ) ;
  132. X    }
  133. X
  134. X    if ( scp->sc_only_from != NULL )
  135. X    {
  136. X        addrlist_free( scp->sc_only_from ) ;
  137. X        pset_destroy( scp->sc_only_from ) ;
  138. X    }
  139. X
  140. X    if ( scp->sc_no_access != NULL )
  141. X    {
  142. X        addrlist_free( scp->sc_no_access ) ;
  143. X        pset_destroy( scp->sc_no_access ) ;
  144. X    }
  145. X
  146. X   if ( scp->sc_env_var_defs != NULL )
  147. X        release_string_pset( scp->sc_env_var_defs ) ;
  148. X    if ( scp->sc_pass_env_vars != NULL )
  149. X        release_string_pset( scp->sc_pass_env_vars ) ;
  150. X    if ( SC_ENV( scp )->env_type == CUSTOM_ENV && 
  151. X                                                SC_ENV( scp )->env_handle != ENV_NULL )
  152. X        env_destroy( SC_ENV( scp )->env_handle ) ;
  153. X    
  154. X    FREE_SCONF( scp ) ;
  155. X}
  156. X
  157. X
  158. X/*
  159. X * Create a configuration for one of the special services
  160. X */
  161. Xstruct service_config *sc_make_special( service_name, bp, instances )
  162. X    char *service_name ;
  163. X    builtin_s *bp ;
  164. X    int instances ;
  165. X{
  166. X    char *name ;
  167. X    struct service_config *scp ;
  168. X    char *func = "sc_make" ;
  169. X
  170. X    name = make_string( 1, service_name ) ;
  171. X    if ( name == NULL )
  172. X    {
  173. X        out_of_memory( func ) ;
  174. X        return( NULL ) ;
  175. X    }
  176. X
  177. X    if ( ( scp = sc_alloc( name ) ) == NULL )
  178. X    {
  179. X        free( name ) ;
  180. X        return( NULL ) ;
  181. X    }
  182. X
  183. X   scp->sc_id = make_string( 1, scp->sc_name ) ;
  184. X   if ( scp->sc_id == NULL )
  185. X   {
  186. X      free( name ) ;
  187. X      out_of_memory( func ) ;
  188. X      return( NULL ) ;
  189. X   }
  190. X   SC_SPECIFY( scp, A_ID ) ;
  191. X
  192. X    /*
  193. X     * All special services are internal
  194. X     */
  195. X   M_SET( scp->sc_type, ST_SPECIAL ) ;
  196. X   M_SET( scp->sc_type, ST_INTERNAL ) ;
  197. X    scp->sc_builtin = bp ;
  198. X   SC_SPECIFY( scp, A_TYPE ) ;
  199. X
  200. X   M_SET( scp->sc_flags, SF_NORETRY ) ;
  201. X   SC_SPECIFY( scp, A_FLAGS ) ;
  202. X
  203. X   scp->sc_instances = instances ;
  204. X   SC_SPECIFY( scp, A_INSTANCES ) ;
  205. X
  206. X   scp->sc_wait = NO ;
  207. X   SC_SPECIFY( scp, A_WAIT ) ;
  208. X
  209. X    return( scp ) ;
  210. X}
  211. X
  212. X
  213. X
  214. XPRIVATE void dump_log_data( fd, scp, tab_level )
  215. X    int fd ;
  216. X    register struct service_config *scp ;
  217. X    int tab_level ;
  218. X{
  219. X    register struct log *lp = SC_LOG( scp ) ;
  220. X    register struct filelog *flp ;
  221. X    int i ;
  222. X
  223. X    switch ( log_get_type( lp ) )
  224. X    {
  225. X        case L_NONE:
  226. X            tabprint( fd, tab_level, "No logging\n" ) ;
  227. X            return ;
  228. X
  229. X        case L_COMMON_FILE:
  230. X            tabprint( fd, tab_level, "Logging to common log file\n" ) ;
  231. X            break ;
  232. X
  233. X        case L_FILE:
  234. X            flp = log_filelog( lp ) ;
  235. X            tabprint( fd, tab_level, "Logging to file: %s", flp->fl_filename ) ;
  236. X
  237. X            if ( FILELOG_SIZE_CONTROL( flp ) )
  238. X                Sprint( fd, " (soft=%d hard=%d)\n",
  239. X                                flp->fl_soft_limit, flp->fl_hard_limit ) ;
  240. X            else
  241. X                Sprint( fd, " (no limits)\n" ) ;
  242. X            break ;
  243. X        
  244. X        case L_SYSLOG:
  245. X            tabprint( fd, tab_level,
  246. X                "Logging to syslog. Facility = %s, level = %s\n",
  247. X                    nv_get_name( syslog_facilities, log_syslog( lp )->sl_facility ),
  248. X                    nv_get_name( syslog_levels, log_syslog( lp )->sl_level ) ) ;
  249. X            break ;
  250. X    }
  251. X
  252. X    tabprint( fd, tab_level, "Log_on_success flags =" ) ;
  253. X    for ( i = 0 ; success_log_options[ i ].name != NULL ; i++ )
  254. X        if ( M_IS_SET( scp->sc_log_on_success, success_log_options[ i ].value ) )
  255. X            Sprint( fd, " %s", success_log_options[ i ].name ) ;
  256. X    Sputchar( fd, '\n' ) ;
  257. X
  258. X    tabprint( fd, tab_level, "Log_on_failure flags =" ) ;
  259. X    for ( i = 0 ; failure_log_options[ i ].name != NULL ; i++ )
  260. X        if ( M_IS_SET( scp->sc_log_on_failure, failure_log_options[ i ].value ) )
  261. X            Sprint( fd, " %s", failure_log_options[ i ].name ) ;
  262. X    Sputchar( fd, '\n' ) ;
  263. X}
  264. X
  265. X
  266. X/*
  267. X * Print info about service scp to file descriptor fd
  268. X */
  269. Xvoid sc_dump( scp, fd, tab_level, is_defaults )
  270. X    register struct service_config *scp ;
  271. X    register int fd ;
  272. X    int tab_level ;
  273. X    bool_int is_defaults ;
  274. X{
  275. X    register struct name_value        *nvp ;
  276. X    register unsigned                 u ;
  277. X    register char                         **pp ;
  278. X    void                                     ti_dump() ;
  279. X
  280. X    if ( is_defaults )
  281. X        tabprint( fd, tab_level, "Service defaults\n" ) ;
  282. X    else
  283. X        tabprint( fd, tab_level, "Service configuration: %s\n", scp->sc_name ) ;
  284. X
  285. X    if ( ! is_defaults )
  286. X    {
  287. X        tabprint( fd, tab_level+1, "id = %s\n", scp->sc_id ) ;
  288. X
  289. X        if ( ! M_ARE_ALL_CLEAR( scp->sc_flags ) )
  290. X        {
  291. X            tabprint( fd, tab_level+1, "flags =" ) ;
  292. X            for ( nvp = &service_flags[ 0 ] ; nvp->name != NULL ; nvp++ )
  293. X                if ( M_IS_SET( scp->sc_flags, nvp->value ) )
  294. X                    Sprint( fd, " %s", nvp->name ) ;
  295. X            Sputchar( fd, '\n' ) ;
  296. X        }
  297. X
  298. X        if ( ! M_ARE_ALL_CLEAR( scp->sc_type ) )
  299. X        {
  300. X            tabprint( fd, tab_level+1, "type =" ) ;
  301. X            for ( nvp = &service_types[ 0 ] ; nvp->name != NULL ; nvp++ )
  302. X                if ( M_IS_SET( scp->sc_type, nvp->value ) )
  303. X                    Sprint( fd, " %s", nvp->name ) ;
  304. X            Sputchar( fd, '\n' ) ;
  305. X        }
  306. X
  307. X        tabprint( fd, tab_level+1, "socket_type = %s\n",
  308. X            nv_get_name( socket_types, scp->sc_socket_type ) ) ;
  309. X
  310. X        if ( SC_SPECIFIED( scp, A_PORT ) )
  311. X            tabprint( fd, tab_level+1, "port = %d\n", scp->sc_port ) ;
  312. X
  313. X        tabprint( fd, tab_level+1, "Protocol (name,number) = (%s,%d)\n",
  314. X                scp->sc_protocol.name, scp->sc_protocol.value ) ;
  315. X    }
  316. X
  317. X    if ( SC_SPECIFIED( scp, A_INSTANCES ) )
  318. X        if ( scp->sc_instances == UNLIMITED )
  319. X            tabprint( fd, tab_level+1, "Instances = UNLIMITED\n" ) ;
  320. X        else
  321. X            tabprint( fd, tab_level+1, "Instances = %d\n", scp->sc_instances ) ;
  322. X        
  323. X    if ( SC_SPECIFIED( scp, A_NICE ) )
  324. X        tabprint( fd, tab_level+1, "Nice = %d\n", scp->sc_nice ) ;
  325. X
  326. X    if ( ! is_defaults )
  327. X    {
  328. X        if ( ! SC_IS_INTERNAL( scp ) )
  329. X        {
  330. X            tabprint( fd, tab_level+1, "Server = %s\n", scp->sc_server ) ;
  331. X            tabprint( fd, tab_level+1, "Server argv =" ) ;
  332. X            for ( pp = scp->sc_server_argv ; *pp ; pp++ )
  333. X                Sprint( fd, " %s", *pp ) ;
  334. X            Sputchar( fd, '\n' ) ;
  335. X        } 
  336. X
  337. X        if ( SC_IS_RPC( scp ) )
  338. X        {
  339. X            struct rpc_data *rdp = SC_RPCDATA( scp ) ;
  340. X
  341. X            tabprint( fd, tab_level+1, "RPC data\n" ) ;
  342. X            tabprint( fd, tab_level+2,
  343. X                                    "program number = %ld\n", rdp->rd_program_number ) ;
  344. X            tabprint( fd, tab_level+2, "rpc_version = " ) ;
  345. X            if ( rdp->rd_min_version == rdp->rd_max_version )
  346. X                Sprint( fd, "%ld\n", rdp->rd_min_version ) ;
  347. X            else
  348. X                Sprint( fd, "%ld-%ld\n",
  349. X                                    rdp->rd_min_version, rdp->rd_max_version ) ;
  350. X        }
  351. X
  352. X        if ( SC_SPECIFIED( scp, A_ACCESS_TIMES ) )
  353. X        {
  354. X            tabprint( fd, tab_level+1, "Access times =" ) ;
  355. X            ti_dump( scp->sc_access_times, fd ) ;
  356. X            Sputchar ( fd, '\n' ) ;
  357. X        }
  358. X    }
  359. X
  360. X    if ( SC_SPECIFIED( scp, A_ONLY_FROM ) )
  361. X    {
  362. X        tabprint( fd, tab_level+1, "Only from: " ) ;
  363. X        addrlist_dump( scp->sc_only_from, fd ) ;
  364. X        Sputchar( fd, '\n' ) ;
  365. X    }
  366. X
  367. X    if ( SC_SPECIFIED( scp, A_NO_ACCESS ) )
  368. X    {
  369. X        tabprint( fd, tab_level+1, "No access: " ) ;
  370. X        addrlist_dump( scp->sc_no_access, fd ) ;
  371. X        Sputchar( fd, '\n' ) ;
  372. X    }
  373. X    
  374. X    dump_log_data( fd, scp, tab_level+1 ) ;
  375. X
  376. X    if ( SC_SPECIFIED( scp, A_PASSENV ) )
  377. X    {
  378. X        tabprint( fd, tab_level+1, "Passenv =" ) ;
  379. X        for ( u = 0 ; u < pset_count( scp->sc_pass_env_vars ) ; u++ )
  380. X            Sprint( fd, " %s",
  381. X                        (char *) pset_pointer( scp->sc_pass_env_vars, u ) ) ;
  382. X        Sputchar ( fd, '\n' ) ;
  383. X    }
  384. X
  385. X    if ( ! is_defaults )
  386. X        if ( SC_SPECIFIED( scp, A_ENV ) )
  387. X        {
  388. X            tabprint( fd, tab_level+1, "Environment additions:\n" ) ;
  389. X            for ( u = 0 ; u < pset_count( scp->sc_env_var_defs ) ; u++ )
  390. X                tabprint( fd, tab_level+2,
  391. X                        "%s\n", (char *) pset_pointer( scp->sc_env_var_defs, u ) ) ;
  392. X        }
  393. X    
  394. X    if ( SC_ENV( scp )->env_type == CUSTOM_ENV )
  395. X    {
  396. X        tabprint( fd, tab_level+1, "Environment strings:\n" ) ;
  397. X        for ( pp = env_getvars( SC_ENV( scp )->env_handle ) ; *pp ; pp++ )
  398. X            tabprint( fd, tab_level+2, "%s\n", *pp ) ;
  399. X    }
  400. X    Sflush( fd ) ;
  401. X}
  402. X
  403. X
  404. X#define SC_RPCPROGNUM( s )    RD_PROGNUM( SC_RPCDATA( s ) )
  405. X#define SAME_RPC( s1, s2 )    ( SC_RPCPROGNUM( s1 ) == SC_RPCPROGNUM( s2 ) )
  406. X#define SAME_NONRPC( s1, s2 ) ( (s1)->sc_socket_type == (s2)->sc_socket_type \
  407. X                                 && (s1)->sc_port == (s2)->sc_port )
  408. X
  409. X/*
  410. X * Two service configurations are considered different if any of the
  411. X * following is TRUE:
  412. X *        1) only one is unlisted
  413. X *        2) only one is internal
  414. X *        3) only one is RPC
  415. X *        4) they have different values for the 'wait' attribute
  416. X *        5) they use different protocols
  417. X *        6) they are both RPC services but have different program numbers
  418. X *        7) neither is an RPC service and they have different socket_types or
  419. X *            use diffent ports
  420. X *
  421. X * This function returns TRUE if the specified configurations are different.
  422. X *
  423. X * Note that this function is closely related to the 'readjust' function
  424. X * that is invoked on reconfiguration; that function will not change 
  425. X * attributes that this function checks to determine if two configurations
  426. X * are different.
  427. X */
  428. Xbool_int sc_different_confs( scp1, scp2 )
  429. X    struct service_config *scp1, *scp2 ;
  430. X{
  431. X   if ( SC_IS_UNLISTED( scp1 ) != SC_IS_UNLISTED( scp2 ) ||
  432. X                SC_IS_INTERNAL( scp1 ) != SC_IS_INTERNAL( scp2 ) ||
  433. X                    SC_IS_RPC( scp1 ) != SC_IS_RPC( scp2 ) )
  434. X      return( TRUE ) ;
  435. X
  436. X   if ( scp1->sc_wait != scp2->sc_wait )
  437. X      return( TRUE ) ;
  438. X  
  439. X    if ( scp1->sc_protocol.value != scp2->sc_protocol.value )
  440. X      return( TRUE ) ;
  441. X
  442. X   if ( SC_IS_RPC( scp1 ) )
  443. X   {
  444. X        if ( ! SAME_RPC( scp1, scp2 ) )
  445. X         return( TRUE ) ;
  446. X   }
  447. X   else
  448. X   {
  449. X        if ( ! SAME_NONRPC( scp1, scp2 ) )
  450. X         return( TRUE ) ;
  451. X   }
  452. X   return( FALSE ) ;
  453. X}
  454. X
  455. END_OF_FILE
  456. if test 11251 -ne `wc -c <'xinetd/sconf.c'`; then
  457.     echo shar: \"'xinetd/sconf.c'\" unpacked with wrong size!
  458. fi
  459. # end of 'xinetd/sconf.c'
  460. fi
  461. if test -f 'xinetd/shutdown.c' -a "${1}" != "-c" ; then 
  462.   echo shar: Will not clobber existing file \"'xinetd/shutdown.c'\"
  463. else
  464. echo shar: Extracting \"'xinetd/shutdown.c'\" \(10894 characters\)
  465. sed "s/^X//" >'xinetd/shutdown.c' <<'END_OF_FILE'
  466. X/*
  467. X * (c) Copyright 1992 by Panagiotis Tsirigotis
  468. X * All rights reserved.  The file named COPYRIGHT specifies the terms 
  469. X * and conditions for redistribution.
  470. X */
  471. X
  472. Xstatic char RCSid[] = "$Id: shutdown.c,v 6.4 1993/06/13 01:47:17 panos Exp $" ;
  473. X
  474. X#include <sys/types.h>
  475. X#include <sys/socket.h>
  476. X#include <netinet/in.h>
  477. X#include <netdb.h>
  478. X#include <pwd.h>
  479. X#include <string.h>
  480. X#include <syslog.h>
  481. X
  482. X#include "sio.h"
  483. X#include "str.h"
  484. X
  485. X#include "defs.h"
  486. X
  487. Xchar *malloc() ;
  488. Xchar *crypt() ;
  489. X
  490. Xvoid msg() ;
  491. X
  492. Xtypedef enum { SD_LOGIN, SD_SHELL, SD_EXEC, SD_FINGER } shutdown_e ;
  493. X
  494. Xstruct shutdown_function
  495. X{
  496. X    char            *sf_service ;
  497. X    voidfunc     sf_func ;
  498. X    char            *sf_function_name ;
  499. X} ;
  500. X
  501. X
  502. XPRIVATE void rlogin_shutdown() ;
  503. XPRIVATE void rexec_shutdown() ;
  504. XPRIVATE void rsh_shutdown() ;
  505. XPRIVATE void finger_shutdown() ;
  506. X
  507. Xstatic struct shutdown_function shutdown_functions[] =
  508. X   {
  509. X      { "login",        rlogin_shutdown,    "rlogin_shutdown"    },
  510. X        { "shell",        rsh_shutdown,        "rsh_shutdown"        },
  511. X        { "exec",        rexec_shutdown,    "rexec_shutdown"    },
  512. X        { "finger",        finger_shutdown,    "finger_shutdown"    },
  513. X      { CHAR_NULL }
  514. X   } ;
  515. X
  516. X
  517. Xtypedef enum
  518. X    {
  519. X        RS_OK, RS_EOF, RS_IOERR, RS_NOMEM, RS_TOOLONG, RS_BADCONN
  520. X    } read_status_e ;
  521. X
  522. Xstatic struct name_value read_status_names[] =
  523. X    {
  524. X        { "Error: out of memory",        (int) RS_NOMEM        },
  525. X        { "Error: input too long",        (int) RS_TOOLONG    },
  526. X        { "Error: I/O",                    (int) RS_IOERR      },
  527. X        { "Error: end-of-file",            (int) RS_EOF        },
  528. X        { "Error: bad connection",        (int) RS_BADCONN    },
  529. X        { CHAR_NULL,                        1                        },
  530. X        { "UNKNOWN",                        0                        }
  531. X    } ;
  532. X
  533. X#define rs_explain( s )            nv_get_name( read_status_names, (int) (s) )
  534. X
  535. X
  536. X/*
  537. X * NOTE: All shutdown functions assume that the process will exit
  538. X *         very soon, so they don't bother to deallocate any malloc'ed
  539. X *            memory. In particular, it is not guaranteed that the memory 
  540. X *            returned by these functions will point to malloc'ed memory
  541. X */
  542. X
  543. X
  544. X/*
  545. X * Locate and return the shutdown function for the given service
  546. X */
  547. Xvoidfunc get_shutdown_by_name( service ) 
  548. X    register char *service ;
  549. X{
  550. X    register struct shutdown_function *sfp ;
  551. X
  552. X    for ( sfp = &shutdown_functions[ 0 ] ; sfp->sf_service ; sfp++ )
  553. X        if ( EQ( service, sfp->sf_service ) )
  554. X            return( sfp->sf_func ) ;
  555. X    return( NULL ) ;
  556. X}
  557. X
  558. X
  559. Xchar *get_shutdown_by_addr( func )
  560. X    register voidfunc func ;
  561. X{
  562. X    register struct shutdown_function *sfp ;
  563. X
  564. X    for ( sfp = &shutdown_functions[ 0 ] ; sfp->sf_service ; sfp++ )
  565. X        if ( func == sfp->sf_func )
  566. X            break ;
  567. X    return( sfp->sf_function_name ) ;
  568. X}
  569. X
  570. X
  571. X/*
  572. X * Read a string of length at most max_len from socket sd.
  573. X * The string is placed in buf (if buf is not NULL). If buf
  574. X * is NULL, the input is drained.
  575. X * The input string is always read even if the allowed length
  576. X * is exceeded (the extra characters are ignored).
  577. X * max_len is the maximum length of the input string excluding the
  578. X * terminating NUL.
  579. X * The actual length is returned in lenp.
  580. X */
  581. XPRIVATE read_status_e read_string( sd, max_len, buf, lenp )
  582. X    int                    sd ;
  583. X    register unsigned max_len ;
  584. X    char                    *buf ;
  585. X    unsigned                *lenp ;
  586. X{
  587. X    char                        c ;
  588. X    register char            *p ;
  589. X    int                        cc ;
  590. X    read_status_e            read_status ;
  591. X    register status_e        status        = OK ;
  592. X    register int            len            = 0 ;
  593. X    int                        drain_input = ( buf == NULL ) ;
  594. X
  595. X    if ( drain_input )
  596. X    {
  597. X        status = FAILED ;
  598. X        p = &c ;
  599. X    }
  600. X    else
  601. X    {
  602. X        p = buf ;
  603. X        status = OK ;
  604. X    }
  605. X
  606. X    for ( ;; )
  607. X    {
  608. X        /*
  609. X         * Keep reading characters one by one (ugly !!!)
  610. X         * If status == FAILED, don't store them
  611. X         * Interesting side-effect: since we stop increasing p in
  612. X         * this case, *p will be used for storing all subsequent input
  613. X         * until the NUL. So we get a NUL terminated string with
  614. X         * the extra characters ignored.
  615. X         */
  616. X        if ( len > max_len )
  617. X        {
  618. X            status = FAILED ;
  619. X            read_status = RS_TOOLONG ;
  620. X        }
  621. X
  622. X        /*
  623. X         * If an I/O error occurs, end the loop
  624. X         */
  625. X        if ( ( cc = read( sd, p, 1 ) ) != 1 )
  626. X        {
  627. X            if ( cc == -1 )
  628. X                if ( errno == EINTR )
  629. X                    continue ;
  630. X                else
  631. X                    read_status = RS_IOERR ;
  632. X            else
  633. X                read_status = RS_EOF ;
  634. X            status = FAILED ;
  635. X            break ;
  636. X        }
  637. X        if ( *p == NUL )
  638. X            break ;
  639. X        if ( status == OK )
  640. X        {
  641. X            len++ ;
  642. X            p++ ;
  643. X        }
  644. X    }
  645. X    if ( status == OK )
  646. X    {
  647. X        *lenp = len ;
  648. X        read_status = RS_OK ;
  649. X    }
  650. X    return( drain_input ? RS_OK : read_status ) ;
  651. X}
  652. X
  653. X
  654. X/*
  655. X * Allocates a single buffer big enough to hold <count> strings whose
  656. X * maximum lengths are given in the <limits> array
  657. X * The pointers in the <strings> array will point to the part
  658. X * of the buffer for each string.
  659. X */
  660. XPRIVATE char *setup( count, limits, strings )
  661. X    register unsigned        count ;
  662. X    unsigned                    limits[] ;
  663. X    char                        *strings[] ;
  664. X{
  665. X    register unsigned        total_len ;
  666. X    register unsigned        index ;
  667. X    register unsigned        u ;
  668. X    char                        *buf ;
  669. X
  670. X    for ( u = 0, total_len = 0 ; u < count ; u++ )
  671. X        total_len += limits[ u ] ;
  672. X    
  673. X    buf = malloc( total_len + count ) ;        /* count the NULs */
  674. X    if ( buf == NUL )
  675. X        return( NULL ) ;
  676. X    
  677. X    for ( u = 0, index = 0 ; u < count ; u++ )
  678. X    {
  679. X        strings[ u ] = &buf[ index ] ;
  680. X        index += limits[ u ] + 1 ;
  681. X    }
  682. X    return( buf ) ;
  683. X}
  684. X
  685. X
  686. X
  687. XPRIVATE int connect_back( id, sd, port )
  688. X    shutdown_e            id ;
  689. X    int                    sd ;
  690. X    unsigned short     port ;
  691. X{
  692. X    int                        new_sd ;
  693. X    struct sockaddr_in    sin ;
  694. X    int                        sin_len    = sizeof( sin ) ;
  695. X    char                        *func        = "connect_back" ;
  696. X
  697. X    /*
  698. X     * Get the remote address
  699. X     */
  700. X    if ( getpeername( sd, SA( &sin ), &sin_len ) == -1 )
  701. X    {
  702. X        if ( debug.on )
  703. X            msg( LOG_DEBUG, func, "id=%d, getpeername: %m", (int) id ) ;
  704. X        return( -1 ) ;
  705. X    }
  706. X
  707. X    /*
  708. X     * Get a socket for the new connection.
  709. X     * For the shell service, the socket must have a proviliged local port
  710. X     */
  711. X    if ( id == SD_SHELL )
  712. X    {
  713. X        int local_port = IPPORT_RESERVED - 1 ;
  714. X        unsigned short client_port = ntohs( sin.sin_port ) ;
  715. X
  716. X        if ( ! ( client_port >= IPPORT_RESERVED/2 &&
  717. X                                            client_port < IPPORT_RESERVED ) )
  718. X        return( -1 ) ;
  719. X
  720. X        if ( ( new_sd = rresvport( &local_port ) ) == -1 )
  721. X            return( -1 ) ;
  722. X    }
  723. X    else if ( id == SD_EXEC )
  724. X    {
  725. X        if ( ( new_sd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 )
  726. X            return( -1 ) ;
  727. X    }
  728. X    else
  729. X        return( -1 ) ;
  730. X
  731. X    sin.sin_port = htons( port ) ;
  732. X    sin.sin_family = AF_INET ;
  733. X    if ( connect( new_sd, SA( &sin ), sizeof( sin ) ) == -1 )
  734. X    {
  735. X        if ( debug.on )
  736. X            msg( LOG_DEBUG, func, "connect: %m (port=%d)", port ) ;
  737. X        (void) close( new_sd ) ;
  738. X        return( -1 ) ;
  739. X    }
  740. X    return( new_sd ) ;
  741. X}
  742. X
  743. X
  744. XPRIVATE status_e rservices_common( id, sd, nargs, 
  745. X                                        limits, strings, total_lenp, pp )
  746. X    shutdown_e    id ;                /* service id                                             */
  747. X    unsigned        nargs ;            /* number of expected args. args are             */
  748. X                                        /* NUL-terminated strings                            */
  749. X    unsigned        limits[] ;        /* max length of each arg                            */
  750. X    char            *strings[] ;    /* array of arg pointers                            */
  751. X    unsigned        *total_lenp ;    /* total length of args                                */
  752. X    char            **pp ;            /* pointer to string to put error message        */
  753. X{
  754. X    read_status_e    rs ;
  755. X    char                *store_buf ;
  756. X    unsigned            total_len ;
  757. X    unsigned            len ;
  758. X    int                i ;
  759. X    char                *func = "rservices_common" ;
  760. X
  761. X    store_buf = setup( nargs, limits, strings ) ;
  762. X    if ( store_buf == NULL )
  763. X    {
  764. X        *pp = rs_explain( RS_NOMEM ) ;
  765. X        return( FAILED ) ;
  766. X    }
  767. X
  768. X    for ( i = 0, total_len = 0 ; i < nargs ; i++ )
  769. X    {
  770. X        rs = read_string( sd, limits[ i ], strings[ i ], &len ) ;
  771. X        if ( rs != RS_OK )
  772. X        {
  773. X            *pp = rs_explain( rs ) ;
  774. X            return( FAILED ) ;
  775. X        }
  776. X
  777. X        if ( i == 0 && ( id == SD_SHELL || id == SD_EXEC ) )
  778. X        {
  779. X            unsigned short port = atoi( strings[ 0 ] ) ;
  780. X
  781. X            if ( debug.on )
  782. X                msg( LOG_DEBUG, func, "port for new connection = %d", port ) ;
  783. X
  784. X            if ( port != 0 && connect_back( id, sd, port ) == -1 )
  785. X            {
  786. X                *pp = rs_explain( RS_BADCONN ) ;
  787. X                return( FAILED ) ;
  788. X            }
  789. X        }
  790. X        else
  791. X            total_len += len ;
  792. X    }
  793. X    *total_lenp = total_len ;
  794. X    return( OK ) ;
  795. X}
  796. X
  797. X
  798. X#define RLOGIN_ARGS         4
  799. X
  800. XPRIVATE void rlogin_shutdown( sd, pp )
  801. X    int sd ;
  802. X    char **pp ;
  803. X{
  804. X    char                    *print_buf ;
  805. X    unsigned                print_buf_size ;
  806. X    unsigned                total_len ;
  807. X    char                    *strings[ RLOGIN_ARGS ] ;
  808. X    static unsigned    limits[ RLOGIN_ARGS ] = { 0, 16, 16, 4096 } ;
  809. X
  810. X    (void) write( sd, "", 1 ) ;
  811. X
  812. X    if ( pp == NULL )
  813. X        return ;
  814. X
  815. X    if ( rservices_common( SD_LOGIN, sd,
  816. X                RLOGIN_ARGS, limits, strings, &total_len, pp ) == FAILED )
  817. X        return ;
  818. X
  819. X    print_buf_size = total_len + 100 ;
  820. X    print_buf = malloc( print_buf_size ) ;
  821. X    if ( print_buf != NULL )
  822. X        *pp = strx_sprint( print_buf, print_buf_size,
  823. X                        "remote_user=%s local_user=%s tty=%s",
  824. X                            strings[ 1 ], strings[ 2 ], strings[ 3 ] ) ;
  825. X    else
  826. X        *pp = rs_explain( RS_NOMEM ) ;
  827. X}
  828. X
  829. X
  830. X    
  831. X#define REXEC_ARGS            4
  832. X#define SALT_LEN                2
  833. X
  834. XPRIVATE void rexec_shutdown( sd, pp )
  835. X    int sd ;
  836. X    char **pp ;
  837. X{
  838. X    char                    *print_buf ;
  839. X    unsigned                print_buf_size ;
  840. X    char                    *password ;
  841. X    char                    salt[ SALT_LEN ] ;
  842. X    struct passwd        *pw ;
  843. X    char                    *verify ;
  844. X    unsigned                total_len ;
  845. X    char                    *strings[ REXEC_ARGS ] ;
  846. X    char                    error_indication        = '\1' ;
  847. X    char                    *error_message            = "Permission denied.\n" ;
  848. X    static unsigned    limits[ REXEC_ARGS ] = { 5, 16, 16, 4096 } ;
  849. X
  850. X    (void) write( sd, &error_indication, 1 ) ;
  851. X    (void) write( sd, error_message, strlen( error_message ) + 1 ) ;
  852. X    
  853. X    if ( pp == NULL )
  854. X        return ;
  855. X
  856. X    if ( rservices_common( SD_EXEC, sd,
  857. X                REXEC_ARGS, limits, strings, &total_len, pp ) == FAILED )
  858. X        return ;
  859. X
  860. X    /*
  861. X     * Verify the password
  862. X     */
  863. X    password = strings[ 2 ] ;
  864. X    pw = getpwnam( strings[ 1 ] ) ;
  865. X    if ( pw != NULL )
  866. X    {
  867. X        strncpy( salt, pw->pw_passwd, SALT_LEN )[ SALT_LEN ] = NUL ;
  868. X        if ( EQ( crypt( password, salt ), pw->pw_passwd ) )
  869. X            verify = "ok" ;
  870. X        else
  871. X            verify = "failed" ;
  872. X    }
  873. X    else
  874. X        verify = "baduser" ;
  875. X
  876. X    str_fill( password, ' ' ) ;        /* clear the password */
  877. X
  878. X    print_buf_size = total_len + 100 ;
  879. X    print_buf = malloc( print_buf_size ) ;
  880. X    if ( print_buf != NULL )
  881. X        *pp = strx_sprint( print_buf, print_buf_size, 
  882. X                            "remote_user=%s verify=%s command=%s",
  883. X                                            strings[ 1 ], verify, strings[ 3 ] ) ;
  884. X    else
  885. X        *pp = rs_explain( RS_NOMEM ) ;
  886. X}
  887. X
  888. X
  889. X
  890. X#define RSH_ARGS            4
  891. X
  892. XPRIVATE void rsh_shutdown( sd, pp )
  893. X    int sd ;
  894. X    char **pp ;
  895. X{
  896. X    char                    *print_buf ;
  897. X    unsigned                print_buf_size ;
  898. X    unsigned                total_len ;
  899. X    char                    *strings[ RSH_ARGS ] ;
  900. X    char                    error_indication        = '\1' ;
  901. X    char                    *error_message            = "Permission denied.\n" ;
  902. X    static unsigned    limits[ RSH_ARGS ]    = { 5, 16, 16, 4096 } ;
  903. X
  904. X    (void) write( sd, &error_indication, 1 ) ;
  905. X    (void) write( sd, error_message, strlen( error_message ) + 1 ) ;
  906. X
  907. X    if ( pp == NULL )
  908. X        return ;
  909. X    
  910. X    if ( rservices_common( SD_SHELL, sd,
  911. X                    RSH_ARGS, limits, strings, &total_len, pp ) == FAILED )
  912. X        return ;
  913. X    
  914. X    print_buf_size = total_len + 100 ;
  915. X    print_buf = malloc( print_buf_size ) ;
  916. X    if ( print_buf != NULL )
  917. X        *pp = strx_sprint( print_buf, print_buf_size,
  918. X                    "remote_user=%s local_user=%s command=%s",
  919. X                            strings[ 1 ], strings[ 2 ], strings[ 3 ] ) ;
  920. X    else
  921. X        *pp = rs_explain( RS_NOMEM ) ;
  922. X}
  923. X
  924. X
  925. XPRIVATE void finger_shutdown( sd, pp )
  926. X    int sd ;
  927. X    char **pp ;
  928. X{
  929. X    char *line ;
  930. X    int line_len ;
  931. X
  932. X    if ( pp == NULL )
  933. X        return ;
  934. X    
  935. X    line = Srdline( sd ) ;
  936. X    line_len = SIOLINELEN( sd ) ;
  937. X
  938. X    if ( line_len > 0 && line[ line_len-1 ] == '\r' )
  939. X        line[ --line_len ] = NUL ;
  940. X
  941. X    *pp = ( line_len == 0 ) ? "EMPTY-LINE" : line ;
  942. X}
  943. X
  944. END_OF_FILE
  945. if test 10894 -ne `wc -c <'xinetd/shutdown.c'`; then
  946.     echo shar: \"'xinetd/shutdown.c'\" unpacked with wrong size!
  947. fi
  948. # end of 'xinetd/shutdown.c'
  949. fi
  950. echo shar: End of archive 20 \(of 31\).
  951. cp /dev/null ark20isdone
  952. MISSING=""
  953. 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
  954.     if test ! -f ark${I}isdone ; then
  955.     MISSING="${MISSING} ${I}"
  956.     fi
  957. done
  958. if test "${MISSING}" = "" ; then
  959.     echo You have unpacked all 31 archives.
  960.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  961. else
  962.     echo You still need to unpack the following archives:
  963.     echo "        " ${MISSING}
  964. fi
  965. ##  End of shell archive.
  966. exit 0
  967.