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/>.
22 #include <sys/capability.h>
25 #include "capability.h"
29 #include "bus-message.h"
30 #include "bus-internal.h"
34 static char *indent(unsigned level) {
37 p = new(char, 2 + level + 1);
42 memset(p + 2, '\t', level);
48 int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
59 "%s%s%sType=%s%s%s Endian=%c Flags=%u Version=%u Serial=%u ",
60 m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
61 m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
62 m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_highlight_off(),
63 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
67 BUS_MESSAGE_SERIAL(m));
69 if (m->reply_serial != 0)
70 fprintf(f, " ReplySerial=%u", m->reply_serial);
75 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
77 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
79 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
81 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
83 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
85 if (m->sender || m->destination || m->path || m->interface || m->member)
88 if (sd_bus_error_is_set(&m->error))
91 " ErrorMessage=%s\"%s\"%s\n",
92 ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(),
93 ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
95 if (m->monotonic != 0)
96 fprintf(f, " Monotonic=%llu", (unsigned long long) m->monotonic);
98 fprintf(f, " Realtime=%llu", (unsigned long long) m->realtime);
100 if (m->monotonic != 0 || m->realtime != 0)
103 bus_creds_dump(&m->creds, f);
106 r = sd_bus_message_rewind(m, true);
108 log_error("Failed to rewind: %s", strerror(-r));
112 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
115 _cleanup_free_ char *prefix = NULL;
116 const char *contents = NULL;
131 r = sd_bus_message_peek_type(m, &type, &contents);
133 log_error("Failed to peek type: %s", strerror(-r));
141 r = sd_bus_message_exit_container(m);
143 log_error("Failed to exit container: %s", strerror(-r));
149 prefix = indent(level);
153 fprintf(f, "%s};\n", prefix);
157 prefix = indent(level);
161 if (bus_type_is_container(type) > 0) {
162 r = sd_bus_message_enter_container(m, type, contents);
164 log_error("Failed to enter container: %s", strerror(-r));
168 if (type == SD_BUS_TYPE_ARRAY)
169 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
170 else if (type == SD_BUS_TYPE_VARIANT)
171 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
172 else if (type == SD_BUS_TYPE_STRUCT)
173 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
174 else if (type == SD_BUS_TYPE_DICT_ENTRY)
175 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
182 r = sd_bus_message_read_basic(m, type, &basic);
184 log_error("Failed to get basic: %s", strerror(-r));
192 case SD_BUS_TYPE_BYTE:
193 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
196 case SD_BUS_TYPE_BOOLEAN:
197 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), yes_no(basic.i), ansi_highlight_off());
200 case SD_BUS_TYPE_INT16:
201 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
204 case SD_BUS_TYPE_UINT16:
205 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
208 case SD_BUS_TYPE_INT32:
209 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
212 case SD_BUS_TYPE_UINT32:
213 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
216 case SD_BUS_TYPE_INT64:
217 fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off());
220 case SD_BUS_TYPE_UINT64:
221 fprintf(f, "%sUINT64 %s%llu%s;\n", prefix, ansi_highlight(), (unsigned long long) basic.u64, ansi_highlight_off());
224 case SD_BUS_TYPE_DOUBLE:
225 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
228 case SD_BUS_TYPE_STRING:
229 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
232 case SD_BUS_TYPE_OBJECT_PATH:
233 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
236 case SD_BUS_TYPE_SIGNATURE:
237 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
240 case SD_BUS_TYPE_UNIX_FD:
241 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
245 assert_not_reached("Unknown basic type.");
249 fprintf(f, " };\n\n");
253 static void dump_capabilities(
257 int (*has)(sd_bus_creds *c, int capability)) {
259 unsigned long i, last_cap;
273 fprintf(f, " %s=", name);
274 last_cap = cap_last_cap();
283 fputs(cap_to_name(i), f);
298 int bus_creds_dump(sd_bus_creds *c, FILE *f) {
299 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
300 const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
301 uid_t owner, audit_loginuid;
302 uint32_t audit_sessionid;
303 char **cmdline = NULL;
311 if (c->mask & SD_BUS_CREDS_PID)
312 fprintf(f, " PID=%lu", (unsigned long) c->pid);
313 if (c->mask & SD_BUS_CREDS_PID_STARTTIME)
314 fprintf(f, " PIDStartTime=%llu", (unsigned long long) c->pid_starttime);
315 if (c->mask & SD_BUS_CREDS_TID)
316 fprintf(f, " TID=%lu", (unsigned long) c->tid);
317 if (c->mask & SD_BUS_CREDS_UID)
318 fprintf(f, " UID=%lu", (unsigned long) c->uid);
319 r = sd_bus_creds_get_owner_uid(c, &owner);
321 fprintf(f, " OwnerUID=%lu", (unsigned long) owner);
322 if (c->mask & SD_BUS_CREDS_GID)
323 fprintf(f, " GID=%lu", (unsigned long) c->gid);
325 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)
328 if (c->mask & SD_BUS_CREDS_EXE)
329 fprintf(f, " Exe=%s", c->exe);
330 if (c->mask & SD_BUS_CREDS_COMM)
331 fprintf(f, " Comm=%s", c->comm);
332 if (c->mask & SD_BUS_CREDS_TID_COMM)
333 fprintf(f, " TIDComm=%s", c->tid_comm);
334 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
335 fprintf(f, " Label=%s", c->label);
337 if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_SELINUX_CONTEXT))
340 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
343 fputs(" CommandLine=", f);
344 STRV_FOREACH(i, cmdline) {
354 if (c->mask & SD_BUS_CREDS_CGROUP)
355 fprintf(f, " CGroup=%s", c->cgroup);
356 sd_bus_creds_get_unit(c, &u);
358 fprintf(f, " Unit=%s", u);
359 sd_bus_creds_get_user_unit(c, &uu);
361 fprintf(f, " UserUnit=%s", uu);
362 sd_bus_creds_get_slice(c, &sl);
364 fprintf(f, " Slice=%s", sl);
365 sd_bus_creds_get_session(c, &s);
367 fprintf(f, " Session=%s", s);
369 if ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s)
372 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
373 audit_loginuid_is_set = true;
374 fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid);
376 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
377 audit_sessionid_is_set = true;
378 fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid);
381 if (audit_loginuid_is_set || audit_sessionid_is_set)
384 dump_capabilities(c, f, "EffectiveCapabilities", sd_bus_creds_has_effective_cap);
385 dump_capabilities(c, f, "PermittedCapabilities", sd_bus_creds_has_permitted_cap);
386 dump_capabilities(c, f, "InheritableCapabilities", sd_bus_creds_has_inheritable_cap);
387 dump_capabilities(c, f, "BoundingCapabilities", sd_bus_creds_has_bounding_cap);