From 02a4c5101ca4751963f76a0e016d3308389dc2a5 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Mon, 9 Apr 2007 15:20:04 -0400 Subject: [PATCH] associate parameters (key/value pairs) with the Action class This is useful for letting mechanisms convey information which may be useful in making a decision whether an action is OK. For example, NetworkManager could use this to provide the phone-number parameter with a hypothetical "nm-dialup" action. Then a site or vendor can provide insert mandatory polkit-run-program.so program="/usr/lib/check-dialup-number.sh" privilege="nm-dialup" into /etc/PolicyKit/PolicyKit.conf and have said program check $POLKIT_ACTION_PARAM_PHONE_NUMBER in that program. --- doc/man/polkit-check-caller.1.in | 15 +++-- doc/man/polkit-check-session.1.in | 15 +++-- doc/man/polkit-module-run-program.8.in | 5 ++ libpolkit/libpolkit-action.c | 80 +++++++++++++++++++++++++ libpolkit/libpolkit-action.h | 26 ++++++-- modules/run-program/polkit-module-run-program.c | 25 ++++++++ tools/polkit-check-caller.c | 38 ++++++++++-- tools/polkit-check-session.c | 36 ++++++++++- 8 files changed, 217 insertions(+), 23 deletions(-) diff --git a/doc/man/polkit-check-caller.1.in b/doc/man/polkit-check-caller.1.in index f7f5a2e..a204387 100644 --- a/doc/man/polkit-check-caller.1.in +++ b/doc/man/polkit-check-caller.1.in @@ -22,19 +22,22 @@ depending on the distribution. .SH OPTIONS The following options are supported: .TP -.I "--resource-type" -Type of resource. -.TP -.I "--resource" -Identifier of resource. -.TP .I "--action" The action to check. .TP +.I "--action-param =" +Append parameters to action. +.TP .I "--caller" The caller to check for. Must be the callers unique name on the D-Bus system message bus. .TP +.I "--resource-type" +Type of resource. +.TP +.I "--resource" +Identifier of resource. +.TP .I "--help" Print out usage. .TP diff --git a/doc/man/polkit-check-session.1.in b/doc/man/polkit-check-session.1.in index dbf549b..bba8f01 100644 --- a/doc/man/polkit-check-session.1.in +++ b/doc/man/polkit-check-session.1.in @@ -22,19 +22,22 @@ depending on the distribution. .SH OPTIONS The following options are supported: .TP -.I "--resource-type" -Type of resource. -.TP -.I "--resource" -Identifier of resource. -.TP .I "--action" The action to check. .TP +.I "--action-param =" +Append parameters to action. +.TP .I "--session" The session to check for. Must be a ConsoleKit object path. If ommitted the current session is used. .TP +.I "--resource-type" +Type of resource. +.TP +.I "--resource" +Identifier of resource. +.TP .I "--help" Print out usage. .TP diff --git a/doc/man/polkit-module-run-program.8.in b/doc/man/polkit-module-run-program.8.in index 1824452..643f4dd 100644 --- a/doc/man/polkit-module-run-program.8.in +++ b/doc/man/polkit-module-run-program.8.in @@ -101,6 +101,11 @@ the system message bus. .B POLKIT_ACTION_ID An identifier for the action .TP +.B POLKIT_ACTION_= +All action parameters are put in the environment; the key is +uppercased and hyphen and period characters are replaced with +underscores. +.TP .B POLKIT_RESOURCE_ID Resource identifier .TP diff --git a/libpolkit/libpolkit-action.c b/libpolkit/libpolkit-action.c index 6a82bdc..d3ab2c6 100644 --- a/libpolkit/libpolkit-action.c +++ b/libpolkit/libpolkit-action.c @@ -56,6 +56,7 @@ struct PolKitAction { int refcount; char *id; + GHashTable *params; }; /** @@ -71,6 +72,10 @@ libpolkit_action_new (void) PolKitAction *action; action = g_new0 (PolKitAction, 1); action->refcount = 1; + action->params = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_free); return action; } @@ -106,6 +111,7 @@ libpolkit_action_unref (PolKitAction *action) if (action->refcount > 0) return; g_free (action->id); + g_hash_table_destroy (action->params); g_free (action); } @@ -157,3 +163,77 @@ libpolkit_action_debug (PolKitAction *action) g_return_if_fail (action != NULL); _pk_debug ("PolKitAction: refcount=%d id=%s", action->refcount, action->id); } + +/** + * libpolkit_action_set_param: + * @action: the action + * @key: key + * @value: value + * + * Set a parameter (a key/value pair) associated with the action. + **/ +void +libpolkit_action_set_param (PolKitAction *action, const char *key, const char *value) +{ + g_return_if_fail (action != NULL); + g_return_if_fail (key != NULL); + + g_hash_table_insert (action->params, g_strdup (key), g_strdup (value)); +} + +/** + * libpolkit_action_get_param: + * @action: the action + * @key: key + * + * Get a parameter (a key/value pair) associated with the action. + * + * Returns: the value or #NULL if the parameter wasn't set. + **/ +const char * +libpolkit_action_get_param (PolKitAction *action, const char *key) +{ + const char *value; + + g_return_val_if_fail (action != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + value = g_hash_table_lookup (action->params, key); + return value; +} + +typedef struct { + PolKitAction *action; + PolKitActionParamForeachFunc cb; + gpointer user_data; +} HashClosure; + +static void +_hash_cb (gpointer key, gpointer value, gpointer user_data) +{ + HashClosure *data = user_data; + data->cb (data->action, key, value, data->user_data); +} + +/** + * libpolkit_action_param_foreach: + * @action: the action + * @cb: function to call + * @user_data: user data + * + * Calls the given function for each parameter on the object. + **/ +void +libpolkit_action_param_foreach (PolKitAction *action, PolKitActionParamForeachFunc cb, gpointer user_data) +{ + HashClosure data; + + g_return_if_fail (action != NULL); + g_return_if_fail (cb != NULL); + + data.action = action; + data.cb = cb; + data.user_data = user_data; + g_hash_table_foreach (action->params, _hash_cb, &data); +} + diff --git a/libpolkit/libpolkit-action.h b/libpolkit/libpolkit-action.h index 8c2ae14..4486c8a 100644 --- a/libpolkit/libpolkit-action.h +++ b/libpolkit/libpolkit-action.h @@ -34,13 +34,31 @@ struct PolKitAction; typedef struct PolKitAction PolKitAction; +/** + * PolKitActionParamForeachFunc: + * @action: the action + * @key: key of parameter + * @value: value of parameter + * @user_data: user data + * + * Type for function used in libpolkit_action_param_foreach(). + **/ +typedef void (*PolKitActionParamForeachFunc) (PolKitAction *action, + const char *key, + const char *value, + gpointer user_data); + PolKitAction *libpolkit_action_new (void); PolKitAction *libpolkit_action_ref (PolKitAction *action); -void libpolkit_action_unref (PolKitAction *action); -void libpolkit_action_set_action_id (PolKitAction *action, const char *action_id); -gboolean libpolkit_action_get_action_id (PolKitAction *action, char **out_action_id); +void libpolkit_action_unref (PolKitAction *action); +void libpolkit_action_set_action_id (PolKitAction *action, const char *action_id); +gboolean libpolkit_action_get_action_id (PolKitAction *action, char **out_action_id); + +void libpolkit_action_set_param (PolKitAction *action, const char *key, const char *value); +const char *libpolkit_action_get_param (PolKitAction *action, const char *key); +void libpolkit_action_param_foreach (PolKitAction *action, PolKitActionParamForeachFunc cb, gpointer user_data); -void libpolkit_action_debug (PolKitAction *action); +void libpolkit_action_debug (PolKitAction *action); #endif /* LIBPOLKIT_ACTION_H */ diff --git a/modules/run-program/polkit-module-run-program.c b/modules/run-program/polkit-module-run-program.c index ae05e35..bd4738a 100644 --- a/modules/run-program/polkit-module-run-program.c +++ b/modules/run-program/polkit-module-run-program.c @@ -105,6 +105,29 @@ _module_shutdown (PolKitModuleInterface *module_interface) } } +static void +_add_action_param_to_env (PolKitAction *action, const char *key, const char *value, gpointer user_data) +{ + int n; + char *upper; + GPtrArray *envp = user_data; + + if (key == NULL || value == NULL) + return; + + upper = g_ascii_strup (key, -1); + for (n = 0; upper[n] != '\0'; n++) { + switch (upper[n]) { + case '.': + case '-': + upper[n] = '_'; + break; + } + } + g_ptr_array_add (envp, g_strdup_printf ("POLKIT_ACTION_PARAM_%s=%s", upper, value)); + g_free (upper); +} + static gboolean _add_action_to_env (PolKitAction *action, GPtrArray *envp) { @@ -112,6 +135,8 @@ _add_action_to_env (PolKitAction *action, GPtrArray *envp) if (!libpolkit_action_get_action_id (action, &p_id)) goto error; g_ptr_array_add (envp, g_strdup_printf ("POLKIT_ACTION_ID=%s", p_id)); + + libpolkit_action_param_foreach (action, _add_action_param_to_env, envp); return TRUE; error: return FALSE; diff --git a/tools/polkit-check-caller.c b/tools/polkit-check-caller.c index 066ef73..874c7f2 100644 --- a/tools/polkit-check-caller.c +++ b/tools/polkit-check-caller.c @@ -43,15 +43,17 @@ usage (int argc, char *argv[]) fprintf (stderr, "\n" "usage : polkit-check-caller\n" + " --caller --action \n" + " [--action-param =]\n" " --resource-type --resource-id \n" - " --action --caller \n" " [--version] [--help]\n"); fprintf (stderr, "\n" + " --caller Unique name of caller on the system bus\n" + " --action Requested action\n" + " --action-param Action parameters (may occur multiple times)\n" " --resource-type Type of resource\n" " --resource-id Identifier of resource\n" - " --action Requested action\n" - " --caller Unique name of caller on the system bus\n" " --version Show version and exit\n" " --help Show this information and exit\n" "\n" @@ -77,12 +79,17 @@ main (int argc, char *argv[]) PolKitAction *action; gboolean allowed; GError *g_error; - + GPtrArray *params; + int n; + char *param_key; + char *param_value; + if (argc <= 1) { usage (argc, argv); return 1; } + params = g_ptr_array_new (); while (1) { int c; int option_index = 0; @@ -91,6 +98,7 @@ main (int argc, char *argv[]) {"resource-type", 1, NULL, 0}, {"resource-id", 1, NULL, 0}, {"action", 1, NULL, 0}, + {"action-param", 1, NULL, 0}, {"caller", 1, NULL, 0}, {"version", 0, NULL, 0}, {"help", 0, NULL, 0}, @@ -117,6 +125,18 @@ main (int argc, char *argv[]) resource_id = strdup (optarg); } else if (strcmp (opt, "action") == 0) { action_id = strdup (optarg); + } else if (strcmp (opt, "action-param") == 0) { + param_key = strdup (optarg); + param_value = NULL; + for (n = 0; param_key[n] != '=' && param_key[n] != '\0'; n++) + ; + if (param_key[n] == '\0') + usage (argc, argv); + param_key[n] = '\0'; + param_value = param_key + n + 1; + g_ptr_array_add (params, g_strdup (param_key)); + g_ptr_array_add (params, g_strdup (param_value)); + g_free (param_key); } else if (strcmp (opt, "caller") == 0) { dbus_name = strdup (optarg); } @@ -156,6 +176,16 @@ main (int argc, char *argv[]) action = libpolkit_action_new (); libpolkit_action_set_action_id (action, action_id); + for (n = 0; n < (int) params->len; n += 2) { + char *key; + char *value; + key = params->pdata[n]; + value = params->pdata[n+1]; + libpolkit_action_set_param (action, key, value); + g_free (key); + g_free (value); + } + g_ptr_array_free (params, TRUE); resource = libpolkit_resource_new (); libpolkit_resource_set_resource_type (resource, resource_type); diff --git a/tools/polkit-check-session.c b/tools/polkit-check-session.c index 2c6fe91..da5ada9 100644 --- a/tools/polkit-check-session.c +++ b/tools/polkit-check-session.c @@ -43,15 +43,17 @@ usage (int argc, char *argv[]) fprintf (stderr, "\n" "usage : polkit-check-session\n" + " [--session ] --action \n" + " [--action-param =]" " --resource-type --resource-id \n" - " --action [--session ]\n" " [--version] [--help]\n"); fprintf (stderr, "\n" + " --session ConsoleKit object path of session\n" + " --action Requested action\n" + " --action-param Action parameters (may occur multiple times)\n" " --resource-type Type of resource\n" " --resource-id Identifier of resource\n" - " --action Requested action\n" - " --session ConsoleKit object path of session\n" " --version Show version and exit\n" " --help Show this information and exit\n" "\n" @@ -78,6 +80,10 @@ main (int argc, char *argv[]) PolKitAction *action; gboolean allowed; GError *g_error; + GPtrArray *params; + int n; + char *param_key; + char *param_value; if (argc <= 1) { usage (argc, argv); @@ -86,6 +92,7 @@ main (int argc, char *argv[]) cookie = getenv ("XDG_SESSION_COOKIE"); + params = g_ptr_array_new (); while (1) { int c; int option_index = 0; @@ -94,6 +101,7 @@ main (int argc, char *argv[]) {"resource-type", 1, NULL, 0}, {"resource-id", 1, NULL, 0}, {"action", 1, NULL, 0}, + {"action-param", 1, NULL, 0}, {"session", 1, NULL, 0}, {"version", 0, NULL, 0}, {"help", 0, NULL, 0}, @@ -120,6 +128,18 @@ main (int argc, char *argv[]) resource_id = strdup (optarg); } else if (strcmp (opt, "action") == 0) { action_id = strdup (optarg); + } else if (strcmp (opt, "action-param") == 0) { + param_key = strdup (optarg); + param_value = NULL; + for (n = 0; param_key[n] != '=' && param_key[n] != '\0'; n++) + ; + if (param_key[n] == '\0') + usage (argc, argv); + param_key[n] = '\0'; + param_value = param_key + n + 1; + g_ptr_array_add (params, g_strdup (param_key)); + g_ptr_array_add (params, g_strdup (param_value)); + g_free (param_key); } else if (strcmp (opt, "session") == 0) { session_id = strdup (optarg); } @@ -173,6 +193,16 @@ main (int argc, char *argv[]) action = libpolkit_action_new (); libpolkit_action_set_action_id (action, action_id); + for (n = 0; n < (int) params->len; n += 2) { + char *key; + char *value; + key = params->pdata[n]; + value = params->pdata[n+1]; + libpolkit_action_set_param (action, key, value); + g_free (key); + g_free (value); + } + g_ptr_array_free (params, TRUE); resource = libpolkit_resource_new (); libpolkit_resource_set_resource_type (resource, resource_type); -- 2.7.4