Skip to content

Commit

Permalink
polkitbackendactionpool: support /etc/polkit-1/actions as alternative…
Browse files Browse the repository at this point in the history
… location

monitor and load .policy files from /etc/polkit-1/actions in addition to
/usr/share/polkit-1/actions.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Dec 16, 2017
1 parent 05a7876 commit d69e133
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 24 deletions.
6 changes: 4 additions & 2 deletions docs/man/polkit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ System Context | |
^ |
| +--------------------------------------+
| | /usr/share/polkit-1/actions/*.policy |
| | /etc/polkit-1/actions/*.policy |
| +--------------------------------------+
|
+--------------------------------------+
Expand Down Expand Up @@ -217,8 +218,9 @@ System Context | |
order to use polkit. Actions correspond to operations that
clients can request the mechanism to carry out and are defined
in XML files that the mechanism installs into the <filename
class='directory'>/usr/share/polkit-1/actions</filename>
directory.
class='directory'>/usr/share/polkit-1/actions</filename> and in
<filename class='directory'>/etc/polkit-1/actions</filename>
directories.
</para>

<para>
Expand Down
18 changes: 16 additions & 2 deletions docs/polkit-1-diagrams.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
95 changes: 80 additions & 15 deletions src/polkitbackend/polkitbackendactionpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ typedef struct

GFileMonitor *usr_dir_monitor;

/* directory with .policy files, e.g. /etc/polkit-1/actions */
GFile *etc_directory;

GFileMonitor *etc_dir_monitor;

/* maps from action_id to a ParsedAction struct */
GHashTable *parsed_actions;

Expand All @@ -109,6 +114,7 @@ enum
{
PROP_0,
PROP_USR_DIRECTORY,
PROP_ETC_DIRECTORY,
};

#define POLKIT_BACKEND_ACTION_POOL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_BACKEND_TYPE_ACTION_POOL, PolkitBackendActionPoolPrivate))
Expand Down Expand Up @@ -153,9 +159,15 @@ polkit_backend_action_pool_finalize (GObject *object)
if (priv->usr_directory != NULL)
g_object_unref (priv->usr_directory);

if (priv->etc_directory != NULL)
g_object_unref (priv->etc_directory);

if (priv->usr_dir_monitor != NULL)
g_object_unref (priv->usr_dir_monitor);

if (priv->etc_dir_monitor != NULL)
g_object_unref (priv->etc_dir_monitor);

if (priv->parsed_actions != NULL)
g_hash_table_unref (priv->parsed_actions);

