Skip to content

Commit

Permalink
Implement configuration reloading on SIGHUP and sd_notify support (#495)
Browse files Browse the repository at this point in the history
Add support for active reloading of config files via SIGHUP.
Also integrate with sd_notify when building with libsystemd, and
set Type=notify-reload in the systemd unit, so that a 'systemctl
reload polkit' works out of the box.
This is especially useful when booting a read-only image, which
gets configuration updates via overmounting with another read-only
image.
  • Loading branch information
bluca authored Oct 9, 2024
1 parent 9958c25 commit 5a6cad0
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 3 deletions.
2 changes: 1 addition & 1 deletion data/polkit.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions src/polkitbackend/polkitbackendactionpool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/polkitbackend/polkitbackendactionpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
23 changes: 23 additions & 0 deletions src/polkitbackend/polkitbackendinteractiveauthority.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <polkit/polkit.h>
#include "polkitbackendinteractiveauthority.h"
#include "polkitbackendactionpool.h"
#include "polkitbackendcommon.h"
#include "polkitbackendsessionmonitor.h"

#include <polkit/polkitprivate.h>
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/polkitbackend/polkitbackendinteractiveauthority.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
49 changes: 49 additions & 0 deletions src/polkitbackend/polkitd.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <polkit/polkit.h>
#include <polkitbackend/polkitbackend.h>

#ifdef HAVE_LIBSYSTEMD
# include <systemd/sd-daemon.h>
#endif

/* ---------------------------------------------------------------------------------------------------- */

static PolkitBackendAuthority *authority = NULL;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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. */
Expand Down Expand Up @@ -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 |
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions test/integration/systemd/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 5a6cad0

Please sign in to comment.