Add an API to allow skipping the system-wide hooks directory (/etc/libvirt/hooks) for non-root users. When enabled, only the user hooks directory (~/.config/libvirt/hooks) is searched.
This allows daemon config to control whether system hooks should be used in session mode. Signed-off-by: Marc-André Lureau <[email protected]> --- src/libvirt_private.syms | 1 + src/util/virhook.c | 30 +++++++++++++++++++++++++++--- src/util/virhook.h | 1 + 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 798d2d28c893..ce00f961b678 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2618,6 +2618,7 @@ virHashCodeGen; virHookCall; virHookInitialize; virHookPresent; +virHookSetSkipSystemHooks; # util/virhostcpu.h diff --git a/src/util/virhook.c b/src/util/virhook.c index f62ac902bb40..aa68109ff193 100644 --- a/src/util/virhook.c +++ b/src/util/virhook.c @@ -41,6 +41,21 @@ VIR_LOG_INIT("util.hook"); #define LIBVIRT_HOOK_DIR SYSCONFDIR "/libvirt/hooks" +static bool virHookSkipSystemHooks; + +/** + * virHookSetSkipSystemHooks: + * @skip: if true, skip system hooks directory for non-root + * + * Configure whether the system-wide hooks directory (/etc/libvirt/hooks) + * should be skipped for non-root users. By default, both the system + * directory and the user directory (~/.config/libvirt/hooks) are searched. + */ +void +virHookSetSkipSystemHooks(bool skip) +{ + virHookSkipSystemHooks = skip; +} /** * virHookGetDirs: @@ -48,7 +63,10 @@ VIR_LOG_INIT("util.hook"); * Returns a NULL-terminated array of hook directories to search, * in priority order. For root, only /etc/libvirt/hooks is returned. * For non-root users, both /etc/libvirt/hooks and - * ~/.config/libvirt/hooks are returned (system first, then user). + * ~/.config/libvirt/hooks are returned (system first, then user), + * unless virHookSetSkipSystemHooks(true) has been called (via the + * skip_system_hooks config option), in which case only the user + * directory is returned. * * The caller must free the result with g_strfreev(). */ @@ -58,9 +76,12 @@ virHookGetDirs(void) g_autofree char *configdir = NULL; GPtrArray *dirs = g_ptr_array_new(); - g_ptr_array_add(dirs, g_strdup(LIBVIRT_HOOK_DIR)); + if (geteuid() == 0) { + g_ptr_array_add(dirs, g_strdup(LIBVIRT_HOOK_DIR)); + } else { + if (!virHookSkipSystemHooks) + g_ptr_array_add(dirs, g_strdup(LIBVIRT_HOOK_DIR)); - if (geteuid() != 0) { configdir = virGetUserConfigDirectory(); g_ptr_array_add(dirs, g_build_filename(configdir, "hooks", NULL)); } @@ -377,6 +398,9 @@ virRunScript(const char *path, * output produced by each script is fed as input to the next script and * so on, chaining across directories. * + * For non-root users, the system hooks directory can be skipped by setting + * the skip_system_hooks daemon config option. + * * Returns: 0 if the execution succeeded, 1 if the script was not found or * invalid parameters, and -1 if script returned an error */ diff --git a/src/util/virhook.h b/src/util/virhook.h index d8237c837e94..47d5bf4266e9 100644 --- a/src/util/virhook.h +++ b/src/util/virhook.h @@ -109,6 +109,7 @@ typedef enum { } virHookBhyveOpType; int virHookInitialize(void); +void virHookSetSkipSystemHooks(bool skip); int virHookPresent(int driver); -- 2.56.0.rc0.29.g47ce80527c56
