summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Habacker <ralf.habacker@freenet.de>2013-08-07 23:34:42 +0200
committerRalf Habacker <ralf.habacker@freenet.de>2013-08-30 09:20:04 +0200
commit377078835801636ec6d6697d5b3c18610e923e7f (patch)
tree69b6bea527ec8190aed86567d9a7bf1469ed3246
parent17daf33b264162d6e33b914d1861f7c5a43b27ae (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.c4
-rw-r--r--bus/config-parser.c67
-rw-r--r--bus/connection.c19
-rw-r--r--bus/policy.c65
-rw-r--r--bus/policy.h12
-rw-r--r--dbus/dbus-sysdeps-util-win.c17
-rw-r--r--dbus/dbus-sysdeps-win.c2
-rw-r--r--dbus/dbus-sysdeps.h2
8 files changed, 159 insertions, 29 deletions
diff --git a/bus/bus.c b/bus/bus.c
index 307c15861..f6bf83df5 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 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"