1 /*****************************************************************************
2 *
3 * CONFIG.C - Configuration input and verification routines for Nagios
4 *
5 * Copyright (c) 1999-2008 Ethan Galstad (egalstad@nagios.org)
6 * Last Modified: 12-14-2008
7 *
8 * License:
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *****************************************************************************/
24
25 #include "../include/config.h"
26 #include "../include/common.h"
27 #include "../include/objects.h"
28 #include "../include/macros.h"
29 #include "../include/nagios.h"
30 #include "../include/broker.h"
31 #include "../include/nebmods.h"
32 #include "../include/nebmodules.h"
33
34
35 extern char *log_file;
36 extern char *command_file;
37 extern char *temp_file;
38 extern char *temp_path;
39 extern char *check_result_path;
40 extern char *lock_file;
41 extern char *log_archive_path;
42 extern char *auth_file;
43 extern char *p1_file;
44
45 extern char *nagios_user;
46 extern char *nagios_group;
47
48 extern char *macro_user[MAX_USER_MACROS];
49
50 extern char *global_host_event_handler;
51 extern char *global_service_event_handler;
52 extern command *global_host_event_handler_ptr;
53 extern command *global_service_event_handler_ptr;
54
55 extern char *ocsp_command;
56 extern char *ochp_command;
57 extern command *ocsp_command_ptr;
58 extern command *ochp_command_ptr;
59
60 extern char *illegal_object_chars;
61 extern char *illegal_output_chars;
62
63 extern int use_regexp_matches;
64 extern int use_true_regexp_matching;
65
66 extern int use_syslog;
67 extern int log_notifications;
68 extern int log_service_retries;
69 extern int log_host_retries;
70 extern int log_event_handlers;
71 extern int log_external_commands;
72 extern int log_passive_checks;
73
74 extern int service_check_timeout;
75 extern int service_check_timeout_state;
76 extern int host_check_timeout;
77 extern int event_handler_timeout;
78 extern int notification_timeout;
79 extern int ocsp_timeout;
80 extern int ochp_timeout;
81
82 extern int log_initial_states;
83
84 extern int daemon_mode;
85 extern int daemon_dumps_core;
86
87 extern int verify_config;
88 extern int verify_object_relationships;
89 extern int verify_circular_paths;
90 extern int test_scheduling;
91 extern int precache_objects;
92 extern int use_precached_objects;
93
94 extern double sleep_time;
95 extern int interval_length;
96 extern int service_inter_check_delay_method;
97 extern int host_inter_check_delay_method;
98 extern int service_interleave_factor_method;
99 extern int max_host_check_spread;
100 extern int max_service_check_spread;
101
102 extern sched_info scheduling_info;
103
104 extern int max_child_process_time;
105
106 extern int max_parallel_service_checks;
107
108 extern int command_check_interval;
109 extern int check_reaper_interval;
110 extern int max_check_reaper_time;
111 extern int service_freshness_check_interval;
112 extern int host_freshness_check_interval;
113 extern int auto_rescheduling_interval;
114 extern int auto_rescheduling_window;
115
116 extern int check_external_commands;
117 extern int check_orphaned_services;
118 extern int check_orphaned_hosts;
119 extern int check_service_freshness;
120 extern int check_host_freshness;
121 extern int auto_reschedule_checks;
122
123 extern int additional_freshness_latency;
124
125 extern int check_for_updates;
126 extern int bare_update_check;
127
128 extern int use_aggressive_host_checking;
129 extern unsigned long cached_host_check_horizon;
130 extern unsigned long cached_service_check_horizon;
131 extern int enable_predictive_host_dependency_checks;
132 extern int enable_predictive_service_dependency_checks;
133
134 extern int soft_state_dependencies;
135
136 extern int retain_state_information;
137 extern int retention_update_interval;
138 extern int use_retained_program_state;
139 extern int use_retained_scheduling_info;
140 extern int retention_scheduling_horizon;
141 extern unsigned long retained_host_attribute_mask;
142 extern unsigned long retained_service_attribute_mask;
143 extern unsigned long retained_contact_host_attribute_mask;
144 extern unsigned long retained_contact_service_attribute_mask;
145 extern unsigned long retained_process_host_attribute_mask;
146 extern unsigned long retained_process_service_attribute_mask;
147
148 extern int log_rotation_method;
149
150 extern int enable_notifications;
151 extern int execute_service_checks;
152 extern int accept_passive_service_checks;
153 extern int execute_host_checks;
154 extern int accept_passive_host_checks;
155 extern int enable_event_handlers;
156 extern int obsess_over_services;
157 extern int obsess_over_hosts;
158 extern int enable_failure_prediction;
159
160 extern int translate_passive_host_checks;
161 extern int passive_host_checks_are_soft;
162
163 extern int aggregate_status_updates;
164 extern int status_update_interval;
165
166 extern int time_change_threshold;
167
168 extern unsigned long event_broker_options;
169
170 extern int process_performance_data;
171
172 extern int enable_flap_detection;
173
174 extern double low_service_flap_threshold;
175 extern double high_service_flap_threshold;
176 extern double low_host_flap_threshold;
177 extern double high_host_flap_threshold;
178
179 extern int use_large_installation_tweaks;
180 extern int enable_environment_macros;
181 extern int free_child_process_memory;
182 extern int child_processes_fork_twice;
183
184 extern int enable_embedded_perl;
185 extern int use_embedded_perl_implicitly;
186
187 extern int date_format;
188 extern char *use_timezone;
189
190 extern contact *contact_list;
191 extern contactgroup *contactgroup_list;
192 extern host *host_list;
193 extern hostgroup *hostgroup_list;
194 extern service *service_list;
195 extern servicegroup *servicegroup_list;
196 extern notification *notification_list;
197 extern command *command_list;
198 extern timeperiod *timeperiod_list;
199 extern serviceescalation *serviceescalation_list;
200 extern servicedependency *servicedependency_list;
201 extern hostdependency *hostdependency_list;
202 extern hostescalation *hostescalation_list;
203
204 extern host **host_hashlist;
205 extern service **service_hashlist;
206
207 extern int external_command_buffer_slots;
208
209 extern unsigned long max_check_result_file_age;
210
211 extern char *debug_file;
212 extern int debug_level;
213 extern int debug_verbosity;
214 extern unsigned long max_debug_file_size;
215
216 extern int allow_empty_hostgroup_assignment;
217
218
219
220 /******************************************************************/
221 /************** CONFIGURATION INPUT FUNCTIONS *********************/
222 /******************************************************************/
223
224 /* read all configuration data */
read_all_object_data(char * main_config_file)225 int read_all_object_data(char *main_config_file) {
226 int result = OK;
227 int options = 0;
228 int cache = FALSE;
229 int precache = FALSE;
230
231 options = READ_ALL_OBJECT_DATA;
232
233 /* cache object definitions if we're up and running */
234 if(verify_config == FALSE && test_scheduling == FALSE)
235 cache = TRUE;
236
237 /* precache object definitions */
238 if(precache_objects == TRUE && (verify_config == TRUE || test_scheduling == TRUE))
239 precache = TRUE;
240
241 /* read in all host configuration data from external sources */
242 result = read_object_config_data(main_config_file, options, cache, precache);
243 if(result != OK)
244 return ERROR;
245
246 return OK;
247 }
248
249
250 /* process the main configuration file */
read_main_config_file(char * main_config_file)251 int read_main_config_file(char *main_config_file) {
252 char *input = NULL;
253 char *variable = NULL;
254 char *value = NULL;
255 char *error_message = NULL;
256 char *temp_ptr = NULL;
257 mmapfile *thefile = NULL;
258 int current_line = 0;
259 int error = FALSE;
260 int command_check_interval_is_seconds = FALSE;
261 char *modptr = NULL;
262 char *argptr = NULL;
263 DIR *tmpdir = NULL;
264 nagios_macros *mac;
265
266 mac = get_global_macros();
267
268
269 /* open the config file for reading */
270 if((thefile = mmap_fopen(main_config_file)) == NULL) {
271 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Cannot open main configuration file '%s' for reading!", main_config_file);
272 return ERROR;
273 }
274
275 /* save the main config file macro */
276 my_free(mac->x[MACRO_MAINCONFIGFILE]);
277 if((mac->x[MACRO_MAINCONFIGFILE] = (char *)strdup(main_config_file)))
278 strip(mac->x[MACRO_MAINCONFIGFILE]);
279
280 /* process all lines in the config file */
281 while(1) {
282
283 /* free memory */
284 my_free(input);
285 my_free(variable);
286 my_free(value);
287
288 /* read the next line */
289 if((input = mmap_fgets_multiline(thefile)) == NULL)
290 break;
291
292 current_line = thefile->current_line;
293
294 strip(input);
295
296 /* skip blank lines and comments */
297 if(input[0] == '\x0' || input[0] == '#')
298 continue;
299
300 /* get the variable name */
301 if((temp_ptr = my_strtok(input, "=")) == NULL) {
302 asprintf(&error_message, "NULL variable");
303 error = TRUE;
304 break;
305 }
306 if((variable = (char *)strdup(temp_ptr)) == NULL) {
307 asprintf(&error_message, "malloc() error");
308 error = TRUE;
309 break;
310 }
311
312 /* get the value */
313 if((temp_ptr = my_strtok(NULL, "\n")) == NULL) {
314 asprintf(&error_message, "NULL value");
315 error = TRUE;
316 break;
317 }
318 if((value = (char *)strdup(temp_ptr)) == NULL) {
319 asprintf(&error_message, "malloc() error");
320 error = TRUE;
321 break;
322 }
323 strip(variable);
324 strip(value);
325
326 /* process the variable/value */
327
328 if(!strcmp(variable, "resource_file")) {
329
330 /* save the macro */
331 my_free(mac->x[MACRO_RESOURCEFILE]);
332 mac->x[MACRO_RESOURCEFILE] = (char *)strdup(value);
333
334 /* process the resource file */
335 read_resource_file(value);
336 }
337
338 else if(!strcmp(variable, "log_file")) {
339
340 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
341 asprintf(&error_message, "Log file is too long");
342 error = TRUE;
343 break;
344 }
345
346 my_free(log_file);
347 log_file = (char *)strdup(value);
348
349 /* save the macro */
350 my_free(mac->x[MACRO_LOGFILE]);
351 mac->x[MACRO_LOGFILE] = (char *)strdup(log_file);
352 }
353
354 else if(!strcmp(variable, "debug_level"))
355 debug_level = atoi(value);
356
357 else if(!strcmp(variable, "debug_verbosity"))
358 debug_verbosity = atoi(value);
359
360 else if(!strcmp(variable, "debug_file")) {
361
362 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
363 asprintf(&error_message, "Debug log file is too long");
364 error = TRUE;
365 break;
366 }
367
368 my_free(debug_file);
369 debug_file = (char *)strdup(value);
370 }
371
372 else if(!strcmp(variable, "max_debug_file_size"))
373 max_debug_file_size = strtoul(value, NULL, 0);
374
375 else if(!strcmp(variable, "command_file")) {
376
377 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
378 asprintf(&error_message, "Command file is too long");
379 error = TRUE;
380 break;
381 }
382
383 my_free(command_file);
384 command_file = (char *)strdup(value);
385
386 /* save the macro */
387 my_free(mac->x[MACRO_COMMANDFILE]);
388 mac->x[MACRO_COMMANDFILE] = (char *)strdup(value);
389 }
390
391 else if(!strcmp(variable, "temp_file")) {
392
393 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
394 asprintf(&error_message, "Temp file is too long");
395 error = TRUE;
396 break;
397 }
398
399 my_free(temp_file);
400 temp_file = (char *)strdup(value);
401
402 /* save the macro */
403 my_free(mac->x[MACRO_TEMPFILE]);
404 mac->x[MACRO_TEMPFILE] = (char *)strdup(temp_file);
405 }
406
407 else if(!strcmp(variable, "temp_path")) {
408
409 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
410 asprintf(&error_message, "Temp path is too long");
411 error = TRUE;
412 break;
413 }
414
415 if((tmpdir = opendir((char *)value)) == NULL) {
416 asprintf(&error_message, "Temp path is not a valid directory");
417 error = TRUE;
418 break;
419 }
420 closedir(tmpdir);
421
422 my_free(temp_path);
423 if((temp_path = (char *)strdup(value))) {
424 strip(temp_path);
425 /* make sure we don't have a trailing slash */
426 if(temp_path[strlen(temp_path) - 1] == '/')
427 temp_path[strlen(temp_path) - 1] = '\x0';
428 }
429
430 /* save the macro */
431 my_free(mac->x[MACRO_TEMPPATH]);
432 mac->x[MACRO_TEMPPATH] = (char *)strdup(temp_path);
433 }
434
435 else if(!strcmp(variable, "check_result_path")) {
436
437 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
438 asprintf(&error_message, "Check result path is too long");
439 error = TRUE;
440 break;
441 }
442
443 if((tmpdir = opendir((char *)value)) == NULL) {
444 asprintf(&error_message, "Check result path is not a valid directory");
445 error = TRUE;
446 break;
447 }
448 closedir(tmpdir);
449
450 my_free(temp_path);
451 if((temp_path = (char *)strdup(value))) {
452 strip(temp_path);
453 /* make sure we don't have a trailing slash */
454 if(temp_path[strlen(temp_path) - 1] == '/')
455 temp_path[strlen(temp_path) - 1] = '\x0';
456 }
457
458 my_free(check_result_path);
459 check_result_path = (char *)strdup(temp_path);
460 }
461
462 else if(!strcmp(variable, "max_check_result_file_age"))
463 max_check_result_file_age = strtoul(value, NULL, 0);
464
465 else if(!strcmp(variable, "lock_file")) {
466
467 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
468 asprintf(&error_message, "Lock file is too long");
469 error = TRUE;
470 break;
471 }
472
473 my_free(lock_file);
474 lock_file = (char *)strdup(value);
475 }
476
477 else if(!strcmp(variable, "global_host_event_handler")) {
478 my_free(global_host_event_handler);
479 global_host_event_handler = (char *)strdup(value);
480 }
481
482 else if(!strcmp(variable, "global_service_event_handler")) {
483 my_free(global_service_event_handler);
484 global_service_event_handler = (char *)strdup(value);
485 }
486
487 else if(!strcmp(variable, "ocsp_command")) {
488 my_free(ocsp_command);
489 ocsp_command = (char *)strdup(value);
490 }
491
492 else if(!strcmp(variable, "ochp_command")) {
493 my_free(ochp_command);
494 ochp_command = (char *)strdup(value);
495 }
496
497 else if(!strcmp(variable, "nagios_user")) {
498 my_free(nagios_user);
499 nagios_user = (char *)strdup(value);
500 }
501
502 else if(!strcmp(variable, "nagios_group")) {
503 my_free(nagios_group);
504 nagios_group = (char *)strdup(value);
505 }
506
507 else if(!strcmp(variable, "admin_email")) {
508
509 /* save the macro */
510 my_free(mac->x[MACRO_ADMINEMAIL]);
511 mac->x[MACRO_ADMINEMAIL] = (char *)strdup(value);
512 }
513
514 else if(!strcmp(variable, "admin_pager")) {
515
516 /* save the macro */
517 my_free(mac->x[MACRO_ADMINPAGER]);
518 mac->x[MACRO_ADMINPAGER] = (char *)strdup(value);
519 }
520
521 else if(!strcmp(variable, "use_syslog")) {
522
523 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
524 asprintf(&error_message, "Illegal value for use_syslog");
525 error = TRUE;
526 break;
527 }
528
529 use_syslog = (atoi(value) > 0) ? TRUE : FALSE;
530 }
531
532 else if(!strcmp(variable, "log_notifications")) {
533
534 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
535 asprintf(&error_message, "Illegal value for log_notifications");
536 error = TRUE;
537 break;
538 }
539
540 log_notifications = (atoi(value) > 0) ? TRUE : FALSE;
541 }
542
543 else if(!strcmp(variable, "log_service_retries")) {
544
545 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
546 asprintf(&error_message, "Illegal value for log_service_retries");
547 error = TRUE;
548 break;
549 }
550
551 log_service_retries = (atoi(value) > 0) ? TRUE : FALSE;
552 }
553
554 else if(!strcmp(variable, "log_host_retries")) {
555
556 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
557 asprintf(&error_message, "Illegal value for log_host_retries");
558 error = TRUE;
559 break;
560 }
561
562 log_host_retries = (atoi(value) > 0) ? TRUE : FALSE;
563 }
564
565 else if(!strcmp(variable, "log_event_handlers")) {
566
567 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
568 asprintf(&error_message, "Illegal value for log_event_handlers");
569 error = TRUE;
570 break;
571 }
572
573 log_event_handlers = (atoi(value) > 0) ? TRUE : FALSE;
574 }
575
576 else if(!strcmp(variable, "log_external_commands")) {
577
578 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
579 asprintf(&error_message, "Illegal value for log_external_commands");
580 error = TRUE;
581 break;
582 }
583
584 log_external_commands = (atoi(value) > 0) ? TRUE : FALSE;
585 }
586
587 else if(!strcmp(variable, "log_passive_checks")) {
588
589 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
590 asprintf(&error_message, "Illegal value for log_passive_checks");
591 error = TRUE;
592 break;
593 }
594
595 log_passive_checks = (atoi(value) > 0) ? TRUE : FALSE;
596 }
597
598 else if(!strcmp(variable, "log_initial_states")) {
599
600 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
601 asprintf(&error_message, "Illegal value for log_initial_states");
602 error = TRUE;
603 break;
604 }
605
606 log_initial_states = (atoi(value) > 0) ? TRUE : FALSE;
607 }
608
609 else if(!strcmp(variable, "retain_state_information")) {
610
611 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
612 asprintf(&error_message, "Illegal value for retain_state_information");
613 error = TRUE;
614 break;
615 }
616
617 retain_state_information = (atoi(value) > 0) ? TRUE : FALSE;
618 }
619
620 else if(!strcmp(variable, "retention_update_interval")) {
621
622 retention_update_interval = atoi(value);
623 if(retention_update_interval < 0) {
624 asprintf(&error_message, "Illegal value for retention_update_interval");
625 error = TRUE;
626 break;
627 }
628 }
629
630 else if(!strcmp(variable, "use_retained_program_state")) {
631
632 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
633 asprintf(&error_message, "Illegal value for use_retained_program_state");
634 error = TRUE;
635 break;
636 }
637
638 use_retained_program_state = (atoi(value) > 0) ? TRUE : FALSE;
639 }
640
641 else if(!strcmp(variable, "use_retained_scheduling_info")) {
642
643 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
644 asprintf(&error_message, "Illegal value for use_retained_scheduling_info");
645 error = TRUE;
646 break;
647 }
648
649 use_retained_scheduling_info = (atoi(value) > 0) ? TRUE : FALSE;
650 }
651
652 else if(!strcmp(variable, "retention_scheduling_horizon")) {
653
654 retention_scheduling_horizon = atoi(value);
655
656 if(retention_scheduling_horizon <= 0) {
657 asprintf(&error_message, "Illegal value for retention_scheduling_horizon");
658 error = TRUE;
659 break;
660 }
661 }
662
663 else if(!strcmp(variable, "additional_freshness_latency"))
664 additional_freshness_latency = atoi(value);
665
666 else if(!strcmp(variable, "retained_host_attribute_mask"))
667 retained_host_attribute_mask = strtoul(value, NULL, 0);
668
669 else if(!strcmp(variable, "retained_service_attribute_mask"))
670 retained_service_attribute_mask = strtoul(value, NULL, 0);
671
672 else if(!strcmp(variable, "retained_process_host_attribute_mask"))
673 retained_process_host_attribute_mask = strtoul(value, NULL, 0);
674
675 else if(!strcmp(variable, "retained_process_service_attribute_mask"))
676 retained_process_service_attribute_mask = strtoul(value, NULL, 0);
677
678 else if(!strcmp(variable, "retained_contact_host_attribute_mask"))
679 retained_contact_host_attribute_mask = strtoul(value, NULL, 0);
680
681 else if(!strcmp(variable, "retained_contact_service_attribute_mask"))
682 retained_contact_service_attribute_mask = strtoul(value, NULL, 0);
683
684 else if(!strcmp(variable, "obsess_over_services")) {
685
686 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
687 asprintf(&error_message, "Illegal value for obsess_over_services");
688 error = TRUE;
689 break;
690 }
691
692 obsess_over_services = (atoi(value) > 0) ? TRUE : FALSE;
693 }
694
695 else if(!strcmp(variable, "obsess_over_hosts")) {
696
697 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
698 asprintf(&error_message, "Illegal value for obsess_over_hosts");
699 error = TRUE;
700 break;
701 }
702
703 obsess_over_hosts = (atoi(value) > 0) ? TRUE : FALSE;
704 }
705
706 else if(!strcmp(variable, "translate_passive_host_checks")) {
707
708 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
709 asprintf(&error_message, "Illegal value for translate_passive_host_checks");
710 error = TRUE;
711 break;
712 }
713
714 translate_passive_host_checks = (atoi(value) > 0) ? TRUE : FALSE;
715 }
716
717 else if(!strcmp(variable, "passive_host_checks_are_soft"))
718 passive_host_checks_are_soft = (atoi(value) > 0) ? TRUE : FALSE;
719
720 else if(!strcmp(variable, "service_check_timeout")) {
721
722 service_check_timeout = atoi(value);
723
724 if(service_check_timeout <= 0) {
725 asprintf(&error_message, "Illegal value for service_check_timeout");
726 error = TRUE;
727 break;
728 }
729 }
730
731
732 else if(!strcmp(variable, "service_check_timeout_state")) {
733
734 if(!strcmp(value, "o"))
735 service_check_timeout_state = STATE_OK;
736 else if(!strcmp(value, "w"))
737 service_check_timeout_state = STATE_WARNING;
738 else if(!strcmp(value, "c"))
739 service_check_timeout_state = STATE_CRITICAL;
740 else if(!strcmp(value, "u"))
741 service_check_timeout_state = STATE_UNKNOWN;
742 else {
743 asprintf(&error_message, "Illegal value for service_check_timeout_state");
744 error = TRUE;
745 break;
746 }
747 }
748
749 else if(!strcmp(variable, "host_check_timeout")) {
750
751 host_check_timeout = atoi(value);
752
753 if(host_check_timeout <= 0) {
754 asprintf(&error_message, "Illegal value for host_check_timeout");
755 error = TRUE;
756 break;
757 }
758 }
759
760 else if(!strcmp(variable, "event_handler_timeout")) {
761
762 event_handler_timeout = atoi(value);
763
764 if(event_handler_timeout <= 0) {
765 asprintf(&error_message, "Illegal value for event_handler_timeout");
766 error = TRUE;
767 break;
768 }
769 }
770
771 else if(!strcmp(variable, "notification_timeout")) {
772
773 notification_timeout = atoi(value);
774
775 if(notification_timeout <= 0) {
776 asprintf(&error_message, "Illegal value for notification_timeout");
777 error = TRUE;
778 break;
779 }
780 }
781
782 else if(!strcmp(variable, "ocsp_timeout")) {
783
784 ocsp_timeout = atoi(value);
785
786 if(ocsp_timeout <= 0) {
787 asprintf(&error_message, "Illegal value for ocsp_timeout");
788 error = TRUE;
789 break;
790 }
791 }
792
793 else if(!strcmp(variable, "ochp_timeout")) {
794
795 ochp_timeout = atoi(value);
796
797 if(ochp_timeout <= 0) {
798 asprintf(&error_message, "Illegal value for ochp_timeout");
799 error = TRUE;
800 break;
801 }
802 }
803
804 else if(!strcmp(variable, "use_agressive_host_checking") || !strcmp(variable, "use_aggressive_host_checking")) {
805
806 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
807 asprintf(&error_message, "Illegal value for use_aggressive_host_checking");
808 error = TRUE;
809 break;
810 }
811
812 use_aggressive_host_checking = (atoi(value) > 0) ? TRUE : FALSE;
813 }
814
815 else if(!strcmp(variable, "cached_host_check_horizon"))
816 cached_host_check_horizon = strtoul(value, NULL, 0);
817
818 else if(!strcmp(variable, "enable_predictive_host_dependency_checks"))
819 enable_predictive_host_dependency_checks = (atoi(value) > 0) ? TRUE : FALSE;
820
821 else if(!strcmp(variable, "cached_service_check_horizon"))
822 cached_service_check_horizon = strtoul(value, NULL, 0);
823
824 else if(!strcmp(variable, "enable_predictive_service_dependency_checks"))
825 enable_predictive_service_dependency_checks = (atoi(value) > 0) ? TRUE : FALSE;
826
827 else if(!strcmp(variable, "soft_state_dependencies")) {
828 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
829 asprintf(&error_message, "Illegal value for soft_state_dependencies");
830 error = TRUE;
831 break;
832 }
833
834 soft_state_dependencies = (atoi(value) > 0) ? TRUE : FALSE;
835 }
836
837 else if(!strcmp(variable, "log_rotation_method")) {
838 if(!strcmp(value, "n"))
839 log_rotation_method = LOG_ROTATION_NONE;
840 else if(!strcmp(value, "h"))
841 log_rotation_method = LOG_ROTATION_HOURLY;
842 else if(!strcmp(value, "d"))
843 log_rotation_method = LOG_ROTATION_DAILY;
844 else if(!strcmp(value, "w"))
845 log_rotation_method = LOG_ROTATION_WEEKLY;
846 else if(!strcmp(value, "m"))
847 log_rotation_method = LOG_ROTATION_MONTHLY;
848 else {
849 asprintf(&error_message, "Illegal value for log_rotation_method");
850 error = TRUE;
851 break;
852 }
853 }
854
855 else if(!strcmp(variable, "log_archive_path")) {
856
857 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
858 asprintf(&error_message, "Log archive path too long");
859 error = TRUE;
860 break;
861 }
862
863 my_free(log_archive_path);
864 log_archive_path = (char *)strdup(value);
865 }
866
867 else if(!strcmp(variable, "enable_event_handlers"))
868 enable_event_handlers = (atoi(value) > 0) ? TRUE : FALSE;
869
870 else if(!strcmp(variable, "enable_notifications"))
871 enable_notifications = (atoi(value) > 0) ? TRUE : FALSE;
872
873 else if(!strcmp(variable, "execute_service_checks"))
874 execute_service_checks = (atoi(value) > 0) ? TRUE : FALSE;
875
876 else if(!strcmp(variable, "accept_passive_service_checks"))
877 accept_passive_service_checks = (atoi(value) > 0) ? TRUE : FALSE;
878
879 else if(!strcmp(variable, "execute_host_checks"))
880 execute_host_checks = (atoi(value) > 0) ? TRUE : FALSE;
881
882 else if(!strcmp(variable, "accept_passive_host_checks"))
883 accept_passive_host_checks = (atoi(value) > 0) ? TRUE : FALSE;
884
885 else if(!strcmp(variable, "service_inter_check_delay_method")) {
886 if(!strcmp(value, "n"))
887 service_inter_check_delay_method = ICD_NONE;
888 else if(!strcmp(value, "d"))
889 service_inter_check_delay_method = ICD_DUMB;
890 else if(!strcmp(value, "s"))
891 service_inter_check_delay_method = ICD_SMART;
892 else {
893 service_inter_check_delay_method = ICD_USER;
894 scheduling_info.service_inter_check_delay = strtod(value, NULL);
895 if(scheduling_info.service_inter_check_delay <= 0.0) {
896 asprintf(&error_message, "Illegal value for service_inter_check_delay_method");
897 error = TRUE;
898 break;
899 }
900 }
901 }
902
903 else if(!strcmp(variable, "max_service_check_spread")) {
904 strip(value);
905 max_service_check_spread = atoi(value);
906 if(max_service_check_spread < 1) {
907 asprintf(&error_message, "Illegal value for max_service_check_spread");
908 error = TRUE;
909 break;
910 }
911 }
912
913 else if(!strcmp(variable, "host_inter_check_delay_method")) {
914
915 if(!strcmp(value, "n"))
916 host_inter_check_delay_method = ICD_NONE;
917 else if(!strcmp(value, "d"))
918 host_inter_check_delay_method = ICD_DUMB;
919 else if(!strcmp(value, "s"))
920 host_inter_check_delay_method = ICD_SMART;
921 else {
922 host_inter_check_delay_method = ICD_USER;
923 scheduling_info.host_inter_check_delay = strtod(value, NULL);
924 if(scheduling_info.host_inter_check_delay <= 0.0) {
925 asprintf(&error_message, "Illegal value for host_inter_check_delay_method");
926 error = TRUE;
927 break;
928 }
929 }
930 }
931
932 else if(!strcmp(variable, "max_host_check_spread")) {
933
934 max_host_check_spread = atoi(value);
935 if(max_host_check_spread < 1) {
936 asprintf(&error_message, "Illegal value for max_host_check_spread");
937 error = TRUE;
938 break;
939 }
940 }
941
942 else if(!strcmp(variable, "service_interleave_factor")) {
943 if(!strcmp(value, "s"))
944 service_interleave_factor_method = ILF_SMART;
945 else {
946 service_interleave_factor_method = ILF_USER;
947 scheduling_info.service_interleave_factor = atoi(value);
948 if(scheduling_info.service_interleave_factor < 1)
949 scheduling_info.service_interleave_factor = 1;
950 }
951 }
952
953 else if(!strcmp(variable, "max_concurrent_checks")) {
954
955 max_parallel_service_checks = atoi(value);
956 if(max_parallel_service_checks < 0) {
957 asprintf(&error_message, "Illegal value for max_concurrent_checks");
958 error = TRUE;
959 break;
960 }
961 }
962
963 else if(!strcmp(variable, "check_result_reaper_frequency") || !strcmp(variable, "service_reaper_frequency")) {
964
965 check_reaper_interval = atoi(value);
966 if(check_reaper_interval < 1) {
967 asprintf(&error_message, "Illegal value for check_result_reaper_frequency");
968 error = TRUE;
969 break;
970 }
971 }
972
973 else if(!strcmp(variable, "max_check_result_reaper_time")) {
974
975 max_check_reaper_time = atoi(value);
976 if(max_check_reaper_time < 1) {
977 asprintf(&error_message, "Illegal value for max_check_result_reaper_time");
978 error = TRUE;
979 break;
980 }
981 }
982
983 else if(!strcmp(variable, "sleep_time")) {
984
985 sleep_time = atof(value);
986 if(sleep_time <= 0.0) {
987 asprintf(&error_message, "Illegal value for sleep_time");
988 error = TRUE;
989 break;
990 }
991 }
992
993 else if(!strcmp(variable, "interval_length")) {
994
995 interval_length = atoi(value);
996 if(interval_length < 1) {
997 asprintf(&error_message, "Illegal value for interval_length");
998 error = TRUE;
999 break;
1000 }
1001 }
1002
1003 else if(!strcmp(variable, "check_external_commands")) {
1004
1005 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1006 asprintf(&error_message, "Illegal value for check_external_commands");
1007 error = TRUE;
1008 break;
1009 }
1010
1011 check_external_commands = (atoi(value) > 0) ? TRUE : FALSE;
1012 }
1013
1014 else if(!strcmp(variable, "command_check_interval")) {
1015
1016 command_check_interval_is_seconds = (strstr(value, "s")) ? TRUE : FALSE;
1017 command_check_interval = atoi(value);
1018 if(command_check_interval < -1 || command_check_interval == 0) {
1019 asprintf(&error_message, "Illegal value for command_check_interval");
1020 error = TRUE;
1021 break;
1022 }
1023 }
1024
1025 else if(!strcmp(variable, "check_for_orphaned_services")) {
1026
1027 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1028 asprintf(&error_message, "Illegal value for check_for_orphaned_services");
1029 error = TRUE;
1030 break;
1031 }
1032
1033 check_orphaned_services = (atoi(value) > 0) ? TRUE : FALSE;
1034 }
1035
1036 else if(!strcmp(variable, "check_for_orphaned_hosts")) {
1037
1038 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1039 asprintf(&error_message, "Illegal value for check_for_orphaned_hosts");
1040 error = TRUE;
1041 break;
1042 }
1043
1044 check_orphaned_hosts = (atoi(value) > 0) ? TRUE : FALSE;
1045 }
1046
1047 else if(!strcmp(variable, "check_service_freshness")) {
1048
1049 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1050 asprintf(&error_message, "Illegal value for check_service_freshness");
1051 error = TRUE;
1052 break;
1053 }
1054
1055 check_service_freshness = (atoi(value) > 0) ? TRUE : FALSE;
1056 }
1057
1058 else if(!strcmp(variable, "check_host_freshness")) {
1059
1060 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1061 asprintf(&error_message, "Illegal value for check_host_freshness");
1062 error = TRUE;
1063 break;
1064 }
1065
1066 check_host_freshness = (atoi(value) > 0) ? TRUE : FALSE;
1067 }
1068
1069 else if(!strcmp(variable, "service_freshness_check_interval") || !strcmp(variable, "freshness_check_interval")) {
1070
1071 service_freshness_check_interval = atoi(value);
1072 if(service_freshness_check_interval <= 0) {
1073 asprintf(&error_message, "Illegal value for service_freshness_check_interval");
1074 error = TRUE;
1075 break;
1076 }
1077 }
1078
1079 else if(!strcmp(variable, "host_freshness_check_interval")) {
1080
1081 host_freshness_check_interval = atoi(value);
1082 if(host_freshness_check_interval <= 0) {
1083 asprintf(&error_message, "Illegal value for host_freshness_check_interval");
1084 error = TRUE;
1085 break;
1086 }
1087 }
1088 else if(!strcmp(variable, "auto_reschedule_checks")) {
1089
1090 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1091 asprintf(&error_message, "Illegal value for auto_reschedule_checks");
1092 error = TRUE;
1093 break;
1094 }
1095
1096 auto_reschedule_checks = (atoi(value) > 0) ? TRUE : FALSE;
1097 }
1098
1099 else if(!strcmp(variable, "auto_rescheduling_interval")) {
1100
1101 auto_rescheduling_interval = atoi(value);
1102 if(auto_rescheduling_interval <= 0) {
1103 asprintf(&error_message, "Illegal value for auto_rescheduling_interval");
1104 error = TRUE;
1105 break;
1106 }
1107 }
1108
1109 else if(!strcmp(variable, "auto_rescheduling_window")) {
1110
1111 auto_rescheduling_window = atoi(value);
1112 if(auto_rescheduling_window <= 0) {
1113 asprintf(&error_message, "Illegal value for auto_rescheduling_window");
1114 error = TRUE;
1115 break;
1116 }
1117 }
1118
1119 else if(!strcmp(variable, "aggregate_status_updates")) {
1120
1121 /* DEPRECATED - ALL UPDATED ARE AGGREGATED AS OF NAGIOS 3.X */
1122 /*aggregate_status_updates=(atoi(value)>0)?TRUE:FALSE;*/
1123
1124 logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: aggregate_status_updates directive ignored. All status file updates are now aggregated.");
1125 }
1126
1127 else if(!strcmp(variable, "status_update_interval")) {
1128
1129 status_update_interval = atoi(value);
1130 if(status_update_interval <= 1) {
1131 asprintf(&error_message, "Illegal value for status_update_interval");
1132 error = TRUE;
1133 break;
1134 }
1135 }
1136
1137 else if(!strcmp(variable, "time_change_threshold")) {
1138
1139 time_change_threshold = atoi(value);
1140
1141 if(time_change_threshold <= 5) {
1142 asprintf(&error_message, "Illegal value for time_change_threshold");
1143 error = TRUE;
1144 break;
1145 }
1146 }
1147
1148 else if(!strcmp(variable, "process_performance_data"))
1149 process_performance_data = (atoi(value) > 0) ? TRUE : FALSE;
1150
1151 else if(!strcmp(variable, "enable_flap_detection"))
1152 enable_flap_detection = (atoi(value) > 0) ? TRUE : FALSE;
1153
1154 else if(!strcmp(variable, "enable_failure_prediction"))
1155 enable_failure_prediction = (atoi(value) > 0) ? TRUE : FALSE;
1156
1157 else if(!strcmp(variable, "low_service_flap_threshold")) {
1158
1159 low_service_flap_threshold = strtod(value, NULL);
1160 if(low_service_flap_threshold <= 0.0 || low_service_flap_threshold >= 100.0) {
1161 asprintf(&error_message, "Illegal value for low_service_flap_threshold");
1162 error = TRUE;
1163 break;
1164 }
1165 }
1166
1167 else if(!strcmp(variable, "high_service_flap_threshold")) {
1168
1169 high_service_flap_threshold = strtod(value, NULL);
1170 if(high_service_flap_threshold <= 0.0 || high_service_flap_threshold > 100.0) {
1171 asprintf(&error_message, "Illegal value for high_service_flap_threshold");
1172 error = TRUE;
1173 break;
1174 }
1175 }
1176
1177 else if(!strcmp(variable, "low_host_flap_threshold")) {
1178
1179 low_host_flap_threshold = strtod(value, NULL);
1180 if(low_host_flap_threshold <= 0.0 || low_host_flap_threshold >= 100.0) {
1181 asprintf(&error_message, "Illegal value for low_host_flap_threshold");
1182 error = TRUE;
1183 break;
1184 }
1185 }
1186
1187 else if(!strcmp(variable, "high_host_flap_threshold")) {
1188
1189 high_host_flap_threshold = strtod(value, NULL);
1190 if(high_host_flap_threshold <= 0.0 || high_host_flap_threshold > 100.0) {
1191 asprintf(&error_message, "Illegal value for high_host_flap_threshold");
1192 error = TRUE;
1193 break;
1194 }
1195 }
1196
1197 else if(!strcmp(variable, "date_format")) {
1198
1199 if(!strcmp(value, "euro"))
1200 date_format = DATE_FORMAT_EURO;
1201 else if(!strcmp(value, "iso8601"))
1202 date_format = DATE_FORMAT_ISO8601;
1203 else if(!strcmp(value, "strict-iso8601"))
1204 date_format = DATE_FORMAT_STRICT_ISO8601;
1205 else
1206 date_format = DATE_FORMAT_US;
1207 }
1208
1209 else if(!strcmp(variable, "use_timezone")) {
1210 my_free(use_timezone);
1211 use_timezone = (char *)strdup(value);
1212 }
1213
1214 else if(!strcmp(variable, "p1_file")) {
1215
1216 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
1217 asprintf(&error_message, "P1 file is too long");
1218 error = TRUE;
1219 break;
1220 }
1221
1222 my_free(p1_file);
1223 p1_file = (char *)strdup(value);
1224 }
1225
1226 else if(!strcmp(variable, "event_broker_options")) {
1227
1228 if(!strcmp(value, "-1"))
1229 event_broker_options = BROKER_EVERYTHING;
1230 else
1231 event_broker_options = strtoul(value, NULL, 0);
1232 }
1233
1234 else if(!strcmp(variable, "illegal_object_name_chars"))
1235 illegal_object_chars = (char *)strdup(value);
1236
1237 else if(!strcmp(variable, "illegal_macro_output_chars"))
1238 illegal_output_chars = (char *)strdup(value);
1239
1240
1241 else if(!strcmp(variable, "broker_module")) {
1242 modptr = strtok(value, " \n");
1243 argptr = strtok(NULL, "\n");
1244 #ifdef USE_EVENT_BROKER
1245 neb_add_module(modptr, argptr, TRUE);
1246 #endif
1247 }
1248
1249 else if(!strcmp(variable, "use_regexp_matching"))
1250 use_regexp_matches = (atoi(value) > 0) ? TRUE : FALSE;
1251
1252 else if(!strcmp(variable, "use_true_regexp_matching"))
1253 use_true_regexp_matching = (atoi(value) > 0) ? TRUE : FALSE;
1254
1255 else if(!strcmp(variable, "daemon_dumps_core")) {
1256
1257 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1258 asprintf(&error_message, "Illegal value for daemon_dumps_core");
1259 error = TRUE;
1260 break;
1261 }
1262
1263 daemon_dumps_core = (atoi(value) > 0) ? TRUE : FALSE;
1264 }
1265
1266 else if(!strcmp(variable, "use_large_installation_tweaks")) {
1267
1268 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1269 asprintf(&error_message, "Illegal value for use_large_installation_tweaks ");
1270 error = TRUE;
1271 break;
1272 }
1273
1274 use_large_installation_tweaks = (atoi(value) > 0) ? TRUE : FALSE;
1275 }
1276
1277 else if(!strcmp(variable, "enable_environment_macros"))
1278 enable_environment_macros = (atoi(value) > 0) ? TRUE : FALSE;
1279
1280 else if(!strcmp(variable, "free_child_process_memory"))
1281 free_child_process_memory = (atoi(value) > 0) ? TRUE : FALSE;
1282
1283 else if(!strcmp(variable, "child_processes_fork_twice"))
1284 child_processes_fork_twice = (atoi(value) > 0) ? TRUE : FALSE;
1285
1286 else if(!strcmp(variable, "enable_embedded_perl")) {
1287
1288 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1289 asprintf(&error_message, "Illegal value for enable_embedded_perl");
1290 error = TRUE;
1291 break;
1292 }
1293
1294 enable_embedded_perl = (atoi(value) > 0) ? TRUE : FALSE;
1295 }
1296
1297 else if(!strcmp(variable, "use_embedded_perl_implicitly")) {
1298
1299 if(strlen(value) != 1 || value[0] < '0' || value[0] > '1') {
1300 asprintf(&error_message, "Illegal value for use_embedded_perl_implicitly");
1301 error = TRUE;
1302 break;
1303 }
1304
1305 use_embedded_perl_implicitly = (atoi(value) > 0) ? TRUE : FALSE;
1306 }
1307
1308 else if(!strcmp(variable, "external_command_buffer_slots"))
1309 external_command_buffer_slots = atoi(value);
1310
1311 else if(!strcmp(variable, "check_for_updates"))
1312 check_for_updates = (atoi(value) > 0) ? TRUE : FALSE;
1313
1314 else if(!strcmp(variable, "bare_update_check"))
1315 bare_update_check = (atoi(value) > 0) ? TRUE : FALSE;
1316
1317 /*** AUTH_FILE VARIABLE USED BY EMBEDDED PERL INTERPRETER ***/
1318 else if(!strcmp(variable, "auth_file")) {
1319
1320 if(strlen(value) > MAX_FILENAME_LENGTH - 1) {
1321 asprintf(&error_message, "Auth file is too long");
1322 error = TRUE;
1323 break;
1324 }
1325
1326 my_free(auth_file);
1327 auth_file = (char *)strdup(value);
1328 }
1329
1330 /* warn about old variables */
1331 else if(!strcmp(variable, "comment_file") || !strcmp(variable, "xcddefault_comment_file")) {
1332 logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: comment_file variable ignored. Comments are now stored in the status and retention files.");
1333 }
1334 else if(!strcmp(variable, "downtime_file") || !strcmp(variable, "xdddefault_downtime_file")) {
1335 logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: downtime_file variable ignored. Downtime entries are now stored in the status and retention files.");
1336 }
1337
1338 /* skip external data directives */
1339 else if(strstr(input, "x") == input)
1340 continue;
1341
1342 /* ignore external variables */
1343 else if(!strcmp(variable, "status_file"))
1344 continue;
1345 else if(!strcmp(variable, "perfdata_timeout"))
1346 continue;
1347 else if(strstr(variable, "host_perfdata") == variable)
1348 continue;
1349 else if(strstr(variable, "service_perfdata") == variable)
1350 continue;
1351 else if(strstr(input, "cfg_file=") == input || strstr(input, "cfg_dir=") == input)
1352 continue;
1353 else if(strstr(input, "state_retention_file=") == input)
1354 continue;
1355 else if(strstr(input, "object_cache_file=") == input)
1356 continue;
1357 else if(strstr(input, "precached_object_file=") == input)
1358 continue;
1359 else if(!strcmp(variable, "allow_empty_hostgroup_assignment")) {
1360 allow_empty_hostgroup_assignment = (atoi(value) > 0) ? TRUE : FALSE;
1361 }
1362
1363 /* we don't know what this variable is... */
1364 else {
1365 asprintf(&error_message, "UNKNOWN VARIABLE");
1366 error = TRUE;
1367 break;
1368 }
1369
1370 }
1371
1372 /* adjust timezone values */
1373 if(use_timezone != NULL)
1374 set_environment_var("TZ", use_timezone, 1);
1375 tzset();
1376
1377 /* adjust command check interval */
1378 if(command_check_interval_is_seconds == FALSE && command_check_interval != -1)
1379 command_check_interval *= interval_length;
1380
1381 /* adjust tweaks */
1382 if(free_child_process_memory == -1)
1383 free_child_process_memory = (use_large_installation_tweaks == TRUE) ? FALSE : TRUE;
1384 if(child_processes_fork_twice == -1)
1385 child_processes_fork_twice = (use_large_installation_tweaks == TRUE) ? FALSE : TRUE;
1386
1387
1388 /* handle errors */
1389 if(error == TRUE) {
1390 logit(NSLOG_CONFIG_ERROR, TRUE, "Error in configuration file '%s' - Line %d (%s)", main_config_file, current_line, (error_message == NULL) ? "NULL" : error_message);
1391 return ERROR;
1392 }
1393
1394 /* free leftover memory and close the file */
1395 my_free(input);
1396 mmap_fclose(thefile);
1397
1398 /* free memory */
1399 my_free(error_message);
1400 my_free(input);
1401 my_free(variable);
1402 my_free(value);
1403
1404 /* make sure a log file has been specified */
1405 strip(log_file);
1406 if(!strcmp(log_file, "")) {
1407 if(daemon_mode == FALSE)
1408 printf("Error: Log file is not specified anywhere in main config file '%s'!\n", main_config_file);
1409 return ERROR;
1410 }
1411
1412 return OK;
1413 }
1414
1415
1416
1417 /* processes macros in resource file */
read_resource_file(char * resource_file)1418 int read_resource_file(char *resource_file) {
1419 char *input = NULL;
1420 char *variable = NULL;
1421 char *value = NULL;
1422 char *temp_ptr = NULL;
1423 mmapfile *thefile = NULL;
1424 int current_line = 1;
1425 int error = FALSE;
1426 int user_index = 0;
1427
1428 if((thefile = mmap_fopen(resource_file)) == NULL) {
1429 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Cannot open resource file '%s' for reading!", resource_file);
1430 return ERROR;
1431 }
1432
1433 /* process all lines in the resource file */
1434 while(1) {
1435
1436 /* free memory */
1437 my_free(input);
1438 my_free(variable);
1439 my_free(value);
1440
1441 /* read the next line */
1442 if((input = mmap_fgets_multiline(thefile)) == NULL)
1443 break;
1444
1445 current_line = thefile->current_line;
1446
1447 /* skip blank lines and comments */
1448 if(input[0] == '#' || input[0] == '\x0' || input[0] == '\n' || input[0] == '\r')
1449 continue;
1450
1451 strip(input);
1452
1453 /* get the variable name */
1454 if((temp_ptr = my_strtok(input, "=")) == NULL) {
1455 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: NULL variable - Line %d of resource file '%s'", current_line, resource_file);
1456 error = TRUE;
1457 break;
1458 }
1459 if((variable = (char *)strdup(temp_ptr)) == NULL) {
1460 error = TRUE;
1461 break;
1462 }
1463
1464 /* get the value */
1465 if((temp_ptr = my_strtok(NULL, "\n")) == NULL) {
1466 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: NULL variable value - Line %d of resource file '%s'", current_line, resource_file);
1467 error = TRUE;
1468 break;
1469 }
1470 if((value = (char *)strdup(temp_ptr)) == NULL) {
1471 error = TRUE;
1472 break;
1473 }
1474
1475 /* what should we do with the variable/value pair? */
1476
1477 /* check for macro declarations */
1478 if(variable[0] == '$' && variable[strlen(variable) - 1] == '$') {
1479
1480 /* $USERx$ macro declarations */
1481 if(strstr(variable, "$USER") == variable && strlen(variable) > 5) {
1482 user_index = atoi(variable + 5) - 1;
1483 if(user_index >= 0 && user_index < MAX_USER_MACROS) {
1484 my_free(macro_user[user_index]);
1485 macro_user[user_index] = (char *)strdup(value);
1486 }
1487 }
1488 }
1489 }
1490
1491 /* free leftover memory and close the file */
1492 my_free(input);
1493 mmap_fclose(thefile);
1494
1495 /* free memory */
1496 my_free(variable);
1497 my_free(value);
1498
1499 if(error == TRUE)
1500 return ERROR;
1501
1502 return OK;
1503 }
1504
1505
1506
1507
1508
1509
1510 /****************************************************************/
1511 /**************** CONFIG VERIFICATION FUNCTIONS *****************/
1512 /****************************************************************/
1513
1514 /* do a pre-flight check to make sure object relationships, etc. make sense */
pre_flight_check(void)1515 int pre_flight_check(void) {
1516 host *temp_host = NULL;
1517 char *buf = NULL;
1518 service *temp_service = NULL;
1519 command *temp_command = NULL;
1520 char *temp_command_name = "";
1521 int warnings = 0;
1522 int errors = 0;
1523 struct timeval tv[4];
1524 double runtime[4];
1525 int temp_path_fd = -1;
1526
1527
1528 if(test_scheduling == TRUE)
1529 gettimeofday(&tv[0], NULL);
1530
1531 /********************************************/
1532 /* check object relationships */
1533 /********************************************/
1534 pre_flight_object_check(&warnings, &errors);
1535 if(test_scheduling == TRUE)
1536 gettimeofday(&tv[1], NULL);
1537
1538
1539 /********************************************/
1540 /* check for circular paths between hosts */
1541 /********************************************/
1542 pre_flight_circular_check(&warnings, &errors);
1543 if(test_scheduling == TRUE)
1544 gettimeofday(&tv[2], NULL);
1545
1546
1547 /********************************************/
1548 /* check global event handler commands... */
1549 /********************************************/
1550 if(verify_config == TRUE)
1551 printf("Checking global event handlers...\n");
1552 if(global_host_event_handler != NULL) {
1553
1554 /* check the event handler command */
1555 buf = (char *)strdup(global_host_event_handler);
1556
1557 /* get the command name, leave any arguments behind */
1558 temp_command_name = my_strtok(buf, "!");
1559
1560 temp_command = find_command(temp_command_name);
1561 if(temp_command == NULL) {
1562 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Global host event handler command '%s' is not defined anywhere!", temp_command_name);
1563 errors++;
1564 }
1565
1566 /* save the pointer to the command for later */
1567 global_host_event_handler_ptr = temp_command;
1568
1569 my_free(buf);
1570 }
1571 if(global_service_event_handler != NULL) {
1572
1573 /* check the event handler command */
1574 buf = (char *)strdup(global_service_event_handler);
1575
1576 /* get the command name, leave any arguments behind */
1577 temp_command_name = my_strtok(buf, "!");
1578
1579 temp_command = find_command(temp_command_name);
1580 if(temp_command == NULL) {
1581 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Global service event handler command '%s' is not defined anywhere!", temp_command_name);
1582 errors++;
1583 }
1584
1585 /* save the pointer to the command for later */
1586 global_service_event_handler_ptr = temp_command;
1587
1588 my_free(buf);
1589 }
1590
1591
1592 /**************************************************/
1593 /* check obsessive processor commands... */
1594 /**************************************************/
1595 if(verify_config == TRUE)
1596 printf("Checking obsessive compulsive processor commands...\n");
1597 if(ocsp_command != NULL) {
1598
1599 buf = (char *)strdup(ocsp_command);
1600
1601 /* get the command name, leave any arguments behind */
1602 temp_command_name = my_strtok(buf, "!");
1603
1604 temp_command = find_command(temp_command_name);
1605 if(temp_command == NULL) {
1606 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Obsessive compulsive service processor command '%s' is not defined anywhere!", temp_command_name);
1607 errors++;
1608 }
1609
1610 /* save the pointer to the command for later */
1611 ocsp_command_ptr = temp_command;
1612
1613 my_free(buf);
1614 }
1615 if(ochp_command != NULL) {
1616
1617 buf = (char *)strdup(ochp_command);
1618
1619 /* get the command name, leave any arguments behind */
1620 temp_command_name = my_strtok(buf, "!");
1621
1622 temp_command = find_command(temp_command_name);
1623 if(temp_command == NULL) {
1624 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Obsessive compulsive host processor command '%s' is not defined anywhere!", temp_command_name);
1625 errors++;
1626 }
1627
1628 /* save the pointer to the command for later */
1629 ochp_command_ptr = temp_command;
1630
1631 my_free(buf);
1632 }
1633
1634
1635 /**************************************************/
1636 /* check various settings... */
1637 /**************************************************/
1638 if(verify_config == TRUE)
1639 printf("Checking misc settings...\n");
1640
1641 /* check if we can write to temp_path */
1642 asprintf(&buf, "%s/nagiosXXXXXX", temp_path);
1643 if((temp_path_fd = mkstemp(buf)) == -1) {
1644 logit(NSLOG_VERIFICATION_ERROR, TRUE, "\tError: Unable to write to temp_path ('%s') - %s\n", temp_path, strerror(errno));
1645 errors++;
1646 }
1647 else {
1648 close(temp_path_fd);
1649 remove(buf);
1650 }
1651 my_free(buf);
1652
1653 /* check if we can write to check_result_path */
1654 asprintf(&buf, "%s/nagiosXXXXXX", check_result_path);
1655 if((temp_path_fd = mkstemp(buf)) == -1) {
1656 logit(NSLOG_VERIFICATION_WARNING, TRUE, "\tError: Unable to write to check_result_path ('%s') - %s\n", check_result_path, strerror(errno));
1657 errors++;
1658 }
1659 else {
1660 close(temp_path_fd);
1661 remove(buf);
1662 }
1663 my_free(buf);
1664
1665 /* warn if user didn't specify any illegal macro output chars */
1666 if(illegal_output_chars == NULL) {
1667 logit(NSLOG_VERIFICATION_WARNING, TRUE, "%s", "Warning: Nothing specified for illegal_macro_output_chars variable!\n");
1668 warnings++;
1669 }
1670
1671 /* count number of services associated with each host (we need this for flap detection)... */
1672 for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
1673 if((temp_host = find_host(temp_service->host_name))) {
1674 temp_host->total_services++;
1675 temp_host->total_service_check_interval += temp_service->check_interval;
1676 }
1677 }
1678
1679 if(verify_config == TRUE) {
1680 printf("\n");
1681 printf("Total Warnings: %d\n", warnings);
1682 printf("Total Errors: %d\n", errors);
1683 }
1684
1685 if(test_scheduling == TRUE)
1686 gettimeofday(&tv[3], NULL);
1687
1688 if(test_scheduling == TRUE) {
1689
1690 if(verify_object_relationships == TRUE)
1691 runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0);
1692 else
1693 runtime[0] = 0.0;
1694 if(verify_circular_paths == TRUE)
1695 runtime[1] = (double)((double)(tv[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0);
1696 else
1697 runtime[1] = 0.0;
1698 runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0);
1699 runtime[3] = runtime[0] + runtime[1] + runtime[2];
1700
1701 printf("Timing information on configuration verification is listed below.\n\n");
1702
1703 printf("CONFIG VERIFICATION TIMES (* = Potential for speedup with -x option)\n");
1704 printf("----------------------------------\n");
1705 printf("Object Relationships: %.6lf sec\n", runtime[0]);
1706 printf("Circular Paths: %.6lf sec *\n", runtime[1]);
1707 printf("Misc: %.6lf sec\n", runtime[2]);
1708 printf(" ============\n");
1709 printf("TOTAL: %.6lf sec * = %.6lf sec (%.1f%%) estimated savings\n", runtime[3], runtime[1], (runtime[1] / runtime[3]) * 100.0);
1710 printf("\n\n");
1711 }
1712
1713 return (errors > 0) ? ERROR : OK;
1714 }
1715
1716
1717
1718 /* do a pre-flight check to make sure object relationships make sense */
pre_flight_object_check(int * w,int * e)1719 int pre_flight_object_check(int *w, int *e) {
1720 contact *temp_contact = NULL;
1721 commandsmember *temp_commandsmember = NULL;
1722 contactgroup *temp_contactgroup = NULL;
1723 contactsmember *temp_contactsmember = NULL;
1724 contactgroupsmember *temp_contactgroupsmember = NULL;
1725 host *temp_host = NULL;
1726 host *temp_host2 = NULL;
1727 hostsmember *temp_hostsmember = NULL;
1728 hostgroup *temp_hostgroup = NULL;
1729 servicegroup *temp_servicegroup = NULL;
1730 servicesmember *temp_servicesmember = NULL;
1731 service *temp_service = NULL;
1732 service *temp_service2 = NULL;
1733 command *temp_command = NULL;
1734 timeperiod *temp_timeperiod = NULL;
1735 timeperiod *temp_timeperiod2 = NULL;
1736 timeperiodexclusion *temp_timeperiodexclusion = NULL;
1737 serviceescalation *temp_se = NULL;
1738 hostescalation *temp_he = NULL;
1739 servicedependency *temp_sd = NULL;
1740 hostdependency *temp_hd = NULL;
1741 char *buf = NULL;
1742 char *temp_command_name = "";
1743 int found = FALSE;
1744 int total_objects = 0;
1745 int warnings = 0;
1746 int errors = 0;
1747
1748
1749 #ifdef TEST
1750 void *ptr = NULL;
1751 char *buf1 = "";
1752 char *buf2 = "";
1753 buf1 = "temptraxe1";
1754 buf2 = "Probe 2";
1755 for(temp_se = get_first_serviceescalation_by_service(buf1, buf2, &ptr); temp_se != NULL; temp_se = get_next_serviceescalation_by_service(buf1, buf2, &ptr)) {
1756 printf("FOUND ESCALATION FOR SVC '%s'/'%s': %d-%d/%.3f, PTR=%p\n", buf1, buf2, temp_se->first_notification, temp_se->last_notification, temp_se->notification_interval, ptr);
1757 }
1758 for(temp_he = get_first_hostescalation_by_host(buf1, &ptr); temp_he != NULL; temp_he = get_next_hostescalation_by_host(buf1, &ptr)) {
1759 printf("FOUND ESCALATION FOR HOST '%s': %d-%d/%d, PTR=%p\n", buf1, temp_he->first_notification, temp_he->last_notification, temp_he->notification_interval, ptr);
1760 }
1761 #endif
1762
1763 /* bail out if we aren't supposed to verify object relationships */
1764 if(verify_object_relationships == FALSE)
1765 return OK;
1766
1767
1768 /*****************************************/
1769 /* check each service... */
1770 /*****************************************/
1771 if(verify_config == TRUE)
1772 printf("Checking services...\n");
1773 if(get_service_count() == 0) {
1774 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: There are no services defined!");
1775 errors++;
1776 }
1777 total_objects = 0;
1778 for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
1779
1780 total_objects++;
1781 found = FALSE;
1782
1783 /* check for a valid host */
1784 temp_host = find_host(temp_service->host_name);
1785
1786 /* we couldn't find an associated host! */
1787 if(!temp_host) {
1788 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host '%s' specified in service '%s' not defined anywhere!", temp_service->host_name, temp_service->description);
1789 errors++;
1790 }
1791
1792 /* save the host pointer for later */
1793 temp_service->host_ptr = temp_host;
1794
1795 /* add a reverse link from the host to the service for faster lookups later */
1796 add_service_link_to_host(temp_host, temp_service);
1797
1798 /* check the event handler command */
1799 if(temp_service->event_handler != NULL) {
1800
1801 /* check the event handler command */
1802 buf = (char *)strdup(temp_service->event_handler);
1803
1804 /* get the command name, leave any arguments behind */
1805 temp_command_name = my_strtok(buf, "!");
1806
1807 temp_command = find_command(temp_command_name);
1808 if(temp_command == NULL) {
1809 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Event handler command '%s' specified in service '%s' for host '%s' not defined anywhere", temp_command_name, temp_service->description, temp_service->host_name);
1810 errors++;
1811 }
1812
1813 my_free(buf);
1814
1815 /* save the pointer to the event handler for later */
1816 temp_service->event_handler_ptr = temp_command;
1817 }
1818
1819 /* check the service check_command */
1820 buf = (char *)strdup(temp_service->service_check_command);
1821
1822 /* get the command name, leave any arguments behind */
1823 temp_command_name = my_strtok(buf, "!");
1824
1825 temp_command = find_command(temp_command_name);
1826 if(temp_command == NULL) {
1827 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service check command '%s' specified in service '%s' for host '%s' not defined anywhere!", temp_command_name, temp_service->description, temp_service->host_name);
1828 errors++;
1829 }
1830
1831 my_free(buf);
1832
1833 /* save the pointer to the check command for later */
1834 temp_service->check_command_ptr = temp_command;
1835
1836 /* check for sane recovery options */
1837 if(temp_service->notify_on_recovery == TRUE && temp_service->notify_on_warning == FALSE && temp_service->notify_on_critical == FALSE) {
1838 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Recovery notification option in service '%s' for host '%s' doesn't make any sense - specify warning and/or critical options as well", temp_service->description, temp_service->host_name);
1839 warnings++;
1840 }
1841
1842 /* reset the found flag */
1843 found = FALSE;
1844
1845 /* check for valid contacts */
1846 for(temp_contactsmember = temp_service->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {
1847
1848 temp_contact = find_contact(temp_contactsmember->contact_name);
1849
1850 if(temp_contact == NULL) {
1851 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in service '%s' for host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_service->description, temp_service->host_name);
1852 errors++;
1853 }
1854
1855 /* save the contact pointer for later */
1856 temp_contactsmember->contact_ptr = temp_contact;
1857 }
1858
1859 /* check all contact groupss */
1860 for(temp_contactgroupsmember = temp_service->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) {
1861
1862 temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name);
1863
1864 if(temp_contactgroup == NULL) {
1865 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in service '%s' for host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_service->description, temp_service->host_name);
1866 errors++;
1867 }
1868
1869 /* save the contact group pointer for later */
1870 temp_contactgroupsmember->group_ptr = temp_contactgroup;
1871 }
1872
1873 /* check to see if there is at least one contact/group */
1874 if(temp_service->contacts == NULL && temp_service->contact_groups == NULL) {
1875 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has no default contacts or contactgroups defined!", temp_service->description, temp_service->host_name);
1876 warnings++;
1877 }
1878
1879 /* verify service check timeperiod */
1880 if(temp_service->check_period == NULL) {
1881 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has no check time period defined!", temp_service->description, temp_service->host_name);
1882 warnings++;
1883 }
1884 else {
1885 temp_timeperiod = find_timeperiod(temp_service->check_period);
1886 if(temp_timeperiod == NULL) {
1887 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Check period '%s' specified for service '%s' on host '%s' is not defined anywhere!", temp_service->check_period, temp_service->description, temp_service->host_name);
1888 errors++;
1889 }
1890
1891 /* save the pointer to the check timeperiod for later */
1892 temp_service->check_period_ptr = temp_timeperiod;
1893 }
1894
1895 /* check service notification timeperiod */
1896 if(temp_service->notification_period == NULL) {
1897 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has no notification time period defined!", temp_service->description, temp_service->host_name);
1898 warnings++;
1899 }
1900
1901 else {
1902 temp_timeperiod = find_timeperiod(temp_service->notification_period);
1903 if(temp_timeperiod == NULL) {
1904 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Notification period '%s' specified for service '%s' on host '%s' is not defined anywhere!", temp_service->notification_period, temp_service->description, temp_service->host_name);
1905 errors++;
1906 }
1907
1908 /* save the pointer to the notification timeperiod for later */
1909 temp_service->notification_period_ptr = temp_timeperiod;
1910 }
1911
1912 /* see if the notification interval is less than the check interval */
1913 if(temp_service->notification_interval < temp_service->check_interval && temp_service->notification_interval != 0) {
1914 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service '%s' on host '%s' has a notification interval less than its check interval! Notifications are only re-sent after checks are made, so the effective notification interval will be that of the check interval.", temp_service->description, temp_service->host_name);
1915 warnings++;
1916 }
1917
1918 /* check for illegal characters in service description */
1919 if(use_precached_objects == FALSE) {
1920 if(contains_illegal_object_chars(temp_service->description) == TRUE) {
1921 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The description string for service '%s' on host '%s' contains one or more illegal characters.", temp_service->description, temp_service->host_name);
1922 errors++;
1923 }
1924 }
1925 }
1926
1927 if(verify_config == TRUE)
1928 printf("\tChecked %d services.\n", total_objects);
1929
1930
1931
1932 /*****************************************/
1933 /* check all hosts... */
1934 /*****************************************/
1935 if(verify_config == TRUE)
1936 printf("Checking hosts...\n");
1937
1938 if(get_host_count() == 0) {
1939 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: There are no hosts defined!");
1940 errors++;
1941 }
1942
1943 total_objects = 0;
1944 for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {
1945
1946 total_objects++;
1947 found = FALSE;
1948
1949 /* make sure each host has at least one service associated with it */
1950 /* 02/21/08 NOTE: this is extremely inefficient */
1951 if(use_precached_objects == FALSE && use_large_installation_tweaks == FALSE) {
1952
1953 for(temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) {
1954 if(!strcmp(temp_service->host_name, temp_host->name)) {
1955 found = TRUE;
1956 break;
1957 }
1958 }
1959
1960 /* we couldn't find a service associated with this host! */
1961 if(found == FALSE) {
1962 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Host '%s' has no services associated with it!", temp_host->name);
1963 warnings++;
1964 }
1965
1966 found = FALSE;
1967 }
1968
1969 /* check the event handler command */
1970 if(temp_host->event_handler != NULL) {
1971
1972 /* check the event handler command */
1973 buf = (char *)strdup(temp_host->event_handler);
1974
1975 /* get the command name, leave any arguments behind */
1976 temp_command_name = my_strtok(buf, "!");
1977
1978 temp_command = find_command(temp_command_name);
1979 if(temp_command == NULL) {
1980 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Event handler command '%s' specified for host '%s' not defined anywhere", temp_command_name, temp_host->name);
1981 errors++;
1982 }
1983
1984 my_free(buf);
1985
1986 /* save the pointer to the event handler command for later */
1987 temp_host->event_handler_ptr = temp_command;
1988 }
1989
1990 /* hosts that don't have check commands defined shouldn't ever be checked... */
1991 if(temp_host->host_check_command != NULL) {
1992
1993 /* check the host check_command */
1994 buf = (char *)strdup(temp_host->host_check_command);
1995
1996 /* get the command name, leave any arguments behind */
1997 temp_command_name = my_strtok(buf, "!");
1998
1999 temp_command = find_command(temp_command_name);
2000 if(temp_command == NULL) {
2001 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host check command '%s' specified for host '%s' is not defined anywhere!", temp_command_name, temp_host->name);
2002 errors++;
2003 }
2004
2005 /* save the pointer to the check command for later */
2006 temp_host->check_command_ptr = temp_command;
2007
2008 my_free(buf);
2009 }
2010
2011 /* check host check timeperiod */
2012 if(temp_host->check_period != NULL) {
2013 temp_timeperiod = find_timeperiod(temp_host->check_period);
2014 if(temp_timeperiod == NULL) {
2015 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Check period '%s' specified for host '%s' is not defined anywhere!", temp_host->check_period, temp_host->name);
2016 errors++;
2017 }
2018
2019 /* save the pointer to the check timeperiod for later */
2020 temp_host->check_period_ptr = temp_timeperiod;
2021 }
2022
2023 /* check all contacts */
2024 for(temp_contactsmember = temp_host->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {
2025
2026 temp_contact = find_contact(temp_contactsmember->contact_name);
2027
2028 if(temp_contact == NULL) {
2029 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_host->name);
2030 errors++;
2031 }
2032
2033 /* save the contact pointer for later */
2034 temp_contactsmember->contact_ptr = temp_contact;
2035 }
2036
2037 /* check all contact groups */
2038 for(temp_contactgroupsmember = temp_host->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) {
2039
2040 temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name);
2041
2042 if(temp_contactgroup == NULL) {
2043 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_host->name);
2044 errors++;
2045 }
2046
2047 /* save the contact group pointer for later */
2048 temp_contactgroupsmember->group_ptr = temp_contactgroup;
2049 }
2050
2051 /* check to see if there is at least one contact/group */
2052 if(temp_host->contacts == NULL && temp_host->contact_groups == NULL) {
2053 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Host '%s' has no default contacts or contactgroups defined!", temp_host->name);
2054 warnings++;
2055 }
2056
2057 /* check notification timeperiod */
2058 if(temp_host->notification_period != NULL) {
2059 temp_timeperiod = find_timeperiod(temp_host->notification_period);
2060 if(temp_timeperiod == NULL) {
2061 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Notification period '%s' specified for host '%s' is not defined anywhere!", temp_host->notification_period, temp_host->name);
2062 errors++;
2063 }
2064
2065 /* save the pointer to the notification timeperiod for later */
2066 temp_host->notification_period_ptr = temp_timeperiod;
2067 }
2068
2069 /* check all parent parent host */
2070 for(temp_hostsmember = temp_host->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
2071
2072 if((temp_host2 = find_host(temp_hostsmember->host_name)) == NULL) {
2073 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: '%s' is not a valid parent for host '%s'!", temp_hostsmember->host_name, temp_host->name);
2074 errors++;
2075 }
2076
2077 /* save the parent host pointer for later */
2078 temp_hostsmember->host_ptr = temp_host2;
2079
2080 /* add a reverse (child) link to make searches faster later on */
2081 add_child_link_to_host(temp_host2, temp_host);
2082 }
2083
2084 /* check for sane recovery options */
2085 if(temp_host->notify_on_recovery == TRUE && temp_host->notify_on_down == FALSE && temp_host->notify_on_unreachable == FALSE) {
2086 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Recovery notification option in host '%s' definition doesn't make any sense - specify down and/or unreachable options as well", temp_host->name);
2087 warnings++;
2088 }
2089
2090 /* check for illegal characters in host name */
2091 if(use_precached_objects == FALSE) {
2092 if(contains_illegal_object_chars(temp_host->name) == TRUE) {
2093 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of host '%s' contains one or more illegal characters.", temp_host->name);
2094 errors++;
2095 }
2096 }
2097 }
2098
2099
2100 if(verify_config == TRUE)
2101 printf("\tChecked %d hosts.\n", total_objects);
2102
2103
2104 /*****************************************/
2105 /* check each host group... */
2106 /*****************************************/
2107 if(verify_config == TRUE)
2108 printf("Checking host groups...\n");
2109 for(temp_hostgroup = hostgroup_list, total_objects = 0; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next, total_objects++) {
2110
2111 /* check all group members */
2112 for(temp_hostsmember = temp_hostgroup->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
2113
2114 temp_host = find_host(temp_hostsmember->host_name);
2115 if(temp_host == NULL) {
2116 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host '%s' specified in host group '%s' is not defined anywhere!", temp_hostsmember->host_name, temp_hostgroup->group_name);
2117 errors++;
2118 }
2119
2120 /* save a pointer to this hostgroup for faster host/group membership lookups later */
2121 else
2122 add_object_to_objectlist(&temp_host->hostgroups_ptr, (void *)temp_hostgroup);
2123
2124 /* save host pointer for later */
2125 temp_hostsmember->host_ptr = temp_host;
2126 }
2127
2128 /* check for illegal characters in hostgroup name */
2129 if(use_precached_objects == FALSE) {
2130 if(contains_illegal_object_chars(temp_hostgroup->group_name) == TRUE) {
2131 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of hostgroup '%s' contains one or more illegal characters.", temp_hostgroup->group_name);
2132 errors++;
2133 }
2134 }
2135 }
2136
2137 if(verify_config == TRUE)
2138 printf("\tChecked %d host groups.\n", total_objects);
2139
2140
2141 /*****************************************/
2142 /* check each service group... */
2143 /*****************************************/
2144 if(verify_config == TRUE)
2145 printf("Checking service groups...\n");
2146 for(temp_servicegroup = servicegroup_list, total_objects = 0; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next, total_objects++) {
2147
2148 /* check all group members */
2149 for(temp_servicesmember = temp_servicegroup->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) {
2150
2151 temp_service = find_service(temp_servicesmember->host_name, temp_servicesmember->service_description);
2152 if(temp_service == NULL) {
2153 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service '%s' on host '%s' specified in service group '%s' is not defined anywhere!", temp_servicesmember->service_description, temp_servicesmember->host_name, temp_servicegroup->group_name);
2154 errors++;
2155 }
2156
2157 /* save a pointer to this servicegroup for faster service/group membership lookups later */
2158 else
2159 add_object_to_objectlist(&temp_service->servicegroups_ptr, (void *)temp_servicegroup);
2160
2161 /* save service pointer for later */
2162 temp_servicesmember->service_ptr = temp_service;
2163 }
2164
2165 /* check for illegal characters in servicegroup name */
2166 if(use_precached_objects == FALSE) {
2167 if(contains_illegal_object_chars(temp_servicegroup->group_name) == TRUE) {
2168 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of servicegroup '%s' contains one or more illegal characters.", temp_servicegroup->group_name);
2169 errors++;
2170 }
2171 }
2172 }
2173
2174 if(verify_config == TRUE)
2175 printf("\tChecked %d service groups.\n", total_objects);
2176
2177
2178
2179 /*****************************************/
2180 /* check all contacts... */
2181 /*****************************************/
2182 if(verify_config == TRUE)
2183 printf("Checking contacts...\n");
2184 if(contact_list == NULL) {
2185 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: There are no contacts defined!");
2186 errors++;
2187 }
2188 for(temp_contact = contact_list, total_objects = 0; temp_contact != NULL; temp_contact = temp_contact->next, total_objects++) {
2189
2190 /* check service notification commands */
2191 if(temp_contact->service_notification_commands == NULL) {
2192 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' has no service notification commands defined!", temp_contact->name);
2193 errors++;
2194 }
2195 else for(temp_commandsmember = temp_contact->service_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) {
2196
2197 /* check the host notification command */
2198 buf = (char *)strdup(temp_commandsmember->command);
2199
2200 /* get the command name, leave any arguments behind */
2201 temp_command_name = my_strtok(buf, "!");
2202
2203 temp_command = find_command(temp_command_name);
2204 if(temp_command == NULL) {
2205 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service notification command '%s' specified for contact '%s' is not defined anywhere!", temp_command_name, temp_contact->name);
2206 errors++;
2207 }
2208
2209 /* save pointer to the command for later */
2210 temp_commandsmember->command_ptr = temp_command;
2211
2212 my_free(buf);
2213 }
2214
2215 /* check host notification commands */
2216 if(temp_contact->host_notification_commands == NULL) {
2217 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' has no host notification commands defined!", temp_contact->name);
2218 errors++;
2219 }
2220 else for(temp_commandsmember = temp_contact->host_notification_commands; temp_commandsmember != NULL; temp_commandsmember = temp_commandsmember->next) {
2221
2222 /* check the host notification command */
2223 buf = (char *)strdup(temp_commandsmember->command);
2224
2225 /* get the command name, leave any arguments behind */
2226 temp_command_name = my_strtok(buf, "!");
2227
2228 temp_command = find_command(temp_command_name);
2229 if(temp_command == NULL) {
2230 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host notification command '%s' specified for contact '%s' is not defined anywhere!", temp_command_name, temp_contact->name);
2231 errors++;
2232 }
2233
2234 /* save pointer to the command for later */
2235 temp_commandsmember->command_ptr = temp_command;
2236
2237 my_free(buf);
2238 }
2239
2240 /* check service notification timeperiod */
2241 if(temp_contact->service_notification_period == NULL) {
2242 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Contact '%s' has no service notification time period defined!", temp_contact->name);
2243 warnings++;
2244 }
2245
2246 else {
2247 temp_timeperiod = find_timeperiod(temp_contact->service_notification_period);
2248 if(temp_timeperiod == NULL) {
2249 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service notification period '%s' specified for contact '%s' is not defined anywhere!", temp_contact->service_notification_period, temp_contact->name);
2250 errors++;
2251 }
2252
2253 /* save the pointer to the service notification timeperiod for later */
2254 temp_contact->service_notification_period_ptr = temp_timeperiod;
2255 }
2256
2257 /* check host notification timeperiod */
2258 if(temp_contact->host_notification_period == NULL) {
2259 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Contact '%s' has no host notification time period defined!", temp_contact->name);
2260 warnings++;
2261 }
2262
2263 else {
2264 temp_timeperiod = find_timeperiod(temp_contact->host_notification_period);
2265 if(temp_timeperiod == NULL) {
2266 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host notification period '%s' specified for contact '%s' is not defined anywhere!", temp_contact->host_notification_period, temp_contact->name);
2267 errors++;
2268 }
2269
2270 /* save the pointer to the host notification timeperiod for later */
2271 temp_contact->host_notification_period_ptr = temp_timeperiod;
2272 }
2273
2274 /* check for sane host recovery options */
2275 if(temp_contact->notify_on_host_recovery == TRUE && temp_contact->notify_on_host_down == FALSE && temp_contact->notify_on_host_unreachable == FALSE) {
2276 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Host recovery notification option for contact '%s' doesn't make any sense - specify down and/or unreachable options as well", temp_contact->name);
2277 warnings++;
2278 }
2279
2280 /* check for sane service recovery options */
2281 if(temp_contact->notify_on_service_recovery == TRUE && temp_contact->notify_on_service_critical == FALSE && temp_contact->notify_on_service_warning == FALSE) {
2282 logit(NSLOG_VERIFICATION_WARNING, TRUE, "Warning: Service recovery notification option for contact '%s' doesn't make any sense - specify critical and/or warning options as well", temp_contact->name);
2283 warnings++;
2284 }
2285
2286 /* check for illegal characters in contact name */
2287 if(use_precached_objects == FALSE) {
2288 if(contains_illegal_object_chars(temp_contact->name) == TRUE) {
2289 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of contact '%s' contains one or more illegal characters.", temp_contact->name);
2290 errors++;
2291 }
2292 }
2293 }
2294
2295 if(verify_config == TRUE)
2296 printf("\tChecked %d contacts.\n", total_objects);
2297
2298
2299
2300 /*****************************************/
2301 /* check each contact group... */
2302 /*****************************************/
2303 if(verify_config == TRUE)
2304 printf("Checking contact groups...\n");
2305 for(temp_contactgroup = contactgroup_list, total_objects = 0; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next, total_objects++) {
2306
2307 found = FALSE;
2308
2309 /* check all the group members */
2310 for(temp_contactsmember = temp_contactgroup->members; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {
2311
2312 temp_contact = find_contact(temp_contactsmember->contact_name);
2313 if(temp_contact == NULL) {
2314 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in contact group '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_contactgroup->group_name);
2315 errors++;
2316 }
2317
2318 /* save a pointer to this contactgroup for faster contact/group membership lookups later */
2319 else
2320 add_object_to_objectlist(&temp_contact->contactgroups_ptr, (void *)temp_contactgroup);
2321
2322 /* save the contact pointer for later */
2323 temp_contactsmember->contact_ptr = temp_contact;
2324 }
2325
2326 /* check for illegal characters in contactgroup name */
2327 if(use_precached_objects == FALSE) {
2328 if(contains_illegal_object_chars(temp_contactgroup->group_name) == TRUE) {
2329 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of contact group '%s' contains one or more illegal characters.", temp_contactgroup->group_name);
2330 errors++;
2331 }
2332 }
2333 }
2334
2335 if(verify_config == TRUE)
2336 printf("\tChecked %d contact groups.\n", total_objects);
2337
2338
2339
2340 /*****************************************/
2341 /* check all service escalations... */
2342 /*****************************************/
2343 if(verify_config == TRUE)
2344 printf("Checking service escalations...\n");
2345
2346 for(temp_se = serviceescalation_list, total_objects = 0; temp_se != NULL; temp_se = temp_se->next, total_objects++) {
2347
2348 /* find the service */
2349 temp_service = find_service(temp_se->host_name, temp_se->description);
2350 if(temp_service == NULL) {
2351 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service '%s' on host '%s' specified in service escalation is not defined anywhere!", temp_se->description, temp_se->host_name);
2352 errors++;
2353 }
2354
2355 /* save the service pointer for later */
2356 temp_se->service_ptr = temp_service;
2357
2358 /* find the timeperiod */
2359 if(temp_se->escalation_period != NULL) {
2360 temp_timeperiod = find_timeperiod(temp_se->escalation_period);
2361 if(temp_timeperiod == NULL) {
2362 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Escalation period '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!", temp_se->escalation_period, temp_se->description, temp_se->host_name);
2363 errors++;
2364 }
2365
2366 /* save the timeperiod pointer for later */
2367 temp_se->escalation_period_ptr = temp_timeperiod;
2368 }
2369
2370 /* find the contacts */
2371 for(temp_contactsmember = temp_se->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {
2372
2373 /* find the contact */
2374 temp_contact = find_contact(temp_contactsmember->contact_name);
2375 if(temp_contact == NULL) {
2376 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_se->description, temp_se->host_name);
2377 errors++;
2378 }
2379
2380 /* save the contact pointer for later */
2381 temp_contactsmember->contact_ptr = temp_contact;
2382 }
2383
2384 /* check all contact groups */
2385 for(temp_contactgroupsmember = temp_se->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) {
2386
2387 temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name);
2388
2389 if(temp_contactgroup == NULL) {
2390 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_se->description, temp_se->host_name);
2391 errors++;
2392 }
2393
2394 /* save the contact group pointer for later */
2395 temp_contactgroupsmember->group_ptr = temp_contactgroup;
2396 }
2397 }
2398
2399 if(verify_config == TRUE)
2400 printf("\tChecked %d service escalations.\n", total_objects);
2401
2402
2403
2404 /*****************************************/
2405 /* check all service dependencies... */
2406 /*****************************************/
2407 if(verify_config == TRUE)
2408 printf("Checking service dependencies...\n");
2409
2410 for(temp_sd = servicedependency_list, total_objects = 0; temp_sd != NULL; temp_sd = temp_sd->next, total_objects++) {
2411
2412 /* find the dependent service */
2413 temp_service = find_service(temp_sd->dependent_host_name, temp_sd->dependent_service_description);
2414 if(temp_service == NULL) {
2415 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependent service '%s' on host '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!", temp_sd->dependent_service_description, temp_sd->dependent_host_name, temp_sd->service_description, temp_sd->host_name);
2416 errors++;
2417 }
2418
2419 /* save pointer for later */
2420 temp_sd->dependent_service_ptr = temp_service;
2421
2422 /* find the service we're depending on */
2423 temp_service2 = find_service(temp_sd->host_name, temp_sd->service_description);
2424 if(temp_service2 == NULL) {
2425 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service '%s' on host '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!", temp_sd->service_description, temp_sd->host_name, temp_sd->dependent_service_description, temp_sd->dependent_host_name);
2426 errors++;
2427 }
2428
2429 /* save pointer for later */
2430 temp_sd->master_service_ptr = temp_service2;
2431
2432 /* make sure they're not the same service */
2433 if(temp_service == temp_service2) {
2434 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service dependency definition for service '%s' on host '%s' is circular (it depends on itself)!", temp_sd->dependent_service_description, temp_sd->dependent_host_name);
2435 errors++;
2436 }
2437
2438 /* find the timeperiod */
2439 if(temp_sd->dependency_period != NULL) {
2440 temp_timeperiod = find_timeperiod(temp_sd->dependency_period);
2441 if(temp_timeperiod == NULL) {
2442 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependency period '%s' specified in service dependency for service '%s' on host '%s' is not defined anywhere!", temp_sd->dependency_period, temp_sd->dependent_service_description, temp_sd->dependent_host_name);
2443 errors++;
2444 }
2445
2446 /* save the timeperiod pointer for later */
2447 temp_sd->dependency_period_ptr = temp_timeperiod;
2448 }
2449 }
2450
2451 if(verify_config == TRUE)
2452 printf("\tChecked %d service dependencies.\n", total_objects);
2453
2454
2455
2456 /*****************************************/
2457 /* check all host escalations... */
2458 /*****************************************/
2459 if(verify_config == TRUE)
2460 printf("Checking host escalations...\n");
2461
2462 for(temp_he = hostescalation_list, total_objects = 0; temp_he != NULL; temp_he = temp_he->next, total_objects++) {
2463
2464 /* find the host */
2465 temp_host = find_host(temp_he->host_name);
2466 if(temp_host == NULL) {
2467 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host '%s' specified in host escalation is not defined anywhere!", temp_he->host_name);
2468 errors++;
2469 }
2470
2471 /* save the host pointer for later */
2472 temp_he->host_ptr = temp_host;
2473
2474 /* find the timeperiod */
2475 if(temp_he->escalation_period != NULL) {
2476 temp_timeperiod = find_timeperiod(temp_he->escalation_period);
2477 if(temp_timeperiod == NULL) {
2478 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Escalation period '%s' specified in host escalation for host '%s' is not defined anywhere!", temp_he->escalation_period, temp_he->host_name);
2479 errors++;
2480 }
2481
2482 /* save the timeperiod pointer for later */
2483 temp_he->escalation_period_ptr = temp_timeperiod;
2484 }
2485
2486 /* find the contacts */
2487 for(temp_contactsmember = temp_he->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {
2488
2489 /* find the contact*/
2490 temp_contact = find_contact(temp_contactsmember->contact_name);
2491 if(temp_contact == NULL) {
2492 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact '%s' specified in host escalation for host '%s' is not defined anywhere!", temp_contactsmember->contact_name, temp_he->host_name);
2493 errors++;
2494 }
2495
2496 /* save the contact pointer for later */
2497 temp_contactsmember->contact_ptr = temp_contact;
2498 }
2499
2500 /* check all contact groups */
2501 for(temp_contactgroupsmember = temp_he->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) {
2502
2503 temp_contactgroup = find_contactgroup(temp_contactgroupsmember->group_name);
2504
2505 if(temp_contactgroup == NULL) {
2506 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Contact group '%s' specified in host escalation for host '%s' is not defined anywhere!", temp_contactgroupsmember->group_name, temp_he->host_name);
2507 errors++;
2508 }
2509
2510 /* save the contact group pointer for later */
2511 temp_contactgroupsmember->group_ptr = temp_contactgroup;
2512 }
2513 }
2514
2515 if(verify_config == TRUE)
2516 printf("\tChecked %d host escalations.\n", total_objects);
2517
2518
2519
2520 /*****************************************/
2521 /* check all host dependencies... */
2522 /*****************************************/
2523 if(verify_config == TRUE)
2524 printf("Checking host dependencies...\n");
2525
2526 for(temp_hd = hostdependency_list, total_objects = 0; temp_hd != NULL; temp_hd = temp_hd->next, total_objects++) {
2527
2528 /* find the dependent host */
2529 temp_host = find_host(temp_hd->dependent_host_name);
2530 if(temp_host == NULL) {
2531 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependent host specified in host dependency for host '%s' is not defined anywhere!", temp_hd->dependent_host_name);
2532 errors++;
2533 }
2534
2535 /* save pointer for later */
2536 temp_hd->dependent_host_ptr = temp_host;
2537
2538 /* find the host we're depending on */
2539 temp_host2 = find_host(temp_hd->host_name);
2540 if(temp_host2 == NULL) {
2541 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host specified in host dependency for host '%s' is not defined anywhere!", temp_hd->dependent_host_name);
2542 errors++;
2543 }
2544
2545 /* save pointer for later */
2546 temp_hd->master_host_ptr = temp_host2;
2547
2548 /* make sure they're not the same host */
2549 if(temp_host == temp_host2) {
2550 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host dependency definition for host '%s' is circular (it depends on itself)!", temp_hd->dependent_host_name);
2551 errors++;
2552 }
2553
2554 /* find the timeperiod */
2555 if(temp_hd->dependency_period != NULL) {
2556 temp_timeperiod = find_timeperiod(temp_hd->dependency_period);
2557 if(temp_timeperiod == NULL) {
2558 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Dependency period '%s' specified in host dependency for host '%s' is not defined anywhere!", temp_hd->dependency_period, temp_hd->dependent_host_name);
2559 errors++;
2560 }
2561
2562 /* save the timeperiod pointer for later */
2563 temp_hd->dependency_period_ptr = temp_timeperiod;
2564 }
2565 }
2566
2567 if(verify_config == TRUE)
2568 printf("\tChecked %d host dependencies.\n", total_objects);
2569
2570
2571
2572 /*****************************************/
2573 /* check all commands... */
2574 /*****************************************/
2575 if(verify_config == TRUE)
2576 printf("Checking commands...\n");
2577
2578 for(temp_command = command_list, total_objects = 0; temp_command != NULL; temp_command = temp_command->next, total_objects++) {
2579
2580 /* check for illegal characters in command name */
2581 if(use_precached_objects == FALSE) {
2582 if(contains_illegal_object_chars(temp_command->name) == TRUE) {
2583 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of command '%s' contains one or more illegal characters.", temp_command->name);
2584 errors++;
2585 }
2586 }
2587 }
2588
2589 if(verify_config == TRUE)
2590 printf("\tChecked %d commands.\n", total_objects);
2591
2592
2593
2594 /*****************************************/
2595 /* check all timeperiods... */
2596 /*****************************************/
2597 if(verify_config == TRUE)
2598 printf("Checking time periods...\n");
2599
2600 for(temp_timeperiod = timeperiod_list, total_objects = 0; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next, total_objects++) {
2601
2602 /* check for illegal characters in timeperiod name */
2603 if(use_precached_objects == FALSE) {
2604 if(contains_illegal_object_chars(temp_timeperiod->name) == TRUE) {
2605 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The name of time period '%s' contains one or more illegal characters.", temp_timeperiod->name);
2606 errors++;
2607 }
2608 }
2609
2610 /* check for valid timeperiod names in exclusion list */
2611 for(temp_timeperiodexclusion = temp_timeperiod->exclusions; temp_timeperiodexclusion != NULL; temp_timeperiodexclusion = temp_timeperiodexclusion->next) {
2612
2613 temp_timeperiod2 = find_timeperiod(temp_timeperiodexclusion->timeperiod_name);
2614 if(temp_timeperiod2 == NULL) {
2615 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Excluded time period '%s' specified in timeperiod '%s' is not defined anywhere!", temp_timeperiodexclusion->timeperiod_name, temp_timeperiod->name);
2616 errors++;
2617 }
2618
2619 /* save the timeperiod pointer for later */
2620 temp_timeperiodexclusion->timeperiod_ptr = temp_timeperiod2;
2621 }
2622 }
2623
2624 if(verify_config == TRUE)
2625 printf("\tChecked %d time periods.\n", total_objects);
2626
2627
2628
2629 /* update warning and error count */
2630 *w += warnings;
2631 *e += errors;
2632
2633 return (errors > 0) ? ERROR : OK;
2634 }
2635
2636
2637 /* dfs status values */
2638 #define DFS_UNCHECKED 0 /* default value */
2639 #define DFS_TEMP_CHECKED 1 /* check just one time */
2640 #define DFS_OK 2 /* no problem */
2641 #define DFS_NEAR_LOOP 3 /* has trouble sons */
2642 #define DFS_LOOPY 4 /* is a part of a loop */
2643
2644 #define dfs_get_status(h) h->circular_path_checked
2645 #define dfs_unset_status(h) h->circular_path_checked = 0
2646 #define dfs_set_status(h, flag) h->circular_path_checked = (flag)
2647 #define dfs_host_status(h) (h ? dfs_get_status(h) : DFS_OK)
2648
2649 /**
2650 * Modified version of Depth-first Search
2651 * http://en.wikipedia.org/wiki/Depth-first_search
2652 */
dfs_host_path(host * root)2653 static int dfs_host_path(host *root) {
2654 hostsmember *child = NULL;
2655
2656 if(!root)
2657 return DFS_NEAR_LOOP;
2658
2659 if(dfs_get_status(root) != DFS_UNCHECKED)
2660 return dfs_get_status(root);
2661
2662 /* Mark the root temporary checked */
2663 dfs_set_status(root, DFS_TEMP_CHECKED);
2664
2665 /* We are scanning the children */
2666 for(child = root->child_hosts; child != NULL; child = child->next) {
2667 int child_status = dfs_get_status(child->host_ptr);
2668
2669 /* If a child is not checked, check it */
2670 if(child_status == DFS_UNCHECKED)
2671 child_status = dfs_host_path(child->host_ptr);
2672
2673 /* If a child already temporary checked, its a problem,
2674 * loop inside, and its a acked status */
2675 if(child_status == DFS_TEMP_CHECKED) {
2676 dfs_set_status(child->host_ptr, DFS_LOOPY);
2677 dfs_set_status(root, DFS_LOOPY);
2678 }
2679
2680 /* If a child already temporary checked, its a problem, loop inside */
2681 if(child_status == DFS_NEAR_LOOP || child_status == DFS_LOOPY) {
2682 /* if a node is know to be part of a loop, do not let it be less */
2683 if(dfs_get_status(root) != DFS_LOOPY)
2684 dfs_set_status(root, DFS_NEAR_LOOP);
2685
2686 /* we already saw this child, it's a problem */
2687 dfs_set_status(child->host_ptr, DFS_LOOPY);
2688 }
2689 }
2690
2691 /*
2692 * If root have been modified, do not set it OK
2693 * A node is OK if and only if all of his children are OK
2694 * If it does not have child, goes ok
2695 */
2696 if(dfs_get_status(root) == DFS_TEMP_CHECKED)
2697 dfs_set_status(root, DFS_OK);
2698 return dfs_get_status(root);
2699 }
2700
2701
2702 /* check for circular paths and dependencies */
pre_flight_circular_check(int * w,int * e)2703 int pre_flight_circular_check(int *w, int *e) {
2704 host *temp_host = NULL;
2705 servicedependency *temp_sd = NULL;
2706 servicedependency *temp_sd2 = NULL;
2707 hostdependency *temp_hd = NULL;
2708 hostdependency *temp_hd2 = NULL;
2709 int found = FALSE;
2710 int result = OK;
2711 int warnings = 0;
2712 int errors = 0;
2713
2714
2715 /* bail out if we aren't supposed to verify circular paths */
2716 if(verify_circular_paths == FALSE)
2717 return OK;
2718
2719
2720 /********************************************/
2721 /* check for circular paths between hosts */
2722 /********************************************/
2723 if(verify_config == TRUE)
2724 printf("Checking for circular paths between hosts...\n");
2725
2726 /* check routes between all hosts */
2727 found = FALSE;
2728 result = OK;
2729
2730
2731 /* We clean the dsf status from previous check */
2732 for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {
2733 dfs_set_status(temp_host, DFS_UNCHECKED);
2734 }
2735
2736 for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {
2737 if(dfs_host_path(temp_host) == DFS_LOOPY)
2738 errors = 1;
2739 }
2740
2741 for(temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) {
2742 if(dfs_get_status(temp_host) == DFS_LOOPY)
2743 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: The host '%s' is part of a circular parent/child chain!", temp_host->name);
2744 /* clean DFS status */
2745 dfs_set_status(temp_host, DFS_UNCHECKED);
2746 }
2747
2748
2749 /********************************************/
2750 /* check for circular dependencies */
2751 /********************************************/
2752 if(verify_config == TRUE)
2753 printf("Checking for circular host and service dependencies...\n");
2754
2755 /* check execution dependencies between all services */
2756 for(temp_sd = servicedependency_list; temp_sd != NULL; temp_sd = temp_sd->next) {
2757
2758 /* clear checked flag for all dependencies */
2759 for(temp_sd2 = servicedependency_list; temp_sd2 != NULL; temp_sd2 = temp_sd2->next)
2760 temp_sd2->circular_path_checked = FALSE;
2761
2762 found = check_for_circular_servicedependency_path(temp_sd, temp_sd, EXECUTION_DEPENDENCY);
2763 if(found == TRUE) {
2764 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular execution dependency (which could result in a deadlock) exists for service '%s' on host '%s'!", temp_sd->service_description, temp_sd->host_name);
2765 errors++;
2766 }
2767 }
2768
2769 /* check notification dependencies between all services */
2770 for(temp_sd = servicedependency_list; temp_sd != NULL; temp_sd = temp_sd->next) {
2771
2772 /* clear checked flag for all dependencies */
2773 for(temp_sd2 = servicedependency_list; temp_sd2 != NULL; temp_sd2 = temp_sd2->next)
2774 temp_sd2->circular_path_checked = FALSE;
2775
2776 found = check_for_circular_servicedependency_path(temp_sd, temp_sd, NOTIFICATION_DEPENDENCY);
2777 if(found == TRUE) {
2778 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular notification dependency (which could result in a deadlock) exists for service '%s' on host '%s'!", temp_sd->service_description, temp_sd->host_name);
2779 errors++;
2780 }
2781 }
2782
2783 /* check execution dependencies between all hosts */
2784 for(temp_hd = hostdependency_list; temp_hd != NULL; temp_hd = temp_hd->next) {
2785
2786 /* clear checked flag for all dependencies */
2787 for(temp_hd2 = hostdependency_list; temp_hd2 != NULL; temp_hd2 = temp_hd2->next)
2788 temp_hd2->circular_path_checked = FALSE;
2789
2790 found = check_for_circular_hostdependency_path(temp_hd, temp_hd, EXECUTION_DEPENDENCY);
2791 if(found == TRUE) {
2792 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular execution dependency (which could result in a deadlock) exists for host '%s'!", temp_hd->host_name);
2793 errors++;
2794 }
2795 }
2796
2797 /* check notification dependencies between all hosts */
2798 for(temp_hd = hostdependency_list; temp_hd != NULL; temp_hd = temp_hd->next) {
2799
2800 /* clear checked flag for all dependencies */
2801 for(temp_hd2 = hostdependency_list; temp_hd2 != NULL; temp_hd2 = temp_hd2->next)
2802 temp_hd2->circular_path_checked = FALSE;
2803
2804 found = check_for_circular_hostdependency_path(temp_hd, temp_hd, NOTIFICATION_DEPENDENCY);
2805 if(found == TRUE) {
2806 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: A circular notification dependency (which could result in a deadlock) exists for host '%s'!", temp_hd->host_name);
2807 errors++;
2808 }
2809 }
2810
2811
2812 /* update warning and error count */
2813 *w += warnings;
2814 *e += errors;
2815
2816 return (errors > 0) ? ERROR : OK;
2817 }
2818
2819