]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journalctl.c
treewide: use log_*_errno whenever %m is in the format string
[thirdparty/systemd.git] / src / journal / journalctl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <locale.h>
23 #include <fcntl.h>
24 #include <fnmatch.h>
25 #include <errno.h>
26 #include <stddef.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <time.h>
32 #include <getopt.h>
33 #include <signal.h>
34 #include <poll.h>
35 #include <sys/stat.h>
36 #include <sys/ioctl.h>
37 #include <sys/inotify.h>
38 #include <linux/fs.h>
39
40 #ifdef HAVE_ACL
41 #include <sys/acl.h>
42 #include "acl-util.h"
43 #endif
44
45 #include "sd-journal.h"
46 #include "sd-bus.h"
47
48 #include "log.h"
49 #include "logs-show.h"
50 #include "util.h"
51 #include "path-util.h"
52 #include "fileio.h"
53 #include "build.h"
54 #include "pager.h"
55 #include "strv.h"
56 #include "set.h"
57 #include "journal-internal.h"
58 #include "journal-def.h"
59 #include "journal-verify.h"
60 #include "journal-authenticate.h"
61 #include "journal-qrcode.h"
62 #include "journal-vacuum.h"
63 #include "fsprg.h"
64 #include "unit-name.h"
65 #include "catalog.h"
66 #include "mkdir.h"
67 #include "bus-util.h"
68 #include "bus-error.h"
69
70 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
71
72 enum {
73 /* Special values for arg_lines */
74 ARG_LINES_DEFAULT = -2,
75 ARG_LINES_ALL = -1,
76 };
77
78 static OutputMode arg_output = OUTPUT_SHORT;
79 static bool arg_utc = false;
80 static bool arg_pager_end = false;
81 static bool arg_follow = false;
82 static bool arg_full = true;
83 static bool arg_all = false;
84 static bool arg_no_pager = false;
85 static int arg_lines = ARG_LINES_DEFAULT;
86 static bool arg_no_tail = false;
87 static bool arg_quiet = false;
88 static bool arg_merge = false;
89 static bool arg_boot = false;
90 static sd_id128_t arg_boot_id = {};
91 static int arg_boot_offset = 0;
92 static bool arg_dmesg = false;
93 static const char *arg_cursor = NULL;
94 static const char *arg_after_cursor = NULL;
95 static bool arg_show_cursor = false;
96 static const char *arg_directory = NULL;
97 static char **arg_file = NULL;
98 static int arg_priorities = 0xFF;
99 static const char *arg_verify_key = NULL;
100 #ifdef HAVE_GCRYPT
101 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
102 static bool arg_force = false;
103 #endif
104 static usec_t arg_since, arg_until;
105 static bool arg_since_set = false, arg_until_set = false;
106 static char **arg_syslog_identifier = NULL;
107 static char **arg_system_units = NULL;
108 static char **arg_user_units = NULL;
109 static const char *arg_field = NULL;
110 static bool arg_catalog = false;
111 static bool arg_reverse = false;
112 static int arg_journal_type = 0;
113 static const char *arg_root = NULL;
114 static const char *arg_machine = NULL;
115 static off_t arg_vacuum_size = (off_t) -1;
116 static usec_t arg_vacuum_time = USEC_INFINITY;
117
118 static enum {
119 ACTION_SHOW,
120 ACTION_NEW_ID128,
121 ACTION_PRINT_HEADER,
122 ACTION_SETUP_KEYS,
123 ACTION_VERIFY,
124 ACTION_DISK_USAGE,
125 ACTION_LIST_CATALOG,
126 ACTION_DUMP_CATALOG,
127 ACTION_UPDATE_CATALOG,
128 ACTION_LIST_BOOTS,
129 ACTION_FLUSH,
130 ACTION_VACUUM,
131 } arg_action = ACTION_SHOW;
132
133 typedef struct boot_id_t {
134 sd_id128_t id;
135 uint64_t first;
136 uint64_t last;
137 } boot_id_t;
138
139 static void pager_open_if_enabled(void) {
140
141 if (arg_no_pager)
142 return;
143
144 pager_open(arg_pager_end);
145 }
146
147 static char *format_timestamp_maybe_utc(char *buf, size_t l, usec_t t) {
148
149 if (arg_utc)
150 return format_timestamp_utc(buf, l, t);
151
152 return format_timestamp(buf, l, t);
153 }
154
155 static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset) {
156 sd_id128_t id = SD_ID128_NULL;
157 int off = 0, r;
158
159 if (strlen(x) >= 32) {
160 char *t;
161
162 t = strndupa(x, 32);
163 r = sd_id128_from_string(t, &id);
164 if (r >= 0)
165 x += 32;
166
167 if (*x != '-' && *x != '+' && *x != 0)
168 return -EINVAL;
169
170 if (*x != 0) {
171 r = safe_atoi(x, &off);
172 if (r < 0)
173 return r;
174 }
175 } else {
176 r = safe_atoi(x, &off);
177 if (r < 0)
178 return r;
179 }
180
181 if (boot_id)
182 *boot_id = id;
183
184 if (offset)
185 *offset = off;
186
187 return 0;
188 }
189
190 static void help(void) {
191
192 pager_open_if_enabled();
193
194 printf("%s [OPTIONS...] [MATCHES...]\n\n"
195 "Query the journal.\n\n"
196 "Flags:\n"
197 " --system Show the system journal\n"
198 " --user Show the user journal for the current user\n"
199 " -M --machine=CONTAINER Operate on local container\n"
200 " --since=DATE Start showing entries on or newer than the specified date\n"
201 " --until=DATE Stop showing entries on or newer than the specified date\n"
202 " -c --cursor=CURSOR Start showing entries from the specified cursor\n"
203 " --after-cursor=CURSOR Start showing entries from after the specified cursor\n"
204 " --show-cursor Print the cursor after all the entries\n"
205 " -b --boot[=ID] Show data only from ID or, if unspecified, the current boot\n"
206 " --list-boots Show terse information about recorded boots\n"
207 " -k --dmesg Show kernel message log from the current boot\n"
208 " -u --unit=UNIT Show data only from the specified unit\n"
209 " --user-unit=UNIT Show data only from the specified user session unit\n"
210 " -t --identifier=STRING Show only messages with the specified syslog identifier\n"
211 " -p --priority=RANGE Show only messages within the specified priority range\n"
212 " -e --pager-end Immediately jump to end of the journal in the pager\n"
213 " -f --follow Follow the journal\n"
214 " -n --lines[=INTEGER] Number of journal entries to show\n"
215 " --no-tail Show all lines, even in follow mode\n"
216 " -r --reverse Show the newest entries first\n"
217 " -o --output=STRING Change journal output mode (short, short-iso,\n"
218 " short-precise, short-monotonic, verbose,\n"
219 " export, json, json-pretty, json-sse, cat)\n"
220 " --utc Express time in Coordinated Universal Time (UTC)\n"
221 " -x --catalog Add message explanations where available\n"
222 " --no-full Ellipsize fields\n"
223 " -a --all Show all fields, including long and unprintable\n"
224 " -q --quiet Do not show privilege warning\n"
225 " --no-pager Do not pipe output into a pager\n"
226 " -m --merge Show entries from all available journals\n"
227 " -D --directory=PATH Show journal files from directory\n"
228 " --file=PATH Show journal file\n"
229 " --root=ROOT Operate on catalog files underneath the root ROOT\n"
230 #ifdef HAVE_GCRYPT
231 " --interval=TIME Time interval for changing the FSS sealing key\n"
232 " --verify-key=KEY Specify FSS verification key\n"
233 " --force Force overriding of the FSS key pair with --setup-keys\n"
234 #endif
235 "\nCommands:\n"
236 " -h --help Show this help text\n"
237 " --version Show package version\n"
238 " -F --field=FIELD List all values that a specified field takes\n"
239 " --new-id128 Generate a new 128-bit ID\n"
240 " --disk-usage Show total disk usage of all journal files\n"
241 " --vacuum-size=BYTES Remove old journals until disk space drops below size\n"
242 " --vacuum-time=TIME Remove old journals until none left older than\n"
243 " --flush Flush all journal data from /run into /var\n"
244 " --header Show journal header information\n"
245 " --list-catalog Show message IDs of all entries in the message catalog\n"
246 " --dump-catalog Show entries in the message catalog\n"
247 " --update-catalog Update the message catalog database\n"
248 #ifdef HAVE_GCRYPT
249 " --setup-keys Generate a new FSS key pair\n"
250 " --verify Verify journal file consistency\n"
251 #endif
252 , program_invocation_short_name);
253 }
254
255 static int parse_argv(int argc, char *argv[]) {
256
257 enum {
258 ARG_VERSION = 0x100,
259 ARG_NO_PAGER,
260 ARG_NO_FULL,
261 ARG_NO_TAIL,
262 ARG_NEW_ID128,
263 ARG_LIST_BOOTS,
264 ARG_USER,
265 ARG_SYSTEM,
266 ARG_ROOT,
267 ARG_HEADER,
268 ARG_SETUP_KEYS,
269 ARG_FILE,
270 ARG_INTERVAL,
271 ARG_VERIFY,
272 ARG_VERIFY_KEY,
273 ARG_DISK_USAGE,
274 ARG_SINCE,
275 ARG_UNTIL,
276 ARG_AFTER_CURSOR,
277 ARG_SHOW_CURSOR,
278 ARG_USER_UNIT,
279 ARG_LIST_CATALOG,
280 ARG_DUMP_CATALOG,
281 ARG_UPDATE_CATALOG,
282 ARG_FORCE,
283 ARG_UTC,
284 ARG_FLUSH,
285 ARG_VACUUM_SIZE,
286 ARG_VACUUM_TIME,
287 };
288
289 static const struct option options[] = {
290 { "help", no_argument, NULL, 'h' },
291 { "version" , no_argument, NULL, ARG_VERSION },
292 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
293 { "pager-end", no_argument, NULL, 'e' },
294 { "follow", no_argument, NULL, 'f' },
295 { "force", no_argument, NULL, ARG_FORCE },
296 { "output", required_argument, NULL, 'o' },
297 { "all", no_argument, NULL, 'a' },
298 { "full", no_argument, NULL, 'l' },
299 { "no-full", no_argument, NULL, ARG_NO_FULL },
300 { "lines", optional_argument, NULL, 'n' },
301 { "no-tail", no_argument, NULL, ARG_NO_TAIL },
302 { "new-id128", no_argument, NULL, ARG_NEW_ID128 },
303 { "quiet", no_argument, NULL, 'q' },
304 { "merge", no_argument, NULL, 'm' },
305 { "boot", optional_argument, NULL, 'b' },
306 { "list-boots", no_argument, NULL, ARG_LIST_BOOTS },
307 { "this-boot", optional_argument, NULL, 'b' }, /* deprecated */
308 { "dmesg", no_argument, NULL, 'k' },
309 { "system", no_argument, NULL, ARG_SYSTEM },
310 { "user", no_argument, NULL, ARG_USER },
311 { "directory", required_argument, NULL, 'D' },
312 { "file", required_argument, NULL, ARG_FILE },
313 { "root", required_argument, NULL, ARG_ROOT },
314 { "header", no_argument, NULL, ARG_HEADER },
315 { "identifier", required_argument, NULL, 't' },
316 { "priority", required_argument, NULL, 'p' },
317 { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
318 { "interval", required_argument, NULL, ARG_INTERVAL },
319 { "verify", no_argument, NULL, ARG_VERIFY },
320 { "verify-key", required_argument, NULL, ARG_VERIFY_KEY },
321 { "disk-usage", no_argument, NULL, ARG_DISK_USAGE },
322 { "cursor", required_argument, NULL, 'c' },
323 { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR },
324 { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR },
325 { "since", required_argument, NULL, ARG_SINCE },
326 { "until", required_argument, NULL, ARG_UNTIL },
327 { "unit", required_argument, NULL, 'u' },
328 { "user-unit", required_argument, NULL, ARG_USER_UNIT },
329 { "field", required_argument, NULL, 'F' },
330 { "catalog", no_argument, NULL, 'x' },
331 { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG },
332 { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG },
333 { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG },
334 { "reverse", no_argument, NULL, 'r' },
335 { "machine", required_argument, NULL, 'M' },
336 { "utc", no_argument, NULL, ARG_UTC },
337 { "flush", no_argument, NULL, ARG_FLUSH },
338 { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE },
339 { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME },
340 {}
341 };
342
343 int c, r;
344
345 assert(argc >= 0);
346 assert(argv);
347
348 while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:t:u:F:xrM:", options, NULL)) >= 0)
349
350 switch (c) {
351
352 case 'h':
353 help();
354 return 0;
355
356 case ARG_VERSION:
357 puts(PACKAGE_STRING);
358 puts(SYSTEMD_FEATURES);
359 return 0;
360
361 case ARG_NO_PAGER:
362 arg_no_pager = true;
363 break;
364
365 case 'e':
366 arg_pager_end = true;
367
368 if (arg_lines == ARG_LINES_DEFAULT)
369 arg_lines = 1000;
370
371 break;
372
373 case 'f':
374 arg_follow = true;
375 break;
376
377 case 'o':
378 arg_output = output_mode_from_string(optarg);
379 if (arg_output < 0) {
380 log_error("Unknown output format '%s'.", optarg);
381 return -EINVAL;
382 }
383
384 if (arg_output == OUTPUT_EXPORT ||
385 arg_output == OUTPUT_JSON ||
386 arg_output == OUTPUT_JSON_PRETTY ||
387 arg_output == OUTPUT_JSON_SSE ||
388 arg_output == OUTPUT_CAT)
389 arg_quiet = true;
390
391 break;
392
393 case 'l':
394 arg_full = true;
395 break;
396
397 case ARG_NO_FULL:
398 arg_full = false;
399 break;
400
401 case 'a':
402 arg_all = true;
403 break;
404
405 case 'n':
406 if (optarg) {
407 if (streq(optarg, "all"))
408 arg_lines = ARG_LINES_ALL;
409 else {
410 r = safe_atoi(optarg, &arg_lines);
411 if (r < 0 || arg_lines < 0) {
412 log_error("Failed to parse lines '%s'", optarg);
413 return -EINVAL;
414 }
415 }
416 } else {
417 arg_lines = 10;
418
419 /* Hmm, no argument? Maybe the next
420 * word on the command line is
421 * supposed to be the argument? Let's
422 * see if there is one, and is
423 * parsable. */
424 if (optind < argc) {
425 int n;
426 if (streq(argv[optind], "all")) {
427 arg_lines = ARG_LINES_ALL;
428 optind++;
429 } else if (safe_atoi(argv[optind], &n) >= 0 && n >= 0) {
430 arg_lines = n;
431 optind++;
432 }
433 }
434 }
435
436 break;
437
438 case ARG_NO_TAIL:
439 arg_no_tail = true;
440 break;
441
442 case ARG_NEW_ID128:
443 arg_action = ACTION_NEW_ID128;
444 break;
445
446 case 'q':
447 arg_quiet = true;
448 break;
449
450 case 'm':
451 arg_merge = true;
452 break;
453
454 case 'b':
455 arg_boot = true;
456
457 if (optarg) {
458 r = parse_boot_descriptor(optarg, &arg_boot_id, &arg_boot_offset);
459 if (r < 0) {
460 log_error("Failed to parse boot descriptor '%s'", optarg);
461 return -EINVAL;
462 }
463 } else {
464
465 /* Hmm, no argument? Maybe the next
466 * word on the command line is
467 * supposed to be the argument? Let's
468 * see if there is one and is parsable
469 * as a boot descriptor... */
470
471 if (optind < argc &&
472 parse_boot_descriptor(argv[optind], &arg_boot_id, &arg_boot_offset) >= 0)
473 optind++;
474 }
475
476 break;
477
478 case ARG_LIST_BOOTS:
479 arg_action = ACTION_LIST_BOOTS;
480 break;
481
482 case 'k':
483 arg_boot = arg_dmesg = true;
484 break;
485
486 case ARG_SYSTEM:
487 arg_journal_type |= SD_JOURNAL_SYSTEM;
488 break;
489
490 case ARG_USER:
491 arg_journal_type |= SD_JOURNAL_CURRENT_USER;
492 break;
493
494 case 'M':
495 arg_machine = optarg;
496 break;
497
498 case 'D':
499 arg_directory = optarg;
500 break;
501
502 case ARG_FILE:
503 r = glob_extend(&arg_file, optarg);
504 if (r < 0)
505 return log_error_errno(r, "Failed to add paths: %m");
506 break;
507
508 case ARG_ROOT:
509 arg_root = optarg;
510 break;
511
512 case 'c':
513 arg_cursor = optarg;
514 break;
515
516 case ARG_AFTER_CURSOR:
517 arg_after_cursor = optarg;
518 break;
519
520 case ARG_SHOW_CURSOR:
521 arg_show_cursor = true;
522 break;
523
524 case ARG_HEADER:
525 arg_action = ACTION_PRINT_HEADER;
526 break;
527
528 case ARG_VERIFY:
529 arg_action = ACTION_VERIFY;
530 break;
531
532 case ARG_DISK_USAGE:
533 arg_action = ACTION_DISK_USAGE;
534 break;
535
536 case ARG_VACUUM_SIZE:
537 r = parse_size(optarg, 1024, &arg_vacuum_size);
538 if (r < 0) {
539 log_error("Failed to parse vacuum size: %s", optarg);
540 return r;
541 }
542
543 arg_action = ACTION_VACUUM;
544 break;
545
546 case ARG_VACUUM_TIME:
547 r = parse_sec(optarg, &arg_vacuum_time);
548 if (r < 0) {
549 log_error("Failed to parse vacuum time: %s", optarg);
550 return r;
551 }
552
553 arg_action = ACTION_VACUUM;
554 break;
555
556 #ifdef HAVE_GCRYPT
557 case ARG_FORCE:
558 arg_force = true;
559 break;
560
561 case ARG_SETUP_KEYS:
562 arg_action = ACTION_SETUP_KEYS;
563 break;
564
565
566 case ARG_VERIFY_KEY:
567 arg_action = ACTION_VERIFY;
568 arg_verify_key = optarg;
569 arg_merge = false;
570 break;
571
572 case ARG_INTERVAL:
573 r = parse_sec(optarg, &arg_interval);
574 if (r < 0 || arg_interval <= 0) {
575 log_error("Failed to parse sealing key change interval: %s", optarg);
576 return -EINVAL;
577 }
578 break;
579 #else
580 case ARG_SETUP_KEYS:
581 case ARG_VERIFY_KEY:
582 case ARG_INTERVAL:
583 case ARG_FORCE:
584 log_error("Forward-secure sealing not available.");
585 return -ENOTSUP;
586 #endif
587
588 case 'p': {
589 const char *dots;
590
591 dots = strstr(optarg, "..");
592 if (dots) {
593 char *a;
594 int from, to, i;
595
596 /* a range */
597 a = strndup(optarg, dots - optarg);
598 if (!a)
599 return log_oom();
600
601 from = log_level_from_string(a);
602 to = log_level_from_string(dots + 2);
603 free(a);
604
605 if (from < 0 || to < 0) {
606 log_error("Failed to parse log level range %s", optarg);
607 return -EINVAL;
608 }
609
610 arg_priorities = 0;
611
612 if (from < to) {
613 for (i = from; i <= to; i++)
614 arg_priorities |= 1 << i;
615 } else {
616 for (i = to; i <= from; i++)
617 arg_priorities |= 1 << i;
618 }
619
620 } else {
621 int p, i;
622
623 p = log_level_from_string(optarg);
624 if (p < 0) {
625 log_error("Unknown log level %s", optarg);
626 return -EINVAL;
627 }
628
629 arg_priorities = 0;
630
631 for (i = 0; i <= p; i++)
632 arg_priorities |= 1 << i;
633 }
634
635 break;
636 }
637
638 case ARG_SINCE:
639 r = parse_timestamp(optarg, &arg_since);
640 if (r < 0) {
641 log_error("Failed to parse timestamp: %s", optarg);
642 return -EINVAL;
643 }
644 arg_since_set = true;
645 break;
646
647 case ARG_UNTIL:
648 r = parse_timestamp(optarg, &arg_until);
649 if (r < 0) {
650 log_error("Failed to parse timestamp: %s", optarg);
651 return -EINVAL;
652 }
653 arg_until_set = true;
654 break;
655
656 case 't':
657 r = strv_extend(&arg_syslog_identifier, optarg);
658 if (r < 0)
659 return log_oom();
660 break;
661
662 case 'u':
663 r = strv_extend(&arg_system_units, optarg);
664 if (r < 0)
665 return log_oom();
666 break;
667
668 case ARG_USER_UNIT:
669 r = strv_extend(&arg_user_units, optarg);
670 if (r < 0)
671 return log_oom();
672 break;
673
674 case 'F':
675 arg_field = optarg;
676 break;
677
678 case 'x':
679 arg_catalog = true;
680 break;
681
682 case ARG_LIST_CATALOG:
683 arg_action = ACTION_LIST_CATALOG;
684 break;
685
686 case ARG_DUMP_CATALOG:
687 arg_action = ACTION_DUMP_CATALOG;
688 break;
689
690 case ARG_UPDATE_CATALOG:
691 arg_action = ACTION_UPDATE_CATALOG;
692 break;
693
694 case 'r':
695 arg_reverse = true;
696 break;
697
698 case ARG_UTC:
699 arg_utc = true;
700 break;
701
702 case ARG_FLUSH:
703 arg_action = ACTION_FLUSH;
704 break;
705
706 case '?':
707 return -EINVAL;
708
709 default:
710 assert_not_reached("Unhandled option");
711 }
712
713 if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
714 arg_lines = 10;
715
716 if (!!arg_directory + !!arg_file + !!arg_machine > 1) {
717 log_error("Please specify either -D/--directory= or --file= or -M/--machine=, not more than one.");
718 return -EINVAL;
719 }
720
721 if (arg_since_set && arg_until_set && arg_since > arg_until) {
722 log_error("--since= must be before --until=.");
723 return -EINVAL;
724 }
725
726 if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) {
727 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.");
728 return -EINVAL;
729 }
730
731 if (arg_follow && arg_reverse) {
732 log_error("Please specify either --reverse= or --follow=, not both.");
733 return -EINVAL;
734 }
735
736 if (arg_action != ACTION_SHOW && optind < argc) {
737 log_error("Extraneous arguments starting with '%s'", argv[optind]);
738 return -EINVAL;
739 }
740
741 return 1;
742 }
743
744 static int generate_new_id128(void) {
745 sd_id128_t id;
746 int r;
747 unsigned i;
748
749 r = sd_id128_randomize(&id);
750 if (r < 0)
751 return log_error_errno(r, "Failed to generate ID: %m");
752
753 printf("As string:\n"
754 SD_ID128_FORMAT_STR "\n\n"
755 "As UUID:\n"
756 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
757 "As macro:\n"
758 "#define MESSAGE_XYZ SD_ID128_MAKE(",
759 SD_ID128_FORMAT_VAL(id),
760 SD_ID128_FORMAT_VAL(id));
761 for (i = 0; i < 16; i++)
762 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
763 fputs(")\n\n", stdout);
764
765 printf("As Python constant:\n"
766 ">>> import uuid\n"
767 ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
768 SD_ID128_FORMAT_VAL(id));
769
770 return 0;
771 }
772
773 static int add_matches(sd_journal *j, char **args) {
774 char **i;
775 bool have_term = false;
776
777 assert(j);
778
779 STRV_FOREACH(i, args) {
780 int r;
781
782 if (streq(*i, "+")) {
783 if (!have_term)
784 break;
785 r = sd_journal_add_disjunction(j);
786 have_term = false;
787
788 } else if (path_is_absolute(*i)) {
789 _cleanup_free_ char *p, *t = NULL, *t2 = NULL;
790 const char *path;
791 _cleanup_free_ char *interpreter = NULL;
792 struct stat st;
793
794 p = canonicalize_file_name(*i);
795 path = p ? p : *i;
796
797 if (stat(path, &st) < 0) {
798 log_error_errno(errno, "Couldn't stat file: %m");
799 return -errno;
800 }
801
802 if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
803 if (executable_is_script(path, &interpreter) > 0) {
804 _cleanup_free_ char *comm;
805
806 comm = strndup(basename(path), 15);
807 if (!comm)
808 return log_oom();
809
810 t = strappend("_COMM=", comm);
811
812 /* Append _EXE only if the interpreter is not a link.
813 Otherwise, it might be outdated often. */
814 if (lstat(interpreter, &st) == 0 &&
815 !S_ISLNK(st.st_mode)) {
816 t2 = strappend("_EXE=", interpreter);
817 if (!t2)
818 return log_oom();
819 }
820 } else
821 t = strappend("_EXE=", path);
822 } else if (S_ISCHR(st.st_mode)) {
823 if (asprintf(&t, "_KERNEL_DEVICE=c%u:%u",
824 major(st.st_rdev),
825 minor(st.st_rdev)) < 0)
826 return -ENOMEM;
827 } else if (S_ISBLK(st.st_mode)) {
828 if (asprintf(&t, "_KERNEL_DEVICE=b%u:%u",
829 major(st.st_rdev),
830 minor(st.st_rdev)) < 0)
831 return -ENOMEM;
832 } else {
833 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
834 return -EINVAL;
835 }
836
837 if (!t)
838 return log_oom();
839
840 r = sd_journal_add_match(j, t, 0);
841 if (t2)
842 r = sd_journal_add_match(j, t2, 0);
843 have_term = true;
844
845 } else {
846 r = sd_journal_add_match(j, *i, 0);
847 have_term = true;
848 }
849
850 if (r < 0)
851 return log_error_errno(r, "Failed to add match '%s': %m", *i);
852 }
853
854 if (!strv_isempty(args) && !have_term) {
855 log_error("\"+\" can only be used between terms");
856 return -EINVAL;
857 }
858
859 return 0;
860 }
861
862 static int boot_id_cmp(const void *a, const void *b) {
863 uint64_t _a, _b;
864
865 _a = ((const boot_id_t *)a)->first;
866 _b = ((const boot_id_t *)b)->first;
867
868 return _a < _b ? -1 : (_a > _b ? 1 : 0);
869 }
870
871 static int get_boots(sd_journal *j,
872 boot_id_t **boots,
873 unsigned int *count,
874 boot_id_t *query_ref_boot) {
875 int r;
876 const void *data;
877 size_t length, allocated = 0;
878
879 assert(j);
880 assert(boots);
881 assert(count);
882
883 r = sd_journal_query_unique(j, "_BOOT_ID");
884 if (r < 0)
885 return r;
886
887 *count = 0;
888 SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
889 boot_id_t *id;
890
891 assert(startswith(data, "_BOOT_ID="));
892
893 if (!GREEDY_REALLOC(*boots, allocated, *count + 1))
894 return log_oom();
895
896 id = *boots + *count;
897
898 r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
899 if (r < 0)
900 continue;
901
902 r = sd_journal_add_match(j, data, length);
903 if (r < 0)
904 return r;
905
906 r = sd_journal_seek_head(j);
907 if (r < 0)
908 return r;
909
910 r = sd_journal_next(j);
911 if (r < 0)
912 return r;
913 else if (r == 0)
914 goto flush;
915
916 r = sd_journal_get_realtime_usec(j, &id->first);
917 if (r < 0)
918 return r;
919
920 if (query_ref_boot) {
921 id->last = 0;
922 if (sd_id128_equal(id->id, query_ref_boot->id))
923 *query_ref_boot = *id;
924 } else {
925 r = sd_journal_seek_tail(j);
926 if (r < 0)
927 return r;
928
929 r = sd_journal_previous(j);
930 if (r < 0)
931 return r;
932 else if (r == 0)
933 goto flush;
934
935 r = sd_journal_get_realtime_usec(j, &id->last);
936 if (r < 0)
937 return r;
938 }
939
940 (*count)++;
941 flush:
942 sd_journal_flush_matches(j);
943 }
944
945 qsort_safe(*boots, *count, sizeof(boot_id_t), boot_id_cmp);
946 return 0;
947 }
948
949 static int list_boots(sd_journal *j) {
950 int r, w, i;
951 unsigned int count;
952 boot_id_t *id;
953 _cleanup_free_ boot_id_t *all_ids = NULL;
954
955 assert(j);
956
957 r = get_boots(j, &all_ids, &count, NULL);
958 if (r < 0)
959 return r;
960
961 pager_open_if_enabled();
962
963 /* numbers are one less, but we need an extra char for the sign */
964 w = DECIMAL_STR_WIDTH(count - 1) + 1;
965
966 for (id = all_ids, i = 0; id < all_ids + count; id++, i++) {
967 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
968
969 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
970 w, i - count + 1,
971 SD_ID128_FORMAT_VAL(id->id),
972 format_timestamp_maybe_utc(a, sizeof(a), id->first),
973 format_timestamp_maybe_utc(b, sizeof(b), id->last));
974 }
975
976 return 0;
977 }
978
979 static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) {
980 int r;
981 unsigned int count;
982 boot_id_t ref_boot_id = {}, *id;
983 _cleanup_free_ boot_id_t *all_ids = NULL;
984
985 assert(j);
986 assert(boot_id);
987
988 ref_boot_id.id = *boot_id;
989 r = get_boots(j, &all_ids, &count, &ref_boot_id);
990 if (r < 0)
991 return r;
992
993 if (sd_id128_equal(*boot_id, SD_ID128_NULL)) {
994 if (offset > (int) count || offset <= -(int)count)
995 return -EADDRNOTAVAIL;
996
997 *boot_id = all_ids[(offset <= 0)*count + offset - 1].id;
998 } else {
999 id = bsearch(&ref_boot_id, all_ids, count, sizeof(boot_id_t), boot_id_cmp);
1000
1001 if (!id ||
1002 offset <= 0 ? (id - all_ids) + offset < 0 :
1003 (id - all_ids) + offset >= (int) count)
1004 return -EADDRNOTAVAIL;
1005
1006 *boot_id = (id + offset)->id;
1007 }
1008
1009 return 0;
1010 }
1011
1012 static int add_boot(sd_journal *j) {
1013 char match[9+32+1] = "_BOOT_ID=";
1014 int r;
1015
1016 assert(j);
1017
1018 if (!arg_boot)
1019 return 0;
1020
1021 if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
1022 return add_match_this_boot(j, arg_machine);
1023
1024 r = get_boot_id_by_offset(j, &arg_boot_id, arg_boot_offset);
1025 if (r < 0) {
1026 if (sd_id128_equal(arg_boot_id, SD_ID128_NULL))
1027 log_error_errno(r, "Failed to look up boot %+i: %m", arg_boot_offset);
1028 else
1029 log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s",
1030 SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, strerror(-r));
1031 return r;
1032 }
1033
1034 sd_id128_to_string(arg_boot_id, match + 9);
1035
1036 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1037 if (r < 0)
1038 return log_error_errno(r, "Failed to add match: %m");
1039
1040 r = sd_journal_add_conjunction(j);
1041 if (r < 0)
1042 return r;
1043
1044 return 0;
1045 }
1046
1047 static int add_dmesg(sd_journal *j) {
1048 int r;
1049 assert(j);
1050
1051 if (!arg_dmesg)
1052 return 0;
1053
1054 r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
1055 if (r < 0)
1056 return log_error_errno(r, "Failed to add match: %m");
1057
1058 r = sd_journal_add_conjunction(j);
1059 if (r < 0)
1060 return r;
1061
1062 return 0;
1063 }
1064
1065 static int get_possible_units(sd_journal *j,
1066 const char *fields,
1067 char **patterns,
1068 Set **units) {
1069 _cleanup_set_free_free_ Set *found;
1070 const char *field;
1071 int r;
1072
1073 found = set_new(&string_hash_ops);
1074 if (!found)
1075 return log_oom();
1076
1077 NULSTR_FOREACH(field, fields) {
1078 const void *data;
1079 size_t size;
1080
1081 r = sd_journal_query_unique(j, field);
1082 if (r < 0)
1083 return r;
1084
1085 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1086 char **pattern, *eq;
1087 size_t prefix;
1088 _cleanup_free_ char *u = NULL;
1089
1090 eq = memchr(data, '=', size);
1091 if (eq)
1092 prefix = eq - (char*) data + 1;
1093 else
1094 prefix = 0;
1095
1096 u = strndup((char*) data + prefix, size - prefix);
1097 if (!u)
1098 return log_oom();
1099
1100 STRV_FOREACH(pattern, patterns)
1101 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1102 log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1103
1104 r = set_consume(found, u);
1105 u = NULL;
1106 if (r < 0 && r != -EEXIST)
1107 return r;
1108
1109 break;
1110 }
1111 }
1112 }
1113
1114 *units = found;
1115 found = NULL;
1116 return 0;
1117 }
1118
1119 /* This list is supposed to return the superset of unit names
1120 * possibly matched by rules added with add_matches_for_unit... */
1121 #define SYSTEM_UNITS \
1122 "_SYSTEMD_UNIT\0" \
1123 "COREDUMP_UNIT\0" \
1124 "UNIT\0" \
1125 "OBJECT_SYSTEMD_UNIT\0" \
1126 "_SYSTEMD_SLICE\0"
1127
1128 /* ... and add_matches_for_user_unit */
1129 #define USER_UNITS \
1130 "_SYSTEMD_USER_UNIT\0" \
1131 "USER_UNIT\0" \
1132 "COREDUMP_USER_UNIT\0" \
1133 "OBJECT_SYSTEMD_USER_UNIT\0"
1134
1135 static int add_units(sd_journal *j) {
1136 _cleanup_strv_free_ char **patterns = NULL;
1137 int r, count = 0;
1138 char **i;
1139
1140 assert(j);
1141
1142 STRV_FOREACH(i, arg_system_units) {
1143 _cleanup_free_ char *u = NULL;
1144
1145 u = unit_name_mangle(*i, MANGLE_GLOB);
1146 if (!u)
1147 return log_oom();
1148
1149 if (string_is_glob(u)) {
1150 r = strv_push(&patterns, u);
1151 if (r < 0)
1152 return r;
1153 u = NULL;
1154 } else {
1155 r = add_matches_for_unit(j, u);
1156 if (r < 0)
1157 return r;
1158 r = sd_journal_add_disjunction(j);
1159 if (r < 0)
1160 return r;
1161 count ++;
1162 }
1163 }
1164
1165 if (!strv_isempty(patterns)) {
1166 _cleanup_set_free_free_ Set *units = NULL;
1167 Iterator it;
1168 char *u;
1169
1170 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1171 if (r < 0)
1172 return r;
1173
1174 SET_FOREACH(u, units, it) {
1175 r = add_matches_for_unit(j, u);
1176 if (r < 0)
1177 return r;
1178 r = sd_journal_add_disjunction(j);
1179 if (r < 0)
1180 return r;
1181 count ++;
1182 }
1183 }
1184
1185 strv_free(patterns);
1186 patterns = NULL;
1187
1188 STRV_FOREACH(i, arg_user_units) {
1189 _cleanup_free_ char *u = NULL;
1190
1191 u = unit_name_mangle(*i, MANGLE_GLOB);
1192 if (!u)
1193 return log_oom();
1194
1195 if (string_is_glob(u)) {
1196 r = strv_push(&patterns, u);
1197 if (r < 0)
1198 return r;
1199 u = NULL;
1200 } else {
1201 r = add_matches_for_user_unit(j, u, getuid());
1202 if (r < 0)
1203 return r;
1204 r = sd_journal_add_disjunction(j);
1205 if (r < 0)
1206 return r;
1207 count ++;
1208 }
1209 }
1210
1211 if (!strv_isempty(patterns)) {
1212 _cleanup_set_free_free_ Set *units = NULL;
1213 Iterator it;
1214 char *u;
1215
1216 r = get_possible_units(j, USER_UNITS, patterns, &units);
1217 if (r < 0)
1218 return r;
1219
1220 SET_FOREACH(u, units, it) {
1221 r = add_matches_for_user_unit(j, u, getuid());
1222 if (r < 0)
1223 return r;
1224 r = sd_journal_add_disjunction(j);
1225 if (r < 0)
1226 return r;
1227 count ++;
1228 }
1229 }
1230
1231 /* Complain if the user request matches but nothing whatsoever was
1232 * found, since otherwise everything would be matched. */
1233 if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1234 return -ENODATA;
1235
1236 r = sd_journal_add_conjunction(j);
1237 if (r < 0)
1238 return r;
1239
1240 return 0;
1241 }
1242
1243 static int add_priorities(sd_journal *j) {
1244 char match[] = "PRIORITY=0";
1245 int i, r;
1246 assert(j);
1247
1248 if (arg_priorities == 0xFF)
1249 return 0;
1250
1251 for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1252 if (arg_priorities & (1 << i)) {
1253 match[sizeof(match)-2] = '0' + i;
1254
1255 r = sd_journal_add_match(j, match, strlen(match));
1256 if (r < 0)
1257 return log_error_errno(r, "Failed to add match: %m");
1258 }
1259
1260 r = sd_journal_add_conjunction(j);
1261 if (r < 0)
1262 return r;
1263
1264 return 0;
1265 }
1266
1267
1268 static int add_syslog_identifier(sd_journal *j) {
1269 int r;
1270 char **i;
1271
1272 assert(j);
1273
1274 STRV_FOREACH(i, arg_syslog_identifier) {
1275 char *u;
1276
1277 u = strappenda("SYSLOG_IDENTIFIER=", *i);
1278 r = sd_journal_add_match(j, u, 0);
1279 if (r < 0)
1280 return r;
1281 r = sd_journal_add_disjunction(j);
1282 if (r < 0)
1283 return r;
1284 }
1285
1286 r = sd_journal_add_conjunction(j);
1287 if (r < 0)
1288 return r;
1289
1290 return 0;
1291 }
1292
1293 static int setup_keys(void) {
1294 #ifdef HAVE_GCRYPT
1295 size_t mpk_size, seed_size, state_size, i;
1296 uint8_t *mpk, *seed, *state;
1297 ssize_t l;
1298 int fd = -1, r, attr = 0;
1299 sd_id128_t machine, boot;
1300 char *p = NULL, *k = NULL;
1301 struct FSSHeader h;
1302 uint64_t n;
1303 struct stat st;
1304
1305 r = stat("/var/log/journal", &st);
1306 if (r < 0 && errno != ENOENT && errno != ENOTDIR) {
1307 log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1308 return -errno;
1309 }
1310
1311 if (r < 0 || !S_ISDIR(st.st_mode)) {
1312 log_error("%s is not a directory, must be using persistent logging for FSS.",
1313 "/var/log/journal");
1314 return r < 0 ? -errno : -ENOTDIR;
1315 }
1316
1317 r = sd_id128_get_machine(&machine);
1318 if (r < 0)
1319 return log_error_errno(r, "Failed to get machine ID: %m");
1320
1321 r = sd_id128_get_boot(&boot);
1322 if (r < 0)
1323 return log_error_errno(r, "Failed to get boot ID: %m");
1324
1325 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1326 SD_ID128_FORMAT_VAL(machine)) < 0)
1327 return log_oom();
1328
1329 if (access(p, F_OK) >= 0) {
1330 if (arg_force) {
1331 r = unlink(p);
1332 if (r < 0) {
1333 log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1334 r = -errno;
1335 goto finish;
1336 }
1337 } else {
1338 log_error("Sealing key file %s exists already. (--force to recreate)", p);
1339 r = -EEXIST;
1340 goto finish;
1341 }
1342 }
1343
1344 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1345 SD_ID128_FORMAT_VAL(machine)) < 0) {
1346 r = log_oom();
1347 goto finish;
1348 }
1349
1350 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1351 mpk = alloca(mpk_size);
1352
1353 seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1354 seed = alloca(seed_size);
1355
1356 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1357 state = alloca(state_size);
1358
1359 fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1360 if (fd < 0) {
1361 log_error_errno(errno, "Failed to open /dev/random: %m");
1362 r = -errno;
1363 goto finish;
1364 }
1365
1366 log_info("Generating seed...");
1367 l = loop_read(fd, seed, seed_size, true);
1368 if (l < 0 || (size_t) l != seed_size) {
1369 log_error_errno(EIO, "Failed to read random seed: %m");
1370 r = -EIO;
1371 goto finish;
1372 }
1373
1374 log_info("Generating key pair...");
1375 FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1376
1377 log_info("Generating sealing key...");
1378 FSPRG_GenState0(state, mpk, seed, seed_size);
1379
1380 assert(arg_interval > 0);
1381
1382 n = now(CLOCK_REALTIME);
1383 n /= arg_interval;
1384
1385 safe_close(fd);
1386 fd = mkostemp_safe(k, O_WRONLY|O_CLOEXEC);
1387 if (fd < 0) {
1388 log_error_errno(errno, "Failed to open %s: %m", k);
1389 r = -errno;
1390 goto finish;
1391 }
1392
1393 /* Enable secure remove, exclusion from dump, synchronous
1394 * writing and in-place updating */
1395 if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
1396 log_warning_errno(errno, "FS_IOC_GETFLAGS failed: %m");
1397
1398 attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
1399
1400 if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
1401 log_warning_errno(errno, "FS_IOC_SETFLAGS failed: %m");
1402
1403 zero(h);
1404 memcpy(h.signature, "KSHHRHLP", 8);
1405 h.machine_id = machine;
1406 h.boot_id = boot;
1407 h.header_size = htole64(sizeof(h));
1408 h.start_usec = htole64(n * arg_interval);
1409 h.interval_usec = htole64(arg_interval);
1410 h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1411 h.fsprg_state_size = htole64(state_size);
1412
1413 l = loop_write(fd, &h, sizeof(h), false);
1414 if (l < 0 || (size_t) l != sizeof(h)) {
1415 log_error_errno(EIO, "Failed to write header: %m");
1416 r = -EIO;
1417 goto finish;
1418 }
1419
1420 l = loop_write(fd, state, state_size, false);
1421 if (l < 0 || (size_t) l != state_size) {
1422 log_error_errno(EIO, "Failed to write state: %m");
1423 r = -EIO;
1424 goto finish;
1425 }
1426
1427 if (link(k, p) < 0) {
1428 log_error_errno(errno, "Failed to link file: %m");
1429 r = -errno;
1430 goto finish;
1431 }
1432
1433 if (on_tty()) {
1434 fprintf(stderr,
1435 "\n"
1436 "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
1437 "the following local file. This key file is automatically updated when the\n"
1438 "sealing key is advanced. It should not be used on multiple hosts.\n"
1439 "\n"
1440 "\t%s\n"
1441 "\n"
1442 "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
1443 "at a safe location and should not be saved locally on disk.\n"
1444 "\n\t" ANSI_HIGHLIGHT_RED_ON, p);
1445 fflush(stderr);
1446 }
1447 for (i = 0; i < seed_size; i++) {
1448 if (i > 0 && i % 3 == 0)
1449 putchar('-');
1450 printf("%02x", ((uint8_t*) seed)[i]);
1451 }
1452
1453 printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1454
1455 if (on_tty()) {
1456 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1457
1458 fprintf(stderr,
1459 ANSI_HIGHLIGHT_OFF "\n"
1460 "The sealing key is automatically changed every %s.\n",
1461 format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1462
1463 hn = gethostname_malloc();
1464
1465 if (hn) {
1466 hostname_cleanup(hn, false);
1467 fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1468 } else
1469 fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1470
1471 #ifdef HAVE_QRENCODE
1472 /* If this is not an UTF-8 system don't print any QR codes */
1473 if (is_locale_utf8()) {
1474 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1475 print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1476 }
1477 #endif
1478 free(hn);
1479 }
1480
1481 r = 0;
1482
1483 finish:
1484 safe_close(fd);
1485
1486 if (k) {
1487 unlink(k);
1488 free(k);
1489 }
1490
1491 free(p);
1492
1493 return r;
1494 #else
1495 log_error("Forward-secure sealing not available.");
1496 return -ENOTSUP;
1497 #endif
1498 }
1499
1500 static int verify(sd_journal *j) {
1501 int r = 0;
1502 Iterator i;
1503 JournalFile *f;
1504
1505 assert(j);
1506
1507 log_show_color(true);
1508
1509 ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1510 int k;
1511 usec_t first, validated, last;
1512
1513 #ifdef HAVE_GCRYPT
1514 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1515 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1516 #endif
1517
1518 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1519 if (k == -EINVAL) {
1520 /* If the key was invalid give up right-away. */
1521 return k;
1522 } else if (k < 0) {
1523 log_warning("FAIL: %s (%s)", f->path, strerror(-k));
1524 r = k;
1525 } else {
1526 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1527 log_info("PASS: %s", f->path);
1528
1529 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1530 if (validated > 0) {
1531 log_info("=> Validated from %s to %s, final %s entries not sealed.",
1532 format_timestamp_maybe_utc(a, sizeof(a), first),
1533 format_timestamp_maybe_utc(b, sizeof(b), validated),
1534 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1535 } else if (last > 0)
1536 log_info("=> No sealing yet, %s of entries not sealed.",
1537 format_timespan(c, sizeof(c), last - first, 0));
1538 else
1539 log_info("=> No sealing yet, no entries in file.");
1540 }
1541 }
1542 }
1543
1544 return r;
1545 }
1546
1547 #ifdef HAVE_ACL
1548 static int access_check_var_log_journal(sd_journal *j) {
1549 _cleanup_strv_free_ char **g = NULL;
1550 bool have_access;
1551 int r;
1552
1553 assert(j);
1554
1555 have_access = in_group("systemd-journal") > 0;
1556
1557 if (!have_access) {
1558 /* Let's enumerate all groups from the default ACL of
1559 * the directory, which generally should allow access
1560 * to most journal files too */
1561 r = search_acl_groups(&g, "/var/log/journal/", &have_access);
1562 if (r < 0)
1563 return r;
1564 }
1565
1566 if (!have_access) {
1567
1568 if (strv_isempty(g))
1569 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1570 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1571 " turn off this notice.");
1572 else {
1573 _cleanup_free_ char *s = NULL;
1574
1575 r = strv_extend(&g, "systemd-journal");
1576 if (r < 0)
1577 return log_oom();
1578
1579 strv_sort(g);
1580 strv_uniq(g);
1581
1582 s = strv_join(g, "', '");
1583 if (!s)
1584 return log_oom();
1585
1586 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1587 " Users in the groups '%s' can see all messages.\n"
1588 " Pass -q to turn off this notice.", s);
1589 }
1590 }
1591
1592 return 0;
1593 }
1594 #endif
1595
1596 static int access_check(sd_journal *j) {
1597 Iterator it;
1598 void *code;
1599 int r = 0;
1600
1601 assert(j);
1602
1603 if (set_isempty(j->errors)) {
1604 if (ordered_hashmap_isempty(j->files))
1605 log_notice("No journal files were found.");
1606 return 0;
1607 }
1608
1609 if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
1610 #ifdef HAVE_ACL
1611 /* If /var/log/journal doesn't even exist,
1612 * unprivileged users have no access at all */
1613 if (access("/var/log/journal", F_OK) < 0 &&
1614 geteuid() != 0 &&
1615 in_group("systemd-journal") <= 0) {
1616 log_error("Unprivileged users cannot access messages, unless persistent log storage is\n"
1617 "enabled. Users in the 'systemd-journal' group may always access messages.");
1618 return -EACCES;
1619 }
1620
1621 /* If /var/log/journal exists, try to pring a nice
1622 notice if the user lacks access to it */
1623 if (!arg_quiet && geteuid() != 0) {
1624 r = access_check_var_log_journal(j);
1625 if (r < 0)
1626 return r;
1627 }
1628 #else
1629 if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
1630 log_error("Unprivileged users cannot access messages. Users in the 'systemd-journal' group\n"
1631 "group may access messages.");
1632 return -EACCES;
1633 }
1634 #endif
1635
1636 if (ordered_hashmap_isempty(j->files)) {
1637 log_error("No journal files were opened due to insufficient permissions.");
1638 r = -EACCES;
1639 }
1640 }
1641
1642 SET_FOREACH(code, j->errors, it) {
1643 int err;
1644
1645 err = -PTR_TO_INT(code);
1646 assert(err > 0);
1647
1648 if (err != EACCES)
1649 log_warning_errno(err, "Error was encountered while opening journal files: %m");
1650 }
1651
1652 return r;
1653 }
1654
1655 static int flush_to_var(void) {
1656 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1657 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
1658 _cleanup_close_ int watch_fd = -1;
1659 int r;
1660
1661 /* Quick exit */
1662 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1663 return 0;
1664
1665 /* OK, let's actually do the full logic, send SIGUSR1 to the
1666 * daemon and set up inotify to wait for the flushed file to appear */
1667 r = bus_open_system_systemd(&bus);
1668 if (r < 0)
1669 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1670
1671 r = sd_bus_call_method(
1672 bus,
1673 "org.freedesktop.systemd1",
1674 "/org/freedesktop/systemd1",
1675 "org.freedesktop.systemd1.Manager",
1676 "KillUnit",
1677 &error,
1678 NULL,
1679 "ssi", "systemd-journald.service", "main", SIGUSR1);
1680 if (r < 0) {
1681 log_error("Failed to kill journal service: %s", bus_error_message(&error, r));
1682 return r;
1683 }
1684
1685 mkdir_p("/run/systemd/journal", 0755);
1686
1687 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1688 if (watch_fd < 0) {
1689 log_error_errno(errno, "Failed to create inotify watch: %m");
1690 return -errno;
1691 }
1692
1693 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1694 if (r < 0) {
1695 log_error_errno(errno, "Failed to watch journal directory: %m");
1696 return -errno;
1697 }
1698
1699 for (;;) {
1700 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1701 break;
1702
1703 if (errno != ENOENT) {
1704 log_error_errno(errno, "Failed to check for existance of /run/systemd/journal/flushed: %m");
1705 return -errno;
1706 }
1707
1708 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1709 if (r < 0)
1710 return log_error_errno(r, "Failed to wait for event: %m");
1711
1712 r = flush_fd(watch_fd);
1713 if (r < 0)
1714 return log_error_errno(r, "Failed to flush inotify events: %m");
1715 }
1716
1717 return 0;
1718 }
1719
1720 int main(int argc, char *argv[]) {
1721 int r;
1722 _cleanup_journal_close_ sd_journal *j = NULL;
1723 bool need_seek = false;
1724 sd_id128_t previous_boot_id;
1725 bool previous_boot_id_valid = false, first_line = true;
1726 int n_shown = 0;
1727 bool ellipsized = false;
1728
1729 setlocale(LC_ALL, "");
1730 log_parse_environment();
1731 log_open();
1732
1733 r = parse_argv(argc, argv);
1734 if (r <= 0)
1735 goto finish;
1736
1737 signal(SIGWINCH, columns_lines_cache_reset);
1738
1739 if (arg_action == ACTION_NEW_ID128) {
1740 r = generate_new_id128();
1741 goto finish;
1742 }
1743
1744 if (arg_action == ACTION_FLUSH) {
1745 r = flush_to_var();
1746 goto finish;
1747 }
1748
1749 if (arg_action == ACTION_SETUP_KEYS) {
1750 r = setup_keys();
1751 goto finish;
1752 }
1753
1754 if (arg_action == ACTION_UPDATE_CATALOG ||
1755 arg_action == ACTION_LIST_CATALOG ||
1756 arg_action == ACTION_DUMP_CATALOG) {
1757
1758 _cleanup_free_ char *database;
1759
1760 database = path_join(arg_root, CATALOG_DATABASE, NULL);
1761 if (!database) {
1762 r = log_oom();
1763 goto finish;
1764 }
1765
1766 if (arg_action == ACTION_UPDATE_CATALOG) {
1767 r = catalog_update(database, arg_root, catalog_file_dirs);
1768 if (r < 0)
1769 log_error_errno(r, "Failed to list catalog: %m");
1770 } else {
1771 bool oneline = arg_action == ACTION_LIST_CATALOG;
1772
1773 if (optind < argc)
1774 r = catalog_list_items(stdout, database,
1775 oneline, argv + optind);
1776 else
1777 r = catalog_list(stdout, database, oneline);
1778 if (r < 0)
1779 log_error_errno(r, "Failed to list catalog: %m");
1780 }
1781
1782 goto finish;
1783 }
1784
1785 if (arg_directory)
1786 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
1787 else if (arg_file)
1788 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
1789 else if (arg_machine)
1790 r = sd_journal_open_container(&j, arg_machine, 0);
1791 else
1792 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
1793 if (r < 0) {
1794 log_error_errno(r, "Failed to open %s: %m",
1795 arg_directory ? arg_directory : arg_file ? "files" : "journal");
1796 return EXIT_FAILURE;
1797 }
1798
1799 r = access_check(j);
1800 if (r < 0)
1801 return EXIT_FAILURE;
1802
1803 if (arg_action == ACTION_VERIFY) {
1804 r = verify(j);
1805 goto finish;
1806 }
1807
1808 if (arg_action == ACTION_PRINT_HEADER) {
1809 journal_print_header(j);
1810 return EXIT_SUCCESS;
1811 }
1812
1813 if (arg_action == ACTION_DISK_USAGE) {
1814 uint64_t bytes = 0;
1815 char sbytes[FORMAT_BYTES_MAX];
1816
1817 r = sd_journal_get_usage(j, &bytes);
1818 if (r < 0)
1819 return EXIT_FAILURE;
1820
1821 printf("Archived and active journals take up %s on disk.\n",
1822 format_bytes(sbytes, sizeof(sbytes), bytes));
1823 return EXIT_SUCCESS;
1824 }
1825
1826 if (arg_action == ACTION_VACUUM) {
1827 Directory *d;
1828 Iterator i;
1829
1830 HASHMAP_FOREACH(d, j->directories_by_path, i) {
1831 int q;
1832
1833 if (d->is_root)
1834 continue;
1835
1836 q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_time, NULL, true);
1837 if (q < 0) {
1838 log_error_errno(q, "Failed to vacuum: %m");
1839 r = q;
1840 }
1841 }
1842
1843 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1844 }
1845
1846 if (arg_action == ACTION_LIST_BOOTS) {
1847 r = list_boots(j);
1848 goto finish;
1849 }
1850
1851 /* add_boot() must be called first!
1852 * It may need to seek the journal to find parent boot IDs. */
1853 r = add_boot(j);
1854 if (r < 0)
1855 return EXIT_FAILURE;
1856
1857 r = add_dmesg(j);
1858 if (r < 0)
1859 return EXIT_FAILURE;
1860
1861 r = add_units(j);
1862 strv_free(arg_system_units);
1863 strv_free(arg_user_units);
1864
1865 if (r < 0) {
1866 log_error_errno(r, "Failed to add filter for units: %m");
1867 return EXIT_FAILURE;
1868 }
1869
1870 r = add_syslog_identifier(j);
1871 if (r < 0) {
1872 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
1873 return EXIT_FAILURE;
1874 }
1875
1876 r = add_priorities(j);
1877 if (r < 0) {
1878 log_error_errno(r, "Failed to add filter for priorities: %m");
1879 return EXIT_FAILURE;
1880 }
1881
1882 r = add_matches(j, argv + optind);
1883 if (r < 0) {
1884 log_error_errno(r, "Failed to add filters: %m");
1885 return EXIT_FAILURE;
1886 }
1887
1888 if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1889 _cleanup_free_ char *filter;
1890
1891 filter = journal_make_match_string(j);
1892 log_debug("Journal filter: %s", filter);
1893 }
1894
1895 if (arg_field) {
1896 const void *data;
1897 size_t size;
1898
1899 r = sd_journal_set_data_threshold(j, 0);
1900 if (r < 0) {
1901 log_error("Failed to unset data size threshold");
1902 return EXIT_FAILURE;
1903 }
1904
1905 r = sd_journal_query_unique(j, arg_field);
1906 if (r < 0) {
1907 log_error_errno(r, "Failed to query unique data objects: %m");
1908 return EXIT_FAILURE;
1909 }
1910
1911 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1912 const void *eq;
1913
1914 if (arg_lines >= 0 && n_shown >= arg_lines)
1915 break;
1916
1917 eq = memchr(data, '=', size);
1918 if (eq)
1919 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
1920 else
1921 printf("%.*s\n", (int) size, (const char*) data);
1922
1923 n_shown ++;
1924 }
1925
1926 return EXIT_SUCCESS;
1927 }
1928
1929 /* Opening the fd now means the first sd_journal_wait() will actually wait */
1930 if (arg_follow) {
1931 r = sd_journal_get_fd(j);
1932 if (r < 0)
1933 return EXIT_FAILURE;
1934 }
1935
1936 if (arg_cursor || arg_after_cursor) {
1937 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
1938 if (r < 0) {
1939 log_error_errno(r, "Failed to seek to cursor: %m");
1940 return EXIT_FAILURE;
1941 }
1942 if (!arg_reverse)
1943 r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
1944 else
1945 r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
1946
1947 if (arg_after_cursor && r < 2 && !arg_follow)
1948 /* We couldn't find the next entry after the cursor. */
1949 arg_lines = 0;
1950
1951 } else if (arg_since_set && !arg_reverse) {
1952 r = sd_journal_seek_realtime_usec(j, arg_since);
1953 if (r < 0) {
1954 log_error_errno(r, "Failed to seek to date: %m");
1955 return EXIT_FAILURE;
1956 }
1957 r = sd_journal_next(j);
1958
1959 } else if (arg_until_set && arg_reverse) {
1960 r = sd_journal_seek_realtime_usec(j, arg_until);
1961 if (r < 0) {
1962 log_error_errno(r, "Failed to seek to date: %m");
1963 return EXIT_FAILURE;
1964 }
1965 r = sd_journal_previous(j);
1966
1967 } else if (arg_lines >= 0) {
1968 r = sd_journal_seek_tail(j);
1969 if (r < 0) {
1970 log_error_errno(r, "Failed to seek to tail: %m");
1971 return EXIT_FAILURE;
1972 }
1973
1974 r = sd_journal_previous_skip(j, arg_lines);
1975
1976 } else if (arg_reverse) {
1977 r = sd_journal_seek_tail(j);
1978 if (r < 0) {
1979 log_error_errno(r, "Failed to seek to tail: %m");
1980 return EXIT_FAILURE;
1981 }
1982
1983 r = sd_journal_previous(j);
1984
1985 } else {
1986 r = sd_journal_seek_head(j);
1987 if (r < 0) {
1988 log_error_errno(r, "Failed to seek to head: %m");
1989 return EXIT_FAILURE;
1990 }
1991
1992 r = sd_journal_next(j);
1993 }
1994
1995 if (r < 0) {
1996 log_error_errno(r, "Failed to iterate through journal: %m");
1997 return EXIT_FAILURE;
1998 }
1999
2000 if (!arg_follow)
2001 pager_open_if_enabled();
2002
2003 if (!arg_quiet) {
2004 usec_t start, end;
2005 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
2006
2007 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2008 if (r < 0) {
2009 log_error_errno(r, "Failed to get cutoff: %m");
2010 goto finish;
2011 }
2012
2013 if (r > 0) {
2014 if (arg_follow)
2015 printf("-- Logs begin at %s. --\n",
2016 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2017 else
2018 printf("-- Logs begin at %s, end at %s. --\n",
2019 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2020 format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2021 }
2022 }
2023
2024 for (;;) {
2025 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2026 int flags;
2027
2028 if (need_seek) {
2029 if (!arg_reverse)
2030 r = sd_journal_next(j);
2031 else
2032 r = sd_journal_previous(j);
2033 if (r < 0) {
2034 log_error_errno(r, "Failed to iterate through journal: %m");
2035 goto finish;
2036 }
2037 if (r == 0)
2038 break;
2039 }
2040
2041 if (arg_until_set && !arg_reverse) {
2042 usec_t usec;
2043
2044 r = sd_journal_get_realtime_usec(j, &usec);
2045 if (r < 0) {
2046 log_error_errno(r, "Failed to determine timestamp: %m");
2047 goto finish;
2048 }
2049 if (usec > arg_until)
2050 goto finish;
2051 }
2052
2053 if (arg_since_set && arg_reverse) {
2054 usec_t usec;
2055
2056 r = sd_journal_get_realtime_usec(j, &usec);
2057 if (r < 0) {
2058 log_error_errno(r, "Failed to determine timestamp: %m");
2059 goto finish;
2060 }
2061 if (usec < arg_since)
2062 goto finish;
2063 }
2064
2065 if (!arg_merge && !arg_quiet) {
2066 sd_id128_t boot_id;
2067
2068 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2069 if (r >= 0) {
2070 if (previous_boot_id_valid &&
2071 !sd_id128_equal(boot_id, previous_boot_id))
2072 printf("%s-- Reboot --%s\n",
2073 ansi_highlight(), ansi_highlight_off());
2074
2075 previous_boot_id = boot_id;
2076 previous_boot_id_valid = true;
2077 }
2078 }
2079
2080 flags =
2081 arg_all * OUTPUT_SHOW_ALL |
2082 arg_full * OUTPUT_FULL_WIDTH |
2083 on_tty() * OUTPUT_COLOR |
2084 arg_catalog * OUTPUT_CATALOG |
2085 arg_utc * OUTPUT_UTC;
2086
2087 r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
2088 need_seek = true;
2089 if (r == -EADDRNOTAVAIL)
2090 break;
2091 else if (r < 0 || ferror(stdout))
2092 goto finish;
2093
2094 n_shown++;
2095 }
2096
2097 if (!arg_follow) {
2098 if (arg_show_cursor) {
2099 _cleanup_free_ char *cursor = NULL;
2100
2101 r = sd_journal_get_cursor(j, &cursor);
2102 if (r < 0 && r != -EADDRNOTAVAIL)
2103 log_error_errno(r, "Failed to get cursor: %m");
2104 else if (r >= 0)
2105 printf("-- cursor: %s\n", cursor);
2106 }
2107
2108 break;
2109 }
2110
2111 r = sd_journal_wait(j, (uint64_t) -1);
2112 if (r < 0) {
2113 log_error_errno(r, "Couldn't wait for journal event: %m");
2114 goto finish;
2115 }
2116
2117 first_line = false;
2118 }
2119
2120 finish:
2121 pager_close();
2122
2123 strv_free(arg_file);
2124
2125 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2126 }