1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
6 #include "sd-journal.h"
9 #include "alloc-util.h"
10 #include "bus-error.h"
11 #include "bus-locator.h"
16 #include "journal-internal.h"
17 #include "journal-util.h"
20 #include "user-util.h"
22 static int access_check_var_log_journal(sd_journal
*j
, bool want_other_users
) {
27 /* If we are root, we should have access, don't warn. */
31 /* If we are in the 'systemd-journal' group, we should have
33 r
= in_group("systemd-journal");
35 return log_error_errno(r
, "Failed to check if we are in the 'systemd-journal' group: %m");
40 _cleanup_strv_free_
char **g
= NULL
;
43 if (access_nofollow("/run/log/journal", F_OK
) >= 0)
44 dir
= "/run/log/journal";
46 dir
= "/var/log/journal";
48 /* If we are in any of the groups listed in the journal ACLs,
49 * then all is good, too. Let's enumerate all groups from the
50 * default ACL of the directory, which generally should allow
51 * access to most journal files too. */
52 r
= acl_search_groups(dir
, &g
);
54 return log_error_errno(r
, "Failed to search journal ACL: %m");
58 /* Print a pretty list, if there were ACLs set. */
59 if (!strv_isempty(g
)) {
60 _cleanup_free_
char *s
= NULL
;
62 /* There are groups in the ACL, let's list them */
63 r
= strv_extend(&g
, "systemd-journal");
69 s
= strv_join(g
, "', '");
73 log_notice("Hint: You are currently not seeing messages from %s.\n"
74 " Users in groups '%s' can see all messages.\n"
75 " Pass -q to turn off this notice.",
76 want_other_users
? "other users and the system" : "the system",
82 /* If no ACLs were found, print a short version of the message. */
83 log_notice("Hint: You are currently not seeing messages from %s.\n"
84 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
85 " turn off this notice.",
86 want_other_users
? "other users and the system" : "the system");
91 int journal_access_blocked(sd_journal
*j
) {
92 return hashmap_contains(j
->errors
, INT_TO_PTR(-EACCES
));
95 int journal_access_check_and_warn(sd_journal
*j
, bool quiet
, bool want_other_users
) {
102 if (hashmap_isempty(j
->errors
)) {
103 if (ordered_hashmap_isempty(j
->files
) && !quiet
)
104 log_notice("No journal files were found.");
109 if (journal_access_blocked(j
)) {
111 (void) access_check_var_log_journal(j
, want_other_users
);
113 if (ordered_hashmap_isempty(j
->files
))
114 r
= log_error_errno(EACCES
, "No journal files were opened due to insufficient permissions.");
117 HASHMAP_FOREACH_KEY(path
, code
, j
->errors
) {
120 err
= ABS(PTR_TO_INT(code
));
127 log_warning_errno(err
, "Journal file %s is truncated, ignoring file.", path
);
130 case EPROTONOSUPPORT
:
131 log_warning_errno(err
, "Journal file %1$s uses an unsupported feature, ignoring file.\n"
132 "Use SYSTEMD_LOG_LEVEL=debug journalctl --file=%1$s to see the details.",
137 log_warning_errno(err
, "Journal file %s corrupted, ignoring file.", path
);
141 log_warning_errno(err
, "Too many journal files (limit is at %u) in scope, ignoring file '%s'.", JOURNAL_FILES_MAX
, path
);
145 log_warning_errno(err
, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path
);
152 int journal_open_machine(sd_journal
**ret
, const char *machine
, int flags
) {
153 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
154 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
155 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
156 _cleanup_(sd_journal_closep
) sd_journal
*j
= NULL
;
157 _cleanup_close_
int machine_fd
= -EBADF
;
164 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
165 * the container, thus we need root privileges to override them. */
166 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Using the --machine= switch requires root privileges.");
168 r
= sd_bus_open_system(&bus
);
170 return log_error_errno(r
, "Failed to open system bus: %m");
172 r
= bus_call_method(bus
, bus_machine_mgr
, "OpenMachineRootDirectory", &error
, &reply
, "s", machine
);
174 return log_error_errno(r
, "Failed to open root directory of machine '%s': %s",
175 machine
, bus_error_message(&error
, r
));
177 r
= sd_bus_message_read(reply
, "h", &fd
);
179 return bus_log_parse_error(r
);
181 machine_fd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
183 return log_error_errno(errno
, "Failed to duplicate file descriptor: %m");
185 r
= sd_journal_open_directory_fd(&j
, machine_fd
, SD_JOURNAL_OS_ROOT
| SD_JOURNAL_TAKE_DIRECTORY_FD
| flags
);
187 return log_error_errno(r
, "Failed to open journal in machine '%s': %m", machine
);