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.
16 #include <sys/types.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
22 #include <limits.h> /* For LONG_MIN and LONG_MAX */
28 #if defined(hpux) && !defined(X_OK)
39 #include "libportable.h"
41 #include "addr.h" /* check_hostname() */
43 #define NEW_SET( set, v1, v2 ) \
44 if ( (set) == NULL && \
45 ( (set) = pset_create( (v1), (v2) ) ) == NULL ) \
47 out_of_memory( func ) ; \
51 static void missing_attr_msg(const char *par, const char *item)
53 parsemsg( LOG_WARNING, par,
54 "attribute %s expects at least 1 value and none were given.",
60 * Find the flags corresponding to strings in "values" and apply
61 * them to "*maskp" (apply means add or remove depending on "op")
62 * "description" describes the type of flags.
64 static status_e parse_value_list( pset_h values,
66 const struct name_value list[],
68 const char *description )
71 const struct name_value *nvp ;
72 const char *func = "parse_value_list" ;
74 for ( u=0; u<pset_count( values ); u++ )
76 const char *name = (char *) pset_pointer( values, u ) ;
78 nvp = nv_find_value( list, name ) ;
82 M_SET( *maskp, nvp->value ) ;
84 M_CLEAR( *maskp, nvp->value ) ;
88 parsemsg( LOG_WARNING, func, "Bad %s: %s", description, name ) ;
96 status_e type_parser( pset_h values,
97 struct service_config *scp,
100 if ( pset_count( values ) >= 1 )
102 return( parse_value_list( values,
103 &SC_TYPE(scp), service_types, PLUS_EQ, "service type" ) ) ;
107 missing_attr_msg("type_parser", "type");
113 status_e flags_parser( pset_h values,
114 struct service_config *scp,
117 if ( pset_count( values ) >= 1 )
119 return( parse_value_list( values,
120 &SC_XFLAGS(scp), service_flags, PLUS_EQ, "service flag" ) ) ;
124 missing_attr_msg("flags_parser", "flags");
130 status_e socket_type_parser( const pset_h values,
131 struct service_config *scp,
134 const struct name_value *nvp ;
135 const char *type = (char *) pset_pointer( values, 0 ) ;
136 const char *func = "socket_type_parser" ;
138 nvp = nv_find_value( socket_types, type ) ;
141 SC_SOCKET_TYPE(scp) = nvp->value ;
146 parsemsg( LOG_ERR, func, "Bad socket type: %s", type ) ;
152 status_e rpc_version_parser( pset_h values,
153 struct service_config *scp,
156 struct rpc_data *rdp = SC_RPCDATA( scp ) ;
157 char *version = (char *) pset_pointer( values, 0 ) ;
158 int min_version=0, max_version=0;
159 char *p = strchr( version, '-' ) ;
160 const char *func = "rpc_version_parser" ;
164 if ( parse_base10(version, &min_version) )
165 max_version = min_version - 1;
167 max_version = min_version;
172 if ( parse_base10(version, &min_version) ||
173 parse_base10(p+1, &max_version) )
174 max_version = min_version - 1;
176 if ( min_version > max_version )
178 parsemsg( LOG_ERR, func, "bad version range: %s", version ) ;
181 rdp->rd_min_version = min_version;
182 rdp->rd_max_version = max_version;
187 status_e rpc_number_parser( pset_h values,
188 struct service_config *scp,
193 if ( parse_base10((char *) pset_pointer( values, 0 ), &num) ) {
194 parsemsg(LOG_ERR, "rpc_number_parser", "Error parsing: %s",
195 (char *)pset_pointer( values, 0 ));
198 SC_RPCDATA( scp )->rd_program_number = num;
203 status_e protocol_parser( pset_h values,
204 struct service_config *scp,
207 char *proto_name = (char *) pset_pointer( values, 0 ) ;
208 struct protoent *pep ;
209 const char *func = "protocol_parser" ;
211 if( proto_name == NULL ) {
212 parsemsg( LOG_ERR, func, "Protocol name is null in %s", SC_NAME(scp) );
216 if ( ( pep = getprotobyname( proto_name ) ) == NULL )
218 parsemsg( LOG_ERR, func,
219 "Protocol %s not in /etc/protocols", proto_name ) ;
223 SC_PROTONAME(scp) = new_string( proto_name ) ;
224 if ( SC_PROTONAME(scp) == NULL )
226 out_of_memory( func ) ;
229 SC_PROTOVAL(scp) = pep->p_proto ;
234 status_e wait_parser( pset_h values,
235 struct service_config *scp,
238 char *val = (char *) pset_pointer( values, 0 ) ;
239 const char *func = "wait_parser" ;
241 if ( EQ( val, "yes" ) )
243 else if ( EQ( val, "no" ) )
247 parsemsg( LOG_ERR, func, "Bad value for wait: %s", val ) ;
254 status_e mdns_parser( pset_h values,
255 struct service_config *scp,
258 char *val = (char *) pset_pointer( values, 0 ) ;
259 const char *func = "mdns_parser" ;
261 if ( EQ( val, "yes" ) )
263 else if ( EQ( val, "no" ) )
267 parsemsg( LOG_ERR, func, "Bad value for mdns: %s", val ) ;
274 status_e user_parser( pset_h values,
275 struct service_config *scp,
278 char *user = (char *) pset_pointer( values, 0 ) ;
279 const char *func = "user_parser" ;
281 if (parse_all_digits(user) == TRUE)
282 { /* We will assume the number is a valid user. This is a workaround
283 for some Solaris systems that have problems doing getgr*. */
284 if (parse_ubase10(user, (unsigned int *)&SC_UID(scp)))
286 parsemsg( LOG_ERR, func, "Error parsing user as a number: %s", user ) ;
289 SC_USER_GID(scp) = SC_UID(scp) ;
295 pw = getpwnam( user ) ;
298 parsemsg( LOG_ERR, func, "Unknown user: %s", user ) ;
301 str_fill( pw->pw_passwd, ' ' );
302 SC_UID(scp) = pw->pw_uid ;
303 SC_USER_GID(scp) = pw->pw_gid ;
309 status_e group_parser( pset_h values,
310 struct service_config *scp,
313 const char *func = "group_parser" ;
314 char *group_ptr = (char *) pset_pointer( values, 0 ) ;
316 if (parse_all_digits(group_ptr) == TRUE)
317 { /* We will assume the number is a valid group. This is a workaround
318 for some Solaris systems that have problems doing getgr*. */
319 if (parse_ubase10(group_ptr, (unsigned int *)&SC_GID(scp)))
321 parsemsg( LOG_ERR, func, "Error parsing group as a number: %s", group_ptr ) ;
327 struct group *grp = getgrnam( group_ptr ) ;
330 parsemsg( LOG_ERR, func, "Unknown group: %s", group_ptr ) ;
334 SC_GID(scp) = grp->gr_gid ;
340 status_e svcdisable_parser( pset_h values,
341 struct service_config *scp,
344 const char *func = "svcdisable_parser" ;
345 char *val = (char *) pset_pointer( values, 0 ) ;
347 if( EQ( val, "yes" ) )
349 else if( EQ( val, "no" ) )
353 parsemsg( LOG_ERR, func, "Bad value: %s", val ) ;
361 status_e groups_parser( pset_h values,
362 struct service_config *scp,
365 char *val = (char *) pset_pointer( values, 0 ) ;
366 const char *func = "groups_parser" ;
368 if ( EQ( val, "yes" ) )
369 SC_GROUPS(scp) = YES ;
370 else if ( EQ( val, "no" ) )
371 SC_GROUPS(scp) = NO ;
374 parsemsg( LOG_ERR, func, "Bad value for groups: %s", val ) ;
382 status_e v6only_parser( pset_h values,
383 struct service_config *scp,
386 char *val = (char *) pset_pointer( values, 0 );
387 const char *func = "v6only_parser" ;
389 if ( EQ( val, "yes" ) )
390 SC_V6ONLY(scp) = YES;
391 else if ( EQ( val, "no" ) )
395 parsemsg( LOG_ERR, func, "Bad value for v6only: %s", val );
402 status_e server_parser( pset_h values,
403 struct service_config *scp,
406 char *server = (char *) pset_pointer( values, 0 ) ;
407 const char *func = "server_parser" ;
411 * Access is used so that the real user ID permissions
414 if ( access( server, X_OK ) == -1 )
416 parsemsg( LOG_ERR, func, "Server %s is not executable", server ) ;
419 if (stat(server, &sb) == -1)
421 parsemsg( LOG_ERR, func, "Unable to stat: %s.", server ) ;
425 SC_SERVER(scp) = new_string( server ) ;
426 if ( SC_SERVER(scp) == NULL )
428 out_of_memory( func ) ;
435 status_e server_args_parser( pset_h values,
436 struct service_config *scp,
443 unsigned argv_index ;
444 unsigned n_args = pset_count( values ) ;
445 const char *func = "server_args_parser" ;
448 * Create the argv for a future exec call
449 * Reserve space for the server. We cannot use scp->sc_server
450 * since it may not have a value yet.
452 argv = argv_alloc( n_args+1 ) ;
453 count = pset_count( values );
456 missing_attr_msg("server_args_parser", "server_args");
457 free( (char *) argv ) ;
461 if( SC_NAMEINARGS( scp ) )
463 for (u = 0; u < count; u++)
465 register char *s = new_string( (char *) pset_pointer( values, u )) ;
469 for ( i = 1 ; i < u ; i++ )
471 free( (char *) argv ) ;
472 out_of_memory( func ) ;
480 for (u = 0, argv_index = 1 ; u < count; u++, argv_index++)
482 register char *s = new_string((char *) pset_pointer( values, u )) ;
486 for ( i = 1 ; i < argv_index ; i++ )
488 free( (char *) argv ) ;
489 out_of_memory( func ) ;
492 argv[ argv_index ] = s ;
494 argv[ argv_index ] = argv[ 0 ] = NULL ;
496 SC_SERVER_ARGV(scp) = argv ;
501 status_e instances_parser( pset_h values,
502 struct service_config *scp,
505 char *instances = (char *) pset_pointer( values, 0 ) ;
506 const char *func = "instances_parser" ;
508 if ( EQ( instances, "UNLIMITED" ) )
509 SC_INSTANCES(scp) = UNLIMITED ;
512 if ( parse_base10(instances, &SC_INSTANCES(scp)) ||
513 SC_INSTANCES(scp) < 0 )
515 parsemsg( LOG_ERR, func,
516 "Number of instances is invalid: %s", instances ) ;
524 status_e per_source_parser( pset_h values,
525 struct service_config *scp,
528 char *per_source = (char *) pset_pointer( values, 0 ) ;
529 const char *func = "per_source_parser" ;
531 if ( EQ( per_source, "UNLIMITED" ) )
532 SC_PER_SOURCE(scp) = UNLIMITED;
535 if ( parse_base10(per_source, &SC_PER_SOURCE(scp)) ||
536 SC_PER_SOURCE(scp) < 0 )
538 parsemsg( LOG_ERR, func, "Number of per source instances is invalid: %s", per_source ) ;
546 status_e cps_parser( pset_h values,
547 struct service_config *scp,
550 char *cps = (char *) pset_pointer(values, 0);
551 char *waittime = (char *) pset_pointer(values, 1);
552 unsigned int waittime_int, conn_max;
554 if( cps == NULL || waittime == NULL ) {
555 parsemsg(LOG_ERR, "cps_parser", "NULL options specified in cps");
558 if( parse_ubase10(cps, &conn_max) ) {
559 parsemsg(LOG_ERR, "cps_parser", "cps argument not a number");
560 SC_TIME_CONN_MAX(scp) = 0;
561 SC_TIME_WAIT(scp) = 0;
564 if( parse_ubase10(waittime, &waittime_int) ) {
565 parsemsg(LOG_ERR, "cps_parser", "cps time argument not a number");
566 SC_TIME_CONN_MAX(scp) = 0;
567 SC_TIME_WAIT(scp) = 0;
570 SC_TIME_WAIT(scp) = waittime_int;
571 SC_TIME_CONN_MAX(scp) = conn_max;
573 if( SC_TIME_CONN_MAX(scp) < 0 || SC_TIME_WAIT(scp) < 0 ) {
574 parsemsg(LOG_ERR, "cps_parser", "cps arguments invalid");
575 SC_TIME_CONN_MAX(scp) = 0;
576 SC_TIME_WAIT(scp) = 0;
583 status_e id_parser( pset_h values,
584 struct service_config *scp,
587 const char *func = "id_parser" ;
589 SC_ID(scp) = new_string( (char *) pset_pointer( values, 0 ) ) ;
590 if ( SC_ID(scp) != NULL )
592 out_of_memory( func ) ;
599 #define PORT_MAX ( 1 << PORT_BITS )
601 status_e port_parser( pset_h values,
602 struct service_config *scp,
606 const char *func = "port_parser" ;
608 if ( parse_base10((char *) pset_pointer( values, 0 ), &port) ||
609 port < 0 || port >= PORT_MAX )
611 parsemsg( LOG_ERR, func, "port number is invalid" ) ;
614 SC_PORT(scp) = (uint16_t)port ;
619 static status_e add_new_string( pset_h set, char *str )
621 char *p = new_string( str ) ;
622 const char *func = "add_new_string" ;
626 parsemsg( LOG_CRIT, func, ES_NOMEM ) ;
629 if ( pset_add( set, p ) == NULL )
632 parsemsg( LOG_CRIT, func, ES_NOMEM ) ;
639 status_e env_parser( pset_h values,
640 struct service_config *scp,
644 const char *func = "env_parser" ;
646 if ( op == MINUS_EQ )
648 parsemsg( LOG_WARNING, func,
649 "operator '-=' not supported for env attribute" ) ;
653 NEW_SET( SC_ENV_VAR_DEFS(scp), 5, 5 ) ;
655 if ( op == SET_EQ && pset_count( SC_ENV_VAR_DEFS(scp) ) != 0 )
657 pset_apply( SC_ENV_VAR_DEFS(scp), free, NULL ) ;
658 pset_clear( SC_ENV_VAR_DEFS(scp) ) ;
661 for ( u = 0 ; u < pset_count( values ) ; u++ )
663 char *str = (char *) pset_pointer( values, u ) ;
666 * Check if the string contains an '='
668 if ( strchr( str, '=' ) == NULL )
670 parsemsg( LOG_ERR, func, "%s has no '='", str ) ;
674 if ( add_new_string( SC_ENV_VAR_DEFS(scp), str ) == FAILED )
681 status_e passenv_parser( pset_h values,
682 struct service_config *scp,
687 const char *func = "passenv_parser" ;
689 NEW_SET( SC_PASS_ENV_VARS(scp), 0, 0 ) ;
691 var_set = SC_PASS_ENV_VARS(scp) ;
695 pset_apply( var_set, free, NULL ) ;
696 pset_clear( var_set ) ;
700 for ( u = 0 ; u < pset_count( values ) ; u++ )
702 char *env_var = (char *) pset_pointer( values, u ) ;
707 * Check if it is already there
709 for ( found = NO, v = 0 ; v < pset_count( var_set ) ; v++ )
710 if ( EQ( env_var, (char *) pset_pointer( var_set, v ) ) )
716 if ( ((op == MINUS_EQ) && (found == NO)) || ((op != MINUS_EQ) && (found == YES)) )
719 if ( op == MINUS_EQ )
721 free( (char *) pset_pointer( var_set, v ) ) ;
722 pset_remove_index( var_set, v ) ;
726 if ( env_lookup( std_env, env_var ) == CHAR_NULL )
728 parsemsg( LOG_WARNING, func,
729 "undefined environment variable: %s", env_var ) ;
733 if ( add_new_string( var_set, env_var ) == FAILED )
741 status_e disabled_parser( pset_h values,
742 struct service_config *scp,
746 const char *func = "disabled_parser" ;
748 NEW_SET( SC_DISABLED(scp), pset_count( values ), 0 ) ;
750 for ( u = 0 ; u < pset_count( values ) ; u++ )
752 char *name = (char *) pset_pointer( values, u ) ;
754 if ( add_new_string( SC_DISABLED(scp), name ) == FAILED )
761 status_e enabled_parser( pset_h values,
762 struct service_config *scp,
766 const char *func = "enabled_parser" ;
768 NEW_SET( SC_ENABLED(scp), pset_count( values ), 0 ) ;
770 for ( u = 0 ; u < pset_count( values ) ; u++ )
772 char *name = (char *) pset_pointer( values, u ) ;
774 if ( add_new_string( SC_ENABLED(scp), name ) == FAILED )
781 * Interpret a number of the form: <num>[m|M|k|K]
782 * m and M mean megabytes, k and K mean kilobytes, nothing means bytes
784 static int get_limit( char *limit_str, rlim_t *res )
786 unsigned long long limit_int;
790 if (*limit_str == NUL) {
795 p = limit_str + strlen( limit_str ) - 1;
796 while ( p > limit_str && isspace( *p ) )
799 if (*p == 'k' || *p == 'K') {
802 } else if (*p == 'm' || *p == 'M') {
804 multiplier = 1024 * 1024;
808 if (parse_ull(limit_str, 10, -1, &limit_int)) {
813 *res = (rlim_t)limit_int;
814 if (*res != limit_int) {
819 *res = (rlim_t)limit_int * multiplier;
820 if (*res / multiplier != (rlim_t)limit_int) {
829 static status_e parse_filelog( struct filelog *flp, pset_h values )
834 unsigned count = pset_count( values ) ;
835 const char *func = "parse_filelog" ;
837 if ( count < 2 || count > 4 )
839 parsemsg( LOG_ERR, func, "wrong number of arguments" ) ;
843 file = new_string( (char *) pset_pointer( values, 1 ) ) ;
846 out_of_memory( func ) ;
851 * Get the limits, if any
855 if ( get_limit( (char *) pset_pointer( values, 2 ), &soft_limit ) )
857 parsemsg( LOG_ERR, func, "soft limit is invalid" ) ;
863 * If a hard limit was specified check that it is at least equal
864 * to the soft limit. If no hard limit was specified, determine
865 * it from the formula:
868 * min( 1%soft,LOG_EXTRA_MIN ) <= x <= max( 1%soft,LOG_EXTRA_MAX )
872 if ( get_limit( (char *) pset_pointer( values, 3 ), &hard_limit) )
874 parsemsg( LOG_ERR, func, "hard limit is invalid" ) ;
878 if ( hard_limit < soft_limit )
880 parsemsg( LOG_ERR, func,
881 "hard limit (%lu) is less than soft limit (%lu)",
882 (unsigned long)hard_limit, (unsigned long)soft_limit ) ;
889 unsigned extra = soft_limit / 100 ; /* 1% of soft limit */
891 if ( extra < LOG_EXTRA_MIN )
892 extra = LOG_EXTRA_MIN ;
893 else if ( extra > LOG_EXTRA_MAX )
894 extra = LOG_EXTRA_MAX ;
895 hard_limit = soft_limit + extra ;
897 flp->fl_soft_limit = soft_limit ;
898 flp->fl_hard_limit = hard_limit ;
900 flp->fl_filename = file ;
905 static status_e parse_syslog( struct syslog *slp, pset_h values )
907 const char *facility ;
909 const struct name_value *nvp ;
910 unsigned count = pset_count( values ) ;
911 const char *func = "parse_syslog" ;
913 if ( count < 2 || count > 3 )
915 parsemsg( LOG_ERR, func, "wrong number of arguments" ) ;
919 facility = (char *) pset_pointer( values, 1 ) ;
920 if ( ( nvp = nv_find_value( syslog_facilities, facility ) ) == NULL )
922 parsemsg( LOG_ERR, func, "Unknown syslog facility: %s", facility ) ;
925 slp->sl_facility = nvp->value ;
929 level = (char *) pset_pointer( values, 2 ) ;
930 if ( ( nvp = nv_find_value( syslog_levels, level ) ) == NULL )
932 parsemsg( LOG_ERR, func, "Unknown syslog level: %s", level ) ;
935 slp->sl_level = nvp->value ;
938 slp->sl_level = DEFAULT_SERVICE_SYSLOG_LEVEL ;
944 status_e log_type_parser( pset_h values,
945 struct service_config *scp,
948 struct log *lp = SC_LOG( scp ) ;
950 const char *func = "parse_log_type" ;
951 int count = pset_count( values);
955 missing_attr_msg(func, "log_type");
959 type = (char *) pset_pointer( values, 0 ) ;
961 if ( EQ( type, "FILE" ) )
963 if ( parse_filelog( LOG_GET_FILELOG( lp ), values ) == FAILED )
965 lp->l_type = L_FILE ;
967 else if ( EQ( type, "SYSLOG" ) )
969 if ( parse_syslog( LOG_GET_SYSLOG( lp ), values ) == FAILED )
971 lp->l_type = L_SYSLOG ;
975 parsemsg( LOG_ERR, func, "Unknown log type: %s", type ) ;
982 static status_e parse_log_flags( pset_h values,
985 const struct name_value options[],
990 M_CLEAR_ALL( *maskp ) ;
994 return( parse_value_list( values, maskp, options, op, name ) ) ;
998 status_e log_on_success_parser( pset_h values,
999 struct service_config *scp,
1002 return( parse_log_flags( values, op,
1003 &SC_LOG_ON_SUCCESS(scp), success_log_options, "log_on_success flag" ) ) ;
1007 status_e log_on_failure_parser( pset_h values,
1008 struct service_config *scp,
1011 return( parse_log_flags( values, op,
1012 &SC_LOG_ON_FAILURE(scp), failure_log_options, "log_on_failure flag" ) ) ;
1016 static status_e parse_inet_addresses( pset_h values,
1022 statfunc addrlist_func ;
1023 const char *func = "parse_inet_addresses" ;
1025 NEW_SET( *addr_list, 0, 0 );
1027 addr_set = *addr_list;
1030 * If the op was '=' clear the existing list of addresses
1035 addrlist_free( addr_set ) ;
1036 pset_clear( addr_set ) ;
1039 addrlist_func = ( op == PLUS_EQ ) ? addrlist_add : addrlist_remove ;
1041 for ( u = 0 ; u < pset_count( values ) ; u++ )
1043 register char *str_addr = (char *) pset_pointer( values, u ) ;
1045 /* If it is factorized, allow a comma. Otherwise complain */
1046 if (strchr(str_addr, ',') && !strchr(str_addr, '{'))
1048 parsemsg( LOG_ERR, func,
1049 "Address: %s has a comma in it - remove the comma",
1054 if ( (*addrlist_func)( addr_set, str_addr ) == FAILED )
1056 parsemsg( LOG_ERR, func, "Failed adding: %s", str_addr ) ;
1064 status_e only_from_parser( pset_h values,
1065 struct service_config *scp,
1068 return( parse_inet_addresses( values, op, &SC_ONLY_FROM(scp) ) ) ;
1072 status_e no_access_parser( pset_h values,
1073 struct service_config *scp,
1076 return( parse_inet_addresses( values, op, &SC_NO_ACCESS(scp) ) ) ;
1080 status_e banner_parser(pset_h values,
1081 struct service_config *scp,
1084 const char *func = "banner_parser";
1086 if( pset_pointer(values, 0) == NULL )
1088 msg(LOG_ERR, func, "pset_pointer returned NULL");
1092 SC_BANNER(scp) = new_string( pset_pointer(values,0) );
1093 if( SC_BANNER(scp) == NULL ) {
1094 msg(LOG_ERR, func, ES_NOMEM);
1101 status_e banner_success_parser(pset_h values,
1102 struct service_config *scp,
1105 const char *func = "banner_success_parser";
1107 if( pset_pointer(values, 0) == NULL ) {
1108 msg(LOG_ERR, func, "pset_pointer returned NULL" );
1112 SC_BANNER_SUCCESS(scp) = new_string(pset_pointer(values,0) );
1113 if( SC_BANNER_SUCCESS(scp) == NULL ) {
1114 msg(LOG_ERR, func, ES_NOMEM);
1121 status_e banner_fail_parser(pset_h values,
1122 struct service_config *scp,
1125 const char *func = "banner_fail_parser";
1127 if( pset_pointer(values, 0) == NULL ) {
1128 msg(LOG_ERR, func, "pset_pointer returned NULL");
1132 SC_BANNER_FAIL(scp) = new_string(pset_pointer(values,0) );
1133 if( SC_BANNER_FAIL(scp) == NULL ) {
1134 msg(LOG_ERR, func, ES_NOMEM);
1142 status_e max_load_parser(pset_h values,
1143 struct service_config *scp,
1146 const char *func = "max_load_parser" ;
1147 char *adr = (char *)pset_pointer(values, 0);
1149 if( sscanf(adr, "%lf", &SC_MAX_LOAD(scp)) < 1 ) {
1150 parsemsg(LOG_ERR, func, "error reading max_load argument");
1154 if( SC_MAX_LOAD(scp) == 0 ) {
1155 parsemsg(LOG_ERR, func, "error parsing max_load argument");
1163 status_e redir_parser(pset_h values,
1164 struct service_config *scp,
1167 char *adr = (char *)pset_pointer(values, 0);
1168 const char *func = "redir_parser";
1171 struct addrinfo hints, *res;
1173 port_char = pset_pointer(values, 1);
1174 if (parse_base10(port_char, &port_int) || port_int <= 0)
1175 { /* OK, maybe its a service name... */
1176 struct servent *entry;
1177 entry = getservbyname(port_char, "tcp");
1180 parsemsg(LOG_ERR, func, "port number invalid");
1183 port_int = ntohs(entry->s_port);
1185 if (port_int >= PORT_MAX)
1187 parsemsg(LOG_ERR, func, "port number too large");
1191 SC_REDIR_ADDR(scp) = (union xsockaddr *)malloc(sizeof(union xsockaddr));
1192 if( SC_REDIR_ADDR(scp) == NULL )
1194 parsemsg(LOG_ERR, func, "can't allocate space for redir addr");
1198 memset(&hints, 0, sizeof(hints));
1199 hints.ai_flags = AI_CANONNAME;
1200 hints.ai_socktype = SOCK_STREAM;
1201 if (strchr(adr, ':'))
1202 hints.ai_family = AF_INET6;
1204 hints.ai_family = AF_INET;
1206 if( getaddrinfo(adr, NULL, &hints, &res) < 0 ) {
1207 parsemsg(LOG_ERR, func, "bad address");
1208 free( SC_REDIR_ADDR(scp) );
1209 SC_REDIR_ADDR(scp) = NULL;
1213 if( (res == NULL) || (res->ai_addr == NULL) ) {
1214 parsemsg(LOG_ERR, func, "no addresses returned");
1215 free( SC_REDIR_ADDR(scp) );
1216 SC_REDIR_ADDR(scp) = NULL;
1220 if( (res->ai_family == AF_INET) || (res->ai_family == AF_INET6) )
1221 memcpy(SC_REDIR_ADDR(scp), res->ai_addr, res->ai_addrlen);
1222 if( SC_REDIR_ADDR(scp)->sa.sa_family == AF_INET )
1223 SC_REDIR_ADDR(scp)->sa_in.sin_port = port_int;
1224 if( SC_REDIR_ADDR(scp)->sa.sa_family == AF_INET6 )
1225 SC_REDIR_ADDR(scp)->sa_in6.sin6_port = port_int;
1231 status_e bind_parser( pset_h values,
1232 struct service_config *scp,
1235 char *adr = (char *)pset_pointer(values, 0);
1236 const char *func = "bind_parser";
1237 struct addrinfo hints, *res, *ressave;
1240 memset(&hints, 0, sizeof(hints));
1241 hints.ai_flags = AI_CANONNAME;
1244 * Use tcp to cut down returned address records. Get addrinfo normally
1245 * returns 2 address records, one for each socket type.
1247 hints.ai_socktype = SOCK_STREAM;
1249 if (check_hostname(adr) == 0)
1251 hints.ai_family = AF_INET;
1252 hints.ai_flags |= AI_NUMERICHOST;
1254 else if (strchr(adr, ':'))
1256 hints.ai_family = AF_INET6;
1257 hints.ai_flags |= AI_NUMERICHOST;
1261 hints.ai_family = AF_UNSPEC;
1264 if( getaddrinfo(adr, NULL, &hints, &res) < 0 ) {
1265 parsemsg(LOG_ERR, func, "bad address");
1269 if( (res == NULL) || (res->ai_addr == NULL) ) {
1270 parsemsg(LOG_ERR, func, "no addresses returned");
1275 * If more than 1 record comes back, we need to defer selection
1276 * until we are finished reading all attributes of the service.
1277 * Hopefully, they will have specified IPv4 or IPv6.
1289 SC_BIND_ADDR(scp) = (union xsockaddr *)malloc(sizeof(union xsockaddr));
1290 if( SC_BIND_ADDR(scp) == NULL )
1292 parsemsg(LOG_ERR, func, "can't allocate space for bind addr");
1295 memcpy(SC_BIND_ADDR(scp), res->ai_addr, res->ai_addrlen);
1298 SC_ORIG_BIND_ADDR(scp) = new_string(adr);
1304 status_e access_times_parser( pset_h values,
1305 struct service_config *scp,
1309 const char *func = "access_times_parser" ;
1311 NEW_SET( SC_ACCESS_TIMES(scp), 0, 0 ) ;
1312 count = pset_count( values) ;
1316 missing_attr_msg("access_times_parser", "access_times");
1320 for ( u = 0 ; u < count ; u++ )
1322 register char *interval = (char *) pset_pointer( values, u ) ;
1324 if ( ti_add( SC_ACCESS_TIMES(scp), interval ) == FAILED )
1331 status_e nice_parser( pset_h values,
1332 struct service_config *scp,
1335 if ( parse_base10((char *) pset_pointer( values, 0 ), &SC_NICE(scp)) ) {
1336 parsemsg(LOG_ERR, "nice_parser", "Error parsing: %s", (char *)pset_pointer( values, 0 ));
1343 status_e rlim_as_parser( pset_h values,
1344 struct service_config *scp,
1347 char *mem = (char *) pset_pointer( values, 0 ) ;
1348 const char *func = "rlim_as_parser" ;
1350 if ( EQ( mem, "UNLIMITED" ) )
1351 SC_RLIM_AS(scp) = (rlim_t)RLIM_INFINITY ;
1354 if ( get_limit ( mem, &SC_RLIM_AS(scp)) )
1356 parsemsg( LOG_ERR, func,
1357 "Address space limit is invalid: %s", mem ) ;
1366 status_e rlim_cpu_parser( pset_h values,
1367 struct service_config *scp,
1370 char *cpu_str = (char *) pset_pointer( values, 0 ) ;
1371 unsigned long long cpu_int;
1372 const char *func = "rlim_cpu_parser" ;
1374 if ( EQ( cpu_str, "UNLIMITED" ) )
1375 SC_RLIM_CPU(scp) = (rlim_t)RLIM_INFINITY ;
1378 if ( parse_ull(cpu_str, 10, -1, &cpu_int) || cpu_int < 0 )
1380 parsemsg( LOG_ERR, func,
1381 "CPU limit is invalid: %s", cpu_str ) ;
1384 SC_RLIM_CPU(scp) = (rlim_t) cpu_int ;
1385 if ( SC_RLIM_CPU(scp) != cpu_int )
1387 parsemsg( LOG_ERR, func, "CPU limit is invalid: %s", cpu_str );
1396 status_e rlim_data_parser( pset_h values,
1397 struct service_config *scp,
1400 char *mem = (char *) pset_pointer( values, 0 ) ;
1401 const char *func = "rlim_data_parser" ;
1403 if ( EQ( mem, "UNLIMITED" ) )
1404 SC_RLIM_DATA(scp) = (rlim_t)RLIM_INFINITY ;
1407 if ( get_limit ( mem, &SC_RLIM_DATA(scp) ) )
1409 parsemsg( LOG_ERR, func,
1410 "Data limit is invalid: %s", mem ) ;
1419 status_e rlim_rss_parser( pset_h values,
1420 struct service_config *scp,
1423 char *mem = (char *) pset_pointer( values, 0 ) ;
1424 const char *func = "rlim_rss_parser" ;
1426 if ( EQ( mem, "UNLIMITED" ) )
1427 SC_RLIM_RSS(scp) = (rlim_t)RLIM_INFINITY ;
1430 if ( get_limit ( mem, &SC_RLIM_RSS(scp) ) )
1432 parsemsg( LOG_ERR, func,
1433 "RSS limit is invalid: %s", mem ) ;
1442 status_e rlim_stack_parser( pset_h values,
1443 struct service_config *scp,
1446 char *mem = (char *) pset_pointer( values, 0 ) ;
1447 const char *func = "rlim_stack_parser" ;
1449 if ( EQ( mem, "UNLIMITED" ) )
1450 SC_RLIM_STACK(scp) = (rlim_t)RLIM_INFINITY ;
1453 if ( get_limit ( mem, &SC_RLIM_STACK(scp) ) )
1455 parsemsg( LOG_ERR, func,
1456 "Stack limit is invalid: %s", mem ) ;
1464 status_e deny_time_parser( pset_h values,
1465 struct service_config *scp,
1468 char *deny_time = (char *) pset_pointer( values, 0 ) ;
1470 if ( EQ( deny_time, "FOREVER" ) )
1471 SC_DENY_TIME(scp) = -1 ;
1472 else if ( EQ( deny_time, "NEVER" ) )
1473 SC_DENY_TIME(scp) = 0 ;
1474 else if ( parse_base10( deny_time, &SC_DENY_TIME(scp) ) ) {
1475 parsemsg(LOG_ERR, "deny_time_parser", "Error parsing: %s", deny_time);
1481 status_e umask_parser( pset_h values,
1482 struct service_config *scp,
1485 char *umask_str = (char *)pset_pointer(values, 0);
1488 if( parse_int(umask_str, 8, -1, &umask_int) ||
1489 umask_int < 0 || umask_int > 0777)
1491 parsemsg(LOG_ERR, "umask_parser", "umask argument is invalid.\n");
1494 SC_UMASK(scp) = umask_int;
1499 status_e libwrap_parser( pset_h values,
1500 struct service_config *scp,
1503 char *libwrap = (char *) pset_pointer( values, 0 ) ;
1504 const char *func = "libwrap_parser" ;
1506 SC_LIBWRAP(scp) = new_string( libwrap ) ;
1507 if ( SC_LIBWRAP(scp) == NULL )
1509 out_of_memory( func ) ;