diff --git a/data/polkit.service.in b/data/polkit.service.in index 15f44da6..96b5cda1 100644 --- a/data/polkit.service.in +++ b/data/polkit.service.in @@ -3,7 +3,7 @@ Description=Authorization Manager Documentation=man:polkit(8) [Service] -Type=dbus +Type=notify-reload BusName=org.freedesktop.PolicyKit1 CapabilityBoundingSet=CAP_SETUID CAP_SETGID DeviceAllow=/dev/null rw diff --git a/src/polkitbackend/polkitbackendactionpool.c b/src/polkitbackend/polkitbackendactionpool.c index e093bdd6..a0264b59 100644 --- a/src/polkitbackend/polkitbackendactionpool.c +++ b/src/polkitbackend/polkitbackendactionpool.c @@ -463,6 +463,28 @@ polkit_backend_action_pool_get_all_actions (PolkitBackendActionPool *pool, return ret; } +/** + * polkit_backend_action_pool_reload: + * @pool: A #PolkitBackendActionPool. + * + * Reload all PolicyKit actions in @pool. + **/ +void +polkit_backend_action_pool_reload (PolkitBackendActionPool *pool) +{ + PolkitBackendActionPoolPrivate *priv; + + if (!POLKIT_BACKEND_IS_ACTION_POOL (pool)) + return; + + priv = polkit_backend_action_pool_get_instance_private (pool); + + g_hash_table_remove_all (priv->parsed_files); + g_hash_table_remove_all (priv->parsed_actions); + priv->has_loaded_all_files = FALSE; + ensure_all_files (pool); +} + /* ---------------------------------------------------------------------------------------------------- */ static void diff --git a/src/polkitbackend/polkitbackendactionpool.h b/src/polkitbackend/polkitbackendactionpool.h index 1597aee1..a2b76980 100644 --- a/src/polkitbackend/polkitbackendactionpool.h +++ b/src/polkitbackend/polkitbackendactionpool.h @@ -71,6 +71,7 @@ GList *polkit_backend_action_pool_get_all_actions (PolkitBack PolkitActionDescription *polkit_backend_action_pool_get_action (PolkitBackendActionPool *pool, const gchar *action_id, const gchar *locale); +void polkit_backend_action_pool_reload (PolkitBackendActionPool *pool); G_END_DECLS diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c index 232e2ede..34d908f3 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.c +++ b/src/polkitbackend/polkitbackendinteractiveauthority.c @@ -34,6 +34,7 @@ #include #include "polkitbackendinteractiveauthority.h" #include "polkitbackendactionpool.h" +#include "polkitbackendcommon.h" #include "polkitbackendsessionmonitor.h" #include @@ -1409,6 +1410,28 @@ polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInte return ret; } +/** + * polkit_backend_interactive_authority_reload: + * @authority: A #PolkitBackendInteractiveAuthority. + * + * Reload configuration files. + */ +void +polkit_backend_interactive_authority_reload (PolkitBackendInteractiveAuthority *authority) +{ + PolkitBackendInteractiveAuthorityPrivate *priv; + PolkitBackendJsAuthority *jsauthority; + + if (!authority) + return; + + priv = polkit_backend_interactive_authority_get_instance_private (authority); + polkit_backend_action_pool_reload (priv->action_pool); + + jsauthority = POLKIT_BACKEND_JS_AUTHORITY (authority); + polkit_backend_common_reload_scripts (jsauthority); +} + /* ---------------------------------------------------------------------------------------------------- */ struct AuthenticationSession diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.h b/src/polkitbackend/polkitbackendinteractiveauthority.h index 80c4cf13..3cd4f27e 100644 --- a/src/polkitbackend/polkitbackendinteractiveauthority.h +++ b/src/polkitbackend/polkitbackendinteractiveauthority.h @@ -143,6 +143,7 @@ PolkitImplicitAuthorization polkit_backend_interactive_authority_check_authoriza const gchar *action_id, PolkitDetails *details, PolkitImplicitAuthorization implicit); +void polkit_backend_interactive_authority_reload (PolkitBackendInteractiveAuthority *authority); G_END_DECLS diff --git a/src/polkitbackend/polkitd.c b/src/polkitbackend/polkitd.c index 96874472..de0aa3f5 100644 --- a/src/polkitbackend/polkitd.c +++ b/src/polkitbackend/polkitd.c @@ -30,6 +30,10 @@ #include #include +#ifdef HAVE_LIBSYSTEMD +# include +#endif + /* ---------------------------------------------------------------------------------------------------- */ static PolkitBackendAuthority *authority = NULL; @@ -102,6 +106,34 @@ on_sigint (gpointer user_data) return TRUE; } +static gboolean +on_sighup (gpointer user_data) +{ +#ifdef HAVE_LIBSYSTEMD + gchar reload_message[sizeof("RELOADING=1\nMONOTONIC_USEC=18446744073709551615")]; + gint64 monotonic_now; + + /* Notify systemd that we are reloading, including a CLOCK_MONOTONIC timestamp in usec + * so that the program is compatible with a Type=notify-reload service. */ + + monotonic_now = g_get_monotonic_time (); + g_snprintf (reload_message, sizeof(reload_message), "RELOADING=1\nMONOTONIC_USEC=%" G_GINT64_FORMAT, monotonic_now); + + sd_notify (0, reload_message); +#endif + + g_print ("Handling SIGHUP\n"); + + polkit_backend_interactive_authority_reload (POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority)); + +#ifdef HAVE_LIBSYSTEMD + /* Notify systemd that we have finished reloading. */ + sd_notify (0, "READY=1\nSTATUS=Processing requests..."); +#endif + + return TRUE; +} + static gboolean become_user (const gchar *user, GError **error) @@ -176,11 +208,13 @@ main (int argc, GOptionContext *opt_context; guint name_owner_id; guint sigint_id; + guint sighup_id; loop = NULL; opt_context = NULL; name_owner_id = 0; sigint_id = 0; + sighup_id = 0; registration_id = NULL; /* Disable remote file access from GIO. */ @@ -237,6 +271,10 @@ main (int argc, on_sigint, NULL); + sighup_id = g_unix_signal_add (SIGHUP, + on_sighup, + NULL); + name_owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM, "org.freedesktop.PolicyKit1", G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | @@ -248,12 +286,23 @@ main (int argc, NULL); g_print ("Entering main event loop\n"); + +#ifdef HAVE_LIBSYSTEMD + sd_notify (0, "READY=1\nSTATUS=Processing requests..."); +#endif + g_main_loop_run (loop); +#ifdef HAVE_LIBSYSTEMD + sd_notify (0, "STOPPING=1"); +#endif + g_print ("Shutting down\n"); out: if (sigint_id > 0) g_source_remove (sigint_id); + if (sighup_id > 0) + g_source_remove (sighup_id); if (name_owner_id != 0) g_bus_unown_name (name_owner_id); if (registration_id != NULL) diff --git a/test/integration/systemd/test.sh b/test/integration/systemd/test.sh index c0f6f015..8dd98c8d 100755 --- a/test/integration/systemd/test.sh +++ b/test/integration/systemd/test.sh @@ -12,7 +12,7 @@ at_exit() { : "Cleanup" userdel -rf "$TEST_USER" rm -f /etc/polkit-1/rules.d/99-test.rules - systemctl restart polkit + systemctl reload polkit } trap at_exit EXIT @@ -34,7 +34,7 @@ EOF systemctl daemon-reload # Copy the test polkit rule in place cp -fv "$TEST_RULES/start-restart-stop-unit.rules" /etc/polkit-1/rules.d/99-test.rules -systemctl restart polkit +systemctl reload polkit # Following systemctl invocations should not trigger polkit's authentication prompt sudo -u "$TEST_USER" systemctl start start-restart-stop.service sudo -u "$TEST_USER" systemctl restart start-restart-stop.service