fixes init script for non ipv6 enabled systems #472755
[packages/xinetd.git] / xinetd / server.c
1 /*
2  * (c) Copyright 1992 by Panagiotis Tsirigotis
3  * (c) Sections Copyright 1998-2001 by Rob Braun
4  * All rights reserved.  The file named COPYRIGHT specifies the terms 
5  * and conditions for redistribution.
6  */
7
8 #include "config.h"
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
13 #include <syslog.h>
14 #include <fcntl.h>
15 #include <time.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18
19 #ifdef HAVE_SYS_FILE_H
20 #include <sys/file.h>
21 #endif
22
23 #include "pset.h"
24 #include "sio.h"
25 #include "server.h"
26 #include "util.h"
27 #include "msg.h"
28 #include "service.h"
29 #include "sconf.h"
30 #include "state.h"
31 #include "main.h"
32 #include "xconfig.h"
33 #include "retry.h"
34 #include "child.h"
35 #include "signals.h"
36
37
38 #define NEW_SERVER()                NEW( struct server )
39 #define FREE_SERVER( serp )         FREE( serp )
40
41
42 #ifndef DEBUG_RETRY
43 #define do_fork()         fork()
44 #else
45 #include <errno.h>
46 extern int errno ;
47
48 /*
49  * 3 out of 4 times the do_fork() will fail
50  */
51 #define do_fork()         ( random() & 0x11 ) ? ( errno = EAGAIN, -1 ) : fork()
52 #endif    /* DEBUG_RETRY */
53
54
55 /*
56  * Allocate a server, initialize it from init_serp, and insert it in the server
57  * table.
58  */
59 struct server *server_alloc( const struct server *init_serp )
60 {
61    struct server   *serp ;
62    const char      *func = "server_alloc" ;
63
64    serp = NEW_SERVER() ;
65    if ( serp == NULL )
66    {
67       out_of_memory( func ) ;
68       return( NULL ) ;
69    }
70
71    if ( pset_add( SERVERS(ps), serp ) == NULL )
72    {
73       msg( LOG_CRIT, func, "couldn't insert server in server table" ) ;
74       CLEAR( *serp ) ;
75       FREE_SERVER( serp ) ;
76       return( NULL ) ;
77    }
78
79    *serp = *init_serp ;         /* initialize it */
80    SVC_HOLD( SERVER_SERVICE(serp) ) ;
81
82    return( serp ) ;
83 }
84
85
86 void server_release( struct server *serp )
87 {
88    struct service   *sp   = SERVER_SERVICE( serp ) ;
89    int              count = SVC_RELE( sp ) ;
90
91    pset_remove(SERVERS(ps), serp);
92    if ( count == 0 ) {
93       if( ! SC_IS_SPECIAL( SVC_CONF( sp ) )  )
94          pset_remove( SERVICES( ps ), sp ) ;
95       svc_release( sp );
96    }
97    
98    CLEAR( *serp ) ;
99    FREE_SERVER( serp ) ;
100 }
101
102
103 /*
104  * If a service is internal and does not require forking a process:
105  *      -    if it accepts connections, we put the accepted connection
106  *       in non-blocking mode to avoid a possible block on 
107  *       the write(2).
108  *      -   the log flags that have to do with the server exiting are 
109  *         ignored (i.e. nothing is logged).
110  *      -   it can be identified in the log because the server pid is 0.
111  */
112 static void server_internal( struct server *serp )
113 {
114    struct service *sp = SERVER_SERVICE(serp) ;
115    const char *func = "server_internal" ;
116
117    SERVER_PID(serp) = 0 ;
118    if ( SVC_ACCEPTS_CONNECTIONS( sp ) &&
119             fcntl( SERVER_FD( serp ), F_SETFL, FNDELAY ) == -1 )
120    {
121       msg( LOG_ERR, func, "%s: fcntl F_SETFL failed: %m", SVC_ID( sp ) ) ;
122       return ;
123    }
124    svc_log_success( sp, SERVER_CONNECTION(serp), SERVER_PID(serp) ) ;
125    SVC_INTERNAL( sp, serp ) ;
126 }
127  
128
129 /*
130  * Attempt to start a server for service 'sp' to handle
131  * connection 'cp'.
132  * Return value:
133  *   OK:   if a server is started or a retry attempt is scheduled
134  *   FAILED:   otherwise (a log entry is also made)
135  */
136 status_e server_run( struct service *sp, connection_s *cp )
137 {
138    struct server    server ;
139    struct server   *serp = NULL;
140    const char      *func = "server_run" ;
141
142    CLEAR( server ) ;
143    server.svr_sp = sp ;
144    server.svr_conn = cp ;
145
146    if ( ! SVC_FORKS( sp ) )
147    {  /*
148        * SG - Added this check so that internal services get the
149        * same protection that external services get. This is
150        * mandatory for the sensor patch to work.
151        */
152
153       if (svc_child_access_control( sp, cp ) == OK)
154          server_internal( &server ) ;
155       else {
156          if ( SVC_WAITS( sp ) )
157             svc_resume( sp );
158          return( FAILED );
159       }
160       if ( SVC_WAITS( sp ) )
161          svc_resume( sp );
162       return( OK ) ;
163    }
164
165    /*
166     * Insert new struct server in server table first, to avoid the
167     * possibility of running out of memory *after* the fork.
168     */
169    serp = server_alloc( &server ) ;
170    if ( serp == NULL )
171       return( FAILED ) ;
172
173    if ( server_start( serp ) == OK )
174    {
175       if( !SVC_WAITS(sp) )
176          CONN_CLOSE( cp ) ;
177       return( OK ) ;
178    }
179
180    /* server will be removed in server_release() */
181
182    /*
183     * Currently, fork failures are the only reason for retrying.
184     * There is no retry if we exceed the max allowed number of fork failures
185     */
186    if ( ! SERVER_FORKLIMIT( serp ) && SVC_RETRY( sp ) )
187    {
188       if ( schedule_retry( serp ) == OK )
189          return( OK ) ;
190       else
191          msg( LOG_ERR, func, "Retry failure for %s service", SVC_ID( sp ) ) ;
192    }
193    else
194       svc_log_failure( sp, cp, AC_FORK ) ;
195
196    server_release( serp ) ;
197    return( FAILED ) ;
198 }
199
200
201 /*
202  *  Try to fork a server process.
203  *  Actually, we won't fork if tcpmux_child is set, becuase we have
204  *  already forked to keep the xinetd parent from blocking on the
205  *  read of the service name.
206  */
207 status_e server_start( struct server *serp )
208 {
209    struct service   *sp = SERVER_SERVICE(serp) ;
210    const char       *func = "server_start" ;
211
212    if( debug.on )
213       msg( LOG_DEBUG, func, "Starting service %s", SC_NAME( SVC_CONF( sp ) ) );
214    SERVER_LOGUSER(serp) = SVC_LOGS_USERID_ON_SUCCESS( sp ) ;
215    
216    SERVER_PID(serp) = do_fork() ;
217
218    switch ( SERVER_PID(serp) )
219    {
220       case 0:
221          ps.rws.env_is_valid = FALSE ;
222          child_process( serp ) ;
223
224          msg( LOG_ERR, func, "INTERNAL ERROR: child_process returned" ) ;
225          _exit( 0 ) ;
226          /* NOTREACHED */
227       
228       case -1:
229          msg( LOG_ERR, func, "%s: fork failed: %m", SVC_ID( sp ) ) ;
230          SERVER_FORK_FAILURES(serp)++ ;
231          return( FAILED ) ;
232
233       default:
234          (void) time( &SERVER_STARTTIME(serp) ) ;
235          SVC_INC_RUNNING_SERVERS( sp ) ;
236
237          /*
238           * Log the start of another server (if it is not an interceptor).
239           * Determine if the server writes to the log (because in that case
240           * we will have to check the log size).
241           */
242          if ( ! SVC_IS_INTERCEPTED( sp ) )
243             svc_log_success( sp, SERVER_CONNECTION(serp), SERVER_PID(serp) ) ;
244          else
245             SERVER_WRITES_TO_LOG(serp) = SVC_IS_LOGGING( sp ) ;
246          SERVER_WRITES_TO_LOG(serp) |= SERVER_LOGUSER(serp) ;
247          return( OK ) ;
248    }
249 }
250
251
252 void server_dump( const struct server *serp, int fd )
253 {
254    const struct service *sp = SERVER_SERVICE(serp) ;
255
256    Sprint( fd, "%s server\n", SVC_ID( sp ) ) ;
257    Sprint( fd, "pid = %d\n", SERVER_PID(serp) ) ;
258    Sprint( fd, "start_time = %s", ctime( &SERVER_STARTTIME(serp) ) ) ;
259    Sprint( fd, "Connection info:\n" ) ;
260    conn_dump( SERVER_CONNECTION(serp), fd ) ;
261    if ( SERVER_FORK_FAILURES(serp) )
262       Sprint( fd, "fork_failures = %d\n", SERVER_FORK_FAILURES(serp) ) ;
263    Sprint( fd,
264          "log_remote_user = %s\n", SERVER_LOGUSER(serp) ? "YES" : "NO" ) ;
265    Sprint( fd,
266          "writes_to_log = %s\n", SERVER_WRITES_TO_LOG(serp) ? "YES" : "NO" ) ;
267    Sputchar( fd, '\n' ) ;
268    Sflush( fd ) ;
269 }
270
271
272 /*
273  * Invoked when a server dies, either because of a signal or in case of
274  * a normal exit.
275  */
276 void server_end( struct server *serp )
277 {
278    struct service *sp = SERVER_SERVICE(serp) ;
279    const char *func = "server_end" ;
280
281    if ( PROC_EXITED( SERVER_EXITSTATUS(serp) ) || 
282          PROC_SIGNALED( SERVER_EXITSTATUS(serp) ) )
283    {
284       const char *death_type = PROC_EXITED( SERVER_EXITSTATUS(serp) ) ? "exited"
285            : "died" ;
286       if ( debug.on )
287       {
288          struct service *conn_sp = CONN_SERVICE( SERVER_CONNECTION(serp) ) ;
289
290          if ( conn_sp == sp )
291             msg( LOG_DEBUG, func,
292                "%s server %d %s", SVC_ID( sp ) , SERVER_PID(serp), death_type ) ;
293          else
294             msg( LOG_DEBUG, func,
295                "%s server %d running on behalf of service %s %s",
296                   SVC_ID( sp ), SERVER_PID(serp), SVC_ID( conn_sp ), death_type ) ;
297       }
298       
299       /* Added this for when accepting wait=yes services */
300       if( SVC_WAITS( sp ) )
301          FD_SET( SVC_FD( sp ), &ps.rws.socket_mask ) ;
302
303       svc_postmortem( sp, serp ) ;
304       server_release( serp ) ;
305    }
306    else if ( PROC_STOPPED( SERVER_EXITSTATUS(serp) ) )
307       msg( LOG_WARNING, func, "service %s: server with pid %d stopped",
308          SVC_ID( sp ), SERVER_PID(serp) ) ;
309 }
310
311
312 /*
313  * Find the running server with the specified pid
314  */
315 struct server *server_lookup( pid_t pid )
316 {
317    unsigned u ;
318
319    for ( u = 0 ; u < pset_count( SERVERS( ps ) ) ; u++ )
320    {
321       register struct server *serp ;
322
323       serp = SERP( pset_pointer( SERVERS( ps ), u ) ) ;
324       if ( SERVER_PID(serp) == pid )
325          return( serp ) ;
326    }
327    return( NULL ) ;
328 }
329