diff options
| author | Havoc Pennington <hp@redhat.com> | 2003-04-14 02:29:21 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2003-04-14 02:29:21 +0000 | 
| commit | 777707ed8dff6958972a93894a87ec1945c65c14 (patch) | |
| tree | 4ade9d56eccc5280150968e692a389e8749ed029 | |
| parent | 8aabca8dd28a113712389be51e75ea8c2fd17838 (diff) | |
2003-04-13  Havoc Pennington  <hp@pobox.com>
	* dbus/dbus-mainloop.c: fix some reentrancy issues by refcounting
	callbacks
	* test/data/valid-config-files/debug-allow-all.conf.in: allow all
	users
	* dbus/dbus-transport.c (_dbus_transport_get_dispatch_status):
	fix to only recover unused bytes if we're already authenticated
	(_dbus_transport_get_is_authenticated): fix to still mark us
	authenticated if there are unused bytes.
	* bus/dispatch.c: implement security policy checking
	* bus/connection.c (bus_transaction_send_from_driver): new
	* bus/bus.c (bus_context_check_security_policy): new
	* bus/dispatch.c (send_service_nonexistent_error): delete this,
	now we just set the DBusError and it gets converted to an error
	reply.
	* bus/connection.c (allow_user_function): enable code using actual
	data from the config file
	* bus/policy.c (list_allows_user): handle wildcard rules for
	user/group connection perms
