[lib-fix] moved dbus_connection_get_unix_user from daemon to library
[platform/upstream/dbus.git] / bus / services.c
index 8a18627..90a2f5f 100644 (file)
 #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 "connection.h"
 #include "policy.h"
 #include "bus.h"
 #include "selinux.h"
+
 #ifdef ENABLE_KDBUS_TRANSPORT
+#include <linux/types.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+
 #include "kdbus-d.h"
 #include "dbus/kdbus.h"
+#include "dbus/kdbus-common.h"
 #endif
 
 struct BusService
@@ -221,7 +223,7 @@ bus_owner_set_flags (BusOwner *owner,
 
 #ifdef ENABLE_KDBUS_TRANSPORT
    owner->is_kdbus_starter =
-        (flags & KDBUS_NAME_STARTER) != FALSE;
+        (flags & KDBUS_NAME_STARTER_NAME) != FALSE;
 #endif
 }
 
@@ -649,13 +651,14 @@ bus_registry_acquire_kdbus_service (BusRegistry      *registry,
   dbus_bool_t retval;
   BusService *service;
   BusActivation  *activation;
-
   DBusString service_name_real;
   const DBusString *service_name = &service_name_real;
   char* name;
   dbus_uint32_t flags;
   __u64 sender_id;
-  dbus_bool_t rm_owner_daemon = FALSE;
+  const char* conn_unique_name;
+  DBusConnection* phantom;
+  unsigned long int uid;
 
   if (!dbus_message_get_args (message, error,
                               DBUS_TYPE_STRING, &name,
@@ -671,125 +674,113 @@ bus_registry_acquire_kdbus_service (BusRegistry      *registry,
                                 _dbus_string_get_length (service_name)))
     {
       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
-                      "Requested bus name \"%s\" is not valid",
-                      _dbus_string_get_const_data (service_name));
+                      "Requested bus name \"%s\" is not valid", name);
 
       _dbus_verbose ("Attempt to acquire invalid service name\n");
 
-      goto out;
+      return FALSE;
     }
 
   if (_dbus_string_get_byte (service_name, 0) == ':')
     {
       /* Not allowed; only base services can start with ':' */
       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
-                      "Cannot acquire a service starting with ':' such as \"%s\"",
-                      _dbus_string_get_const_data (service_name));
+                      "Cannot acquire a service starting with ':' such as \"%s\"", name);
 
-      _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"",
-                     _dbus_string_get_const_data (service_name));
+      _dbus_verbose ("Attempt to acquire invalid base service name \"%s\"", name);
 
-      goto out;
+      return FALSE;
     }
 
+  conn_unique_name = dbus_message_get_sender(message);
+
   if (_dbus_string_equal_c_str (service_name, DBUS_SERVICE_DBUS))
     {
       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
                       "Connection \"%s\" is not allowed to own the service \"%s\"because "
                       "it is reserved for D-Bus' use only",
-                      bus_connection_is_active (connection) ?
-                      bus_connection_get_name (connection) :
-                      "(inactive)",
-                      DBUS_SERVICE_DBUS);
-      goto out;
+                      conn_unique_name, DBUS_SERVICE_DBUS);
+      return FALSE;
     }
 
-       service = bus_registry_lookup (registry, service_name);
-       if (service == NULL)
-       {
-               service = bus_registry_ensure (registry, service_name, connection, flags,
-                                                                        transaction, error);  //adds daemon to service owners list - must be removed after right owner is set
-               if (service == NULL)
-                 goto out;
+  sender_id = sender_name_to_id(conn_unique_name, error);
+  if(dbus_error_is_set(error))
+    return FALSE;
 
-               rm_owner_daemon = TRUE;
-               if(!kdbus_register_policy(service_name, connection))
-               {
-                       dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
-                                                 "Connection is not allowed to own the service \"%s\" due to security policies in the configuration file",
-                                                 _dbus_string_get_const_data (service_name));
-                       goto failed;
-               }
-       }
+  phantom = bus_connections_find_conn_by_name(bus_connection_get_connections(connection), conn_unique_name);
+  if(phantom == NULL)
+    {
+      phantom = create_phantom_connection(connection, conn_unique_name, error);
+      if(phantom == NULL)
+        return FALSE;
+    }
 
-       sender_id = sender_name_to_id(dbus_message_get_sender(message), error);
-       if(dbus_error_is_set(error))
-               goto failed;
+  if (!bus_client_policy_check_can_own (bus_connection_get_policy (phantom), service_name))
+    {
+      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+          "Connection \"%s\" is not allowed to own the service \"%s\" due "
+          "to security policies in the configuration file", conn_unique_name, name);
+      goto failed;
+    }
 
-       *result = kdbus_request_name(connection, service_name, flags, sender_id);
-       if(*result == -EPERM)
-       {
-               dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
-                                         "Connection is not allowed to own the service \"%s\" due to security policies in the configuration file",
-                                         _dbus_string_get_const_data (service_name));
-               goto failed;
-       }
-       else if(*result < 0)
-       {
-               dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired", name);
-               goto failed;
-       }
+  if (!kdbus_connection_get_unix_user(phantom, conn_unique_name, &uid, NULL))
+    goto failed;
 
-       if((*result == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) || (*result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER))
-       {
-           DBusConnection* phantom;
-           const char* name;
-//         DBusList *link;
-
-           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))
-               goto failed2;
-           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_remove_owner fail, we ignore it, because it has
-             * almost none impact on the usage
-             */
-               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
-           }*/
-       }
+#ifdef POLICY_TO_KDBUS
+  if (!register_kdbus_policy(name, dbus_connection_get_transport(phantom), uid))
+  {
+    dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+            "Kdbus error when setting policy for connection \"%s\" and  service name \"%s\"",
+            conn_unique_name, name);
+    goto failed;
+  }
+#endif
 
-  activation = bus_context_get_activation (registry->context);
-  retval = bus_activation_send_pending_auto_activation_messages (activation,
-                                                                service,
-                                                                transaction,
-                                                                error);
- out:
-     return retval;
+  *result = kdbus_request_name(connection, service_name, flags, sender_id);
+  if(*result == -EPERM)
+    {
+      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
+          "Kdbus not allowed %s to own the service \"%s\"",
+          conn_unique_name, _dbus_string_get_const_data (service_name));
+      goto failed;
+    }
+  else if(*result < 0)
+    {
+      dbus_set_error (error, DBUS_ERROR_FAILED , "Name \"%s\" could not be acquired", name);
+      goto failed;
+    }
+
+  if((*result == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) || (*result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER))
+    {
+      service = bus_registry_lookup (registry, service_name);
+      if (service == NULL)
+        {
+          service = bus_registry_ensure (registry, service_name, phantom, flags,
+                       transaction, error);
+          if (service == NULL)
+            goto failed2;
+        }
+      else
+        {
+          if (!bus_service_add_owner (service, phantom, flags, transaction, error))
+            goto failed2;
+        }
+
+      activation = bus_context_get_activation (registry->context);
+      retval = bus_activation_send_pending_auto_activation_messages (activation,
+                   service,
+                   transaction,
+                   error);
+    }
+  else
+    retval = TRUE;
+
+  return retval;
   
 failed2:
-    kdbus_release_name(connection, service_name, sender_id);
+  kdbus_release_name(phantom, service_name, sender_id);
 failed:
-    if(_bus_service_find_owner_link (service, connection))
-        bus_service_remove_owner (service, connection, transaction, NULL);
+  bus_connection_disconnected(phantom);
 
   return FALSE;
 }
@@ -1509,13 +1500,29 @@ DBusConnection *
 bus_service_get_primary_owners_connection (BusService *service)
 {
   BusOwner *owner;
+#ifdef ENABLE_KDBUS_TRANSPORT
+  char unique_name[(unsigned int)(snprintf((char*)NULL, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
+#endif
 
   owner = bus_service_get_primary_owner (service);
 
+#ifdef ENABLE_KDBUS_TRANSPORT
+  if(!owner)
+    return NULL;
+  if(bus_context_is_kdbus(service->registry->context))
+  {
+    if(kdbus_get_name_owner(owner->conn, bus_service_get_name(service), unique_name) < 0)
+      return NULL;
+    return _bus_service_find_owner_connection(service, unique_name);  //bus_connections_find_conn_by_name would be safer? but slower
+  }
+  else
+    return owner->conn;
+#else
   if (owner != NULL)
     return owner->conn;
   else
     return NULL;
+#endif
 }
 
 BusOwner*