d9577dbd92555b0755881e37724019ef9c578404Stef Walter/*
d9577dbd92555b0755881e37724019ef9c578404Stef Walter Authors:
d9577dbd92555b0755881e37724019ef9c578404Stef Walter Stef Walter <stefw@redhat.com>
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter Copyright (C) 2014 Red Hat
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter This program is free software; you can redistribute it and/or modify
d9577dbd92555b0755881e37724019ef9c578404Stef Walter it under the terms of the GNU General Public License as published by
d9577dbd92555b0755881e37724019ef9c578404Stef Walter the Free Software Foundation; either version 3 of the License, or
d9577dbd92555b0755881e37724019ef9c578404Stef Walter (at your option) any later version.
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter This program is distributed in the hope that it will be useful,
d9577dbd92555b0755881e37724019ef9c578404Stef Walter but WITHOUT ANY WARRANTY; without even the implied warranty of
d9577dbd92555b0755881e37724019ef9c578404Stef Walter MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d9577dbd92555b0755881e37724019ef9c578404Stef Walter GNU General Public License for more details.
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter You should have received a copy of the GNU General Public License
d9577dbd92555b0755881e37724019ef9c578404Stef Walter along with this program. If not, see <http://www.gnu.org/licenses/>.
d9577dbd92555b0755881e37724019ef9c578404Stef Walter*/
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter#include "util/util.h"
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek#include "util/sss_utf8.h"
d9577dbd92555b0755881e37724019ef9c578404Stef Walter#include "sbus/sssd_dbus.h"
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter#include "sbus/sssd_dbus_private.h"
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter#include <sys/time.h>
d9577dbd92555b0755881e37724019ef9c578404Stef Walter#include <dbus/dbus.h>
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
8779b9ee101ed3e5a6836b5366c006dc21dd36c0Pavel Březina#define INTERNAL_ERROR "Internal Error"
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walterstatic int sbus_request_destructor(struct sbus_request *dbus_req)
d9577dbd92555b0755881e37724019ef9c578404Stef Walter{
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_message_unref(dbus_req->message);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return 0;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter}
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walterstruct sbus_request *
d9577dbd92555b0755881e37724019ef9c578404Stef Waltersbus_new_request(struct sbus_connection *conn,
d9577dbd92555b0755881e37724019ef9c578404Stef Walter struct sbus_interface *intf,
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DBusMessage *message)
d9577dbd92555b0755881e37724019ef9c578404Stef Walter{
d9577dbd92555b0755881e37724019ef9c578404Stef Walter struct sbus_request *dbus_req;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_req = talloc_zero(conn, struct sbus_request);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter if (!dbus_req) {
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus request\n");
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return NULL;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter }
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_req->intf = intf;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_req->conn = conn;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_req->message = dbus_message_ref(message);
71c9027d4192bf149afa4fcf9fef93bf6e901121Pavel Březina dbus_req->path = dbus_message_get_path(message);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter talloc_set_destructor(dbus_req, sbus_request_destructor);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return dbus_req;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter}
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Waltervoid
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Waltersbus_request_invoke_or_finish(struct sbus_request *dbus_req,
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter sbus_msg_handler_fn handler_fn,
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter void *handler_data,
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter sbus_method_invoker_fn invoker_fn)
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter{
8779b9ee101ed3e5a6836b5366c006dc21dd36c0Pavel Březina DBusError error;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter int ret;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina if (invoker_fn != NULL) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter ret = invoker_fn(dbus_req, handler_fn);
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina } else if (handler_fn != NULL) {
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter ret = handler_fn(dbus_req, handler_data);
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina } else {
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina ret = EINVAL;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter switch(ret) {
c30b7a1931211fdcae0564551a7625cc4f6dee9fJakub Hrozek case ERR_SBUS_REQUEST_HANDLED:
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter case EOK:
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter return;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter case ENOMEM:
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory handling DBus message\n");
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter sbus_request_finish(dbus_req, NULL);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter break;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter default:
91c637615fc45679235b3371792e2eaf63a62b4fPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Handler failed [%d]: %s\n",
91c637615fc45679235b3371792e2eaf63a62b4fPavel Březina ret, sss_strerror(ret));
6c4b1250ece32296ccdc15eccf2a0f740b3768b0Jakub Hrozek dbus_error_init(&error);
8779b9ee101ed3e5a6836b5366c006dc21dd36c0Pavel Březina dbus_set_error_const(&error, DBUS_ERROR_FAILED, INTERNAL_ERROR);
8779b9ee101ed3e5a6836b5366c006dc21dd36c0Pavel Březina sbus_request_fail_and_finish(dbus_req, &error);
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter break;
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter }
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter}
dff909d473f43a6bd0f0286fa2d279c0ebe945c6Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walterint sbus_request_finish(struct sbus_request *dbus_req,
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DBusMessage *reply)
d9577dbd92555b0755881e37724019ef9c578404Stef Walter{
d9577dbd92555b0755881e37724019ef9c578404Stef Walter if (reply) {
d9577dbd92555b0755881e37724019ef9c578404Stef Walter sbus_conn_send_reply(dbus_req->conn, reply);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter }
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return talloc_free(dbus_req);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter}
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozekstatic int sbus_request_valist_check(va_list va, int first_arg_type)
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek{
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek int ret = EOK;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek#ifdef HAVE_DBUSBASICVALUE
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek int type;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek va_list va_check;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek const DBusBasicValue *value;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek bool ok;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek va_copy(va_check, va);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek type = first_arg_type;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek while (type != DBUS_TYPE_INVALID) {
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek value = va_arg(va_check, const DBusBasicValue*);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek if (type == DBUS_TYPE_STRING) {
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek ok = sss_utf8_check((const uint8_t *) value->str,
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek strlen(value->str));
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek if (!ok) {
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE,
de1131abe5ba7aaeb59f81fc3a9cd2a71c0b52ddLukas Slebodnik "sbus message argument [%s] contains invalid "
de1131abe5ba7aaeb59f81fc3a9cd2a71c0b52ddLukas Slebodnik "non-UTF8 characters\n", value->str);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek ret = EINVAL;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek break;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek }
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek }
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek type = va_arg(va_check, int);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek }
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek va_end(va_check);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek#endif /* HAVE_DBUSBASICVALUE */
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek return ret;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek}
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek
d9577dbd92555b0755881e37724019ef9c578404Stef Walterint sbus_request_return_and_finish(struct sbus_request *dbus_req,
d9577dbd92555b0755881e37724019ef9c578404Stef Walter int first_arg_type,
d9577dbd92555b0755881e37724019ef9c578404Stef Walter ...)
d9577dbd92555b0755881e37724019ef9c578404Stef Walter{
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DBusMessage *reply;
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek DBusError error = DBUS_ERROR_INIT;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_bool_t dbret;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter va_list va;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter int ret;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek va_start(va, first_arg_type);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek ret = sbus_request_valist_check(va, first_arg_type);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek if (ret != EOK) {
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek va_end(va);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek dbus_set_error_const(&error, DBUS_ERROR_INVALID_ARGS, INTERNAL_ERROR);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek return sbus_request_fail_and_finish(dbus_req, &error);
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek }
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek
d9577dbd92555b0755881e37724019ef9c578404Stef Walter reply = dbus_message_new_method_return(dbus_req->message);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter if (!reply) {
6b01dae732eedee808f32a9cdd4b5656a9f839c4Jakub Hrozek va_end(va);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus message\n");
d9577dbd92555b0755881e37724019ef9c578404Stef Walter sbus_request_finish(dbus_req, NULL);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return ENOMEM;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter }
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbret = dbus_message_append_args_valist(reply, first_arg_type, va);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter va_end(va);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter if (dbret) {
d9577dbd92555b0755881e37724019ef9c578404Stef Walter ret = sbus_request_finish(dbus_req, reply);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter } else {
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't build DBus message\n");
d9577dbd92555b0755881e37724019ef9c578404Stef Walter sbus_request_finish(dbus_req, NULL);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter ret = EINVAL;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter }
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_message_unref(reply);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return ret;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter}
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walterint sbus_request_fail_and_finish(struct sbus_request *dbus_req,
d9577dbd92555b0755881e37724019ef9c578404Stef Walter const DBusError *error)
d9577dbd92555b0755881e37724019ef9c578404Stef Walter{
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DBusMessage *reply;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter int ret;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina if (error == NULL) {
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina sbus_request_finish(dbus_req, NULL);
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina return ENOMEM;
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina }
a2ac7f081721cae6a6c4671fee3dfd9fe7d7da48Pavel Březina
d9577dbd92555b0755881e37724019ef9c578404Stef Walter reply = dbus_message_new_error(dbus_req->message, error->name, error->message);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter if (!reply) {
d9577dbd92555b0755881e37724019ef9c578404Stef Walter DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus message\n");
d9577dbd92555b0755881e37724019ef9c578404Stef Walter sbus_request_finish(dbus_req, NULL);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return ENOMEM;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter }
d9577dbd92555b0755881e37724019ef9c578404Stef Walter
d9577dbd92555b0755881e37724019ef9c578404Stef Walter ret = sbus_request_finish(dbus_req, reply);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter dbus_message_unref(reply);
d9577dbd92555b0755881e37724019ef9c578404Stef Walter return ret;
d9577dbd92555b0755881e37724019ef9c578404Stef Walter}
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březinastatic DBusError *sbus_error_new_va(TALLOC_CTX *mem_ctx,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina const char *error_name,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina const char *fmt,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina va_list ap)
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina{
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina DBusError *error;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina const char *error_msg;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina error = talloc_zero(mem_ctx, DBusError);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina if (error == NULL) {
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina return NULL;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina }
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina if (fmt != NULL) {
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina error_msg = talloc_vasprintf(error, fmt, ap);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina if (error_msg == NULL) {
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina talloc_free(error);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina return NULL;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina }
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina } else {
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina error_msg = NULL;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina }
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina dbus_error_init(error);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina dbus_set_error_const(error, error_name, error_msg);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina return error;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina}
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub HrozekDBusError *sbus_error_new(TALLOC_CTX *mem_ctx,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina const char *dbus_error_name,
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek const char *fmt,
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek ...)
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek{
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina DBusError *error;
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek va_list ap;
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina va_start(ap, fmt);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina error = sbus_error_new_va(mem_ctx, dbus_error_name, fmt, ap);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina va_end(ap);
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina return error;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina}
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březinavoid sbus_request_reply_error(struct sbus_request *sbus_req,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina const char *error_name,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina const char *fmt,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina ...)
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina{
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina DBusError *error;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina va_list ap;
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina va_start(ap, fmt);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina error = sbus_error_new_va(sbus_req, error_name, fmt, ap);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina va_end(ap);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina if (error == NULL) {
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina "Unable to create D-Bus error, killing request!\n");
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina talloc_free(sbus_req);
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina return;
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek }
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek
a06e23c0bcf0c8669a29b801876aca8aac422931Pavel Březina sbus_request_fail_and_finish(sbus_req, error);
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek}
87729e3a6c56383642a8d3a86b2856487f2ee064Jakub Hrozek
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walterstruct array_arg {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter char **dbus_array;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter};
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walterstatic int array_arg_destructor(struct array_arg *arg)
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter{
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter dbus_free_string_array(arg->dbus_array);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter return 0;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter}
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walterstatic bool
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walterparent_dbus_string_arrays(struct sbus_request *request, int first_arg_type,
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_list va)
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter{
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter struct array_arg *array_arg;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter int arg_type;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter void **arg_ptr;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter /*
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter * Here we iterate through the entire thing again and look for
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter * things we need to fix allocation for. Normally certain types
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter * returned from dbus_message_get_args() and friends require
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter * later freeing. We tie those to the talloc context here.
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter *
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter * The list of argument has already been validated by the previous
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter * dbus_message_get_args() call, so we can be cheap.
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter arg_type = first_arg_type;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter while (arg_type != DBUS_TYPE_INVALID) {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter if (arg_type == DBUS_TYPE_ARRAY) {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter arg_type = va_arg(va, int); /* the array element type */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter arg_ptr = va_arg(va, void **); /* the array elements */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_arg(va, int *); /* the array length */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter /* Arrays of these things need to be freed */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter if (arg_type == DBUS_TYPE_STRING ||
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter arg_type == DBUS_TYPE_OBJECT_PATH ||
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter arg_type == DBUS_TYPE_SIGNATURE) {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter array_arg = talloc_zero(request, struct array_arg);
3d5908ed0faf400a5c7d9c3e4312597ee1b7786aJakub Hrozek if (array_arg == NULL) {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter /* no kidding ... */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory while trying not to leak memory\n");
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter return false;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter }
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter array_arg->dbus_array = *arg_ptr;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter talloc_set_destructor(array_arg, array_arg_destructor);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter }
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter /* A non array argument */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter } else {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter arg_ptr = va_arg(va, void**);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter }
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter /* The next type */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter arg_type = va_arg(va, int);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter }
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter return true;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter}
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walterbool
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Waltersbus_request_parse_or_finish(struct sbus_request *request,
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter int first_arg_type,
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter ...)
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter{
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter DBusError error = DBUS_ERROR_INIT;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter bool ret = true;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_list va2;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_list va;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_start(va, first_arg_type);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_copy(va2, va);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter if (dbus_message_get_args_valist(request->message, &error,
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter first_arg_type, va)) {
3d5908ed0faf400a5c7d9c3e4312597ee1b7786aJakub Hrozek ret = parent_dbus_string_arrays(request, first_arg_type, va2);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter } else {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter /* Trying to send the error back to the caller in this case is a joke */
94f07a6f4375ec25d8fa5c99a0c4f68de7002457Jakub Hrozek if (!dbus_error_is_set(&error) &&
94f07a6f4375ec25d8fa5c99a0c4f68de7002457Jakub Hrozek dbus_error_has_name(&error, DBUS_ERROR_NO_MEMORY)) {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory parsing DBus message\n");
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter sbus_request_finish(request, NULL);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter /* Log other errors and send them back, this include o.f.d.InvalidArgs */
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter } else {
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter DEBUG(SSSDBG_OP_FAILURE, "Couldn't parse DBus message %s.%s: %s\n",
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter dbus_message_get_interface(request->message),
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter dbus_message_get_member(request->message),
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter error.message);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter sbus_request_fail_and_finish(request, &error);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter }
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter dbus_error_free(&error);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter ret = false;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter }
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_end(va2);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter va_end(va);
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter return ret;
06b7bc8ca2e005ed510210d3b8dee16afbabbcc9Stef Walter}
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozekstruct sbus_get_sender_id_state {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct sbus_connection *conn;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBusConnection *sysbus_conn;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek char *sender;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek int64_t uid;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek};
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozekstatic void sbus_get_sender_id_done(DBusPendingCall *pending, void *ptr);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozekstruct tevent_req *sbus_get_sender_id_send(TALLOC_CTX *mem_ctx,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct tevent_context *ev,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct sbus_connection *conn,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek const char *sender)
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek{
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct tevent_req *req;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct sbus_get_sender_id_state *state;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBusError dbus_error;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBusMessage *msg = NULL;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_bool_t dbret;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek errno_t ret;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek hash_key_t key;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek hash_value_t value;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek req = tevent_req_create(mem_ctx, &state, struct sbus_get_sender_id_state);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (req == NULL) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek return NULL;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek state->conn = conn;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek state->uid = -1;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (conn->connection_type != SBUS_CONN_TYPE_SYSBUS) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, "Not a sysbus message, quit\n");
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = EOK;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (sender == NULL) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = ERR_SBUS_NO_SENDER;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
9118a539a5d59f669f551114f880fe91d6bb8741Jakub Hrozek if (strcmp(sender, "org.freedesktop.DBus") == 0) {
9118a539a5d59f669f551114f880fe91d6bb8741Jakub Hrozek ret = ERR_SBUS_SENDER_BUS;
9118a539a5d59f669f551114f880fe91d6bb8741Jakub Hrozek goto immediate;
9118a539a5d59f669f551114f880fe91d6bb8741Jakub Hrozek }
9118a539a5d59f669f551114f880fe91d6bb8741Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek state->sender = talloc_strdup(state, sender);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (state->sender == NULL) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = ENOMEM;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
6c2a29a912f4c995343315f1f70c825ca2200640Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
6c2a29a912f4c995343315f1f70c825ca2200640Jakub Hrozek "Looking for identity of sender [%s]\n", sender);
6c2a29a912f4c995343315f1f70c825ca2200640Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek key.type = HASH_KEY_STRING;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek key.str = discard_const(sender);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = hash_lookup(conn->clients, &key, &value);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (ret == HASH_SUCCESS) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "%s already present in the clients table\n", sender);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek state->uid = (int64_t) value.ul;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = EOK;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek } else if (ret != HASH_ERROR_KEY_NOT_FOUND) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "Failed to look up %s in the clients table\n", sender);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = ERR_SBUS_GET_SENDER_ERROR;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek /* We don't know this sender yet, let's ask the system bus */
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek /* Connect to the well-known system bus */
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_error_init(&dbus_error);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek state->sysbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (state->sysbus_conn == NULL) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "Failed to connect to D-BUS system bus.\n");
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = ERR_SBUS_GET_SENDER_ERROR;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_connection_set_exit_on_disconnect(state->sysbus_conn, FALSE);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek /* If we ever need to get the SELinux context or the PID here, we need
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek * to call GetConnectionCredentials instead
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek */
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek msg = dbus_message_new_method_call("org.freedesktop.DBus", /* bus name */
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "/org/freedesktop/DBus", /* path */
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "org.freedesktop.DBus", /* interface */
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "GetConnectionUnixUser");
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (msg == NULL) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = ENOMEM;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbret = dbus_message_append_args(msg,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBUS_TYPE_STRING, &sender,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBUS_TYPE_INVALID);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (!dbret) {
6c2a29a912f4c995343315f1f70c825ca2200640Jakub Hrozek ret = ERR_INTERNAL;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = sss_dbus_conn_send(state->sysbus_conn, msg, 3000,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek sbus_get_sender_id_done,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek req, NULL);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_message_unref(msg);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek msg = NULL;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (ret != EOK) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto immediate;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek return req;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozekimmediate:
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (ret == EOK) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek tevent_req_done(req);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek } else {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (msg != NULL) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_message_unref(msg);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (state->sysbus_conn != NULL) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_connection_unref(state->sysbus_conn);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek tevent_req_error(req, ret);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek tevent_req_post(req, ev);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek return req;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek}
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozekstatic void sbus_get_sender_id_done(DBusPendingCall *pending, void *ptr)
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek{
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct tevent_req *req;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct sbus_get_sender_id_state *state;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBusMessage *reply;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBusError dbus_error;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek hash_key_t key;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek hash_value_t value;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_bool_t dbret;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek int ret;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek uid_t uid;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_error_init(&dbus_error);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek req = talloc_get_type(ptr, struct tevent_req);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek state = tevent_req_data(req, struct sbus_get_sender_id_state);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek reply = dbus_pending_call_steal_reply(pending);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (!reply) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek /* reply should never be null. This function shouldn't be called
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek * until reply is valid or timeout has occurred. If reply is NULL
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek * here, something is seriously wrong and we should bail out.
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek */
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "Severe error. A reply callback was called but no reply "
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek "was received and no timeout occurred\n");
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = EIO;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto done;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbret = dbus_message_get_args(reply,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek &dbus_error,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBUS_TYPE_UINT32, &uid,
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek DBUS_TYPE_INVALID);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (!dbret) {
6c2a29a912f4c995343315f1f70c825ca2200640Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse reply!\n");
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = EIO;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto done;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek state->uid = uid;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek key.type = HASH_KEY_STRING;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek key.str = talloc_steal(state->conn->clients, state->sender);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek value.type = HASH_VALUE_UINT;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek value.ul = state->uid;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = hash_enter(state->conn->clients, &key, &value);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (ret != HASH_SUCCESS) {
6c2a29a912f4c995343315f1f70c825ca2200640Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "Could not add key to hash table!\n");
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = EIO;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek goto done;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek ret = EOK;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozekdone:
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_pending_call_unref(pending);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_message_unref(reply);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek dbus_connection_unref(state->sysbus_conn);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (ret != EOK) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek tevent_req_error(req, ret);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek } else {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek tevent_req_done(req);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek}
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozekint sbus_get_sender_id_recv(struct tevent_req *req, int64_t *_uid)
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek{
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek struct sbus_get_sender_id_state *state = \
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek tevent_req_data(req, struct sbus_get_sender_id_state);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek TEVENT_REQ_RETURN_ON_ERROR(req);
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek if (_uid) {
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek *_uid = state->uid;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek }
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek return EOK;
0161a3c5637a0c0092bf54c436bb3d6508d7df26Jakub Hrozek}