1 /* @(#) $Id: localfile-config.c,v 1.25 2009/11/03 21:07:32 dcid Exp $ */
3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 3) as published by the FSF - Free Software
15 #include "localfile-config.h"
18 int Read_Localfile(XML_NODE node, void *d1, void *d2)
31 char *xml_localfile_location = "location";
32 char *xml_localfile_command = "command";
33 char *xml_localfile_logformat = "log_format";
37 logreader_config *log_config;
39 log_config = (logreader_config *)d1;
42 /* If config is not set, we need to create it */
43 if(!log_config->config)
45 os_calloc(2, sizeof(logreader), log_config->config);
46 logf = log_config->config;
48 logf[0].command = NULL;
49 logf[0].logformat = NULL;
51 logf[1].command = NULL;
52 logf[1].logformat = NULL;
56 logf = log_config->config;
57 while(logf[pl].file != NULL)
62 /* Allocating more memory */
63 os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config);
64 logf = log_config->config;
65 logf[pl +1].file = NULL;
66 logf[pl +1].command = NULL;
67 logf[pl +1].logformat = NULL;
71 logf[pl].command = NULL;
72 logf[pl].logformat = NULL;
74 logf[pl].ffile = NULL;
75 logf[pl].djb_program_name = NULL;
78 /* Searching for entries related to files */
84 merror(XML_ELEMNULL, ARGV0);
87 else if(!node[i]->content)
89 merror(XML_VALUENULL, ARGV0, node[i]->element);
92 else if(strcmp(node[i]->element,xml_localfile_command) == 0)
94 os_strdup(node[i]->content, logf[pl].file);
95 logf[pl].command = logf[pl].file;
97 else if(strcmp(node[i]->element,xml_localfile_location) == 0)
100 /* Expand variables on Windows. */
101 if(strchr(node[i]->content, '%'))
103 int expandreturn = 0;
104 char newfile[OS_MAXSTR +1];
106 newfile[OS_MAXSTR] = '\0';
107 expandreturn = ExpandEnvironmentStrings(node[i]->content,
110 if((expandreturn > 0) && (expandreturn < OS_MAXSTR))
112 free(node[i]->content);
114 os_strdup(newfile, node[i]->content);
121 * We will call this file multiple times until
122 * there is no one else available.
124 #ifndef WIN32 /* No windows support for glob */
125 if(strchr(node[i]->content, '*') ||
126 strchr(node[i]->content, '?') ||
127 strchr(node[i]->content, '['))
131 /* Setting ot the first entry of the glob */
135 if(glob(node[i]->content, 0, NULL, &g) != 0)
137 merror(GLOB_ERROR, ARGV0, node[i]->content);
138 os_strdup(node[i]->content, logf[pl].file);
143 /* Checking for the last entry */
144 if((g.gl_pathv[glob_offset]) == NULL)
146 /* Checking when nothing is found. */
149 merror(GLOB_NFOUND, ARGV0, node[i]->content);
157 /* Checking for strftime on globs too. */
158 if(strchr(g.gl_pathv[glob_offset], '%'))
161 time_t l_time = time(0);
162 char lfile[OS_FLSIZE + 1];
165 p = localtime(&l_time);
167 lfile[OS_FLSIZE] = '\0';
168 ret = strftime(lfile, OS_FLSIZE, g.gl_pathv[glob_offset], p);
171 merror(PARSE_ERROR, ARGV0, g.gl_pathv[glob_offset]);
175 os_strdup(g.gl_pathv[glob_offset], logf[pl].ffile);
176 os_strdup(g.gl_pathv[glob_offset], logf[pl].file);
180 os_strdup(g.gl_pathv[glob_offset], logf[pl].file);
187 /* Now we need to create another file entry */
189 os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config);
190 logf = log_config->config;
192 logf[pl].file = NULL;
193 logf[pl].logformat = NULL;
195 logf[pl].ffile = NULL;
197 logf[pl +1].file = NULL;
198 logf[pl +1].logformat = NULL;
200 /* We can not increment the file count in here */
203 else if(strchr(node[i]->content, '%'))
205 if(strchr(node[i]->content, '%'))
208 /* We need the format file (based on date) */
211 time_t l_time = time(0);
212 char lfile[OS_FLSIZE + 1];
215 p = localtime(&l_time);
217 lfile[OS_FLSIZE] = '\0';
218 ret = strftime(lfile, OS_FLSIZE, node[i]->content, p);
221 merror(PARSE_ERROR, ARGV0, node[i]->content);
225 os_strdup(node[i]->content, logf[pl].ffile);
226 os_strdup(node[i]->content, logf[pl].file);
233 os_strdup(node[i]->content, logf[pl].file);
237 /* Getting log format */
238 else if(strcasecmp(node[i]->element,xml_localfile_logformat) == 0)
240 os_strdup(node[i]->content, logf[pl].logformat);
242 if(strcmp(logf[pl].logformat, "syslog") == 0)
245 else if(strcmp(logf[pl].logformat, "snort-full") == 0)
248 else if(strcmp(logf[pl].logformat, "snort-fast") == 0)
251 else if(strcmp(logf[pl].logformat, "apache") == 0)
254 else if(strcmp(logf[pl].logformat, "iis") == 0)
257 else if(strcmp(logf[pl].logformat, "squid") == 0)
260 else if(strcmp(logf[pl].logformat, "nmapg") == 0)
263 else if(strcmp(logf[pl].logformat, "mysql_log") == 0)
266 else if(strcmp(logf[pl].logformat, "mssql_log") == 0)
269 else if(strcmp(logf[pl].logformat, "postgresql_log") == 0)
272 else if(strcmp(logf[pl].logformat, "djb-multilog") == 0)
275 else if(strcmp(logf[pl].logformat, "syslog-pipe") == 0)
278 else if(strcmp(logf[pl].logformat, "command") == 0)
281 else if(strcmp(logf[pl].logformat, EVENTLOG) == 0)
286 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
292 merror(XML_INVELEM, ARGV0, node[i]->element);
300 /* Validating glob entries */
305 /* Getting log format */
306 if(logf[pl].logformat)
308 format = logf[pl].logformat;
310 else if(logf[glob_set -1].logformat)
312 format = logf[glob_set -1].logformat;
316 merror(MISS_LOG_FORMAT, ARGV0);
320 /* The last entry is always null on glob */
324 /* Setting format for all entries */
325 for(i = (glob_set -1); i<= pl; i++)
327 /* Every entry must be valid */
330 merror(MISS_FILE, ARGV0);
334 if(logf[i].logformat == NULL)
336 logf[i].logformat = format;
342 /* Missing log format */
343 if(!logf[pl].logformat)
345 merror(MISS_LOG_FORMAT, ARGV0);
352 merror(MISS_FILE, ARGV0);
356 /* Verifying a valid event log config */
357 if(strcmp(logf[pl].logformat, EVENTLOG) == 0)
359 if((strcmp(logf[pl].file, "Application") != 0)&&
360 (strcmp(logf[pl].file, "System") != 0)&&
361 (strcmp(logf[pl].file, "Security") != 0))
363 /* Invalid event log */
364 merror(NSTD_EVTLOG, ARGV0, logf[pl].file);
369 if(strcmp(logf[pl].logformat, "command") == 0)
371 if(!logf[pl].command)
373 merror("%s: ERROR: Missing 'command' argument. "
374 "This option will be ignored.", ARGV0);