2
* Copyright 2007 Red Hat Inc., Durham, North Carolina.
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
* Steve Grubb <sgrubb@redhat.com>
34
#include "audispd-config.h"
37
/* Local prototypes */
48
int (*parser)(struct nv_pair *, int, daemon_conf_t *);
58
static char *get_line(FILE *f, char *buf);
59
static int nv_split(char *buf, struct nv_pair *nv);
60
static const struct kw_pair *kw_lookup(const char *val);
61
static int q_depth_parser(struct nv_pair *nv, int line,
62
daemon_conf_t *config);
63
static int name_format_parser(struct nv_pair *nv, int line,
64
daemon_conf_t *config);
65
static int name_parser(struct nv_pair *nv, int line,
66
daemon_conf_t *config);
67
static int sanity_check(daemon_conf_t *config, const char *file);
69
static const struct kw_pair keywords[] =
71
{"q_depth", q_depth_parser, 0 },
72
{"name_format", name_format_parser, 0 },
73
{"name", name_parser, 0 },
77
static const struct nv_list node_name_formats[] =
80
{"hostname", N_HOSTNAME },
82
{"numeric", N_NUMERIC },
88
* Set everything to its default value
90
void clear_config(daemon_conf_t *config)
93
config->node_name_format = N_NONE;
97
int load_config(daemon_conf_t *config, const char *file)
99
int fd, rc, mode, lineno = 1;
104
clear_config(config);
108
rc = open(file, mode);
110
if (errno != ENOENT) {
111
audit_msg(LOG_ERR, "Error opening %s (%s)", file,
115
audit_msg(LOG_WARNING,
116
"Config file %s doesn't exist, skipping", file);
121
/* check the file's permissions: owned by root, not world writable,
124
audit_msg(LOG_DEBUG, "Config file %s opened for parsing",
126
if (fstat(fd, &st) < 0) {
127
audit_msg(LOG_ERR, "Error fstat'ing config file (%s)",
132
if (st.st_uid != 0) {
133
audit_msg(LOG_ERR, "Error - %s isn't owned by root",
138
if ((st.st_mode & S_IWOTH) == S_IWOTH) {
139
audit_msg(LOG_ERR, "Error - %s is world writable",
144
if (!S_ISREG(st.st_mode)) {
145
audit_msg(LOG_ERR, "Error - %s is not a regular file",
151
/* it's ok, read line by line */
154
audit_msg(LOG_ERR, "Error - fdopen failed (%s)",
160
while (get_line(f, buf)) {
161
// convert line into name-value pair
162
const struct kw_pair *kw;
164
rc = nv_split(buf, &nv);
168
case 1: // not the right number of tokens.
170
"Wrong number of arguments for line %d in %s",
173
case 2: // no '=' sign
175
"Missing equal sign for line %d in %s",
178
default: // something else went wrong...
180
"Unknown error for line %d in %s",
184
if (nv.name == NULL) {
188
if (nv.value == NULL) {
193
/* identify keyword or error */
194
kw = kw_lookup(nv.name);
195
if (kw->name == NULL) {
197
"Unknown keyword \"%s\" in line %d of %s",
198
nv.name, lineno, file);
203
/* Check number of options */
204
if (kw->max_options == 0 && nv.option != NULL) {
206
"Keyword \"%s\" has invalid option "
207
"\"%s\" in line %d of %s",
208
nv.name, nv.option, lineno, file);
213
/* dispatch to keyword's local parser */
214
rc = kw->parser(&nv, lineno, config);
217
return 1; // local parser puts message out
225
return sanity_check(config, file);
229
static char *get_line(FILE *f, char *buf)
231
if (fgets_unlocked(buf, 128, f)) {
233
char *ptr = strchr(buf, 0x0a);
241
static int nv_split(char *buf, struct nv_pair *nv)
243
/* Get the name part */
249
ptr = strtok(buf, " ");
251
return 0; /* If there's nothing, go to next line */
253
return 0; /* If there's a comment, go to next line */
256
/* Check for a '=' */
257
ptr = strtok(NULL, " ");
260
if (strcmp(ptr, "=") != 0)
264
ptr = strtok(NULL, " ");
269
/* See if there's an option */
270
ptr = strtok(NULL, " ");
274
/* Make sure there's nothing else */
275
ptr = strtok(NULL, " ");
280
/* Everything is OK */
284
static const struct kw_pair *kw_lookup(const char *val)
287
while (keywords[i].name != NULL) {
288
if (strcasecmp(keywords[i].name, val) == 0)
295
static int q_depth_parser(struct nv_pair *nv, int line,
296
daemon_conf_t *config)
298
const char *ptr = nv->value;
301
/* check that all chars are numbers */
302
for (i=0; ptr[i]; i++) {
303
if (!isdigit(ptr[i])) {
305
"Value %s should only be numbers - line %d",
311
/* convert to unsigned long */
313
i = strtoul(nv->value, NULL, 10);
316
"Error converting string to a number (%s) - line %d",
317
strerror(errno), line);
321
audit_msg(LOG_ERR, "q_depth must be 99999 or less");
329
static int name_format_parser(struct nv_pair *nv, int line,
330
daemon_conf_t *config)
334
for (i=0; node_name_formats[i].name != NULL; i++) {
335
if (strcasecmp(nv->value, node_name_formats[i].name) == 0) {
336
config->node_name_format = node_name_formats[i].option;
340
audit_msg(LOG_ERR, "Option %s not found - line %d", nv->value, line);
344
static int name_parser(struct nv_pair *nv, int line,
345
daemon_conf_t *config)
347
if (nv->value == NULL)
350
config->name = strdup(nv->value);
355
* This function is where we do the integrated check of the audispd config
356
* options. At this point, all fields have been read. Returns 0 if no
357
* problems and 1 if problems detected.
359
static int sanity_check(daemon_conf_t *config, const char *file)
362
if (config->node_name_format == N_USER && config->name == NULL) {
364
"Error - node_name_format is user supplied but none given (%s)",
371
void free_config(daemon_conf_t *config)