diff options
author | Ralf Habacker <ralf.habacker@freenet.de> | 2013-08-07 23:34:42 +0200 |
---|---|---|
committer | Ralf Habacker <ralf.habacker@freenet.de> | 2013-08-30 09:20:04 +0200 |
commit | 377078835801636ec6d6697d5b3c18610e923e7f (patch) | |
tree | 69b6bea527ec8190aed86567d9a7bf1469ed3246 | |
parent | 17daf33b264162d6e33b914d1861f7c5a43b27ae (diff) |
Add attribute 'sid' to policy element 'allow'.windows-service
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
-rw-r--r-- | bus/bus.c | 4 | ||||
-rw-r--r-- | bus/config-parser.c | 67 | ||||
-rw-r--r-- | bus/connection.c | 19 | ||||
-rw-r--r-- | bus/policy.c | 65 | ||||
-rw-r--r-- | bus/policy.h | 12 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-util-win.c | 17 | ||||
-rw-r--r-- | dbus/dbus-sysdeps-win.c | 2 | ||||
-rw-r--r-- | dbus/dbus-sysdeps.h | 2 |
8 files changed, 159 insertions, 29 deletions
@@ -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 12a2d2e7b..cb9ca7d3f 100644 --- a/bus/config-parser.c +++ b/bus/config-parser.c @@ -1165,6 +1165,7 @@ append_rule_from_element (BusConfigParser *parser, const char *own_prefix; const char *user; const char *group; + const char *sid; BusPolicyRule *rule; @@ -1190,6 +1191,7 @@ append_rule_from_element (BusConfigParser *parser, "own", &own, "own_prefix", &own_prefix, "user", &user, + "sid", &sid, "group", &group, "log", &log, NULL)) @@ -1200,7 +1202,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", @@ -1241,7 +1243,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_member && (send_error || receive_interface || @@ -1251,7 +1254,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_error && (receive_interface || receive_member || @@ -1260,7 +1264,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_destination && (receive_interface || receive_member || @@ -1269,7 +1274,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_type && (receive_interface || receive_member || @@ -1278,7 +1284,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_path && (receive_interface || receive_member || @@ -1287,7 +1294,8 @@ append_rule_from_element (BusConfigParser *parser, receive_requested_reply || own || own_prefix || user || - group)) || + group || + sid)) || (send_requested_reply && (receive_interface || receive_member || @@ -1296,35 +1304,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>", @@ -1588,6 +1602,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 <allow> or <deny>"); diff --git a/bus/connection.c b/bus/connection.c index d69758c97..25e96658d 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 082f3853b..aa587ad79 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 d1d3e72b7..f15fa53a5 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 fe4b1a22c..7bf3d40c4 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -767,9 +767,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 dbc7ae41a..56a662a3d 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 e586946fb..7243ecd59 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -105,6 +105,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" |