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%sType=%s%s%s Endian=%c Flags=%u Version=%u",
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(),
66 /* Display synthetic message serial number in a more readable
67 * format than (uint32_t) -1 */
68 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
69 fprintf(f, " Cookie=-1");
71 fprintf(f, " Cookie=%lu", (unsigned long) BUS_MESSAGE_COOKIE(m));
73 if (m->reply_cookie != 0)
74 fprintf(f, " ReplyCookie=%lu", (unsigned long) m->reply_cookie);
79 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
81 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
83 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
85 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
87 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
89 if (m->sender || m->destination || m->path || m->interface || m->member)
92 if (sd_bus_error_is_set(&m->error))
95 " ErrorMessage=%s\"%s\"%s\n",
96 ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(),
97 ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
99 if (m->monotonic != 0)
100 fprintf(f, " Monotonic=%llu", (unsigned long long) m->monotonic);
101 if (m->realtime != 0)
102 fprintf(f, " Realtime=%llu", (unsigned long long) m->realtime);
104 if (m->monotonic != 0 || m->realtime != 0)
107 bus_creds_dump(&m->creds, f);
110 r = sd_bus_message_rewind(m, true);
112 log_error("Failed to rewind: %s", strerror(-r));
116 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
119 _cleanup_free_ char *prefix = NULL;
120 const char *contents = NULL;
135 r = sd_bus_message_peek_type(m, &type, &contents);
137 log_error("Failed to peek type: %s", strerror(-r));
145 r = sd_bus_message_exit_container(m);
147 log_error("Failed to exit container: %s", strerror(-r));
153 prefix = indent(level);
157 fprintf(f, "%s};\n", prefix);
161 prefix = indent(level);
165 if (bus_type_is_container(type) > 0) {
166 r = sd_bus_message_enter_container(m, type, contents);
168 log_error("Failed to enter container: %s", strerror(-r));
172 if (type == SD_BUS_TYPE_ARRAY)
173 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
174 else if (type == SD_BUS_TYPE_VARIANT)
175 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
176 else if (type == SD_BUS_TYPE_STRUCT)
177 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
178 else if (type == SD_BUS_TYPE_DICT_ENTRY)
179 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
186 r = sd_bus_message_read_basic(m, type, &basic);
188 log_error("Failed to get basic: %s", strerror(-r));
196 case SD_BUS_TYPE_BYTE:
197 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
200 case SD_BUS_TYPE_BOOLEAN:
201 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off());
204 case SD_BUS_TYPE_INT16:
205 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
208 case SD_BUS_TYPE_UINT16:
209 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
212 case SD_BUS_TYPE_INT32:
213 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
216 case SD_BUS_TYPE_UINT32:
217 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
220 case SD_BUS_TYPE_INT64:
221 fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off());
224 case SD_BUS_TYPE_UINT64:
225 fprintf(f, "%sUINT64 %s%llu%s;\n", prefix, ansi_highlight(), (unsigned long long) basic.u64, ansi_highlight_off());
228 case SD_BUS_TYPE_DOUBLE:
229 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
232 case SD_BUS_TYPE_STRING:
233 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
236 case SD_BUS_TYPE_OBJECT_PATH:
237 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
240 case SD_BUS_TYPE_SIGNATURE:
241 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
244 case SD_BUS_TYPE_UNIX_FD:
245 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
249 assert_not_reached("Unknown basic type.");
253 fprintf(f, " };\n\n");
257 static void dump_capabilities(
261 int (*has)(sd_bus_creds *c, int capability)) {
263 unsigned long i, last_cap;
277 fprintf(f, " %s=", name);
278 last_cap = cap_last_cap();
282 _cleanup_cap_free_charp_ char *t;
305 int bus_creds_dump(sd_bus_creds *c, FILE *f) {
306 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
307 const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
308 uid_t owner, audit_loginuid;
309 uint32_t audit_sessionid;
310 char **cmdline = NULL, **well_known = NULL;
318 if (c->mask & SD_BUS_CREDS_PID)
319 fprintf(f, " PID=%lu", (unsigned long) c->pid);
320 if (c->mask & SD_BUS_CREDS_PID_STARTTIME)
321 fprintf(f, " PIDStartTime=%llu", (unsigned long long) c->pid_starttime);
322 if (c->mask & SD_BUS_CREDS_TID)
323 fprintf(f, " TID=%lu", (unsigned long) c->tid);
324 if (c->mask & SD_BUS_CREDS_UID)
325 fprintf(f, " UID=%lu", (unsigned long) c->uid);
326 r = sd_bus_creds_get_owner_uid(c, &owner);
328 fprintf(f, " OwnerUID=%lu", (unsigned long) owner);
329 if (c->mask & SD_BUS_CREDS_GID)
330 fprintf(f, " GID=%lu", (unsigned long) c->gid);
332 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)
335 if (c->mask & SD_BUS_CREDS_EXE)
336 fprintf(f, " Exe=%s", c->exe);
337 if (c->mask & SD_BUS_CREDS_COMM)
338 fprintf(f, " Comm=%s", c->comm);
339 if (c->mask & SD_BUS_CREDS_TID_COMM)
340 fprintf(f, " TIDComm=%s", c->tid_comm);
341 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
342 fprintf(f, " Label=%s", c->label);
344 if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_SELINUX_CONTEXT))
347 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
350 fputs(" CommandLine={", f);
351 STRV_FOREACH(i, cmdline) {
361 if (c->mask & SD_BUS_CREDS_CGROUP)
362 fprintf(f, " CGroup=%s", c->cgroup);
363 sd_bus_creds_get_unit(c, &u);
365 fprintf(f, " Unit=%s", u);
366 sd_bus_creds_get_user_unit(c, &uu);
368 fprintf(f, " UserUnit=%s", uu);
369 sd_bus_creds_get_slice(c, &sl);
371 fprintf(f, " Slice=%s", sl);
372 sd_bus_creds_get_session(c, &s);
374 fprintf(f, " Session=%s", s);
376 if ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s)
379 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
380 audit_loginuid_is_set = true;
381 fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid);
383 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
384 audit_sessionid_is_set = true;
385 fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid);
388 if (audit_loginuid_is_set || audit_sessionid_is_set)
391 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
392 fprintf(f, " UniqueName=%s", c->unique_name);
394 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
397 fputs(" WellKnownNames={", f);
398 STRV_FOREACH(i, well_known) {
408 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known)
411 dump_capabilities(c, f, "EffectiveCapabilities", sd_bus_creds_has_effective_cap);
412 dump_capabilities(c, f, "PermittedCapabilities", sd_bus_creds_has_permitted_cap);
413 dump_capabilities(c, f, "InheritableCapabilities", sd_bus_creds_has_inheritable_cap);
414 dump_capabilities(c, f, "BoundingCapabilities", sd_bus_creds_has_bounding_cap);