From 0e85f07781f8eab9670e06cee32b38657e3b62ce Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Thu, 24 May 2012 14:51:46 -0400 Subject: [PATCH] Combine action and details parameters This also removes the ability to change detail parameters which is actually a good thing. If we later need a way to change the authentication message, we can always add something like polkit.addAuthenticationMessageRule() so the user can register a function returning a string. Signed-off-by: David Zeuthen --- docs/man/polkit.xml | 379 ++++++++++-------- src/polkitbackend/50-default.rules | 2 +- src/polkitbackend/init.js | 26 +- src/polkitbackend/polkitbackendjsauthority.c | 106 ++--- .../etc/polkit-1/rules.d/10-testing.rules | 83 ++-- .../etc/polkit-1/rules.d/15-testing.rules | 19 +- .../share/polkit-1/rules.d/10-testing.rules | 12 +- .../share/polkit-1/rules.d/20-testing.rules | 22 +- .../test-polkitbackendjsauthority.c | 85 +++- 9 files changed, 382 insertions(+), 352 deletions(-) diff --git a/docs/man/polkit.xml b/docs/man/polkit.xml index de4bb4a..9718541 100644 --- a/docs/man/polkit.xml +++ b/docs/man/polkit.xml @@ -484,120 +484,196 @@ System Context | | programming language and interface with polkitd through the global polkit object (of type Polkit). - The following methods are available: - - - - void addRule - string function(action, subject, details) {...} - - - - - - - void addAdminRule - string[] function(action, subject, details) {...} - - - - - - - void log - string message - - - - - - - string spawn - string[] argv - - + + The <type>Polkit</type> type - - The addRule() method is used for adding a - function that may be called whenever an authorization check for - action, subject - and details is performed. Functions are - called in the order they have been added until one of the - functions returns a value. Hence, to add an authorization rule - that is processed before other rules, put it in a file in - /etc/polkit-1/rules.d - with a name that sorts before other rules files, for example - 00-early-checks.rules. Each function should - return one of the values "no", - "yes", "auth_self", - "auth_self_keep", - "auth_admin", - "auth_admin_keep" as defined above. If the - function returns null, - undefined or does not return a value at - all, the next function is tried. - + + The following methods are available on the polkit object: + - - The addAdminRule() method is used for - adding a function may be called whenever administrator - authentication is required. The function is used to specify what - identies may be used for administrator authentication for the - authorization check identified by action, - subject and - details. Functions added are called in - the order they have been added until one of the functions - returns a value. Each function should return an array of strings - where each string is of the form - "unix-group:<group>", - "unix-netgroup:<netgroup>" or - "unix-user:<user>". If the function - returns null, - undefined or does not return a value at - all, the next function is tried. - + + + + void addRule + string function(action, subject) {...} + + - - There is no guarantee that a function registered with - addRule() or - addAdminRule() is ever called - for example - an early rules file could register a function that always return - a value, hence ensuring that functions added later are never - called. - + + + + void addAdminRule + string[] function(action, subject) {...} + + - - If user-provided code takes a long time to execute an exception - will be thrown which normally results in the function being - terminated (the current limit is 15 seconds). This is used to - catch runaway scripts. - + + + + void log + string message + + - - The log() method writes the given - message to the system logger. Log entries - are emitted using the LOG_AUTHPRIV flag - meaning that the log entries usually ends up in the file - /var/log/secure. The - log() method is usually only used when - debugging rules. - + + + + string spawn + string[] argv + + - - The spawn() method spawns an external - helper identified by the argument vector - argv and waits for it to terminate. If an - error occurs or the helper doesn't exit normally with exit code - 0, an exception is thrown. If the helper does not exit within 10 - seconds it is killed. Otherwise, the program's - standard output is returned as a string. - The spawn() method should be used sparingly - as helpers may take a very long or indeterminate amount of time - to complete and no other authorization check can be handled - while the helper is running. - + + The addRule() method is used for adding a + function that may be called whenever an authorization check for + action and subject + is performed. Functions are + called in the order they have been added until one of the + functions returns a value. Hence, to add an authorization rule + that is processed before other rules, put it in a file in + /etc/polkit-1/rules.d + with a name that sorts before other rules files, for example + 00-early-checks.rules. Each function should + return one of the values "no", + "yes", "auth_self", + "auth_self_keep", + "auth_admin", + "auth_admin_keep" as defined above. If the + function returns null, + undefined or does not return a value at + all, the next function is tried. + + + + The addAdminRule() method is used for + adding a function may be called whenever administrator + authentication is required. The function is used to specify what + identies may be used for administrator authentication for the + authorization check identified by action + and subject. Functions added are called in + the order they have been added until one of the functions + returns a value. Each function should return an array of strings + where each string is of the form + "unix-group:<group>", + "unix-netgroup:<netgroup>" or + "unix-user:<user>". If the function + returns null, + undefined or does not return a value at + all, the next function is tried. + + + + There is no guarantee that a function registered with + addRule() or + addAdminRule() is ever called - for example + an early rules file could register a function that always return + a value, hence ensuring that functions added later are never + called. + + + + If user-provided code takes a long time to execute an exception + will be thrown which normally results in the function being + terminated (the current limit is 15 seconds). This is used to + catch runaway scripts. + + + + The spawn() method spawns an external + helper identified by the argument vector + argv and waits for it to terminate. If an + error occurs or the helper doesn't exit normally with exit code + 0, an exception is thrown. If the helper does not exit within 10 + seconds it is killed. Otherwise, the program's + standard output is returned as a string. + The spawn() method should be used sparingly + as helpers may take a very long or indeterminate amount of time + to complete and no other authorization check can be handled + while the helper is running. + + + + The log() method writes the given + message to the system logger prefixed + with the JavaScript filename and line number. Log entries are + emitted using the LOG_AUTHPRIV flag meaning + that the log entries usually ends up in the file + /var/log/secure. The + log() method is usually only used when + debugging rules. The Action and + Subject types has suitable + toString() methods defined for easy + logging, for example, + + + + will produce the following when the user runs 'pkexec bash -i' from a shelll: + + + + + + + The <type>Action</type> type + + + The action parameter passed to user + functions is an object with information about the action + being checked. It is of type Action and has + the following attribute: + + + + + string id + + + The action identifier, for example + org.freedesktop.policykit.exec. + + + + + + + The following methods are available on the Action type: + + + + + + string lookup + string key + + + + + The lookup() method is used to lookup the + polkit variables passed from the mechanism. For example, the + pkexec1 + mechanism sets the variable program + which can be obtained in Javascript using the expression + action.lookup("program"). If there is + no value for the given key, + then undefined is returned. + + + Consult the documentation for each mechanism for what + variables are available for each action. + + The <type>Subject</type> type @@ -700,52 +776,6 @@ System Context | | isInNetGroup() can be used to check if the subject is in a given netgroup. - - - - - The <type>Details</type> type - - - The details parameter passed to user - functions is an object with more information about the action - being checked. It is of type Details and has - details being set by the mechanism as attributes. For example, - the pkexec1 - mechanism sets the variable program - which can be obtained in Javascript using the expression - details["program"]. Consult the - documentation for each mechanism for what variables are - available for each action. - - - - The details also has the following - well-known attributes: - - - - polkit.message - - - The message to show in the authentication dialog (only - used if authentication is needed). Its initial value is - taken from the action declaration (the message element in the .policy file) but the value - can be overridden by the mechanism setting this key in - the details passed when doing the - CheckAuthorization() - call. - - - - - - Note that a rule can set the - polkit.message attribute to change the - message shown in the authentication dialog. - @@ -757,8 +787,8 @@ System Context | | users: wheel group: Forbid users in group children to change - hostname configuration (that is, any action starting with - org.freedesktop.hostname1.) and allow - anyone else to do it after authenticating as themselves: + hostname configuration (that is, any action with an identifier + starting with org.freedesktop.hostname1.) + and allow anyone else to do it after authenticating as + themselves: - The following example showcases two things + The following example shows how the authorization decision + can depend on variables passed by the + pkexec1 + mechanism: - - how the authorization decision can depend on variables passed by the mechanism - how to override the message shown in the authentication dialog - priv->cx, authority->priv->js_global, src, strlen (src), @@ -831,18 +831,18 @@ details_to_jsval (PolkitBackendJsAuthority *authority, } obj = JSVAL_TO_OBJECT (ret_jsval); + + set_property_str (authority, obj, "id", action_id); + keys = polkit_details_get_keys (details); for (n = 0; keys != NULL && keys[n] != NULL; n++) { - const gchar *key = keys[n]; - JSString *value_jsstr; - jsval value_jsval; + gchar *key; const gchar *value; - + key = g_strdup_printf ("_detail_%s", keys[n]); value = polkit_details_lookup (details, keys[n]); - value_jsstr = JS_NewStringCopyZ (authority->priv->cx, value); - value_jsval = STRING_TO_JSVAL (value_jsstr); - JS_SetProperty (authority->priv->cx, obj, key, &value_jsval); + set_property_str (authority, obj, key, value); + g_free (key); } g_free (keys); @@ -990,31 +990,27 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA { PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority); GList *ret = NULL; - jsval argv[3] = {0}; + jsval argv[2] = {0}; jsval rval = {0}; - JSString *action_id_jstr; guint n; GError *error = NULL; JSString *ret_jsstr; gchar *ret_str = NULL; gchar **ret_strs = NULL; - action_id_jstr = JS_NewStringCopyZ (authority->priv->cx, action_id); - argv[0] = STRING_TO_JSVAL (action_id_jstr); - - if (!subject_to_jsval (authority, subject, user_for_subject, &argv[1], &error)) + if (!action_and_details_to_jsval (authority, action_id, details, &argv[0], &error)) { polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), - "Error converting subject to JS object: %s", + "Error converting action and details to JS object: %s", error->message); g_clear_error (&error); goto out; } - if (!details_to_jsval (authority, details, &argv[2], &error)) + if (!subject_to_jsval (authority, subject, user_for_subject, &argv[1], &error)) { polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), - "Error converting details to JS object: %s", + "Error converting subject to JS object: %s", error->message); g_clear_error (&error); goto out; @@ -1022,7 +1018,7 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA if (!call_js_function_with_runaway_killer (authority, "_runAdminRules", - 3, + 2, argv, &rval)) { @@ -1093,34 +1089,27 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu { PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority); PolkitImplicitAuthorization ret = implicit; - jsval argv[3] = {0}; + jsval argv[2] = {0}; jsval rval = {0}; - JSString *action_id_jstr; GError *error = NULL; JSString *ret_jsstr; const jschar *ret_utf16; gchar *ret_str = NULL; gboolean good = FALSE; - JSIdArray *ids; - JSObject *details_obj; - gint n; - action_id_jstr = JS_NewStringCopyZ (authority->priv->cx, action_id); - argv[0] = STRING_TO_JSVAL (action_id_jstr); - - if (!subject_to_jsval (authority, subject, user_for_subject, &argv[1], &error)) + if (!action_and_details_to_jsval (authority, action_id, details, &argv[0], &error)) { polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), - "Error converting subject to JS object: %s", + "Error converting action and details to JS object: %s", error->message); g_clear_error (&error); goto out; } - if (!details_to_jsval (authority, details, &argv[2], &error)) + if (!subject_to_jsval (authority, subject, user_for_subject, &argv[1], &error)) { polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), - "Error converting details to JS object: %s", + "Error converting subject to JS object: %s", error->message); g_clear_error (&error); goto out; @@ -1169,53 +1158,6 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu goto out; } - - /* the JS code may have modifed @details - update PolkitDetails - * object accordingly - */ - details_obj = JSVAL_TO_OBJECT (argv[2]); - ids = JS_Enumerate (authority->priv->cx, details_obj); - if (ids == NULL) - { - polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority), - "Failed to enumerate properties of Details object"); - goto out; - } - for (n = 0; n < ids->length; n++) - { - jsval id_val; - jsval value_val; - char *id_s = NULL; - char *value_s = NULL; - - if (!JS_IdToValue (authority->priv->cx, ids->vector[n], &id_val)) - { - g_warning ("Error getting string for property id %d", n); - goto cont; - } - id_s = JS_EncodeString (authority->priv->cx, JSVAL_TO_STRING (id_val)); - - if (!JS_GetPropertyById (authority->priv->cx, details_obj, ids->vector[n], &value_val)) - { - g_warning ("Error getting value string for property value %s", id_s); - goto cont; - } - - /* skip e.g. functions */ - if (!JSVAL_IS_STRING (value_val) && !JSVAL_IS_NULL (value_val)) - goto cont; - - value_s = JS_EncodeString (authority->priv->cx, JSVAL_TO_STRING (value_val)); - - polkit_details_insert (details, id_s, value_s); - cont: - if (id_s != NULL) - JS_free (authority->priv->cx, id_s); - if (value_s != NULL) - JS_free (authority->priv->cx, value_s); - } - JS_DestroyIdArray (authority->priv->cx, ids); - good = TRUE; out: diff --git a/test/data/etc/polkit-1/rules.d/10-testing.rules b/test/data/etc/polkit-1/rules.d/10-testing.rules index 1dba38a..4a17f8c 100644 --- a/test/data/etc/polkit-1/rules.d/10-testing.rules +++ b/test/data/etc/polkit-1/rules.d/10-testing.rules @@ -4,55 +4,75 @@ /* NOTE: this is the /etc/polkit-1/rules.d version of 10-testing.rules */ -polkit.addAdminRule(function(action, subject, details) { - if (action == "net.company.action1") { +// --------------------------------------------------------------------- +// admin rules + +polkit.addAdminRule(function(action, subject) { + if (action.id == "net.company.action1") { return ["unix-group:admin"]; } }); -polkit.addAdminRule(function(action, subject, details) { - if (action == "net.company.action2") { +polkit.addAdminRule(function(action, subject) { + if (action.id == "net.company.action2") { return ["unix-group:users"]; } }); -polkit.addAdminRule(function(action, subject, details) { - if (action == "net.company.action3") { +polkit.addAdminRule(function(action, subject) { + if (action.id == "net.company.action3") { return ["unix-netgroup:foo"]; } }); // Fallback -polkit.addAdminRule(function(action, subject, details) { +polkit.addAdminRule(function(action, subject) { return ["unix-group:admin", "unix-user:root"]; }); // ----- -polkit.addRule(function(action, subject, details) { - if (action == "net.company.productA.action0") { +// --------------------------------------------------------------------- +// basics + +polkit.addRule(function(action, subject) { + if (action.id == "net.company.productA.action0") { return "auth_admin"; } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.productA.action1") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.productA.action1") { return "auth_self"; } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order0") { - details["test_detail"] = "a"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order0") { return "yes"; } }); +// --------------------------------------------------------------------- +// variables + +polkit.addRule(function(action, subject) { + if (action.id == "net.company.group.variables") { + if (action.lookup("foo") == "1") + return "yes"; + else if (action.lookup("foo") == "2") + return "auth_self"; + else + return "auth_admin"; + } +}); + + // --------------------------------------------------------------------- // group membership -polkit.addRule(function(action, subject, details) { - if (action == "net.company.group.only_group_users") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.group.only_group_users") { if (subject.isInGroup("users")) return "yes"; else @@ -63,8 +83,8 @@ polkit.addRule(function(action, subject, details) { // --------------------------------------------------------------------- // netgroup membership -polkit.addRule(function(action, subject, details) { - if (action == "net.company.group.only_netgroup_users") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.group.only_netgroup_users") { if (subject.isInNetGroup("foo")) return "yes"; else @@ -75,8 +95,8 @@ polkit.addRule(function(action, subject, details) { // --------------------------------------------------------------------- // spawning -polkit.addRule(function(action, subject, details) { - if (action == "net.company.spawning.non_existing_helper") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.spawning.non_existing_helper") { try { polkit.spawn(["/path/to/non/existing/helper"]); return "no"; @@ -86,8 +106,8 @@ polkit.addRule(function(action, subject, details) { } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.spawning.successful_helper") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.spawning.successful_helper") { try { polkit.spawn(["/bin/true"]); return "yes"; @@ -97,8 +117,8 @@ polkit.addRule(function(action, subject, details) { } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.spawning.failing_helper") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.spawning.failing_helper") { try { polkit.spawn(["/bin/false"]); return "no"; @@ -108,8 +128,8 @@ polkit.addRule(function(action, subject, details) { } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.spawning.helper_with_output") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.spawning.helper_with_output") { try { var out = polkit.spawn(["echo", "-n", "-e", "Hello\nWorld"]); if (out == "Hello\nWorld") @@ -122,8 +142,8 @@ polkit.addRule(function(action, subject, details) { } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.spawning.helper_timeout") { +polkit.addRule(function(action, subject) { + if (action.id == "net.company.spawning.helper_timeout") { try { polkit.spawn(["sleep", "20"]); return "no"; @@ -135,8 +155,11 @@ polkit.addRule(function(action, subject, details) { } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.run_away_script") { +// --------------------------------------------------------------------- +// runaway scripts + +polkit.addRule(function(action, subject) { + if (action.id == "net.company.run_away_script") { try { // The following code will never terminate so the runaway // script killer will step in after 15 seconds and throw diff --git a/test/data/etc/polkit-1/rules.d/15-testing.rules b/test/data/etc/polkit-1/rules.d/15-testing.rules index 9968aa7..b64d731 100644 --- a/test/data/etc/polkit-1/rules.d/15-testing.rules +++ b/test/data/etc/polkit-1/rules.d/15-testing.rules @@ -2,23 +2,20 @@ /* see test/polkitbackend/test-polkitbackendjsauthority.c */ -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order0") { - details["test_detail"] = "c"; - return "yes"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order0") { + return "no"; // earlier rule should win } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order1") { - details["test_detail"] = "c"; - return "yes"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order1") { + return "no"; // earlier rule should win } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order2") { - details["test_detail"] = "c"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order2") { return "yes"; } }); diff --git a/test/data/usr/share/polkit-1/rules.d/10-testing.rules b/test/data/usr/share/polkit-1/rules.d/10-testing.rules index 48c4957..c60e262 100644 --- a/test/data/usr/share/polkit-1/rules.d/10-testing.rules +++ b/test/data/usr/share/polkit-1/rules.d/10-testing.rules @@ -4,16 +4,14 @@ /* NOTE: this is the /usr/share/polkit-1/rules.d version of 10-testing.rules */ -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order0") { - details["test_detail"] = "c"; - return "yes"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order0") { + return "no"; // earlier rule should win } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order1") { - details["test_detail"] = "b"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order1") { return "yes"; } }); diff --git a/test/data/usr/share/polkit-1/rules.d/20-testing.rules b/test/data/usr/share/polkit-1/rules.d/20-testing.rules index 16dd039..5c5bb2c 100644 --- a/test/data/usr/share/polkit-1/rules.d/20-testing.rules +++ b/test/data/usr/share/polkit-1/rules.d/20-testing.rules @@ -2,24 +2,20 @@ /* see test/polkitbackend/test-polkitbackendjsauthority.c */ -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order0") { - polkit.log("blabla"); - details["test_detail"] = "d"; - return "yes"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order0") { + return "no"; // earlier rule should win } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order1") { - details["test_detail"] = "d"; - return "yes"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order1") { + return "no"; // earlier rule should win } }); -polkit.addRule(function(action, subject, details) { - if (action == "net.company.order2") { - details["test_detail"] = "d"; - return "yes"; +polkit.addRule(function(action, subject) { + if (action.id == "net.company.order2") { + return "no"; // earlier rule should win } }); diff --git a/test/polkitbackend/test-polkitbackendjsauthority.c b/test/polkitbackend/test-polkitbackendjsauthority.c index 728b433..0a5d0e8 100644 --- a/test/polkitbackend/test-polkitbackendjsauthority.c +++ b/test/polkitbackend/test-polkitbackendjsauthority.c @@ -24,6 +24,8 @@ #include "glib.h" #include +#include + #include #include #include @@ -156,8 +158,8 @@ struct RulesTestCase const gchar *test_name; const gchar *action_id; const gchar *identity; + const gchar *vars; PolkitImplicitAuthorization expected_result; - const gchar *expected_detail; }; static const RulesTestCase rules_test_cases[] = { @@ -166,15 +168,15 @@ static const RulesTestCase rules_test_cases[] = { "basic0", "net.company.productA.action0", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED, - NULL }, { "basic1", "net.company.productA.action1", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED, - NULL }, /* Ordering tests ... we have four rules files, check they are @@ -192,24 +194,47 @@ static const RulesTestCase rules_test_cases[] = { "order0", "net.company.order0", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - "a" }, { /* defined in file b, c, d - should pick file b */ "order1", "net.company.order1", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - "b" }, { /* defined in file c, d - should pick file c */ "order2", "net.company.order2", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - "c" + }, + + /* variables */ + { + "variables1", + "net.company.group.variables", + "unix-user:root", + "foo=1", + POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, + }, + { + "variables2", + "net.company.group.variables", + "unix-user:root", + "foo=2", + POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED, + }, + { + "variables3", + "net.company.group.variables", + "unix-user:root", + NULL, + POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED, }, /* check group membership */ @@ -218,16 +243,16 @@ static const RulesTestCase rules_test_cases[] = { "group_membership_with_member", "net.company.group.only_group_users", "unix-user:john", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, { /* sally is not a member of group 'users', see test/etc/group */ "group_membership_with_non_member", "net.company.group.only_group_users", "unix-user:sally", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, - NULL }, /* check netgroup membership */ @@ -236,16 +261,16 @@ static const RulesTestCase rules_test_cases[] = { "netgroup_membership_with_member", "net.company.group.only_netgroup_users", "unix-user:john", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, { /* sally is not a member of netgroup 'foo', see test/etc/netgroup */ "netgroup_membership_with_non_member", "net.company.group.only_netgroup_users", "unix-user:sally", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED, - NULL }, /* spawning */ @@ -253,43 +278,45 @@ static const RulesTestCase rules_test_cases[] = { "spawning_non_existing_helper", "net.company.spawning.non_existing_helper", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, { "spawning_successful_helper", "net.company.spawning.successful_helper", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, { "spawning_failing_helper", "net.company.spawning.failing_helper", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, { "spawning_helper_with_output", "net.company.spawning.helper_with_output", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, { - "runaway_script", - "net.company.run_away_script", + "spawning_helper_timeout", + "net.company.spawning.helper_timeout", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, + + /* runaway scripts */ { - "spawning_helper_timeout", - "net.company.spawning.helper_timeout", + "runaway_script", + "net.company.run_away_script", "unix-user:root", + NULL, POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED, - NULL }, }; @@ -316,6 +343,23 @@ rules_test_func (gconstpointer user_data) details = polkit_details_new (); + if (tc->vars != NULL) + { + gchar *s; + const gchar *key; + const gchar *value; + + s = g_strdup (tc->vars); + key = s; + value = strchr (key, '='); + g_assert (value != NULL); + *((gchar *) value) = '\0'; + value += 1; + + polkit_details_insert (details, key, value); + g_free (s); + } + result = polkit_backend_interactive_authority_check_authorization_sync (POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority), caller, subject, @@ -326,7 +370,6 @@ rules_test_func (gconstpointer user_data) details, POLKIT_IMPLICIT_AUTHORIZATION_UNKNOWN); g_assert_cmpint (result, ==, tc->expected_result); - g_assert_cmpstr (polkit_details_lookup (details, "test_detail"), ==, tc->expected_detail); g_clear_object (&user_for_subject); g_clear_object (&subject); -- 2.34.1