2 * (c) Copyright 1998-2001 by Rob Braun
3 * All rights reserved. The file named COPYRIGHT specifies the terms
4 * and conditions for redistribution.
26 static int get_next_inet_entry( int fd, pset_h sconfs,
27 struct service_config *defaults);
29 void parse_inet_conf_file( int fd, struct configuration *confp )
31 pset_h sconfs = CNF_SERVICE_CONFS( confp );
32 struct service_config *default_config = CNF_DEFAULTS( confp );
38 if (get_next_inet_entry(fd, sconfs, default_config) == -2)
43 static int get_next_inet_entry( int fd, pset_h sconfs,
44 struct service_config *defaults)
48 char *line = next_line(fd);
49 struct service_config *scp;
51 const char *func = "get_next_inet_entry";
52 char *name = NULL, *rpcvers = NULL, *rpcproto = NULL;
53 char *group, *proto, *stype;
54 const struct name_value *nvp;
55 struct protoent *pep ;
58 const char *dot = ".";
59 const char *slash = "/";
62 if( line == CHAR_NULL )
65 strp = str_parse( line, " \t", STR_RETURN_ERROR, INT_NULL ) ;
68 parsemsg( LOG_CRIT, func, "inetd.conf - str_parse failed" ) ;
72 if( (args = pset_create(10,10)) == NULL )
78 /* Break the line into components, based on spaces */
79 while( (p = str_component( strp )) )
81 if( pset_add(args, p) == NULL )
83 parsemsg( LOG_CRIT, func, ES_NOMEM );
90 /* get the service name */
91 name = new_string((char *)pset_pointer( args, 0 ));
93 parsemsg( LOG_ERR, func, "inetd.conf - Invalid service name" );
98 /* Check to find the '/' for specifying RPC version numbers */
99 if( (rpcvers = strstr(name, slash)) != NULL ) {
104 scp = sc_alloc( name );
112 * sc_alloc makes its own copy of name. At this point, sc_alloc worked
113 * so we will free our copy to avoid leaks.
117 /* Replicate inetd behavior in this regard. Also makes sure the
118 * service actually works on system where setgroups(0,NULL) doesn't
121 SC_GROUPS(scp) = YES;
122 SC_SPECIFY( scp, A_GROUPS );
124 /* Get the socket type (stream dgram) */
125 stype = (char *)pset_pointer(args, 1);
126 if( stype == NULL ) {
127 parsemsg( LOG_ERR, func, "inetd.conf - Invalid socket type" );
132 nvp = nv_find_value( socket_types, stype );
135 parsemsg( LOG_ERR, func, "inetd.conf - Bad socket type: %s", p);
141 SC_SOCKET_TYPE(scp) = nvp->value;
143 /* Get the protocol type */
144 proto = (char *)pset_pointer(args,2);
145 if( strstr(proto, "rpc") != NULL )
148 struct rpc_data *rdp = SC_RPCDATA( scp ) ;
150 if( rpcvers == NULL ) {
157 p = strchr(rpcvers, '-');
158 if( p && parse_int(rpcvers, 10, '-', &rpcmin) == 0 ) {
159 if( parse_base10(p + 1, &rpcmax) || rpcmin > rpcmax ) {
165 if( parse_base10(rpcvers, &rpcmin) ) {
174 /* now have min and max rpc versions */
175 rdp->rd_min_version = rpcmin;
176 rdp->rd_max_version = rpcmax;
178 rpcproto = strstr(proto, slash);
179 if( rpcproto == NULL ) {
180 parsemsg( LOG_ERR, func, "inetd.conf - bad rpc version numbers" );
189 /* Set the RPC type field */
190 nvp = nv_find_value( service_types, "RPC" );
193 parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ;
199 M_SET(SC_TYPE(scp), nvp->value);
201 if ( ( pep = getprotobyname( proto ) ) == NULL )
203 parsemsg( LOG_ERR, func, "inetd.conf - Protocol %s not in /etc/protocols",
210 SC_PROTONAME(scp) = new_string( proto ) ;
211 if ( SC_PROTONAME(scp) == NULL )
213 out_of_memory( func ) ;
218 SC_PROTOVAL(scp) = pep->p_proto;
219 SC_SPECIFY(scp, A_PROTOCOL);
221 /* Get the wait attribute */
222 p = (char *)pset_pointer(args, 3);
224 parsemsg( LOG_ERR, func, "inetd.conf - No value specified for wait" );
228 if ( EQ( p, "wait" ) )
230 else if ( EQ( p, "nowait" ) )
233 parsemsg( LOG_ERR, func, "inetd.conf - Bad value for wait: %s", p ) ;
235 /* Get the user to run as */
236 p = (char *)pset_pointer(args, 4);
238 parsemsg( LOG_ERR, func, "inetd.conf - No value specified for user" );
242 if( (group = strstr(p, dot)) )
247 grp = (struct group *)getgrnam( (char *)group ) ;
250 parsemsg( LOG_ERR, func, "inetd.conf - Unknown group: %s", group ) ;
256 SC_GID(scp) = ((struct group *)grp)->gr_gid;
257 SC_SPECIFY( scp, A_GROUP );
263 parsemsg( LOG_ERR, func, "inetd.conf - Unknown user: %s", p ) ;
268 str_fill( pw->pw_passwd, ' ' );
269 SC_UID(scp) = pw->pw_uid;
270 SC_USER_GID(scp) = pw->pw_gid;
272 /* Get server name, or flag as internal */
273 p = (char *)pset_pointer(args, 5);
275 parsemsg( LOG_ERR, func, "inetd.conf - No value specified for user" );
279 if( EQ( p, "internal" ) )
281 nvp = nv_find_value( service_types, "INTERNAL" );
284 parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ;
290 M_SET(SC_TYPE(scp), nvp->value);
292 if( EQ( SC_NAME(scp), "time" ) ) {
293 if( EQ( proto, "stream" ) )
294 SC_ID(scp) = new_string("time-stream");
296 SC_ID(scp) = new_string("time-dgram");
299 if( EQ( SC_NAME(scp), "daytime" ) ) {
300 if( EQ( proto, "stream" ) )
301 SC_ID(scp) = new_string("daytime-stream");
303 SC_ID(scp) = new_string("daytime-dgram");
306 if( EQ( SC_NAME(scp), "chargen" ) ) {
307 if( EQ( proto, "stream" ) )
308 SC_ID(scp) = new_string("chargen-stream");
310 SC_ID(scp) = new_string("chargen-dgram");
313 if( EQ( SC_NAME(scp), "echo" ) ) {
314 if( EQ( proto, "stream" ) )
315 SC_ID(scp) = new_string("echo-stream");
317 SC_ID(scp) = new_string("echo-dgram");
320 if( EQ( SC_NAME(scp), "discard" ) )
322 parsemsg(LOG_WARNING, func,
323 "inetd.conf - service discard not supported");
331 SC_SERVER(scp) = new_string( p );
332 if ( SC_SERVER(scp) == NULL )
334 out_of_memory( func ) ;
339 SC_SPECIFY( scp, A_SERVER);
342 SC_SERVER_ARGV(scp) = (char **)argv_alloc(pset_count(args)+1);
344 for( u = 0; u < pset_count(args)-6 ; u++ )
346 p = new_string((char *)pset_pointer(args, u+6));
349 for ( i = 1 ; i < u ; i++ )
350 free( SC_SERVER_ARGV(scp)[i] );
351 free( SC_SERVER_ARGV(scp) );
356 SC_SERVER_ARGV(scp)[u] = p;
358 /* Set the reuse flag, as this is the default for inetd */
359 nvp = nv_find_value( service_flags, "REUSE" );
362 parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ;
367 M_SET(SC_XFLAGS(scp), nvp->value);
369 /* Set the NOLIBWRAP flag, since inetd doesn't have libwrap built in */
370 nvp = nv_find_value( service_flags, "NOLIBWRAP" );
373 parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ;
378 M_SET(SC_XFLAGS(scp), nvp->value);
380 /* Set the NAMEINARGS flag, as that's the default for inetd */
381 nvp = nv_find_value( service_flags, "NAMEINARGS" );
384 parsemsg( LOG_WARNING, func, "inetd.conf - Bad foo %s", name ) ;
389 M_SET(SC_XFLAGS(scp), nvp->value);
390 SC_SPECIFY( scp, A_SERVER_ARGS );
392 if ( (SC_ID(scp) = new_string( SC_NAME(scp) )) )
393 SC_PRESENT( scp, A_ID ) ;
396 out_of_memory( func ) ;
403 SC_SPECIFY( scp, A_PROTOCOL );
404 SC_SPECIFY( scp, A_USER );
405 SC_SPECIFY( scp, A_SOCKET_TYPE );
406 SC_SPECIFY( scp, A_WAIT );
408 if( ! pset_add(sconfs, scp) )
410 out_of_memory( func );
417 parsemsg( LOG_DEBUG, func, "added service %s", SC_NAME(scp));