source: trunk/src/sh_log_parse_pacct.c@ 201

Last change on this file since 201 was 199, checked in by katerina, 16 years ago

While we're at it, implement 'else' cor the config file conditionals. Also fix some compile warnings and improve docs.

File size: 7.5 KB
Line 
1/**************************************
2 **
3 ** PARSER RULES
4 **
5 ** (a) must set record->host
6 ** (eventually to dummy value)
7 **
8 ** (b) must set record->prefix
9 ** (command)
10 **
11 **
12 **************************************/
13
14/* Based on the GNU Accounting Utilities, which is distributed with the
15 * following copyright:
16 */
17
18/* Copyright (C) 1993, 1996, 1997, 2003, 2005 Free Software Foundation, Inc.
19 *
20 * This file is part of the GNU Accounting Utilities
21 *
22 * The GNU Accounting Utilities are free software; you can redistribute
23 * them and/or modify them under the terms of the GNU General Public
24 * License as published by the Free Software Foundation; either version
25 * 2, or (at your option) any later version.
26 *
27 * The GNU Accounting Utilities are distributed in the hope that they will
28 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
29 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 * General Public License for more details.
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with the GNU Accounting Utilities; see the file COPYING. If
34 * not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
35 * MA 02139, USA. */
36
37#include "config_xor.h"
38
39#include <ctype.h>
40#include <string.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <sys/types.h>
44#include <sys/stat.h>
45#include <unistd.h>
46#include <pwd.h>
47#include <dirent.h>
48
49#if defined(USE_LOGFILE_MONITOR) && defined(HAVE_SYS_ACCT_H)
50
51#include <sys/acct.h>
52
53#include "samhain.h"
54#include "sh_pthread.h"
55#include "sh_log_check.h"
56#include "sh_utils.h"
57#include "sh_string.h"
58
59#undef FIL__
60#define FIL__ _("sh_log_parse_pacct.c")
61
62extern int flag_err_debug;
63
64#ifndef ACCT_COMM
65#define ACCT_COMM 16
66#endif
67#ifndef AHZ
68#define AHZ 100
69#endif
70
71#if defined(ACUTIME_COMPT) || defined(ACSTIME_COMPT) || defined(ACETIME_COMPT)
72static double comp_t_2_double (comp_t ct)
73{
74 unsigned long out = 0;
75
76 out = ct & 017777;
77 ct >>= 13;
78
79 while (ct) {
80 ct--;
81 out <<= 3;
82 }
83
84 return (double) out;
85}
86#endif
87
88#ifdef ACUTIME_COMPT
89# define ACUTIME_2_DOUBLE(x) (comp_t_2_double(x))
90#else
91# define ACUTIME_2_DOUBLE(x) ((double)(x))
92#endif
93
94#ifdef ACSTIME_COMPT
95# define ACSTIME_2_DOUBLE(x) (comp_t_2_double(x))
96#else
97# define ACSTIME_2_DOUBLE(x) ((double)(x))
98#endif
99
100#ifdef ACETIME_COMPT
101# define ACETIME_2_DOUBLE(x) (comp_t_2_double(x))
102#else
103# define ACETIME_2_DOUBLE(x) ((double)(x))
104#endif
105
106
107static void expand_flags(char flag, char * out)
108{
109 int i = 0;
110
111#define BIT(flg, ch) if (flag & flg) out[i] = ch; else out[i] = ' '; ++i
112
113 BIT(ASU, 'S');
114 BIT(AFORK, 'F');
115#ifdef ACOMPAT
116 BIT(ACOMPAT, 'C');
117#endif
118 BIT(ACORE, 'D');
119 BIT(AXSIG, 'X');
120
121 out[i] = '\0';
122 return;
123}
124
125static char * uid_name (int uid)
126{
127 static int userid = 0;
128 static char user[16] = "";
129
130 if (uid == userid && user[0] != '\0')
131 {
132 return user;
133 }
134 else
135 {
136 struct passwd *thispw = getpwuid (uid);
137 if (thispw)
138 sl_strlcpy (user, thispw->pw_name, sizeof(user));
139 else
140 sl_snprintf(user, sizeof(user), "%d", uid);
141 user[sizeof(user)-1] = '\0';
142 userid = uid;
143 }
144 return user;
145}
146
147struct dev_struct {
148 char * device;
149 long dev_id;
150 struct dev_struct * next;
151};
152static struct dev_struct * devicelist = NULL;
153
154static void add_devices(const char * dir)
155{
156 DIR * mdir;
157 char dirl[256];
158
159 sl_strlcpy(dirl, dir, sizeof(dirl));
160 dirl[sizeof(dirl)-1] = '\0';
161
162 mdir = opendir(dir);
163
164 if (mdir)
165 {
166 char * path;
167 size_t len;
168 struct dirent * dent;
169 struct stat buf;
170
171 while (NULL != (dent = readdir(mdir)))
172 {
173 if (0 == strcmp(dent->d_name, "."))
174 continue;
175 if (0 == strcmp(dent->d_name, ".."))
176 continue;
177 len = strlen(dir) + strlen(dent->d_name) + 2;
178 path = SH_ALLOC(len);
179 snprintf(path, len, "%s/%s", dir, dent->d_name);
180 if (0 == lstat(path, &buf) && S_ISCHR(buf.st_mode))
181 {
182 struct dev_struct * dstruct;
183 dstruct = SH_ALLOC(sizeof(struct dev_struct));
184 /* eliminate leading '/dev/' */
185 memmove(path, &path[5], strlen(path)-4);
186 dstruct->device = path;
187 dstruct->dev_id = buf.st_rdev;
188 dstruct->next = devicelist;
189 devicelist = dstruct;
190 }
191 else
192 {
193 SH_FREE(path);
194 }
195 }
196 closedir(mdir);
197 }
198 return;
199}
200
201static char * dev_name(long tty)
202{
203 struct dev_struct * dstruct;
204
205 if (!devicelist)
206 {
207 add_devices("/dev");
208 add_devices("/dev/pts");
209 add_devices("/dev/pty");
210 add_devices("/dev/ptym");
211 }
212
213 dstruct = devicelist;
214 while (dstruct)
215 {
216 if (dstruct->dev_id == tty)
217 return dstruct->device;
218 dstruct = dstruct->next;
219 }
220 return "??";
221}
222
223/* This looks strange, but it's real ANSI C. */
224extern struct acct pacct_rd_never_used;
225#define COMM_LEN ((int) sizeof (pacct_rd_never_used.ac_comm))
226
227sh_string * sh_read_pacct (sh_string * record, struct sh_logfile * logfile)
228{
229#if defined(__linux__)
230# define STRUCT_ACCT struct acct_v3
231#else
232# define STRUCT_ACCT struct acct
233#endif
234
235 STRUCT_ACCT rec;
236
237 if (NULL != sh_binary_reader ((void*) &rec, sizeof(STRUCT_ACCT), logfile))
238 {
239 time_t btime = (time_t) rec.ac_btime;
240 double ut = ACUTIME_2_DOUBLE (rec.ac_utime);
241 double st = ACSTIME_2_DOUBLE (rec.ac_stime);
242 char fl[6];
243 char comm[COMM_LEN+1];
244 int i;
245 char out[64+COMM_LEN+1+5+8+8+32+4+19+7]; /* see printf format below */
246
247 expand_flags(rec.ac_flag, fl);
248
249 /* ac_comm may not be null terminated
250 */
251 for (i = 0; i < COMM_LEN; i++)
252 {
253 if (rec.ac_comm[i] == '\0')
254 {
255 comm[i] = '\0';
256 break;
257 }
258 if (! isprint (rec.ac_comm[i]))
259 comm[i] = '?';
260 else
261 comm[i] = rec.ac_comm[i];
262 }
263 comm[COMM_LEN] = '\0';
264
265 sl_snprintf (out, sizeof(out),
266 "%ld:%-*.*s %5.5s %-8.8s %-8.8s %6.2f secs %-19.19s",
267 btime,
268 COMM_LEN, COMM_LEN, comm, fl,
269 uid_name(rec.ac_uid),
270 dev_name((long)rec.ac_tty),
271 ((ut + st) / (double) AHZ),
272 ctime (&btime));
273
274
275 sh_string_set_from_char(record, out);
276 return record;
277 }
278
279 if (record)
280 sh_string_destroy(&record);
281 return NULL;
282}
283
284static void * sh_dummy_record = NULL;
285
286struct sh_logrecord * sh_parse_pacct (sh_string * logline, void * fileinfo)
287{
288 char * p;
289 char * endptr;
290 unsigned long ltime;
291 struct sh_logrecord * record = NULL;
292
293 (void) fileinfo;
294
295 sh_dummy_record = (void *) &record;
296
297 if (sh_string_len(logline) > 0 && flag_err_debug == SL_TRUE)
298 {
299 SH_MUTEX_LOCK(mutex_thread_nolog);
300 sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, 0, MSG_E_SUBGEN,
301 sh_string_str(logline),
302 _("sh_parse_pacct"));
303 SH_MUTEX_UNLOCK(mutex_thread_nolog);
304 }
305
306 p = strchr(sh_string_str(logline), ':');
307
308 if (!p || p == sh_string_str(logline))
309 return NULL;
310
311 ltime = strtoul(sh_string_str(logline), &endptr, 10);
312 if (p != endptr)
313 return NULL;
314
315 ++p; /* points to first char of pacct record */
316
317 if (*p != '\0')
318 {
319 size_t lengths[7];
320 unsigned int fields = 7;
321 char ** array;
322 sh_string * message = sh_string_new_from_lchar(p, strlen(p));
323 array = split_array_ws(p, &fields, lengths);
324
325 if (fields == 7)
326 {
327 record = SH_ALLOC(sizeof(struct sh_logrecord));
328
329 record->timestamp = ltime;
330 record->timestr = sh_string_new_from_lchar(array[6], lengths[6]);
331 record->message = message;
332 record->pid = 0;
333 record->host = sh_string_new_from_lchar(sh.host.name, strlen(sh.host.name));
334 }
335 else
336 {
337 sh_string_destroy(&message);
338 }
339 SH_FREE(array);
340 }
341 return record;
342}
343/* USE_LOGFILE_MONITOR */
344#endif
Note: See TracBrowser for help on using the repository browser.