]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-bus/bus-dump.c
nspawn: ignore EEXIST when creating mount point
[thirdparty/systemd.git] / src / libsystemd / sd-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
3db0e46b
LP
22#include "util.h"
23#include "capability.h"
24#include "strv.h"
5b12334d 25#include "audit.h"
3db0e46b
LP
26
27#include "bus-message.h"
28#include "bus-internal.h"
29#include "bus-type.h"
30#include "bus-dump.h"
31
f8cfb5f5
LP
32static char *indent(unsigned level) {
33 char *p;
34
35 p = new(char, 2 + level + 1);
36 if (!p)
37 return NULL;
38
39 p[0] = p[1] = ' ';
40 memset(p + 2, '\t', level);
41 p[2 + level] = 0;
42
43 return p;
44}
45
3db0e46b 46int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
3db0e46b
LP
47 unsigned level = 1;
48 int r;
3db0e46b
LP
49
50 assert(m);
51
52 if (!f)
53 f = stdout;
54
55 if (with_header) {
56 fprintf(f,
6b01f1d3 57 "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%lli",
f8cfb5f5
LP
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(),
3db0e46b 61 ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_highlight_off(),
f8cfb5f5 62 m->header->endian,
3db0e46b 63 m->header->flags,
ca7b42c8
LP
64 m->header->version,
65 (long long) m->priority);
a009c158
LS
66
67 /* Display synthetic message serial number in a more readable
68 * format than (uint32_t) -1 */
693eb9a2
LP
69 if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
70 fprintf(f, " Cookie=-1");
a009c158 71 else
42c4ebcb 72 fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
3db0e46b 73
693eb9a2 74 if (m->reply_cookie != 0)
42c4ebcb 75 fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
3db0e46b
LP
76
77 fputs("\n", f);
78
79 if (m->sender)
80 fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_highlight_off());
81 if (m->destination)
82 fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_highlight_off());
83 if (m->path)
84 fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_highlight_off());
85 if (m->interface)
86 fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_highlight_off());
87 if (m->member)
88 fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_highlight_off());
89
90 if (m->sender || m->destination || m->path || m->interface || m->member)
91 fputs("\n", f);
92
93 if (sd_bus_error_is_set(&m->error))
94 fprintf(f,
95 " ErrorName=%s%s%s"
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());
99
3db0e46b 100 if (m->monotonic != 0)
de0671ee 101 fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
3db0e46b 102 if (m->realtime != 0)
de0671ee 103 fprintf(f, " Realtime="USEC_FMT, m->realtime);
6a0e376c 104 if (m->seqnum != 0)
de0671ee 105 fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
3db0e46b 106
6a0e376c 107 if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
3db0e46b
LP
108 fputs("\n", f);
109
5b12334d 110 bus_creds_dump(&m->creds, f);
3db0e46b
LP
111 }
112
113 r = sd_bus_message_rewind(m, true);
114 if (r < 0) {
115 log_error("Failed to rewind: %s", strerror(-r));
116 return r;
117 }
118
f8cfb5f5 119 fprintf(f, " MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
3db0e46b 120
f168c273 121 for (;;) {
3db0e46b
LP
122 _cleanup_free_ char *prefix = NULL;
123 const char *contents = NULL;
124 char type;
125 union {
126 uint8_t u8;
127 uint16_t u16;
128 int16_t s16;
129 uint32_t u32;
130 int32_t s32;
131 uint64_t u64;
132 int64_t s64;
133 double d64;
134 const char *string;
135 int i;
136 } basic;
137
138 r = sd_bus_message_peek_type(m, &type, &contents);
139 if (r < 0) {
140 log_error("Failed to peek type: %s", strerror(-r));
141 return r;
142 }
143
144 if (r == 0) {
145 if (level <= 1)
146 break;
147
148 r = sd_bus_message_exit_container(m);
149 if (r < 0) {
150 log_error("Failed to exit container: %s", strerror(-r));
151 return r;
152 }
153
154 level--;
155
f8cfb5f5 156 prefix = indent(level);
3db0e46b
LP
157 if (!prefix)
158 return log_oom();
159
160 fprintf(f, "%s};\n", prefix);
161 continue;
162 }
163
f8cfb5f5 164 prefix = indent(level);
3db0e46b
LP
165 if (!prefix)
166 return log_oom();
167
168 if (bus_type_is_container(type) > 0) {
169 r = sd_bus_message_enter_container(m, type, contents);
170 if (r < 0) {
171 log_error("Failed to enter container: %s", strerror(-r));
172 return r;
173 }
174
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);
183
184 level ++;
185
186 continue;
187 }
188
189 r = sd_bus_message_read_basic(m, type, &basic);
190 if (r < 0) {
191 log_error("Failed to get basic: %s", strerror(-r));
192 return r;
193 }
194
195 assert(r > 0);
196
197 switch (type) {
198
199 case SD_BUS_TYPE_BYTE:
200 fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_highlight_off());
201 break;
202
203 case SD_BUS_TYPE_BOOLEAN:
5232c42e 204 fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_highlight_off());
3db0e46b
LP
205 break;
206
207 case SD_BUS_TYPE_INT16:
208 fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_highlight_off());
209 break;
210
211 case SD_BUS_TYPE_UINT16:
212 fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_highlight_off());
213 break;
214
215 case SD_BUS_TYPE_INT32:
216 fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_highlight_off());
217 break;
218
219 case SD_BUS_TYPE_UINT32:
220 fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_highlight_off());
221 break;
222
223 case SD_BUS_TYPE_INT64:
de0671ee 224 fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_highlight_off());
3db0e46b
LP
225 break;
226
227 case SD_BUS_TYPE_UINT64:
de0671ee 228 fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_highlight_off());
3db0e46b
LP
229 break;
230
231 case SD_BUS_TYPE_DOUBLE:
232 fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_highlight_off());
233 break;
234
235 case SD_BUS_TYPE_STRING:
236 fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
237 break;
238
239 case SD_BUS_TYPE_OBJECT_PATH:
240 fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
241 break;
242
243 case SD_BUS_TYPE_SIGNATURE:
244 fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_highlight_off());
245 break;
246
247 case SD_BUS_TYPE_UNIX_FD:
248 fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_highlight_off());
249 break;
250
251 default:
252 assert_not_reached("Unknown basic type.");
253 }
254 }
255
f8cfb5f5 256 fprintf(f, " };\n\n");
3db0e46b
LP
257 return 0;
258}
5b12334d
LP
259
260static void dump_capabilities(
261 sd_bus_creds *c,
262 FILE *f,
263 const char *name,
264 int (*has)(sd_bus_creds *c, int capability)) {
265
266 unsigned long i, last_cap;
267 unsigned n = 0;
268 int r;
269
270 assert(c);
271 assert(f);
272 assert(name);
273 assert(has);
274
275 i = 0;
276 r = has(c, i);
277 if (r < 0)
278 return;
279
280 fprintf(f, " %s=", name);
281 last_cap = cap_last_cap();
282
283 for (;;) {
284 if (r > 0) {
5ce70e5b
ZJS
285 _cleanup_cap_free_charp_ char *t;
286
5b12334d
LP
287 if (n > 0)
288 fputc(' ', f);
289 if (n % 4 == 3)
290 fputs("\n ", f);
291
5ce70e5b
ZJS
292 t = cap_to_name(i);
293 fprintf(f, "%s", t);
5b12334d
LP
294 n++;
295 }
296
297 i++;
298
299 if (i > last_cap)
300 break;
301
302 r = has(c, i);
303 }
304
305 fputs("\n", f);
306}
307
308int 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;
49b832c5 313 char **cmdline = NULL, **well_known = NULL;
5b12334d
LP
314 int r;
315
316 assert(c);
317
318 if (!f)
319 f = stdout;
320
321 if (c->mask & SD_BUS_CREDS_PID)
de0671ee 322 fprintf(f, " PID="PID_FMT, c->pid);
5b12334d 323 if (c->mask & SD_BUS_CREDS_PID_STARTTIME)
de0671ee 324 fprintf(f, " PIDStartTime="USEC_FMT, c->pid_starttime);
5b12334d 325 if (c->mask & SD_BUS_CREDS_TID)
de0671ee 326 fprintf(f, " TID="PID_FMT, c->tid);
5b12334d 327 if (c->mask & SD_BUS_CREDS_UID)
de0671ee 328 fprintf(f, " UID="UID_FMT, c->uid);
5b12334d
LP
329 r = sd_bus_creds_get_owner_uid(c, &owner);
330 if (r >= 0)
de0671ee 331 fprintf(f, " OwnerUID="UID_FMT, owner);
5b12334d 332 if (c->mask & SD_BUS_CREDS_GID)
de0671ee 333 fprintf(f, " GID="GID_FMT, c->gid);
5b12334d
LP
334
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)
336 fputs("\n", f);
337
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);
14008e4e
LP
344
345 if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM))
346 fputs("\n", f);
347
5b12334d
LP
348 if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
349 fprintf(f, " Label=%s", c->label);
cccb0b2c
LP
350 if (c->mask & SD_BUS_CREDS_CONNECTION_NAME)
351 fprintf(f, " ConnectionName=%s", c->conn_name);
5b12334d 352
14008e4e 353 if (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_CONNECTION_NAME))
5b12334d
LP
354 fputs("\n", f);
355
356 if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
357 char **i;
358
49b832c5 359 fputs(" CommandLine={", f);
5b12334d
LP
360 STRV_FOREACH(i, cmdline) {
361 if (i != cmdline)
362 fputc(' ', f);
363
364 fputs(*i, f);
365 }
366
49b832c5 367 fputs("}\n", f);
5b12334d
LP
368 }
369
370 if (c->mask & SD_BUS_CREDS_CGROUP)
371 fprintf(f, " CGroup=%s", c->cgroup);
372 sd_bus_creds_get_unit(c, &u);
373 if (u)
374 fprintf(f, " Unit=%s", u);
375 sd_bus_creds_get_user_unit(c, &uu);
376 if (uu)
377 fprintf(f, " UserUnit=%s", uu);
378 sd_bus_creds_get_slice(c, &sl);
379 if (sl)
380 fprintf(f, " Slice=%s", sl);
381 sd_bus_creds_get_session(c, &s);
382 if (s)
383 fprintf(f, " Session=%s", s);
384
385 if ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s)
386 fputs("\n", f);
387
388 if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
389 audit_loginuid_is_set = true;
de0671ee 390 fprintf(f, " AuditLoginUID="UID_FMT, audit_loginuid);
5b12334d
LP
391 }
392 if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
393 audit_sessionid_is_set = true;
de0671ee 394 fprintf(f, " AuditSessionID=%"PRIu32, audit_sessionid);
5b12334d
LP
395 }
396
397 if (audit_loginuid_is_set || audit_sessionid_is_set)
398 fputs("\n", f);
399
49b832c5
LP
400 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
401 fprintf(f, " UniqueName=%s", c->unique_name);
402
403 if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
404 char **i;
405
406 fputs(" WellKnownNames={", f);
407 STRV_FOREACH(i, well_known) {
408 if (i != well_known)
409 fputc(' ', f);
410
411 fputs(*i, f);
412 }
413
3310dfd5 414 fputc('}', f);
49b832c5
LP
415 }
416
3310dfd5
LP
417 if (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known)
418 fputc('\n', f);
419
5b12334d
LP
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);
424
425 return 0;
426}