diff options
| author | David Zeuthen <davidz@redhat.com> | 2004-07-19 20:55:58 +0000 | 
|---|---|---|
| committer | David Zeuthen <davidz@redhat.com> | 2004-07-19 20:55:58 +0000 | 
| commit | c9c0adce43caa00345ad2aeb55822eabde523c2c (patch) | |
| tree | 0fcc4a4b7f5f453781b654a689efb84277fea9e5 | |
| parent | dcbc92bfeb600efb7244f80247655f004cb558b2 (diff) | |
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-- | ChangeLog | 32 | ||||
| -rw-r--r-- | bus/dispatch.c | 163 | ||||
| -rw-r--r-- | bus/driver.c | 78 | ||||
| -rw-r--r-- | dbus/dbus-auth.c | 4 | ||||
| -rw-r--r-- | dbus/dbus-connection.c | 31 | ||||
| -rw-r--r-- | dbus/dbus-connection.h | 2 | ||||
| -rw-r--r-- | dbus/dbus-protocol.h | 1 | ||||
| -rw-r--r-- | dbus/dbus-transport.c | 32 | ||||
| -rw-r--r-- | dbus/dbus-transport.h | 2 | 
9 files changed, 341 insertions, 4 deletions
| @@ -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, | 
