From d69e133dcda0d75fae2c00efa2c15a8cb97b4e85 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sat, 16 Dec 2017 00:10:19 +0100 Subject: [PATCH] polkitbackendactionpool: support /etc/polkit-1/actions as alternative location monitor and load .policy files from /etc/polkit-1/actions in addition to /usr/share/polkit-1/actions. Signed-off-by: Giuseppe Scrivano --- docs/man/polkit.xml | 6 +- docs/polkit-1-diagrams.svg | 18 +++- src/polkitbackend/polkitbackendactionpool.c | 95 ++++++++++++++++--- src/polkitbackend/polkitbackendactionpool.h | 2 +- .../polkitbackendinteractiveauthority.c | 10 +- 5 files changed, 107 insertions(+), 24 deletions(-) diff --git a/docs/man/polkit.xml b/docs/man/polkit.xml index f2c1acf..004df31 100644 --- a/docs/man/polkit.xml +++ b/docs/man/polkit.xml @@ -105,6 +105,7 @@ System Context | | ^ | | +--------------------------------------+ | | /usr/share/polkit-1/actions/*.policy | + | | /etc/polkit-1/actions/*.policy | | +--------------------------------------+ | +--------------------------------------+ @@ -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 /usr/share/polkit-1/actions - directory. + class='directory'>/usr/share/polkit-1/actions and in + /etc/polkit-1/actions + directories. diff --git a/docs/polkit-1-diagrams.svg b/docs/polkit-1-diagrams.svg index d595ce8..e6c83bc 100644 --- a/docs/polkit-1-diagrams.svg +++ b/docs/polkit-1-diagrams.svg @@ -970,16 +970,30 @@ xml:space="preserve" style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans" x="445.0928" - y="434.35934" + y="444.35934" id="text13594-3" inkscape:export-filename="/home/davidz/Hacking/polkit/docs/polkit-architecture.png" inkscape:export-xdpi="96.720001" inkscape:export-ydpi="96.720001">/usr/share/polkit-1/actions/*.policy + /etc/polkit-1/actions/*.policy 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); @@ -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; @@ -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; @@ -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, @@ -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: @@ -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; @@ -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; @@ -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, @@ -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); @@ -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; } /* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/polkitbackend/polkitbackendactionpool.h b/src/polkitbackend/polkitbackendactionpool.h index 69b5911..5f4b726 100644 --- a/src/polkitbackend/polkitbackendactionpool.h +++ b/src/polkitbackend/polkitbackendactionpool.h @@ -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); diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index ccfd608..d76deb5 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -291,7 +291,7 @@ static void polkit_backend_interactive_authority_init (PolkitBackendInteractiveAuthority *authority) { PolkitBackendInteractiveAuthorityPrivate *priv; - GFile *directory; + GFile *usr_directory, *etc_directory; GError *error; /* Force registering error domain */ @@ -299,9 +299,11 @@ polkit_backend_interactive_authority_init (PolkitBackendInteractiveAuthority *au 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,