*
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2003 CodeFactory AB
+ * Copyright (C) 2013 Samsung Electronics
*
* Licensed under the Academic Free License version 2.1
*
#include <dbus/dbus-list.h>
#include <dbus/dbus-mempool.h>
#include <dbus/dbus-marshal-validate.h>
+#ifdef ENABLE_KDBUS_TRANSPORT
#include <linux/types.h>
#include <errno.h>
#include <stdlib.h>
-
+#endif
#include "driver.h"
#include "services.h"
#include "policy.h"
#include "bus.h"
#include "selinux.h"
+#ifdef ENABLE_KDBUS_TRANSPORT
#include "kdbus-d.h"
+#include "dbus/kdbus.h"
+#endif
struct BusService
{
unsigned int allow_replacement : 1;
unsigned int do_not_queue : 1;
+#ifdef ENABLE_KDBUS_TRANSPORT
+ unsigned int is_kdbus_starter : 1;
+#endif
};
struct BusRegistry
return link;
}
+#ifdef ENABLE_KDBUS_TRANSPORT
static DBusConnection *
_bus_service_find_owner_connection (BusService *service,
const char* unique_name)
return NULL;
}
+#endif
static void
bus_owner_set_flags (BusOwner *owner,
owner->do_not_queue =
(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE) != FALSE;
+
+#ifdef ENABLE_KDBUS_TRANSPORT
+ owner->is_kdbus_starter =
+ (flags & KDBUS_NAME_STARTER) != FALSE;
+#endif
}
static BusOwner *
return retval;
}
+#ifdef ENABLE_KDBUS_TRANSPORT
dbus_bool_t
bus_registry_acquire_kdbus_service (BusRegistry *registry,
DBusConnection *connection,
char* name;
dbus_uint32_t flags;
__u64 sender_id;
+ dbus_bool_t rm_owner_daemon = FALSE;
if (!dbus_message_get_args (message, error,
DBUS_TYPE_STRING, &name,
if (service == NULL)
goto out;
+ rm_owner_daemon = TRUE;
if(!kdbus_register_policy(service_name, connection))
{
dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
if((*result == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) || (*result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER))
{
DBusConnection* phantom;
+ const char* name;
+// DBusList *link;
- phantom = create_phantom_connection(connection, dbus_message_get_sender(message), error);
+ name = dbus_message_get_sender(message);
+ phantom = bus_connections_find_conn_by_name(bus_connection_get_connections(connection), name);
+ if(phantom == NULL)
+ phantom = create_phantom_connection(connection, name, error);
if(phantom == NULL)
goto failed2;
if (!bus_service_add_owner (service, phantom, flags, transaction, error))
- {
- dbus_connection_unref_phantom(phantom);
goto failed2;
- }
- if(*result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+ if((*result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) && rm_owner_daemon)
{
/* Here we are removing DBus daemon as an owner of the service,
* which is set by bus_registry_ensure.
if(_bus_service_find_owner_link (service, connection))
bus_service_remove_owner (service, connection, transaction, NULL);
}
+ /*if(bus_service_get_is_kdbus_starter(service))
+ {
+ if (!bus_service_swap_owner (service, bus_service_get_primary_owners_connection(service),
+ transaction, error))
+ goto failed2;
+ }*/
+ /*if((link = _bus_service_find_owner_link (service, connection))) //if daemon is a starter
+ {
+ _dbus_list_unlink (&service->owners, link);
+ _dbus_list_append_link (&service->owners, link); //it must be moved at the end of the queue
+ }*/
}
activation = bus_context_get_activation (registry->context);
return FALSE;
}
+#endif
dbus_bool_t
bus_registry_release_service (BusRegistry *registry,
goto out;
}
- if(bus_context_is_kdbus(bus_transaction_get_context (transaction)))
- {
- __u64 sender_id;
+ service = bus_registry_lookup (registry, service_name);
- sender_id = sender_name_to_id((const char*)registry, error);
- if(dbus_error_is_set(error))
- return FALSE;
+ if (service == NULL)
+ {
+ *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
+ }
+ else if (!bus_service_has_owner (service, connection))
+ {
+ *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
+ }
+ else
+ {
+ if (!bus_service_remove_owner (service, connection,
+ transaction, error))
+ goto out;
- *result = kdbus_release_name(connection, service_name, sender_id);
+ _dbus_assert (!bus_service_has_owner (service, connection));
+ *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
+ }
- if(*result == DBUS_RELEASE_NAME_REPLY_RELEASED)
- {
- const char* name;
+ retval = TRUE;
- name = (const char*)registry; //get name passed in registry pointer
- registry = bus_connection_get_registry (connection); //than take original registry address
+ out:
+ return retval;
+}
- service = bus_registry_lookup (registry, service_name);
- if(service)
- {
- DBusConnection* phantom;
-
- phantom = _bus_service_find_owner_connection(service, name);
- if(phantom)
- {
- bus_service_remove_owner (service, phantom, transaction, NULL);
- dbus_connection_unref_phantom(phantom);
- }
- else
- _dbus_verbose ("Didn't find phantom connection for released name!\n");
- }
- }
- }
- else
- {
- service = bus_registry_lookup (registry, service_name);
+#ifdef ENABLE_KDBUS_TRANSPORT
+dbus_bool_t
+bus_registry_release_service_kdbus (const char* sender_name,
+ DBusConnection *connection,
+ const DBusString *service_name,
+ dbus_uint32_t *result,
+ BusTransaction *transaction,
+ DBusError *error)
+{
+ dbus_bool_t retval = FALSE;
+ __u64 sender_id;
- if (service == NULL)
- {
- *result = DBUS_RELEASE_NAME_REPLY_NON_EXISTENT;
- }
- else if (!bus_service_has_owner (service, connection))
- {
- *result = DBUS_RELEASE_NAME_REPLY_NOT_OWNER;
- }
- else
- {
- if (!bus_service_remove_owner (service, connection,
- transaction, error))
- goto out;
+ if (!_dbus_validate_bus_name (service_name, 0,
+ _dbus_string_get_length (service_name)))
+ {
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Given bus name \"%s\" is not valid",
+ _dbus_string_get_const_data (service_name));
- _dbus_assert (!bus_service_has_owner (service, connection));
- *result = DBUS_RELEASE_NAME_REPLY_RELEASED;
- }
- }
+ _dbus_verbose ("Attempt to release invalid service name\n");
+
+ goto out;
+ }
+
+ if (_dbus_string_get_byte (service_name, 0) == ':')
+ {
+ /* Not allowed; the base service name cannot be created or released */
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Cannot release a service starting with ':' such as \"%s\"",
+ _dbus_string_get_const_data (service_name));
+
+ _dbus_verbose ("Attempt to release invalid base service name \"%s\"",
+ _dbus_string_get_const_data (service_name));
+
+ goto out;
+ }
+
+ if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
+ {
+ /* Not allowed; the base service name cannot be created or released */
+ dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+ "Cannot release the %s service because it is owned by the bus",
+ DBUS_SERVICE_DBUS);
+
+ _dbus_verbose ("Attempt to release service name \"%s\"",
+ DBUS_SERVICE_DBUS);
+
+ goto out;
+ }
+
+ sender_id = sender_name_to_id(sender_name, error);
+ if(dbus_error_is_set(error))
+ return FALSE;
+
+ *result = kdbus_release_name(connection, service_name, sender_id);
+
+ if(*result == DBUS_RELEASE_NAME_REPLY_RELEASED)
+ {
+ BusRegistry* registry;
+ BusService *service;
+
+ registry = bus_connection_get_registry (connection);
+ service = bus_registry_lookup (registry, service_name);
+ if(service)
+ {
+ DBusConnection* phantom;
+
+ phantom = _bus_service_find_owner_connection(service, sender_name);
+ if(phantom)
+ {
+ bus_service_remove_owner (service, phantom, transaction, NULL);
+ /* todo we could remove phantom if he doesn't own any name
+ * to do this we should write function in connection.c to check if
+ * _dbus_list_get_last (&d->services_owned) returns not NULL
+ * or we can leave phantom - he will be removed when he disconnects from the bus
+ */
+ }
+ else
+ _dbus_verbose ("Didn't find phantom connection for released name!\n");
+ }
+ }
retval = TRUE;
out:
return retval;
}
+#endif
dbus_bool_t
bus_registry_set_service_context_table (BusRegistry *registry,
return owner->allow_replacement;
}
+#ifdef ENABLE_KDBUS_TRANSPORT
+dbus_bool_t
+bus_service_get_is_kdbus_starter (BusService *service)
+{
+ BusOwner *owner;
+ DBusList *link;
+
+ _dbus_assert (service->owners != NULL);
+
+ link = _dbus_list_get_first_link (&service->owners);
+ owner = (BusOwner *) link->data;
+
+ return owner->is_kdbus_starter;
+}
+#endif
+
dbus_bool_t
bus_service_has_owner (BusService *service,
DBusConnection *connection)
owner = (BusOwner *) link->data;
uname = bus_connection_get_name (owner->conn);
- if (!_dbus_list_append (return_list, (char *)uname))
- goto oom;
+#ifdef ENABLE_KDBUS_TRANSPORT
+ if(!owner->is_kdbus_starter)
+#endif
+ if (!_dbus_list_append (return_list, (char *)uname))
+ goto oom;
link = _dbus_list_get_next_link (&service->owners, link);
}