e1fc23dc141971c7d97bbfee32bb335240132cdc
[ossec-hids.git] / src / os_dbd / rules.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All rights reserved.
5  *
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 2) as published by the FSF - Free Software
9  * Foundation
10  *
11  * License details at the LICENSE file included with OSSEC or
12  * online at: http://www.ossec.net/en/licensing.html
13  */
14
15
16 #include "dbd.h"
17 #include "config/config.h"
18 #include "rules_op.h"
19
20
21
22 /** int __Groups_SelectGroup(char *group, DBConfig *db_config)
23  * Select group (categories) from to the db.
24  * Returns 0 if not found.
25  */
26 int __Groups_SelectGroup(char *group, DBConfig *db_config)
27 {
28     int result = 0;
29     char sql_query[OS_SIZE_1024];
30
31     memset(sql_query, '\0', OS_SIZE_1024);
32
33
34     /* Generating SQL */
35     snprintf(sql_query, OS_SIZE_1024 -1,
36             "SELECT cat_id FROM "
37             "category WHERE cat_name = '%s'",
38             group);
39
40
41     /* Checking return code. */
42     result = osdb_query_select(db_config->conn, sql_query);
43
44     return(result);
45 }
46
47
48 /** int __Groups_InsertGroup(char *group, DBConfig *db_config)
49  * Insert group (categories) in to the db.
50  */
51 int __Groups_InsertGroup(char *group, DBConfig *db_config)
52 {
53     char sql_query[OS_SIZE_1024];
54     
55     memset(sql_query, '\0', OS_SIZE_1024);
56
57     /* Generating SQL */
58     snprintf(sql_query, OS_SIZE_1024 -1,
59             "INSERT INTO "
60             "category(cat_name) "
61             "VALUES ('%s')",
62             group);
63
64
65     /* Checking return code. */
66     if(!osdb_query_insert(db_config->conn, sql_query))
67     {
68         merror(DB_GENERROR, ARGV0);
69     }
70
71     return(0);
72 }
73
74
75 /** int __Groups_SelectGroupMapping()
76  * Select group (categories) from to the db.
77  * Returns 0 if not found.
78  */
79 int __Groups_SelectGroupMapping(int cat_id, int rule_id, DBConfig *db_config)
80 {
81     int result = 0;
82     char sql_query[OS_SIZE_1024];
83
84     memset(sql_query, '\0', OS_SIZE_1024);
85
86
87     /* Generating SQL */
88     snprintf(sql_query, OS_SIZE_1024 -1,
89             "SELECT id FROM signature_category_mapping "
90             "WHERE cat_id = '%u' AND rule_id = '%u'",
91             cat_id, rule_id);
92
93
94     /* Checking return code. */
95     result = osdb_query_select(db_config->conn, sql_query);
96
97     return(result);
98 }
99
100
101 /** int __Groups_InsertGroup(int cat_id, int rule_id, DBConfig *db_config)
102  * Insert group (categories) in to the db.
103  */
104 int __Groups_InsertGroupMapping(int cat_id, int rule_id, DBConfig *db_config)
105 {
106     char sql_query[OS_SIZE_1024];
107
108     memset(sql_query, '\0', OS_SIZE_1024);
109
110     /* Generating SQL */
111     snprintf(sql_query, OS_SIZE_1024 -1,
112             "INSERT INTO "
113             "signature_category_mapping(cat_id, rule_id) "
114             "VALUES ('%u', '%u')",
115             cat_id, rule_id);
116
117
118     /* Checking return code. */
119     if(!osdb_query_insert(db_config->conn, sql_query))
120     {
121         merror(DB_GENERROR, ARGV0);
122     }
123
124     return(0);
125 }
126
127
128
129 /** void _Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)
130  * Insert groups (categories) in to the db.
131  */
132 void _Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)
133 {
134     /* We must insert each group separately. */
135     int cat_id;
136     char *tmp_group;
137     char *tmp_str;
138
139     
140     debug1("%s: DEBUG: entering _Groups_ReadInsertDB", ARGV0);
141
142
143     /* If group is null, just return */
144     if(rule->group == NULL)
145     {
146         return;
147     }
148     
149     tmp_str = strchr(rule->group, ',');
150     tmp_group = rule->group;
151
152
153     /* Groups are separated by comma */
154     while(tmp_group)
155     {
156         if(tmp_str)
157         {
158             *tmp_str = '\0';
159             tmp_str++;
160         }
161
162         /* Removing white spaces */
163         while(*tmp_group == ' ')
164             tmp_group++;
165
166         
167         /* Checking for empty group */
168         if(*tmp_group == '\0')
169         {
170             tmp_group = tmp_str;
171             if(tmp_group)
172             {
173                 tmp_str = strchr(tmp_group, ',');
174             }
175             continue;
176         }
177
178         cat_id = __Groups_SelectGroup(tmp_group, db_config);
179
180
181         /* We firt check if we have this group in the db already.
182          * If not, we add it.
183          */
184         if(cat_id == 0)
185         {
186             __Groups_InsertGroup(tmp_group, db_config);
187             cat_id = __Groups_SelectGroup(tmp_group, db_config);
188         }
189
190
191         /* If our cat_id is valid (not zero), we need to insert
192          * the mapping between the category and the rule. */
193         if(cat_id != 0)
194         {
195             /* But, we first check if the mapping is already not there. */
196             if(!__Groups_SelectGroupMapping(cat_id, rule->sigid, db_config))
197             {
198                 /* If not, we add it */
199                 __Groups_InsertGroupMapping(cat_id, rule->sigid, db_config);
200             }
201         }
202
203         
204         /* Getting next category */
205         tmp_group = tmp_str;
206         if(tmp_group)
207         {
208             tmp_str = strchr(tmp_group, ',');
209         }
210     }
211     
212     return;
213 }
214
215
216
217 /** void *_Rules_ReadInsertDB(RuleInfo *rule, void *db_config)
218  * Insert rules in to the db.
219  */
220 void *_Rules_ReadInsertDB(RuleInfo *rule, void *db_config)
221 {
222     DBConfig *dbc = (DBConfig *)db_config;
223     char sql_query[OS_SIZE_1024];
224     memset(sql_query, '\0', OS_SIZE_1024);
225
226     
227     /* Escaping strings */
228     osdb_escapestr(rule->group);
229     osdb_escapestr(rule->comment);
230
231
232     /* Checking level limit */
233     if(rule->level > 20)
234         rule->level = 20;
235     if(rule->level < 0)
236         rule->level = 0;
237     
238     
239     debug1("%s: DEBUG: entering _Rules_ReadInsertDB()", ARGV0);
240     
241     
242     /* Checking rule limit */
243     if(rule->sigid < 0 || rule->sigid > 9999999)
244     {
245         merror("%s: Invalid rule id: %u", ARGV0, rule->sigid);
246         return(NULL);
247     }
248
249
250     /* Inserting group into the signature mapping */
251     _Groups_ReadInsertDB(rule, db_config);
252     
253     
254     
255     debug2("%s: DEBUG: Inserting: %d", ARGV0, rule->sigid);
256
257     
258     /* Generating SQL */
259     snprintf(sql_query, OS_SIZE_1024 -1,
260              "SELECT id FROM signature "
261              "where rule_id = %u",
262              rule->sigid);
263     
264     if(osdb_query_select(dbc->conn, sql_query) == 0)
265     {
266         snprintf(sql_query, OS_SIZE_1024 -1,
267                 "INSERT INTO "
268                 "signature(rule_id, level, description) "
269                 "VALUES ('%u','%u','%s')",
270                 rule->sigid, rule->level, rule->comment);
271     }
272     else
273     {
274         snprintf(sql_query, OS_SIZE_1024 -1,
275                 "UPDATE signature SET level='%u',description='%s' "
276                 "WHERE rule_id='%u'",
277                 rule->level, rule->comment,rule->sigid);
278     }
279
280     
281     /* Checking return code. */
282     if(!osdb_query_insert(dbc->conn, sql_query))
283     {
284         merror(DB_GENERROR, ARGV0);
285     }
286
287     return(NULL);
288 }
289
290
291 int OS_InsertRulesDB(DBConfig *db_config)
292 {
293     char **rulesfiles;
294     
295     rulesfiles = db_config->includes;
296     while(rulesfiles && *rulesfiles)
297     {
298         debug1("%s: Reading rules file: '%s'", ARGV0, *rulesfiles);
299         
300         if(OS_ReadXMLRules(*rulesfiles, _Rules_ReadInsertDB, db_config) < 0)
301         {
302             merror(RULES_ERROR, ARGV0, *rulesfiles);
303             return(-1);
304         }
305
306         free(*rulesfiles);
307         rulesfiles++;
308     }
309
310     free(db_config->includes);
311     db_config->includes = NULL;
312
313
314     return(0);
315 }
316
317
318 /* EOF */