/***
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 <errno.h>
#include <stddef.h>
#include <string.h>
#include "sd-bus.h"
#include "alloc-util.h"
#include "bus-internal.h"
#include "bus-message.h"
#include "bus-util.h"
#include "driver.h"
#include "env-util.h"
#include "proxy.h"
#include "set.h"
#include "strv.h"
#include "synthesize.h"
#include "util.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;
}
/*
* The org.freedesktop.DBus.Peer.Ping() call returned. We don't care
* whether this succeeded, failed, was not implemented or timed out. We
* cannot assume that the target reacts to this properly. Hence, just
* send the reply to the activation request and be done.
*/
}
int bus_proxy_process_driver(Proxy *p, 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);
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);
} 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);
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);
};
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)
char *n;
continue;
break;
}
r = strv_consume(&owners, n);
if (r < 0) {
err = r;
break;
}
}
}
if (err < 0)
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);
if (p->n_activations >= PROXY_ACTIVATIONS_MAX)
r = sd_bus_message_get_cookie(m, &cookie);
if (r < 0)
return synthetic_reply_method_errno(m, r, NULL);
&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);
if (!activation)
r = sd_bus_call_async(a,
&activation->slot,
msg,
0);
if (r < 0) {
return synthetic_reply_method_errno(m, r, NULL);
}
activation->proxy = p;
++p->n_activations;
return 1;
} 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)
if (!env_assignment_is_valid(s)) {
log_warning("UpdateActivationEnvironment() called with invalid assignment, discarding: %s", s);
} else {
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);
return synthetic_reply_method_return(m, NULL);
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);
}
}