Coverage Report

Created: 2019-06-19 13:33

/src/systemd/src/shared/journal-util.c
Line
Count
Source (jump to first uncovered line)
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
        _cleanup_strv_free_ char **g = NULL;
15
        const char* dir;
16
#endif
17
        int r;
18
0
19
0
        assert(j);
20
0
21
0
        /* If we are root, we should have access, don't warn. */
22
0
        if (getuid() == 0)
23
0
                return 0;
24
0
25
0
        /* If we are in the 'systemd-journal' group, we should have
26
0
         * 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
0
33
#if HAVE_ACL
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
                /* There 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
65
                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
                return 1;
71
        }
72
#endif
73
74
0
        /* 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
0
                   "      Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
77
0
                   "      turn off this notice.",
78
0
                   want_other_users ? "other users and the system" : "the system");
79
0
80
0
        return 1;
81
0
}
82
83
0
int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_users) {
84
0
        Iterator it;
85
0
        void *code;
86
0
        char *path;
87
0
        int r = 0;
88
0
89
0
        assert(j);
90
0
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
0
95
0
                return 0;
96
0
        }
97
0
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
0
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
0
        }
105
0
106
0
        HASHMAP_FOREACH_KEY(path, code, j->errors, it) {
107
0
                int err;
108
0
109
0
                err = abs(PTR_TO_INT(code));
110
0
111
0
                switch (err) {
112
0
                case EACCES:
113
0
                        continue;
114
0
115
0
                case ENODATA:
116
0
                        log_warning_errno(err, "Journal file %s is truncated, ignoring file.", path);
117
0
                        break;
118
0
119
0
                case EPROTONOSUPPORT:
120
0
                        log_warning_errno(err, "Journal file %1$s uses an unsupported feature, ignoring file.\n"
121
0
                                               "Use SYSTEMD_LOG_LEVEL=debug journalctl --file=%1$s to see the details.",
122
0
                                               path);
123
0
                        break;
124
0
125
0
                case EBADMSG:
126
0
                        log_warning_errno(err, "Journal file %s corrupted, ignoring file.", path);
127
0
                        break;
128
0
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
0
                }
133
0
        }
134
0
135
0
        return r;
136
0
}
137
138
841k
bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
139
841k
        const char *a;
140
841k
141
841k
        /* We kinda enforce POSIX syntax recommendations for
142
841k
           environment variables here, but make a couple of additional
143
841k
           requirements.
144
841k
145
841k
           http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
146
841k
147
841k
        if (l == (size_t) -1)
148
0
                l = strlen(p);
149
841k
150
841k
        /* No empty field names */
151
841k
        if (l <= 0)
152
6.20k
                return false;
153
835k
154
835k
        /* Don't allow names longer than 64 chars */
155
835k
        if (l > 64)
156
3.53k
                return false;
157
831k
158
831k
        /* Variables starting with an underscore are protected */
159
831k
        if (!allow_protected && p[0] == '_')
160
621
                return false;
161
830k
162
830k
        /* Don't allow digits as first character */
163
830k
        if (p[0] >= '0' && p[0] <= '9')
164
2.86k
                return false;
165
828k
166
828k
        /* Only allow A-Z0-9 and '_' */
167
4.80M
        for (a = p; a < p + l; a++)
168
4.01M
                if ((*a < 'A' || *a > 'Z') &&
169
4.01M
                    (*a < '0' || *a > '9') &&
170
4.01M
                    *a != '_')
171
41.2k
                        return false;
172
828k
173
828k
        return true;
174
828k
}