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 fprintf(f, " SequenceNumber=%llu", (unsigned long long) m->seqnum);
106 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
109 bus_creds_dump(&m->creds, f);
112 r = sd_bus_message_rewind(m, true);
114 log_error("Failed to rewind: %s", strerror(-r));
118 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
121 _cleanup_free_ char *prefix = NULL;
122 const char *contents = NULL;
137 r = sd_bus_message_peek_type(m, &type, &contents);
139 log_error("Failed to peek type: %s", strerror(-r));
147 r = sd_bus_message_exit_container(m);
149 log_error("Failed to exit container: %s", strerror(-r));
155 prefix = indent(level);
159 fprintf(f, "%s};\n", prefix);
163 prefix = indent(level);
167 if (bus_type_is_container(type) > 0) {
168 r = sd_bus_message_enter_container(m, type, contents);
170 log_error("Failed to enter container: %s", strerror(-r));
174 if (type == SD_BUS_TYPE_ARRAY)
175 fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
176 else if (type == SD_BUS_TYPE_VARIANT)
177 fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
178 else if (type == SD_BUS_TYPE_STRUCT)
179 fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
180 else if (type == SD_BUS_TYPE_DICT_ENTRY)
181 fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
188 r = sd_bus_message_read_basic(m, type, &basic);
190 log_error("Failed to get basic: %s", strerror(-r));
198 case SD_BUS_TYPE_BYTE:
199 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
202 case SD_BUS_TYPE_BOOLEAN:
203 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off());
206 case SD_BUS_TYPE_INT16:
207 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
210 case SD_BUS_TYPE_UINT16:
211 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
214 case SD_BUS_TYPE_INT32:
215 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
218 case SD_BUS_TYPE_UINT32:
219 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
222 case SD_BUS_TYPE_INT64:
223 fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off());
226 case SD_BUS_TYPE_UINT64:
227 fprintf(f, "%sUINT64 %s%llu%s;\n", prefix, ansi_highlight(), (unsigned long long) basic.u64, ansi_highlight_off());
230 case SD_BUS_TYPE_DOUBLE:
231 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
234 case SD_BUS_TYPE_STRING:
235 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
238 case SD_BUS_TYPE_OBJECT_PATH:
239 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
242 case SD_BUS_TYPE_SIGNATURE:
243 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
246 case SD_BUS_TYPE_UNIX_FD:
247 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
251 assert_not_reached("Unknown basic type.");
255 fprintf(f, " };\n\n");
259 static void dump_capabilities(
263 int (*has)(sd_bus_creds *c, int capability)) {
265 unsigned long i, last_cap;
279 fprintf(f, " %s=", name);
280 last_cap = cap_last_cap();
284 _cleanup_cap_free_charp_ char *t;
307 int bus_creds_dump(sd_bus_creds *c, FILE *f) {
308 bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
309 const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
310 uid_t owner, audit_loginuid;
311 uint32_t audit_sessionid;
312 char **cmdline = NULL, **well_known = NULL;
320 if (c->mask & SD_BUS_CREDS_PID)
321 fprintf(f, " PID=%lu", (unsigned long) c->pid);
322 if (c->mask & SD_BUS_CREDS_PID_STARTTIME)
323 fprintf(f, " PIDStartTime=%llu", (unsigned long long) c->pid_starttime);
324 if (c->mask & SD_BUS_CREDS_TID)
325 fprintf(f, " TID=%lu", (unsigned long) c->tid);
326 if (c->mask & SD_BUS_CREDS_UID)
327 fprintf(f, " UID=%lu", (unsigned long) c->uid);
328 r = sd_bus_creds_get_owner_uid(c, &owner);
330 fprintf(f, " OwnerUID=%lu", (unsigned long) owner);
331 if (c->mask & SD_BUS_CREDS_GID)
332 fprintf(f, " GID=%lu", (unsigned long) c->gid);
334 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)
337 if (c->mask & SD_BUS_CREDS_EXE)
338 fprintf(f, " Exe=%s", c->exe);
339 if (c->mask & SD_BUS_CREDS_COMM)
340 fprintf(f, " Comm=%s", c->comm);
341 if (c->mask & SD_BUS_CREDS_TID_COMM)
342 fprintf(f, " TIDComm=%s", c->tid_comm);
344 if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
347 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
348 fprintf(f, " Label=%s", c->label);
349 if (c->mask & SD_BUS_CREDS_CONNECTION_NAME)
350 fprintf(f, " ConnectionName=%s", c->conn_name);
352 if (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_CONNECTION_NAME))
355 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
358 fputs(" CommandLine={", f);
359 STRV_FOREACH(i, cmdline) {
369 if (c->mask & SD_BUS_CREDS_CGROUP)
370 fprintf(f, " CGroup=%s", c->cgroup);
371 sd_bus_creds_get_unit(c, &u);
373 fprintf(f, " Unit=%s", u);
374 sd_bus_creds_get_user_unit(c, &uu);
376 fprintf(f, " UserUnit=%s", uu);
377 sd_bus_creds_get_slice(c, &sl);
379 fprintf(f, " Slice=%s", sl);
380 sd_bus_creds_get_session(c, &s);
382 fprintf(f, " Session=%s", s);
384 if ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s)
387 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
388 audit_loginuid_is_set = true;
389 fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid);
391 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
392 audit_sessionid_is_set = true;
393 fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid);
396 if (audit_loginuid_is_set || audit_sessionid_is_set)
399 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
400 fprintf(f, " UniqueName=%s", c->unique_name);
402 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
405 fputs(" WellKnownNames={", f);
406 STRV_FOREACH(i, well_known) {
416 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known)
419 dump_capabilities(c, f, "EffectiveCapabilities", sd_bus_creds_has_effective_cap);
420 dump_capabilities(c, f, "PermittedCapabilities", sd_bus_creds_has_permitted_cap);
421 dump_capabilities(c, f, "InheritableCapabilities", sd_bus_creds_has_inheritable_cap);
422 dump_capabilities(c, f, "BoundingCapabilities", sd_bus_creds_has_bounding_cap);