summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-04-14 02:29:21 +0000
committerHavoc Pennington <hp@redhat.com>2003-04-14 02:29:21 +0000
commit777707ed8dff6958972a93894a87ec1945c65c14 (patch)
tree4ade9d56eccc5280150968e692a389e8749ed029 /dbus
parent8aabca8dd28a113712389be51e75ea8c2fd17838 (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
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-connection.c4
-rw-r--r--dbus/dbus-mainloop.c65
-rw-r--r--dbus/dbus-message.c2
-rw-r--r--dbus/dbus-sysdeps.c75
-rw-r--r--dbus/dbus-sysdeps.h3
-rw-r--r--dbus/dbus-transport-protected.h1
-rw-r--r--dbus/dbus-transport.c38
7 files changed, 129 insertions, 59 deletions
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;