Commit 0e85f077 authored by David Zeuthen's avatar David Zeuthen
Browse files

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: default avatarDavid Zeuthen <davidz@redhat.com>
parent 2ec9e681
This diff is collapsed.
......@@ -7,6 +7,6 @@
// See the polkit(8) man page for more information
// about configuring polkit.
polkit.addAdminRule(function(action, subject, details) {
polkit.addAdminRule(function(action, subject) {
return ["unix-group:wheel"];
});
/* -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- */
function Details() {
function Action() {
this.lookup = function(name) {
return this["_detail_" + name];
},
this.toString = function() {
var ret = "[Details";
var ret = "[Action id='" + this.id + "'";
for (var i in this) {
if (typeof this[i] != "function") {
if (typeof this[i] == "string")
ret += " " + i + "='" + this[i] + "'";
else
ret += " " + i + "=" + this[i];
if (i.indexOf("_detail_") == 0) {
var key = i.substr(8);
var value = this[i];
ret += " " + key + "='" + value + "'";
}
}
ret += "]";
......@@ -17,7 +20,6 @@ function Details() {
};
function Subject() {
this.isInGroup = function(group) {
for (var n = 0; n < this.groups.length; n++) {
if (this.groups[n] == group)
......@@ -47,11 +49,11 @@ function Subject() {
polkit._adminRuleFuncs = [];
polkit.addAdminRule = function(callback) {this._adminRuleFuncs.push(callback);};
polkit._runAdminRules = function(action, subject, details) {
polkit._runAdminRules = function(action, subject) {
var ret = null;
for (var n = 0; n < this._adminRuleFuncs.length; n++) {
var func = this._adminRuleFuncs[n];
var func_ret = func(action, subject, details);
var func_ret = func(action, subject);
if (func_ret) {
ret = func_ret;
break
......@@ -62,11 +64,11 @@ polkit._runAdminRules = function(action, subject, details) {
polkit._ruleFuncs = [];
polkit.addRule = function(callback) {this._ruleFuncs.push(callback);};
polkit._runRules = function(action, subject, details) {
polkit._runRules = function(action, subject) {
var ret = null;
for (var n = 0; n < this._ruleFuncs.length; n++) {
var func = this._ruleFuncs[n];
var func_ret = func(action, subject, details);
var func_ret = func(action, subject);
if (func_ret) {
ret = func_ret;
break
......
......@@ -806,10 +806,11 @@ subject_to_jsval (PolkitBackendJsAuthority *authority,
/* ---------------------------------------------------------------------------------------------------- */
static gboolean
details_to_jsval (PolkitBackendJsAuthority *authority,
PolkitDetails *details,
jsval *out_jsval,
GError **error)
action_and_details_to_jsval (PolkitBackendJsAuthority *authority,
const gchar *action_id,
PolkitDetails *details,
jsval *out_jsval,
GError **error)
{
gboolean ret = FALSE;
jsval ret_jsval;
......@@ -818,8 +819,7 @@ details_to_jsval (PolkitBackendJsAuthority *authority,
gchar **keys;
guint n;
src = "new Details();";
src = "new Action();";
if (!JS_EvaluateScript (authority->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:
......
......@@ -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
......
......@@ -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";
}
});
......@@ -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";
}
});
......@@ -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
}
});
......@@ -24,6 +24,8 @@
#include "glib.h"
#include <locale.h>
#include <string.h>
#include <polkit/polkit.h>
#include <polkitbackend/polkitbackendjsauthority.h>
#include <polkittesthelper.h>
......@@ -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,
},