mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-01-06 09:30:15 +01:00
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
This commit is contained in:
parent
dcbc92bfeb
commit
c9c0adce43
9 changed files with 341 additions and 4 deletions
32
ChangeLog
32
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
|
||||
|
|
|
|||
163
bus/dispatch.c
163
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))
|
||||
{
|
||||
|
|
|
|||
78
bus/driver.c
78
bus/driver.c
|
|
@ -906,6 +906,83 @@ bus_driver_handle_get_connection_unix_user (DBusConnection *connection,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -2984,6 +2984,37 @@ dbus_connection_get_unix_user (DBusConnection *connection,
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -937,6 +937,38 @@ _dbus_transport_get_unix_user (DBusTransport *transport,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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().
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue