The commit
4938696301a914ec26bcfc60bb99a1e9624e3789 overlooked the
fact that unit files can be specified as unit file paths, not unit
file names, wrongly passing a unit file path to the 1st argument of
manager_load_unit() that handles it as a unit file name. As a result,
the following 4 systemctl subcommands:
enable
disable
reenable
link
mask
unmask
fail with the following error message:
# systemctl enable /usr/lib/systemd/system/kdump.service
Failed to execute operation: Unit name /usr/lib/systemd/system/kdump.service is not valid.
# systemctl disable /usr/lib/systemd/system/kdump.service
Failed to execute operation: Unit name /usr/lib/systemd/system/kdump.service is not valid.
# systemctl reenable /usr/lib/systemd/system/kdump.service
Failed to execute operation: Unit name /usr/lib/systemd/system/kdump.service is not valid.
# cp /usr/lib/systemd/system/kdump.service /tmp/
# systemctl link /tmp/kdump.service
Failed to execute operation: Unit name /tmp/kdump.service is not valid.
# systemctl mask /usr/lib/systemd/system/kdump.service
Failed to execute operation: Unit name /usr/lib/systemd/system/kdump.service is not valid.
# systemctl unmask /usr/lib/systemd/system/kdump.service
Failed to execute operation: Unit name /usr/lib/systemd/system/kdump.service is not valid.
To fix the issue, first check whether a unit file is passed as a unit
file name or a unit file path, and then pass the unit file to the
appropreate argument of manager_load_unit().
By the way, even with this commit mask and unmask reject unit file
paths as follows and this is a correct behavior:
# systemctl mask /usr/lib/systemd/system/kdump.service
Failed to execute operation: Invalid argument
# systemctl unmask /usr/lib/systemd/system/kdump.service
Failed to execute operation: Invalid argument
#include "selinux-util.h"
#include "audit-fd.h"
#include "strv.h"
+#include "path-util.h"
static bool initialized = false;
int r;
STRV_FOREACH(i, units) {
- r = manager_load_unit(m, *i, NULL, error, &u);
+ if (is_path(*i))
+ r = manager_load_unit(m, NULL, *i, error, &u);
+ else
+ r = manager_load_unit(m, *i, NULL, error, &u);
if (r < 0)
return r;
r = mac_selinux_unit_access_check(u, message, permission, error);