Support backup/restore of FBE policies

Change-Id: Iba8ef20f57b0fb57bb9406c53148a806441d0b59
diff --git a/libtar/extract.c b/libtar/extract.c
index 6a63ff7..ba29a77 100644
--- a/libtar/extract.c
+++ b/libtar/extract.c
@@ -32,6 +32,10 @@
 # include "selinux/selinux.h"
 #endif
 
+#ifdef HAVE_EXT4_CRYPT
+# include "ext4crypt_tar.h"
+#endif
+
 const unsigned long long progress_size = (unsigned long long)(T_BLOCKSIZE);
 
 static int
@@ -492,7 +496,7 @@
 			}
 			else
 			{
-#ifdef DEBUG
+#if 1 //def DEBUG
 				puts("  *** using existing directory");
 #endif
 				return 1;
@@ -507,6 +511,28 @@
 		}
 	}
 
+#ifdef HAVE_EXT4_CRYPT
+	if(t->th_buf.e4crypt_policy != NULL)
+	{
+#ifdef DEBUG
+		printf("tar_extract_file(): restoring EXT4 crypt policy %s to dir %s\n", t->th_buf.e4crypt_policy, realname);
+#endif
+		char binary_policy[EXT4_KEY_DESCRIPTOR_SIZE];
+		if (!lookup_ref_tar(t->th_buf.e4crypt_policy, &binary_policy)) {
+			printf("error looking up proper e4crypt policy for '%s' - %s\n", realname, t->th_buf.e4crypt_policy);
+			return -1;
+		}
+		char policy_hex[EXT4_KEY_DESCRIPTOR_HEX];
+		policy_to_hex(binary_policy, policy_hex);
+		printf("restoring policy %s > '%s' to '%s'\n", t->th_buf.e4crypt_policy, policy_hex, realname);
+		if (!e4crypt_policy_set(realname, binary_policy, EXT4_KEY_DESCRIPTOR_SIZE, 0))
+		{
+			printf("tar_extract_file(): failed to restore EXT4 crypt policy %s to dir '%s' '%s'!!!\n", t->th_buf.e4crypt_policy, realname, policy_hex);
+			//return -1; // This may not be an error in some cases, so log and ignore
+		}
+	}
+#endif
+
 	return 0;
 }