Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
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 : :
12 : 0 : static int access_check_var_log_journal(sd_journal *j, bool want_other_users) {
13 : : #if HAVE_ACL
14 : 0 : _cleanup_strv_free_ char **g = NULL;
15 : : const char* dir;
16 : : #endif
17 : : int r;
18 : :
19 [ # # ]: 0 : assert(j);
20 : :
21 : : /* If we are root, we should have access, don't warn. */
22 [ # # ]: 0 : if (getuid() == 0)
23 : 0 : return 0;
24 : :
25 : : /* If we are in the 'systemd-journal' group, we should have
26 : : * access too. */
27 : 0 : r = in_group("systemd-journal");
28 [ # # ]: 0 : if (r < 0)
29 [ # # ]: 0 : return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
30 [ # # ]: 0 : if (r > 0)
31 : 0 : return 0;
32 : :
33 : : #if HAVE_ACL
34 [ # # ]: 0 : if (laccess("/run/log/journal", F_OK) >= 0)
35 : 0 : dir = "/run/log/journal";
36 : : else
37 : 0 : 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 : 0 : r = acl_search_groups(dir, &g);
44 [ # # ]: 0 : if (r < 0)
45 [ # # ]: 0 : return log_error_errno(r, "Failed to search journal ACL: %m");
46 [ # # ]: 0 : if (r > 0)
47 : 0 : return 0;
48 : :
49 : : /* Print a pretty list, if there were ACLs set. */
50 [ # # ]: 0 : if (!strv_isempty(g)) {
51 : 0 : _cleanup_free_ char *s = NULL;
52 : :
53 : : /* There are groups in the ACL, let's list them */
54 : 0 : r = strv_extend(&g, "systemd-journal");
55 [ # # ]: 0 : if (r < 0)
56 : 0 : return log_oom();
57 : :
58 : 0 : strv_sort(g);
59 : 0 : strv_uniq(g);
60 : :
61 : 0 : s = strv_join(g, "', '");
62 [ # # ]: 0 : if (!s)
63 : 0 : return log_oom();
64 : :
65 [ # # # # ]: 0 : log_notice("Hint: You are currently not seeing messages from %s.\n"
66 : : " Users in groups '%s' can see all messages.\n"
67 : : " Pass -q to turn off this notice.",
68 : : want_other_users ? "other users and the system" : "the system",
69 : : s);
70 : 0 : return 1;
71 : : }
72 : : #endif
73 : :
74 : : /* If no ACLs were found, print a short version of the message. */
75 [ # # # # ]: 0 : log_notice("Hint: You are currently not seeing messages from %s.\n"
76 : : " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
77 : : " turn off this notice.",
78 : : want_other_users ? "other users and the system" : "the system");
79 : :
80 : 0 : return 1;
81 : : }
82 : :
83 : 0 : int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_users) {
84 : : Iterator it;
85 : : void *code;
86 : : char *path;
87 : 0 : int r = 0;
88 : :
89 [ # # ]: 0 : assert(j);
90 : :
91 [ # # ]: 0 : if (hashmap_isempty(j->errors)) {
92 [ # # # # ]: 0 : if (ordered_hashmap_isempty(j->files) && !quiet)
93 [ # # ]: 0 : log_notice("No journal files were found.");
94 : :
95 : 0 : return 0;
96 : : }
97 : :
98 [ # # ]: 0 : if (hashmap_contains(j->errors, INT_TO_PTR(-EACCES))) {
99 [ # # ]: 0 : if (!quiet)
100 : 0 : (void) access_check_var_log_journal(j, want_other_users);
101 : :
102 [ # # ]: 0 : if (ordered_hashmap_isempty(j->files))
103 [ # # ]: 0 : r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
104 : : }
105 : :
106 [ # # ]: 0 : HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
107 : : int err;
108 : :
109 : 0 : err = abs(PTR_TO_INT(code));
110 : :
111 [ # # # # : 0 : switch (err) {
# ]
112 : 0 : case EACCES:
113 : 0 : continue;
114 : :
115 : 0 : case ENODATA:
116 [ # # ]: 0 : log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
117 : 0 : break;
118 : :
119 : 0 : case EPROTONOSUPPORT:
120 [ # # ]: 0 : 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 : 0 : break;
124 : :
125 : 0 : case EBADMSG:
126 [ # # ]: 0 : log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
127 : 0 : break;
128 : :
129 : 0 : default:
130 [ # # ]: 0 : log_warning_errno(err, "An error was encountered while opening journal file or directory %s, ignoring file: %m", path);
131 : 0 : break;
132 : : }
133 : : }
134 : :
135 : 0 : return r;
136 : : }
137 : :
138 : 44 : bool 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 [ - + ]: 44 : if (l == (size_t) -1)
148 : 0 : l = strlen(p);
149 : :
150 : : /* No empty field names */
151 [ - + ]: 44 : if (l <= 0)
152 : 0 : return false;
153 : :
154 : : /* Don't allow names longer than 64 chars */
155 [ - + ]: 44 : if (l > 64)
156 : 0 : return false;
157 : :
158 : : /* Variables starting with an underscore are protected */
159 [ + + - + ]: 44 : if (!allow_protected && p[0] == '_')
160 : 0 : return false;
161 : :
162 : : /* Don't allow digits as first character */
163 [ + - - + ]: 44 : if (p[0] >= '0' && p[0] <= '9')
164 : 0 : return false;
165 : :
166 : : /* Only allow A-Z0-9 and '_' */
167 [ + + ]: 540 : for (a = p; a < p + l; a++)
168 [ + + + + ]: 496 : if ((*a < 'A' || *a > 'Z') &&
169 [ + - + + ]: 68 : (*a < '0' || *a > '9') &&
170 [ - + ]: 60 : *a != '_')
171 : 0 : return false;
172 : :
173 : 44 : return true;
174 : : }
|