Imported Upstream version 2.7
[ossec-hids.git] / src / config / syscheck-config.c
1 /* @(#) $Id: ./src/config/syscheck-config.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All right reserved.
6  *
7  * This program is a free software; you can redistribute it
8  * and/or modify it under the terms of the GNU General Public
9  * License (version 2) as published by the FSF - Free Software
10  * Foundation
11  */
12
13
14 #include "shared.h"
15
16 #include "syscheck-config.h"
17
18
19
20 int dump_syscheck_entry(config *syscheck, char *entry, int vals, int reg, char *restrictfile)
21 {
22     int pl = 0;
23
24     if(reg == 1)
25     {
26         #ifdef WIN32
27         if(syscheck->registry == NULL)
28         {
29             os_calloc(2, sizeof(char *), syscheck->registry);
30             syscheck->registry[pl + 1] = NULL;
31             os_strdup(entry, syscheck->registry[pl]);
32         }
33         else
34         {
35             while(syscheck->registry[pl] != NULL)
36             {
37                 pl++;
38             }
39             os_realloc(syscheck->registry, (pl +2) * sizeof(char *),
40                         syscheck->registry);
41             syscheck->registry[pl + 1] = NULL;
42             os_strdup(entry, syscheck->registry[pl]);
43         }
44         #endif
45
46     }
47
48
49     else
50     {
51         if(syscheck->dir == NULL)
52         {
53             os_calloc(2, sizeof(char *), syscheck->dir);
54             syscheck->dir[pl + 1] = NULL;
55             os_strdup(entry, syscheck->dir[pl]);
56
57             os_calloc(2, sizeof(int), syscheck->opts);
58             syscheck->opts[pl + 1] = 0;
59             syscheck->opts[pl] = vals;
60
61             os_calloc(2, sizeof(OSMatch *), syscheck->filerestrict);
62             syscheck->filerestrict[pl] = NULL;
63             syscheck->filerestrict[pl + 1] = NULL;
64         }
65         else
66         {
67             while(syscheck->dir[pl] != NULL)
68             {
69                 pl++;
70             }
71             os_realloc(syscheck->dir, (pl +2) * sizeof(char *),
72                        syscheck->dir);
73             syscheck->dir[pl + 1] = NULL;
74             os_strdup(entry, syscheck->dir[pl]);
75
76             os_realloc(syscheck->opts, (pl +2) * sizeof(int),
77                        syscheck->opts);
78             syscheck->opts[pl + 1] = 0;
79             syscheck->opts[pl] = vals;
80
81             os_realloc(syscheck->filerestrict, (pl +2) * sizeof(char *),
82                        syscheck->filerestrict);
83             syscheck->filerestrict[pl] = NULL;
84             syscheck->filerestrict[pl + 1] = NULL;
85         }
86         if(restrictfile)
87         {
88             os_calloc(1, sizeof(OSMatch), syscheck->filerestrict[pl]);
89             if(!OSMatch_Compile(restrictfile, syscheck->filerestrict[pl], 0))
90             {
91                 OSMatch *ptm;
92
93                 ptm = syscheck->filerestrict[pl];
94
95                 merror(REGEX_COMPILE, ARGV0, restrictfile,
96                        ptm->error);
97                 free(syscheck->filerestrict[pl]);
98                 syscheck->filerestrict[pl] = NULL;
99             }
100         }
101     }
102
103     return(1);
104 }
105
106
107
108 /* Read Windows registry configuration */
109 #ifdef WIN32
110 int read_reg(config *syscheck, char *entries)
111 {
112     int i;
113     char **entry;
114     char *tmp_str;
115
116
117     /* Getting each entry separately */
118     entry = OS_StrBreak(',', entries, MAX_DIR_SIZE); /* Max number */
119
120
121     /* entry can not be null */
122     if(entry == NULL)
123     {
124         return(0);
125     }
126
127
128     /* Doing it for each Entry */
129     while(*entry)
130     {
131         char *tmp_entry;
132
133         tmp_entry = *entry;
134
135         /* Removing spaces at the beginning */
136         while(*tmp_entry == ' ')
137         {
138             tmp_entry++;
139         }
140
141         /* Removing spaces at the end */
142         tmp_str = strchr(tmp_entry, ' ');
143         if(tmp_str)
144         {
145             tmp_str++;
146
147             /* Checking if it is really at the end */
148             if((*tmp_str == '\0') || (*tmp_str == ' '))
149             {
150                 tmp_str--;
151                 *tmp_str = '\0';
152             }
153         }
154
155
156         /* Adding entries - looking for the last available */
157         i = 0;
158         while(syscheck->registry && syscheck->registry[i])
159         {
160             int str_len_i;
161             int str_len_dir;
162
163             str_len_dir = strlen(tmp_entry);
164             str_len_i = strlen(syscheck->registry[i]);
165
166             if(str_len_dir > str_len_i)
167             {
168                 str_len_dir = str_len_i;
169             }
170
171             /* Duplicated entry */
172             if(strcmp(syscheck->registry[i], tmp_entry) == 0)
173             {
174                 merror(SK_DUP, ARGV0, tmp_entry);
175                 return(1);
176             }
177             i++;
178         }
179
180         /* Adding new entry */
181         dump_syscheck_entry(syscheck, tmp_entry, 0, 1, NULL);
182
183
184         /* Next entry */
185         entry++;
186     }
187
188     return(1);
189 }
190 #endif /* For read_reg */
191
192
193
194
195 /* Read directories attributes */
196 int read_attr(config *syscheck, char *dirs, char **g_attrs, char **g_values)
197 {
198     char *xml_check_all = "check_all";
199     char *xml_check_sum = "check_sum";
200     char *xml_check_sha1sum = "check_sha1sum";
201     char *xml_check_md5sum = "check_md5sum";
202     char *xml_check_size = "check_size";
203     char *xml_check_owner = "check_owner";
204     char *xml_check_group = "check_group";
205     char *xml_check_perm = "check_perm";
206     char *xml_real_time = "realtime";
207     char *xml_report_changes = "report_changes";
208     char *xml_restrict = "restrict";
209
210     char *restrictfile = NULL;
211     char **dir;
212     char *tmp_str;
213     dir = OS_StrBreak(',', dirs, MAX_DIR_SIZE); /* Max number */
214     char **dir_org = dir;
215
216     int ret = 0, i;
217
218     /* Dir can not be null */
219     if(dir == NULL)
220     {
221         return(0);
222     }
223
224
225     /* Doing it for each directory */
226     while(*dir)
227     {
228         int i = 0;
229         int opts = 0;
230         char *tmp_dir;
231
232         char **attrs = NULL;
233         char **values = NULL;
234
235         tmp_dir = *dir;
236         restrictfile = NULL;
237
238         /* Removing spaces at the beginning */
239         while(*tmp_dir == ' ')
240         {
241             tmp_dir++;
242         }
243
244         /* Removing spaces at the end */
245         tmp_str = strchr(tmp_dir, ' ');
246         if(tmp_str)
247         {
248             tmp_str++;
249
250             /* Checking if it is really at the end */
251             if((*tmp_str == '\0') || (*tmp_str == ' '))
252             {
253                 tmp_str--;
254                 *tmp_str = '\0';
255             }
256         }
257
258
259         /* Getting the options */
260         if(!g_attrs || !g_values)
261         {
262             merror(SYSCHECK_NO_OPT, ARGV0, dirs);
263             ret = 0;
264             goto out_free;
265         }
266
267         attrs = g_attrs;
268         values = g_values;
269
270         while(*attrs && *values)
271         {
272             /* Checking all */
273             if(strcmp(*attrs, xml_check_all) == 0)
274             {
275                 if(strcmp(*values, "yes") == 0)
276                 {
277                     opts|=CHECK_MD5SUM;
278                     opts|=CHECK_SHA1SUM;
279                     opts|=CHECK_PERM;
280                     opts|=CHECK_SIZE;
281                     opts|=CHECK_OWNER;
282                     opts|=CHECK_GROUP;
283                 }
284                 else if(strcmp(*values, "no") == 0)
285                 {
286                 }
287                 else
288                 {
289                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
290                     ret = 0;
291                     goto out_free;
292                 }
293             }
294             /* Checking sum */
295             else if(strcmp(*attrs, xml_check_sum) == 0)
296             {
297                 if(strcmp(*values, "yes") == 0)
298                 {
299                     opts|=CHECK_MD5SUM;
300                     opts|=CHECK_SHA1SUM;
301                 }
302                 else if(strcmp(*values, "no") == 0)
303                 {
304                 }
305                 else
306                 {
307                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
308                     ret = 0;
309                     goto out_free;
310                 }
311             }
312             /* Checking md5sum */
313             else if(strcmp(*attrs, xml_check_md5sum) == 0)
314             {
315                 if(strcmp(*values, "yes") == 0)
316                 {
317                     opts|=CHECK_MD5SUM;
318                 }
319                 else if(strcmp(*values, "no") == 0)
320                 {
321                 }
322                 else
323                 {
324                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
325                     ret = 0;
326                     goto out_free;
327                 }
328             }
329             /* Checking sha1sum */
330             else if(strcmp(*attrs, xml_check_sha1sum) == 0)
331             {
332                 if(strcmp(*values, "yes") == 0)
333                 {
334                     opts|=CHECK_SHA1SUM;
335                 }
336                 else if(strcmp(*values, "no") == 0)
337                 {
338                 }
339                 else
340                 {
341                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
342                     ret = 0;
343                     goto out_free;
344                 }
345             }
346             /* Checking permission */
347             else if(strcmp(*attrs, xml_check_perm) == 0)
348             {
349                 if(strcmp(*values, "yes") == 0)
350                 {
351                     opts|=CHECK_PERM;
352                 }
353                 else if(strcmp(*values, "no") == 0)
354                 {
355                 }
356                 else
357                 {
358                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
359                     ret = 0;
360                     goto out_free;
361                 }
362             }
363             /* Checking size */
364             else if(strcmp(*attrs, xml_check_size) == 0)
365             {
366                 if(strcmp(*values, "yes") == 0)
367                 {
368                     opts|=CHECK_SIZE;
369                 }
370                 else if(strcmp(*values, "no") == 0)
371                 {
372                 }
373                 else
374                 {
375                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
376                     ret = 0;
377                     goto out_free;
378                 }
379             }
380             /* Checking owner */
381             else if(strcmp(*attrs, xml_check_owner) == 0)
382             {
383                 if(strcmp(*values, "yes") == 0)
384                 {
385                     opts|=CHECK_OWNER;
386                 }
387                 else if(strcmp(*values, "no") == 0)
388                 {
389                 }
390                 else
391                 {
392                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
393                     ret = 0;
394                     goto out_free;
395                 }
396             }
397             /* Checking group */
398             else if(strcmp(*attrs, xml_check_group) == 0)
399             {
400                 if(strcmp(*values, "yes") == 0)
401                 {
402                     opts|=CHECK_GROUP;
403                 }
404                 else if(strcmp(*values, "no") == 0)
405                 {
406                 }
407                 else
408                 {
409                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
410                     ret = 0;
411                     goto out_free;
412                 }
413             }
414             else if(strcmp(*attrs, xml_real_time) == 0)
415             {
416                 if(strcmp(*values, "yes") == 0)
417                 {
418                     opts|=CHECK_REALTIME;
419                 }
420                 else if(strcmp(*values, "no") == 0)
421                 {
422                 }
423                 else
424                 {
425                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
426                     ret = 0;
427                     goto out_free;
428                 }
429             }
430             else if(strcmp(*attrs, xml_report_changes) == 0)
431             {
432                 if(strcmp(*values, "yes") == 0)
433                 {
434                     opts|=CHECK_SEECHANGES;
435                 }
436                 else if(strcmp(*values, "no") == 0)
437                 {
438                 }
439                 else
440                 {
441                     merror(SK_INV_OPT, ARGV0, *values, *attrs);
442                     ret = 0;
443                     goto out_free;
444                 }
445             }
446             else if(strcmp(*attrs, xml_restrict) == 0)
447             {
448                 os_strdup(*values, restrictfile);
449             }
450             else
451             {
452                 merror(SK_INV_ATTR, ARGV0, *attrs);
453                 ret = 0;
454                 goto out_free;
455             }
456             attrs++; values++;
457         }
458
459
460         /* You must have something set */
461         if(opts == 0)
462         {
463             merror(SYSCHECK_NO_OPT, ARGV0, dirs);
464             if(restrictfile) free(restrictfile);
465             ret = 0;
466             goto out_free;
467         }
468
469
470         /* Adding directory - looking for the last available */
471         i = 0;
472         while(syscheck->dir && syscheck->dir[i])
473         {
474             int str_len_i;
475             int str_len_dir;
476
477             str_len_dir = strlen(tmp_dir);
478             str_len_i = strlen(syscheck->dir[i]);
479
480             if(str_len_dir > str_len_i)
481             {
482                 str_len_dir = str_len_i;
483             }
484
485             /* Duplicate entry */
486             if(strcmp(syscheck->dir[i], tmp_dir) == 0)
487             {
488                 merror(SK_DUP, ARGV0, tmp_dir);
489                 ret = 1;
490                 goto out_free;
491             }
492
493             i++;
494         }
495
496
497         /* Checking for glob. */
498         #ifndef WIN32
499         if(strchr(tmp_dir, '*') ||
500            strchr(tmp_dir, '?') ||
501            strchr(tmp_dir, '['))
502         {
503             int gindex = 0;
504             glob_t g;
505
506             if(glob(tmp_dir, 0, NULL, &g) != 0)
507             {
508                 merror(GLOB_ERROR, ARGV0, tmp_dir);
509                 ret = 1;
510                 goto out_free;
511             }
512
513             if(g.gl_pathv[0] == NULL)
514             {
515                 merror(GLOB_NFOUND, ARGV0, tmp_dir);
516                 ret = 1;
517                 goto out_free;
518             }
519
520             while(g.gl_pathv[gindex])
521             {
522                 dump_syscheck_entry(syscheck, g.gl_pathv[gindex], opts, 0, restrictfile);
523                 gindex++;
524             }
525
526             globfree(&g);
527         }
528
529         else
530         {
531             dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
532         }
533         #else
534         dump_syscheck_entry(syscheck, tmp_dir, opts, 0, restrictfile);
535         #endif
536
537         if(restrictfile)
538         {
539             free(restrictfile);
540             restrictfile = NULL;
541         }
542
543
544         /* Next entry */
545         dir++;
546     }
547
548     ret = 1;
549
550 out_free:
551
552     i = 0;
553     while(dir_org[i])
554         free(dir_org[i++]);
555
556     free(dir_org);
557
558     return ret;
559 }
560
561
562
563 int Read_Syscheck(XML_NODE node, void *configp, void *mailp)
564 {
565     int i = 0;
566
567     /* XML Definitions */
568     char *xml_directories = "directories";
569     char *xml_registry = "windows_registry";
570     char *xml_time = "frequency";
571     char *xml_scanday = "scan_day";
572     char *xml_scantime = "scan_time";
573     char *xml_ignore = "ignore";
574     char *xml_registry_ignore = "registry_ignore";
575     char *xml_auto_ignore = "auto_ignore";
576     char *xml_alert_new_files = "alert_new_files";
577     char *xml_disabled = "disabled";
578     char *xml_scan_on_start = "scan_on_start";
579     char *xml_prefilter_cmd = "prefilter_cmd";
580
581     /* Configuration example
582     <directories check_all="yes">/etc,/usr/bin</directories>
583     <directories check_owner="yes" check_group="yes" check_perm="yes"
584     check_sum="yes">/var/log</directories>
585     */
586
587     config *syscheck;
588
589     syscheck = (config *)configp;
590
591
592     while(node[i])
593     {
594         if(!node[i]->element)
595         {
596             merror(XML_ELEMNULL, ARGV0);
597             return(OS_INVALID);
598         }
599         else if(!node[i]->content)
600         {
601             merror(XML_VALUENULL, ARGV0, node[i]->element);
602             return(OS_INVALID);
603         }
604
605         /* Getting directories */
606         else if(strcmp(node[i]->element,xml_directories) == 0)
607         {
608             char dirs[OS_MAXSTR];
609
610             #ifdef WIN32
611             ExpandEnvironmentStrings(node[i]->content, dirs, sizeof(dirs) -1);
612             #else
613             strncpy(dirs, node[i]->content, sizeof(dirs) -1);
614             #endif
615
616             if(!read_attr(syscheck,
617                         dirs,
618                         node[i]->attributes,
619                         node[i]->values))
620             {
621                 return(OS_INVALID);
622             }
623         }
624         /* Getting windows registry */
625         else if(strcmp(node[i]->element,xml_registry) == 0)
626         {
627             #ifdef WIN32
628             if(!read_reg(syscheck, node[i]->content))
629             {
630                 return(OS_INVALID);
631             }
632             #endif
633         }
634         /* Getting frequency */
635         else if(strcmp(node[i]->element,xml_time) == 0)
636         {
637             if(!OS_StrIsNum(node[i]->content))
638             {
639                 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
640                 return(OS_INVALID);
641             }
642
643             syscheck->time = atoi(node[i]->content);
644         }
645         /* Getting scan time */
646         else if(strcmp(node[i]->element,xml_scantime) == 0)
647         {
648             syscheck->scan_time = OS_IsValidUniqueTime(node[i]->content);
649             if(!syscheck->scan_time)
650             {
651                 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
652                 return(OS_INVALID);
653             }
654         }
655
656         /* Getting scan day */
657         else if(strcmp(node[i]->element,xml_scanday) == 0)
658         {
659             syscheck->scan_day = OS_IsValidDay(node[i]->content);
660             if(!syscheck->scan_day)
661             {
662                 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
663                 return(OS_INVALID);
664             }
665         }
666
667         /* Getting if xml_scan_on_start. */
668         else if(strcmp(node[i]->element, xml_scan_on_start) == 0)
669         {
670             if(strcmp(node[i]->content, "yes") == 0)
671                 syscheck->scan_on_start = 1;
672             else if(strcmp(node[i]->content, "no") == 0)
673                 syscheck->scan_on_start = 0;
674             else
675             {
676                 merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
677                 return(OS_INVALID);
678             }
679         }
680
681         /* Getting if disabled. */
682         else if(strcmp(node[i]->element,xml_disabled) == 0)
683         {
684             if(strcmp(node[i]->content, "yes") == 0)
685                 syscheck->disabled = 1;
686             else if(strcmp(node[i]->content, "no") == 0)
687                 syscheck->disabled = 0;
688             else
689             {
690                 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
691                 return(OS_INVALID);
692             }
693         }
694
695         /* Getting file/dir ignore */
696         else if(strcmp(node[i]->element,xml_ignore) == 0)
697         {
698             int ign_size = 0;
699
700             /* For Windows, we attempt to expand environment variables. */
701             #ifdef WIN32
702             char *new_ig = NULL;
703             os_calloc(2048, sizeof(char), new_ig);
704
705             ExpandEnvironmentStrings(node[i]->content, new_ig, 2047);
706
707             free(node[i]->content);
708             node[i]->content = new_ig;
709             #endif
710
711             /* Adding if regex */
712             if(node[i]->attributes && node[i]->values)
713             {
714                 if(node[i]->attributes[0] && node[i]->values[0] &&
715                    (strcmp(node[i]->attributes[0], "type") == 0) &&
716                    (strcmp(node[i]->values[0], "sregex") == 0))
717                 {
718                     OSMatch *mt_pt;
719
720                     if(!syscheck->ignore_regex)
721                     {
722                         os_calloc(2, sizeof(OSMatch *),syscheck->ignore_regex);
723                         syscheck->ignore_regex[0] = NULL;
724                         syscheck->ignore_regex[1] = NULL;
725                     }
726                     else
727                     {
728                         while(syscheck->ignore_regex[ign_size] != NULL)
729                             ign_size++;
730
731                         os_realloc(syscheck->ignore_regex,
732                                 sizeof(OSMatch *)*(ign_size +2),
733                                 syscheck->ignore_regex);
734                         syscheck->ignore_regex[ign_size +1] = NULL;
735                     }
736                     os_calloc(1, sizeof(OSMatch),
737                             syscheck->ignore_regex[ign_size]);
738
739                     if(!OSMatch_Compile(node[i]->content,
740                                         syscheck->ignore_regex[ign_size], 0))
741                     {
742                         mt_pt = (OSMatch *)syscheck->ignore_regex[ign_size];
743                         merror(REGEX_COMPILE, ARGV0, node[i]->content,
744                               mt_pt->error);
745                         return(0);
746                     }
747                 }
748                 else
749                 {
750                     merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
751                     return(OS_INVALID);
752                 }
753             }
754
755             /* Adding if simple entry -- checking for duplicates */
756             else if(!os_IsStrOnArray(node[i]->content, syscheck->ignore))
757             {
758                 if(!syscheck->ignore)
759                 {
760                     os_calloc(2, sizeof(char *), syscheck->ignore);
761                     syscheck->ignore[0] = NULL;
762                     syscheck->ignore[1] = NULL;
763                 }
764                 else
765                 {
766                     while(syscheck->ignore[ign_size] != NULL)
767                         ign_size++;
768
769                     os_realloc(syscheck->ignore,
770                             sizeof(char *)*(ign_size +2),
771                             syscheck->ignore);
772                     syscheck->ignore[ign_size +1] = NULL;
773                 }
774                 os_strdup(node[i]->content,syscheck->ignore[ign_size]);
775             }
776         }
777
778         /* Getting registry ignore list */
779         else if(strcmp(node[i]->element,xml_registry_ignore) == 0)
780         {
781             #ifdef WIN32
782             int ign_size = 0;
783
784             /* Adding if regex */
785             if(node[i]->attributes && node[i]->values)
786             {
787                 if(node[i]->attributes[0] && node[i]->values[0] &&
788                    (strcmp(node[i]->attributes[0], "type") == 0) &&
789                    (strcmp(node[i]->values[0], "sregex") == 0))
790                 {
791                     OSMatch *mt_pt;
792
793                     if(!syscheck->registry_ignore_regex)
794                     {
795                         os_calloc(2, sizeof(OSMatch *),
796                                      syscheck->registry_ignore_regex);
797                         syscheck->registry_ignore_regex[0] = NULL;
798                         syscheck->registry_ignore_regex[1] = NULL;
799                     }
800                     else
801                     {
802                         while(syscheck->registry_ignore_regex[ign_size] !=NULL)
803                             ign_size++;
804
805                         os_realloc(syscheck->registry_ignore_regex,
806                                 sizeof(OSMatch *)*(ign_size +2),
807                                 syscheck->registry_ignore_regex);
808                         syscheck->registry_ignore_regex[ign_size +1] = NULL;
809                     }
810
811                     os_calloc(1, sizeof(OSMatch),
812                             syscheck->registry_ignore_regex[ign_size]);
813
814                     if(!OSMatch_Compile(node[i]->content,
815                                 syscheck->registry_ignore_regex[ign_size], 0))
816                     {
817                         mt_pt = (OSMatch *)
818                                 syscheck->registry_ignore_regex[ign_size];
819                         merror(REGEX_COMPILE, ARGV0, node[i]->content,
820                              mt_pt->error);
821                         return(0);
822                     }
823                 }
824                 else
825                 {
826                     merror(SK_INV_ATTR, ARGV0, node[i]->attributes[0]);
827                     return(OS_INVALID);
828                 }
829             }
830             /* We do not add duplicated entries */
831             else if(!os_IsStrOnArray(node[i]->content,
832                      syscheck->registry_ignore))
833             {
834                 if(!syscheck->registry_ignore)
835                 {
836                     os_calloc(2, sizeof(char *), syscheck->registry_ignore);
837                     syscheck->registry_ignore[0] = NULL;
838                     syscheck->registry_ignore[1] = NULL;
839                 }
840                 else
841                 {
842                     while(syscheck->registry_ignore[ign_size] != NULL)
843                         ign_size++;
844
845                     os_realloc(syscheck->registry_ignore,
846                             sizeof(char *)*(ign_size +2),
847                             syscheck->registry_ignore);
848                     syscheck->registry_ignore[ign_size +1] = NULL;
849                 }
850                 os_strdup(node[i]->content,syscheck->registry_ignore[ign_size]);
851             }
852             #endif
853         }
854         else if(strcmp(node[i]->element,xml_auto_ignore) == 0)
855         {
856             /* auto_ignore is not read here. */
857         }
858         else if(strcmp(node[i]->element,xml_alert_new_files) == 0)
859         {
860             /* alert_new_files option is not read here. */
861         }
862         else if(strcmp(node[i]->element,xml_prefilter_cmd) == 0)
863         {
864             char cmd[OS_MAXSTR];
865             struct stat statbuf;
866
867             #ifdef WIN32
868             ExpandEnvironmentStrings(node[i]->content, cmd, sizeof(cmd) -1);
869             #else
870             strncpy(cmd, node[i]->content, sizeof(cmd)-1);
871             #endif
872
873             if (strlen(cmd) > 0) {
874                 char statcmd[OS_MAXSTR];
875                 char *ix;
876                 strncpy(statcmd, cmd, sizeof(statcmd)-1);
877                 if (NULL != (ix = strchr(statcmd, ' '))) { *ix = '\0'; }
878                 if (stat(statcmd, &statbuf) == 0) {
879                     // More checks needed (perms, owner, etc.)
880                     os_calloc(1, strlen(cmd)+1, syscheck->prefilter_cmd);
881                     strncpy(syscheck->prefilter_cmd, cmd, strlen(cmd));
882                 }
883                 else
884                 {
885                     merror(XML_VALUEERR,ARGV0, node[i]->element, node[i]->content);
886                     return(OS_INVALID);
887                 }
888             }
889         }
890         else
891         {
892             merror(XML_INVELEM, ARGV0, node[i]->element);
893             return(OS_INVALID);
894         }
895         i++;
896     }
897
898     return(0);
899 }