/
githubmirror
/
audit-userspace
Обзор
Документация
Войти
/
githubmirror
/
audit-userspace
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/ausearch-checkpt.c
277 строк
7 KB
Steve Grubb
Update license and copyrights 2
20 июл 2026, 22:58
20 июл 2026, 22:58
1a67be2
Код
Авторство
О чём код?
/* * ausearch-checkpt.c - ausearch checkpointing feature * Copyright 2014,2017,2023-24,2026 Red Hat Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <stdlib.h> #include <errno.h> #include <sys/stat.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <inttypes.h> #include "ausearch-checkpt.h" #define DBG 0 /* set to non-zero for debug */ #if SIZEOF_LONG < SIZEOF_TIME_T #define TIME_T_SPECIFIER "%lld" #else #define TIME_T_SPECIFIER "%ld" #endif /* Remember why we failed */ unsigned checkpt_failure = 0; /* * Remember the file we were processing when we had incomplete events. * We remember this via it's dev and inode */ static dev_t checkpt_dev = (dev_t)NULL; static ino_t checkpt_ino = (ino_t)NULL; /* Remember the last event output */ static event last_event = {0, 0, 0, NULL, 0}; /* Loaded values from a given checkpoint file */ dev_t chkpt_input_dev = (dev_t)NULL; ino_t chkpt_input_ino = (ino_t)NULL; event chkpt_input_levent = {0, 0, 0, NULL, 0}; /* * Record the dev_t and ino_t of the given file * * Returns: * 1 Failed to get status * 0 OK */ int set_ChkPtFileDetails(const char *fn) { struct stat sbuf; if (stat(fn, &sbuf) != 0) { fprintf(stderr, "Cannot stat audit file for checkpoint " "details - %s: %s\n", fn, strerror(errno)); checkpt_failure |= CP_STATFAILED; return 1; } checkpt_dev = sbuf.st_dev; checkpt_ino = sbuf.st_ino; return 0; } /* * Save the given event in the last_event record * Returns: * 1 no memory * 0 OK */ int set_ChkPtLastEvent(const event *e) { /* Set the event node if necessary */ if (e->node) { if (last_event.node) { if (strcmp(e->node, last_event.node) != 0) { free((void *)last_event.node); last_event.node = strdup(e->node); } } else last_event.node = strdup(e->node); if (last_event.node == NULL) { fprintf(stderr, "No memory to allocate " "checkpoint last event node name\n"); return 1; } } else { if (last_event.node) free((void *)last_event.node); last_event.node = NULL; } last_event.sec = e->sec; last_event.milli = e->milli; last_event.serial = e->serial; last_event.type = e->type; return 0; } /* Free all checkpoint memory */ void free_ChkPtMemory(void) { if (last_event.node) (void)free((void *)last_event.node); last_event.node = NULL; if (chkpt_input_levent.node) (void)free((void *)chkpt_input_levent.node); chkpt_input_levent.node = NULL; } /* * Save the checkpoint to the given file * Returns: * 1 io error * 0 OK */ void save_ChkPt(const char *fn) { FILE *fd; if ((fd = fopen(fn, "w")) == NULL) { fprintf(stderr, "Cannot open checkpoint file - %s: %s\n", fn, strerror(errno)); checkpt_failure |= CP_STATUSIO; return; } // Write the inode in decimal to make ls -i easier to use. fprintf(fd, "dev=0x%" PRIX64 "\ninode=%" PRIu64 "\n", (uint64_t)checkpt_dev, (uint64_t)checkpt_ino); fprintf(fd, "output=%s %lld.%03u:%lu 0x%X\n", last_event.node ? last_event.node : "-", (long long int)last_event.sec, last_event.milli, last_event.serial, (unsigned int)last_event.type); fclose(fd); } /* * Parse a checkpoint file "output=" record * Returns * 1 failed to parse or no memory * 0 parsed OK */ static int parse_checkpt_event(char *lbuf, int ndix, event *e) { char *rest; /* sscanf's %X conversion requires unsigned int storage. */ unsigned int type; /* * Find the space after the node, then make it '\0' so * we terminate the node value. We leave 'rest' at the start * of the event time/serial element */ rest = strchr(&lbuf[ndix], ' '); if (rest == NULL) { fprintf(stderr, "Malformed output/event checkpoint line " "near node - [%s]\n", lbuf); checkpt_failure |= CP_STATUSBAD; return 1; } *rest++ = '\0'; if (lbuf[ndix] == '-') e->node = NULL; else { e->node = strdup(&lbuf[ndix]); if (e->node == NULL) { fprintf(stderr, "No memory for node when loading " "checkpoint line - [%s]\n", lbuf); checkpt_failure |= CP_NOMEM; return 1; } } if (sscanf(rest, TIME_T_SPECIFIER ".%03u:%lu 0x%X", &e->sec, &e->milli, &e->serial, &type) != 4) { fprintf(stderr, "Malformed output/event checkpoint line " "after node - [%s]\n", lbuf); checkpt_failure |= CP_STATUSBAD; return 1; } e->type = (int)type; return 0; } /* * Load the checkpoint from the given file * Returns: * < -1 error * == -1 no file present * == 0 loaded data */ int load_ChkPt(const char *fn) { #define MAX_LN 1023 FILE *fd; char lbuf[MAX_LN]; if ((fd = fopen(fn, "r")) == NULL) { if (errno == ENOENT) return -1; fprintf(stderr, "Cannot open checkpoint file - %s: %s\n", fn, strerror(errno)); return -2; } chkpt_input_levent.node = NULL; while (fgets(lbuf, MAX_LN, fd) != NULL) { size_t len = strlen(lbuf); if (len && lbuf[len - 1] == '\n') /* drop the newline */ lbuf[len - 1] = '\0'; if (strncmp(lbuf, "dev=", 4) == 0) { errno = 0; chkpt_input_dev = (dev_t)strtoull(&lbuf[4], NULL, 16); if (errno) { fprintf(stderr, "Malformed dev checkpoint " "line - [%s]\n", lbuf); checkpt_failure |= CP_STATUSBAD; break; } } else if (strncmp(lbuf, "inode=", 6) == 0) { errno = 0; chkpt_input_ino = (ino_t)strtoull(&lbuf[6], NULL, 0); if (errno) { fprintf(stderr, "Malformed inode checkpoint " "line - [%s]\n", lbuf); checkpt_failure |= CP_STATUSBAD; break; } } else if (strncmp(lbuf, "output=", 7) == 0) { free((void *)chkpt_input_levent.node); chkpt_input_levent.node = NULL; if (parse_checkpt_event(lbuf, 7, &chkpt_input_levent)) break; } else { fprintf(stderr, "Unknown checkpoint line - [%s]\n", lbuf); checkpt_failure |= CP_STATUSBAD; break; } } if ( (chkpt_input_ino == (ino_t)NULL) || (chkpt_input_dev == (dev_t)NULL) ) { fprintf(stderr, "Missing dev/inode lines from checkpoint " "file %s\n", fn); checkpt_failure |= CP_STATUSBAD; } fclose(fd); if (checkpt_failure) return -3; #if DBG { fprintf(stderr, "Loaded %s - dev: 0x%X, ino: 0x%X\n", fn, chkpt_input_dev, chkpt_input_ino); fprintf(stderr, "output:%s %lld.%03d:%lu 0x%X\n", chkpt_input_levent.node ? chkpt_input_levent.node : "-", (long long int)chkpt_input_levent.sec, chkpt_input_levent.milli, chkpt_input_levent.serial, chkpt_input_levent.type); } #endif /* DBG */ return 0; }