Skip to content

Commit 97abf01

Browse files
committed
Refactor audit log file processing for ausearch/report
Introduced shared audit log helpers to capture first record timestamps, list rotated logs, and free associated resources, enabling timestamp-driven log selection across tools. Updated aureport to leverage the new log enumeration routines, selecting the correct starting log based on --start time while simplifying filename traversal. Refactored ausearch so checkpoint handling occurs before log enumeration; when no checkpoint is used, it now mirrors aureport’s timestamp-based log selection for cleaner, non-duplicated logic.
1 parent 70cd16e commit 97abf01

File tree

4 files changed

+247
-70
lines changed

4 files changed

+247
-70
lines changed

src/aureport.c

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,10 @@ int main(int argc, char *argv[])
171171

172172
static int process_logs(void)
173173
{
174+
struct audit_log_info *logs = NULL;
174175
char *filename;
175176
size_t len;
176-
int num = 0;
177+
size_t log_cnt = 0;
177178

178179
if (user_file && userfile_is_dir) {
179180
char dirname[MAXPATHLEN+1];
@@ -189,32 +190,38 @@ static int process_logs(void)
189190
fprintf(stderr, "NOTE - using logs in %s\n", config.log_file);
190191
}
191192

192-
/* for each file */
193193
len = strlen(config.log_file) + 16;
194194
filename = malloc(len);
195195
if (!filename) {
196196
fprintf(stderr, "No memory\n");
197197
free_config(&config);
198198
return 1;
199199
}
200-
/* Find oldest log file */
201-
snprintf(filename, len, "%s", config.log_file);
202-
do {
203-
if (access(filename, R_OK) != 0)
204-
break;
205-
// FIXME: do a time check and put them on linked list for later
206-
num++;
207-
snprintf(filename, len, "%s.%d", config.log_file, num);
208-
} while (1);
209-
num--;
210-
/*
211-
* We note how many files we need to process
212-
*/
213-
files_to_process = num;
200+
201+
/* Count the logs */
202+
if (audit_log_list(config.log_file, &logs, &log_cnt)) {
203+
fprintf(stderr, "No memory\n");
204+
free(filename);
205+
free_config(&config);
206+
return 1;
207+
}
208+
209+
if (log_cnt == 0) {
210+
snprintf(filename, len, "%s", config.log_file);
211+
int ret = process_file(filename);
212+
free(filename);
213+
free_config(&config);
214+
return ret;
215+
}
216+
217+
/* Locate the starting file that is in range */
218+
files_to_process = audit_log_find_start(logs, log_cnt, start_time);
219+
audit_log_free(logs, log_cnt);
214220

215221
/* Got it, now process logs from last to first */
216-
if (num > 0)
217-
snprintf(filename, len, "%s.%d", config.log_file, num);
222+
if (files_to_process > 0)
223+
snprintf(filename, len, "%s.%d", config.log_file,
224+
files_to_process);
218225
else
219226
snprintf(filename, len, "%s", config.log_file);
220227
do {
@@ -225,15 +232,17 @@ static int process_logs(void)
225232
return ret;
226233
}
227234

235+
if (files_to_process == 0)
236+
break;
237+
228238
/* Get next log file */
229-
files_to_process--; /* one less file to process */
230-
num--;
231-
if (num > 0)
232-
snprintf(filename, len, "%s.%d", config.log_file, num);
233-
else if (num == 0)
234-
snprintf(filename, len, "%s", config.log_file);
239+
files_to_process--;
240+
if (files_to_process > 0)
241+
snprintf(filename, len, "%s.%d",
242+
config.log_file, files_to_process);
235243
else
236-
break;
244+
snprintf(filename, len, "%s",
245+
config.log_file);
237246
} while (1);
238247
free(filename);
239248
free_config(&config);

src/ausearch-parse.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <netdb.h>
3535
#include <limits.h> /* PATH_MAX */
3636
#include <ctype.h>
37+
#include <unistd.h>
3738
#include "libaudit.h"
3839
#include "ausearch-options.h"
3940
#include "ausearch-lookup.h"
@@ -2830,3 +2831,133 @@ static int parse_kernel(lnode *n, search_items *s)
28302831
return 0;
28312832
}
28322833

2834+
//////// These are used by ausearch / aureport ///////////////
2835+
2836+
/* read_first_ts - get timestamp of the first record in a log file
2837+
* @file: path to the log file
2838+
* @sec: returned seconds component
2839+
* @milli: returned milliseconds component
2840+
*
2841+
* Returns 0 on success and -1 on failure.
2842+
*/
2843+
static int read_first_ts(const char *file, time_t *sec, unsigned int *milli)
2844+
{
2845+
FILE *fp;
2846+
char buf[MAX_AUDIT_MESSAGE_LENGTH];
2847+
char *p, *e;
2848+
2849+
*sec = 0;
2850+
*milli = 0;
2851+
2852+
fp = fopen(file, "rm");
2853+
if (fp == NULL)
2854+
return -1;
2855+
if (fgets_unlocked(buf, sizeof(buf), fp) == NULL) {
2856+
fclose(fp);
2857+
return -1;
2858+
}
2859+
fclose(fp);
2860+
2861+
p = strstr(buf, "audit(");
2862+
if (p == NULL)
2863+
return -1;
2864+
p += 6;
2865+
*sec = strtoll(p, &e, 10);
2866+
if (*e == '.')
2867+
*milli = strtoul(e + 1, &e, 10);
2868+
2869+
return 0;
2870+
}
2871+
2872+
/* audit_log_list - collect audit logs and their first timestamps
2873+
* @basefile: base audit log file
2874+
* @logs: returned array of log information
2875+
* @log_cnt: number of entries in @logs
2876+
*
2877+
* Returns 0 on success and -1 on failure.
2878+
*/
2879+
int audit_log_list(const char *basefile, struct audit_log_info **logs,
2880+
size_t *log_cnt)
2881+
{
2882+
char *filename;
2883+
size_t len;
2884+
int num = 0;
2885+
struct audit_log_info *list = NULL;
2886+
2887+
len = strlen(basefile) + 16;
2888+
filename = malloc(len);
2889+
if (filename == NULL)
2890+
return -1;
2891+
2892+
snprintf(filename, len, "%s", basefile);
2893+
do {
2894+
struct audit_log_info *tmp;
2895+
time_t sec;
2896+
unsigned int milli;
2897+
2898+
if (access(filename, R_OK) != 0)
2899+
break;
2900+
if (read_first_ts(filename, &sec, &milli))
2901+
sec = 0;
2902+
tmp = realloc(list, (num + 1) * sizeof(*list));
2903+
if (tmp == NULL) {
2904+
free(filename);
2905+
audit_log_free(list, num);
2906+
return -1;
2907+
}
2908+
list = tmp;
2909+
list[num].name = strdup(filename);
2910+
if (list[num].name == NULL) {
2911+
free(filename);
2912+
audit_log_free(list, num);
2913+
return -1;
2914+
}
2915+
list[num].sec = sec;
2916+
list[num].milli = milli;
2917+
num++;
2918+
snprintf(filename, len, "%s.%d", basefile, num);
2919+
} while (1);
2920+
2921+
free(filename);
2922+
*logs = list;
2923+
*log_cnt = num;
2924+
return 0;
2925+
}
2926+
2927+
/* audit_log_find_start - choose oldest log that may contain @start
2928+
* @logs: array of log information
2929+
* @log_cnt: number of logs
2930+
* @start: requested start time
2931+
*
2932+
* Returns index of the log to begin processing from.
2933+
*/
2934+
unsigned audit_log_find_start(const struct audit_log_info *logs,
2935+
size_t log_cnt, time_t start)
2936+
{
2937+
size_t start_idx = log_cnt ? log_cnt - 1 : 0;
2938+
2939+
if (start) {
2940+
ssize_t i;
2941+
for (i = log_cnt - 1; i >= 0; i--) {
2942+
if (logs[i].sec > start) {
2943+
if ((size_t)i < log_cnt - 1)
2944+
start_idx = i + 1;
2945+
break;
2946+
}
2947+
}
2948+
}
2949+
return start_idx;
2950+
}
2951+
2952+
/* audit_log_free - release memory held by audit_log_list */
2953+
void audit_log_free(struct audit_log_info *logs, size_t log_cnt)
2954+
{
2955+
size_t i;
2956+
2957+
if (logs == NULL)
2958+
return;
2959+
for (i = 0; i < log_cnt; i++)
2960+
free(logs[i].name);
2961+
free(logs);
2962+
}
2963+

src/ausearch-parse.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,17 @@
3131
int extract_search_items(llist *l);
3232
void lookup_uid_destroy_list(void);
3333

34+
struct audit_log_info {
35+
char *name;
36+
time_t sec;
37+
unsigned int milli;
38+
};
39+
40+
int audit_log_list(const char *basefile, struct audit_log_info **logs,
41+
size_t *log_cnt);
42+
unsigned audit_log_find_start(const struct audit_log_info *logs,
43+
size_t log_cnt, time_t start);
44+
void audit_log_free(struct audit_log_info *logs, size_t log_cnt);
45+
3446
#endif
3547

0 commit comments

Comments
 (0)