Commit 02a4c510 authored by David Zeuthen's avatar David Zeuthen

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.
parent 7222fca1
......@@ -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 <key>=<value>"
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
......
......@@ -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 <key>=<value>"
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
......
......@@ -101,6 +101,11 @@ the system message bus.
.B POLKIT_ACTION_ID
An identifier for the action
.TP
.B POLKIT_ACTION_<KEY_NAME>=<value-name>
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
......
......@@ -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);
}
......@@ -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 */
......
......@@ -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;
......
......@@ -43,15 +43,17 @@ usage (int argc, char *argv[])
fprintf (stderr,
"\n"
"usage : polkit-check-caller\n"
" --caller <dbus-name> --action <action>\n"
" [--action-param <key>=<value>]\n"
" --resource-type <type> --resource-id <id>\n"
" --action <action> --caller <dbus-name>\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);
......
......@@ -43,15 +43,17 @@ usage (int argc, char *argv[])
fprintf (stderr,
"\n"
"usage : polkit-check-session\n"
" [--session <session>] --action <action>\n"
" [--action-param <key>=<value>]"
" --resource-type <type> --resource-id <id>\n"
" --action <action> [--session <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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment