mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-02-05 04:10:35 +01:00
2007-06-09 Havoc Pennington <hp@redhat.com>
* bus/policy.c (bus_policy_create_client_policy): gracefully continue if the connection has no unix user - just don't apply any unix user dependent rules. * bus/config-parser.c: remove dbus-userdb.h usage * bus/bus.c: remove dbus-userdb.h usage * dbus/dbus-transport.c (_dbus_transport_get_is_authenticated): support Windows user function; also, fix the logic for checking auth as root in the default auth code (broken in the previous commit) * dbus/dbus-connection.c (dbus_connection_set_windows_user_function): new function (dbus_connection_get_windows_user): new function
This commit is contained in:
parent
2383267226
commit
7be5fd95cd
18 changed files with 646 additions and 194 deletions
19
ChangeLog
19
ChangeLog
|
|
@ -1,3 +1,22 @@
|
|||
2007-06-09 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* bus/policy.c (bus_policy_create_client_policy): gracefully
|
||||
continue if the connection has no unix user - just don't apply
|
||||
any unix user dependent rules.
|
||||
|
||||
* bus/config-parser.c: remove dbus-userdb.h usage
|
||||
|
||||
* bus/bus.c: remove dbus-userdb.h usage
|
||||
|
||||
* dbus/dbus-transport.c (_dbus_transport_get_is_authenticated):
|
||||
support Windows user function; also, fix the logic for checking
|
||||
auth as root in the default auth code (broken in the previous
|
||||
commit)
|
||||
|
||||
* dbus/dbus-connection.c
|
||||
(dbus_connection_set_windows_user_function): new function
|
||||
(dbus_connection_get_windows_user): new function
|
||||
|
||||
2007-06-09 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* bus/dispatch.c (check_get_connection_unix_process_id): adapt
|
||||
|
|
|
|||
23
bus/bus.c
23
bus/bus.c
|
|
@ -34,7 +34,6 @@
|
|||
#include <dbus/dbus-list.h>
|
||||
#include <dbus/dbus-hash.h>
|
||||
#include <dbus/dbus-internals.h>
|
||||
#include <dbus/dbus-userdb.h>
|
||||
|
||||
struct BusContext
|
||||
{
|
||||
|
|
@ -794,7 +793,7 @@ bus_context_reload_config (BusContext *context,
|
|||
dbus_bool_t ret;
|
||||
|
||||
/* Flush the user database cache */
|
||||
_dbus_user_database_flush_system ();
|
||||
_dbus_flush_caches ();
|
||||
|
||||
ret = FALSE;
|
||||
_dbus_string_init_const (&config_file, context->config_file);
|
||||
|
|
@ -995,11 +994,23 @@ bus_context_get_loop (BusContext *context)
|
|||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_context_allow_user (BusContext *context,
|
||||
unsigned long uid)
|
||||
bus_context_allow_unix_user (BusContext *context,
|
||||
unsigned long uid)
|
||||
{
|
||||
return bus_policy_allow_user (context->policy,
|
||||
uid);
|
||||
return bus_policy_allow_unix_user (context->policy,
|
||||
uid);
|
||||
}
|
||||
|
||||
/* For now this is never actually called because the default
|
||||
* DBusConnection behavior of 'same user that owns the bus can connect'
|
||||
* is all it would do.
|
||||
*/
|
||||
dbus_bool_t
|
||||
bus_context_allow_windows_user (BusContext *context,
|
||||
const char *windows_sid)
|
||||
{
|
||||
return bus_policy_allow_windows_user (context->policy,
|
||||
windows_sid);
|
||||
}
|
||||
|
||||
BusPolicy *
|
||||
|
|
|
|||
|
|
@ -85,8 +85,10 @@ BusConnections* bus_context_get_connections (BusContext
|
|||
BusActivation* bus_context_get_activation (BusContext *context);
|
||||
BusMatchmaker* bus_context_get_matchmaker (BusContext *context);
|
||||
DBusLoop* bus_context_get_loop (BusContext *context);
|
||||
dbus_bool_t bus_context_allow_user (BusContext *context,
|
||||
dbus_bool_t bus_context_allow_unix_user (BusContext *context,
|
||||
unsigned long uid);
|
||||
dbus_bool_t bus_context_allow_windows_user (BusContext *context,
|
||||
const char *windows_sid);
|
||||
BusPolicy* bus_context_get_policy (BusContext *context);
|
||||
|
||||
BusClientPolicy* bus_context_create_client_policy (BusContext *context,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "selinux.h"
|
||||
#include <dbus/dbus-list.h>
|
||||
#include <dbus/dbus-internals.h>
|
||||
#include <dbus/dbus-userdb.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef enum
|
||||
|
|
@ -983,8 +982,8 @@ start_busconfig_child (BusConfigParser *parser,
|
|||
DBusString username;
|
||||
_dbus_string_init_const (&username, user);
|
||||
|
||||
if (_dbus_get_user_id (&username,
|
||||
&e->d.policy.gid_uid_or_at_console))
|
||||
if (_dbus_parse_unix_user_from_config (&username,
|
||||
&e->d.policy.gid_uid_or_at_console))
|
||||
e->d.policy.type = POLICY_USER;
|
||||
else
|
||||
_dbus_warn ("Unknown username \"%s\" in message bus configuration file\n",
|
||||
|
|
@ -995,8 +994,8 @@ start_busconfig_child (BusConfigParser *parser,
|
|||
DBusString group_name;
|
||||
_dbus_string_init_const (&group_name, group);
|
||||
|
||||
if (_dbus_get_group_id (&group_name,
|
||||
&e->d.policy.gid_uid_or_at_console))
|
||||
if (_dbus_parse_unix_group_from_config (&group_name,
|
||||
&e->d.policy.gid_uid_or_at_console))
|
||||
e->d.policy.type = POLICY_GROUP;
|
||||
else
|
||||
_dbus_warn ("Unknown group \"%s\" in message bus configuration file\n",
|
||||
|
|
@ -1469,7 +1468,7 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
|
||||
_dbus_string_init_const (&username, user);
|
||||
|
||||
if (_dbus_get_user_id (&username, &uid))
|
||||
if (_dbus_parse_unix_user_from_config (&username, &uid))
|
||||
{
|
||||
rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow);
|
||||
if (rule == NULL)
|
||||
|
|
@ -1501,7 +1500,7 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
|
||||
_dbus_string_init_const (&groupname, group);
|
||||
|
||||
if (_dbus_get_user_id (&groupname, &gid))
|
||||
if (_dbus_parse_unix_group_from_config (&groupname, &gid))
|
||||
{
|
||||
rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow);
|
||||
if (rule == NULL)
|
||||
|
|
@ -1571,7 +1570,7 @@ append_rule_from_element (BusConfigParser *parser,
|
|||
|
||||
case POLICY_CONSOLE:
|
||||
if (!bus_policy_append_console_rule (parser->policy, pe->d.policy.gid_uid_or_at_console,
|
||||
rule))
|
||||
rule))
|
||||
goto nomem;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include <dbus/dbus-list.h>
|
||||
#include <dbus/dbus-hash.h>
|
||||
#include <dbus/dbus-timeout.h>
|
||||
#include <dbus/dbus-userdb.h>
|
||||
|
||||
static void bus_connection_remove_transactions (DBusConnection *connection);
|
||||
|
||||
|
|
@ -243,7 +242,9 @@ bus_connection_disconnected (DBusConnection *connection)
|
|||
|
||||
dbus_connection_set_unix_user_function (connection,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
dbus_connection_set_windows_user_function (connection,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
dbus_connection_set_dispatch_status_function (connection,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
|
|
@ -369,9 +370,9 @@ dispatch_status_function (DBusConnection *connection,
|
|||
}
|
||||
|
||||
static dbus_bool_t
|
||||
allow_user_function (DBusConnection *connection,
|
||||
unsigned long uid,
|
||||
void *data)
|
||||
allow_unix_user_function (DBusConnection *connection,
|
||||
unsigned long uid,
|
||||
void *data)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
|
||||
|
|
@ -379,7 +380,7 @@ allow_user_function (DBusConnection *connection,
|
|||
|
||||
_dbus_assert (d != NULL);
|
||||
|
||||
return bus_context_allow_user (d->connections->context, uid);
|
||||
return bus_context_allow_unix_user (d->connections->context, uid);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -597,9 +598,14 @@ bus_connections_setup_connection (BusConnections *connections,
|
|||
NULL,
|
||||
connection, NULL))
|
||||
goto out;
|
||||
|
||||
|
||||
/* For now we don't need to set a Windows user function because
|
||||
* there are no policies in the config file controlling what
|
||||
* Windows users can connect. The default 'same user that owns the
|
||||
* bus can connect' behavior of DBusConnection is fine on Windows.
|
||||
*/
|
||||
dbus_connection_set_unix_user_function (connection,
|
||||
allow_user_function,
|
||||
allow_unix_user_function,
|
||||
NULL, NULL);
|
||||
|
||||
dbus_connection_set_dispatch_status_function (connection,
|
||||
|
|
@ -679,6 +685,9 @@ bus_connections_setup_connection (BusConnections *connections,
|
|||
dbus_connection_set_unix_user_function (connection,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
dbus_connection_set_windows_user_function (connection,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
dbus_connection_set_dispatch_status_function (connection,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
|
|
@ -772,10 +781,10 @@ expire_incomplete_timeout (void *data)
|
|||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_connection_get_groups (DBusConnection *connection,
|
||||
unsigned long **groups,
|
||||
int *n_groups,
|
||||
DBusError *error)
|
||||
bus_connection_get_unix_groups (DBusConnection *connection,
|
||||
unsigned long **groups,
|
||||
int *n_groups,
|
||||
DBusError *error)
|
||||
{
|
||||
BusConnectionData *d;
|
||||
unsigned long uid;
|
||||
|
|
@ -789,7 +798,7 @@ bus_connection_get_groups (DBusConnection *connection,
|
|||
|
||||
if (dbus_connection_get_unix_user (connection, &uid))
|
||||
{
|
||||
if (!_dbus_groups_from_uid (uid, groups, n_groups))
|
||||
if (!_dbus_unix_groups_from_uid (uid, groups, n_groups))
|
||||
{
|
||||
_dbus_verbose ("Did not get any groups for UID %lu\n",
|
||||
uid);
|
||||
|
|
@ -807,15 +816,15 @@ bus_connection_get_groups (DBusConnection *connection,
|
|||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_connection_is_in_group (DBusConnection *connection,
|
||||
unsigned long gid)
|
||||
bus_connection_is_in_unix_group (DBusConnection *connection,
|
||||
unsigned long gid)
|
||||
{
|
||||
int i;
|
||||
unsigned long *group_ids;
|
||||
int n_group_ids;
|
||||
|
||||
if (!bus_connection_get_groups (connection, &group_ids, &n_group_ids,
|
||||
NULL))
|
||||
if (!bus_connection_get_unix_groups (connection, &group_ids, &n_group_ids,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
||||
i = 0;
|
||||
|
|
|
|||
|
|
@ -105,12 +105,12 @@ dbus_bool_t bus_connection_complete (DBusConnection *connection,
|
|||
/* called by dispatch.c when the connection is dropped */
|
||||
void bus_connection_disconnected (DBusConnection *connection);
|
||||
|
||||
dbus_bool_t bus_connection_is_in_group (DBusConnection *connection,
|
||||
unsigned long gid);
|
||||
dbus_bool_t bus_connection_get_groups (DBusConnection *connection,
|
||||
unsigned long **groups,
|
||||
int *n_groups,
|
||||
DBusError *error);
|
||||
dbus_bool_t bus_connection_is_in_unix_group (DBusConnection *connection,
|
||||
unsigned long gid);
|
||||
dbus_bool_t bus_connection_get_unix_groups (DBusConnection *connection,
|
||||
unsigned long **groups,
|
||||
int *n_groups,
|
||||
DBusError *error);
|
||||
BusClientPolicy* bus_connection_get_policy (DBusConnection *connection);
|
||||
|
||||
/* transaction API so we can send or not send a block of messages as a whole */
|
||||
|
|
|
|||
92
bus/policy.c
92
bus/policy.c
|
|
@ -28,7 +28,6 @@
|
|||
#include <dbus/dbus-list.h>
|
||||
#include <dbus/dbus-hash.h>
|
||||
#include <dbus/dbus-internals.h>
|
||||
#include <dbus/dbus-userdb.h>
|
||||
|
||||
BusPolicyRule*
|
||||
bus_policy_rule_new (BusPolicyRuleType type,
|
||||
|
|
@ -296,7 +295,7 @@ bus_policy_create_client_policy (BusPolicy *policy,
|
|||
int n_groups;
|
||||
int i;
|
||||
|
||||
if (!bus_connection_get_groups (connection, &groups, &n_groups, error))
|
||||
if (!bus_connection_get_unix_groups (connection, &groups, &n_groups, error))
|
||||
goto failed;
|
||||
|
||||
i = 0;
|
||||
|
|
@ -321,43 +320,39 @@ bus_policy_create_client_policy (BusPolicy *policy,
|
|||
|
||||
dbus_free (groups);
|
||||
}
|
||||
|
||||
if (!dbus_connection_get_unix_user (connection, &uid))
|
||||
|
||||
if (dbus_connection_get_unix_user (connection, &uid))
|
||||
{
|
||||
dbus_set_error (error, DBUS_ERROR_FAILED,
|
||||
"No user ID known for connection, cannot determine security policy\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
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 (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
|
||||
{
|
||||
if (!add_list_to_client (list, client))
|
||||
DBusList **list;
|
||||
|
||||
list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
|
||||
uid);
|
||||
|
||||
if (list != NULL)
|
||||
{
|
||||
if (!add_list_to_client (list, client))
|
||||
goto nomem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add console rules */
|
||||
at_console = _dbus_unix_user_is_at_console (uid, error);
|
||||
|
||||
if (at_console)
|
||||
{
|
||||
if (!add_list_to_client (&policy->at_console_true_rules, client))
|
||||
goto nomem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add console rules */
|
||||
at_console = _dbus_is_console_user (uid, error);
|
||||
|
||||
if (at_console)
|
||||
{
|
||||
if (!add_list_to_client (&policy->at_console_true_rules, client))
|
||||
goto nomem;
|
||||
}
|
||||
else if (dbus_error_is_set (error) == TRUE)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
else if (!add_list_to_client (&policy->at_console_false_rules, client))
|
||||
{
|
||||
goto nomem;
|
||||
else if (dbus_error_is_set (error) == TRUE)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
else if (!add_list_to_client (&policy->at_console_false_rules, client))
|
||||
{
|
||||
goto nomem;
|
||||
}
|
||||
}
|
||||
|
||||
if (!add_list_to_client (&policy->mandatory_rules,
|
||||
|
|
@ -438,23 +433,23 @@ list_allows_user (dbus_bool_t def,
|
|||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_policy_allow_user (BusPolicy *policy,
|
||||
unsigned long uid)
|
||||
bus_policy_allow_unix_user (BusPolicy *policy,
|
||||
unsigned long uid)
|
||||
{
|
||||
dbus_bool_t allowed;
|
||||
unsigned long *group_ids;
|
||||
int n_group_ids;
|
||||
|
||||
/* On OOM or error we always reject the user */
|
||||
if (!_dbus_groups_from_uid (uid, &group_ids, &n_group_ids))
|
||||
if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids))
|
||||
{
|
||||
_dbus_verbose ("Did not get any groups for UID %lu\n",
|
||||
uid);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Default to "user owning bus" or root can connect */
|
||||
allowed = uid == _dbus_getuid ();
|
||||
/* Default to "user owning bus" can connect */
|
||||
allowed = _dbus_unix_user_is_process_owner (uid);
|
||||
|
||||
allowed = list_allows_user (allowed,
|
||||
&policy->default_rules,
|
||||
|
|
@ -473,6 +468,23 @@ bus_policy_allow_user (BusPolicy *policy,
|
|||
return allowed;
|
||||
}
|
||||
|
||||
/* For now this is never actually called because the default
|
||||
* DBusConnection behavior of 'same user that owns the bus can
|
||||
* connect' is all it would do. Set the windows user function in
|
||||
* connection.c if the config file ever supports doing something
|
||||
* interesting here.
|
||||
*/
|
||||
dbus_bool_t
|
||||
bus_policy_allow_windows_user (BusPolicy *policy,
|
||||
const char *windows_sid)
|
||||
{
|
||||
/* Windows has no policies here since only the session bus
|
||||
* is really used for now, so just checking that the
|
||||
* connecting person is the same as the bus owner is fine.
|
||||
*/
|
||||
return _dbus_windows_user_is_process_owner (windows_sid);
|
||||
}
|
||||
|
||||
dbus_bool_t
|
||||
bus_policy_append_default_rule (BusPolicy *policy,
|
||||
BusPolicyRule *rule)
|
||||
|
|
|
|||
|
|
@ -113,8 +113,10 @@ void bus_policy_unref (BusPolicy *policy);
|
|||
BusClientPolicy* bus_policy_create_client_policy (BusPolicy *policy,
|
||||
DBusConnection *connection,
|
||||
DBusError *error);
|
||||
dbus_bool_t bus_policy_allow_user (BusPolicy *policy,
|
||||
dbus_bool_t bus_policy_allow_unix_user (BusPolicy *policy,
|
||||
unsigned long uid);
|
||||
dbus_bool_t bus_policy_allow_windows_user (BusPolicy *policy,
|
||||
const char *windows_sid);
|
||||
dbus_bool_t bus_policy_append_default_rule (BusPolicy *policy,
|
||||
BusPolicyRule *rule);
|
||||
dbus_bool_t bus_policy_append_mandatory_rule (BusPolicy *policy,
|
||||
|
|
|
|||
|
|
@ -4763,8 +4763,10 @@ dbus_connection_get_socket(DBusConnection *connection,
|
|||
|
||||
/**
|
||||
* Gets the UNIX user ID of the connection if known. Returns #TRUE if
|
||||
* the uid is filled in. Always returns #FALSE on non-UNIX platforms.
|
||||
* Always returns #FALSE prior to authenticating the connection.
|
||||
* the uid is filled in. Always returns #FALSE on non-UNIX platforms
|
||||
* for now, though in theory someone could hook Windows to NIS or
|
||||
* something. Always returns #FALSE prior to authenticating the
|
||||
* connection.
|
||||
*
|
||||
* The UID is only read by servers from clients; clients can't usually
|
||||
* get the UID of servers, because servers do not authenticate to
|
||||
|
|
@ -4789,14 +4791,6 @@ dbus_connection_get_unix_user (DBusConnection *connection,
|
|||
|
||||
_dbus_return_val_if_fail (connection != NULL, FALSE);
|
||||
_dbus_return_val_if_fail (uid != NULL, FALSE);
|
||||
|
||||
#ifdef DBUS_WIN
|
||||
/* FIXME this should be done at a lower level, but it's kind of hard,
|
||||
* just want to be sure we don't ship with this API returning
|
||||
* some weird internal fake uid for 1.0
|
||||
*/
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
CONNECTION_LOCK (connection);
|
||||
|
||||
|
|
@ -4805,6 +4799,11 @@ dbus_connection_get_unix_user (DBusConnection *connection,
|
|||
else
|
||||
result = _dbus_transport_get_unix_user (connection->transport,
|
||||
uid);
|
||||
|
||||
#ifdef DBUS_WIN
|
||||
_dbus_assert (!result);
|
||||
#endif
|
||||
|
||||
CONNECTION_UNLOCK (connection);
|
||||
|
||||
return result;
|
||||
|
|
@ -4812,7 +4811,7 @@ dbus_connection_get_unix_user (DBusConnection *connection,
|
|||
|
||||
/**
|
||||
* Gets the process ID of the connection if any.
|
||||
* Returns #TRUE if the uid is filled in.
|
||||
* Returns #TRUE if the pid is filled in.
|
||||
* Always returns #FALSE prior to authenticating the
|
||||
* connection.
|
||||
*
|
||||
|
|
@ -4828,14 +4827,6 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
|
|||
|
||||
_dbus_return_val_if_fail (connection != NULL, FALSE);
|
||||
_dbus_return_val_if_fail (pid != NULL, FALSE);
|
||||
|
||||
#ifdef DBUS_WIN
|
||||
/* FIXME this should be done at a lower level, but it's kind of hard,
|
||||
* just want to be sure we don't ship with this API returning
|
||||
* some weird internal fake uid for 1.0
|
||||
*/
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
CONNECTION_LOCK (connection);
|
||||
|
||||
|
|
@ -4844,6 +4835,10 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
|
|||
else
|
||||
result = _dbus_transport_get_unix_process_id (connection->transport,
|
||||
pid);
|
||||
#ifdef DBUS_WIN
|
||||
_dbus_assert (!result);
|
||||
#endif
|
||||
|
||||
CONNECTION_UNLOCK (connection);
|
||||
|
||||
return result;
|
||||
|
|
@ -4858,14 +4853,13 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
|
|||
*
|
||||
* If the function is set to #NULL (as it is by default), then
|
||||
* only the same UID as the server process will be allowed to
|
||||
* connect.
|
||||
* connect. Also, root is always allowed to connect.
|
||||
*
|
||||
* On Windows, the function will be set and its free_data_function will
|
||||
* be invoked when the connection is freed or a new function is set.
|
||||
* However, the function will never be called, because there are
|
||||
* no UNIX user ids to pass to it.
|
||||
*
|
||||
* @todo add a Windows API analogous to dbus_connection_set_unix_user_function()
|
||||
* no UNIX user ids to pass to it, or at least none of the existing
|
||||
* auth protocols would allow authenticating as a UNIX user on Windows.
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param function the predicate
|
||||
|
|
@ -4890,7 +4884,106 @@ dbus_connection_set_unix_user_function (DBusConnection *connection,
|
|||
CONNECTION_UNLOCK (connection);
|
||||
|
||||
if (old_free_function != NULL)
|
||||
(* old_free_function) (old_data);
|
||||
(* old_free_function) (old_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Windows user SID of the connection if known. Returns
|
||||
* #TRUE if the ID is filled in. Always returns #FALSE on non-Windows
|
||||
* platforms for now, though in theory someone could hook UNIX to
|
||||
* Active Directory or something. Always returns #FALSE prior to
|
||||
* authenticating the connection.
|
||||
*
|
||||
* The user is only read by servers from clients; clients can't usually
|
||||
* get the user of servers, because servers do not authenticate to
|
||||
* clients. The returned user is the user the connection authenticated
|
||||
* as.
|
||||
*
|
||||
* The message bus is a server and the apps connecting to the bus
|
||||
* are clients.
|
||||
*
|
||||
* The returned user string has to be freed with dbus_free().
|
||||
*
|
||||
* The return value indicates whether the user SID is available;
|
||||
* if it's available but we don't have the memory to copy it,
|
||||
* then the return value is #TRUE and #NULL is given as the SID.
|
||||
*
|
||||
* @todo We would like to be able to say "You can ask the bus to tell
|
||||
* you the user of another connection though if you like; this is done
|
||||
* with dbus_bus_get_windows_user()." But this has to be implemented
|
||||
* in bus/driver.c and dbus/dbus-bus.c, and is pointless anyway
|
||||
* since on Windows we only use the session bus for now.
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param windows_sid_p return location for an allocated copy of the user ID, or #NULL if no memory
|
||||
* @returns #TRUE if user is available (returned value may be #NULL anyway if no memory)
|
||||
*/
|
||||
dbus_bool_t
|
||||
dbus_connection_get_windows_user (DBusConnection *connection,
|
||||
char **windows_sid_p)
|
||||
{
|
||||
dbus_bool_t result;
|
||||
|
||||
_dbus_return_val_if_fail (connection != NULL, FALSE);
|
||||
_dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
|
||||
|
||||
CONNECTION_LOCK (connection);
|
||||
|
||||
if (!_dbus_transport_get_is_authenticated (connection->transport))
|
||||
result = FALSE;
|
||||
else
|
||||
result = _dbus_transport_get_windows_user (connection->transport,
|
||||
windows_sid_p);
|
||||
|
||||
#ifdef DBUS_UNIX
|
||||
_dbus_assert (!result);
|
||||
#endif
|
||||
|
||||
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;
|
||||
* if it returns #TRUE, the connection is allowed to proceed,
|
||||
* otherwise the connection is disconnected.
|
||||
*
|
||||
* If the function is set to #NULL (as it is by default), then
|
||||
* only the same user owning the server process will be allowed to
|
||||
* connect.
|
||||
*
|
||||
* On UNIX, the function will be set and its free_data_function will
|
||||
* be invoked when the connection is freed or a new function is set.
|
||||
* However, the function will never be called, because there is no
|
||||
* way right now to authenticate as a Windows user on UNIX.
|
||||
*
|
||||
* @param connection the connection
|
||||
* @param function the predicate
|
||||
* @param data data to pass to the predicate
|
||||
* @param free_data_function function to free the data
|
||||
*/
|
||||
void
|
||||
dbus_connection_set_windows_user_function (DBusConnection *connection,
|
||||
DBusAllowWindowsUserFunction function,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_function)
|
||||
{
|
||||
void *old_data = NULL;
|
||||
DBusFreeFunction old_free_function = NULL;
|
||||
|
||||
_dbus_return_if_fail (connection != NULL);
|
||||
|
||||
CONNECTION_LOCK (connection);
|
||||
_dbus_transport_set_windows_user_function (connection->transport,
|
||||
function, data, free_data_function,
|
||||
&old_data, &old_free_function);
|
||||
CONNECTION_UNLOCK (connection);
|
||||
|
||||
if (old_free_function != NULL)
|
||||
(* old_free_function) (old_data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -132,14 +132,28 @@ typedef void (* DBusDispatchStatusFunction) (DBusConnection *connection,
|
|||
* to do. Set with dbus_connection_set_wakeup_main_function().
|
||||
*/
|
||||
typedef void (* DBusWakeupMainFunction) (void *data);
|
||||
|
||||
/**
|
||||
* Called during authentication on UNIX systems to check whether the given
|
||||
* user ID is allowed to connect. Never called on Windows. Set with
|
||||
* Called during authentication to check whether the given UNIX user
|
||||
* ID is allowed to connect, if the client tried to auth as a UNIX
|
||||
* user ID. Normally on Windows this would never happen. Set with
|
||||
* dbus_connection_set_unix_user_function().
|
||||
*/
|
||||
typedef dbus_bool_t (* DBusAllowUnixUserFunction) (DBusConnection *connection,
|
||||
unsigned long uid,
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* Called during authentication to check whether the given Windows user
|
||||
* ID is allowed to connect, if the client tried to auth as a Windows
|
||||
* user ID. Normally on UNIX this would never happen. Set with
|
||||
* dbus_connection_set_windows_user_function().
|
||||
*/
|
||||
typedef dbus_bool_t (* DBusAllowWindowsUserFunction) (DBusConnection *connection,
|
||||
const char *user_sid,
|
||||
void *data);
|
||||
|
||||
|
||||
/**
|
||||
* Called when a pending call now has a reply available. Set with
|
||||
* dbus_pending_call_set_notify().
|
||||
|
|
@ -219,6 +233,12 @@ void dbus_connection_set_unix_user_function (DBusConnection
|
|||
DBusAllowUnixUserFunction function,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_function);
|
||||
dbus_bool_t dbus_connection_get_windows_user (DBusConnection *connection,
|
||||
char **windows_sid_p);
|
||||
void dbus_connection_set_windows_user_function (DBusConnection *connection,
|
||||
DBusAllowWindowsUserFunction function,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_function);
|
||||
void dbus_connection_set_route_peer_messages (DBusConnection *connection,
|
||||
dbus_bool_t value);
|
||||
|
||||
|
|
|
|||
|
|
@ -2916,4 +2916,17 @@ _dbus_get_standard_session_servicedirs (DBusList **dirs)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the bus daemon is signaled to reload its configuration; any
|
||||
* caches should be nuked. Of course any caches that need explicit reload
|
||||
* are probably broken, but c'est la vie.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void
|
||||
_dbus_flush_caches (void)
|
||||
{
|
||||
_dbus_user_database_flush_system ();
|
||||
}
|
||||
|
||||
/* tests in dbus-sysdeps-util.c */
|
||||
|
|
|
|||
|
|
@ -120,8 +120,6 @@ dbus_bool_t _dbus_group_info_fill_gid (DBusGroupInfo *info,
|
|||
DBusError *error);
|
||||
void _dbus_group_info_free (DBusGroupInfo *info);
|
||||
|
||||
|
||||
dbus_pid_t _dbus_getpid (void);
|
||||
dbus_uid_t _dbus_getuid (void);
|
||||
dbus_gid_t _dbus_getgid (void);
|
||||
|
||||
|
|
|
|||
|
|
@ -780,6 +780,98 @@ _dbus_group_info_fill_gid (DBusGroupInfo *info,
|
|||
return fill_group_info (info, gid, NULL, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a UNIX user from the bus config file. On Windows, this should
|
||||
* simply always fail (just return #FALSE).
|
||||
*
|
||||
* @param username the username text
|
||||
* @param uid_p place to return the uid
|
||||
* @returns #TRUE on success
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_parse_unix_user_from_config (const DBusString *username,
|
||||
dbus_uid_t *uid_p)
|
||||
{
|
||||
return _dbus_get_user_id (username, uid_p);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a UNIX group from the bus config file. On Windows, this should
|
||||
* simply always fail (just return #FALSE).
|
||||
*
|
||||
* @param groupname the groupname text
|
||||
* @param gid_p place to return the gid
|
||||
* @returns #TRUE on success
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_parse_unix_group_from_config (const DBusString *groupname,
|
||||
dbus_gid_t *gid_p)
|
||||
{
|
||||
return _dbus_get_group_id (groupname, gid_p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all groups corresponding to the given UNIX user ID. On UNIX,
|
||||
* just calls _dbus_groups_from_uid(). On Windows, should always
|
||||
* fail since we don't know any UNIX groups.
|
||||
*
|
||||
* @param uid the UID
|
||||
* @param group_ids return location for array of group IDs
|
||||
* @param n_group_ids return location for length of returned array
|
||||
* @returns #TRUE if the UID existed and we got some credentials
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_unix_groups_from_uid (dbus_uid_t uid,
|
||||
dbus_gid_t **group_ids,
|
||||
int *n_group_ids)
|
||||
{
|
||||
return _dbus_groups_from_uid (uid, group_ids, n_group_ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the UNIX user ID is at the console.
|
||||
* Should always fail on Windows (set the error to
|
||||
* #DBUS_ERROR_NOT_SUPPORTED).
|
||||
*
|
||||
* @param uid UID of person to check
|
||||
* @param error return location for errors
|
||||
* @returns #TRUE if the UID is the same as the console user and there are no errors
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_unix_user_is_at_console (dbus_uid_t uid,
|
||||
DBusError *error)
|
||||
{
|
||||
return _dbus_is_console_user (uid, error);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the UNIX user ID matches the UID of
|
||||
* the process. Should always return #FALSE on Windows.
|
||||
*
|
||||
* @param uid the UNIX user ID
|
||||
* @returns #TRUE if this uid owns the process.
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_unix_user_is_process_owner (dbus_uid_t uid)
|
||||
{
|
||||
return uid == _dbus_getuid ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the Windows user SID matches the owner of
|
||||
* the process. Should always return #FALSE on UNIX.
|
||||
*
|
||||
* @param windows_sid the Windows user SID
|
||||
* @returns #TRUE if this user owns the process.
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_windows_user_is_process_owner (const char *windows_sid)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** @} */ /* End of DBusInternalsUtils functions */
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -173,6 +173,18 @@ dbus_bool_t _dbus_append_desired_identity (DBusString *str);
|
|||
dbus_bool_t _dbus_homedir_from_current_process (const DBusString **homedir);
|
||||
dbus_bool_t _dbus_homedir_from_username (const DBusString *username,
|
||||
DBusString *homedir);
|
||||
dbus_bool_t _dbus_parse_unix_user_from_config (const DBusString *username,
|
||||
dbus_uid_t *uid_p);
|
||||
dbus_bool_t _dbus_parse_unix_group_from_config (const DBusString *groupname,
|
||||
dbus_gid_t *gid_p);
|
||||
dbus_bool_t _dbus_unix_groups_from_uid (dbus_uid_t uid,
|
||||
dbus_gid_t **group_ids,
|
||||
int *n_group_ids);
|
||||
dbus_bool_t _dbus_unix_user_is_at_console (dbus_uid_t uid,
|
||||
DBusError *error);
|
||||
dbus_bool_t _dbus_unix_user_is_process_owner (dbus_uid_t uid);
|
||||
dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid);
|
||||
|
||||
|
||||
/** Opaque type representing an atomically-modifiable integer
|
||||
* that can be used from multiple threads.
|
||||
|
|
@ -420,6 +432,14 @@ dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs,
|
|||
|
||||
unsigned long _dbus_pid_for_log (void);
|
||||
|
||||
/* FIXME move back to dbus-sysdeps-unix.h probably -
|
||||
* the PID file handling just needs a little more abstraction
|
||||
* in the bus daemon first.
|
||||
*/
|
||||
dbus_pid_t _dbus_getpid (void);
|
||||
|
||||
void _dbus_flush_caches (void);
|
||||
|
||||
/** @} */
|
||||
|
||||
DBUS_END_DECLS
|
||||
|
|
|
|||
|
|
@ -161,8 +161,10 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir, const char *speci
|
|||
#endif
|
||||
|
||||
run_data_test ("credentials", specific_test, _dbus_credentials_test, test_data_dir);
|
||||
|
||||
|
||||
#ifdef DBUS_UNIX
|
||||
run_data_test ("userdb", specific_test, _dbus_userdb_test, test_data_dir);
|
||||
#endif
|
||||
|
||||
run_test ("keyring", specific_test, _dbus_keyring_test);
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,11 @@ struct DBusTransport
|
|||
void *unix_user_data; /**< Data for unix_user_function */
|
||||
|
||||
DBusFreeFunction free_unix_user_data; /**< Function to free unix_user_data */
|
||||
|
||||
DBusAllowWindowsUserFunction windows_user_function; /**< Function for checking whether a user is authorized. */
|
||||
void *windows_user_data; /**< Data for windows_user_function */
|
||||
|
||||
DBusFreeFunction free_windows_user_data; /**< Function to free windows_user_data */
|
||||
|
||||
unsigned int disconnected : 1; /**< #TRUE if we are disconnected. */
|
||||
unsigned int authenticated : 1; /**< Cache of auth state; use _dbus_transport_get_is_authenticated() to query value */
|
||||
|
|
|
|||
|
|
@ -167,6 +167,10 @@ _dbus_transport_init_base (DBusTransport *transport,
|
|||
transport->unix_user_data = NULL;
|
||||
transport->free_unix_user_data = NULL;
|
||||
|
||||
transport->windows_user_function = NULL;
|
||||
transport->windows_user_data = NULL;
|
||||
transport->free_windows_user_data = NULL;
|
||||
|
||||
transport->expected_guid = NULL;
|
||||
|
||||
/* Try to default to something that won't totally hose the system,
|
||||
|
|
@ -202,6 +206,9 @@ _dbus_transport_finalize_base (DBusTransport *transport)
|
|||
|
||||
if (transport->free_unix_user_data != NULL)
|
||||
(* transport->free_unix_user_data) (transport->unix_user_data);
|
||||
|
||||
if (transport->free_windows_user_data != NULL)
|
||||
(* transport->free_windows_user_data) (transport->windows_user_data);
|
||||
|
||||
_dbus_message_loader_unref (transport->loader);
|
||||
_dbus_auth_unref (transport->auth);
|
||||
|
|
@ -491,12 +498,157 @@ _dbus_transport_get_is_connected (DBusTransport *transport)
|
|||
return !transport->disconnected;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
auth_via_unix_user_function (DBusTransport *transport)
|
||||
{
|
||||
DBusCredentials *auth_identity;
|
||||
dbus_bool_t allow;
|
||||
DBusConnection *connection;
|
||||
DBusAllowUnixUserFunction unix_user_function;
|
||||
void *unix_user_data;
|
||||
dbus_uid_t uid;
|
||||
|
||||
/* Dropping the lock here probably isn't that safe. */
|
||||
|
||||
auth_identity = _dbus_auth_get_identity (transport->auth);
|
||||
_dbus_assert (auth_identity != NULL);
|
||||
|
||||
connection = transport->connection;
|
||||
unix_user_function = transport->unix_user_function;
|
||||
unix_user_data = transport->unix_user_data;
|
||||
uid = _dbus_credentials_get_unix_uid (auth_identity),
|
||||
|
||||
_dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_connection_unlock (connection);
|
||||
|
||||
allow = (* unix_user_function) (connection,
|
||||
uid,
|
||||
unix_user_data);
|
||||
|
||||
_dbus_verbose ("lock %s post unix user function\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_connection_lock (connection);
|
||||
|
||||
if (allow)
|
||||
{
|
||||
_dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbus_verbose ("Client UID "DBUS_UID_FORMAT
|
||||
" was rejected, disconnecting\n",
|
||||
_dbus_credentials_get_unix_uid (auth_identity));
|
||||
_dbus_transport_disconnect (transport);
|
||||
}
|
||||
|
||||
return allow;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
auth_via_windows_user_function (DBusTransport *transport)
|
||||
{
|
||||
DBusCredentials *auth_identity;
|
||||
dbus_bool_t allow;
|
||||
DBusConnection *connection;
|
||||
DBusAllowWindowsUserFunction windows_user_function;
|
||||
void *windows_user_data;
|
||||
char *windows_sid;
|
||||
|
||||
/* Dropping the lock here probably isn't that safe. */
|
||||
|
||||
auth_identity = _dbus_auth_get_identity (transport->auth);
|
||||
_dbus_assert (auth_identity != NULL);
|
||||
|
||||
connection = transport->connection;
|
||||
windows_user_function = transport->windows_user_function;
|
||||
windows_user_data = transport->unix_user_data;
|
||||
windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
|
||||
|
||||
if (windows_sid == NULL)
|
||||
{
|
||||
/* OOM */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_connection_unlock (connection);
|
||||
|
||||
allow = (* windows_user_function) (connection,
|
||||
windows_sid,
|
||||
windows_user_data);
|
||||
|
||||
_dbus_verbose ("lock %s post windows user function\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_connection_lock (connection);
|
||||
|
||||
if (allow)
|
||||
{
|
||||
_dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
|
||||
_dbus_credentials_get_windows_sid (auth_identity));
|
||||
_dbus_transport_disconnect (transport);
|
||||
}
|
||||
|
||||
return allow;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
auth_via_default_rules (DBusTransport *transport)
|
||||
{
|
||||
DBusCredentials *auth_identity;
|
||||
DBusCredentials *our_identity;
|
||||
dbus_bool_t allow;
|
||||
|
||||
auth_identity = _dbus_auth_get_identity (transport->auth);
|
||||
_dbus_assert (auth_identity != NULL);
|
||||
|
||||
/* By default, connection is allowed if the client is
|
||||
* 1) root or 2) has the same UID as us
|
||||
*/
|
||||
|
||||
our_identity = _dbus_credentials_new_from_current_process ();
|
||||
if (our_identity == NULL)
|
||||
{
|
||||
/* OOM */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_dbus_credentials_get_unix_uid (auth_identity) == 0 ||
|
||||
_dbus_credentials_same_user (our_identity,
|
||||
auth_identity))
|
||||
{
|
||||
/* FIXME the verbose spam here is unix-specific */
|
||||
_dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
|
||||
" matching our UID "DBUS_UID_FORMAT"\n",
|
||||
_dbus_credentials_get_unix_uid(auth_identity),
|
||||
_dbus_credentials_get_unix_uid(our_identity));
|
||||
/* We have authenticated! */
|
||||
allow = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME the verbose spam here is unix-specific */
|
||||
_dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
|
||||
" but our UID is "DBUS_UID_FORMAT", disconnecting\n",
|
||||
_dbus_credentials_get_unix_uid(our_identity),
|
||||
_dbus_credentials_get_unix_uid(our_identity));
|
||||
_dbus_transport_disconnect (transport);
|
||||
allow = FALSE;
|
||||
}
|
||||
|
||||
_dbus_credentials_unref (our_identity);
|
||||
|
||||
return allow;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns #TRUE if we have been authenticated. Will return #TRUE
|
||||
* even if the transport is disconnected.
|
||||
*
|
||||
* @todo we drop connection->mutex when calling the unix_user_function,
|
||||
* which may not be safe really.
|
||||
* and windows_user_function, which may not be safe really.
|
||||
*
|
||||
* @param transport the transport
|
||||
* @returns whether we're authenticated
|
||||
|
|
@ -532,6 +684,8 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
|
|||
}
|
||||
}
|
||||
|
||||
/* If we're the client, verify the GUID
|
||||
*/
|
||||
if (maybe_authenticated && !transport->is_server)
|
||||
{
|
||||
const char *server_guid;
|
||||
|
|
@ -560,106 +714,40 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
* done, for example they may allow connection as any identity,
|
||||
* but then impose restrictions on certain identities.
|
||||
* Or they may give certain identities extra privileges.
|
||||
|
||||
/* If we're the server, see if we want to allow this identity to proceed.
|
||||
*/
|
||||
|
||||
if (maybe_authenticated && transport->is_server)
|
||||
{
|
||||
dbus_bool_t allow;
|
||||
DBusCredentials *auth_identity;
|
||||
|
||||
|
||||
auth_identity = _dbus_auth_get_identity (transport->auth);
|
||||
_dbus_assert (auth_identity != NULL);
|
||||
|
||||
/* If we have a UNIX user and a unix user function, delegate
|
||||
* deciding whether auth credentials are good enough to the app;
|
||||
* otherwise, use our default decision process.
|
||||
|
||||
/* If we have an auth'd user and a user function, delegate
|
||||
* deciding whether auth credentials are good enough to the
|
||||
* app; otherwise, use our default decision process.
|
||||
*/
|
||||
if (transport->unix_user_function != NULL &&
|
||||
_dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
|
||||
{
|
||||
dbus_bool_t allow;
|
||||
DBusConnection *connection;
|
||||
DBusAllowUnixUserFunction unix_user_function;
|
||||
void *unix_user_data;
|
||||
dbus_uid_t uid;
|
||||
|
||||
/* Dropping the lock here probably isn't that safe. */
|
||||
|
||||
connection = transport->connection;
|
||||
unix_user_function = transport->unix_user_function;
|
||||
unix_user_data = transport->unix_user_data;
|
||||
uid = _dbus_credentials_get_unix_uid (auth_identity),
|
||||
|
||||
_dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_connection_unlock (connection);
|
||||
|
||||
allow = (* unix_user_function) (connection,
|
||||
uid,
|
||||
unix_user_data);
|
||||
|
||||
_dbus_verbose ("lock %s post unix user function\n", _DBUS_FUNCTION_NAME);
|
||||
_dbus_connection_lock (connection);
|
||||
|
||||
if (allow)
|
||||
{
|
||||
_dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dbus_verbose ("Client UID "DBUS_UID_FORMAT
|
||||
" was rejected, disconnecting\n",
|
||||
_dbus_credentials_get_unix_uid (auth_identity));
|
||||
_dbus_transport_disconnect (transport);
|
||||
_dbus_connection_unref_unlocked (connection);
|
||||
return FALSE;
|
||||
}
|
||||
allow = auth_via_unix_user_function (transport);
|
||||
}
|
||||
else if (transport->windows_user_function != NULL &&
|
||||
_dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
|
||||
{
|
||||
allow = auth_via_windows_user_function (transport);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBusCredentials *our_identity;
|
||||
|
||||
/* By default, connection is allowed if the client is
|
||||
* 1) root or 2) has the same UID as us
|
||||
*/
|
||||
|
||||
our_identity = _dbus_credentials_new_from_current_process ();
|
||||
if (our_identity == NULL)
|
||||
{
|
||||
/* OOM */
|
||||
_dbus_connection_unref_unlocked (transport->connection);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_dbus_credentials_get_unix_uid (auth_identity) == 0 ||
|
||||
!_dbus_credentials_same_user (our_identity,
|
||||
auth_identity))
|
||||
{
|
||||
/* FIXME the verbose spam here is unix-specific */
|
||||
_dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
|
||||
" but our UID is "DBUS_UID_FORMAT", disconnecting\n",
|
||||
_dbus_credentials_get_unix_uid(our_identity),
|
||||
_dbus_credentials_get_unix_uid(our_identity));
|
||||
_dbus_transport_disconnect (transport);
|
||||
_dbus_connection_unref_unlocked (transport->connection);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME the verbose spam here is unix-specific */
|
||||
_dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
|
||||
" matching our UID "DBUS_UID_FORMAT"\n",
|
||||
_dbus_credentials_get_unix_uid(auth_identity),
|
||||
_dbus_credentials_get_unix_uid(our_identity));
|
||||
}
|
||||
allow = auth_via_default_rules (transport);
|
||||
}
|
||||
|
||||
if (!allow)
|
||||
maybe_authenticated = FALSE;
|
||||
}
|
||||
|
||||
|
||||
transport->authenticated = maybe_authenticated;
|
||||
|
||||
_dbus_connection_unref_unlocked (transport->connection);
|
||||
|
|
@ -1136,6 +1224,65 @@ _dbus_transport_set_unix_user_function (DBusTransport *transport,
|
|||
transport->free_unix_user_data = free_data_function;
|
||||
}
|
||||
|
||||
/**
|
||||
* See dbus_connection_get_windows_user().
|
||||
*
|
||||
* @param transport the transport
|
||||
* @param windows_sid_p return location for the user ID
|
||||
* @returns #TRUE if user is available; the returned value may still be #NULL if no memory to copy it
|
||||
*/
|
||||
dbus_bool_t
|
||||
_dbus_transport_get_windows_user (DBusTransport *transport,
|
||||
char **windows_sid_p)
|
||||
{
|
||||
DBusCredentials *auth_identity;
|
||||
|
||||
*windows_sid_p = NULL;
|
||||
|
||||
if (!transport->authenticated)
|
||||
return FALSE;
|
||||
|
||||
auth_identity = _dbus_auth_get_identity (transport->auth);
|
||||
|
||||
if (_dbus_credentials_include (auth_identity,
|
||||
DBUS_CREDENTIAL_WINDOWS_SID))
|
||||
{
|
||||
/* If no memory, we are supposed to return TRUE and set NULL */
|
||||
*windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See dbus_connection_set_windows_user_function().
|
||||
*
|
||||
* @param transport the transport
|
||||
* @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_transport_set_windows_user_function (DBusTransport *transport,
|
||||
DBusAllowWindowsUserFunction function,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_function,
|
||||
void **old_data,
|
||||
DBusFreeFunction *old_free_data_function)
|
||||
{
|
||||
*old_data = transport->windows_user_data;
|
||||
*old_free_data_function = transport->free_windows_user_data;
|
||||
|
||||
transport->windows_user_function = function;
|
||||
transport->windows_user_data = data;
|
||||
transport->free_windows_user_data = free_data_function;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SASL authentication mechanisms supported by this transport.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -68,6 +68,14 @@ void _dbus_transport_set_unix_user_function (DBusTransport
|
|||
DBusFreeFunction free_data_function,
|
||||
void **old_data,
|
||||
DBusFreeFunction *old_free_data_function);
|
||||
dbus_bool_t _dbus_transport_get_windows_user (DBusTransport *transport,
|
||||
char **windows_sid_p);
|
||||
void _dbus_transport_set_windows_user_function (DBusTransport *transport,
|
||||
DBusAllowWindowsUserFunction function,
|
||||
void *data,
|
||||
DBusFreeFunction free_data_function,
|
||||
void **old_data,
|
||||
DBusFreeFunction *old_free_data_function);
|
||||
dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
|
||||
const char **mechanisms);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue