bus-util.c revision 6bb648a16ae4a682ad4784412af706d2e6a3e4da
842ae4bd224140319ae7feec1872b93dfd491143fielding/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
842ae4bd224140319ae7feec1872b93dfd491143fielding This file is part of systemd.
842ae4bd224140319ae7feec1872b93dfd491143fielding Copyright 2013 Lennart Poettering
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd systemd is free software; you can redistribute it and/or modify it
059f354a6b7b116e4469ff7fe99c1142affa0ad6fielding under the terms of the GNU Lesser General Public License as published by
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd the Free Software Foundation; either version 2.1 of the License, or
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd (at your option) any later version.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd systemd is distributed in the hope that it will be useful, but
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd WITHOUT ANY WARRANTY; without even the implied warranty of
059f354a6b7b116e4469ff7fe99c1142affa0ad6fielding MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6343482c5c85d8119543e6c1798a08d9b08dfe57stoddard Lesser General Public License for more details.
cd772754fa5df268f4f8cfee93eb2267d6f04c80stoddard You should have received a copy of the GNU Lesser General Public License
cd772754fa5df268f4f8cfee93eb2267d6f04c80stoddard along with systemd; If not, see <http://www.gnu.org/licenses/>.
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wrowestatic int name_owner_change_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wroweint bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wrowe const char *unique;
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wrowe /* We unregister the name here and then wait for the
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wrowe * NameOwnerChanged signal for this event to arrive before we
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wrowe * quit. We do this in order to make sure that any queued
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wrowe * requests are still processed before we really exit. */
fe679cfd0b0ba1f8d59f09460548d2a7d0231f63wrowe "sender='org.freedesktop.DBus',"
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein "type='signal',"
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein "interface='org.freedesktop.DBus',"
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein "member='NameOwnerChanged',"
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein "arg0='%s',"
cccd31fa4a72fe23cc3249c06db181b274a55a69gstein "arg1='%s',"
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe r = sd_bus_add_match(bus, match, name_owner_change_callback, e);
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe const char *name,
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe bool exiting = false;
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe if (r == 0 && !exiting) {
9e12bb8a48225fc58bc56166b1104158e0d17ed4wroweint bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe _cleanup_bus_message_unref_ sd_bus_message *rep = NULL;
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe "org.freedesktop.DBus",
9e12bb8a48225fc58bc56166b1104158e0d17ed4wrowe "org.freedesktop.DBus",
&rep,
name);
return has_owner;
int bus_verify_polkit(
sd_bus_message *m,
const char *action,
bool interactive,
bool *_challenge,
sd_bus_error *e) {
assert(m);
if (uid == 0)
#ifdef ENABLE_POLKIT
const char *sender;
if (!sender)
return -EBADMSG;
r = sd_bus_call_method(
bus,
&reply,
return -EACCES;
if (authorized)
if (_challenge) {
return -EACCES;
#ifdef ENABLE_POLKIT
typedef struct AsyncPolkitQuery {
void *userdata;
if (q->serial > 0 && b)
free(q);
static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
assert(q);
q->serial = 0;
goto finish;
sd_bus_message *m,
const char *action,
bool interactive,
void *userdata) {
#ifdef ENABLE_POLKIT
AsyncPolkitQuery *q;
const char *sender;
assert(m);
#ifdef ENABLE_POLKIT
const sd_bus_error *e;
return -EACCES;
return -sd_bus_error_get_errno(e);
if (authorized)
return -EACCES;
if (uid == 0)
#ifdef ENABLE_POLKIT
if (!sender)
return -EBADMSG;
bus,
&pk);
pk,
NULL);
return -ENOMEM;
return -EACCES;
#ifdef ENABLE_POLKIT
AsyncPolkitQuery *q;
socklen_t l;
int fd;
assert(c);
if (fd < 0)
return fd;
l = sizeof(struct ucred);
return -errno;
if (l != sizeof(struct ucred))
return -E2BIG;
return -EPERM;
if (geteuid() != 0)
#ifdef ENABLE_KDBUS
#ifdef ENABLE_KDBUS
return -ENOMEM;
if (!ee)
return -ENOMEM;
return -ENOMEM;
char type;
const char *contents;
switch (type) {
case SD_BUS_TYPE_STRING: {
case SD_BUS_TYPE_BOOLEAN: {
case SD_BUS_TYPE_UINT64: {
uint64_t u;
if (t || all)
case SD_BUS_TYPE_UINT32: {
uint32_t u;
case SD_BUS_TYPE_INT32: {
int32_t i;
case SD_BUS_TYPE_DOUBLE: {
case SD_BUS_TYPE_ARRAY:
bool first = true;
const char *str;
if (first)
first = false;
const uint8_t *u;
size_t n;
if (all || n > 0) {
uint32_t *u;
size_t n;
if (all || n > 0) {
int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
dest,
path,
&error,
&reply,
const char *name;
const char *contents;
if (all)
int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
size_t n;
*p = SD_ID128_NULL;
return -EINVAL;
static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
char type;
switch (type) {
case SD_BUS_TYPE_STRING: {
char *str;
char **p = userdata;
if (isempty(s))
if (!str) {
r = -ENOMEM;
free(*p);
*p = str;
case SD_BUS_TYPE_ARRAY: {
char ***p = userdata;
r = bus_message_read_strv_extend(m, &l);
strv_free(*p);
l = NULL;
case SD_BUS_TYPE_BOOLEAN: {
bool *p = userdata;
case SD_BUS_TYPE_UINT32: {
uint64_t u;
case SD_BUS_TYPE_UINT64: {
uint64_t t;
const char *destination,
const char *path,
void *userdata) {
r = sd_bus_call_method(
bus,
path,
&error,
const char *member;
const char *contents;
if (prop) {
r = sd_bus_message_exit_container(m);
r = sd_bus_message_exit_container(m);
switch (transport) {
case BUS_TRANSPORT_LOCAL:
if (user)
case BUS_TRANSPORT_REMOTE:
case BUS_TRANSPORT_CONTAINER:
switch (transport) {
case BUS_TRANSPORT_LOCAL:
if (user)
case BUS_TRANSPORT_REMOTE:
case BUS_TRANSPORT_CONTAINER:
const char *path,
const char *interface,
const char *property,
void *userdata,
const char *path,
const char *interface,
const char *property,
void *userdata,
int b = *(bool*) userdata;
const char *path,
const char *interface,
const char *property,
void *userdata,
const char *path,
const char *interface,
const char *property,
void *userdata,
const char *path,
const char *interface,
const char *property,
void *userdata,
int bus_log_parse_error(int r) {
int bus_log_create_error(int r) {
assert(u);
return sd_bus_message_read(
&u->id,
&u->description,
&u->load_state,
&u->active_state,
&u->sub_state,
&u->following,
&u->unit_path,
&u->job_id,
&u->job_type,
&u->job_path);
assert(m);
log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s",