1 /*
2 * AIDE (Advanced Intrusion Detection Environment)
3 *
4 * Copyright (C) 1999-2006, 2010-2013, 2015-2017, 2019-2021 Rami Lehti,
5 * Pablo Virolainen, Mike Markley, Richard van den Berg,
6 * Hannes von Haugwitz
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include "aide.h"
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <signal.h>
31 #include <sys/types.h>
32 #include <dirent.h>
33 #include <time.h>
34
35 #if HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38
39 #include "md.h"
40 #include "commandconf.h"
41 #include "report.h"
42 #include "db_config.h"
43 #include "db_disk.h"
44 #include "db.h"
45 #include "do_md.h"
46 #include "log.h"
47 #include "errorcodes.h"
48 #include "gen_list.h"
49 #include "getopt.h"
50 #include "list.h"
51 #include "util.h"
52 #include "base64.h"
53 /*for locale support*/
54 #include "locale-aide.h"
55 /*for locale support*/
56 db_config* conf;
57 char* before = NULL;
58 char* after = NULL;
59
60 #ifndef MAXHOSTNAMELEN
61 #define MAXHOSTNAMELEN 256
62 #endif
63
usage(int exitvalue)64 static void usage(int exitvalue)
65 {
66 fprintf(stdout,
67 _("Aide " AIDEVERSION" \n\n"
68 "Usage: aide [options] command\n\n"
69 "Commands:\n"
70 " -i, --init\t\tInitialize the database\n"
71 " -n, --dry-init\tTraverse the file system and match each file against rule tree\n"
72 " -C, --check\t\tCheck the database\n"
73 " -u, --update\t\tCheck and update the database non-interactively\n"
74 " -E, --compare\t\tCompare two databases\n\n"
75 "Miscellaneous:\n"
76 " -D,\t\t\t--config-check\t\t\tTest the configuration file\n"
77 " -p file_type:path\t--path-check=file_type:path\tMatch file type and path against rule tree\n"
78 " -v,\t\t\t--version\t\t\tShow version of AIDE and compilation options\n"
79 " -h,\t\t\t--help\t\t\t\tShow this help message\n\n"
80 "Options:\n"
81 " -c [cfgfile]\t--config=[cfgfile]\tGet config options from [cfgfile]\n"
82 " -l [REGEX]\t--limit=[REGEX]\t\tLimit command to entries matching [REGEX]\n"
83 " -B \"OPTION\"\t--before=\"OPTION\"\tBefore configuration file is read define OPTION\n"
84 " -A \"OPTION\"\t--after=\"OPTION\"\tAfter configuration file is read define OPTION\n"
85 " -L [level]\t--log-level=[level]\tSet log message level to [level]\n"
86 "\n")
87 );
88
89 exit(exitvalue);
90 }
91
92 static void sig_handler(int);
93
init_sighandler()94 static void init_sighandler()
95 {
96 signal(SIGBUS,sig_handler);
97 signal(SIGTERM,sig_handler);
98 signal(SIGUSR1,sig_handler);
99 signal(SIGHUP,sig_handler);
100
101 return;
102 }
103
sig_handler(int signum)104 static void sig_handler(int signum)
105 {
106 switch(signum){
107 case SIGBUS : {
108 if(conf->catch_mmap==1){
109 log_msg(LOG_LEVEL_NOTICE, "Caught SIGBUS while mmapping. File was truncated while aide was running?");
110 conf->catch_mmap=0;
111 } else {
112 log_msg(LOG_LEVEL_ERROR, "Caught SIGBUS. Exiting");
113 exit(EXIT_FAILURE);
114 }
115 break;
116 }
117 case SIGHUP : {
118 log_msg(LOG_LEVEL_INFO, "Caught SIGHUP");
119 break;
120 }
121 case SIGTERM : {
122 log_msg(LOG_LEVEL_INFO, "Caught SIGTERM. Use SIGKILL to terminate");
123 break;
124 }
125 case SIGUSR1 : {
126 log_msg(LOG_LEVEL_INFO, "Caught SIGUSR1, toggle debug level: set log level to %s", get_log_level_name(toogle_log_level(LOG_LEVEL_DEBUG)));
127 break;
128 }
129 }
130 init_sighandler();
131
132 return;
133 }
134
print_version(void)135 static void print_version(void)
136 {
137 fprintf(stdout,
138 "Aide " AIDEVERSION "\n\n"
139 "Compiled with the following options:\n\n" AIDECOMPILEOPTIONS "\n");
140
141 fprintf(stdout, "Default config values:\n");
142 fprintf(stdout, "config file: %s\n", conf->config_file?conf->config_file:"<none>");
143 fprintf(stdout, "database_in: %s\n",
144 #ifdef DEFAULT_DB
145 DEFAULT_DB
146 #else
147 "<none>"
148 #endif
149 ),
150 fprintf(stdout, "database_out: %s\n",
151 #ifdef DEFAULT_DB_OUT
152 DEFAULT_DB_OUT
153 #else
154 "<none>"
155 #endif
156 ),
157
158 fprintf(stdout, "\nAvailable hashsum groups:\n");
159 DB_ATTR_TYPE available_hashsums = get_hashes(false);
160 for (int i = 0; i < num_hashes; ++i) {
161 fprintf(stdout, "%s: %s\n", attributes[hashsums[i].attribute].config_name, ATTR(hashsums[i].attribute)&available_hashsums?"yes":"no");
162 }
163
164 fprintf(stdout, "\nDefault compound groups:\n");
165 char* predefined_groups[] = { "R", "L", ">", "H", "X" };
166 for (unsigned long i = 0 ; i < sizeof(predefined_groups)/sizeof(char*); ++i) {
167 char* str;
168 fprintf(stdout, "%s: %s\n", predefined_groups[i], str = diff_attributes(0, get_groupval(predefined_groups[i])));
169 free(str);
170 }
171
172 exit(0);
173 }
174
append_line_to_config(char * config,char * line)175 static char *append_line_to_config(char *config, char *line) {
176 size_t line_length = strlen(line);
177 if (config == NULL) {
178 config = checked_malloc((line_length+2)*sizeof(char));
179 strcpy(config,line);
180 strcat(config,"\n");
181 } else {
182 char *tmp = checked_malloc(sizeof(char) *(strlen(config)+line_length+2));
183 strcpy(tmp,config);
184 strcat(tmp,line);
185 strcat(tmp,"\n");
186 free(config);
187 config=tmp;
188 }
189 return config;
190 }
191
192 #define INVALID_ARGUMENT(option, format, ...) \
193 fprintf(stderr, "%s: (%s): " #format "\n", argv[0], option, __VA_ARGS__); \
194 exit(INVALID_ARGUMENT_ERROR);
195
196 #define ACTION_CASE(longopt, option, _action, desc) \
197 case option: { \
198 if(conf->action==0){ \
199 conf->action=_action; \
200 log_msg(LOG_LEVEL_INFO,"(%s): %s command", longopt, desc); \
201 } else { \
202 INVALID_ARGUMENT(longopt, %s, "cannot have multiple commands on a single commandline") \
203 exit(INVALID_ARGUMENT_ERROR); \
204 } \
205 break; \
206 }
207
read_param(int argc,char ** argv)208 static void read_param(int argc,char**argv)
209 {
210 int option = -1;
211 int i=0;
212
213
214 static struct option options[] =
215 {
216 { "help", no_argument, NULL, 'h' },
217 { "verbose", optional_argument, NULL, 'V'},
218 { "version", no_argument, NULL, 'v'},
219 { "config", required_argument, NULL, 'c'},
220 { "before", required_argument, NULL, 'B'},
221 { "after", required_argument, NULL, 'A'},
222 { "report", no_argument, NULL, 'r'},
223 { "init", no_argument, NULL, 'i'},
224 { "dry-init", no_argument, NULL, 'n'},
225 { "check", no_argument, NULL, 'C'},
226 { "update", no_argument, NULL, 'u'},
227 { "config-check", no_argument, NULL, 'D'},
228 { "path-check", required_argument, NULL, 'p'},
229 { "limit", required_argument, NULL, 'l'},
230 { "log-level", required_argument, NULL, 'L'},
231 { "compare", no_argument, NULL, 'E'},
232 { NULL,0,NULL,0 }
233 };
234
235 while(1){
236 option = getopt_long(argc, argv, "hL:V::vc:l:p:B:A:riCuDEn", options, &i);
237 if(option==-1)
238 break;
239 switch(option)
240 {
241 case 'h':{
242 usage(0);
243 break;
244 }
245 case 'v':{
246 print_version();
247 break;
248 }
249 case 'V':{
250 INVALID_ARGUMENT("--verbose", %s, "option no longer supported, use 'log_level' and 'report_level' options instead (see man aide.conf for details)")
251 break;
252 }
253 case 'c':{
254 conf->config_file=optarg;
255 log_msg(LOG_LEVEL_INFO,_("(--config): set config file to '%s'"), conf->config_file);
256 break;
257 }
258 case 'B': {
259 before = append_line_to_config(before, optarg);
260 log_msg(LOG_LEVEL_INFO,_("(--before): append '%s' to before config"), optarg);
261 break;
262 }
263 case 'A': {
264 after = append_line_to_config(after, optarg);
265 log_msg(LOG_LEVEL_INFO,_("(--after): append '%s' to after config"), optarg);
266 break;
267 }
268 case 'l': {
269 const char* pcre_error;
270 int pcre_erroffset;
271 conf->limit=checked_malloc(strlen(optarg)+1);
272 strcpy(conf->limit,optarg);
273 if((conf->limit_crx=pcre_compile(conf->limit, PCRE_ANCHORED, &pcre_error, &pcre_erroffset, NULL)) == NULL) {
274 INVALID_ARGUMENT("--limit", error in regular expression '%s' at %i: %s, conf->limit, pcre_erroffset, pcre_error)
275 }
276 log_msg(LOG_LEVEL_INFO,_("(--limit): set limit to '%s'"), conf->limit);
277 break;
278 }
279 case 'L':{
280 LOG_LEVEL level = get_log_level_from_string(optarg);
281 if (level == LOG_LEVEL_UNSET) {
282 INVALID_ARGUMENT("--log-level", invalid log level '%s' (see man aide.conf for details), optarg)
283 } else {
284 set_log_level(level);
285 log_msg(LOG_LEVEL_INFO,"(--log-level): set log level to '%s'", optarg);
286 }
287 break;
288 }
289 case 'p':{
290 if(conf->action==0){
291 conf->action=DO_DRY_RUN;
292 log_msg(LOG_LEVEL_INFO,"(--path-check): path check command");
293
294 if (strlen(optarg) >= 3 && optarg[1] == ':') {
295 RESTRICTION_TYPE file_type = get_restriction_from_char(*optarg);
296 if (file_type == FT_NULL) {
297 INVALID_ARGUMENT("--path-check", invalid file type '%c' (see man aide for details), *optarg)
298 } else {
299 conf->check_file_type = file_type;
300 if (optarg[2] != '/') {
301 INVALID_ARGUMENT("--path-check", '%s' needs to be an absolute path, optarg+2)
302 } else {
303 conf->check_path = checked_strdup(optarg+2);
304 log_msg(LOG_LEVEL_INFO,"(--path-check): set path to '%s' (filetype: %c)", optarg+2, get_restriction_char(conf->check_file_type));
305 }
306 }
307 } else {
308 INVALID_ARGUMENT("--path-check", %s, "missing file type or path (see man aide for details)")
309 }
310
311 } else {
312 INVALID_ARGUMENT("--path-check", %s, "cannot have multiple commands on a single commandline")
313 exit(INVALID_ARGUMENT_ERROR);
314 }
315 break;
316 }
317 case 'r': {
318 INVALID_ARGUMENT("--report", %s, "option no longer supported, use 'report_url' config option instead (see man aide.conf for detail)")
319 break;
320 }
321 ACTION_CASE("--init", 'i', DO_INIT, "database init")
322 ACTION_CASE("--dry-init", 'n', DO_INIT|DO_DRY_RUN, "dry init")
323 ACTION_CASE("--check", 'C', DO_COMPARE, "database check")
324 ACTION_CASE("--update", 'u', DO_INIT|DO_COMPARE, "database update")
325 ACTION_CASE("--compare", 'E', DO_DIFF, "database compare")
326 ACTION_CASE("--config-check", 'D', DO_DRY_RUN, "config check")
327 default: /* '?' */
328 exit(INVALID_ARGUMENT_ERROR);
329 }
330 }
331
332 if(optind<argc){
333 fprintf(stderr, "%s: extra parameter: '%s'\n", argv[0], argv[optind]);
334 exit(INVALID_ARGUMENT_ERROR);
335 }
336 }
337
setdefaults_before_config()338 static void setdefaults_before_config()
339 {
340 DB_ATTR_TYPE X;
341
342 conf=(db_config*)checked_malloc(sizeof(db_config));
343 conf->defsyms=NULL;
344
345 /* Setting some defaults */
346
347 log_msg(LOG_LEVEL_INFO, "initialise rule tree");
348 conf->tree=init_tree();
349 conf->database_add_metadata=1;
350 conf->report_detailed_init=0;
351 conf->report_base16=0;
352 conf->report_quiet=0;
353 conf->report_append=false;
354 conf->report_ignore_added_attrs = 0;
355 conf->report_ignore_removed_attrs = 0;
356 conf->report_ignore_changed_attrs = 0;
357 conf->report_force_attrs = 0;
358 #ifdef WITH_E2FSATTRS
359 conf->report_ignore_e2fsattrs = 0UL;
360 #endif
361
362 conf->check_path=NULL;
363 conf->check_file_type = FT_REG;
364
365 conf->report_urls=NULL;
366 conf->report_level=REPORT_LEVEL_CHANGED_ATTRIBUTES;
367
368 conf->config_file=
369 #ifdef CONFIG_FILE
370 CONFIG_FILE
371 #else
372 NULL
373 #endif
374 ;
375 conf->config_version=NULL;
376
377 #ifdef WITH_ACL
378 conf->no_acl_on_symlinks=0; /* zero means don't do ACLs on symlinks */
379 #endif
380 conf->db_out_attrs = ATTR(attr_filename)|ATTR(attr_attr)|ATTR(attr_perm)|ATTR(attr_inode);
381
382 conf->symlinks_found=0;
383
384 conf->database_in.url = NULL;
385 conf->database_in.filename=NULL;
386 conf->database_in.linenumber=0;
387 conf->database_in.linebuf=NULL;
388 conf->database_in.fp=NULL;
389 #ifdef WITH_ZLIB
390 conf->database_in.gzp = NULL;
391 #endif
392 conf->database_in.lineno = 0;
393 conf->database_in.fields = NULL;
394 conf->database_in.num_fields = 0;
395 conf->database_in.buffer_state = NULL;
396 conf->database_in.mdc = NULL;
397 conf->database_in.db_line = NULL;
398
399 conf->database_out.url = NULL;
400 conf->database_out.filename=NULL;
401 conf->database_out.linenumber=0;
402 conf->database_out.linebuf=NULL;
403 conf->database_out.fp=NULL;
404 #ifdef WITH_ZLIB
405 conf->database_out.gzp = NULL;
406 #endif
407 conf->database_out.lineno = 0;
408 conf->database_out.fields = NULL;
409 conf->database_out.num_fields = 0;
410 conf->database_out.buffer_state = NULL;
411 conf->database_out.mdc = NULL;
412 conf->database_out.db_line = NULL;
413
414 conf->database_new.url = NULL;
415 conf->database_new.filename=NULL;
416 conf->database_new.linenumber=0;
417 conf->database_new.linebuf=NULL;
418 conf->database_new.fp=NULL;
419 #ifdef WITH_ZLIB
420 conf->database_new.gzp = NULL;
421 #endif
422 conf->database_new.lineno = 0;
423 conf->database_new.fields = NULL;
424 conf->database_new.num_fields = 0;
425 conf->database_new.buffer_state = NULL;
426 conf->database_new.mdc = NULL;
427 conf->database_new.db_line = NULL;
428
429 conf->db_attrs = get_hashes(false);
430
431 #ifdef WITH_ZLIB
432 conf->gzip_dbout=0;
433 #endif
434
435 conf->action=0;
436 conf->catch_mmap=0;
437
438 conf->warn_dead_symlinks=0;
439
440 conf->report_grouped=1;
441
442 conf->report_summarize_changes=1;
443
444 conf->root_prefix=NULL;
445 conf->root_prefix_length=0;
446
447 conf->limit=NULL;
448 conf->limit_crx=NULL;
449
450 conf->groupsyms=NULL;
451
452 conf->start_time=time(&(conf->start_time));
453
454 log_msg(LOG_LEVEL_INFO, "define default group definitions");
455
456 for (ATTRIBUTE i = 0 ; i < num_attrs ; ++i) {
457 if (attributes[i].config_name) {
458 do_groupdef(attributes[i].config_name, attributes[i].attr);
459 }
460 }
461
462 X=0LLU;
463 #ifdef WITH_ACL
464 X|=ATTR(attr_acl);
465 #endif
466 #ifdef WITH_SELINUX
467 X|=ATTR(attr_selinux);
468 #endif
469 #ifdef WITH_XATTR
470 X|=ATTR(attr_xattrs);
471 #endif
472 #ifdef WITH_E2FSATTRS
473 X|=ATTR(attr_e2fsattrs);
474 #endif
475 #ifdef WITH_CAPABILITIES
476 X|=ATTR(attr_capabilities);
477 #endif
478
479 DB_ATTR_TYPE common_attrs = ATTR(attr_perm)|ATTR(attr_ftype)|ATTR(attr_inode)|ATTR(attr_linkcount)|ATTR(attr_uid)|ATTR(attr_gid);
480
481 do_groupdef("R",common_attrs|ATTR(attr_size)|ATTR(attr_linkname)|ATTR(attr_mtime)|ATTR(attr_ctime)
482 #if defined(WITH_MHASH) || defined(WITH_GCRYPT)
483 |ATTR(attr_md5)
484 #endif
485 |X);
486 do_groupdef("L",common_attrs|ATTR(attr_linkname)|X);
487 do_groupdef(">",common_attrs|ATTR(attr_sizeg)|ATTR(attr_linkname)|X);
488 do_groupdef("H",get_hashes(false));
489 do_groupdef("X",X);
490 do_groupdef("E",0);
491
492 }
493
setdefaults_after_config()494 static void setdefaults_after_config()
495 {
496 int linenumber=1;
497
498 #ifdef DEFAULT_DB
499 if(conf->database_in.url==NULL){
500 do_dbdef(DB_TYPE_IN, DEFAULT_DB, linenumber++, "(default)", NULL);
501 }
502 #endif
503 #ifdef DEFAULT_DB_OUT
504 if(conf->database_out.url==NULL){
505 do_dbdef(DB_TYPE_OUT, DEFAULT_DB_OUT, linenumber++, "(default)", NULL);
506 }
507 #endif
508
509 if(conf->root_prefix==NULL){
510 do_rootprefix("" , linenumber++, "(default)", NULL);
511 }
512
513 if(conf->report_urls==NULL){
514 do_repurldef("stdout" , linenumber++, "(default)", NULL);
515 }
516
517 if(conf->action==0){
518 conf->action=DO_COMPARE;
519 }
520
521 if (is_log_level_unset()) {
522 set_log_level(LOG_LEVEL_WARNING);
523 };
524 }
525
526
527
main(int argc,char ** argv)528 int main(int argc,char**argv)
529 {
530 int errorno=0;
531
532 #ifdef USE_LOCALE
533 setlocale(LC_ALL,"");
534 bindtextdomain(PACKAGE,LOCALEDIR);
535 textdomain(PACKAGE);
536 #endif
537 umask(0177);
538 init_sighandler();
539
540 setdefaults_before_config();
541
542 log_msg(LOG_LEVEL_INFO, "read command line parameters");
543 read_param(argc,argv);
544
545 /* get hostname */
546 conf->hostname = checked_malloc(sizeof(char) * MAXHOSTNAMELEN + 1);
547 if (gethostname(conf->hostname,MAXHOSTNAMELEN) == -1) {
548 log_msg(LOG_LEVEL_WARNING,"gethostname failed: %s", strerror(errno));
549 free(conf->hostname);
550 conf->hostname = NULL;
551 } else {
552 log_msg(LOG_LEVEL_DEBUG, "hostname: '%s'", conf->hostname);
553 }
554
555 log_msg(LOG_LEVEL_INFO, "parse configuration");
556 errorno=parse_config(before, conf->config_file, after);
557 if (errorno==RETFAIL){
558 exit(INVALID_CONFIGURELINE_ERROR);
559 }
560 free (before);
561 free (after);
562
563 setdefaults_after_config();
564
565 log_msg(LOG_LEVEL_CONFIG, "report_urls:");
566 log_report_urls(LOG_LEVEL_CONFIG);
567
568 log_msg(LOG_LEVEL_RULE, "rule tree:");
569 log_tree(LOG_LEVEL_RULE, conf->tree, 0);
570
571 if (conf->check_path) {
572 rx_rule* rule = NULL;
573 int match = check_rxtree(conf->check_path, conf->tree, &rule, conf->check_file_type, true);
574 if (match < 0) {
575 fprintf(stdout, "[ ] %c '%s': outside of limit '%s'\n", get_restriction_char(conf->check_file_type), conf->check_path, conf->limit);
576 exit(2);
577 } else {
578 exit(match?0:1);
579 }
580 }
581
582 /* Let's do some sanity checks for the config */
583 if (conf->action&(DO_DIFF|DO_COMPARE) && !(conf->database_in.url)) {
584 log_msg(LOG_LEVEL_ERROR,_("missing 'database_in', config option is required"));
585 exit(INVALID_ARGUMENT_ERROR);
586 }
587 if (conf->action&DO_INIT && !(conf->database_out.url)) {
588 log_msg(LOG_LEVEL_ERROR,_("missing 'database_out', config option is required"));
589 exit(INVALID_ARGUMENT_ERROR);
590 }
591 if(conf->database_in.url && conf->database_out.url && cmpurl(conf->database_in.url,conf->database_out.url)==RETOK){
592 log_msg(LOG_LEVEL_NOTICE, "input and output database URLs are the same: '%s'", (conf->database_in.url)->value);
593 if((conf->action&DO_INIT)&&(conf->action&DO_COMPARE)){
594 log_msg(LOG_LEVEL_ERROR,_("input and output database urls cannot be the same "
595 "when doing database update"));
596 exit(INVALID_ARGUMENT_ERROR);
597 }
598 if(conf->action&DO_DIFF){
599 log_msg(LOG_LEVEL_ERROR,_("both input databases cannot be the same "
600 "when doing database compare"));
601 exit(INVALID_ARGUMENT_ERROR);
602 }
603 };
604 if((conf->action&DO_DIFF)&&(!(conf->database_new.url)||!(conf->database_in.url))){
605 log_msg(LOG_LEVEL_ERROR,_("must have both input databases defined for "
606 "database compare"));
607 exit(INVALID_ARGUMENT_ERROR);
608 }
609
610 if (conf->action&DO_INIT && conf->action&DO_DRY_RUN) {
611 if(db_disk_init()==RETFAIL) {
612 exit(IO_ERROR);
613 }
614 log_msg(LOG_LEVEL_INFO, "populate tree (dry-run)");
615 populate_tree(conf->tree, true);
616 exit (0);
617 }
618
619 if (!(conf->action&DO_DRY_RUN)) {
620
621 if (!init_report_urls()) {
622 exit(INVALID_CONFIGURELINE_ERROR);
623 }
624
625 if (conf->action&(DO_INIT|DO_COMPARE) && conf->root_prefix_length > 0) {
626 DIR *dir;
627 if((dir = opendir(conf->root_prefix)) != NULL) {
628 closedir(dir);
629 } else {
630 log_msg(LOG_LEVEL_ERROR,"opendir() for root_prefix %s failed: %s", conf->root_prefix, strerror(errno));
631 exit(INVALID_CONFIGURELINE_ERROR);
632 }
633 }
634 if(conf->action&DO_INIT){
635 if(db_init(&(conf->database_out), false,
636 #ifdef WITH_ZLIB
637 conf->gzip_dbout
638 #else
639 false
640 #endif
641 ) == RETFAIL) {
642 exit(IO_ERROR);
643 }
644 if(db_writespec(conf)==RETFAIL){
645 log_msg(LOG_LEVEL_ERROR,_("Error while writing database. Exiting.."));
646 exit(IO_ERROR);
647 }
648 }
649 if((conf->action&DO_INIT)||(conf->action&DO_COMPARE)){
650 if(db_disk_init()==RETFAIL)
651 exit(IO_ERROR);
652 }
653 if((conf->action&DO_COMPARE)||(conf->action&DO_DIFF)){
654 if(db_init(&(conf->database_in), true, false)==RETFAIL)
655 exit(IO_ERROR);
656 }
657 if(conf->action&DO_DIFF){
658 if(db_init(&(conf->database_new), true, false)==RETFAIL)
659 exit(IO_ERROR);
660 }
661
662 log_msg(LOG_LEVEL_INFO, "populate tree");
663 populate_tree(conf->tree, false);
664
665 if(conf->action&DO_INIT) {
666 log_msg(LOG_LEVEL_INFO, "write new entries to database: %s:%s", get_url_type_string((conf->database_out.url)->type), (conf->database_out.url)->value);
667 write_tree(conf->tree);
668 }
669
670 db_close();
671
672 log_msg(LOG_LEVEL_INFO, "generate reports");
673
674 int exitcode = gen_report(conf->tree);
675
676 log_msg(LOG_LEVEL_INFO, "exit AIDE with exit code '%d'", exitcode);
677
678 exit(exitcode);
679 }
680 return RETOK;
681 }
682 // vi: ts=8 sw=8
683