Commit c9c0adce authored by David Zeuthen's avatar David Zeuthen
Browse files

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
parent dcbc92bf
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
......
......@@ -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))
{
......
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment