summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2004-07-19 20:55:58 +0000
committerDavid Zeuthen <davidz@redhat.com>2004-07-19 20:55:58 +0000
commitc9c0adce43caa00345ad2aeb55822eabde523c2c (patch)
tree0fcc4a4b7f5f453781b654a689efb84277fea9e5
parentdcbc92bfeb600efb7244f80247655f004cb558b2 (diff)
downloaddbus-c9c0adce43caa00345ad2aeb55822eabde523c2c.tar.gz
2004-07-19 David Zeuthen <david@fubar.dk>
* dbus/dbus-protocol.h: Add DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN * bus/dispatch.c: (check_get_connection_unix_user): Debug says GetProperty; but the method is called GetConnectionUnixUser (check_get_connection_unix_process_id): New function (bus_dispatch_test): Actually call check_get_connection_unix_user(); also call check_get_connection_unix_process_id() * bus/driver.c: (bus_driver_handle_get_connection_unix_process_id): New function, handles GetConnectionUnixProcessID on the org.freedesktop.DBus interface * dbus/dbus-auth.c: (handle_server_data_external_mech): Set pid from the credentials obtained from the socket * dbus/dbus-connection.c: (dbus_connection_get_unix_process_id): New function * dbus/dbus-connection.h: Add prototype for dbus_connection_get_unix_process_id * dbus/dbus-transport.c: (_dbus_transport_get_unix_process_id): New function * dbus/dbus-transport.h: Add prototype for _dbus_transport_get_unix_process_id
-rw-r--r--ChangeLog32
-rw-r--r--bus/dispatch.c163
-rw-r--r--bus/driver.c78
-rw-r--r--dbus/dbus-auth.c4
-rw-r--r--dbus/dbus-connection.c31
-rw-r--r--dbus/dbus-connection.h2
-rw-r--r--dbus/dbus-protocol.h1
-rw-r--r--dbus/dbus-transport.c32
-rw-r--r--dbus/dbus-transport.h2
9 files changed, 341 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 789a5364..664bc89f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2004-07-19 David Zeuthen <david@fubar.dk>
+
+ * dbus/dbus-protocol.h: Add DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN
+
+ * bus/dispatch.c:
+ (check_get_connection_unix_user): Debug says GetProperty; but the
+ method is called GetConnectionUnixUser
+ (check_get_connection_unix_process_id): New function
+ (bus_dispatch_test): Actually call check_get_connection_unix_user();
+ also call check_get_connection_unix_process_id()
+
+ * bus/driver.c:
+ (bus_driver_handle_get_connection_unix_process_id): New function,
+ handles GetConnectionUnixProcessID on the org.freedesktop.DBus
+ interface
+
+ * dbus/dbus-auth.c:
+ (handle_server_data_external_mech): Set pid from the credentials
+ obtained from the socket
+
+ * dbus/dbus-connection.c:
+ (dbus_connection_get_unix_process_id): New function
+
+ * dbus/dbus-connection.h:
+ Add prototype for dbus_connection_get_unix_process_id
+
+ * dbus/dbus-transport.c:
+ (_dbus_transport_get_unix_process_id): New function
+
+ * dbus/dbus-transport.h:
+ Add prototype for _dbus_transport_get_unix_process_id
+
2004-07-19 Olivier Andrieu <oliv__a@users.sourceforge.net>
* dbus/dbus-message.c: Message counter fix, patch by Christian
diff --git a/bus/dispatch.c b/bus/dispatch.c
index f38a9904..9bc89a7c 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -1029,7 +1029,7 @@ check_get_connection_unix_user (BusContext *context,
{
if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
{
- _dbus_verbose ("no memory to get uid by GetProperty\n");
+ _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n");
dbus_error_free (&error);
_dbus_wait_for_memory ();
goto retry_get_property;
@@ -1037,7 +1037,7 @@ check_get_connection_unix_user (BusContext *context,
else
{
_dbus_assert (dbus_error_is_set (&error));
- _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetProperty\n");
+ _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
goto out;
}
}
@@ -1056,6 +1056,159 @@ check_get_connection_unix_user (BusContext *context,
return retval;
}
+
+/* returns TRUE if the correct thing happens,
+ * but the correct thing may include OOM errors.
+ */
+static dbus_bool_t
+check_get_connection_unix_process_id (BusContext *context,
+ DBusConnection *connection)
+{
+ DBusMessage *message;
+ dbus_uint32_t serial;
+ dbus_bool_t retval;
+ DBusError error;
+ const char *base_service_name;
+ dbus_uint32_t pid;
+
+ retval = FALSE;
+ dbus_error_init (&error);
+ message = NULL;
+
+ _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection);
+
+ message = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "GetConnectionUnixProcessID");
+
+ if (message == NULL)
+ return TRUE;
+
+ base_service_name = dbus_bus_get_base_service (connection);
+
+ if (!dbus_message_append_args (message,
+ DBUS_TYPE_STRING, base_service_name,
+ DBUS_TYPE_INVALID))
+ {
+ dbus_message_unref (message);
+ return TRUE;
+ }
+
+ if (!dbus_connection_send (connection, message, &serial))
+ {
+ dbus_message_unref (message);
+ return TRUE;
+ }
+
+ /* send our message */
+ bus_test_run_clients_loop (TRUE);
+
+ dbus_message_unref (message);
+ message = NULL;
+
+ dbus_connection_ref (connection); /* because we may get disconnected */
+ block_connection_until_message_from_bus (context, connection);
+
+ if (!dbus_connection_get_is_connected (connection))
+ {
+ _dbus_verbose ("connection was disconnected\n");
+
+ dbus_connection_unref (connection);
+
+ return TRUE;
+ }
+
+ dbus_connection_unref (connection);
+
+ message = pop_message_waiting_for_memory (connection);
+ if (message == NULL)
+ {
+ _dbus_warn ("Did not receive a reply to %s %d on %p\n",
+ "GetConnectionUnixProcessID", serial, connection);
+ goto out;
+ }
+
+ verbose_message_received (connection, message);
+
+ if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
+ {
+ if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
+ {
+ ; /* good, this is a valid response */
+ }
+ else
+ {
+ warn_unexpected (connection, message, "not this error");
+
+ goto out;
+ }
+ }
+ else
+ {
+ if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
+ {
+ ; /* good, expected */
+ }
+ else
+ {
+ warn_unexpected (connection, message,
+ "method_return for GetConnectionUnixProcessID");
+
+ goto out;
+ }
+
+ retry_get_property:
+
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_UINT32, &pid,
+ DBUS_TYPE_INVALID))
+ {
+ if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
+ {
+ _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n");
+ dbus_error_free (&error);
+ _dbus_wait_for_memory ();
+ goto retry_get_property;
+ }
+ else
+ {
+ _dbus_assert (dbus_error_is_set (&error));
+ _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
+ goto out;
+ }
+ } else {
+
+ /* test if returned pid is the same as our own pid
+ *
+ * @todo It would probably be good to restructure the tests
+ * in a way so our parent is the bus that we're testing
+ * cause then we can test that the pid returned matches
+ * getppid()
+ */
+ if (pid != (dbus_uint32_t) _dbus_getpid ())
+ {
+ _dbus_assert (dbus_error_is_set (&error));
+ _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
+ goto out;
+ }
+ }
+ }
+
+ if (!check_no_leftovers (context))
+ goto out;
+
+ retval = TRUE;
+
+ out:
+ dbus_error_free (&error);
+
+ if (message)
+ dbus_message_unref (message);
+
+ return retval;
+}
+
/* returns TRUE if the correct thing happens,
* but the correct thing may include OOM errors.
*/
@@ -2787,6 +2940,12 @@ bus_dispatch_test (const DBusString *test_data_dir)
if (!check_add_match_all (context, baz))
_dbus_assert_not_reached ("AddMatch message failed");
+
+ if (!check_get_connection_unix_user (context, baz))
+ _dbus_assert_not_reached ("GetConnectionUnixUser message failed");
+
+ if (!check_get_connection_unix_process_id (context, baz))
+ _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed");
if (!check_no_leftovers (context))
{
diff --git a/bus/driver.c b/bus/driver.c
index 84e1d6b6..a0d433f0 100644
--- a/bus/driver.c
+++ b/bus/driver.c
@@ -907,6 +907,83 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
}
static dbus_bool_t
+bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection,
+ BusTransaction *transaction,
+ DBusMessage *message,
+ DBusError *error)
+{
+ char *service;
+ DBusString str;
+ BusRegistry *registry;
+ BusService *serv;
+ DBusConnection *conn;
+ DBusMessage *reply;
+ unsigned long pid;
+ const char *base_name;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ registry = bus_connection_get_registry (connection);
+
+ service = NULL;
+ reply = NULL;
+
+ if (! dbus_message_get_args (message, error,
+ DBUS_TYPE_STRING, &service,
+ DBUS_TYPE_INVALID))
+ goto failed;
+
+ _dbus_verbose ("asked for PID of connection %s\n", service);
+
+ _dbus_string_init_const (&str, service);
+ serv = bus_registry_lookup (registry, &str);
+ if (serv == NULL)
+ {
+ dbus_set_error (error,
+ DBUS_ERROR_SERVICE_HAS_NO_OWNER,
+ "Could not get owner of service '%s': no such service", service);
+ goto failed;
+ }
+
+ conn = bus_service_get_primary_owner (serv);
+
+ reply = dbus_message_new_method_return (message);
+ if (reply == NULL)
+ goto oom;
+
+ if (!dbus_connection_get_unix_process_id (conn, &pid))
+ {
+ dbus_set_error (error,
+ DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,
+ "Could not determine PID for '%s'", service);
+ goto failed;
+ }
+
+ if (! dbus_message_append_args (reply,
+ DBUS_TYPE_UINT32, (dbus_uint32_t) pid,
+ DBUS_TYPE_INVALID))
+ goto oom;
+
+ if (! bus_transaction_send_from_driver (transaction, connection, reply))
+ goto oom;
+
+ dbus_message_unref (reply);
+ dbus_free (service);
+
+ return TRUE;
+
+ oom:
+ BUS_SET_OOM (error);
+
+ failed:
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ if (reply)
+ dbus_message_unref (reply);
+ dbus_free (service);
+ return FALSE;
+}
+
+static dbus_bool_t
bus_driver_handle_reload_config (DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *message,
@@ -953,6 +1030,7 @@ struct
{ "RemoveMatch", bus_driver_handle_remove_match },
{ "GetServiceOwner", bus_driver_handle_get_service_owner },
{ "GetConnectionUnixUser", bus_driver_handle_get_connection_unix_user },
+ { "GetConnectionUnixProcessID", bus_driver_handle_get_connection_unix_process_id },
{ "ReloadConfig", bus_driver_handle_reload_config }
};
diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c
index 83dfc8a7..ee3b878d 100644
--- a/dbus/dbus-auth.c
+++ b/dbus/dbus-auth.c
@@ -1048,9 +1048,9 @@ handle_server_data_external_mech (DBusAuth *auth,
DBUS_AUTH_NAME (auth),
auth->desired_identity.uid,
auth->credentials.uid);
-
+
+ auth->authorized_identity.pid = auth->credentials.pid;
auth->authorized_identity.uid = auth->desired_identity.uid;
-
return TRUE;
}
else
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index d68c3958..58ab7900 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -2985,6 +2985,37 @@ dbus_connection_get_unix_user (DBusConnection *connection,
}
/**
+ * Gets the process ID of the connection if any.
+ * Returns #TRUE if the uid is filled in.
+ * Always returns #FALSE prior to authenticating the
+ * connection.
+ *
+ * @param connection the connection
+ * @param pid return location for the process ID
+ * @returns #TRUE if uid is filled in with a valid process ID
+ */
+dbus_bool_t
+dbus_connection_get_unix_process_id (DBusConnection *connection,
+ unsigned long *pid)
+{
+ dbus_bool_t result;
+
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+ _dbus_return_val_if_fail (pid != NULL, FALSE);
+
+ CONNECTION_LOCK (connection);
+
+ if (!_dbus_transport_get_is_authenticated (connection->transport))
+ result = FALSE;
+ else
+ result = _dbus_transport_get_unix_process_id (connection->transport,
+ pid);
+ CONNECTION_UNLOCK (connection);
+
+ return result;
+}
+
+/**
* Sets a predicate function used to determine whether a given user ID
* is allowed to connect. When an incoming connection has
* authenticated with a particular user ID, this function is called;
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index fb6dfbcd..12de0c05 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -138,6 +138,8 @@ void dbus_connection_set_dispatch_status_function (DBusConnection
DBusFreeFunction free_data_function);
dbus_bool_t dbus_connection_get_unix_user (DBusConnection *connection,
unsigned long *uid);
+dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection *connection,
+ unsigned long *pid);
void dbus_connection_set_unix_user_function (DBusConnection *connection,
DBusAllowUnixUserFunction function,
void *data,
diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h
index c30339c9..00c3ba7d 100644
--- a/dbus/dbus-protocol.h
+++ b/dbus/dbus-protocol.h
@@ -154,6 +154,7 @@ extern "C" {
#define DBUS_ERROR_SPAWN_CHILD_EXITED "org.freedesktop.DBus.Error.Spawn.ChildExited"
#define DBUS_ERROR_SPAWN_CHILD_SIGNALED "org.freedesktop.DBus.Error.Spawn.ChildSignaled"
#define DBUS_ERROR_SPAWN_FAILED "org.freedesktop.DBus.Error.Spawn.Failed"
+#define DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown"
#ifdef __cplusplus
}
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index 371ecbfb..ada960d4 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -938,6 +938,38 @@ _dbus_transport_get_unix_user (DBusTransport *transport,
}
/**
+ * See dbus_connection_get_unix_process_id().
+ *
+ * @param transport the transport
+ * @param pid return location for the process ID
+ * @returns #TRUE if uid is filled in with a valid process ID
+ */
+dbus_bool_t
+_dbus_transport_get_unix_process_id (DBusTransport *transport,
+ unsigned long *pid)
+{
+ DBusCredentials auth_identity;
+
+ *pid = DBUS_PID_UNSET; /* Caller should never use this value on purpose,
+ * but we set it to a safe number, INT_MAX,
+ * just to root out possible bugs in bad callers.
+ */
+
+ if (!transport->authenticated)
+ return FALSE;
+
+ _dbus_auth_get_identity (transport->auth, &auth_identity);
+
+ if (auth_identity.pid != DBUS_PID_UNSET)
+ {
+ *pid = auth_identity.pid;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/**
* See dbus_connection_set_unix_user_function().
*
* @param transport the transport
diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h
index 2c17c2a1..b6c7a4ec 100644
--- a/dbus/dbus-transport.h
+++ b/dbus/dbus-transport.h
@@ -59,6 +59,8 @@ void _dbus_transport_set_max_received_size (DBusTransport
long _dbus_transport_get_max_received_size (DBusTransport *transport);
dbus_bool_t _dbus_transport_get_unix_user (DBusTransport *transport,
unsigned long *uid);
+dbus_bool_t _dbus_transport_get_unix_process_id (DBusTransport *transport,
+ unsigned long *pid);
void _dbus_transport_set_unix_user_function (DBusTransport *transport,
DBusAllowUnixUserFunction function,
void *data,