journald: introduce journal_file_parse_uid_from_filename() helper

This commit is contained in:
Franck Bui
2023-01-16 15:04:29 +01:00
parent 43d287ec8c
commit 596c3c7f1b
5 changed files with 89 additions and 16 deletions
+5 -16
View File
@@ -559,9 +559,8 @@ static int server_archive_offline_user_journals(Server *s) {
}
for (;;) {
_cleanup_free_ char *u = NULL, *full = NULL;
_cleanup_free_ char *full = NULL;
_cleanup_close_ int fd = -EBADF;
const char *a, *b;
struct dirent *de;
ManagedJournalFile *f;
uid_t uid;
@@ -573,24 +572,14 @@ static int server_archive_offline_user_journals(Server *s) {
log_ratelimit_warning_errno(errno, JOURNAL_LOG_RATELIMIT,
"Failed to enumerate %s, ignoring: %m",
s->system_storage.path);
break;
}
a = startswith(de->d_name, "user-");
if (!a)
continue;
b = endswith(de->d_name, ".journal");
if (!b)
continue;
u = strndup(a, b-a);
if (!u)
return log_oom();
r = parse_uid(u, &uid);
r = journal_file_parse_uid_from_filename(de->d_name, &uid);
if (r < 0) {
log_debug_errno(r, "Failed to parse UID from file name '%s', ignoring: %m", de->d_name);
/* Don't warn if the file is not an online or offline user journal. */
if (r != -EREMOTE)
log_warning_errno(r, "Failed to parse UID from file name '%s', ignoring: %m", de->d_name);
continue;
}
+2
View File
@@ -191,6 +191,8 @@ libsystemd_pc = custom_target(
############################################################
tests += [
[files('sd-journal/test-journal-file.c')],
[files('sd-journal/test-journal-send.c')],
[files('sd-journal/test-journal-match.c')],
+36
View File
@@ -35,6 +35,7 @@
#include "string-util.h"
#include "strv.h"
#include "sync-util.h"
#include "user-util.h"
#include "xattr-util.h"
#define DEFAULT_DATA_HASH_TABLE_SIZE (2047ULL*sizeof(HashItem))
@@ -3932,6 +3933,41 @@ fail:
return r;
}
int journal_file_parse_uid_from_filename(const char *path, uid_t *ret_uid) {
_cleanup_free_ char *buf = NULL, *p = NULL;
const char *a, *b, *at;
int r;
/* This helper returns -EREMOTE when the filename doesn't match user online/offline journal
* pattern. Hence it currently doesn't parse archived or disposed user journals. */
assert(path);
assert(ret_uid);
r = path_extract_filename(path, &p);
if (r < 0)
return r;
if (r == O_DIRECTORY)
return -EISDIR;
a = startswith(p, "user-");
if (!a)
return -EREMOTE;
b = endswith(p, ".journal");
if (!b)
return -EREMOTE;
at = strchr(a, '@');
if (at)
return -EREMOTE;
buf = strndup(a, b-a);
if (!buf)
return -ENOMEM;
return parse_uid(buf, ret_uid);
}
int journal_file_archive(JournalFile *f, char **ret_previous_path) {
_cleanup_free_ char *p = NULL;
+1
View File
@@ -288,6 +288,7 @@ void journal_file_dump(JournalFile *f);
void journal_file_print_header(JournalFile *f);
int journal_file_archive(JournalFile *f, char **ret_previous_path);
int journal_file_parse_uid_from_filename(const char *path, uid_t *uid);
JournalFile* journal_initiate_close(JournalFile *f, Set *deferred_closes);
int journal_file_dispose(int dir_fd, const char *fname);
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include "journal-file.h"
#include "tests.h"
#include "user-util.h"
static void test_journal_file_parse_uid_from_filename_simple(
const char *path,
uid_t expected_uid,
int expected_error) {
uid_t uid = UID_INVALID;
int r;
log_info("testing %s", path);
r = journal_file_parse_uid_from_filename(path, &uid);
assert_se(r == expected_error);
if (r < 0)
assert_se(uid == UID_INVALID);
else
assert_se(uid == expected_uid);
}
TEST(journal_file_parse_uid_from_filename) {
test_journal_file_parse_uid_from_filename_simple("/var/log/journal/", 0, -EISDIR);
/* The helper should return -EREMOTE for any filenames that don't look like an online or offline user
* journals. This includes archived and disposed journal files. */
test_journal_file_parse_uid_from_filename_simple("/etc/password", 0, -EREMOTE);
test_journal_file_parse_uid_from_filename_simple("system.journal", 0, -EREMOTE);
test_journal_file_parse_uid_from_filename_simple("user-1000@0005d26980bdce6e-2f2a4939583822ef.journal~", 0, -EREMOTE);
test_journal_file_parse_uid_from_filename_simple("user-1000@xxx-yyy-zzz.journal", 0, -EREMOTE);
test_journal_file_parse_uid_from_filename_simple("user-1000.journal", 1000, 0);
test_journal_file_parse_uid_from_filename_simple("user-foo.journal", 0, -EINVAL);
test_journal_file_parse_uid_from_filename_simple("user-65535.journal", 0, -ENXIO);
}
DEFINE_TEST_MAIN(LOG_INFO);