41ad273f59d204ea9d2cba9b3d11cf1b59fb143f
[ossec-hids.git] / src / logcollector / read_mssql_log.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 /* Read MSSQL logs */
16
17
18 #include "shared.h"
19 #include "logcollector.h"
20
21
22
23 /* Send mssql message and check the return code. 
24  */
25 void __send_mssql_msg(int pos, int drop_it, char *buffer)
26 {
27     debug2("%s: DEBUG: Reading MSSQL message: '%s'", ARGV0, buffer);
28     if(drop_it == 0)
29     {
30         if(SendMSG(logr_queue, buffer, logff[pos].file, LOCALFILE_MQ) < 0)
31         {
32             merror(QUEUE_SEND, ARGV0);
33             if((logr_queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
34             {
35                 ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
36             }
37         }
38     }
39 }
40
41
42
43 /* Read PostgreSQL log files */
44 void *read_mssql_log(int pos, int *rc, int drop_it)
45 {
46     int str_len = 0;
47     int need_clear = 0;
48     char *p;
49     char str[OS_MAXSTR + 1];
50     char buffer[OS_MAXSTR + 1];
51
52
53     /* Zeroing buffer and str */
54     buffer[0] = '\0';
55     buffer[OS_MAXSTR] = '\0';    
56     str[OS_MAXSTR]= '\0';
57     *rc = 0;
58
59
60     /* Getting new entry */
61     while(fgets(str, OS_MAXSTR - OS_LOG_HEADER, logff[pos].fp) != NULL)
62     {
63         
64         /* Getting buffer size */
65         str_len = strlen(str);
66
67         
68         /* Checking str_len size. Very useless, but just to make sure.. */
69         if(str_len >= sizeof(buffer) -2)
70         {
71             str_len = sizeof(buffer) -10;
72         }
73
74         
75         /* Getting the last occurence of \n */
76         if ((p = strrchr(str, '\n')) != NULL) 
77         {
78             *p = '\0';
79
80             /* If need clear is set, we just get the line and ignore it. */
81             if(need_clear)
82             {
83                 need_clear = 0;
84                 continue;
85             }
86         }
87         else
88         {
89             need_clear = 1;
90         }
91         
92         
93         #ifdef WIN32
94         if ((p = strrchr(str, '\r')) != NULL)
95         {
96             *p = '\0';
97         }
98
99
100         /* Looking for empty string (only on windows) */
101         if(str_len <= 1)
102         {
103             continue;
104         }
105
106
107         /* Windows can have comment on their logs */
108         if(str[0] == '#')
109         {
110             continue;
111         }
112         #endif
113
114        
115
116         /* MSSQL messages have the following formats:
117          * 2009-03-25 04:47:30.01 Server
118          * 2003-10-09 00:00:06.68 sys1
119          * 2009-02-06 11:48:59     Server
120          */
121         if((str_len > 19) &&
122            (str[4] == '-') && 
123            (str[7] == '-') && 
124            (str[10] == ' ') && 
125            (str[13] == ':') && 
126            (str[16] == ':') && 
127            isdigit((int)str[0]) &&
128            isdigit((int)str[1]) &&
129            isdigit((int)str[2]) &&
130            isdigit((int)str[3]))
131         {
132             
133             /* If the saved message is empty, set it and continue. */
134             if(buffer[0] == '\0')
135             {
136                 strncpy(buffer, str, str_len + 2);
137                 continue;
138             }
139
140             /* If not, send the saved one and store the new one for later */
141             else
142             {
143                 __send_mssql_msg(pos, drop_it, buffer);
144
145
146                 /* Storing current one at the buffer */
147                 strncpy(buffer, str, str_len + 2);
148             }
149         }
150         
151         
152         /* Query logs can be in multiple lines.
153          * They always start with a tab in the additional ones.
154          */
155         else if((str_len > 2) && (buffer[0] != '\0'))
156         {
157             /* Size of the buffer */
158             int buffer_len = strlen(buffer);
159             
160             p = str;
161             
162             /* Removing extra spaces and tabs */
163             while(*p == ' ' || *p == '\t')
164             {
165                 p++;
166             }
167            
168            
169             /* Adding additional message to the saved buffer. */
170             if(sizeof(buffer) - buffer_len > str_len +256)
171             {
172                 /* Here we make sure that the size of the buffer
173                  * minus what was used (strlen) is greater than
174                  * the length of the received message.
175                  */
176                  buffer[buffer_len] = ' ';
177                  buffer[buffer_len +1] = '\0';
178                  strncat(buffer, str, str_len +3);
179             }
180         }
181         
182         continue;
183     }
184
185
186     /* Send whatever is stored. */
187     if(buffer[0] != '\0')
188     {
189         __send_mssql_msg(pos, drop_it, buffer);
190     }
191     
192     return(NULL); 
193 }
194
195 /* EOF */