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
9 #include "config.h"
10 #include <ctype.h>
11 #include <sys/file.h>
12 #include <syslog.h>
13 #include <netdb.h>
14 #include <pwd.h>
15 #include <grp.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <limits.h> /* For LONG_MIN and LONG_MAX */
23 #include <errno.h>
24 #ifdef HAVE_LOADAVG
25 #include <stdio.h>
26 #endif
27
28 #if defined(hpux) && !defined(X_OK)
29 #define X_OK 1
30 #endif
31
32 #include "str.h"
33 #include "parsers.h"
34 #include "msg.h"
35 #include "nvlists.h"
36 #include "env.h"
37 #include "xconfig.h"
38 #include "addr.h"
39 #include "libportable.h"
40 #include "timex.h"
41 #include "addr.h" /* check_hostname() */
42
43 #define NEW_SET( set, v1, v2 ) \
44 if ( (set) == NULL && \
45 ( (set) = pset_create( (v1), (v2) ) ) == NULL ) \
46 { \
47 out_of_memory( func ) ; \
48 return( FAILED ) ; \
49 }
50
missing_attr_msg(const char * par,const char * item)51 static void missing_attr_msg(const char *par, const char *item)
52 {
53 parsemsg( LOG_WARNING, par,
54 "attribute %s expects at least 1 value and none were given.",
55 item );
56 }
57
58
59 /*
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.
63 */
parse_value_list(pset_h values,mask_t * maskp,const struct name_value list[],enum assign_op op,const char * description)64 static status_e parse_value_list( pset_h values,
65 mask_t *maskp,
66 const struct name_value list[],
67 enum assign_op op,
68 const char *description )
69 {
70 unsigned u ;
71 const struct name_value *nvp ;
72 const char *func = "parse_value_list" ;
73
74 for ( u=0; u<pset_count( values ); u++ )
75 {
76 const char *name = (char *) pset_pointer( values, u ) ;
77
78 nvp = nv_find_value( list, name ) ;
79 if ( nvp != NULL )
80 {
81 if ( op == PLUS_EQ )
82 M_SET( *maskp, nvp->value ) ;
83 else
84 M_CLEAR( *maskp, nvp->value ) ;
85 }
86 else
87 {
88 parsemsg( LOG_WARNING, func, "Bad %s: %s", description, name ) ;
89 return( FAILED );
90 }
91 }
92 return( OK ) ;
93 }
94
95
type_parser(pset_h values,struct service_config * scp,enum assign_op op)96 status_e type_parser( pset_h values,
97 struct service_config *scp,
98 enum assign_op op )
99 {
100 if ( pset_count( values ) >= 1 )
101 {
102 return( parse_value_list( values,
103 &SC_TYPE(scp), service_types, PLUS_EQ, "service type" ) ) ;
104 }
105 else
106 {
107 missing_attr_msg("type_parser", "type");
108 return FAILED ;
109 }
110 }
111
112
flags_parser(pset_h values,struct service_config * scp,enum assign_op op)113 status_e flags_parser( pset_h values,
114 struct service_config *scp,
115 enum assign_op op )
116 {
117 if ( pset_count( values ) >= 1 )
118 {
119 return( parse_value_list( values,
120 &SC_XFLAGS(scp), service_flags, PLUS_EQ, "service flag" ) ) ;
121 }
122 else
123 {
124 missing_attr_msg("flags_parser", "flags");
125 return FAILED ;
126 }
127 }
128
129
socket_type_parser(const pset_h values,struct service_config * scp,enum assign_op op)130 status_e socket_type_parser( const pset_h values,
131 struct service_config *scp,
132 enum assign_op op )
133 {
134 const struct name_value *nvp ;
135 const char *type = (char *) pset_pointer( values, 0 ) ;
136 const char *func = "socket_type_parser" ;
137
138 nvp = nv_find_value( socket_types, type ) ;
139 if ( nvp != NULL )
140 {
141 SC_SOCKET_TYPE(scp) = nvp->value ;
142 return( OK ) ;
143 }
144 else
145 {
146 parsemsg( LOG_ERR, func, "Bad socket type: %s", type ) ;
147 return( FAILED ) ;
148 }
149 }
150
151
rpc_version_parser(pset_h values,struct service_config * scp,enum assign_op op)152 status_e rpc_version_parser( pset_h values,
153 struct service_config *scp,
154 enum assign_op op )
155 {
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" ;
161
162 if ( p == NULL )
163 {
164 if ( parse_base10(version, &min_version) )
165 max_version = min_version - 1;
166 else
167 max_version = min_version;
168 }
169 else
170 {
171 *p = NUL ;
172 if ( parse_base10(version, &min_version) ||
173 parse_base10(p+1, &max_version) )
174 max_version = min_version - 1;
175 }
176 if ( min_version > max_version )
177 {
178 parsemsg( LOG_ERR, func, "bad version range: %s", version ) ;
179 return( FAILED ) ;
180 }
181 rdp->rd_min_version = min_version;
182 rdp->rd_max_version = max_version;
183 return( OK ) ;
184 }
185
186
rpc_number_parser(pset_h values,struct service_config * scp,enum assign_op op)187 status_e rpc_number_parser( pset_h values,
188 struct service_config *scp,
189 enum assign_op op )
190 {
191 int num;
192
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 ));
196 return( FAILED );
197 }
198 SC_RPCDATA( scp )->rd_program_number = num;
199 return( OK ) ;
200 }
201
202
protocol_parser(pset_h values,struct service_config * scp,enum assign_op op)203 status_e protocol_parser( pset_h values,
204 struct service_config *scp,
205 enum assign_op op )
206 {
207 char *proto_name = (char *) pset_pointer( values, 0 ) ;
208 struct protoent *pep ;
209 const char *func = "protocol_parser" ;
210
211 if( proto_name == NULL ) {
212 parsemsg( LOG_ERR, func, "Protocol name is null in %s", SC_NAME(scp) );
213 return( FAILED );
214 }
215
216 if ( ( pep = getprotobyname( proto_name ) ) == NULL )
217 {
218 parsemsg( LOG_ERR, func,
219 "Protocol %s not in /etc/protocols", proto_name ) ;
220 return( FAILED ) ;
221 }
222
223 SC_PROTONAME(scp) = new_string( proto_name ) ;
224 if ( SC_PROTONAME(scp) == NULL )
225 {
226 out_of_memory( func ) ;
227 return( FAILED ) ;
228 }
229 SC_PROTOVAL(scp) = pep->p_proto ;
230 return( OK ) ;
231 }
232
233
wait_parser(pset_h values,struct service_config * scp,enum assign_op op)234 status_e wait_parser( pset_h values,
235 struct service_config *scp,
236 enum assign_op op )
237 {
238 char *val = (char *) pset_pointer( values, 0 ) ;
239 const char *func = "wait_parser" ;
240
241 if ( EQ( val, "yes" ) )
242 SC_WAIT(scp) = YES ;
243 else if ( EQ( val, "no" ) )
244 SC_WAIT(scp) = NO ;
245 else
246 {
247 parsemsg( LOG_ERR, func, "Bad value for wait: %s", val ) ;
248 return( FAILED );
249 }
250 return( OK ) ;
251 }
252
253 #ifdef HAVE_MDNS
mdns_parser(pset_h values,struct service_config * scp,enum assign_op op)254 status_e mdns_parser( pset_h values,
255 struct service_config *scp,
256 enum assign_op op )
257 {
258 char *val = (char *) pset_pointer( values, 0 ) ;
259 const char *func = "mdns_parser" ;
260
261 if ( EQ( val, "yes" ) )
262 SC_MDNS(scp) = YES ;
263 else if ( EQ( val, "no" ) )
264 SC_MDNS(scp) = NO ;
265 else
266 {
267 parsemsg( LOG_ERR, func, "Bad value for mdns: %s", val ) ;
268 return( FAILED );
269 }
270 return( OK ) ;
271 }
272 #endif
273
user_parser(pset_h values,struct service_config * scp,enum assign_op op)274 status_e user_parser( pset_h values,
275 struct service_config *scp,
276 enum assign_op op )
277 {
278 char *user = (char *) pset_pointer( values, 0 ) ;
279 const char *func = "user_parser" ;
280
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)))
285 {
286 parsemsg( LOG_ERR, func, "Error parsing user as a number: %s", user ) ;
287 return( FAILED ) ;
288 }
289 SC_USER_GID(scp) = SC_UID(scp) ;
290 }
291 else
292 {
293 struct passwd *pw ;
294
295 pw = getpwnam( user ) ;
296 if ( pw == NULL )
297 {
298 parsemsg( LOG_ERR, func, "Unknown user: %s", user ) ;
299 return( FAILED ) ;
300 }
301 str_fill( pw->pw_passwd, ' ' );
302 SC_UID(scp) = pw->pw_uid ;
303 SC_USER_GID(scp) = pw->pw_gid ;
304 }
305 return( OK ) ;
306 }
307
308
group_parser(pset_h values,struct service_config * scp,enum assign_op op)309 status_e group_parser( pset_h values,
310 struct service_config *scp,
311 enum assign_op op )
312 {
313 const char *func = "group_parser" ;
314 char *group_ptr = (char *) pset_pointer( values, 0 ) ;
315
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)))
320 {
321 parsemsg( LOG_ERR, func, "Error parsing group as a number: %s", group_ptr ) ;
322 return( FAILED ) ;
323 }
324 }
325 else
326 {
327 struct group *grp = getgrnam( group_ptr ) ;
328 if ( grp == NULL )
329 {
330 parsemsg( LOG_ERR, func, "Unknown group: %s", group_ptr ) ;
331 return( FAILED ) ;
332 }
333
334 SC_GID(scp) = grp->gr_gid ;
335 }
336 return( OK ) ;
337 }
338
339
svcdisable_parser(pset_h values,struct service_config * scp,enum assign_op op)340 status_e svcdisable_parser( pset_h values,
341 struct service_config *scp,
342 enum assign_op op )
343 {
344 const char *func = "svcdisable_parser" ;
345 char *val = (char *) pset_pointer( values, 0 ) ;
346
347 if( EQ( val, "yes" ) )
348 SC_DISABLE( scp );
349 else if( EQ( val, "no" ) )
350 SC_ENABLE( scp );
351 else
352 {
353 parsemsg( LOG_ERR, func, "Bad value: %s", val ) ;
354 return( FAILED );
355 }
356
357 return( OK );
358 }
359
360
groups_parser(pset_h values,struct service_config * scp,enum assign_op op)361 status_e groups_parser( pset_h values,
362 struct service_config *scp,
363 enum assign_op op )
364 {
365 char *val = (char *) pset_pointer( values, 0 ) ;
366 const char *func = "groups_parser" ;
367
368 if ( EQ( val, "yes" ) )
369 SC_GROUPS(scp) = YES ;
370 else if ( EQ( val, "no" ) )
371 SC_GROUPS(scp) = NO ;
372 else
373 {
374 parsemsg( LOG_ERR, func, "Bad value for groups: %s", val ) ;
375 return( FAILED );
376 }
377
378 return( OK );
379 }
380
381
v6only_parser(pset_h values,struct service_config * scp,enum assign_op op)382 status_e v6only_parser( pset_h values,
383 struct service_config *scp,
384 enum assign_op op )
385 {
386 char *val = (char *) pset_pointer( values, 0 );
387 const char *func = "v6only_parser" ;
388
389 if ( EQ( val, "yes" ) )
390 SC_V6ONLY(scp) = YES;
391 else if ( EQ( val, "no" ) )
392 SC_V6ONLY(scp) = NO;
393 else
394 {
395 parsemsg( LOG_ERR, func, "Bad value for v6only: %s", val );
396 return( FAILED );
397 }
398 return( OK );
399 }
400
401
server_parser(pset_h values,struct service_config * scp,enum assign_op op)402 status_e server_parser( pset_h values,
403 struct service_config *scp,
404 enum assign_op op )
405 {
406 char *server = (char *) pset_pointer( values, 0 ) ;
407 const char *func = "server_parser" ;
408 struct stat sb;
409
410 /*
411 * Access is used so that the real user ID permissions
412 * are checked.
413 */
414 if ( access( server, X_OK ) == -1 )
415 {
416 parsemsg( LOG_ERR, func, "Server %s is not executable", server ) ;
417 return( FAILED ) ;
418 }
419 if (stat(server, &sb) == -1)
420 {
421 parsemsg( LOG_ERR, func, "Unable to stat: %s.", server ) ;
422 return( FAILED ) ;
423 }
424
425 SC_SERVER(scp) = new_string( server ) ;
426 if ( SC_SERVER(scp) == NULL )
427 {
428 out_of_memory( func ) ;
429 return( FAILED ) ;
430 }
431 return( OK ) ;
432 }
433
434
server_args_parser(pset_h values,struct service_config * scp,enum assign_op op)435 status_e server_args_parser( pset_h values,
436 struct service_config *scp,
437 enum assign_op op )
438 {
439 char **argv ;
440 unsigned u ;
441 unsigned i ;
442 unsigned count;
443 unsigned argv_index ;
444 unsigned n_args = pset_count( values ) ;
445 const char *func = "server_args_parser" ;
446
447 /*
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.
451 */
452 argv = argv_alloc( n_args+1 ) ;
453 count = pset_count( values );
454 if ( count == 0 )
455 {
456 missing_attr_msg("server_args_parser", "server_args");
457 free( (char *) argv ) ;
458 return FAILED;
459 }
460
461 if( SC_NAMEINARGS( scp ) )
462 {
463 for (u = 0; u < count; u++)
464 {
465 register char *s = new_string( (char *) pset_pointer( values, u )) ;
466
467 if ( s == NULL )
468 {
469 for ( i = 1 ; i < u ; i++ )
470 free( argv[ i ] ) ;
471 free( (char *) argv ) ;
472 out_of_memory( func ) ;
473 return( FAILED ) ;
474 }
475 argv[ u ] = s ;
476 }
477 }
478 else
479 {
480 for (u = 0, argv_index = 1 ; u < count; u++, argv_index++)
481 {
482 register char *s = new_string((char *) pset_pointer( values, u )) ;
483
484 if ( s == NULL )
485 {
486 for ( i = 1 ; i < argv_index ; i++ )
487 free( argv[ i ] ) ;
488 free( (char *) argv ) ;
489 out_of_memory( func ) ;
490 return( FAILED ) ;
491 }
492 argv[ argv_index ] = s ;
493 }
494 argv[ argv_index ] = argv[ 0 ] = NULL ;
495 }
496 SC_SERVER_ARGV(scp) = argv ;
497 return( OK ) ;
498 }
499
500
instances_parser(pset_h values,struct service_config * scp,enum assign_op op)501 status_e instances_parser( pset_h values,
502 struct service_config *scp,
503 enum assign_op op )
504 {
505 char *instances = (char *) pset_pointer( values, 0 ) ;
506 const char *func = "instances_parser" ;
507
508 if ( EQ( instances, "UNLIMITED" ) )
509 SC_INSTANCES(scp) = UNLIMITED ;
510 else
511 {
512 if ( parse_base10(instances, &SC_INSTANCES(scp)) ||
513 SC_INSTANCES(scp) < 0 )
514 {
515 parsemsg( LOG_ERR, func,
516 "Number of instances is invalid: %s", instances ) ;
517 return( FAILED ) ;
518 }
519 }
520 return( OK ) ;
521 }
522
523
per_source_parser(pset_h values,struct service_config * scp,enum assign_op op)524 status_e per_source_parser( pset_h values,
525 struct service_config *scp,
526 enum assign_op op )
527 {
528 char *per_source = (char *) pset_pointer( values, 0 ) ;
529 const char *func = "per_source_parser" ;
530
531 if ( EQ( per_source, "UNLIMITED" ) )
532 SC_PER_SOURCE(scp) = UNLIMITED;
533 else
534 {
535 if ( parse_base10(per_source, &SC_PER_SOURCE(scp)) ||
536 SC_PER_SOURCE(scp) < 0 )
537 {
538 parsemsg( LOG_ERR, func, "Number of per source instances is invalid: %s", per_source ) ;
539 return( FAILED );
540 }
541 }
542 return(OK);
543 }
544
545
cps_parser(pset_h values,struct service_config * scp,enum assign_op op)546 status_e cps_parser( pset_h values,
547 struct service_config *scp,
548 enum assign_op op )
549 {
550 char *cps = (char *) pset_pointer(values, 0);
551 char *waittime = (char *) pset_pointer(values, 1);
552 unsigned int waittime_int, conn_max;
553
554 if( cps == NULL || waittime == NULL ) {
555 parsemsg(LOG_ERR, "cps_parser", "NULL options specified in cps");
556 return( FAILED );
557 }
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;
562 return( FAILED );
563 }
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;
568 return( FAILED );
569 }
570 SC_TIME_WAIT(scp) = waittime_int;
571 SC_TIME_CONN_MAX(scp) = conn_max;
572
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;
577 return( FAILED );
578 }
579
580 return(OK);
581 }
582
id_parser(pset_h values,struct service_config * scp,enum assign_op op)583 status_e id_parser( pset_h values,
584 struct service_config *scp,
585 enum assign_op op )
586 {
587 const char *func = "id_parser" ;
588
589 SC_ID(scp) = new_string( (char *) pset_pointer( values, 0 ) ) ;
590 if ( SC_ID(scp) != NULL )
591 return( OK ) ;
592 out_of_memory( func ) ;
593 return( FAILED ) ;
594 }
595
596
597
598 #define PORT_BITS 16
599 #define PORT_MAX ( 1 << PORT_BITS )
600
port_parser(pset_h values,struct service_config * scp,enum assign_op op)601 status_e port_parser( pset_h values,
602 struct service_config *scp,
603 enum assign_op op )
604 {
605 int port;
606 const char *func = "port_parser" ;
607
608 if ( parse_base10((char *) pset_pointer( values, 0 ), &port) ||
609 port < 0 || port >= PORT_MAX )
610 {
611 parsemsg( LOG_ERR, func, "port number is invalid" ) ;
612 return( FAILED ) ;
613 }
614 SC_PORT(scp) = (uint16_t)port ;
615 return( OK ) ;
616 }
617
618
add_new_string(pset_h set,char * str)619 static status_e add_new_string( pset_h set, char *str )
620 {
621 char *p = new_string( str ) ;
622 const char *func = "add_new_string" ;
623
624 if ( p == NULL )
625 {
626 parsemsg( LOG_CRIT, func, ES_NOMEM ) ;
627 return( FAILED ) ;
628 }
629 if ( pset_add( set, p ) == NULL )
630 {
631 free( p ) ;
632 parsemsg( LOG_CRIT, func, ES_NOMEM ) ;
633 return( FAILED ) ;
634 }
635 return( OK ) ;
636 }
637
638
env_parser(pset_h values,struct service_config * scp,enum assign_op op)639 status_e env_parser( pset_h values,
640 struct service_config *scp,
641 enum assign_op op )
642 {
643 unsigned u ;
644 const char *func = "env_parser" ;
645
646 if ( op == MINUS_EQ )
647 {
648 parsemsg( LOG_WARNING, func,
649 "operator '-=' not supported for env attribute" ) ;
650 return( FAILED ) ;
651 }
652
653 NEW_SET( SC_ENV_VAR_DEFS(scp), 5, 5 ) ;
654
655 if ( op == SET_EQ && pset_count( SC_ENV_VAR_DEFS(scp) ) != 0 )
656 {
657 pset_apply( SC_ENV_VAR_DEFS(scp), free, NULL ) ;
658 pset_clear( SC_ENV_VAR_DEFS(scp) ) ;
659 }
660
661 for ( u = 0 ; u < pset_count( values ) ; u++ )
662 {
663 char *str = (char *) pset_pointer( values, u ) ;
664
665 /*
666 * Check if the string contains an '='
667 */
668 if ( strchr( str, '=' ) == NULL )
669 {
670 parsemsg( LOG_ERR, func, "%s has no '='", str ) ;
671 return( FAILED ) ;
672 }
673
674 if ( add_new_string( SC_ENV_VAR_DEFS(scp), str ) == FAILED )
675 return( FAILED ) ;
676 }
677 return( OK ) ;
678 }
679
680
passenv_parser(pset_h values,struct service_config * scp,enum assign_op op)681 status_e passenv_parser( pset_h values,
682 struct service_config *scp,
683 enum assign_op op )
684 {
685 pset_h var_set ;
686 unsigned u ;
687 const char *func = "passenv_parser" ;
688
689 NEW_SET( SC_PASS_ENV_VARS(scp), 0, 0 ) ;
690
691 var_set = SC_PASS_ENV_VARS(scp) ;
692
693 if ( op == SET_EQ )
694 {
695 pset_apply( var_set, free, NULL ) ;
696 pset_clear( var_set ) ;
697 op = PLUS_EQ ;
698 }
699
700 for ( u = 0 ; u < pset_count( values ) ; u++ )
701 {
702 char *env_var = (char *) pset_pointer( values, u ) ;
703 unsigned v ;
704 boolean_e found ;
705
706 /*
707 * Check if it is already there
708 */
709 for ( found = NO, v = 0 ; v < pset_count( var_set ) ; v++ )
710 if ( EQ( env_var, (char *) pset_pointer( var_set, v ) ) )
711 {
712 found = YES ;
713 break ;
714 }
715
716 if ( ((op == MINUS_EQ) && (found == NO)) || ((op != MINUS_EQ) && (found == YES)) )
717 continue ;
718
719 if ( op == MINUS_EQ )
720 {
721 free( (char *) pset_pointer( var_set, v ) ) ;
722 pset_remove_index( var_set, v ) ;
723 }
724 else
725 {
726 if ( env_lookup( std_env, env_var ) == CHAR_NULL )
727 {
728 parsemsg( LOG_WARNING, func,
729 "undefined environment variable: %s", env_var ) ;
730 continue ;
731 }
732
733 if ( add_new_string( var_set, env_var ) == FAILED )
734 return( FAILED ) ;
735 }
736 }
737 return( OK ) ;
738 }
739
740
disabled_parser(pset_h values,struct service_config * scp,enum assign_op op)741 status_e disabled_parser( pset_h values,
742 struct service_config *scp,
743 enum assign_op op )
744 {
745 unsigned u ;
746 const char *func = "disabled_parser" ;
747
748 NEW_SET( SC_DISABLED(scp), pset_count( values ), 0 ) ;
749
750 for ( u = 0 ; u < pset_count( values ) ; u++ )
751 {
752 char *name = (char *) pset_pointer( values, u ) ;
753
754 if ( add_new_string( SC_DISABLED(scp), name ) == FAILED )
755 return( FAILED ) ;
756 }
757 return( OK ) ;
758 }
759
760
enabled_parser(pset_h values,struct service_config * scp,enum assign_op op)761 status_e enabled_parser( pset_h values,
762 struct service_config *scp,
763 enum assign_op op )
764 {
765 unsigned u ;
766 const char *func = "enabled_parser" ;
767
768 NEW_SET( SC_ENABLED(scp), pset_count( values ), 0 ) ;
769
770 for ( u = 0 ; u < pset_count( values ) ; u++ )
771 {
772 char *name = (char *) pset_pointer( values, u ) ;
773
774 if ( add_new_string( SC_ENABLED(scp), name ) == FAILED )
775 return( FAILED ) ;
776 }
777 return( OK ) ;
778 }
779
780 /*
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
783 */
get_limit(char * limit_str,rlim_t * res)784 static int get_limit( char *limit_str, rlim_t *res )
785 {
786 unsigned long long limit_int;
787 int multiplier;
788 char *p;
789
790 if (*limit_str == NUL) {
791 *res = 0;
792 return -1;
793 }
794
795 p = limit_str + strlen( limit_str ) - 1;
796 while ( p > limit_str && isspace( *p ) )
797 p--;
798
799 if (*p == 'k' || *p == 'K') {
800 *p = NUL;
801 multiplier = 1024;
802 } else if (*p == 'm' || *p == 'M') {
803 *p = NUL;
804 multiplier = 1024 * 1024;
805 } else
806 multiplier = 1;
807
808 if (parse_ull(limit_str, 10, -1, &limit_int)) {
809 *res = 0;
810 return -1;
811 }
812
813 *res = (rlim_t)limit_int;
814 if (*res != limit_int) {
815 *res = 0;
816 return -1;
817 }
818
819 *res = (rlim_t)limit_int * multiplier;
820 if (*res / multiplier != (rlim_t)limit_int) {
821 *res = 0;
822 return -1;
823 }
824
825 return 0;
826 }
827
828
parse_filelog(struct filelog * flp,pset_h values)829 static status_e parse_filelog( struct filelog *flp, pset_h values )
830 {
831 rlim_t soft_limit ;
832 rlim_t hard_limit ;
833 char *file ;
834 unsigned count = pset_count( values ) ;
835 const char *func = "parse_filelog" ;
836
837 if ( count < 2 || count > 4 )
838 {
839 parsemsg( LOG_ERR, func, "wrong number of arguments" ) ;
840 return( FAILED ) ;
841 }
842
843 file = new_string( (char *) pset_pointer( values, 1 ) ) ;
844 if ( file == NULL )
845 {
846 out_of_memory( func ) ;
847 return( FAILED ) ;
848 }
849
850 /*
851 * Get the limits, if any
852 */
853 if ( count > 2 )
854 {
855 if ( get_limit( (char *) pset_pointer( values, 2 ), &soft_limit ) )
856 {
857 parsemsg( LOG_ERR, func, "soft limit is invalid" ) ;
858 free( file ) ;
859 return( FAILED ) ;
860 }
861
862 /*
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:
866 * hard = soft + x
867 * where
868 * min( 1%soft,LOG_EXTRA_MIN ) <= x <= max( 1%soft,LOG_EXTRA_MAX )
869 */
870 if ( count == 4 )
871 {
872 if ( get_limit( (char *) pset_pointer( values, 3 ), &hard_limit) )
873 {
874 parsemsg( LOG_ERR, func, "hard limit is invalid" ) ;
875 free( file ) ;
876 return( FAILED ) ;
877 }
878 if ( hard_limit < soft_limit )
879 {
880 parsemsg( LOG_ERR, func,
881 "hard limit (%lu) is less than soft limit (%lu)",
882 (unsigned long)hard_limit, (unsigned long)soft_limit ) ;
883 free( file ) ;
884 return( FAILED ) ;
885 }
886 }
887 else
888 {
889 unsigned extra = soft_limit / 100 ; /* 1% of soft limit */
890
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 ;
896 }
897 flp->fl_soft_limit = soft_limit ;
898 flp->fl_hard_limit = hard_limit ;
899 }
900 flp->fl_filename = file ;
901 return( OK ) ;
902 }
903
904
parse_syslog(struct syslog * slp,pset_h values)905 static status_e parse_syslog( struct syslog *slp, pset_h values )
906 {
907 const char *facility ;
908 const char *level ;
909 const struct name_value *nvp ;
910 unsigned count = pset_count( values ) ;
911 const char *func = "parse_syslog" ;
912
913 if ( count < 2 || count > 3 )
914 {
915 parsemsg( LOG_ERR, func, "wrong number of arguments" ) ;
916 return( FAILED ) ;
917 }
918
919 facility = (char *) pset_pointer( values, 1 ) ;
920 if ( ( nvp = nv_find_value( syslog_facilities, facility ) ) == NULL )
921 {
922 parsemsg( LOG_ERR, func, "Unknown syslog facility: %s", facility ) ;
923 return( FAILED ) ;
924 }
925 slp->sl_facility = nvp->value ;
926
927 if ( count == 3 )
928 {
929 level = (char *) pset_pointer( values, 2 ) ;
930 if ( ( nvp = nv_find_value( syslog_levels, level ) ) == NULL )
931 {
932 parsemsg( LOG_ERR, func, "Unknown syslog level: %s", level ) ;
933 return( FAILED ) ;
934 }
935 slp->sl_level = nvp->value ;
936 }
937 else
938 slp->sl_level = DEFAULT_SERVICE_SYSLOG_LEVEL ;
939
940 return( OK ) ;
941 }
942
943
log_type_parser(pset_h values,struct service_config * scp,enum assign_op op)944 status_e log_type_parser( pset_h values,
945 struct service_config *scp,
946 enum assign_op op )
947 {
948 struct log *lp = SC_LOG( scp ) ;
949 char *type ;
950 const char *func = "parse_log_type" ;
951 int count = pset_count( values);
952
953 if ( count == 0 )
954 {
955 missing_attr_msg(func, "log_type");
956 return( FAILED );
957 }
958
959 type = (char *) pset_pointer( values, 0 ) ;
960
961 if ( EQ( type, "FILE" ) )
962 {
963 if ( parse_filelog( LOG_GET_FILELOG( lp ), values ) == FAILED )
964 return( FAILED ) ;
965 lp->l_type = L_FILE ;
966 }
967 else if ( EQ( type, "SYSLOG" ) )
968 {
969 if ( parse_syslog( LOG_GET_SYSLOG( lp ), values ) == FAILED )
970 return( FAILED ) ;
971 lp->l_type = L_SYSLOG ;
972 }
973 else
974 {
975 parsemsg( LOG_ERR, func, "Unknown log type: %s", type ) ;
976 return( FAILED ) ;
977 }
978 return( OK ) ;
979 }
980
981
parse_log_flags(pset_h values,enum assign_op op,mask_t * maskp,const struct name_value options[],const char * name)982 static status_e parse_log_flags( pset_h values,
983 enum assign_op op,
984 mask_t *maskp,
985 const struct name_value options[],
986 const char *name )
987 {
988 if ( op == SET_EQ )
989 {
990 M_CLEAR_ALL( *maskp ) ;
991 op = PLUS_EQ ;
992 }
993
994 return( parse_value_list( values, maskp, options, op, name ) ) ;
995 }
996
997
log_on_success_parser(pset_h values,struct service_config * scp,enum assign_op op)998 status_e log_on_success_parser( pset_h values,
999 struct service_config *scp,
1000 enum assign_op op )
1001 {
1002 return( parse_log_flags( values, op,
1003 &SC_LOG_ON_SUCCESS(scp), success_log_options, "log_on_success flag" ) ) ;
1004 }
1005
1006
log_on_failure_parser(pset_h values,struct service_config * scp,enum assign_op op)1007 status_e log_on_failure_parser( pset_h values,
1008 struct service_config *scp,
1009 enum assign_op op )
1010 {
1011 return( parse_log_flags( values, op,
1012 &SC_LOG_ON_FAILURE(scp), failure_log_options, "log_on_failure flag" ) ) ;
1013 }
1014
1015
parse_inet_addresses(pset_h values,enum assign_op op,pset_h * addr_list)1016 static status_e parse_inet_addresses( pset_h values,
1017 enum assign_op op,
1018 pset_h *addr_list )
1019 {
1020 unsigned u ;
1021 pset_h addr_set ;
1022 statfunc addrlist_func ;
1023 const char *func = "parse_inet_addresses" ;
1024
1025 NEW_SET( *addr_list, 0, 0 );
1026
1027 addr_set = *addr_list;
1028
1029 /*
1030 * If the op was '=' clear the existing list of addresses
1031 */
1032 if ( op == SET_EQ )
1033 {
1034 op = PLUS_EQ ;
1035 addrlist_free( addr_set ) ;
1036 pset_clear( addr_set ) ;
1037 }
1038
1039 addrlist_func = ( op == PLUS_EQ ) ? addrlist_add : addrlist_remove ;
1040
1041 for ( u = 0 ; u < pset_count( values ) ; u++ )
1042 {
1043 register char *str_addr = (char *) pset_pointer( values, u ) ;
1044
1045 /* If it is factorized, allow a comma. Otherwise complain */
1046 if (strchr(str_addr, ',') && !strchr(str_addr, '{'))
1047 {
1048 parsemsg( LOG_ERR, func,
1049 "Address: %s has a comma in it - remove the comma",
1050 str_addr ) ;
1051 return( FAILED );
1052 }
1053
1054 if ( (*addrlist_func)( addr_set, str_addr ) == FAILED )
1055 {
1056 parsemsg( LOG_ERR, func, "Failed adding: %s", str_addr ) ;
1057 return( FAILED );
1058 }
1059 }
1060 return( OK ) ;
1061 }
1062
1063
only_from_parser(pset_h values,struct service_config * scp,enum assign_op op)1064 status_e only_from_parser( pset_h values,
1065 struct service_config *scp,
1066 enum assign_op op )
1067 {
1068 return( parse_inet_addresses( values, op, &SC_ONLY_FROM(scp) ) ) ;
1069 }
1070
1071
no_access_parser(pset_h values,struct service_config * scp,enum assign_op op)1072 status_e no_access_parser( pset_h values,
1073 struct service_config *scp,
1074 enum assign_op op )
1075 {
1076 return( parse_inet_addresses( values, op, &SC_NO_ACCESS(scp) ) ) ;
1077 }
1078
1079
banner_parser(pset_h values,struct service_config * scp,enum assign_op op)1080 status_e banner_parser(pset_h values,
1081 struct service_config *scp,
1082 enum assign_op op)
1083 {
1084 const char *func = "banner_parser";
1085
1086 if( pset_pointer(values, 0) == NULL )
1087 {
1088 msg(LOG_ERR, func, "pset_pointer returned NULL");
1089 return( FAILED );
1090 }
1091
1092 SC_BANNER(scp) = new_string( pset_pointer(values,0) );
1093 if( SC_BANNER(scp) == NULL ) {
1094 msg(LOG_ERR, func, ES_NOMEM);
1095 return( FAILED );
1096 }
1097
1098 return OK;
1099 }
1100
banner_success_parser(pset_h values,struct service_config * scp,enum assign_op op)1101 status_e banner_success_parser(pset_h values,
1102 struct service_config *scp,
1103 enum assign_op op)
1104 {
1105 const char *func = "banner_success_parser";
1106
1107 if( pset_pointer(values, 0) == NULL ) {
1108 msg(LOG_ERR, func, "pset_pointer returned NULL" );
1109 return( FAILED );
1110 }
1111
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);
1115 return( FAILED );
1116 }
1117
1118 return OK;
1119 }
1120
banner_fail_parser(pset_h values,struct service_config * scp,enum assign_op op)1121 status_e banner_fail_parser(pset_h values,
1122 struct service_config *scp,
1123 enum assign_op op)
1124 {
1125 const char *func = "banner_fail_parser";
1126
1127 if( pset_pointer(values, 0) == NULL ) {
1128 msg(LOG_ERR, func, "pset_pointer returned NULL");
1129 return( FAILED );
1130 }
1131
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);
1135 return( FAILED );
1136 }
1137
1138 return OK;
1139 }
1140
1141 #ifdef HAVE_LOADAVG
max_load_parser(pset_h values,struct service_config * scp,enum assign_op op)1142 status_e max_load_parser(pset_h values,
1143 struct service_config *scp,
1144 enum assign_op op)
1145 {
1146 const char *func = "max_load_parser" ;
1147 char *adr = (char *)pset_pointer(values, 0);
1148
1149 if( sscanf(adr, "%lf", &SC_MAX_LOAD(scp)) < 1 ) {
1150 parsemsg(LOG_ERR, func, "error reading max_load argument");
1151 return( FAILED );
1152 }
1153
1154 if( SC_MAX_LOAD(scp) == 0 ) {
1155 parsemsg(LOG_ERR, func, "error parsing max_load argument");
1156 return( FAILED );
1157 }
1158
1159 return OK;
1160 }
1161 #endif
1162
redir_parser(pset_h values,struct service_config * scp,enum assign_op op)1163 status_e redir_parser(pset_h values,
1164 struct service_config *scp,
1165 enum assign_op op)
1166 {
1167 char *adr = (char *)pset_pointer(values, 0);
1168 const char *func = "redir_parser";
1169 char *port_char;
1170 int port_int;
1171 struct addrinfo hints, *res;
1172
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");
1178 if (entry == 0)
1179 {
1180 parsemsg(LOG_ERR, func, "port number invalid");
1181 return FAILED;
1182 }
1183 port_int = ntohs(entry->s_port);
1184 }
1185 if (port_int >= PORT_MAX)
1186 {
1187 parsemsg(LOG_ERR, func, "port number too large");
1188 return FAILED;
1189 }
1190
1191 SC_REDIR_ADDR(scp) = (union xsockaddr *)malloc(sizeof(union xsockaddr));
1192 if( SC_REDIR_ADDR(scp) == NULL )
1193 {
1194 parsemsg(LOG_ERR, func, "can't allocate space for redir addr");
1195 return FAILED;
1196 }
1197
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;
1203 else
1204 hints.ai_family = AF_INET;
1205
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;
1210 return FAILED;
1211 }
1212
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;
1217 return FAILED;
1218 }
1219
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;
1226
1227 freeaddrinfo(res);
1228 return OK;
1229 }
1230
bind_parser(pset_h values,struct service_config * scp,enum assign_op op)1231 status_e bind_parser( pset_h values,
1232 struct service_config *scp,
1233 enum assign_op op)
1234 {
1235 char *adr = (char *)pset_pointer(values, 0);
1236 const char *func = "bind_parser";
1237 struct addrinfo hints, *res, *ressave;
1238 int addr_cnt = 0;
1239
1240 memset(&hints, 0, sizeof(hints));
1241 hints.ai_flags = AI_CANONNAME;
1242
1243 /*
1244 * Use tcp to cut down returned address records. Get addrinfo normally
1245 * returns 2 address records, one for each socket type.
1246 */
1247 hints.ai_socktype = SOCK_STREAM;
1248
1249 if (check_hostname(adr) == 0)
1250 {
1251 hints.ai_family = AF_INET;
1252 hints.ai_flags |= AI_NUMERICHOST;
1253 }
1254 else if (strchr(adr, ':'))
1255 {
1256 hints.ai_family = AF_INET6;
1257 hints.ai_flags |= AI_NUMERICHOST;
1258 }
1259 else
1260 {
1261 hints.ai_family = AF_UNSPEC;
1262 }
1263
1264 if( getaddrinfo(adr, NULL, &hints, &res) < 0 ) {
1265 parsemsg(LOG_ERR, func, "bad address");
1266 return( FAILED );
1267 }
1268
1269 if( (res == NULL) || (res->ai_addr == NULL) ) {
1270 parsemsg(LOG_ERR, func, "no addresses returned");
1271 return( FAILED );
1272 }
1273
1274 /*
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.
1278 */
1279 ressave = res;
1280 while (res)
1281 {
1282 addr_cnt++;
1283 res = res->ai_next;
1284 }
1285 res = ressave;
1286
1287 if (addr_cnt == 1)
1288 {
1289 SC_BIND_ADDR(scp) = (union xsockaddr *)malloc(sizeof(union xsockaddr));
1290 if( SC_BIND_ADDR(scp) == NULL )
1291 {
1292 parsemsg(LOG_ERR, func, "can't allocate space for bind addr");
1293 return( FAILED );
1294 }
1295 memcpy(SC_BIND_ADDR(scp), res->ai_addr, res->ai_addrlen);
1296 }
1297 else
1298 SC_ORIG_BIND_ADDR(scp) = new_string(adr);
1299
1300 freeaddrinfo(res);
1301 return( OK );
1302 }
1303
access_times_parser(pset_h values,struct service_config * scp,enum assign_op op)1304 status_e access_times_parser( pset_h values,
1305 struct service_config *scp,
1306 enum assign_op op )
1307 {
1308 unsigned u, count ;
1309 const char *func = "access_times_parser" ;
1310
1311 NEW_SET( SC_ACCESS_TIMES(scp), 0, 0 ) ;
1312 count = pset_count( values) ;
1313
1314 if ( count == 0 )
1315 {
1316 missing_attr_msg("access_times_parser", "access_times");
1317 return FAILED;
1318 }
1319
1320 for ( u = 0 ; u < count ; u++ )
1321 {
1322 register char *interval = (char *) pset_pointer( values, u ) ;
1323
1324 if ( ti_add( SC_ACCESS_TIMES(scp), interval ) == FAILED )
1325 return FAILED ;
1326 }
1327 return OK ;
1328 }
1329
1330
nice_parser(pset_h values,struct service_config * scp,enum assign_op op)1331 status_e nice_parser( pset_h values,
1332 struct service_config *scp,
1333 enum assign_op op )
1334 {
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 ));
1337 return( FAILED );
1338 }
1339 return( OK ) ;
1340 }
1341
1342 #ifdef RLIMIT_AS
rlim_as_parser(pset_h values,struct service_config * scp,enum assign_op op)1343 status_e rlim_as_parser( pset_h values,
1344 struct service_config *scp,
1345 enum assign_op op )
1346 {
1347 char *mem = (char *) pset_pointer( values, 0 ) ;
1348 const char *func = "rlim_as_parser" ;
1349
1350 if ( EQ( mem, "UNLIMITED" ) )
1351 SC_RLIM_AS(scp) = (rlim_t)RLIM_INFINITY ;
1352 else
1353 {
1354 if ( get_limit ( mem, &SC_RLIM_AS(scp)) )
1355 {
1356 parsemsg( LOG_ERR, func,
1357 "Address space limit is invalid: %s", mem ) ;
1358 return( FAILED ) ;
1359 }
1360 }
1361 return( OK ) ;
1362 }
1363 #endif
1364
1365 #ifdef RLIMIT_CPU
rlim_cpu_parser(pset_h values,struct service_config * scp,enum assign_op op)1366 status_e rlim_cpu_parser( pset_h values,
1367 struct service_config *scp,
1368 enum assign_op op )
1369 {
1370 char *cpu_str = (char *) pset_pointer( values, 0 ) ;
1371 unsigned long long cpu_int;
1372 const char *func = "rlim_cpu_parser" ;
1373
1374 if ( EQ( cpu_str, "UNLIMITED" ) )
1375 SC_RLIM_CPU(scp) = (rlim_t)RLIM_INFINITY ;
1376 else
1377 {
1378 if ( parse_ull(cpu_str, 10, -1, &cpu_int) < 0 )
1379 {
1380 parsemsg( LOG_ERR, func,
1381 "CPU limit is invalid: %s", cpu_str ) ;
1382 return( FAILED ) ;
1383 }
1384 SC_RLIM_CPU(scp) = (rlim_t) cpu_int ;
1385 if ( SC_RLIM_CPU(scp) != cpu_int )
1386 {
1387 parsemsg( LOG_ERR, func, "CPU limit is invalid: %s", cpu_str );
1388 return( FAILED );
1389 }
1390 }
1391 return( OK ) ;
1392 }
1393 #endif
1394
1395 #ifdef RLIMIT_DATA
rlim_data_parser(pset_h values,struct service_config * scp,enum assign_op op)1396 status_e rlim_data_parser( pset_h values,
1397 struct service_config *scp,
1398 enum assign_op op )
1399 {
1400 char *mem = (char *) pset_pointer( values, 0 ) ;
1401 const char *func = "rlim_data_parser" ;
1402
1403 if ( EQ( mem, "UNLIMITED" ) )
1404 SC_RLIM_DATA(scp) = (rlim_t)RLIM_INFINITY ;
1405 else
1406 {
1407 if ( get_limit ( mem, &SC_RLIM_DATA(scp) ) )
1408 {
1409 parsemsg( LOG_ERR, func,
1410 "Data limit is invalid: %s", mem ) ;
1411 return( FAILED ) ;
1412 }
1413 }
1414 return( OK ) ;
1415 }
1416 #endif
1417
1418 #ifdef RLIMIT_RSS
rlim_rss_parser(pset_h values,struct service_config * scp,enum assign_op op)1419 status_e rlim_rss_parser( pset_h values,
1420 struct service_config *scp,
1421 enum assign_op op )
1422 {
1423 char *mem = (char *) pset_pointer( values, 0 ) ;
1424 const char *func = "rlim_rss_parser" ;
1425
1426 if ( EQ( mem, "UNLIMITED" ) )
1427 SC_RLIM_RSS(scp) = (rlim_t)RLIM_INFINITY ;
1428 else
1429 {
1430 if ( get_limit ( mem, &SC_RLIM_RSS(scp) ) )
1431 {
1432 parsemsg( LOG_ERR, func,
1433 "RSS limit is invalid: %s", mem ) ;
1434 return( FAILED ) ;
1435 }
1436 }
1437 return( OK ) ;
1438 }
1439 #endif
1440
1441 #ifdef RLIMIT_STACK
rlim_stack_parser(pset_h values,struct service_config * scp,enum assign_op op)1442 status_e rlim_stack_parser( pset_h values,
1443 struct service_config *scp,
1444 enum assign_op op )
1445 {
1446 char *mem = (char *) pset_pointer( values, 0 ) ;
1447 const char *func = "rlim_stack_parser" ;
1448
1449 if ( EQ( mem, "UNLIMITED" ) )
1450 SC_RLIM_STACK(scp) = (rlim_t)RLIM_INFINITY ;
1451 else
1452 {
1453 if ( get_limit ( mem, &SC_RLIM_STACK(scp) ) )
1454 {
1455 parsemsg( LOG_ERR, func,
1456 "Stack limit is invalid: %s", mem ) ;
1457 return( FAILED ) ;
1458 }
1459 }
1460 return( OK ) ;
1461 }
1462 #endif
1463
deny_time_parser(pset_h values,struct service_config * scp,enum assign_op op)1464 status_e deny_time_parser( pset_h values,
1465 struct service_config *scp,
1466 enum assign_op op )
1467 {
1468 char *deny_time = (char *) pset_pointer( values, 0 ) ;
1469
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);
1476 return( FAILED );
1477 }
1478 return( OK ) ;
1479 }
1480
umask_parser(pset_h values,struct service_config * scp,enum assign_op op)1481 status_e umask_parser( pset_h values,
1482 struct service_config *scp,
1483 enum assign_op op )
1484 {
1485 char *umask_str = (char *)pset_pointer(values, 0);
1486 int umask_int;
1487
1488 if( parse_int(umask_str, 8, -1, &umask_int) ||
1489 umask_int < 0 || umask_int > 0777)
1490 {
1491 parsemsg(LOG_ERR, "umask_parser", "umask argument is invalid.\n");
1492 return( FAILED );
1493 }
1494 SC_UMASK(scp) = umask_int;
1495 return( OK );
1496 }
1497
1498 #ifdef LIBWRAP
libwrap_parser(pset_h values,struct service_config * scp,enum assign_op op)1499 status_e libwrap_parser( pset_h values,
1500 struct service_config *scp,
1501 enum assign_op op )
1502 {
1503 char *libwrap = (char *) pset_pointer( values, 0 ) ;
1504 const char *func = "libwrap_parser" ;
1505
1506 SC_LIBWRAP(scp) = new_string( libwrap ) ;
1507 if ( SC_LIBWRAP(scp) == NULL )
1508 {
1509 out_of_memory( func ) ;
1510 return( FAILED ) ;
1511 }
1512 return( OK ) ;
1513 }
1514 #endif
1515
1516