Expand Down Expand Up @@ -183,6 +195,10 @@ polkit_backend_action_pool_get_property (GObject *object,
g_value_set_object (value, priv->usr_directory);
break;

case PROP_ETC_DIRECTORY:
g_value_set_object (value, priv->etc_directory);
break;

default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -274,6 +290,28 @@ polkit_backend_action_pool_set_property (GObject *object,
}
break;

case PROP_ETC_DIRECTORY:
priv->etc_directory = g_value_dup_object (value);

error = NULL;
priv->etc_dir_monitor = g_file_monitor_directory (priv->etc_directory,
G_FILE_MONITOR_NONE,
NULL,
&error);
if (priv->etc_dir_monitor == NULL)
{
g_warning ("Error monitoring actions directory: %s", error->message);
g_error_free (error);
}
else
{
g_signal_connect (priv->etc_dir_monitor,
"changed",
(GCallback) dir_monitor_changed,
pool);
}
break;

default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand All @@ -298,7 +336,7 @@ polkit_backend_action_pool_class_init (PolkitBackendActionPoolClass *klass)
*/
g_object_class_install_property (gobject_class,
PROP_USR_DIRECTORY,
g_param_spec_object ("directory",
g_param_spec_object ("usrdirectory",
"Directory",
"Directory to load action description files from",
G_TYPE_FILE,
Expand All @@ -307,6 +345,17 @@ polkit_backend_action_pool_class_init (PolkitBackendActionPoolClass *klass)
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
g_object_class_install_property (gobject_class,
PROP_ETC_DIRECTORY,
g_param_spec_object ("etcdirectory",
"Etc directory",
"Alternative directory to load action description files from",
G_TYPE_FILE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));

/**
* PolkitBackendActionPool::changed:
Expand All @@ -327,19 +376,21 @@ polkit_backend_action_pool_class_init (PolkitBackendActionPoolClass *klass)

/**
* polkit_backend_action_pool_new:
* @directory: A #GFile for the directory holding PolicyKit action description files.
* @usr_directory: A #GFile for the directory holding PolicyKit action description files.
* @etc_directory: A #GFile for an alternative directory holding PolicyKit action description files.
*
* Creates a new #PolkitBackendPool that can be used for looking up #PolkitActionDescription objects.
*
* Returns: A #PolkitBackendActionPool. Free with g_object_unref().
**/
PolkitBackendActionPool *
polkit_backend_action_pool_new (GFile *directory)
polkit_backend_action_pool_new (GFile *usr_directory, GFile *etc_directory)
{
PolkitBackendActionPool *pool;

pool = POLKIT_BACKEND_ACTION_POOL (g_object_new (POLKIT_BACKEND_TYPE_ACTION_POOL,
"directory", directory,
"usrdirectory", usr_directory,
"etcdirectory", etc_directory,
NULL));

return pool;
Expand Down Expand Up @@ -500,8 +551,8 @@ ensure_file (PolkitBackendActionPool *pool,
g_free (uri);
}

static void
ensure_all_files (PolkitBackendActionPool *pool)
static gboolean
ensure_all_files_directory (PolkitBackendActionPool *pool, GFile *directory)
{
PolkitBackendActionPoolPrivate *priv;
GFileEnumerator *e;
Expand All @@ -510,13 +561,8 @@ ensure_all_files (PolkitBackendActionPool *pool)

priv = POLKIT_BACKEND_ACTION_POOL_GET_PRIVATE (pool);

e = NULL;

if (priv->has_loaded_all_files)
goto out;

error = NULL;
e = g_file_enumerate_children (priv->usr_directory,
e = g_file_enumerate_children (directory,
"standard::name",
G_FILE_QUERY_INFO_NONE,
NULL,
Expand All @@ -537,7 +583,7 @@ ensure_all_files (PolkitBackendActionPool *pool)
{
GFile *file;

file = g_file_get_child (priv->usr_directory, name);
file = g_file_get_child (directory, name);

ensure_file (pool, file);

Expand All @@ -548,12 +594,31 @@ ensure_all_files (PolkitBackendActionPool *pool)

} /* for all files */

priv->has_loaded_all_files = TRUE;

out:

if (e != NULL)
g_object_unref (e);

return error == NULL;
}

static void
ensure_all_files (PolkitBackendActionPool *pool)
{
PolkitBackendActionPoolPrivate *priv;
gboolean success = TRUE;

priv = POLKIT_BACKEND_ACTION_POOL_GET_PRIVATE (pool);

if (priv->has_loaded_all_files)
return;

success &= ensure_all_files_directory (pool, priv->usr_directory);
if (success)
success &= ensure_all_files_directory (pool, priv->etc_directory);

if (success)
priv->has_loaded_all_files = TRUE;
}

/* ---------------------------------------------------------------------------------------------------- */
Expand Down
2 changes: 1 addition & 1 deletion src/polkitbackend/polkitbackendactionpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct _PolkitBackendActionPoolClass
};

GType polkit_backend_action_pool_get_type (void) G_GNUC_CONST;
PolkitBackendActionPool *polkit_backend_action_pool_new (GFile *usr_directory);
PolkitBackendActionPool *polkit_backend_action_pool_new (GFile *usr_directory, GFile *etc_directory);
GList *polkit_backend_action_pool_get_all_actions (PolkitBackendActionPool *pool,
const gchar *locale);

Expand Down
10 changes: 6 additions & 4 deletions src/polkitbackend/polkitbackendinteractiveauthority.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,17 +291,19 @@ static void
polkit_backend_interactive_authority_init (PolkitBackendInteractiveAuthority *authority)
{
PolkitBackendInteractiveAuthorityPrivate *priv;
GFile *directory;
GFile *usr_directory, *etc_directory;
GError *error;

/* Force registering error domain */
(void)POLKIT_ERROR;

priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);

directory = g_file_new_for_path (PACKAGE_DATA_DIR "/polkit-1/actions");
priv->action_pool = polkit_backend_action_pool_new (directory);
g_object_unref (directory);
usr_directory = g_file_new_for_path (PACKAGE_DATA_DIR "/polkit-1/actions");
etc_directory = g_file_new_for_path (PACKAGE_SYSCONF_DIR "/polkit-1/actions");
priv->action_pool = polkit_backend_action_pool_new (usr_directory, etc_directory);
g_object_unref (usr_directory);
g_object_unref (etc_directory);
g_signal_connect (priv->action_pool,
"changed",
(GCallback) action_pool_changed,
Expand Down

0 comments on commit d69e133

Please sign in to comment.