LCOV - code coverage report
Current view: top level - shared - journal-util.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 11 79 13.9 %
Date: 2019-08-23 13:36:53 Functions: 1 3 33.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 18 91 19.8 %

           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                 :            : }

Generated by: LCOV version 1.14