+++ /dev/null
-#include <config.h>
-#include "dbus-internals.h"
-#include "dbus-authorization.h"
-#include "dbus-connection.h"
-#include "dbus-connection-internal.h"
-
-struct DBusAuthorization {
- int refcount;
-
- DBusConnection *connection;
-
- /* Authorization functions, used as callback by SASL (implemented by
- * DBUsAuth) */
- DBusAllowUnixUserFunction unix_authorization_cb;
- void *unix_data;
- DBusFreeFunction unix_data_free;
-
- DBusAllowWindowsUserFunction windows_authorization_cb;
- void *windows_data;
- DBusFreeFunction windows_data_free;
-
- dbus_bool_t allow_anonymous;
-};
-
-
-DBusAuthorization *
-_dbus_authorization_new (void)
-{
- DBusAuthorization *ret;
-
- ret = dbus_malloc0 (sizeof (DBusAuthorization));
- if (ret == NULL)
- {
- _dbus_verbose ("OOM\n");
- return NULL; /* OOM */
- }
-
- ret->refcount = 1;
-
- return ret;
-}
-
-DBusAuthorization *
-_dbus_authorization_ref (DBusAuthorization *self)
-{
- _dbus_assert (self != NULL);
-
- self->refcount += 1;
-
- return self;
-}
-
-void
-_dbus_authorization_unref (DBusAuthorization *self)
-{
- _dbus_assert (self != NULL);
- _dbus_assert (self->refcount > 0);
-
- self->refcount -= 1;
-
- if (self->refcount == 0)
- {
- _dbus_verbose ("last reference, finalizing\n");
-
- if (self->unix_data && self->unix_data_free)
- {
- _dbus_verbose ("freeing unix authorization callback data\n");
- (*self->unix_data_free) (self->unix_data);
- self->unix_data = NULL;
- }
-
- if (self->windows_data && self->windows_data_free)
- {
- _dbus_verbose ("freeing windows authorization callback data\n");
- (*self->windows_data_free) (self->windows_data);
- self->windows_data = NULL;
- }
-
- dbus_free (self);
- }
-}
-
-/* Called by transport's set_connection with the connection locked */
-void
-_dbus_authorization_set_connection (DBusAuthorization *self,
- DBusConnection *connection)
-{
- _dbus_assert (connection != NULL);
- _dbus_assert (self->connection == NULL);
-
- self->connection = connection;
-}
-
-
-/**
- * Set the user set authorization callback for Unix identities authorizations.
- * The callback will be called at the end of the EXTERNAL authentication
- * mechanism and on every message.
-
- * See dbus_connection_set_unix_authorization_callback() and
- * _dbus_transport_set_unix_authorization_callback().
- *
- * @param self the authorization struct
- * @param function the predicate
- * @param data data to pass to the predicate
- * @param free_data_function function to free the data
- * @param old_data the old user data to be freed
- * @param old_free_data_function old free data function to free it with
- */
-void
-_dbus_authorization_set_unix_authorization_callback (DBusAuthorization *self,
- DBusAllowUnixUserFunction function,
- void *data,
- DBusFreeFunction free_data_function,
- void **old_data,
- DBusFreeFunction *old_free_data_function)
-{
- *old_data = self->unix_data;
- *old_free_data_function = self->unix_data_free;
-
- self->unix_authorization_cb = function;
- self->unix_data = data;
- self->unix_data_free = free_data_function;
-}
-
-/**
- * Set the user set authorization callback for Windows identities
- * authorizations.
- * The callback will be called at the end of the EXTERNAL authentication
- * mechanism and on every message.
- *
- * See dbus_connection_set_windows_authorization_callback() and
- * _dbus_transport_set_windows_authorization_callback().
- *
- * @param self the authorization struct
- * @param function the predicate
- * @param data data to pass to the predicate
- * @param free_data_function function to free the data
- * @param old_data the old user data to be freed
- * @param old_free_data_function old free data function to free it with
- */
-
-void
-_dbus_authorization_set_windows_authorization_callback (DBusAuthorization *self,
- DBusAllowWindowsUserFunction function,
- void *data,
- DBusFreeFunction free_data_function,
- void **old_data,
- DBusFreeFunction *old_free_data_function)
-{
- *old_data = self->windows_data;
- *old_free_data_function = self->windows_data_free;
-
- self->windows_authorization_cb = function;
- self->windows_data = data;
- self->windows_data_free = free_data_function;
-}
-
-static dbus_bool_t
-auth_via_unix_authorization_callback (DBusAuthorization *self,
- DBusCredentials *auth_identity)
-{
-
- dbus_bool_t allow;
- dbus_uid_t uid;
-
- /* Dropping the lock here probably isn't that safe. */
-
- _dbus_assert (auth_identity != NULL);
-
- uid = _dbus_credentials_get_unix_uid (auth_identity);
-
- _dbus_verbose ("unlock connection before executing user's authorization callback\n");
- _dbus_connection_unlock (self->connection);
-
- allow = (*self->unix_authorization_cb) (self->connection,
- uid,
- self->unix_data);
-
- _dbus_verbose ("lock connection post unix-authorization callback\n");
- _dbus_connection_lock (self->connection);
-
- if (allow)
- {
- _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
- }
- else
- {
- _dbus_verbose ("Client UID "DBUS_UID_FORMAT " wasn't authorized.\n",
- _dbus_credentials_get_unix_uid (auth_identity));
- }
-
- return allow;
-}
-
-
-static dbus_bool_t
-auth_via_windows_authorization_callback (DBusAuthorization *self,
- DBusCredentials *auth_identity)
-{
- dbus_bool_t allow;
- char *windows_sid;
-
- /* Dropping the lock here probably isn't that safe. */
-
- _dbus_assert (auth_identity != NULL);
-
- windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
-
- if (windows_sid == NULL)
- return FALSE; /* OOM */
-
- _dbus_verbose ("unlock connection before executing user's authorization callback\n");
- _dbus_connection_unlock (self->connection);
-
- allow = (*self->windows_authorization_cb) (self->connection,
- windows_sid,
- self->windows_data);
-
- _dbus_verbose ("lock connection post windows user's authorization callback\n");
- _dbus_connection_lock (self->connection);
-
- if (allow)
- {
- _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
- }
- else
- {
- _dbus_verbose ("Client SID '%s' wasn't authorized\n",
- _dbus_credentials_get_windows_sid (auth_identity));
- }
-
- dbus_free (windows_sid);
-
- return allow;
-}
-
-static dbus_bool_t
-auth_via_default_rules (DBusAuthorization *self,
- DBusCredentials *auth_identity)
-
-{
- DBusCredentials *our_identity;
- dbus_bool_t allow;
-
- _dbus_assert (auth_identity != NULL);
-
- /* By default, connection is allowed if the client is 1) root or 2)
- * has the same UID as us or 3) anonymous is allowed.
- */
-
- our_identity = _dbus_credentials_new_from_current_process ();
- if (our_identity == NULL)
- return FALSE; /* OOM */
-
- if (self->allow_anonymous ||
- _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
- _dbus_credentials_same_user (our_identity, auth_identity))
- {
- if (_dbus_credentials_include (our_identity, DBUS_CREDENTIAL_WINDOWS_SID))
- _dbus_verbose ("Client authenticated as SID '%s'"
- "matching our SID '%s': authorized\n",
- _dbus_credentials_get_windows_sid (auth_identity),
- _dbus_credentials_get_windows_sid (our_identity));
- else
- _dbus_verbose ("Client authenticated as UID "DBUS_UID_FORMAT
- " matching our UID "DBUS_UID_FORMAT": authorized\n",
- _dbus_credentials_get_unix_uid (auth_identity),
- _dbus_credentials_get_unix_uid (our_identity));
- /* We have authenticated! */
- allow = TRUE;
- }
- else
- {
- if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
- _dbus_verbose ("Client authenticated as SID '%s'"
- " but our SID is '%s', not authorizing\n",
- (_dbus_credentials_get_windows_sid(auth_identity) ?
- _dbus_credentials_get_windows_sid(auth_identity) : "<null>"),
- (_dbus_credentials_get_windows_sid(our_identity) ?
- _dbus_credentials_get_windows_sid(our_identity) : "<null>"));
- else
- _dbus_verbose ("Client authenticated as UID "DBUS_UID_FORMAT
- " but our UID is "DBUS_UID_FORMAT", not authorizing\n",
- _dbus_credentials_get_unix_uid(auth_identity),
- _dbus_credentials_get_unix_uid(our_identity));
- allow = FALSE;
- }
-
- _dbus_credentials_unref (our_identity);
-
- return allow;
-}
-
-/* Called with DBusConnection lock held */
-dbus_bool_t
-_dbus_authorization_do_authorization (DBusAuthorization *self,
- DBusCredentials *auth_identity)
-{
- dbus_bool_t allow;
-
- /* maybe-FIXME: at this point we *should* have a connection set unless we
- * are in some test case, but we assert its presence only in some if's
- * branches since default_rules does not need one and is used in a test case
- * without a connection set */
-
- if (_dbus_credentials_are_anonymous (auth_identity))
- {
- allow = self->allow_anonymous;
- }
- if (self->unix_authorization_cb != NULL &&
- _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
- {
- _dbus_assert (self->connection != NULL);
- allow = auth_via_unix_authorization_callback (self, auth_identity);
- }
- else if (self->windows_authorization_cb != NULL &&
- _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
- {
- _dbus_assert (self->connection != NULL);
- allow = auth_via_windows_authorization_callback (self, auth_identity);
- }
- else
- {
- allow = auth_via_default_rules (self, auth_identity);
- }
-
- return allow;
-}
-
-
-
-/**
- * See dbus_connection_set_allow_anonymous()
- *
- * @param self an authorization struct
- * @param value #TRUE to allow anonymous connection
- */
-void
-_dbus_authorization_set_allow_anonymous (DBusAuthorization *self,
- dbus_bool_t value)
-{
- self->allow_anonymous = value != FALSE;
-}