mlcustomize: Refactor SELinux_relabel code.

This shouldn't change the effect of this code.

Cherry picked from libguestfs-common
commit 3493d9fcaab6de1c09528e55a01bc24f0fb6c03c and backported
to libguestfs 1.40 branch (which predates the common submodule).
This commit is contained in:
Richard W.M. Jones
2020-05-05 16:44:14 +01:00
parent 38ecae6c02
commit 3bceb391d1

View File

@@ -28,65 +28,74 @@ module G = Guestfs
let array_find a l =
List.mem a (Array.to_list l)
let relabel (g : G.guestfs) =
(* Is the guest using SELinux? *)
if g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
g#is_file ~followsymlinks:true "/etc/selinux/config" then (
(* Is setfiles / SELinux relabelling functionality available? *)
if g#feature_available [| "selinuxrelabel" |] then (
(* Use Augeas to parse /etc/selinux/config. *)
g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
(* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]");
g#aug_load ();
debug_augeas_errors g;
(* Get the SELinux policy name, eg. "targeted", "minimum".
* Use "targeted" if not specified, just like libselinux does.
*)
let policy =
let config_path = "/files/etc/selinux/config" in
let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
let keys = g#aug_ls config_path in
if array_find selinuxtype_path keys then
g#aug_get selinuxtype_path
else
"targeted" in
g#aug_close ();
(* Get the spec file name. *)
let specfile =
sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
(* RHEL 6.2 - 6.5 had a malformed specfile that contained the
* invalid regular expression "/var/run/spice-vdagentd.\pid"
* (instead of "\.p"). This stops setfiles from working on
* the guest.
*
* Because an SELinux relabel writes all over the filesystem,
* it seems reasonable to fix this problem in the specfile
* at the same time. (RHBZ#1374232)
*)
if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
debug "fixing invalid regular expression in %s" specfile;
let old_specfile = specfile ^ "~" in
g#mv specfile old_specfile;
let content = g#read_file old_specfile in
let content =
String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in
g#write specfile content;
g#copy_attributes ~all:true old_specfile specfile
);
(* Relabel everything. *)
g#selinux_relabel ~force:true specfile "/";
(* If that worked, we don't need to autorelabel. *)
let rec relabel (g : G.guestfs) =
(* Is the guest using SELinux? (Otherwise this is a no-op). *)
if is_selinux_guest g then (
try
use_setfiles g;
(* That worked, so we don't need to autorelabel. *)
g#rm_f "/.autorelabel"
)
else (
(* SELinux guest, but not SELinux host. Fallback to this. *)
with Failure _ ->
(* This is the fallback in case something in the setfiles
* method didn't work. That includes the case where a non-SELinux
* host is processing an SELinux guest, and other things.
*)
g#touch "/.autorelabel"
)
)
and is_selinux_guest g =
g#is_file ~followsymlinks:true "/usr/sbin/load_policy" &&
g#is_file ~followsymlinks:true "/etc/selinux/config"
and use_setfiles g =
(* Is setfiles / SELinux relabelling functionality available? *)
if not (g#feature_available [| "selinuxrelabel" |]) then
failwith "no selinux relabel feature";
(* Use Augeas to parse /etc/selinux/config. *)
g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *);
(* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *)
ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]");
g#aug_load ();
debug_augeas_errors g;
(* Get the SELinux policy name, eg. "targeted", "minimum".
* Use "targeted" if not specified, just like libselinux does.
*)
let policy =
let config_path = "/files/etc/selinux/config" in
let selinuxtype_path = config_path ^ "/SELINUXTYPE" in
let keys = g#aug_ls config_path in
if array_find selinuxtype_path keys then
g#aug_get selinuxtype_path
else
"targeted" in
g#aug_close ();
(* Get the spec file name. *)
let specfile =
sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in
(* RHEL 6.2 - 6.5 had a malformed specfile that contained the
* invalid regular expression "/var/run/spice-vdagentd.\pid"
* (instead of "\.p"). This stops setfiles from working on
* the guest.
*
* Because an SELinux relabel writes all over the filesystem,
* it seems reasonable to fix this problem in the specfile
* at the same time. (RHBZ#1374232)
*)
if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then (
debug "fixing invalid regular expression in %s" specfile;
let old_specfile = specfile ^ "~" in
g#mv specfile old_specfile;
let content = g#read_file old_specfile in
let content =
String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in
g#write specfile content;
g#copy_attributes ~all:true old_specfile specfile
);
(* Relabel everything. *)
g#selinux_relabel ~force:true specfile "/"