175 lines
5.7 KiB
C
175 lines
5.7 KiB
C
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
|
|
#include "acl-util.h"
|
|
#include "fs-util.h"
|
|
#include "hashmap.h"
|
|
#include "journal-internal.h"
|
|
#include "journal-util.h"
|
|
#include "log.h"
|
|
#include "strv.h"
|
|
#include "user-util.h"
|
|
|
|
static int access_check_var_log_journal(sd_journal *j, bool want_other_users) {
|
|
#if HAVE_ACL
|
|
_cleanup_strv_free_ char **g = NULL;
|
|
const char* dir;
|
|
#endif
|
|
int r;
|
|
|
|
assert(j);
|
|
|
|
/* If we are root, we should have access, don't warn. */
|
|
if (getuid() == 0)
|
|
return 0;
|
|
|
|
/* If we are in the 'systemd-journal' group, we should have
|
|
* access too. */
|
|
r = in_group("systemd-journal");
|
|
if (r < 0)
|
|
return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
|
|
if (r > 0)
|
|
return 0;
|
|
|
|
#if HAVE_ACL
|
|
if (laccess("/run/log/journal", F_OK) >= 0)
|
|
dir = "/run/log/journal";
|
|
else
|
|
dir = "/var/log/journal";
|
|
|
|
/* If we are in any of the groups listed in the journal ACLs,
|
|
* then all is good, too. Let's enumerate all groups from the
|
|
* default ACL of the directory, which generally should allow
|
|
* access to most journal files too. */
|
|
r = acl_search_groups(dir, &g);
|
|
if (r < 0)
|
|
return log_error_errno(r, "Failed to search journal ACL: %m");
|
|
if (r > 0)
|
|
return 0;
|
|
|
|
/* Print a pretty list, if there were ACLs set. */
|
|
if (!strv_isempty(g)) {
|
|
_cleanup_free_ char *s = NULL;
|
|
|
|
/* There are groups in the ACL, let's list them */
|
|
r = strv_extend(&g, "systemd-journal");
|
|
if (r < 0)
|
|
return log_oom();
|
|
|
|
strv_sort(g);
|
|
strv_uniq(g);
|
|
|
|
s = strv_join(g, "', '");
|
|
if (!s)
|
|
return log_oom();
|
|
|
|
log_notice("Hint: You are currently not seeing messages from %s.\n"
|
|
" Users in groups '%s' can see all messages.\n"
|
|
" Pass -q to turn off this notice.",
|
|
want_other_users ? "other users and the system" : "the system",
|
|
s);
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
/* If no ACLs were found, print a short version of the message. */
|
|
log_notice("Hint: You are currently not seeing messages from %s.\n"
|
|
" Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
|
|
" turn off this notice.",
|
|
want_other_users ? "other users and the system" : "the system");
|
|
|
|
return 1;
|
|
}
|
|
|
|
int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_users) {
|
|
Iterator it;
|
|
void *code;
|
|
char *path;
|
|
int r = 0;
|
|
|
|
assert(j);
|
|
|
|
if (hashmap_isempty(j->errors)) {
|
|
if (ordered_hashmap_isempty(j->files) && !quiet)
|
|
log_notice("No journal files were found.");
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
|
|
if (!quiet)
|
|
(void) access_check_var_log_journal(j, want_other_users);
|
|
|
|
if (ordered_hashmap_isempty(j->files))
|
|
r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
|
|
}
|
|
|
|
HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
|
|
int err;
|
|
|
|
err = abs(PTR_TO_INT(code));
|
|
|
|
switch (err) {
|
|
case EACCES:
|
|
continue;
|
|
|
|
case ENODATA:
|
|
log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
|
|
break;
|
|
|
|
case EPROTONOSUPPORT:
|
|
log_warning_errno(err, "Journal file %1$s uses an unsupported feature, ignoring file.\n"
|
|
"Use SYSTEMD_LOG_LEVEL=debug journalctl --file=%1$s to see the details.",
|
|
path);
|
|
break;
|
|
|
|
case EBADMSG:
|
|
log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
|
|
break;
|
|
|
|
default:
|
|
log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
|
|
const char *a;
|
|
|
|
/* We kinda enforce POSIX syntax recommendations for
|
|
environment variables here, but make a couple of additional
|
|
requirements.
|
|
|
|
http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
|
|
|
|
if (l == (size_t) -1)
|
|
l = strlen(p);
|
|
|
|
/* No empty field names */
|
|
if (l <= 0)
|
|
return false;
|
|
|
|
/* Don't allow names longer than 64 chars */
|
|
if (l > 64)
|
|
return false;
|
|
|
|
/* Variables starting with an underscore are protected */
|
|
if (!allow_protected && p[0] == '_')
|
|
return false;
|
|
|
|
/* Don't allow digits as first character */
|
|
if (p[0] >= '0' && p[0] <= '9')
|
|
return false;
|
|
|
|
/* Only allow A-Z0-9 and '_' */
|
|
for (a = p; a < p + l; a++)
|
|
if ((*a < 'A' || *a > 'Z') &&
|
|
(*a < '0' || *a > '9') &&
|
|
*a != '_')
|
|
return false;
|
|
|
|
return true;
|
|
}
|