]>
Commit | Line | Data |
---|---|---|
4f37cbd9 ZJS |
1 | /*** |
2 | This file is part of systemd. | |
3 | ||
4 | Copyright 2013 Zbigniew Jędrzejewski-Szmek | |
5 | Copyright 2015 Lennart Poettering | |
6 | ||
7 | systemd is free software; you can redistribute it and/or modify it | |
8 | under the terms of the GNU Lesser General Public License as published by | |
9 | the Free Software Foundation; either version 2.1 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | systemd is distributed in the hope that it will be useful, but | |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | Lesser General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU Lesser General Public License | |
18 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
19 | ***/ | |
20 | ||
21 | #include "acl-util.h" | |
22 | #include "fs-util.h" | |
23 | #include "hashmap.h" | |
24 | #include "journal-internal.h" | |
25 | #include "journal-util.h" | |
26 | #include "log.h" | |
27 | #include "strv.h" | |
28 | #include "user-util.h" | |
29 | ||
30 | static int access_check_var_log_journal(sd_journal *j) { | |
349cc4a5 | 31 | #if HAVE_ACL |
4f37cbd9 ZJS |
32 | _cleanup_strv_free_ char **g = NULL; |
33 | const char* dir; | |
34 | #endif | |
35 | int r; | |
36 | ||
37 | assert(j); | |
38 | ||
39 | /* If we are root, we should have access, don't warn. */ | |
40 | if (getuid() == 0) | |
41 | return 0; | |
42 | ||
43 | /* If we are in the 'systemd-journal' group, we should have | |
44 | * access too. */ | |
45 | r = in_group("systemd-journal"); | |
46 | if (r < 0) | |
47 | return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m"); | |
48 | if (r > 0) | |
49 | return 0; | |
50 | ||
349cc4a5 | 51 | #if HAVE_ACL |
4f37cbd9 ZJS |
52 | if (laccess("/run/log/journal", F_OK) >= 0) |
53 | dir = "/run/log/journal"; | |
54 | else | |
55 | dir = "/var/log/journal"; | |
56 | ||
57 | /* If we are in any of the groups listed in the journal ACLs, | |
58 | * then all is good, too. Let's enumerate all groups from the | |
59 | * default ACL of the directory, which generally should allow | |
60 | * access to most journal files too. */ | |
61 | r = acl_search_groups(dir, &g); | |
62 | if (r < 0) | |
63 | return log_error_errno(r, "Failed to search journal ACL: %m"); | |
64 | if (r > 0) | |
65 | return 0; | |
66 | ||
67 | /* Print a pretty list, if there were ACLs set. */ | |
68 | if (!strv_isempty(g)) { | |
69 | _cleanup_free_ char *s = NULL; | |
70 | ||
71 | /* Thre are groups in the ACL, let's list them */ | |
72 | r = strv_extend(&g, "systemd-journal"); | |
73 | if (r < 0) | |
74 | return log_oom(); | |
75 | ||
76 | strv_sort(g); | |
77 | strv_uniq(g); | |
78 | ||
79 | s = strv_join(g, "', '"); | |
80 | if (!s) | |
81 | return log_oom(); | |
82 | ||
83 | log_notice("Hint: You are currently not seeing messages from other users and the system.\n" | |
84 | " Users in groups '%s' can see all messages.\n" | |
85 | " Pass -q to turn off this notice.", s); | |
86 | return 1; | |
87 | } | |
88 | #endif | |
89 | ||
90 | /* If no ACLs were found, print a short version of the message. */ | |
91 | log_notice("Hint: You are currently not seeing messages from other users and the system.\n" | |
92 | " Users in the 'systemd-journal' group can see all messages. Pass -q to\n" | |
93 | " turn off this notice."); | |
94 | ||
95 | return 1; | |
96 | } | |
97 | ||
98 | int journal_access_check_and_warn(sd_journal *j, bool quiet) { | |
99 | Iterator it; | |
100 | void *code; | |
101 | char *path; | |
102 | int r = 0; | |
103 | ||
104 | assert(j); | |
105 | ||
106 | if (hashmap_isempty(j->errors)) { | |
107 | if (ordered_hashmap_isempty(j->files) && !quiet) | |
108 | log_notice("No journal files were found."); | |
109 | ||
110 | return 0; | |
111 | } | |
112 | ||
113 | if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) { | |
114 | if (!quiet) | |
115 | (void) access_check_var_log_journal(j); | |
116 | ||
117 | if (ordered_hashmap_isempty(j->files)) | |
118 | r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions."); | |
119 | } | |
120 | ||
121 | HASHMAP_FOREACH_KEY(path, code, j->errors, it) { | |
122 | int err; | |
123 | ||
124 | err = abs(PTR_TO_INT(code)); | |
125 | ||
126 | switch (err) { | |
127 | case EACCES: | |
128 | continue; | |
129 | ||
130 | case ENODATA: | |
131 | log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path); | |
132 | break; | |
133 | ||
134 | case EPROTONOSUPPORT: | |
135 | log_warning_errno(err, "Journal file %1$s uses an unsupported feature, ignoring file.\n" | |
136 | "Use SYSTEMD_LOG_LEVEL=debug journalctl --file=%1$s to see the details.", | |
137 | path); | |
138 | break; | |
139 | ||
140 | case EBADMSG: | |
141 | log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path); | |
142 | break; | |
143 | ||
144 | default: | |
145 | log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path); | |
146 | break; | |
147 | } | |
148 | } | |
149 | ||
150 | return r; | |
151 | } |