| -rw-r--r-- | ChangeLog | 29 | ||||
| -rw-r--r-- | bus/activation.c | 18 | ||||
| -rw-r--r-- | bus/bus.c | 63 | ||||
| -rw-r--r-- | bus/bus.h | 5 | ||||
| -rw-r--r-- | bus/config-parser.c | 14 | ||||
| -rw-r--r-- | bus/connection.c | 40 | ||||
| -rw-r--r-- | bus/connection.h | 5 | ||||
| -rw-r--r-- | bus/dispatch.c | 152 | ||||
| -rw-r--r-- | bus/dispatch.h | 1 | ||||
| -rw-r--r-- | bus/driver.c | 55 | ||||
| -rw-r--r-- | bus/policy.c | 100 | ||||
| -rw-r--r-- | bus/policy.h | 4 | ||||
| -rw-r--r-- | bus/session.conf.in | 1 | ||||
| -rw-r--r-- | bus/system.conf.in | 2 | ||||
| -rw-r--r-- | dbus/dbus-connection.c | 4 | ||||
| -rw-r--r-- | dbus/dbus-mainloop.c | 65 | ||||
| -rw-r--r-- | dbus/dbus-message.c | 2 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.c | 75 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps.h | 3 | ||||
| -rw-r--r-- | dbus/dbus-transport-protected.h | 1 | ||||
| -rw-r--r-- | dbus/dbus-transport.c | 38 | ||||
| -rw-r--r-- | doc/TODO | 4 | ||||
| -rw-r--r-- | test/data/valid-config-files/debug-allow-all.conf.in | 1 | 
23 files changed, 425 insertions, 257 deletions
| @@ -1,5 +1,34 @@  2003-04-13  Havoc Pennington  <hp@pobox.com> +	* dbus/dbus-mainloop.c: fix some reentrancy issues by refcounting  +	callbacks + +	* test/data/valid-config-files/debug-allow-all.conf.in: allow all +	users + +	* dbus/dbus-transport.c (_dbus_transport_get_dispatch_status): +	fix to only recover unused bytes if we're already authenticated +	(_dbus_transport_get_is_authenticated): fix to still mark us  +	authenticated if there are unused bytes. + +	* bus/dispatch.c: implement security policy checking +	 +	* bus/connection.c (bus_transaction_send_from_driver): new + +	* bus/bus.c (bus_context_check_security_policy): new + +	* bus/dispatch.c (send_service_nonexistent_error): delete this, +	now we just set the DBusError and it gets converted to an error +	reply. + +	* bus/connection.c (allow_user_function): enable code using actual +	data from the config file + +	* bus/policy.c (list_allows_user): handle wildcard rules for +	user/group connection perms + +2003-04-13  Havoc Pennington  <hp@pobox.com> +  	* bus/config-parser.c: Load up the BusPolicy and BusPolicyRules  	* dbus/dbus-sysdeps.c (_dbus_get_user_id): new function diff --git a/bus/activation.c b/bus/activation.c index 1a448a79..0a70d6b1 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -582,8 +582,7 @@ bus_activation_service_created (BusActivation  *activation,  	      goto error;  	    } -	  if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) || -              !dbus_message_append_args (message, +	  if (!dbus_message_append_args (message,  					 DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ACTIVATED,  					 0))  	    { @@ -592,7 +591,7 @@ bus_activation_service_created (BusActivation  *activation,  	      goto error;  	    } -	  if (!bus_transaction_send_message (transaction, entry->connection, message)) +	  if (!bus_transaction_send_from_driver (transaction, entry->connection, message))  	    {  	      dbus_message_unref (message);  	      BUS_SET_OOM (error); @@ -654,14 +653,8 @@ try_send_activation_failure (BusPendingActivation *pending_activation,                                                    how->message);  	  if (!message)              goto error; - -	  if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) -            { -	      dbus_message_unref (message); -	      goto error; -	    } -	  if (!bus_transaction_send_message (transaction, entry->connection, message)) +	  if (!bus_transaction_send_from_driver (transaction, entry->connection, message))  	    {  	      dbus_message_unref (message);  	      goto error; @@ -861,8 +854,7 @@ bus_activation_activate_service (BusActivation  *activation,  	  return FALSE;  	} -      if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS) || -          !dbus_message_append_args (message, +      if (!dbus_message_append_args (message,  				     DBUS_TYPE_UINT32, DBUS_ACTIVATION_REPLY_ALREADY_ACTIVE,   				     0))  	{ @@ -872,7 +864,7 @@ bus_activation_activate_service (BusActivation  *activation,  	  return FALSE;  	} -      retval = bus_transaction_send_message (transaction, connection, message); +      retval = bus_transaction_send_from_driver (transaction, connection, message);        dbus_message_unref (message);        if (!retval)          { @@ -796,3 +796,66 @@ bus_context_get_activation_timeout (BusContext *context)    return context->activation_timeout;  } + +dbus_bool_t +bus_context_check_security_policy (BusContext     *context, +                                   DBusConnection *sender, +                                   DBusConnection *recipient, +                                   DBusMessage    *message, +                                   DBusError      *error) +{ +  BusClientPolicy *sender_policy; +  BusClientPolicy *recipient_policy; + +  /* NULL sender/receiver means the bus driver */ +   +  if (sender != NULL) +    { +      _dbus_assert (dbus_connection_get_is_authenticated (sender)); +      sender_policy = bus_connection_get_policy (sender); +    } +  else +    sender_policy = NULL; + +  if (recipient != NULL) +    { +      _dbus_assert (dbus_connection_get_is_authenticated (recipient)); +      recipient_policy = bus_connection_get_policy (recipient); +    } +  else +    recipient_policy = NULL; + +  if (sender_policy && +      !bus_client_policy_check_can_send (sender_policy, +                                         context->registry, recipient, +                                         message)) +    { +      const char *dest = dbus_message_get_service (message); +      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, +                      "A security policy in place prevents this sender " +                      "from sending this message to this recipient, " +                      "see message bus configuration file (rejected message " +                      "had name \"%s\" destination \"%s\")", +                      dbus_message_get_name (message), +                      dest ? dest : DBUS_SERVICE_DBUS); +      return FALSE; +    } + +  if (recipient_policy && +      !bus_client_policy_check_can_receive (recipient_policy, +                                            context->registry, sender, +                                            message)) +    { +      const char *dest = dbus_message_get_service (message); +      dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, +                      "A security policy in place prevents this recipient " +                      "from receiving this message from this sender, " +                      "see message bus configuration file (rejected message " +                      "had name \"%s\" destination \"%s\")", +                      dbus_message_get_name (message), +                      dest ? dest : DBUS_SERVICE_DBUS); +      return FALSE; +    } + +  return TRUE; +} @@ -57,6 +57,11 @@ dbus_bool_t      bus_context_allow_user             (BusContext       *context,  BusClientPolicy* bus_context_create_client_policy   (BusContext       *context,                                                       DBusConnection   *connection);  int              bus_context_get_activation_timeout (BusContext       *context); +dbus_bool_t      bus_context_check_security_policy  (BusContext       *context, +                                                     DBusConnection   *sender, +                                                     DBusConnection   *recipient, +                                                     DBusMessage      *message, +                                                     DBusError        *error);  #endif /* BUS_BUS_H */ diff --git a/bus/config-parser.c b/bus/config-parser.c index 85c367b3..bf959ae2 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -859,7 +859,7 @@ append_rule_from_element (BusConfigParser   *parser,            if (rule == NULL)              goto nomem; -          /* FIXME the wildcard needs storing in the rule somehow */ +          rule->d.user.uid = DBUS_UID_UNSET;          }        else          { @@ -873,10 +873,7 @@ append_rule_from_element (BusConfigParser   *parser,                rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow);                 if (rule == NULL)                  goto nomem; -               -              rule->d.user.user = _dbus_strdup (user); -              if (rule->d.user.user == NULL) -                goto nomem; +                rule->d.user.uid = uid;              }            else @@ -894,7 +891,7 @@ append_rule_from_element (BusConfigParser   *parser,            if (rule == NULL)              goto nomem; -          /* FIXME the wildcard needs storing in the rule somehow */ +          rule->d.group.gid = DBUS_GID_UNSET;          }        else          { @@ -908,10 +905,7 @@ append_rule_from_element (BusConfigParser   *parser,                rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow);                 if (rule == NULL)                  goto nomem; -               -              rule->d.group.group = _dbus_strdup (group); -              if (rule->d.group.group == NULL) -                goto nomem; +                rule->d.group.gid = gid;              }            else diff --git a/bus/connection.c b/bus/connection.c index 21c8f1a3..4c48fbd6 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -283,8 +283,6 @@ allow_user_function (DBusConnection *connection,    d = BUS_CONNECTION_DATA (connection);    _dbus_assert (d != NULL); - -  return TRUE; /* FIXME - this is just until we can parse a config file */    return bus_context_allow_user (d->connections->context, uid);  } @@ -504,7 +502,7 @@ bus_connection_get_groups  (DBusConnection       *connection,        if (dbus_connection_get_unix_user (connection, &uid))          { -          if (!_dbus_get_groups (uid, &d->group_ids, &d->n_group_ids)) +          if (!_dbus_get_groups (uid, &d->group_ids, &d->n_group_ids, NULL))              {                _dbus_verbose ("Did not get any groups for UID %lu\n",                               uid); @@ -924,9 +922,34 @@ bus_transaction_get_connections (BusTransaction  *transaction)  }  dbus_bool_t -bus_transaction_send_message (BusTransaction *transaction, -                              DBusConnection *connection, -                              DBusMessage    *message) +bus_transaction_send_from_driver (BusTransaction *transaction, +                                  DBusConnection *connection, +                                  DBusMessage    *message) +{ +  /* We have to set the sender to the driver, and have +   * to check security policy since it was not done in +   * dispatch.c +   */ +  _dbus_verbose ("Sending %s from driver\n", +                 dbus_message_get_name (message)); +   +  if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) +    return FALSE; + +  /* If security policy doesn't allow the message, we silently +   * eat it; the driver doesn't care about getting a reply. +   */ +  if (!bus_context_check_security_policy (bus_transaction_get_context (transaction), +                                          NULL, connection, message, NULL)) +    return TRUE; + +  return bus_transaction_send (transaction, connection, message); +} + +dbus_bool_t +bus_transaction_send (BusTransaction *transaction, +                      DBusConnection *connection, +                      DBusMessage    *message)  {    MessageToSend *to_send;    BusConnectionData *d; @@ -934,7 +957,7 @@ bus_transaction_send_message (BusTransaction *transaction,    _dbus_verbose ("  trying to add %s %s to transaction%s\n",                   dbus_message_get_is_error (message) ? "error" : -                 dbus_message_get_reply_serial (message) != 0 ? "reply" : +                 dbus_message_get_reply_serial (message) != -1 ? "reply" :                   "message",                   dbus_message_get_name (message),                   dbus_connection_get_is_connected (connection) ? @@ -1152,8 +1175,7 @@ bus_transaction_send_error_reply (BusTransaction  *transaction,    if (reply == NULL)      return FALSE; -  if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS) || -      !bus_transaction_send_message (transaction, connection, reply)) +  if (!bus_transaction_send_from_driver (transaction, connection, reply))      {        dbus_message_unref (reply);        return FALSE; diff --git a/bus/connection.h b/bus/connection.h index 4962211e..ead47673 100644 --- a/bus/connection.h +++ b/bus/connection.h @@ -84,7 +84,10 @@ typedef void (* BusTransactionCancelFunction) (void *data);  BusTransaction* bus_transaction_new              (BusContext                   *context);  BusContext*     bus_transaction_get_context      (BusTransaction               *transaction);  BusConnections* bus_transaction_get_connections  (BusTransaction               *transaction); -dbus_bool_t     bus_transaction_send_message     (BusTransaction               *transaction, +dbus_bool_t     bus_transaction_send             (BusTransaction               *transaction, +                                                  DBusConnection               *connection, +                                                  DBusMessage                  *message); +dbus_bool_t     bus_transaction_send_from_driver (BusTransaction               *transaction,                                                    DBusConnection               *connection,                                                    DBusMessage                  *message);  dbus_bool_t     bus_transaction_send_error_reply (BusTransaction               *transaction, diff --git a/bus/dispatch.c b/bus/dispatch.c index 41317549..3ce7731c 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -37,6 +37,8 @@ static int message_handler_slot_refcount;  typedef struct  { +  BusContext     *context; +  DBusConnection *sender;    DBusMessage    *message;    BusTransaction *transaction;    DBusError      *error; @@ -50,9 +52,16 @@ send_one_message (DBusConnection *connection, void *data)    if (!bus_connection_is_active (connection))      return TRUE; -  if (!bus_transaction_send_message (d->transaction, -                                     connection, -                                     d->message)) +  if (!bus_context_check_security_policy (d->context, +                                          d->sender, +                                          connection, +                                          d->message, +                                          NULL)) +    return TRUE; /* silently don't send it */ +   +  if (!bus_transaction_send (d->transaction, +                             connection, +                             d->message))      {        BUS_SET_OOM (d->error);        return FALSE; @@ -63,6 +72,7 @@ send_one_message (DBusConnection *connection, void *data)  dbus_bool_t  bus_dispatch_broadcast_message (BusTransaction *transaction, +                                DBusConnection *sender,                                  DBusMessage    *message,                                  DBusError      *error)  { @@ -77,6 +87,8 @@ bus_dispatch_broadcast_message (BusTransaction *transaction,    connections = bus_transaction_get_connections (transaction);    dbus_error_init (&tmp_error); +  d.sender = sender; +  d.context = bus_transaction_get_context (transaction);    d.message = message;    d.transaction = transaction;    d.error = &tmp_error; @@ -92,70 +104,6 @@ bus_dispatch_broadcast_message (BusTransaction *transaction,      return TRUE;  } -static dbus_bool_t -send_service_nonexistent_error (BusTransaction *transaction, -                                DBusConnection *connection, -                                const char     *service_name, -                                DBusMessage    *in_reply_to, -                                DBusError      *error) -{ -  DBusMessage *error_reply; -  DBusString error_message; -  const char *error_str; - -  _DBUS_ASSERT_ERROR_IS_CLEAR (error); -   -  /* Trying to send a message to a non-existant service, -   * bounce back an error message. -   */ -	   -  if (!_dbus_string_init (&error_message)) -    { -      BUS_SET_OOM (error); -      return FALSE; -    } - -  if (!_dbus_string_append (&error_message, "Service \"") || -      !_dbus_string_append (&error_message, service_name) || -      !_dbus_string_append (&error_message, "\" does not exist")) -    { -      _dbus_string_free (&error_message); -      BUS_SET_OOM (error); -      return FALSE; -    } -               -  error_str = _dbus_string_get_const_data (&error_message); -  error_reply = dbus_message_new_error_reply (in_reply_to, -                                              DBUS_ERROR_SERVICE_DOES_NOT_EXIST, -                                              error_str); - -  _dbus_string_free (&error_message); -               -  if (error_reply == NULL) -    { -      BUS_SET_OOM (error); -      return FALSE; -    } - -  if (!dbus_message_set_sender (error_reply, DBUS_SERVICE_DBUS)) -    { -      dbus_message_unref (error_reply); -      BUS_SET_OOM (error); -      return FALSE; -    }       -   -  if (!bus_transaction_send_message (transaction, connection, error_reply)) -    { -      dbus_message_unref (error_reply); -      BUS_SET_OOM (error); -      return FALSE; -    } -               -  dbus_message_unref (error_reply); - -  return TRUE; -} -  static void  bus_dispatch (DBusConnection *connection,                DBusMessage    *message) @@ -188,9 +136,10 @@ bus_dispatch (DBusConnection *connection,    _dbus_verbose ("DISPATCH: %s to %s\n",                   message_name, service_name ? service_name : "peer"); -  /* If service_name is NULL, this is a message to the bus daemon, not intended -   * to actually go "on the bus"; e.g. a peer-to-peer ping. Handle these -   * immediately, especially disconnection messages. +  /* If service_name is NULL, this is a message to the bus daemon, not +   * intended to actually go "on the bus"; e.g. a peer-to-peer +   * ping. Handle these immediately, especially disconnection +   * messages. There are no security policy checks on these.     */    if (service_name == NULL)      {       @@ -235,6 +184,10 @@ bus_dispatch (DBusConnection *connection,    if (strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */      { +      if (!bus_context_check_security_policy (context, +                                              connection, NULL, message, &error)) +        goto out; +              if (!bus_driver_handle_message (connection, transaction, message, &error))        	goto out;      } @@ -249,7 +202,7 @@ bus_dispatch (DBusConnection *connection,     */    else if (strcmp (service_name, DBUS_SERVICE_BROADCAST) == 0) /* spam! */      { -      if (!bus_dispatch_broadcast_message (transaction, message, &error)) +      if (!bus_dispatch_broadcast_message (transaction, connection, message, &error))          goto out;      }    else  /* route to named service */ @@ -265,19 +218,25 @@ bus_dispatch (DBusConnection *connection,        if (service == NULL)          { -          if (!send_service_nonexistent_error (transaction, connection, -                                               service_name, -                                               message, &error)) -            goto out; +          dbus_set_error (&error, +                          DBUS_ERROR_SERVICE_DOES_NOT_EXIST, +                          "Service \"%s\" does not exist", +                          service_name); +          goto out;          }        else          { -          _dbus_assert (bus_service_get_primary_owner (service) != NULL); -       +          DBusConnection *recipient; +           +          recipient = bus_service_get_primary_owner (service); +          _dbus_assert (recipient != NULL); +           +          if (!bus_context_check_security_policy (context, +                                                  connection, recipient, message, &error)) +            goto out; +                      /* Dispatch the message */ -          if (!bus_transaction_send_message (transaction, -                                             bus_service_get_primary_owner (service), -                                             message)) +          if (!bus_transaction_send (transaction, recipient, message))              {                BUS_SET_OOM (&error);                goto out; @@ -316,7 +275,7 @@ bus_dispatch (DBusConnection *connection,                                                   &error, message))              {                bus_connection_send_oom_error (connection, message); - +                              /* cancel transaction due to OOM */                if (transaction != NULL)                  { @@ -608,8 +567,9 @@ kill_client_connection_unchecked (DBusConnection *connection)    /* dispatching disconnect handler will unref once */    if (bus_connection_dispatch_one_message (connection))      _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register"); -  dbus_connection_unref (connection); +    _dbus_assert (!bus_test_client_listed (connection)); +  dbus_connection_unref (connection);  }  typedef struct @@ -740,10 +700,12 @@ check_hello_message (BusContext     *context,    DBusError error;    char *name;    char *acquired; -   + +  retval = FALSE;    dbus_error_init (&error);    name = NULL;    acquired = NULL; +  message = NULL;    message = dbus_message_new (DBUS_SERVICE_DBUS,  			      DBUS_MESSAGE_HELLO); @@ -760,15 +722,22 @@ check_hello_message (BusContext     *context,    dbus_message_unref (message);    message = NULL; -  bus_test_run_everything (context); +  /* send our message */ +  bus_test_run_clients_loop (TRUE); + +  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;      } -   -  retval = FALSE; + +  dbus_connection_unref (connection);    message = pop_message_waiting_for_memory (connection);    if (message == NULL) @@ -1390,7 +1359,10 @@ check_send_exit_to_service (BusContext     *context,    message = dbus_connection_borrow_message (connection);    got_error = message != NULL && dbus_message_get_is_error (message);    if (message) -    dbus_connection_return_message (connection, message); +    { +      dbus_connection_return_message (connection, message); +      message = NULL; +    }    if (!got_error)      { @@ -1944,6 +1916,12 @@ bus_dispatch_test (const DBusString *test_data_dir)    if (!check_hello_message (context, baz))      _dbus_assert_not_reached ("hello message failed"); +  if (!check_no_leftovers (context)) +    { +      _dbus_warn ("Messages were left over after setting up initial connections"); +      _dbus_assert_not_reached ("initial connection setup failed"); +    } +      check1_try_iterations (context, "create_and_hello",                           check_hello_connection); diff --git a/bus/dispatch.h b/bus/dispatch.h index c24170dc..18f74529 100644 --- a/bus/dispatch.h +++ b/bus/dispatch.h @@ -30,6 +30,7 @@  dbus_bool_t bus_dispatch_add_connection    (DBusConnection *connection);  void        bus_dispatch_remove_connection (DBusConnection *connection);  dbus_bool_t bus_dispatch_broadcast_message (BusTransaction *transaction, +                                            DBusConnection *sender,                                              DBusMessage    *message,                                              DBusError      *error); diff --git a/bus/driver.c b/bus/driver.c index f89b70a3..c7d66d53 100644 --- a/bus/driver.c +++ b/bus/driver.c @@ -67,7 +67,7 @@ bus_driver_send_service_deleted (const char     *service_name,        return FALSE;      } -  retval = bus_dispatch_broadcast_message (transaction, message, error); +  retval = bus_dispatch_broadcast_message (transaction, NULL, message, error);    dbus_message_unref (message);    return retval; @@ -107,7 +107,7 @@ bus_driver_send_service_created (const char     *service_name,        return FALSE;      } -  retval = bus_dispatch_broadcast_message (transaction, message, error); +  retval = bus_dispatch_broadcast_message (transaction, NULL, message, error);    dbus_message_unref (message);    return retval; @@ -131,13 +131,6 @@ bus_driver_send_service_lost (DBusConnection *connection,        return FALSE;      } -  if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) -    { -      dbus_message_unref (message); -      BUS_SET_OOM (error); -      return FALSE; -    } -      if (!dbus_message_append_args (message,                                   DBUS_TYPE_STRING, service_name,                                   0)) @@ -147,7 +140,7 @@ bus_driver_send_service_lost (DBusConnection *connection,        return FALSE;      } -  if (!bus_transaction_send_message (transaction, connection, message)) +  if (!bus_transaction_send_from_driver (transaction, connection, message))      {        dbus_message_unref (message);        BUS_SET_OOM (error); @@ -178,13 +171,6 @@ bus_driver_send_service_acquired (DBusConnection *connection,        return FALSE;      } -  if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) -    { -      dbus_message_unref (message); -      BUS_SET_OOM (error); -      return FALSE; -    } -      if (!dbus_message_append_args (message,                                   DBUS_TYPE_STRING, service_name,                                   0)) @@ -194,7 +180,7 @@ bus_driver_send_service_acquired (DBusConnection *connection,        return FALSE;      } -  if (!bus_transaction_send_message (transaction, connection, message)) +  if (!bus_transaction_send_from_driver (transaction, connection, message))      {        dbus_message_unref (message);        BUS_SET_OOM (error); @@ -347,13 +333,6 @@ bus_driver_send_welcome_message (DBusConnection *connection,        return FALSE;      } -  if (!dbus_message_set_sender (welcome, DBUS_SERVICE_DBUS)) -    { -      dbus_message_unref (welcome); -      BUS_SET_OOM (error); -      return FALSE; -    } -      if (!dbus_message_append_args (welcome,                                   DBUS_TYPE_STRING, name,                                   NULL)) @@ -363,7 +342,7 @@ bus_driver_send_welcome_message (DBusConnection *connection,        return FALSE;      } -  if (!bus_transaction_send_message (transaction, connection, welcome)) +  if (!bus_transaction_send_from_driver (transaction, connection, welcome))      {        dbus_message_unref (welcome);        BUS_SET_OOM (error); @@ -417,7 +396,7 @@ bus_driver_handle_list_services (DBusConnection *connection,    dbus_free_string_array (services); -  if (!bus_transaction_send_message (transaction, connection, reply)) +  if (!bus_transaction_send_from_driver (transaction, connection, reply))      {        dbus_message_unref (reply);        BUS_SET_OOM (error); @@ -474,19 +453,13 @@ bus_driver_handle_acquire_service (DBusConnection *connection,        goto out;      } -  if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) -    { -      BUS_SET_OOM (error); -      goto out; -    } -    if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, service_reply, DBUS_TYPE_INVALID))      {        BUS_SET_OOM (error);        goto out;      } -  if (!bus_transaction_send_message (transaction, connection, reply)) +  if (!bus_transaction_send_from_driver (transaction, connection, reply))      {        BUS_SET_OOM (error);        goto out; @@ -534,12 +507,6 @@ bus_driver_handle_service_exists (DBusConnection *connection,        BUS_SET_OOM (error);        goto out;      } -   -  if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS)) -    { -      BUS_SET_OOM (error); -      goto out; -    }    if (!dbus_message_append_args (reply,                                   DBUS_TYPE_UINT32, service != NULL, @@ -549,7 +516,7 @@ bus_driver_handle_service_exists (DBusConnection *connection,        goto out;      } -  if (!bus_transaction_send_message (transaction, connection, reply)) +  if (!bus_transaction_send_from_driver (transaction, connection, reply))      {        BUS_SET_OOM (error);        goto out; @@ -653,6 +620,12 @@ bus_driver_handle_message (DBusConnection *connection,        return FALSE;      } +  if (dbus_message_get_reply_serial (message) != -1) +    { +      _dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n"); +      return TRUE; +    } +      i = 0;    while (i < _DBUS_N_ELEMENTS (message_handlers))      { diff --git a/bus/policy.c b/bus/policy.c index 81894b8b..ad0cfaef 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -73,7 +73,7 @@ bus_policy_rule_unref (BusPolicyRule *rule)    _dbus_assert (rule->refcount > 0);    rule->refcount -= 1; - +      if (rule->refcount == 0)      {        switch (rule->type) @@ -90,10 +90,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)            dbus_free (rule->d.own.service_name);            break;          case BUS_POLICY_RULE_USER: -          dbus_free (rule->d.user.user);            break;          case BUS_POLICY_RULE_GROUP: -          dbus_free (rule->d.group.group);            break;          } @@ -239,7 +237,6 @@ bus_policy_create_client_policy (BusPolicy      *policy,  {    BusClientPolicy *client;    unsigned long uid; -  DBusList **list;    _dbus_assert (dbus_connection_get_is_authenticated (connection)); @@ -266,6 +263,8 @@ bus_policy_create_client_policy (BusPolicy      *policy,        i = 0;        while (i < n_groups)          { +          DBusList **list; +                      list = _dbus_hash_table_lookup_ulong (policy->rules_by_gid,                                                  groups[i]); @@ -282,12 +281,20 @@ bus_policy_create_client_policy (BusPolicy      *policy,    if (!dbus_connection_get_unix_user (connection, &uid))      goto failed; -  list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid, -                                        uid); +  if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0) +    { +      DBusList **list; +       +      list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid, +                                            uid); + +      if (list != NULL) +        { +          if (!add_list_to_client (list, client)) +            goto failed; +        } +    } -  if (!add_list_to_client (list, client)) -    goto failed; -      if (!add_list_to_client (&policy->mandatory_rules,                             client))      goto failed; @@ -310,9 +317,6 @@ list_allows_user (dbus_bool_t           def,  {    DBusList *link;    dbus_bool_t allowed; - -  /* FIXME there's currently no handling of wildcard user/group rules. -   */    allowed = def; @@ -324,23 +328,36 @@ list_allows_user (dbus_bool_t           def,        if (rule->type == BUS_POLICY_RULE_USER)          { -          if (rule->d.user.uid != uid) +          _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n", +                         list, rule->d.user.uid); +           +          if (rule->d.user.uid == DBUS_UID_UNSET) +            ; /* '*' wildcard */ +          else if (rule->d.user.uid != uid)              continue;          }        else if (rule->type == BUS_POLICY_RULE_GROUP)          { -          int i; - -          i = 0; -          while (i < n_group_ids) +          _dbus_verbose ("List %p group rule uid="DBUS_UID_FORMAT"\n", +                         list, rule->d.user.uid); +           +          if (rule->d.group.gid == DBUS_GID_UNSET) +            ;  /* '*' wildcard */ +          else              { -              if (rule->d.group.gid == group_ids[i]) -                break; -              ++i; +              int i; +               +              i = 0; +              while (i < n_group_ids) +                { +                  if (rule->d.group.gid == group_ids[i]) +                    break; +                  ++i; +                } +               +              if (i == n_group_ids) +                continue;              } - -          if (i == n_group_ids) -            continue;          }        else          continue; @@ -360,7 +377,7 @@ bus_policy_allow_user (BusPolicy    *policy,    int n_group_ids;    /* On OOM or error we always reject the user */ -  if (!_dbus_get_groups (uid, &group_ids, &n_group_ids)) +  if (!_dbus_get_groups (uid, &group_ids, &n_group_ids, NULL))      {        _dbus_verbose ("Did not get any groups for UID %lu\n",                       uid); @@ -381,6 +398,8 @@ bus_policy_allow_user (BusPolicy    *policy,    dbus_free (group_ids); +  _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed); +      return allowed;  } @@ -536,15 +555,18 @@ remove_rules_by_type_up_to (BusClientPolicy   *policy,  {    DBusList *link; -  link = _dbus_list_get_first (&policy->rules); +  link = _dbus_list_get_first_link (&policy->rules);    while (link != up_to)      {        BusPolicyRule *rule = link->data;        DBusList *next = _dbus_list_get_next_link (&policy->rules, link); -      bus_policy_rule_unref (rule); -      _dbus_list_remove_link (&policy->rules, link); - +      if (rule->type == type) +        { +          _dbus_list_remove_link (&policy->rules, link); +          bus_policy_rule_unref (rule); +        } +              link = next;      }  } @@ -571,14 +593,19 @@ bus_client_policy_optimize (BusClientPolicy *policy)    _dbus_verbose ("Optimizing policy with %d rules\n",                   _dbus_list_get_length (&policy->rules)); -  link = _dbus_list_get_first (&policy->rules); +  link = _dbus_list_get_first_link (&policy->rules);    while (link != NULL)      { -      BusPolicyRule *rule = link->data; -      DBusList *next = _dbus_list_get_next_link (&policy->rules, link); +      BusPolicyRule *rule; +      DBusList *next;        dbus_bool_t remove_preceding; +      next = _dbus_list_get_next_link (&policy->rules, link); +      rule = link->data; +              remove_preceding = FALSE; + +      _dbus_assert (rule != NULL);        switch (rule->type)          { @@ -601,7 +628,7 @@ bus_client_policy_optimize (BusClientPolicy *policy)            _dbus_assert_not_reached ("invalid rule");            break;          } -                 +        if (remove_preceding)          remove_rules_by_type_up_to (policy, rule->type,                                      link); @@ -617,6 +644,9 @@ dbus_bool_t  bus_client_policy_append_rule (BusClientPolicy *policy,                                 BusPolicyRule   *rule)  { +  _dbus_verbose ("Appending rule %p with type %d to policy %p\n", +                 rule, rule->type, policy); +      if (!_dbus_list_append (&policy->rules, rule))      return FALSE; @@ -639,7 +669,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,     */    allowed = FALSE; -  link = _dbus_list_get_first (&policy->rules); +  link = _dbus_list_get_first_link (&policy->rules);    while (link != NULL)      {        BusPolicyRule *rule = link->data; @@ -711,7 +741,7 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,     */    allowed = FALSE; -  link = _dbus_list_get_first (&policy->rules); +  link = _dbus_list_get_first_link (&policy->rules);    while (link != NULL)      {        BusPolicyRule *rule = link->data; @@ -783,7 +813,7 @@ bus_client_policy_check_can_own (BusClientPolicy  *policy,     */    allowed = FALSE; -  link = _dbus_list_get_first (&policy->rules); +  link = _dbus_list_get_first_link (&policy->rules);    while (link != NULL)      {        BusPolicyRule *rule = link->data; diff --git a/bus/policy.h b/bus/policy.h index 986cfe07..53e30e77 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -74,13 +74,13 @@ struct BusPolicyRule      struct      { -      char *user; +      /* can be DBUS_UID_UNSET meaning "any" */        dbus_uid_t uid;      } user;      struct      { -      char *group; +      /* can be DBUS_GID_UNSET meaning "any" */        dbus_gid_t gid;      } group; diff --git a/bus/session.conf.in b/bus/session.conf.in index d430d990..4feca235 100644 --- a/bus/session.conf.in +++ b/bus/session.conf.in @@ -15,6 +15,7 @@      <allow send="*"/>      <allow receive="*"/>      <allow own="*"/> +    <allow user="*"/>      </policy>    <!-- This is included last so local configuration can override what's  diff --git a/bus/system.conf.in b/bus/system.conf.in index 0e570575..e65c4af1 100644 --- a/bus/system.conf.in +++ b/bus/system.conf.in @@ -34,6 +34,8 @@      <deny send="*"/>      <deny receive="*"/>      <deny own="*"/> +    <!-- But allow all users to connect --> +    <allow user="*"/>    </policy>    <!-- This is included last so local configuration can override what's  diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 9595f48a..94fe075c 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -2082,8 +2082,8 @@ dbus_connection_dispatch (DBusConnection *connection)          }      } -  _dbus_verbose ("  done dispatching %p (%s)\n", message, -                 dbus_message_get_name (message)); +  _dbus_verbose ("  done dispatching %p (%s) on connection %p\n", message, +                 dbus_message_get_name (message), connection);   out:    _dbus_connection_release_dispatch (connection); diff --git a/dbus/dbus-mainloop.c b/dbus/dbus-mainloop.c index bf011082..3c810f22 100644 --- a/dbus/dbus-mainloop.c +++ b/dbus/dbus-mainloop.c @@ -47,6 +47,7 @@ typedef enum  typedef struct  { +  int refcount;    CallbackType type;    void *data;    DBusFreeFunction free_data_func; @@ -74,10 +75,10 @@ typedef struct  #define TIMEOUT_CALLBACK(callback) ((TimeoutCallback*)callback)  static WatchCallback* -watch_callback_new (DBusWatch        *watch, +watch_callback_new (DBusWatch         *watch,                      DBusWatchFunction  function, -                    void             *data, -                    DBusFreeFunction  free_data_func) +                    void              *data, +                    DBusFreeFunction   free_data_func)  {    WatchCallback *cb; @@ -88,18 +89,19 @@ watch_callback_new (DBusWatch        *watch,    cb->watch = watch;    cb->function = function;    cb->last_iteration_oom = FALSE; +  cb->callback.refcount = 1;    cb->callback.type = CALLBACK_WATCH;    cb->callback.data = data;    cb->callback.free_data_func = free_data_func; - +      return cb;  }  static TimeoutCallback* -timeout_callback_new (DBusTimeout        *timeout, +timeout_callback_new (DBusTimeout         *timeout,                        DBusTimeoutFunction  function, -                      void               *data, -                      DBusFreeFunction    free_data_func) +                      void                *data, +                      DBusFreeFunction     free_data_func)  {    TimeoutCallback *cb; @@ -111,6 +113,7 @@ timeout_callback_new (DBusTimeout        *timeout,    cb->function = function;    _dbus_get_current_time (&cb->last_tv_sec,                            &cb->last_tv_usec); +  cb->callback.refcount = 1;        cb->callback.type = CALLBACK_TIMEOUT;    cb->callback.data = data;    cb->callback.free_data_func = free_data_func; @@ -119,12 +122,27 @@ timeout_callback_new (DBusTimeout        *timeout,  }  static void -callback_free (Callback *cb) +callback_ref (Callback *cb) +{ +  _dbus_assert (cb->refcount > 0); +   +  cb->refcount += 1; +} + +static void +callback_unref (Callback *cb)  { -  if (cb->free_data_func) -    (* cb->free_data_func) (cb->data); +  _dbus_assert (cb->refcount > 0); + +  cb->refcount -= 1; -  dbus_free (cb); +  if (cb->refcount == 0) +    { +      if (cb->free_data_func) +        (* cb->free_data_func) (cb->data); +       +      dbus_free (cb); +    }  }  static dbus_bool_t @@ -165,7 +183,7 @@ remove_callback (DBusLoop  *loop,        break;      } -  callback_free (cb); +  callback_unref (cb);    _dbus_list_remove_link (&loop->callbacks, link);    loop->callback_list_serial += 1;  } @@ -229,7 +247,7 @@ _dbus_loop_add_watch (DBusLoop          *loop,    if (!add_callback (loop, (Callback*) wcb))      {        wcb->callback.free_data_func = NULL; /* don't want to have this side effect */ -      callback_free ((Callback*) wcb); +      callback_unref ((Callback*) wcb);        return FALSE;      } @@ -283,7 +301,7 @@ _dbus_loop_add_timeout (DBusLoop            *loop,    if (!add_callback (loop, (Callback*) tcb))      {        tcb->callback.free_data_func = NULL; /* don't want to have this side effect */ -      callback_free ((Callback*) tcb); +      callback_unref ((Callback*) tcb);        return FALSE;      } @@ -490,6 +508,7 @@ _dbus_loop_iterate (DBusLoop     *loop,    fds = NULL;    watches_for_fds = NULL; +  n_fds = 0;    oom_watch_pending = FALSE;    orig_depth = loop->depth; @@ -578,6 +597,8 @@ _dbus_loop_iterate (DBusLoop     *loop,                else if (dbus_watch_get_enabled (wcb->watch))                  {                    watches_for_fds[i] = wcb; + +                  callback_ref (cb);                    flags = dbus_watch_get_flags (wcb->watch); @@ -726,7 +747,7 @@ _dbus_loop_iterate (DBusLoop     *loop,                unsigned int condition;                wcb = watches_for_fds[i]; -                   +                              condition = 0;                if (fds[i].revents & _DBUS_POLLIN)                  condition |= DBUS_WATCH_READABLE; @@ -765,8 +786,18 @@ _dbus_loop_iterate (DBusLoop     *loop,   next_iteration:    if (fds && fds != static_fds)      dbus_free (fds); -  if (watches_for_fds && watches_for_fds != static_watches_for_fds) -    dbus_free (watches_for_fds); +  if (watches_for_fds) +    { +      i = 0; +      while (i < n_fds) +        { +          callback_unref (&watches_for_fds[i]->callback); +          ++i; +        } +       +      if (watches_for_fds != static_watches_for_fds) +        dbus_free (watches_for_fds); +    }    if (_dbus_loop_dispatch (loop))      retval = TRUE; diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c index 0044913e..5e6a2c60 100644 --- a/dbus/dbus-message.c +++ b/dbus/dbus-message.c @@ -585,7 +585,7 @@ _dbus_message_set_serial (DBusMessage  *message,   */  dbus_bool_t  dbus_message_set_reply_serial (DBusMessage  *message, -                                dbus_int32_t  reply_serial) +                               dbus_int32_t  reply_serial)  {    _dbus_assert (!message->locked); diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c index f706d08a..0877a293 100644 --- a/dbus/dbus-sysdeps.c +++ b/dbus/dbus-sysdeps.c @@ -1315,7 +1315,8 @@ static dbus_bool_t  store_user_info (struct passwd    *p,                   DBusCredentials  *credentials,                   DBusString       *homedir, -                 DBusString       *username_out) +                 DBusString       *username_out, +                 DBusError        *error)  {    int old_homedir_len; @@ -1332,7 +1333,7 @@ store_user_info (struct passwd    *p,        if (!_dbus_string_append (homedir, p->pw_dir))          { -          _dbus_verbose ("No memory to get homedir\n"); +          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);            return FALSE;          }      } @@ -1342,7 +1343,7 @@ store_user_info (struct passwd    *p,      {        if (homedir)          _dbus_string_set_length (homedir, old_homedir_len); -      _dbus_verbose ("No memory to get username\n"); +      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);        return FALSE;      } @@ -1363,6 +1364,7 @@ store_user_info (struct passwd    *p,   * @param credentials to fill in or #NULL   * @param homedir string to append homedir to or #NULL   * @param username_out string to append username to or #NULL + * @param error return location for reason for failure   *   * @returns #TRUE on success   */ @@ -1371,7 +1373,8 @@ get_user_info (const DBusString *username,                 dbus_uid_t        uid,                 DBusCredentials  *credentials,                 DBusString       *homedir, -               DBusString       *username_out) +               DBusString       *username_out, +               DBusError        *error)  {    const char *username_c_str; @@ -1417,10 +1420,13 @@ get_user_info (const DBusString *username,      if (result == 0 && p == &p_str)        {          return store_user_info (p, credentials, homedir, -                                username_out); +                                username_out, error);        }      else        { +        dbus_set_error (error, DBUS_ERROR_FAILED, +                        "User \"%s\" unknown or no memory to allocate password entry\n", +                        username_c_str);          _dbus_verbose ("User %s unknown\n", username_c_str);          return FALSE;        } @@ -1438,10 +1444,13 @@ get_user_info (const DBusString *username,      if (p != NULL)        {          return store_user_info (p, credentials, homedir, -                                username_out); +                                username_out, error);        }      else        { +        dbus_set_error (error, DBUS_ERROR_FAILED, +                        "User \"%s\" unknown or no memory to allocate password entry\n", +                        username_c_str);          _dbus_verbose ("User %s unknown\n", username_c_str);          return FALSE;        } @@ -1474,7 +1483,7 @@ dbus_bool_t  _dbus_credentials_from_username (const DBusString *username,                                   DBusCredentials  *credentials)  { -  return get_user_info (username, -1, credentials, NULL, NULL); +  return get_user_info (username, -1, credentials, NULL, NULL, NULL);  }  /** @@ -1512,7 +1521,7 @@ dbus_bool_t  _dbus_credentials_from_user_id (unsigned long     user_id,                                  DBusCredentials  *credentials)  { -  return get_user_info (NULL, user_id, credentials, NULL, NULL); +  return get_user_info (NULL, user_id, credentials, NULL, NULL, NULL);  }  _DBUS_DEFINE_GLOBAL_LOCK (user_info); @@ -1570,7 +1579,7 @@ _dbus_user_info_from_current_process (const DBusString      **username,        _dbus_credentials_clear (&u.creds);        if (!get_user_info (NULL, getuid (), -                          &u.creds, &u.dir, &u.name)) +                          &u.creds, &u.dir, &u.name, NULL))          goto fail_init;        if (!_dbus_register_shutdown_func (shutdown_user_info, @@ -1611,7 +1620,7 @@ dbus_bool_t  _dbus_homedir_from_username (const DBusString *username,                               DBusString       *homedir)  { -  return get_user_info (username, -1, NULL, homedir, NULL); +  return get_user_info (username, -1, NULL, homedir, NULL, NULL);  }  /** @@ -1773,21 +1782,20 @@ _dbus_get_group_id (const DBusString *group_name,  /**   * Gets all groups for a particular user. Returns #FALSE   * if no memory, or user isn't known, but always initializes - * group_ids to a NULL array. - * - * @todo failing to distinguish "out of memory" from - * "unknown user" is kind of bogus and would probably - * result in a failure in a comprehensive test suite. + * group_ids to a NULL array. Sets error to the reason + * for returning #FALSE.   *   * @param uid the user ID   * @param group_ids return location for array of group IDs   * @param n_group_ids return location for length of returned array + * @param error return location for error   * @returns #TRUE on success   */  dbus_bool_t  _dbus_get_groups (unsigned long   uid,                    unsigned long **group_ids, -                  int            *n_group_ids) +                  int            *n_group_ids, +                  DBusError      *error)  {    DBusCredentials creds;    DBusString username; @@ -1800,10 +1808,13 @@ _dbus_get_groups (unsigned long   uid,    retval = FALSE;    if (!_dbus_string_init (&username)) -    return FALSE; +    { +      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +      return FALSE; +    }    if (!get_user_info (NULL, uid, &creds, -                      NULL, &username) || +                      NULL, &username, error) ||        creds.gid == DBUS_GID_UNSET)      goto out; @@ -1818,7 +1829,10 @@ _dbus_get_groups (unsigned long   uid,      buf_count = 17;      buf = dbus_new (gid_t, buf_count);      if (buf == NULL) -      goto out; +      { +        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +        goto out; +      }      if (getgrouplist (username_c,                        creds.gid, @@ -1827,6 +1841,7 @@ _dbus_get_groups (unsigned long   uid,          gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));          if (new == NULL)            { +            dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);              dbus_free (buf);              goto out;            } @@ -1839,6 +1854,7 @@ _dbus_get_groups (unsigned long   uid,      *group_ids = dbus_new (unsigned long, buf_count);      if (*group_ids == NULL)        { +        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);          dbus_free (buf);          goto out;        } @@ -1855,19 +1871,28 @@ _dbus_get_groups (unsigned long   uid,      /* We just get the one group ID */      *group_ids = dbus_new (unsigned long, 1);      if (*group_ids == NULL) -      goto out; +      { +        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +        goto out; +      }      *n_group_ids = 1;      (*group_ids)[0] = creds.gid;    }  #endif /* HAVE_GETGROUPLIST */ +   +  retval = TRUE; +   + out: +  _dbus_string_free (&username); -    retval = TRUE; -     -  out: -    _dbus_string_free (&username); -    return retval; +  if (retval) +    _DBUS_ASSERT_ERROR_IS_CLEAR (error); +  else +    _DBUS_ASSERT_ERROR_IS_SET (error); +   +  return retval;  }  /** diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 4edfe94a..27f27b58 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -148,7 +148,8 @@ dbus_bool_t _dbus_get_group_id (const DBusString  *group_name,                                  dbus_gid_t        *gid);  dbus_bool_t _dbus_get_groups   (dbus_uid_t         uid,                                  dbus_gid_t       **group_ids, -                                int               *n_group_ids); +                                int               *n_group_ids, +                                DBusError         *error);  unsigned long _dbus_getpid (void); diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h index 052c15fa..1c5b4208 100644 --- a/dbus/dbus-transport-protected.h +++ b/dbus/dbus-transport-protected.h @@ -100,6 +100,7 @@ struct DBusTransport    unsigned int send_credentials_pending : 1;  /**< #TRUE if we need to send credentials */    unsigned int receive_credentials_pending : 1; /**< #TRUE if we need to receive credentials */    unsigned int is_server : 1;                 /**< #TRUE if on the server side */ +  unsigned int unused_bytes_recovered : 1;    /**< #TRUE if we've recovered unused bytes from auth */  };  dbus_bool_t _dbus_transport_init_base     (DBusTransport             *transport, diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index f9b3d8a8..e726de24 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -459,9 +459,21 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)        maybe_authenticated =          (!(transport->send_credentials_pending || -           transport->receive_credentials_pending)) && -        _dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_AUTHENTICATED; +           transport->receive_credentials_pending)); +      if (maybe_authenticated) +        { +          switch (_dbus_auth_do_work (transport->auth)) +            { +            case DBUS_AUTH_STATE_AUTHENTICATED: +            case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES: +              /* leave as maybe_authenticated */ +              break; +            default: +              maybe_authenticated = FALSE; +            } +        } +              /* If we've authenticated as some identity, check that the auth         * identity is the same as our own identity.  In the future, we         * may have API allowing applications to specify how this is @@ -768,18 +780,18 @@ _dbus_transport_get_dispatch_status (DBusTransport *transport)    if (!_dbus_transport_get_is_authenticated (transport))      { -      switch (_dbus_auth_do_work (transport->auth)) -        { -        case DBUS_AUTH_STATE_WAITING_FOR_MEMORY: -          return DBUS_DISPATCH_NEED_MEMORY; -        case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES: -          if (!recover_unused_bytes (transport)) -            return DBUS_DISPATCH_NEED_MEMORY; -          break; -        default: -          break; -        } +      if (_dbus_auth_do_work (transport->auth) == +          DBUS_AUTH_STATE_WAITING_FOR_MEMORY) +        return DBUS_DISPATCH_NEED_MEMORY; +      else +        return DBUS_DISPATCH_COMPLETE;      } + +  if (!transport->unused_bytes_recovered && +      !recover_unused_bytes (transport)) +    return DBUS_DISPATCH_NEED_MEMORY; + +  transport->unused_bytes_recovered = TRUE;    if (!_dbus_message_loader_queue_messages (transport->loader))      return DBUS_DISPATCH_NEED_MEMORY; @@ -82,3 +82,7 @@     after the message bus has processed your message but before the service has replied,      it would be nice if the message bus sent you an error reply. + - We have a limit on the number of messages a connection can send, but  +   not on how many can be buffered for a given connection. + + - make client serial and reply serial unsigned and add dbus_message_get_is_reply() diff --git a/test/data/valid-config-files/debug-allow-all.conf.in b/test/data/valid-config-files/debug-allow-all.conf.in index c4308988..0dd8ed4a 100644 --- a/test/data/valid-config-files/debug-allow-all.conf.in +++ b/test/data/valid-config-files/debug-allow-all.conf.in @@ -10,5 +10,6 @@      <allow send="*"/>      <allow receive="*"/>      <allow own="*"/> +    <allow user="*"/>    </policy>  </busconfig> | 
