Blame SOURCES/0230-v2v-windows-Warn-if-Group-Policy-or-AV-software-may-.patch

ffd6ed
From f8a041846bd596276dc37cabd217d5f37312256c Mon Sep 17 00:00:00 2001
ffd6ed
From: "Richard W.M. Jones" <rjones@redhat.com>
ffd6ed
Date: Mon, 7 Sep 2015 17:18:41 +0100
ffd6ed
Subject: [PATCH] v2v: windows: Warn if Group Policy or AV software may result
ffd6ed
 in 7B boot failure (RHBZ#1260689).
ffd6ed
ffd6ed
Check if the Windows guest has Group Policy Objects installed, or one
ffd6ed
of several popular pieces of anti-virus software.  If we are
ffd6ed
installing a virtio block driver, then experience has shown this may
ffd6ed
cause a 7B boot failure.
ffd6ed
ffd6ed
Print a warning when this combination happens.
ffd6ed
ffd6ed
The warnings look like this:
ffd6ed
ffd6ed
[  19.9] Converting Windows Server 2008 R2 Enterprise to run on KVM
ffd6ed
virt-v2v: warning: this guest has Windows Group Policy Objects (GPO) and a
ffd6ed
new virtio block device driver was installed.  In some circumstances, Group
ffd6ed
Policy may prevent new drivers from working (resulting in a 7B boot error).
ffd6ed
 If this happens, try disabling Group Policy before doing the conversion.
ffd6ed
virt-v2v: warning: this guest has Anti-Virus (AV) software and a new virtio
ffd6ed
block device driver was installed.  In some circumstances, AV may prevent
ffd6ed
new drivers from working (resulting in a 7B boot error).  If this happens,
ffd6ed
try disabling AV before doing the conversion.
ffd6ed
virt-v2v: This guest has virtio drivers installed.
ffd6ed
ffd6ed
(cherry picked from commit 8e28d6b18860f8ff4e02489317749a723fa145ab)
ffd6ed
---
ffd6ed
 mllib/common_utils.ml  |  6 +++++
ffd6ed
 mllib/common_utils.mli |  2 ++
ffd6ed
 v2v/convert_windows.ml | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
ffd6ed
 3 files changed, 68 insertions(+)
ffd6ed
ffd6ed
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
ffd6ed
index 8f0f065..198a5fb 100644
ffd6ed
--- a/mllib/common_utils.ml
ffd6ed
+++ b/mllib/common_utils.ml
ffd6ed
@@ -58,6 +58,12 @@ let le32_of_int i =
ffd6ed
   String.unsafe_set s 3 (Char.unsafe_chr (Int64.to_int c3));
ffd6ed
   s
ffd6ed
 
ffd6ed
+let isxdigit = function
ffd6ed
+  | '0'..'9' -> true
ffd6ed
+  | 'a'..'f' -> true
ffd6ed
+  | 'A'..'F' -> true
ffd6ed
+  | _ -> false
ffd6ed
+
ffd6ed
 type wrap_break_t = WrapEOS | WrapSpace | WrapNL
ffd6ed
 
ffd6ed
 let rec wrap ?(chan = stdout) ?(indent = 0) str =
ffd6ed
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
ffd6ed
index ad2b4c7..ed7de7f 100644
ffd6ed
--- a/mllib/common_utils.mli
ffd6ed
+++ b/mllib/common_utils.mli
ffd6ed
@@ -32,6 +32,8 @@ val div_roundup64 : int64 -> int64 -> int64
ffd6ed
 val int_of_le32 : string -> int64
ffd6ed
 val le32_of_int : int64 -> string
ffd6ed
 
ffd6ed
+val isxdigit : char -> bool
ffd6ed
+
ffd6ed
 val wrap : ?chan:out_channel -> ?indent:int -> string -> unit
ffd6ed
 (** Wrap text. *)
ffd6ed
 
ffd6ed
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml
ffd6ed
index e3d3a39..36cf8c1 100644
ffd6ed
--- a/v2v/convert_windows.ml
ffd6ed
+++ b/v2v/convert_windows.ml
ffd6ed
@@ -41,6 +41,14 @@ module G = Guestfs
ffd6ed
 
ffd6ed
 type ('a, 'b) maybe = Either of 'a | Or of 'b
ffd6ed
 
ffd6ed
+(* Antivirus regexps that match on inspect.i_apps.app2_name fields. *)
ffd6ed
+let av_rex =
ffd6ed
+  let alternatives = [
ffd6ed
+    "virus"; (* generic *)
ffd6ed
+    "Kaspersky"; "McAfee"; "Norton"; "Sophos";
ffd6ed
+  ] in
ffd6ed
+  Str.regexp_case_fold (String.concat "\\|" alternatives)
ffd6ed
+
ffd6ed
 let convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
ffd6ed
   (* Get the data directory. *)
ffd6ed
   let virt_tools_data_dir =
ffd6ed
@@ -103,6 +111,47 @@ let convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
ffd6ed
   (*----------------------------------------------------------------------*)
ffd6ed
   (* Inspect the Windows guest. *)
ffd6ed
 
ffd6ed
+  (* Warn if Windows guest appears to be using group policy. *)
ffd6ed
+  let has_group_policy =
ffd6ed
+    let check_group_policy root =
ffd6ed
+      try
ffd6ed
+        let node =
ffd6ed
+          get_node root
ffd6ed
+                   ["Microsoft"; "Windows"; "CurrentVersion"; "Group Policy";
ffd6ed
+                    "History"] in
ffd6ed
+        let children = g#hivex_node_children node in
ffd6ed
+        let children = Array.to_list children in
ffd6ed
+        let children =
ffd6ed
+          List.map (fun { G.hivex_node_h = h } -> g#hivex_node_name h)
ffd6ed
+                   children in
ffd6ed
+        (* Just assume any children looking like "{<GUID>}" mean that
ffd6ed
+         * some GPOs were installed.
ffd6ed
+         *
ffd6ed
+         * In future we might want to look for nodes which match:
ffd6ed
+         * History\{<GUID>}\<N> where <N> is a small integer (the order
ffd6ed
+         * in which policy objects were applied.
ffd6ed
+         *
ffd6ed
+         * For an example registry containing GPOs, see RHBZ#1219651.
ffd6ed
+         * See also: https://support.microsoft.com/en-us/kb/201453
ffd6ed
+         *)
ffd6ed
+        let is_gpo_guid name =
ffd6ed
+          let len = String.length name in
ffd6ed
+          len > 3 && name.[0] = '{' && isxdigit name.[1] && name.[len-1] = '}'
ffd6ed
+        in
ffd6ed
+        List.exists is_gpo_guid children
ffd6ed
+      with
ffd6ed
+        Not_found -> false
ffd6ed
+    in
ffd6ed
+    with_hive "software" ~write:false check_group_policy in
ffd6ed
+
ffd6ed
+  (* Warn if Windows guest has AV installed. *)
ffd6ed
+  let has_antivirus =
ffd6ed
+    let check_app { G.app2_name = name } =
ffd6ed
+      try ignore (Str.search_forward av_rex name 0); true
ffd6ed
+      with Not_found -> false
ffd6ed
+    in
ffd6ed
+    List.exists check_app inspect.i_apps in
ffd6ed
+
ffd6ed
   (* Open the software hive (readonly) and find the Xen PV uninstaller,
ffd6ed
    * if it exists.
ffd6ed
    *)
ffd6ed
@@ -488,6 +537,17 @@ echo uninstalling Xen PV driver
ffd6ed
 
ffd6ed
   fix_ntfs_heads ();
ffd6ed
 
ffd6ed
+  (* Warn if installation of virtio block drivers might conflict with
ffd6ed
+   * group policy or AV software causing a boot 0x7B error (RHBZ#1260689).
ffd6ed
+   *)
ffd6ed
+  let () =
ffd6ed
+    if block_driver = Virtio_blk then (
ffd6ed
+      if has_group_policy then
ffd6ed
+        warning ~prog (f_"this guest has Windows Group Policy Objects (GPO) and a new virtio block device driver was installed.  In some circumstances, Group Policy may prevent new drivers from working (resulting in a 7B boot error).  If this happens, try disabling Group Policy before doing the conversion.");
ffd6ed
+      if has_antivirus then
ffd6ed
+        warning ~prog (f_"this guest has Anti-Virus (AV) software and a new virtio block device driver was installed.  In some circumstances, AV may prevent new drivers from working (resulting in a 7B boot error).  If this happens, try disabling AV before doing the conversion.");
ffd6ed
+    ) in
ffd6ed
+
ffd6ed
   (* Return guest capabilities. *)
ffd6ed
   let guestcaps = {
ffd6ed
     gcaps_block_bus = block_driver;
ffd6ed
-- 
ffd6ed
1.8.3.1
ffd6ed