2013-11-12 12:11:24 +01:00
|
|
|
/***
|
|
|
|
This file is part of systemd.
|
|
|
|
|
|
|
|
Copyright 2013 Lennart Poettering
|
|
|
|
|
|
|
|
systemd is free software; you can redistribute it and/or modify it
|
|
|
|
under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
systemd is distributed in the hope that it will be useful, but
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
|
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
***/
|
|
|
|
|
2015-10-27 03:01:06 +01:00
|
|
|
#include "alloc-util.h"
|
2015-10-26 18:05:03 +01:00
|
|
|
#include "bus-dump.h"
|
2015-10-24 22:58:24 +02:00
|
|
|
#include "bus-internal.h"
|
|
|
|
#include "bus-message.h"
|
|
|
|
#include "bus-type.h"
|
2014-12-10 03:16:14 +01:00
|
|
|
#include "cap-list.h"
|
2015-10-26 23:32:16 +01:00
|
|
|
#include "capability-util.h"
|
2015-10-26 18:05:03 +01:00
|
|
|
#include "fileio.h"
|
2015-04-10 20:43:52 +02:00
|
|
|
#include "formats-util.h"
|
2015-10-26 23:01:30 +01:00
|
|
|
#include "locale-util.h"
|
2015-10-24 22:58:24 +02:00
|
|
|
#include "macro.h"
|
|
|
|
#include "string-util.h"
|
|
|
|
#include "strv.h"
|
2015-04-10 23:15:59 +02:00
|
|
|
#include "terminal-util.h"
|
2015-10-24 22:58:24 +02:00
|
|
|
#include "util.h"
|
2013-11-12 12:11:24 +01:00
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
static char *indent(unsigned level, unsigned flags) {
|
2013-11-19 21:35:31 +01:00
|
|
|
char *p;
|
2014-11-14 17:20:04 +01:00
|
|
|
unsigned n, i = 0;
|
2013-11-19 21:35:31 +01:00
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
n = 0;
|
|
|
|
|
|
|
|
if (flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY && level > 0)
|
|
|
|
level -= 1;
|
|
|
|
|
|
|
|
if (flags & BUS_MESSAGE_DUMP_WITH_HEADER)
|
|
|
|
n += 2;
|
|
|
|
|
|
|
|
p = new(char, n + level*8 + 1);
|
2013-11-19 21:35:31 +01:00
|
|
|
if (!p)
|
|
|
|
return NULL;
|
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
|
|
|
|
p[i++] = ' ';
|
|
|
|
p[i++] = ' ';
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(p + i, ' ', level*8);
|
|
|
|
p[i + level*8] = 0;
|
2013-11-19 21:35:31 +01:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
int bus_message_dump(sd_bus_message *m, FILE *f, unsigned flags) {
|
2013-11-12 12:11:24 +01:00
|
|
|
unsigned level = 1;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
|
|
|
|
if (!f)
|
|
|
|
f = stdout;
|
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
if (flags & BUS_MESSAGE_DUMP_WITH_HEADER) {
|
2013-11-12 12:11:24 +01:00
|
|
|
fprintf(f,
|
2015-01-21 04:22:15 +01:00
|
|
|
"%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64,
|
2013-11-19 21:35:31 +01:00
|
|
|
m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() :
|
|
|
|
m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() :
|
2015-09-19 00:45:05 +02:00
|
|
|
m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", draw_special_char(DRAW_TRIANGULAR_BULLET), ansi_normal(),
|
|
|
|
ansi_highlight(), bus_message_type_to_string(m->header->type), ansi_normal(),
|
2013-11-19 21:35:31 +01:00
|
|
|
m->header->endian,
|
2013-11-12 12:11:24 +01:00
|
|
|
m->header->flags,
|
2014-01-22 20:01:23 +01:00
|
|
|
m->header->version,
|
2015-01-21 04:22:15 +01:00
|
|
|
m->priority);
|
2013-12-02 16:31:46 +01:00
|
|
|
|
|
|
|
/* Display synthetic message serial number in a more readable
|
|
|
|
* format than (uint32_t) -1 */
|
2013-12-25 17:46:45 +01:00
|
|
|
if (BUS_MESSAGE_COOKIE(m) == 0xFFFFFFFFULL)
|
|
|
|
fprintf(f, " Cookie=-1");
|
2013-12-02 16:31:46 +01:00
|
|
|
else
|
2014-03-13 20:33:22 +01:00
|
|
|
fprintf(f, " Cookie=%" PRIu64, BUS_MESSAGE_COOKIE(m));
|
2013-11-12 12:11:24 +01:00
|
|
|
|
2013-12-25 17:46:45 +01:00
|
|
|
if (m->reply_cookie != 0)
|
2014-03-13 20:33:22 +01:00
|
|
|
fprintf(f, " ReplyCookie=%" PRIu64, m->reply_cookie);
|
2013-11-12 12:11:24 +01:00
|
|
|
|
|
|
|
fputs("\n", f);
|
|
|
|
|
|
|
|
if (m->sender)
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, " Sender=%s%s%s", ansi_highlight(), m->sender, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
if (m->destination)
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, " Destination=%s%s%s", ansi_highlight(), m->destination, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
if (m->path)
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, " Path=%s%s%s", ansi_highlight(), m->path, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
if (m->interface)
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, " Interface=%s%s%s", ansi_highlight(), m->interface, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
if (m->member)
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, " Member=%s%s%s", ansi_highlight(), m->member, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
|
|
|
|
if (m->sender || m->destination || m->path || m->interface || m->member)
|
|
|
|
fputs("\n", f);
|
|
|
|
|
|
|
|
if (sd_bus_error_is_set(&m->error))
|
|
|
|
fprintf(f,
|
|
|
|
" ErrorName=%s%s%s"
|
|
|
|
" ErrorMessage=%s\"%s\"%s\n",
|
2015-09-19 00:45:05 +02:00
|
|
|
ansi_highlight_red(), strna(m->error.name), ansi_normal(),
|
|
|
|
ansi_highlight_red(), strna(m->error.message), ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
|
|
|
|
if (m->monotonic != 0)
|
2014-04-25 13:45:15 +02:00
|
|
|
fprintf(f, " Monotonic="USEC_FMT, m->monotonic);
|
2013-11-12 12:11:24 +01:00
|
|
|
if (m->realtime != 0)
|
2014-04-25 13:45:15 +02:00
|
|
|
fprintf(f, " Realtime="USEC_FMT, m->realtime);
|
2014-01-22 10:57:12 +01:00
|
|
|
if (m->seqnum != 0)
|
2014-04-25 13:45:15 +02:00
|
|
|
fprintf(f, " SequenceNumber=%"PRIu64, m->seqnum);
|
2013-11-12 12:11:24 +01:00
|
|
|
|
2014-01-22 10:57:12 +01:00
|
|
|
if (m->monotonic != 0 || m->realtime != 0 || m->seqnum != 0)
|
2013-11-12 12:11:24 +01:00
|
|
|
fputs("\n", f);
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
bus_creds_dump(&m->creds, f, true);
|
2013-11-12 12:11:24 +01:00
|
|
|
}
|
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
r = sd_bus_message_rewind(m, !(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY));
|
2014-11-28 18:23:20 +01:00
|
|
|
if (r < 0)
|
|
|
|
return log_error_errno(r, "Failed to rewind: %m");
|
2013-11-12 12:11:24 +01:00
|
|
|
|
2015-01-26 20:03:25 +01:00
|
|
|
if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
|
|
|
|
_cleanup_free_ char *prefix = NULL;
|
|
|
|
|
|
|
|
prefix = indent(0, flags);
|
|
|
|
if (!prefix)
|
|
|
|
return log_oom();
|
|
|
|
|
|
|
|
fprintf(f, "%sMESSAGE \"%s\" {\n", prefix, strempty(m->root_container.signature));
|
|
|
|
}
|
2013-11-12 12:11:24 +01:00
|
|
|
|
2013-12-03 22:27:45 +01:00
|
|
|
for (;;) {
|
2013-11-12 12:11:24 +01:00
|
|
|
_cleanup_free_ char *prefix = NULL;
|
|
|
|
const char *contents = NULL;
|
|
|
|
char type;
|
|
|
|
union {
|
|
|
|
uint8_t u8;
|
|
|
|
uint16_t u16;
|
|
|
|
int16_t s16;
|
|
|
|
uint32_t u32;
|
|
|
|
int32_t s32;
|
|
|
|
uint64_t u64;
|
|
|
|
int64_t s64;
|
|
|
|
double d64;
|
|
|
|
const char *string;
|
|
|
|
int i;
|
|
|
|
} basic;
|
|
|
|
|
|
|
|
r = sd_bus_message_peek_type(m, &type, &contents);
|
2014-11-28 18:23:20 +01:00
|
|
|
if (r < 0)
|
|
|
|
return log_error_errno(r, "Failed to peek type: %m");
|
2013-11-12 12:11:24 +01:00
|
|
|
|
|
|
|
if (r == 0) {
|
|
|
|
if (level <= 1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
r = sd_bus_message_exit_container(m);
|
2014-11-28 18:23:20 +01:00
|
|
|
if (r < 0)
|
|
|
|
return log_error_errno(r, "Failed to exit container: %m");
|
2013-11-12 12:11:24 +01:00
|
|
|
|
|
|
|
level--;
|
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
prefix = indent(level, flags);
|
2013-11-12 12:11:24 +01:00
|
|
|
if (!prefix)
|
|
|
|
return log_oom();
|
|
|
|
|
|
|
|
fprintf(f, "%s};\n", prefix);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-11-14 17:20:04 +01:00
|
|
|
prefix = indent(level, flags);
|
2013-11-12 12:11:24 +01:00
|
|
|
if (!prefix)
|
|
|
|
return log_oom();
|
|
|
|
|
|
|
|
if (bus_type_is_container(type) > 0) {
|
|
|
|
r = sd_bus_message_enter_container(m, type, contents);
|
2014-11-28 18:23:20 +01:00
|
|
|
if (r < 0)
|
|
|
|
return log_error_errno(r, "Failed to enter container: %m");
|
2013-11-12 12:11:24 +01:00
|
|
|
|
|
|
|
if (type == SD_BUS_TYPE_ARRAY)
|
|
|
|
fprintf(f, "%sARRAY \"%s\" {\n", prefix, contents);
|
|
|
|
else if (type == SD_BUS_TYPE_VARIANT)
|
|
|
|
fprintf(f, "%sVARIANT \"%s\" {\n", prefix, contents);
|
|
|
|
else if (type == SD_BUS_TYPE_STRUCT)
|
|
|
|
fprintf(f, "%sSTRUCT \"%s\" {\n", prefix, contents);
|
|
|
|
else if (type == SD_BUS_TYPE_DICT_ENTRY)
|
|
|
|
fprintf(f, "%sDICT_ENTRY \"%s\" {\n", prefix, contents);
|
|
|
|
|
|
|
|
level ++;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_bus_message_read_basic(m, type, &basic);
|
2014-11-28 18:23:20 +01:00
|
|
|
if (r < 0)
|
|
|
|
return log_error_errno(r, "Failed to get basic: %m");
|
2013-11-12 12:11:24 +01:00
|
|
|
|
|
|
|
assert(r > 0);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_BYTE:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sBYTE %s%u%s;\n", prefix, ansi_highlight(), basic.u8, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_BOOLEAN:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sBOOLEAN %s%s%s;\n", prefix, ansi_highlight(), true_false(basic.i), ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_INT16:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sINT16 %s%i%s;\n", prefix, ansi_highlight(), basic.s16, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_UINT16:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sUINT16 %s%u%s;\n", prefix, ansi_highlight(), basic.u16, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_INT32:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sINT32 %s%i%s;\n", prefix, ansi_highlight(), basic.s32, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_UINT32:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sUINT32 %s%u%s;\n", prefix, ansi_highlight(), basic.u32, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_INT64:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sINT64 %s%"PRIi64"%s;\n", prefix, ansi_highlight(), basic.s64, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_UINT64:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sUINT64 %s%"PRIu64"%s;\n", prefix, ansi_highlight(), basic.u64, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_DOUBLE:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sDOUBLE %s%g%s;\n", prefix, ansi_highlight(), basic.d64, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_STRING:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sSTRING \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_OBJECT_PATH:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sOBJECT_PATH \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_SIGNATURE:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sSIGNATURE \"%s%s%s\";\n", prefix, ansi_highlight(), basic.string, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SD_BUS_TYPE_UNIX_FD:
|
2015-09-19 00:45:05 +02:00
|
|
|
fprintf(f, "%sUNIX_FD %s%i%s;\n", prefix, ansi_highlight(), basic.i, ansi_normal());
|
2013-11-12 12:11:24 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
assert_not_reached("Unknown basic type.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-26 20:03:25 +01:00
|
|
|
if (!(flags & BUS_MESSAGE_DUMP_SUBTREE_ONLY)) {
|
|
|
|
_cleanup_free_ char *prefix = NULL;
|
|
|
|
|
|
|
|
prefix = indent(0, flags);
|
|
|
|
if (!prefix)
|
|
|
|
return log_oom();
|
|
|
|
|
|
|
|
fprintf(f, "%s};\n\n", prefix);
|
|
|
|
}
|
2014-11-14 17:20:04 +01:00
|
|
|
|
2013-11-12 12:11:24 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2013-11-28 17:50:02 +01:00
|
|
|
|
|
|
|
static void dump_capabilities(
|
|
|
|
sd_bus_creds *c,
|
|
|
|
FILE *f,
|
|
|
|
const char *name,
|
2014-11-19 23:59:26 +01:00
|
|
|
bool terse,
|
2013-11-28 17:50:02 +01:00
|
|
|
int (*has)(sd_bus_creds *c, int capability)) {
|
|
|
|
|
|
|
|
unsigned long i, last_cap;
|
|
|
|
unsigned n = 0;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
assert(c);
|
|
|
|
assert(f);
|
|
|
|
assert(name);
|
|
|
|
assert(has);
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
r = has(c, i);
|
|
|
|
if (r < 0)
|
|
|
|
return;
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%s%s=%s", terse ? " " : "", name, terse ? "" : ansi_highlight());
|
2013-11-28 17:50:02 +01:00
|
|
|
last_cap = cap_last_cap();
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
if (r > 0) {
|
2014-01-01 04:35:54 +01:00
|
|
|
|
2013-11-28 17:50:02 +01:00
|
|
|
if (n > 0)
|
|
|
|
fputc(' ', f);
|
|
|
|
if (n % 4 == 3)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, terse ? "\n " : "\n ");
|
2013-11-28 17:50:02 +01:00
|
|
|
|
2014-12-10 03:16:14 +01:00
|
|
|
fprintf(f, "%s", strna(capability_to_name(i)));
|
2013-11-28 17:50:02 +01:00
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
if (i > last_cap)
|
|
|
|
break;
|
|
|
|
|
|
|
|
r = has(c, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
fputs("\n", f);
|
2014-11-19 23:59:26 +01:00
|
|
|
|
|
|
|
if (!terse)
|
2015-09-19 00:45:05 +02:00
|
|
|
fputs(ansi_normal(), f);
|
2013-11-28 17:50:02 +01:00
|
|
|
}
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
|
2013-11-28 17:50:02 +01:00
|
|
|
uid_t owner, audit_loginuid;
|
|
|
|
uint32_t audit_sessionid;
|
2013-11-30 04:14:10 +01:00
|
|
|
char **cmdline = NULL, **well_known = NULL;
|
2015-04-29 21:40:54 +02:00
|
|
|
const char *prefix, *color, *suffix, *s;
|
2015-04-30 11:58:06 +02:00
|
|
|
int r, q, v, w, z;
|
2013-11-28 17:50:02 +01:00
|
|
|
|
|
|
|
assert(c);
|
|
|
|
|
|
|
|
if (!f)
|
|
|
|
f = stdout;
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
if (terse) {
|
|
|
|
prefix = " ";
|
|
|
|
suffix = "";
|
|
|
|
color = "";
|
|
|
|
} else {
|
|
|
|
const char *off;
|
|
|
|
|
|
|
|
prefix = "";
|
|
|
|
color = ansi_highlight();
|
|
|
|
|
2015-09-19 00:45:05 +02:00
|
|
|
off = ansi_normal();
|
2015-02-03 02:05:59 +01:00
|
|
|
suffix = strjoina(off, "\n");
|
2014-11-19 23:59:26 +01:00
|
|
|
}
|
|
|
|
|
2013-11-28 17:50:02 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_PID)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sPID=%s"PID_FMT"%s", prefix, color, c->pid, suffix);
|
2013-11-28 17:50:02 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_TID)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sTID=%s"PID_FMT"%s", prefix, color, c->tid, suffix);
|
2015-04-29 21:40:54 +02:00
|
|
|
if (c->mask & SD_BUS_CREDS_PPID) {
|
|
|
|
if (c->ppid == 0)
|
|
|
|
fprintf(f, "%sPPID=%sn/a%s", prefix, color, suffix);
|
|
|
|
else
|
|
|
|
fprintf(f, "%sPPID=%s"PID_FMT"%s", prefix, color, c->ppid, suffix);
|
|
|
|
}
|
2015-04-23 19:43:40 +02:00
|
|
|
if (c->mask & SD_BUS_CREDS_TTY)
|
|
|
|
fprintf(f, "%sTTY=%s%s%s", prefix, color, strna(c->tty), suffix);
|
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
Also:
- adds support for euid, suid, fsuid, egid, sgid, fsgid fields.
- makes augmentation of creds with data from /proc explicitly
controllable to give apps better control over this, given that this is
racy.
- enables augmentation for kdbus connections (previously we only did it
for dbus1). This is useful since with recent kdbus versions it is
possible for clients to control the metadata they want to send.
- changes sd_bus_query_sender_privilege() to take the euid of the client
into consideration, if known
- when we don't have permissions to read augmentation data from /proc,
don't fail, just don't add the data in
2014-11-24 21:41:40 +01:00
|
|
|
|
2015-04-23 19:43:40 +02:00
|
|
|
if (terse && ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_PPID|SD_BUS_CREDS_TTY))))
|
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
Also:
- adds support for euid, suid, fsuid, egid, sgid, fsgid fields.
- makes augmentation of creds with data from /proc explicitly
controllable to give apps better control over this, given that this is
racy.
- enables augmentation for kdbus connections (previously we only did it
for dbus1). This is useful since with recent kdbus versions it is
possible for clients to control the metadata they want to send.
- changes sd_bus_query_sender_privilege() to take the euid of the client
into consideration, if known
- when we don't have permissions to read augmentation data from /proc,
don't fail, just don't add the data in
2014-11-24 21:41:40 +01:00
|
|
|
fputs("\n", f);
|
|
|
|
|
2013-11-28 17:50:02 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_UID)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sUID=%s"UID_FMT"%s", prefix, color, c->uid, suffix);
|
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
Also:
- adds support for euid, suid, fsuid, egid, sgid, fsgid fields.
- makes augmentation of creds with data from /proc explicitly
controllable to give apps better control over this, given that this is
racy.
- enables augmentation for kdbus connections (previously we only did it
for dbus1). This is useful since with recent kdbus versions it is
possible for clients to control the metadata they want to send.
- changes sd_bus_query_sender_privilege() to take the euid of the client
into consideration, if known
- when we don't have permissions to read augmentation data from /proc,
don't fail, just don't add the data in
2014-11-24 21:41:40 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_EUID)
|
|
|
|
fprintf(f, "%sEUID=%s"UID_FMT"%s", prefix, color, c->euid, suffix);
|
|
|
|
if (c->mask & SD_BUS_CREDS_SUID)
|
|
|
|
fprintf(f, "%sSUID=%s"UID_FMT"%s", prefix, color, c->suid, suffix);
|
|
|
|
if (c->mask & SD_BUS_CREDS_FSUID)
|
|
|
|
fprintf(f, "%sFSUID=%s"UID_FMT"%s", prefix, color, c->fsuid, suffix);
|
2013-11-28 17:50:02 +01:00
|
|
|
r = sd_bus_creds_get_owner_uid(c, &owner);
|
|
|
|
if (r >= 0)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sOwnerUID=%s"UID_FMT"%s", prefix, color, owner, suffix);
|
2013-11-28 17:50:02 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_GID)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sGID=%s"GID_FMT"%s", prefix, color, c->gid, suffix);
|
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
Also:
- adds support for euid, suid, fsuid, egid, sgid, fsgid fields.
- makes augmentation of creds with data from /proc explicitly
controllable to give apps better control over this, given that this is
racy.
- enables augmentation for kdbus connections (previously we only did it
for dbus1). This is useful since with recent kdbus versions it is
possible for clients to control the metadata they want to send.
- changes sd_bus_query_sender_privilege() to take the euid of the client
into consideration, if known
- when we don't have permissions to read augmentation data from /proc,
don't fail, just don't add the data in
2014-11-24 21:41:40 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_EGID)
|
|
|
|
fprintf(f, "%sEGID=%s"GID_FMT"%s", prefix, color, c->egid, suffix);
|
|
|
|
if (c->mask & SD_BUS_CREDS_SGID)
|
|
|
|
fprintf(f, "%sSGID=%s"GID_FMT"%s", prefix, color, c->sgid, suffix);
|
|
|
|
if (c->mask & SD_BUS_CREDS_FSGID)
|
|
|
|
fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
|
|
|
|
|
2014-11-25 13:21:23 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
|
|
|
|
for (i = 0; i < c->n_supplementary_gids; i++)
|
|
|
|
fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
|
|
|
|
fprintf(f, "%s", suffix);
|
|
|
|
}
|
|
|
|
|
sd-bus: update to current kernel version, by splitting off the extended KDBUS_ITEM_PIDS structure from KDBUS_ITEM_CREDS
Also:
- adds support for euid, suid, fsuid, egid, sgid, fsgid fields.
- makes augmentation of creds with data from /proc explicitly
controllable to give apps better control over this, given that this is
racy.
- enables augmentation for kdbus connections (previously we only did it
for dbus1). This is useful since with recent kdbus versions it is
possible for clients to control the metadata they want to send.
- changes sd_bus_query_sender_privilege() to take the euid of the client
into consideration, if known
- when we don't have permissions to read augmentation data from /proc,
don't fail, just don't add the data in
2014-11-24 21:41:40 +01:00
|
|
|
if (terse && ((c->mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
|
2014-11-25 13:21:23 +01:00
|
|
|
SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
|
|
|
|
SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
|
2013-11-28 17:50:02 +01:00
|
|
|
fputs("\n", f);
|
|
|
|
|
|
|
|
if (c->mask & SD_BUS_CREDS_COMM)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sComm=%s%s%s", prefix, color, c->comm, suffix);
|
2013-11-28 17:50:02 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_TID_COMM)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sTIDComm=%s%s%s", prefix, color, c->tid_comm, suffix);
|
2014-11-24 21:37:26 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_EXE)
|
2015-04-29 21:40:54 +02:00
|
|
|
fprintf(f, "%sExe=%s%s%s", prefix, color, strna(c->exe), suffix);
|
2014-01-22 18:43:03 +01:00
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
if (terse && (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)))
|
2014-01-22 18:43:03 +01:00
|
|
|
fputs("\n", f);
|
|
|
|
|
2015-04-29 21:40:54 +02:00
|
|
|
r = sd_bus_creds_get_cmdline(c, &cmdline);
|
|
|
|
if (r >= 0) {
|
2013-11-28 17:50:02 +01:00
|
|
|
char **i;
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sCommandLine=%s", prefix, color);
|
2013-11-28 17:50:02 +01:00
|
|
|
STRV_FOREACH(i, cmdline) {
|
|
|
|
if (i != cmdline)
|
|
|
|
fputc(' ', f);
|
|
|
|
|
|
|
|
fputs(*i, f);
|
|
|
|
}
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%s", suffix);
|
2015-04-29 21:40:54 +02:00
|
|
|
} else if (r != -ENODATA)
|
|
|
|
fprintf(f, "%sCommandLine=%sn/a%s", prefix, color, suffix);
|
2013-11-28 17:50:02 +01:00
|
|
|
|
2014-11-24 21:37:26 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
|
|
|
|
fprintf(f, "%sLabel=%s%s%s", prefix, color, c->label, suffix);
|
|
|
|
if (c->mask & SD_BUS_CREDS_DESCRIPTION)
|
|
|
|
fprintf(f, "%sDescription=%s%s%s", prefix, color, c->description, suffix);
|
|
|
|
|
|
|
|
if (terse && (c->mask & (SD_BUS_CREDS_SELINUX_CONTEXT|SD_BUS_CREDS_DESCRIPTION)))
|
|
|
|
fputs("\n", f);
|
|
|
|
|
2013-11-28 17:50:02 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_CGROUP)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sCGroup=%s%s%s", prefix, color, c->cgroup, suffix);
|
2015-04-29 21:40:54 +02:00
|
|
|
s = NULL;
|
|
|
|
r = sd_bus_creds_get_unit(c, &s);
|
|
|
|
if (r != -ENODATA)
|
|
|
|
fprintf(f, "%sUnit=%s%s%s", prefix, color, strna(s), suffix);
|
|
|
|
s = NULL;
|
|
|
|
v = sd_bus_creds_get_slice(c, &s);
|
|
|
|
if (v != -ENODATA)
|
|
|
|
fprintf(f, "%sSlice=%s%s%s", prefix, color, strna(s), suffix);
|
|
|
|
s = NULL;
|
2015-04-30 11:58:06 +02:00
|
|
|
q = sd_bus_creds_get_user_unit(c, &s);
|
|
|
|
if (q != -ENODATA)
|
|
|
|
fprintf(f, "%sUserUnit=%s%s%s", prefix, color, strna(s), suffix);
|
|
|
|
s = NULL;
|
|
|
|
w = sd_bus_creds_get_user_slice(c, &s);
|
2015-04-29 21:40:54 +02:00
|
|
|
if (w != -ENODATA)
|
2015-04-30 11:58:06 +02:00
|
|
|
fprintf(f, "%sUserSlice=%s%s%s", prefix, color, strna(s), suffix);
|
|
|
|
s = NULL;
|
|
|
|
z = sd_bus_creds_get_session(c, &s);
|
|
|
|
if (z != -ENODATA)
|
2015-04-29 21:40:54 +02:00
|
|
|
fprintf(f, "%sSession=%s%s%s", prefix, color, strna(s), suffix);
|
|
|
|
|
2015-04-30 11:58:06 +02:00
|
|
|
if (terse && ((c->mask & SD_BUS_CREDS_CGROUP) || r != -ENODATA || q != -ENODATA || v != -ENODATA || w != -ENODATA || z != -ENODATA))
|
2013-11-28 17:50:02 +01:00
|
|
|
fputs("\n", f);
|
|
|
|
|
2015-04-29 21:40:54 +02:00
|
|
|
r = sd_bus_creds_get_audit_login_uid(c, &audit_loginuid);
|
|
|
|
if (r >= 0)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sAuditLoginUID=%s"UID_FMT"%s", prefix, color, audit_loginuid, suffix);
|
2015-04-29 21:40:54 +02:00
|
|
|
else if (r != -ENODATA)
|
|
|
|
fprintf(f, "%sAuditLoginUID=%sn/a%s", prefix, color, suffix);
|
|
|
|
q = sd_bus_creds_get_audit_session_id(c, &audit_sessionid);
|
|
|
|
if (q >= 0)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sAuditSessionID=%s%"PRIu32"%s", prefix, color, audit_sessionid, suffix);
|
2015-04-29 21:40:54 +02:00
|
|
|
else if (q != -ENODATA)
|
|
|
|
fprintf(f, "%sAuditSessionID=%sn/a%s", prefix, color, suffix);
|
2013-11-28 17:50:02 +01:00
|
|
|
|
2015-04-29 21:40:54 +02:00
|
|
|
if (terse && (r != -ENODATA || q != -ENODATA))
|
2013-11-28 17:50:02 +01:00
|
|
|
fputs("\n", f);
|
|
|
|
|
2013-11-30 04:14:10 +01:00
|
|
|
if (c->mask & SD_BUS_CREDS_UNIQUE_NAME)
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sUniqueName=%s%s%s", prefix, color, c->unique_name, suffix);
|
2013-11-30 04:14:10 +01:00
|
|
|
|
|
|
|
if (sd_bus_creds_get_well_known_names(c, &well_known) >= 0) {
|
|
|
|
char **i;
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%sWellKnownNames=%s", prefix, color);
|
2013-11-30 04:14:10 +01:00
|
|
|
STRV_FOREACH(i, well_known) {
|
|
|
|
if (i != well_known)
|
|
|
|
fputc(' ', f);
|
|
|
|
|
|
|
|
fputs(*i, f);
|
|
|
|
}
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
fprintf(f, "%s", suffix);
|
2013-11-30 04:14:10 +01:00
|
|
|
}
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
if (terse && (c->mask & SD_BUS_CREDS_UNIQUE_NAME || well_known))
|
2013-11-30 16:08:11 +01:00
|
|
|
fputc('\n', f);
|
|
|
|
|
2014-11-19 23:59:26 +01:00
|
|
|
dump_capabilities(c, f, "EffectiveCapabilities", terse, sd_bus_creds_has_effective_cap);
|
|
|
|
dump_capabilities(c, f, "PermittedCapabilities", terse, sd_bus_creds_has_permitted_cap);
|
|
|
|
dump_capabilities(c, f, "InheritableCapabilities", terse, sd_bus_creds_has_inheritable_cap);
|
|
|
|
dump_capabilities(c, f, "BoundingCapabilities", terse, sd_bus_creds_has_bounding_cap);
|
2013-11-28 17:50:02 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2014-10-30 01:13:11 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* For details about the file format, see:
|
|
|
|
*
|
|
|
|
* http://wiki.wireshark.org/Development/LibpcapFileFormat
|
|
|
|
*/
|
|
|
|
|
|
|
|
typedef struct _packed_ pcap_hdr_s {
|
|
|
|
uint32_t magic_number; /* magic number */
|
|
|
|
uint16_t version_major; /* major version number */
|
|
|
|
uint16_t version_minor; /* minor version number */
|
|
|
|
int32_t thiszone; /* GMT to local correction */
|
|
|
|
uint32_t sigfigs; /* accuracy of timestamps */
|
|
|
|
uint32_t snaplen; /* max length of captured packets, in octets */
|
|
|
|
uint32_t network; /* data link type */
|
|
|
|
} pcap_hdr_t ;
|
|
|
|
|
|
|
|
typedef struct _packed_ pcaprec_hdr_s {
|
|
|
|
uint32_t ts_sec; /* timestamp seconds */
|
|
|
|
uint32_t ts_usec; /* timestamp microseconds */
|
|
|
|
uint32_t incl_len; /* number of octets of packet saved in file */
|
|
|
|
uint32_t orig_len; /* actual length of packet */
|
|
|
|
} pcaprec_hdr_t;
|
|
|
|
|
|
|
|
int bus_pcap_header(size_t snaplen, FILE *f) {
|
|
|
|
|
|
|
|
pcap_hdr_t hdr = {
|
|
|
|
.magic_number = 0xa1b2c3d4U,
|
|
|
|
.version_major = 2,
|
|
|
|
.version_minor = 4,
|
|
|
|
.thiszone = 0, /* UTC */
|
|
|
|
.sigfigs = 0,
|
|
|
|
.network = 231, /* D-Bus */
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!f)
|
|
|
|
f = stdout;
|
|
|
|
|
|
|
|
assert(snaplen > 0);
|
|
|
|
assert((size_t) (uint32_t) snaplen == snaplen);
|
|
|
|
|
|
|
|
hdr.snaplen = (uint32_t) snaplen;
|
|
|
|
|
|
|
|
fwrite(&hdr, 1, sizeof(hdr), f);
|
|
|
|
|
2015-07-29 20:31:07 +02:00
|
|
|
return fflush_and_check(f);
|
2014-10-30 01:13:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int bus_message_pcap_frame(sd_bus_message *m, size_t snaplen, FILE *f) {
|
|
|
|
struct bus_body_part *part;
|
|
|
|
pcaprec_hdr_t hdr = {};
|
|
|
|
struct timeval tv;
|
|
|
|
unsigned i;
|
|
|
|
size_t w;
|
|
|
|
|
|
|
|
if (!f)
|
|
|
|
f = stdout;
|
|
|
|
|
|
|
|
assert(m);
|
|
|
|
assert(snaplen > 0);
|
|
|
|
assert((size_t) (uint32_t) snaplen == snaplen);
|
|
|
|
|
|
|
|
if (m->realtime != 0)
|
|
|
|
timeval_store(&tv, m->realtime);
|
|
|
|
else
|
|
|
|
assert_se(gettimeofday(&tv, NULL) >= 0);
|
|
|
|
|
|
|
|
hdr.ts_sec = tv.tv_sec;
|
|
|
|
hdr.ts_usec = tv.tv_usec;
|
|
|
|
hdr.orig_len = BUS_MESSAGE_SIZE(m);
|
|
|
|
hdr.incl_len = MIN(hdr.orig_len, snaplen);
|
|
|
|
|
|
|
|
/* write the pcap header */
|
|
|
|
fwrite(&hdr, 1, sizeof(hdr), f);
|
|
|
|
|
|
|
|
/* write the dbus header */
|
|
|
|
w = MIN(BUS_MESSAGE_BODY_BEGIN(m), snaplen);
|
|
|
|
fwrite(m->header, 1, w, f);
|
|
|
|
snaplen -= w;
|
|
|
|
|
|
|
|
/* write the dbus body */
|
|
|
|
MESSAGE_FOREACH_PART(part, i, m) {
|
|
|
|
if (snaplen <= 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
w = MIN(part->size, snaplen);
|
|
|
|
fwrite(part->data, 1, w, f);
|
|
|
|
snaplen -= w;
|
|
|
|
}
|
|
|
|
|
2015-07-29 20:31:07 +02:00
|
|
|
return fflush_and_check(f);
|
2014-10-30 01:13:11 +01:00
|
|
|
}
|