]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/bus-dump.c
bus: update kdbus.h
[thirdparty/systemd.git] / src / libsystemd-bus / bus-dump.c
CommitLineData
3db0e46b
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 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 <sys/capability.h>
23
24#include "util.h"
25#include "capability.h"
26#include "strv.h"
5b12334d 27#include "audit.h"
3db0e46b
LP
28
29#include "bus-message.h"
30#include "bus-internal.h"
31#include "bus-type.h"
32#include "bus-dump.h"
33
f8cfb5f5
LP
34static char *indent(unsigned level) {
35 char *p;
36
37 p = new(char, 2 + level + 1);
38 if (!p)
39 return NULL;
40
41 p[0] = p[1] = ' ';
42 memset(p + 2, '\t', level);
43 p[2 + level] = 0;
44
45 return p;
46}
47
3db0e46b 48int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
3db0e46b
LP
49 unsigned level = 1;
50 int r;
3db0e46b
LP
51
52 assert(m);
53
54 if (!f)
55 f = stdout;
56
57 if (with_header) {
58 fprintf(f,
f8cfb5f5
LP
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(),
3db0e46b 63 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
f8cfb5f5 64 m->header->endian,
3db0e46b
LP
65 m->header->flags,
66 m->header->version,
67 BUS_MESSAGE_SERIAL(m));
68
69 if (m->reply_serial != 0)
70 fprintf(f, " ReplySerial=%u", m->reply_serial);
71
72 fputs("\n", f);
73
74 if (m->sender)
75 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
76 if (m->destination)
77 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
78 if (m->path)
79 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
80 if (m->interface)
81 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
82 if (m->member)
83 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
84
85 if (m->sender || m->destination || m->path || m->interface || m->member)
86 fputs("\n", f);
87
88 if (sd_bus_error_is_set(&m->error))
89 fprintf(f,
90 " ErrorName=%s%s%s"
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());
94
3db0e46b
LP
95 if (m->monotonic != 0)
96 fprintf(f, " Monotonic=%llu", (unsigned long long) m->monotonic);
97 if (m->realtime != 0)
98 fprintf(f, " Realtime=%llu", (unsigned long long) m->realtime);
99
100 if (m->monotonic != 0 || m->realtime != 0)
101 fputs("\n", f);
102
5b12334d 103 bus_creds_dump(&m->creds, f);
3db0e46b
LP
104 }
105
106 r = sd_bus_message_rewind(m, true);
107 if (r < 0) {
108 log_error("Failed to rewind: %s", strerror(-r));
109 return r;
110 }
111
f8cfb5f5 112 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3db0e46b
LP
113
114 for(;;) {
115 _cleanup_free_ char *prefix = NULL;
116 const char *contents = NULL;
117 char type;
118 union {
119 uint8_t u8;
120 uint16_t u16;
121 int16_t s16;
122 uint32_t u32;
123 int32_t s32;
124 uint64_t u64;
125 int64_t s64;
126 double d64;
127 const char *string;
128 int i;
129 } basic;
130
131 r = sd_bus_message_peek_type(m, &type, &contents);
132 if (r < 0) {
133 log_error("Failed to peek type: %s", strerror(-r));
134 return r;
135 }
136
137 if (r == 0) {
138 if (level <= 1)
139 break;
140
141 r = sd_bus_message_exit_container(m);
142 if (r < 0) {
143 log_error("Failed to exit container: %s", strerror(-r));
144 return r;
145 }
146
147 level--;
148
f8cfb5f5 149 prefix = indent(level);
3db0e46b
LP
150 if (!prefix)
151 return log_oom();
152
153 fprintf(f, "%s};\n", prefix);
154 continue;
155 }
156
f8cfb5f5 157 prefix = indent(level);
3db0e46b
LP
158 if (!prefix)
159 return log_oom();
160
161 if (bus_type_is_container(type) > 0) {
162 r = sd_bus_message_enter_container(m, type, contents);
163 if (r < 0) {
164 log_error("Failed to enter container: %s", strerror(-r));
165 return r;
166 }
167
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);
176
177 level ++;
178
179 continue;
180 }
181
182 r = sd_bus_message_read_basic(m, type, &basic);
183 if (r < 0) {
184 log_error("Failed to get basic: %s", strerror(-r));
185 return r;
186 }
187
188 assert(r > 0);
189
190 switch (type) {
191
192 case SD_BUS_TYPE_BYTE:
193 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
194 break;
195
196 case SD_BUS_TYPE_BOOLEAN:
197 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), yes_no(basic.i), ansi_highlight_off());
198 break;
199
200 case SD_BUS_TYPE_INT16:
201 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
202 break;
203
204 case SD_BUS_TYPE_UINT16:
205 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
206 break;
207
208 case SD_BUS_TYPE_INT32:
209 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
210 break;
211
212 case SD_BUS_TYPE_UINT32:
213 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
214 break;
215
216 case SD_BUS_TYPE_INT64:
217 fprintf(f, "%sINT64 %s%lli%s;\n", prefix, ansi_highlight(), (long long) basic.s64, ansi_highlight_off());
218 break;
219
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());
222 break;
223
224 case SD_BUS_TYPE_DOUBLE:
225 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
226 break;
227
228 case SD_BUS_TYPE_STRING:
229 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
230 break;
231
232 case SD_BUS_TYPE_OBJECT_PATH:
233 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
234 break;
235
236 case SD_BUS_TYPE_SIGNATURE:
237 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
238 break;
239
240 case SD_BUS_TYPE_UNIX_FD:
241 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
242 break;
243
244 default:
245 assert_not_reached("Unknown basic type.");
246 }
247 }
248
f8cfb5f5 249 fprintf(f, " };\n\n");
3db0e46b
LP
250 return 0;
251}
5b12334d
LP
252
253static void dump_capabilities(
254 sd_bus_creds *c,
255 FILE *f,
256 const char *name,
257 int (*has)(sd_bus_creds *c, int capability)) {
258
259 unsigned long i, last_cap;
260 unsigned n = 0;
261 int r;
262
263 assert(c);
264 assert(f);
265 assert(name);
266 assert(has);
267
268 i = 0;
269 r = has(c, i);
270 if (r < 0)
271 return;
272
273 fprintf(f, " %s=", name);
274 last_cap = cap_last_cap();
275
276 for (;;) {
277 if (r > 0) {
278 if (n > 0)
279 fputc(' ', f);
280 if (n % 4 == 3)
281 fputs("\n ", f);
282
283 fputs(cap_to_name(i), f);
284 n++;
285 }
286
287 i++;
288
289 if (i > last_cap)
290 break;
291
292 r = has(c, i);
293 }
294
295 fputs("\n", f);
296}
297
298int 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;
304 int r;
305
306 assert(c);
307
308 if (!f)
309 f = stdout;
310
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);
320 if (r >= 0)
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);
324
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)
326 fputs("\n", f);
327
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);
336
337 if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_SELINUX_CONTEXT))
338 fputs("\n", f);
339
340 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
341 char **i;
342
343 fputs(" CommandLine=", f);
344 STRV_FOREACH(i, cmdline) {
345 if (i != cmdline)
346 fputc(' ', f);
347
348 fputs(*i, f);
349 }
350
351 fputs("\n", f);
352 }
353
354 if (c->mask & SD_BUS_CREDS_CGROUP)
355 fprintf(f, " CGroup=%s", c->cgroup);
356 sd_bus_creds_get_unit(c, &u);
357 if (u)
358 fprintf(f, " Unit=%s", u);
359 sd_bus_creds_get_user_unit(c, &uu);
360 if (uu)
361 fprintf(f, " UserUnit=%s", uu);
362 sd_bus_creds_get_slice(c, &sl);
363 if (sl)
364 fprintf(f, " Slice=%s", sl);
365 sd_bus_creds_get_session(c, &s);
366 if (s)
367 fprintf(f, " Session=%s", s);
368
369 if ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s)
370 fputs("\n", f);
371
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);
375 }
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);
379 }
380
381 if (audit_loginuid_is_set || audit_sessionid_is_set)
382 fputs("\n", f);
383
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);
388
389 return 0;
390}