]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/journal-util.c
Drop my copyright headers
[thirdparty/systemd.git] / src / shared / journal-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
4f37cbd9
ZJS
2
3#include "acl-util.h"
4#include "fs-util.h"
5#include "hashmap.h"
6#include "journal-internal.h"
7#include "journal-util.h"
8#include "log.h"
9#include "strv.h"
10#include "user-util.h"
11
e79d0b59 12static int access_check_var_log_journal(sd_journal *j, bool want_other_users) {
349cc4a5 13#if HAVE_ACL
4f37cbd9
ZJS
14 _cleanup_strv_free_ char **g = NULL;
15 const char* dir;
16#endif
17 int r;
18
19 assert(j);
20
21 /* If we are root, we should have access, don't warn. */
22 if (getuid() == 0)
23 return 0;
24
25 /* If we are in the 'systemd-journal' group, we should have
26 * access too. */
27 r = in_group("systemd-journal");
28 if (r < 0)
29 return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
30 if (r > 0)
31 return 0;
32
349cc4a5 33#if HAVE_ACL
4f37cbd9
ZJS
34 if (laccess("/run/log/journal", F_OK) >= 0)
35 dir = "/run/log/journal";
36 else
37 dir = "/var/log/journal";
38
39 /* If we are in any of the groups listed in the journal ACLs,
40 * then all is good, too. Let's enumerate all groups from the
41 * default ACL of the directory, which generally should allow
42 * access to most journal files too. */
43 r = acl_search_groups(dir, &g);
44 if (r < 0)
45 return log_error_errno(r, "Failed to search journal ACL: %m");
46 if (r > 0)
47 return 0;
48
49 /* Print a pretty list, if there were ACLs set. */
50 if (!strv_isempty(g)) {
51 _cleanup_free_ char *s = NULL;
52
53 /* Thre are groups in the ACL, let's list them */
54 r = strv_extend(&g, "systemd-journal");
55 if (r < 0)
56 return log_oom();
57
58 strv_sort(g);
59 strv_uniq(g);
60
61 s = strv_join(g, "', '");
62 if (!s)
63 return log_oom();
64
e79d0b59 65 log_notice("Hint: You are currently not seeing messages from %s.\n"
4f37cbd9 66 " Users in groups '%s' can see all messages.\n"
e79d0b59
ZJS
67 " Pass -q to turn off this notice.",
68 want_other_users ? "other users and the system" : "the system",
69 s);
4f37cbd9
ZJS
70 return 1;
71 }
72#endif
73
74 /* If no ACLs were found, print a short version of the message. */
e79d0b59 75 log_notice("Hint: You are currently not seeing messages from %s.\n"
4f37cbd9 76 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
e79d0b59
ZJS
77 " turn off this notice.",
78 want_other_users ? "other users and the system" : "the system");
4f37cbd9
ZJS
79
80 return 1;
81}
82
e79d0b59 83int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_users) {
4f37cbd9
ZJS
84 Iterator it;
85 void *code;
86 char *path;
87 int r = 0;
88
89 assert(j);
90
91 if (hashmap_isempty(j->errors)) {
92 if (ordered_hashmap_isempty(j->files) && !quiet)
93 log_notice("No journal files were found.");
94
95 return 0;
96 }
97
98 if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
99 if (!quiet)
e79d0b59 100 (void) access_check_var_log_journal(j, want_other_users);
4f37cbd9
ZJS
101
102 if (ordered_hashmap_isempty(j->files))
103 r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
104 }
105
106 HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
107 int err;
108
109 err = abs(PTR_TO_INT(code));
110
111 switch (err) {
112 case EACCES:
113 continue;
114
115 case ENODATA:
116 log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
117 break;
118
119 case EPROTONOSUPPORT:
120 log_warning_errno(err, "Journal file %1$s uses an unsupported feature, ignoring file.\n"
121 "Use SYSTEMD_LOG_LEVEL=debug journalctl --file=%1$s to see the details.",
122 path);
123 break;
124
125 case EBADMSG:
126 log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
127 break;
128
129 default:
130 log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
131 break;
132 }
133 }
134
135 return r;
136}
53978b98
LP
137
138bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
139 const char *a;
140
141 /* We kinda enforce POSIX syntax recommendations for
142 environment variables here, but make a couple of additional
143 requirements.
144
145 http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
146
147 if (l == (size_t) -1)
148 l = strlen(p);
149
150 /* No empty field names */
151 if (l <= 0)
152 return false;
153
154 /* Don't allow names longer than 64 chars */
155 if (l > 64)
156 return false;
157
158 /* Variables starting with an underscore are protected */
159 if (!allow_protected && p[0] == '_')
160 return false;
161
162 /* Don't allow digits as first character */
163 if (p[0] >= '0' && p[0] <= '9')
164 return false;
165
166 /* Only allow A-Z0-9 and '_' */
167 for (a = p; a < p + l; a++)
168 if ((*a < 'A' || *a > 'Z') &&
169 (*a < '0' || *a > '9') &&
170 *a != '_')
171 return false;
172
173 return true;
174}