From e06de6965d0d9e38bb845d9d6140aaedfe75aebe Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Wed, 7 Aug 2013 23:34:42 +0200 Subject: [PATCH 2/2] Add attribute 'sid' to policy element 'allow'. This patch is required to allow clients connection to a dbus-daemon running as windows service. The sid could be in one of the following form: - a complete sid like S-1-5-21-776561741-1336601894-839522115-1003 - or a sid prefix like S-1-5-21-776561741-1336601894-839522115 --- bus/bus.c | 4 --- bus/config-parser.c | 67 ++++++++++++++++++++++++++++++++---------- bus/connection.c | 19 ++++++++++++ bus/policy.c | 65 ++++++++++++++++++++++++++++++++++++---- bus/policy.h | 12 ++++++-- dbus/dbus-sysdeps-util-win.c | 17 ++++++++++- dbus/dbus-sysdeps-win.c | 2 +- dbus/dbus-sysdeps.h | 2 ++ 8 Dateien geändert, 159 Zeilen hinzugefügt(+), 29 Zeilen entfernt(-) diff --git a/bus/bus.c b/bus/bus.c index 307c158..f6bf83d 100644 --- a/bus/bus.c +++ b/bus/bus.c @@ -1183,10 +1183,6 @@ bus_context_allow_unix_user (BusContext *context, 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) diff --git a/bus/config-parser.c b/bus/config-parser.c index 6b59dfc..a7a746f 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -1164,6 +1164,7 @@ append_rule_from_element (BusConfigParser *parser, const char *own_prefix; const char *user; const char *group; + const char *sid; BusPolicyRule *rule; @@ -1189,6 +1190,7 @@ append_rule_from_element (BusConfigParser *parser, "own", &own, "own_prefix", &own_prefix, "user", &user, + "sid", &sid, "group", &group, "log", &log, NULL)) @@ -1199,7 +1201,7 @@ append_rule_from_element (BusConfigParser *parser, receive_interface || receive_member || receive_error || receive_sender || receive_type || receive_path || eavesdrop || send_requested_reply || receive_requested_reply || - own || own_prefix || user || group)) + own || own_prefix || user || group || sid)) { dbus_set_error (error, DBUS_ERROR_FAILED, "Element <%s> must have one or more attributes", @@ -1240,7 +1242,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_member && (send_error || receive_interface || @@ -1250,7 +1253,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_error && (receive_interface || receive_member || @@ -1259,7 +1263,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_destination && (receive_interface || receive_member || @@ -1268,7 +1273,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_type && (receive_interface || receive_member || @@ -1277,7 +1283,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_path && (receive_interface || receive_member || @@ -1286,7 +1293,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_requested_reply && (receive_interface || receive_member || @@ -1295,35 +1303,41 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group|| + sid)) || (receive_interface && (receive_error || own || own_prefix || user || - group)) || + group || + sid)) || (receive_member && (receive_error || own || own_prefix || user || - group)) || + group || + sid)) || (receive_error && (own || own_prefix || user || - group)) || + group || + sid)) || (eavesdrop && (own || own_prefix || user || - group)) || + group || + sid)) || (receive_requested_reply && (own || own_prefix || user || - group)) || + group || + sid)) || - (own && (own_prefix || user || group)) || + (own && (own_prefix || user || group || sid)) || - (own_prefix && (own || user || group)) || + (own_prefix && (own || user || group || sid)) || - (user && group)) + (user && group || user && sid || group && sid)) { dbus_set_error (error, DBUS_ERROR_FAILED, "Invalid combination of attributes on element <%s>", @@ -1587,6 +1601,27 @@ append_rule_from_element (BusConfigParser *parser, } } } + else if (sid) + { + if (IS_WILDCARD (sid)) + { + rule = bus_policy_rule_new (BUS_POLICY_RULE_SID, allow); + if (rule == NULL) + goto nomem; + + rule->d.sid.sid = DBUS_SID_UNSET; + _dbus_verbose ("adding wildcard sid\n"); + } + else + { + rule = bus_policy_rule_new (BUS_POLICY_RULE_SID, allow); + if (rule == NULL) + goto nomem; + + rule->d.sid.sid = _dbus_strdup(sid); + _dbus_verbose ("adding sid %s\n", sid); + } + } else _dbus_assert_not_reached ("Did not handle some combination of attributes on or "); diff --git a/bus/connection.c b/bus/connection.c index d69758c..25e9665 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -382,6 +382,21 @@ allow_unix_user_function (DBusConnection *connection, return bus_context_allow_unix_user (d->connections->context, uid); } + +static dbus_bool_t +allow_windows_user_function (DBusConnection *connection, + const char *windows_sid, + void *data) +{ + BusConnectionData *d; + + d = BUS_CONNECTION_DATA (connection); + + _dbus_assert (d != NULL); + + return bus_context_allow_windows_user (d->connections->context, windows_sid); +} + static void free_connection_data (void *data) { @@ -657,6 +672,10 @@ bus_connections_setup_connection (BusConnections *connections, * Windows users can connect. The default 'same user that owns the * bus can connect' behavior of DBusConnection is fine on Windows. */ + dbus_connection_set_windows_user_function (connection, + allow_windows_user_function, + NULL, NULL); + dbus_connection_set_unix_user_function (connection, allow_unix_user_function, NULL, NULL); diff --git a/bus/policy.c b/bus/policy.c index 082f385..aa587ad 100644 --- a/bus/policy.c +++ b/bus/policy.c @@ -52,6 +52,9 @@ bus_policy_rule_new (BusPolicyRuleType type, case BUS_POLICY_RULE_GROUP: rule->d.group.gid = DBUS_GID_UNSET; break; + case BUS_POLICY_RULE_SID: + rule->d.sid.sid = DBUS_SID_UNSET; + break; case BUS_POLICY_RULE_SEND: rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID; @@ -116,6 +119,8 @@ bus_policy_rule_unref (BusPolicyRule *rule) break; case BUS_POLICY_RULE_GROUP: break; + case BUS_POLICY_RULE_SID: + break; } dbus_free (rule); @@ -251,6 +256,7 @@ add_list_to_client (DBusList **list, { case BUS_POLICY_RULE_USER: case BUS_POLICY_RULE_GROUP: + case BUS_POLICY_RULE_SID: /* These aren't per-connection policies */ break; @@ -469,6 +475,41 @@ bus_policy_allow_unix_user (BusPolicy *policy, return allowed; } +static dbus_bool_t +list_allows_windows_user (dbus_bool_t def, + DBusList **list, + const char *sid) +{ + DBusList *link; + dbus_bool_t allowed; + + allowed = def; + + link = _dbus_list_get_first_link (list); + while (link != NULL) + { + BusPolicyRule *rule = link->data; + link = _dbus_list_get_next_link (list, link); + + if (rule->type == BUS_POLICY_RULE_SID) + { + _dbus_verbose ("List %p user rule sid=%s\n", + list, rule->d.sid.sid); + + if (rule->d.sid.sid == DBUS_SID_UNSET) + ; /* '*' wildcard */ + else if (strncmp (sid, rule->d.sid.sid, strlen (rule->d.sid.sid)) != 0) + continue; + } + else + continue; + + allowed = rule->allow; + } + + 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 @@ -479,11 +520,24 @@ 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 allowed; + allowed = _dbus_windows_user_is_process_owner (windows_sid); + _dbus_verbose ("SID %s allowed = %d\n", windows_sid, allowed); + + allowed = list_allows_windows_user (allowed, + &policy->default_rules, + windows_sid); + _dbus_verbose ("SID %s allowed = %d\n", windows_sid, allowed); + + allowed = list_allows_windows_user (allowed, + &policy->mandatory_rules, + windows_sid); + + _dbus_verbose ("SID %s allowed = %d\n", windows_sid, allowed); + + return allowed; + + } dbus_bool_t @@ -832,6 +886,7 @@ bus_client_policy_optimize (BusClientPolicy *policy) break; case BUS_POLICY_RULE_USER: case BUS_POLICY_RULE_GROUP: + case BUS_POLICY_RULE_SID: _dbus_assert_not_reached ("invalid rule"); break; } diff --git a/bus/policy.h b/bus/policy.h index d1d3e72..f15fa53 100644 --- a/bus/policy.h +++ b/bus/policy.h @@ -36,12 +36,14 @@ typedef enum BUS_POLICY_RULE_RECEIVE, BUS_POLICY_RULE_OWN, BUS_POLICY_RULE_USER, - BUS_POLICY_RULE_GROUP + BUS_POLICY_RULE_GROUP, + BUS_POLICY_RULE_SID } BusPolicyRuleType; /** determines whether the rule affects a connection, or some global item */ #define BUS_POLICY_RULE_IS_PER_CLIENT(rule) (!((rule)->type == BUS_POLICY_RULE_USER || \ - (rule)->type == BUS_POLICY_RULE_GROUP)) + (rule)->type == BUS_POLICY_RULE_GROUP || \ + (rule)->type == BUS_POLICY_RULE_SID)) struct BusPolicyRule { @@ -102,6 +104,12 @@ struct BusPolicyRule dbus_gid_t gid; } group; + struct + { + /* can be DBUS_SID_UNSET meaning "any" */ + const char* sid; + } sid; + } d; }; diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c index abb10f7..fdf1567 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -769,9 +769,24 @@ _dbus_unix_user_is_process_owner (dbus_uid_t uid) return FALSE; } +dbus_bool_t _dbus_getsid(char **sid, dbus_pid_t process_id); +dbus_pid_t _dbus_getpid (void); + dbus_bool_t _dbus_windows_user_is_process_owner (const char *windows_sid) { - return TRUE; + char *own_sid; + _dbus_verbose ("%s\n", windows_sid); + if (!_dbus_getsid (&own_sid, _dbus_getpid ())) + return FALSE; + + int result = strcmp (windows_sid, own_sid); + + _dbus_verbose ("%s == %s %d\n", windows_sid, own_sid, result); + + if (own_sid) + LocalFree (own_sid); + + return result == 0 ? TRUE : FALSE; } /*===================================================================== diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 20ecb4e..b6e050a 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -979,7 +979,7 @@ static BOOL is_winxp_sp3_or_lower() * @param process_id the process id for which the sid should be returned * @returns process sid */ -static dbus_bool_t +dbus_bool_t _dbus_getsid(char **sid, dbus_pid_t process_id) { HANDLE process_token = INVALID_HANDLE_VALUE; diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 1053303..15f41a9 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -107,6 +107,8 @@ typedef unsigned long dbus_gid_t; #define DBUS_UID_UNSET ((dbus_uid_t) -1) /** an invalid GID used to represent an uninitialized dbus_gid_t field */ #define DBUS_GID_UNSET ((dbus_gid_t) -1) +/** an invalid SID used to represent an uninitialized sid */ +#define DBUS_SID_UNSET ((char *)NULL) /** an appropriate printf format for dbus_pid_t */ #define DBUS_PID_FORMAT "%lu" -- 1.7.10.4