1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
23 #include "capability.h"
27 #include "bus-message.h"
28 #include "bus-internal.h"
32 static char *indent(unsigned level) {
35 p = new(char, 2 + level + 1);
40 memset(p + 2, '\t', level);
46 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
57 "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%lli",
58 m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
59 m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
60 m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(),
61 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
65 (long long) m->priority);
67 /* Display synthetic message serial number in a more readable
68 * format than (uint32_t) -1 */
69 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
70 fprintf(f, " Cookie=-1");
72 fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
74 if (m->reply_cookie != 0)
75 fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
80 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
82 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
84 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
86 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
88 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
90 if (m->sender || m->destination || m->path || m->interface || m->member)
93 if (sd_bus_error_is_set(&m->error))
96 " ErrorMessage=%s\"%s\"%s\n",
97 ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(),
98 ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
100 if (m->monotonic != 0)
101 fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
102 if (m->realtime != 0)
103 fprintf(f, " Realtime="USEC_FMT, m->realtime);
105 fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
107 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
110 bus_creds_dump(&m->creds, f);
113 r = sd_bus_message_rewind(m, true);
115 log_error("Failed to rewind: %s", strerror(-r));
119 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
122 _cleanup_free_ char *prefix = NULL;
123 const char *contents = NULL;
138 r = sd_bus_message_peek_type(m, &type, &contents);
140 log_error("Failed to peek type: %s", strerror(-r));
148 r = sd_bus_message_exit_container(m);
150 log_error("Failed to exit container: %s", strerror(-r));
156 prefix = indent(level);
160 fprintf(f, "%s};\n", prefix);
164 prefix = indent(level);
168 if (bus_type_is_container(type) > 0) {
169 r = sd_bus_message_enter_container(m, type, contents);
171 log_error("Failed to enter container: %s", strerror(-r));
175 if (type == SD_BUS_TYPE_ARRAY)
176 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
177 else if (type == SD_BUS_TYPE_VARIANT)
178 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
179 else if (type == SD_BUS_TYPE_STRUCT)
180 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
181 else if (type == SD_BUS_TYPE_DICT_ENTRY)
182 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
189 r = sd_bus_message_read_basic(m, type, &basic);
191 log_error("Failed to get basic: %s", strerror(-r));
199 case SD_BUS_TYPE_BYTE:
200 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
203 case SD_BUS_TYPE_BOOLEAN:
204 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off());
207 case SD_BUS_TYPE_INT16:
208 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
211 case SD_BUS_TYPE_UINT16:
212 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
215 case SD_BUS_TYPE_INT32:
216 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
219 case SD_BUS_TYPE_UINT32:
220 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
223 case SD_BUS_TYPE_INT64:
224 fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off());
227 case SD_BUS_TYPE_UINT64:
228 fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off());
231 case SD_BUS_TYPE_DOUBLE:
232 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
235 case SD_BUS_TYPE_STRING:
236 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
239 case SD_BUS_TYPE_OBJECT_PATH:
240 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
243 case SD_BUS_TYPE_SIGNATURE:
244 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
247 case SD_BUS_TYPE_UNIX_FD:
248 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
252 assert_not_reached("Unknown basic type.");
256 fprintf(f, " };\n\n");
260 static void dump_capabilities(
264 int (*has)(sd_bus_creds *c, int capability)) {
266 unsigned long i, last_cap;
280 fprintf(f, " %s=", name);
281 last_cap = cap_last_cap();
285 _cleanup_cap_free_charp_ char *t;
308 int bus_creds_dump(sd_bus_creds *c, FILE *f) {
309 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
310 const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
311 uid_t owner, audit_loginuid;
312 uint32_t audit_sessionid;
313 char **cmdline = NULL, **well_known = NULL;
321 if (c->mask & SD_BUS_CREDS_PID)
322 fprintf(f, " PID="PID_FMT, c->pid);
323 if (c->mask & SD_BUS_CREDS_PID_STARTTIME)
324 fprintf(f, " PIDStartTime="USEC_FMT, c->pid_starttime);
325 if (c->mask & SD_BUS_CREDS_TID)
326 fprintf(f, " TID="PID_FMT, c->tid);
327 if (c->mask & SD_BUS_CREDS_UID)
328 fprintf(f, " UID="UID_FMT, c->uid);
329 r = sd_bus_creds_get_owner_uid(c, &owner);
331 fprintf(f, " OwnerUID="UID_FMT, owner);
332 if (c->mask & SD_BUS_CREDS_GID)
333 fprintf(f, " GID="GID_FMT, c->gid);
335 if ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID)) || r >= 0)
338 if (c->mask & SD_BUS_CREDS_EXE)
339 fprintf(f, " Exe=%s", c->exe);
340 if (c->mask & SD_BUS_CREDS_COMM)
341 fprintf(f, " Comm=%s", c->comm);
342 if (c->mask & SD_BUS_CREDS_TID_COMM)
343 fprintf(f, " TIDComm=%s", c->tid_comm);
345 if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
348 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
349 fprintf(f, " Label=%s", c->label);
350 if (c->mask & SD_BUS_CREDS_CONNECTION_NAME)
351 fprintf(f, " ConnectionName=%s", c->conn_name);
353 if (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_CONNECTION_NAME))
356 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
359 fputs(" CommandLine={", f);
360 STRV_FOREACH(i, cmdline) {
370 if (c->mask & SD_BUS_CREDS_CGROUP)
371 fprintf(f, " CGroup=%s", c->cgroup);
372 sd_bus_creds_get_unit(c, &u);
374 fprintf(f, " Unit=%s", u);
375 sd_bus_creds_get_user_unit(c, &uu);
377 fprintf(f, " UserUnit=%s", uu);
378 sd_bus_creds_get_slice(c, &sl);
380 fprintf(f, " Slice=%s", sl);
381 sd_bus_creds_get_session(c, &s);
383 fprintf(f, " Session=%s", s);
385 if ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s)
388 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
389 audit_loginuid_is_set = true;
390 fprintf(f, " AuditLoginUID="UID_FMT, audit_loginuid);
392 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
393 audit_sessionid_is_set = true;
394 fprintf(f, " AuditSessionID=%"PRIu32, audit_sessionid);
397 if (audit_loginuid_is_set || audit_sessionid_is_set)
400 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
401 fprintf(f, " UniqueName=%s", c->unique_name);
403 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
406 fputs(" WellKnownNames={", f);
407 STRV_FOREACH(i, well_known) {
417 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known)
420 dump_capabilities(c, f, "EffectiveCapabilities", sd_bus_creds_has_effective_cap);
421 dump_capabilities(c, f, "PermittedCapabilities", sd_bus_creds_has_permitted_cap);
422 dump_capabilities(c, f, "InheritableCapabilities", sd_bus_creds_has_inheritable_cap);
423 dump_capabilities(c, f, "BoundingCapabilities", sd_bus_creds_has_bounding_cap);