driver.c revision 15411c0cb1192799b37ec8f25d6f30e8d7292fc6
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
Copyright 2013 Daniel Mack
Copyright 2014 Kay Sievers
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/>.
***/
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include "util.h"
#include "sd-bus.h"
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-util.h"
#include "strv.h"
#include "set.h"
#include "driver.h"
#include "synthesize.h"
static int get_creds_by_name(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
int r;
return sd_bus_error_setf(error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", name);
if (r < 0)
return r;
*_creds = c;
c = NULL;
return 0;
}
static int get_creds_by_message(sd_bus *bus, sd_bus_message *m, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
const char *name;
int r;
assert(m);
if (r < 0)
return r;
}
int bus_proxy_process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m, SharedPolicy *sp, const struct ucred *ucred, Set *owned_names) {
int r;
assert(a);
assert(b);
assert(m);
if (!a->is_kernel)
return 0;
return 0;
/* The "Hello()" call is is handled in process_hello() */
if (!sd_bus_message_has_signature(m, ""))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
return synthetic_reply_method_return(m, "s",
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" "
"<node>\n"
" <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
" <method name=\"Introspect\">\n"
" <arg name=\"data\" type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" </interface>\n"
" <interface name=\"org.freedesktop.DBus\">\n"
" <method name=\"AddMatch\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" </method>\n"
" <method name=\"RemoveMatch\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" </method>\n"
" <method name=\"GetConnectionCredentials\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"a{sv}\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"GetConnectionSELinuxSecurityContext\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"ay\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"GetConnectionUnixProcessID\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"u\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"GetConnectionUnixUser\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"u\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"GetId\">\n"
" <arg type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"GetNameOwner\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"Hello\">\n"
" <arg type=\"s\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"ListActivatableNames\">\n"
" <arg type=\"as\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"ListNames\">\n"
" <arg type=\"as\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"ListQueuedOwners\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"as\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"NameHasOwner\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"b\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"ReleaseName\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"u\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"ReloadConfig\">\n"
" </method>\n"
" <method name=\"RequestName\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"u\" direction=\"in\"/>\n"
" <arg type=\"u\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"StartServiceByName\">\n"
" <arg type=\"s\" direction=\"in\"/>\n"
" <arg type=\"u\" direction=\"in\"/>\n"
" <arg type=\"u\" direction=\"out\"/>\n"
" </method>\n"
" <method name=\"UpdateActivationEnvironment\">\n"
" <arg type=\"a{ss}\" direction=\"in\"/>\n"
" </method>\n"
" <signal name=\"NameAcquired\">\n"
" <arg type=\"s\"/>\n"
" </signal>\n"
" <signal name=\"NameLost\">\n"
" <arg type=\"s\"/>\n"
" </signal>\n"
" <signal name=\"NameOwnerChanged\">\n"
" <arg type=\"s\"/>\n"
" <arg type=\"s\"/>\n"
" <arg type=\"s\"/>\n"
" </signal>\n"
" </interface>\n"
"</node>\n");
const char *match;
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
return synthetic_reply_method_return(m, NULL);
const char *match;
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r == 0)
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "Match rule not found"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
return synthetic_reply_method_return(m, NULL);
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
r = get_creds_by_message(a, m, SD_BUS_CREDS_PID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SELINUX_CONTEXT, &creds, &error);
if (r < 0)
return synthetic_reply_method_errno(m, r, &error);
r = sd_bus_message_new_method_return(m, &reply);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
/* Due to i.e. namespace translations some data might be missing */
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
}
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
}
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
}
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionSELinuxSecurityContext")) {
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, &error);
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "GetConnectionUnixProcessID")) {
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, &error);
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, &error);
char buf[SD_ID128_STRING_MAX];
if (!sd_bus_message_has_signature(m, ""))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
r = sd_bus_get_bus_id(a, &server_id);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
const char *name;
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, &error);
if (!sd_bus_message_has_signature(m, ""))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
/* Let's sort the names list to make it stable */
return synthetic_reply_method_return_strv(m, names);
if (!sd_bus_message_has_signature(m, ""))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
/* Let's sort the names list to make it stable */
return synthetic_reply_method_return_strv(m, names);
struct kdbus_cmd_list cmd = {
};
char *arg0;
int err = 0;
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
sd_bus_error_setf(&error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owners of name '%s': no such name.", arg0);
return synthetic_reply_method_errno(m, r, &error);
}
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
const char *entry_name = NULL;
struct kdbus_item *item;
char *n;
continue;
break;
}
r = strv_consume(&owners, n);
if (r < 0) {
err = r;
break;
}
}
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (err < 0)
return synthetic_reply_method_return_strv(m, owners);
const char *name;
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
return synthetic_reply_method_return(m, "b", true);
return synthetic_reply_method_errno(m, r, NULL);
return synthetic_reply_method_return(m, "b", r >= 0);
const char *name;
if (!sd_bus_message_has_signature(m, "s"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
r = sd_bus_release_name(a, name);
if (r < 0) {
if (r == -ESRCH)
if (r == -EADDRINUSE)
return synthetic_reply_method_errno(m, r, NULL);
}
if (!sd_bus_message_has_signature(m, ""))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
r = shared_policy_reload(sp);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
return synthetic_reply_method_return(m, NULL);
const char *name;
bool in_queue;
if (!sd_bus_message_has_signature(m, "su"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (sp) {
bool denied;
if (denied)
}
param = 0;
if (flags & BUS_NAME_ALLOW_REPLACEMENT)
if (flags & BUS_NAME_REPLACE_EXISTING)
if (!(flags & BUS_NAME_DO_NOT_QUEUE))
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0) {
if (r == -EALREADY)
if (r == -EEXIST)
return synthetic_reply_method_errno(m, r, NULL);
}
in_queue = (r == 0);
if (in_queue)
const char *name;
if (!sd_bus_message_has_signature(m, "su"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (flags != 0)
if (r != -ESRCH)
return synthetic_reply_method_errno(m, r, NULL);
a,
&msg,
name,
"/",
"org.freedesktop.DBus.Peer",
"Ping");
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "UpdateActivationEnvironment")) {
if (!sd_bus_message_has_signature(m, "a{ss}"))
return synthetic_reply_method_error(m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_INVALID_ARGS, "Invalid parameters"));
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
_cleanup_free_ char *s = NULL;
const char *key;
const char *value;
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (!s)
r = strv_extend(&args, s);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
r = sd_bus_message_exit_container(m);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
}
r = sd_bus_message_exit_container(m);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (!args)
a,
&msg,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"SetEnvironment");
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
return synthetic_reply_method_return(m, NULL);
} else {
return synthetic_reply_method_errno(m, r, &error);
}
}