diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b03c195
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/libsemanage-3.3.tar.gz
diff --git a/.libsemanage.metadata b/.libsemanage.metadata
new file mode 100644
index 0000000..4b3389b
--- /dev/null
+++ b/.libsemanage.metadata
@@ -0,0 +1 @@
+11f64c0651cde5d85b1dbbbc05491e95943643bb SOURCES/libsemanage-3.3.tar.gz
diff --git a/SOURCES/0001-libsemanage-Fix-RESOURCE_LEAK-and-USE_AFTER_FREE-cov.patch b/SOURCES/0001-libsemanage-Fix-RESOURCE_LEAK-and-USE_AFTER_FREE-cov.patch
new file mode 100644
index 0000000..4dc4ca8
--- /dev/null
+++ b/SOURCES/0001-libsemanage-Fix-RESOURCE_LEAK-and-USE_AFTER_FREE-cov.patch
@@ -0,0 +1,66 @@
+From 05bc0fe72b53476a9d4da3957c6d6cba00c76eea Mon Sep 17 00:00:00 2001
+From: Petr Lautrbach <plautrba@redhat.com>
+Date: Wed, 7 Nov 2018 18:17:34 +0100
+Subject: [PATCH] libsemanage: Fix RESOURCE_LEAK and USE_AFTER_FREE coverity
+ scan defects
+
+---
+ libsemanage/src/direct_api.c | 21 ++++++++-------------
+ 1 file changed, 8 insertions(+), 13 deletions(-)
+
+diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
+index f0e2300a2f58..b7a3e0f17cc1 100644
+--- a/libsemanage/src/direct_api.c
++++ b/libsemanage/src/direct_api.c
+@@ -1029,7 +1029,7 @@ static int semanage_direct_write_langext(semanage_handle_t *sh,
+ 
+ 	fp = NULL;
+ 
+-	ret = 0;
++	return 0;
+ 
+ cleanup:
+ 	if (fp != NULL) fclose(fp);
+@@ -2186,7 +2186,6 @@ cleanup:
+ 	semanage_module_info_destroy(sh, modinfo);
+ 	free(modinfo);
+ 
+-	if (fp != NULL) fclose(fp);
+ 	return status;
+ }
+ 
+@@ -2351,16 +2350,6 @@ static int semanage_direct_get_module_info(semanage_handle_t *sh,
+ 	free(tmp);
+ 	tmp = NULL;
+ 
+-	if (fclose(fp) != 0) {
+-		ERR(sh,
+-		    "Unable to close %s module lang ext file.",
+-		    (*modinfo)->name);
+-		status = -1;
+-		goto cleanup;
+-	}
+-
+-	fp = NULL;
+-
+ 	/* lookup enabled/disabled status */
+ 	ret = semanage_module_get_path(sh,
+ 				       *modinfo,
+@@ -2404,7 +2393,13 @@ cleanup:
+ 		free(modinfos);
+ 	}
+ 
+-	if (fp != NULL) fclose(fp);
++	if (fp != NULL && fclose(fp) != 0) {
++		ERR(sh,
++		    "Unable to close %s module lang ext file.",
++		    (*modinfo)->name);
++		status = -1;
++	}
++
+ 	return status;
+ }
+ 
+-- 
+2.32.0
+
diff --git a/SOURCES/0002-libsemanage-add-missing-include-to-boolean_record.c.patch b/SOURCES/0002-libsemanage-add-missing-include-to-boolean_record.c.patch
new file mode 100644
index 0000000..ec8fa2c
--- /dev/null
+++ b/SOURCES/0002-libsemanage-add-missing-include-to-boolean_record.c.patch
@@ -0,0 +1,38 @@
+From 5bf29afd8591d93aa6052254855b2ff5c9b38ec6 Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Thu, 3 Feb 2022 17:53:22 +0100
+Subject: [PATCH] libsemanage: add missing include to boolean_record.c
+
+It uses asprintf(3), but doesn't directly include <stdio.h> - fix it.
+
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+Acked-by: James Carter <jwcart2@gmail.com>
+---
+ libsemanage/src/boolean_record.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/libsemanage/src/boolean_record.c b/libsemanage/src/boolean_record.c
+index 95f3a8620ead..40dc6545fbdb 100644
+--- a/libsemanage/src/boolean_record.c
++++ b/libsemanage/src/boolean_record.c
+@@ -7,6 +7,9 @@
+  */
+ 
+ #include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++
+ #include <sepol/boolean_record.h>
+ 
+ typedef sepol_bool_t semanage_bool_t;
+@@ -20,7 +23,6 @@ typedef semanage_bool_key_t record_key_t;
+ #include "boolean_internal.h"
+ #include "handle.h"
+ #include "database.h"
+-#include <stdlib.h>
+ #include <selinux/selinux.h>
+ 
+ /* Key */
+-- 
+2.34.1
+
diff --git a/SOURCES/0003-semodule-libsemanage-move-module-hashing-into-libsem.patch b/SOURCES/0003-semodule-libsemanage-move-module-hashing-into-libsem.patch
new file mode 100644
index 0000000..d17439e
--- /dev/null
+++ b/SOURCES/0003-semodule-libsemanage-move-module-hashing-into-libsem.patch
@@ -0,0 +1,575 @@
+From f77f2b70930c628b362320cbfe07833032ae9b0f Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Thu, 3 Feb 2022 17:53:23 +0100
+Subject: [PATCH] semodule,libsemanage: move module hashing into libsemanage
+
+The main goal of this move is to have the SHA-256 implementation under
+libsemanage, since upcoming patches will make use of SHA-256 for a
+different (but similar) purpose in libsemanage. Having the hashing code
+in libsemanage will reduce code duplication and allow for easier hash
+algorithm upgrade in the future.
+
+Note that libselinux currently also contains a hash function
+implementation (for yet another different purpose). This patch doesn't
+make any effort to address that duplicity yet.
+
+This patch also changes the format of the hash string printed by
+semodule to include the name of the hash. The intent is to avoid
+ambiguity and potential collisions when the algorithm is potentially
+changed in the future.
+
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+---
+ libsemanage/include/semanage/modules.h        |  26 ++
+ libsemanage/src/libsemanage.map               |   4 +
+ libsemanage/src/modules.c                     |  59 ++++
+ .../src/semanageswig_python_exception.i       |   8 +
+ libsemanage/src/sha256.c                      | 294 ++++++++++++++++++
+ libsemanage/src/sha256.h                      |  89 ++++++
+ 6 files changed, 480 insertions(+)
+ create mode 100644 libsemanage/src/sha256.c
+ create mode 100644 libsemanage/src/sha256.h
+
+diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h
+index b51f61f033d5..14666f6dbe00 100644
+--- a/libsemanage/include/semanage/modules.h
++++ b/libsemanage/include/semanage/modules.h
+@@ -282,4 +282,30 @@ extern int semanage_module_get_enabled(semanage_handle_t *sh,
+ 				       const semanage_module_key_t *modkey,
+ 				       int *enabled);
+ 
++/* Compute checksum for @modkey module contents.
++ *
++ * If @checksum is NULL, the function will just return the length of the
++ * checksum string in @checksum_len (checksum strings are guaranteed to
++ * have a fixed length for a given libsemanage binary). @modkey and @cil
++ * are ignored in this case and should be set to NULL and 0 (respectively).
++ *
++ * If @checksum is non-NULL, on success, @checksum will point to a buffer
++ * containing the checksum string and @checksum_len will point to the
++ * length of the string (without the null terminator). The semantics of
++ * @cil are the same as for @extract_cil in semanage_module_extract().
++ *
++ * The caller is responsible to free the buffer returned in @checksum (using
++ * free(3)).
++ *
++ * Callers may assume that if the checksum strings for two modules match,
++ * the module content is the same (collisions are theoretically possible,
++ * yet extremely unlikely).
++ *
++ * Returns 0 on success and -1 on error.
++ */
++extern int semanage_module_compute_checksum(semanage_handle_t *sh,
++					    semanage_module_key_t *modkey,
++					    int cil, char **checksum,
++					    size_t *checksum_len);
++
+ #endif
+diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
+index 3ea7b60f97bb..00259fc817f5 100644
+--- a/libsemanage/src/libsemanage.map
++++ b/libsemanage/src/libsemanage.map
+@@ -345,3 +345,7 @@ LIBSEMANAGE_1.1 {
+     semanage_module_remove_key;
+     semanage_set_store_root;
+ } LIBSEMANAGE_1.0;
++
++LIBSEMANAGE_3.4 {
++    semanage_module_compute_checksum;
++} LIBSEMANAGE_1.1;
+diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
+index b6dd456cac32..5dbb28fdbaa5 100644
+--- a/libsemanage/src/modules.c
++++ b/libsemanage/src/modules.c
+@@ -35,11 +35,13 @@
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include <sys/mman.h>
+ #include <errno.h>
+ #include <ctype.h>
+ 
+ #include "handle.h"
+ #include "modules.h"
++#include "sha256.h"
+ #include "debug.h"
+ 
+ int semanage_module_install(semanage_handle_t * sh,
+@@ -975,3 +977,60 @@ int semanage_module_remove_key(semanage_handle_t *sh,
+ 	return sh->funcs->remove_key(sh, modkey);
+ }
+ 
++static const char CHECKSUM_TYPE[] = "sha256";
++static const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE;
++
++static void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum)
++{
++	size_t i;
++
++	checksum += sprintf(checksum, "%s:", CHECKSUM_TYPE);
++	for (i = 0; i < SHA256_HASH_SIZE; i++) {
++		checksum += sprintf(checksum, "%02x", (unsigned)hash[i]);
++	}
++}
++
++int semanage_module_compute_checksum(semanage_handle_t *sh,
++				     semanage_module_key_t *modkey,
++				     int cil, char **checksum,
++				     size_t *checksum_len)
++{
++	semanage_module_info_t *extract_info = NULL;
++	Sha256Context context;
++	SHA256_HASH sha256_hash;
++	char *checksum_str;
++	void *data;
++	size_t data_len = 0;
++	int result;
++
++	if (!checksum_len)
++		return -1;
++
++	if (!checksum) {
++		*checksum_len = CHECKSUM_CONTENT_SIZE;
++		return 0;
++	}
++
++	result = semanage_module_extract(sh, modkey, cil, &data, &data_len, &extract_info);
++	if (result != 0)
++		return -1;
++
++	semanage_module_info_destroy(sh, extract_info);
++	free(extract_info);
++
++	Sha256Initialise(&context);
++	Sha256Update(&context, data, data_len);
++	Sha256Finalise(&context, &sha256_hash);
++
++	munmap(data, data_len);
++
++	checksum_str = malloc(CHECKSUM_CONTENT_SIZE + 1 /* '\0' */);
++	if (!checksum_str)
++		return -1;
++
++	semanage_hash_to_checksum_string(sha256_hash.bytes, checksum_str);
++
++	*checksum = checksum_str;
++	*checksum_len = CHECKSUM_CONTENT_SIZE;
++	return 0;
++}
+diff --git a/libsemanage/src/semanageswig_python_exception.i b/libsemanage/src/semanageswig_python_exception.i
+index 372ec948866a..0df8bbc350e2 100644
+--- a/libsemanage/src/semanageswig_python_exception.i
++++ b/libsemanage/src/semanageswig_python_exception.i
+@@ -351,6 +351,14 @@
+   }
+ }
+ 
++%exception semanage_module_compute_checksum {
++  $action
++  if (result < 0) {
++     PyErr_SetFromErrno(PyExc_OSError);
++     SWIG_fail;
++  }
++}
++
+ %exception semanage_msg_get_level {
+   $action
+   if (result < 0) {
+diff --git a/libsemanage/src/sha256.c b/libsemanage/src/sha256.c
+new file mode 100644
+index 000000000000..fe2aeef07f53
+--- /dev/null
++++ b/libsemanage/src/sha256.c
+@@ -0,0 +1,294 @@
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  WjCryptLib_Sha256
++//
++//  Implementation of SHA256 hash function.
++//  Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
++//  Modified by WaterJuice retaining Public Domain license.
++//
++//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  IMPORTS
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++#include "sha256.h"
++#include <memory.h>
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  MACROS
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
++
++#define MIN(x, y) ( ((x)<(y))?(x):(y) )
++
++#define STORE32H(x, y)                                                                     \
++     { (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255);   \
++       (y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); }
++
++#define LOAD32H(x, y)                            \
++     { x = ((uint32_t)((y)[0] & 255)<<24) | \
++           ((uint32_t)((y)[1] & 255)<<16) | \
++           ((uint32_t)((y)[2] & 255)<<8)  | \
++           ((uint32_t)((y)[3] & 255)); }
++
++#define STORE64H(x, y)                                                                     \
++   { (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255);     \
++     (y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255);     \
++     (y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255);     \
++     (y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); }
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  CONSTANTS
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++// The K array
++static const uint32_t K[64] = {
++    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
++    0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
++    0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
++    0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
++    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
++    0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
++    0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
++    0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
++    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
++    0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
++    0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
++    0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
++    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
++};
++
++#define BLOCK_SIZE          64
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  INTERNAL FUNCTIONS
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++// Various logical functions
++#define Ch( x, y, z )     (z ^ (x & (y ^ z)))
++#define Maj( x, y, z )    (((x | y) & z) | (x & y))
++#define S( x, n )         ror((x),(n))
++#define R( x, n )         (((x)&0xFFFFFFFFUL)>>(n))
++#define Sigma0( x )       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
++#define Sigma1( x )       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
++#define Gamma0( x )       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
++#define Gamma1( x )       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
++
++#define Sha256Round( a, b, c, d, e, f, g, h, i )       \
++     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i];   \
++     t1 = Sigma0(a) + Maj(a, b, c);                    \
++     d += t0;                                          \
++     h  = t0 + t1;
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  TransformFunction
++//
++//  Compress 512-bits
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++static
++void
++    TransformFunction
++    (
++        Sha256Context*      Context,
++        uint8_t const*      Buffer
++    )
++{
++    uint32_t    S[8];
++    uint32_t    W[64];
++    uint32_t    t0;
++    uint32_t    t1;
++    uint32_t    t;
++    int         i;
++
++    // Copy state into S
++    for( i=0; i<8; i++ )
++    {
++        S[i] = Context->state[i];
++    }
++
++    // Copy the state into 512-bits into W[0..15]
++    for( i=0; i<16; i++ )
++    {
++        LOAD32H( W[i], Buffer + (4*i) );
++    }
++
++    // Fill W[16..63]
++    for( i=16; i<64; i++ )
++    {
++        W[i] = Gamma1( W[i-2]) + W[i-7] + Gamma0( W[i-15] ) + W[i-16];
++    }
++
++    // Compress
++    for( i=0; i<64; i++ )
++    {
++        Sha256Round( S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i );
++        t = S[7];
++        S[7] = S[6];
++        S[6] = S[5];
++        S[5] = S[4];
++        S[4] = S[3];
++        S[3] = S[2];
++        S[2] = S[1];
++        S[1] = S[0];
++        S[0] = t;
++    }
++
++    // Feedback
++    for( i=0; i<8; i++ )
++    {
++        Context->state[i] = Context->state[i] + S[i];
++    }
++}
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  PUBLIC FUNCTIONS
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Initialise
++//
++//  Initialises a SHA256 Context. Use this to initialise/reset a context.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Initialise
++    (
++        Sha256Context*      Context         // [out]
++    )
++{
++    Context->curlen = 0;
++    Context->length = 0;
++    Context->state[0] = 0x6A09E667UL;
++    Context->state[1] = 0xBB67AE85UL;
++    Context->state[2] = 0x3C6EF372UL;
++    Context->state[3] = 0xA54FF53AUL;
++    Context->state[4] = 0x510E527FUL;
++    Context->state[5] = 0x9B05688CUL;
++    Context->state[6] = 0x1F83D9ABUL;
++    Context->state[7] = 0x5BE0CD19UL;
++}
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Update
++//
++//  Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
++//  calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Update
++    (
++        Sha256Context*      Context,        // [in out]
++        void const*         Buffer,         // [in]
++        uint32_t            BufferSize      // [in]
++    )
++{
++    uint32_t n;
++
++    if( Context->curlen > sizeof(Context->buf) )
++    {
++       return;
++    }
++
++    while( BufferSize > 0 )
++    {
++        if( Context->curlen == 0 && BufferSize >= BLOCK_SIZE )
++        {
++           TransformFunction( Context, (uint8_t*)Buffer );
++           Context->length += BLOCK_SIZE * 8;
++           Buffer = (uint8_t*)Buffer + BLOCK_SIZE;
++           BufferSize -= BLOCK_SIZE;
++        }
++        else
++        {
++           n = MIN( BufferSize, (BLOCK_SIZE - Context->curlen) );
++           memcpy( Context->buf + Context->curlen, Buffer, (size_t)n );
++           Context->curlen += n;
++           Buffer = (uint8_t*)Buffer + n;
++           BufferSize -= n;
++           if( Context->curlen == BLOCK_SIZE )
++           {
++              TransformFunction( Context, Context->buf );
++              Context->length += 8*BLOCK_SIZE;
++              Context->curlen = 0;
++           }
++       }
++    }
++}
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Finalise
++//
++//  Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
++//  calling this, Sha256Initialised must be used to reuse the context.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Finalise
++    (
++        Sha256Context*      Context,        // [in out]
++        SHA256_HASH*        Digest          // [out]
++    )
++{
++    int i;
++
++    if( Context->curlen >= sizeof(Context->buf) )
++    {
++       return;
++    }
++
++    // Increase the length of the message
++    Context->length += Context->curlen * 8;
++
++    // Append the '1' bit
++    Context->buf[Context->curlen++] = (uint8_t)0x80;
++
++    // if the length is currently above 56 bytes we append zeros
++    // then compress.  Then we can fall back to padding zeros and length
++    // encoding like normal.
++    if( Context->curlen > 56 )
++    {
++        while( Context->curlen < 64 )
++        {
++            Context->buf[Context->curlen++] = (uint8_t)0;
++        }
++        TransformFunction(Context, Context->buf);
++        Context->curlen = 0;
++    }
++
++    // Pad up to 56 bytes of zeroes
++    while( Context->curlen < 56 )
++    {
++        Context->buf[Context->curlen++] = (uint8_t)0;
++    }
++
++    // Store length
++    STORE64H( Context->length, Context->buf+56 );
++    TransformFunction( Context, Context->buf );
++
++    // Copy output
++    for( i=0; i<8; i++ )
++    {
++        STORE32H( Context->state[i], Digest->bytes+(4*i) );
++    }
++}
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Calculate
++//
++//  Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
++//  buffer.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Calculate
++    (
++        void  const*        Buffer,         // [in]
++        uint32_t            BufferSize,     // [in]
++        SHA256_HASH*        Digest          // [in]
++    )
++{
++    Sha256Context context;
++
++    Sha256Initialise( &context );
++    Sha256Update( &context, Buffer, BufferSize );
++    Sha256Finalise( &context, Digest );
++}
+diff --git a/libsemanage/src/sha256.h b/libsemanage/src/sha256.h
+new file mode 100644
+index 000000000000..406ed869cd82
+--- /dev/null
++++ b/libsemanage/src/sha256.h
+@@ -0,0 +1,89 @@
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  WjCryptLib_Sha256
++//
++//  Implementation of SHA256 hash function.
++//  Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
++//  Modified by WaterJuice retaining Public Domain license.
++//
++//  This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++#pragma once
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  IMPORTS
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++#include <stdint.h>
++#include <stdio.h>
++
++typedef struct
++{
++    uint64_t    length;
++    uint32_t    state[8];
++    uint32_t    curlen;
++    uint8_t     buf[64];
++} Sha256Context;
++
++#define SHA256_HASH_SIZE           ( 256 / 8 )
++
++typedef struct
++{
++    uint8_t      bytes [SHA256_HASH_SIZE];
++} SHA256_HASH;
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  PUBLIC FUNCTIONS
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Initialise
++//
++//  Initialises a SHA256 Context. Use this to initialise/reset a context.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Initialise
++    (
++        Sha256Context*      Context         // [out]
++    );
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Update
++//
++//  Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
++//  calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Update
++    (
++        Sha256Context*      Context,        // [in out]
++        void const*         Buffer,         // [in]
++        uint32_t            BufferSize      // [in]
++    );
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Finalise
++//
++//  Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
++//  calling this, Sha256Initialised must be used to reuse the context.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Finalise
++    (
++        Sha256Context*      Context,        // [in out]
++        SHA256_HASH*        Digest          // [out]
++    );
++
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++//  Sha256Calculate
++//
++//  Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
++//  buffer.
++////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
++void
++    Sha256Calculate
++    (
++        void  const*        Buffer,         // [in]
++        uint32_t            BufferSize,     // [in]
++        SHA256_HASH*        Digest          // [in]
++    );
+-- 
+2.34.1
+
diff --git a/SOURCES/0004-libsemanage-move-compressed-file-handling-into-a-sep.patch b/SOURCES/0004-libsemanage-move-compressed-file-handling-into-a-sep.patch
new file mode 100644
index 0000000..0714895
--- /dev/null
+++ b/SOURCES/0004-libsemanage-move-compressed-file-handling-into-a-sep.patch
@@ -0,0 +1,824 @@
+From 7b059d3ca56dbe7003cec921c13be70f9fa1a0f7 Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Thu, 3 Feb 2022 17:53:24 +0100
+Subject: [PATCH] libsemanage: move compressed file handling into a separate
+ object
+
+In order to reduce exisiting and future code duplication and to avoid
+some unnecessary allocations and copying, factor the compressed file
+utility functions out into a separate C/header file and refactor their
+interface.
+
+Note that this change effectively removes the __fsetlocking(3) call from
+semanage_load_files() - I haven't been able to figure out what purpose
+it serves, but it seems pointless...
+
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+---
+ libsemanage/src/compressed_file.c | 224 +++++++++++++++++++++++++
+ libsemanage/src/compressed_file.h |  78 +++++++++
+ libsemanage/src/direct_api.c      | 263 +++++-------------------------
+ libsemanage/src/direct_api.h      |   4 -
+ libsemanage/src/semanage_store.c  |  52 ++----
+ 5 files changed, 354 insertions(+), 267 deletions(-)
+ create mode 100644 libsemanage/src/compressed_file.c
+ create mode 100644 libsemanage/src/compressed_file.h
+
+diff --git a/libsemanage/src/compressed_file.c b/libsemanage/src/compressed_file.c
+new file mode 100644
+index 000000000000..5546b83074d5
+--- /dev/null
++++ b/libsemanage/src/compressed_file.c
+@@ -0,0 +1,224 @@
++/* Author: Jason Tang	  <jtang@tresys.com>
++ *         Christopher Ashworth <cashworth@tresys.com>
++ *         Ondrej Mosnacek <omosnacek@gmail.com>
++ *
++ * Copyright (C) 2004-2006 Tresys Technology, LLC
++ * Copyright (C) 2005-2021 Red Hat, Inc.
++ *
++ *  This library is free software; you can redistribute it and/or
++ *  modify it under the terms of the GNU Lesser General Public
++ *  License as published by the Free Software Foundation; either
++ *  version 2.1 of the License, or (at your option) any later version.
++ *
++ *  This library is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  Lesser General Public License for more details.
++ *
++ *  You should have received a copy of the GNU Lesser General Public
++ *  License along with this library; if not, write to the Free Software
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++
++#include <stdlib.h>
++#include <string.h>
++#include <stdint.h>
++
++#include <unistd.h>
++#include <fcntl.h>
++
++#include <bzlib.h>
++
++#include "compressed_file.h"
++
++#include "debug.h"
++
++#define BZ2_MAGICSTR "BZh"
++#define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1)
++
++/* bzip() a data to a file, returning the total number of compressed bytes
++ * in the file.  Returns -1 if file could not be compressed. */
++static int bzip(semanage_handle_t *sh, const char *filename, void *data,
++		size_t num_bytes)
++{
++	BZFILE* b;
++	size_t  size = 1<<16;
++	int     bzerror;
++	size_t  total = 0;
++	size_t len = 0;
++	FILE *f;
++
++	if ((f = fopen(filename, "wb")) == NULL) {
++		return -1;
++	}
++
++	if (!sh->conf->bzip_blocksize) {
++		if (fwrite(data, 1, num_bytes, f) < num_bytes) {
++			fclose(f);
++			return -1;
++		}
++		fclose(f);
++		return 0;
++	}
++
++	b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0);
++	if (bzerror != BZ_OK) {
++		BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
++		fclose(f);
++		return -1;
++	}
++
++	while ( num_bytes > total ) {
++		if (num_bytes - total > size) {
++			len = size;
++		} else {
++			len = num_bytes - total;
++		}
++		BZ2_bzWrite ( &bzerror, b, (uint8_t *)data + total, len );
++		if (bzerror == BZ_IO_ERROR) {
++			BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
++			fclose(f);
++			return -1;
++		}
++		total += len;
++	}
++
++	BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 );
++	fclose(f);
++	if (bzerror == BZ_IO_ERROR) {
++		return -1;
++	}
++	return 0;
++}
++
++/* bunzip() a file to '*data', returning the total number of uncompressed bytes
++ * in the file.  Returns -1 if file could not be decompressed. */
++static ssize_t bunzip(semanage_handle_t *sh, FILE *f, void **data)
++{
++	BZFILE*  b = NULL;
++	size_t   nBuf;
++	uint8_t* buf = NULL;
++	size_t   size = 1<<18;
++	size_t   bufsize = size;
++	int      bzerror;
++	size_t   total = 0;
++	uint8_t* uncompress = NULL;
++	uint8_t* tmpalloc = NULL;
++	int      ret = -1;
++
++	buf = malloc(bufsize);
++	if (buf == NULL) {
++		ERR(sh, "Failure allocating memory.");
++		goto exit;
++	}
++
++	/* Check if the file is bzipped */
++	bzerror = fread(buf, 1, BZ2_MAGICLEN, f);
++	rewind(f);
++	if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) {
++		goto exit;
++	}
++
++	b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 );
++	if ( bzerror != BZ_OK ) {
++		ERR(sh, "Failure opening bz2 archive.");
++		goto exit;
++	}
++
++	uncompress = malloc(size);
++	if (uncompress == NULL) {
++		ERR(sh, "Failure allocating memory.");
++		goto exit;
++	}
++
++	while ( bzerror == BZ_OK) {
++		nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize);
++		if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) {
++			if (total + nBuf > size) {
++				size *= 2;
++				tmpalloc = realloc(uncompress, size);
++				if (tmpalloc == NULL) {
++					ERR(sh, "Failure allocating memory.");
++					goto exit;
++				}
++				uncompress = tmpalloc;
++			}
++			memcpy(&uncompress[total], buf, nBuf);
++			total += nBuf;
++		}
++	}
++	if ( bzerror != BZ_STREAM_END ) {
++		ERR(sh, "Failure reading bz2 archive.");
++		goto exit;
++	}
++
++	ret = total;
++	*data = uncompress;
++
++exit:
++	BZ2_bzReadClose ( &bzerror, b );
++	free(buf);
++	if ( ret < 0 ) {
++		free(uncompress);
++	}
++	return ret;
++}
++
++int map_compressed_file(semanage_handle_t *sh, const char *path,
++			struct file_contents *contents)
++{
++	ssize_t size = -1;
++	void *uncompress;
++	int ret = 0, fd = -1;
++	FILE *file = NULL;
++
++	fd = open(path, O_RDONLY);
++	if (fd == -1) {
++		ERR(sh, "Unable to open %s\n", path);
++		return -1;
++	}
++
++	file = fdopen(fd, "r");
++	if (file == NULL) {
++		ERR(sh, "Unable to open %s\n", path);
++		close(fd);
++		return -1;
++	}
++
++	if ((size = bunzip(sh, file, &uncompress)) >= 0) {
++		contents->data = uncompress;
++		contents->len = size;
++		contents->compressed = 1;
++	} else {
++		struct stat sb;
++		if (fstat(fd, &sb) == -1 ||
++		    (uncompress = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
++		    MAP_FAILED) {
++			ret = -1;
++		} else {
++			contents->data = uncompress;
++			contents->len = sb.st_size;
++			contents->compressed = 0;
++		}
++	}
++	fclose(file);
++	return ret;
++}
++
++void unmap_compressed_file(struct file_contents *contents)
++{
++	if (!contents->data)
++		return;
++
++	if (contents->compressed) {
++		free(contents->data);
++	} else {
++		munmap(contents->data, contents->len);
++	}
++}
++
++int write_compressed_file(semanage_handle_t *sh, const char *path,
++			  void *data, size_t len)
++{
++	return bzip(sh, path, data, len);
++}
+diff --git a/libsemanage/src/compressed_file.h b/libsemanage/src/compressed_file.h
+new file mode 100644
+index 000000000000..96cfb4b6304a
+--- /dev/null
++++ b/libsemanage/src/compressed_file.h
+@@ -0,0 +1,78 @@
++/* Author: Jason Tang	  <jtang@tresys.com>
++ *         Christopher Ashworth <cashworth@tresys.com>
++ *         Ondrej Mosnacek <omosnacek@gmail.com>
++ *
++ * Copyright (C) 2004-2006 Tresys Technology, LLC
++ * Copyright (C) 2005-2021 Red Hat, Inc.
++ *
++ *  This library is free software; you can redistribute it and/or
++ *  modify it under the terms of the GNU Lesser General Public
++ *  License as published by the Free Software Foundation; either
++ *  version 2.1 of the License, or (at your option) any later version.
++ *
++ *  This library is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *  Lesser General Public License for more details.
++ *
++ *  You should have received a copy of the GNU Lesser General Public
++ *  License along with this library; if not, write to the Free Software
++ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ */
++
++#ifndef _SEMANAGE_CIL_FILE_H_
++#define _SEMANAGE_CIL_FILE_H_
++
++#include <sys/mman.h>
++#include <sys/types.h>
++
++#include "handle.h"
++
++struct file_contents {
++	void *data; /** file contents (uncompressed) */
++	size_t len; /** length of contents */
++	int compressed; /** whether file was compressed */
++};
++
++/**
++ * Map/read a possibly-compressed file into memory.
++ *
++ * If the file is bzip compressed map_file will uncompress the file into
++ * @p contents. The caller is responsible for calling
++ * @ref unmap_compressed_file on @p contents on success.
++ *
++ * @param sh        semanage handle
++ * @param path      path to the file
++ * @param contents  pointer to struct file_contents, which will be
++ *   populated with data pointer, size, and an indication whether
++ *   the file was compressed or not
++ *
++ * @return 0 on success, -1 otherwise.
++ */
++int map_compressed_file(semanage_handle_t *sh, const char *path,
++			struct file_contents *contents);
++
++/**
++ * Destroy a previously mapped possibly-compressed file.
++ *
++ * If all fields of @p contents are zero/NULL, the function is
++ * guaranteed to do nothing.
++ *
++ * @param contents  pointer to struct file_contents to destroy
++ */
++void unmap_compressed_file(struct file_contents *contents);
++
++/**
++ * Write bytes into a file, using compression if configured.
++ *
++ * @param sh    semanage handle
++ * @param path  path to the file
++ * @param data  pointer to the data
++ * @param len   length of the data
++ *
++ * @return 0 on success, -1 otherwise.
++ */
++int write_compressed_file(semanage_handle_t *sh, const char *path,
++			  void *data, size_t len);
++
++#endif
+diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
+index b7a3e0f17cc1..aa2bfcf35016 100644
+--- a/libsemanage/src/direct_api.c
++++ b/libsemanage/src/direct_api.c
+@@ -50,6 +50,7 @@
+ 
+ #include "debug.h"
+ #include "handle.h"
++#include "compressed_file.h"
+ #include "modules.h"
+ #include "direct_api.h"
+ #include "semanage_store.h"
+@@ -446,194 +447,6 @@ static int parse_module_headers(semanage_handle_t * sh, char *module_data,
+        return 0;
+ }
+ 
+-#include <stdlib.h>
+-#include <bzlib.h>
+-#include <string.h>
+-#include <sys/sendfile.h>
+-
+-/* bzip() a data to a file, returning the total number of compressed bytes
+- * in the file.  Returns -1 if file could not be compressed. */
+-static ssize_t bzip(semanage_handle_t *sh, const char *filename, char *data,
+-			size_t num_bytes)
+-{
+-	BZFILE* b;
+-	size_t  size = 1<<16;
+-	int     bzerror;
+-	size_t  total = 0;
+-	size_t len = 0;
+-	FILE *f;
+-
+-	if ((f = fopen(filename, "wb")) == NULL) {
+-		return -1;
+-	}
+-
+-	if (!sh->conf->bzip_blocksize) {
+-		if (fwrite(data, 1, num_bytes, f) < num_bytes) {
+-			fclose(f);
+-			return -1;
+-		}
+-		fclose(f);
+-		return num_bytes;
+-	}
+-
+-	b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0);
+-	if (bzerror != BZ_OK) {
+-		BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
+-		return -1;
+-	}
+-	
+-	while ( num_bytes > total ) {
+-		if (num_bytes - total > size) {
+-			len = size;
+-		} else {
+-			len = num_bytes - total;
+-		}
+-		BZ2_bzWrite ( &bzerror, b, &data[total], len );
+-		if (bzerror == BZ_IO_ERROR) { 
+-			BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
+-			return -1;
+-		}
+-		total += len;
+-	}
+-
+-	BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 );
+-	fclose(f);
+-	if (bzerror == BZ_IO_ERROR) {
+-		return -1;
+-	}
+-	return total;
+-}
+-
+-#define BZ2_MAGICSTR "BZh"
+-#define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1)
+-
+-/* bunzip() a file to '*data', returning the total number of uncompressed bytes
+- * in the file.  Returns -1 if file could not be decompressed. */
+-ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data)
+-{
+-	BZFILE* b = NULL;
+-	size_t  nBuf;
+-	char*   buf = NULL;
+-	size_t  size = 1<<18;
+-	size_t  bufsize = size;
+-	int     bzerror;
+-	size_t  total = 0;
+-	char*   uncompress = NULL;
+-	char*   tmpalloc = NULL;
+-	int     ret = -1;
+-
+-	buf = malloc(bufsize);
+-	if (buf == NULL) {
+-		ERR(sh, "Failure allocating memory.");
+-		goto exit;
+-	}
+-
+-	/* Check if the file is bzipped */
+-	bzerror = fread(buf, 1, BZ2_MAGICLEN, f);
+-	rewind(f);
+-	if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) {
+-		goto exit;
+-	}
+-
+-	b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 );
+-	if ( bzerror != BZ_OK ) {
+-		ERR(sh, "Failure opening bz2 archive.");
+-		goto exit;
+-	}
+-
+-	uncompress = malloc(size);
+-	if (uncompress == NULL) {
+-		ERR(sh, "Failure allocating memory.");
+-		goto exit;
+-	}
+-
+-	while ( bzerror == BZ_OK) {
+-		nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize);
+-		if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) {
+-			if (total + nBuf > size) {
+-				size *= 2;
+-				tmpalloc = realloc(uncompress, size);
+-				if (tmpalloc == NULL) {
+-					ERR(sh, "Failure allocating memory.");
+-					goto exit;
+-				}
+-				uncompress = tmpalloc;
+-			}
+-			memcpy(&uncompress[total], buf, nBuf);
+-			total += nBuf;
+-		}
+-	}
+-	if ( bzerror != BZ_STREAM_END ) {
+-		ERR(sh, "Failure reading bz2 archive.");
+-		goto exit;
+-	}
+-
+-	ret = total;
+-	*data = uncompress;
+-
+-exit:
+-	BZ2_bzReadClose ( &bzerror, b );
+-	free(buf);
+-	if ( ret < 0 ) {
+-		free(uncompress);
+-	}
+-	return ret;
+-}
+-
+-/* mmap() a file to '*data',
+- *  If the file is bzip compressed map_file will uncompress 
+- * the file into '*data'.
+- * Returns the total number of bytes in memory .
+- * Returns -1 if file could not be opened or mapped. */
+-static ssize_t map_file(semanage_handle_t *sh, const char *path, char **data,
+-			int *compressed)
+-{
+-	ssize_t size = -1;
+-	char *uncompress;
+-	int fd = -1;
+-	FILE *file = NULL;
+-
+-	fd = open(path, O_RDONLY);
+-	if (fd == -1) {
+-		ERR(sh, "Unable to open %s\n", path);
+-		return -1;
+-	}
+-
+-	file = fdopen(fd, "r");
+-	if (file == NULL) {
+-		ERR(sh, "Unable to open %s\n", path);
+-		close(fd);
+-		return -1;
+-	}
+-
+-	if ((size = bunzip(sh, file, &uncompress)) > 0) {
+-		*data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+-		if (*data == MAP_FAILED) {
+-			free(uncompress);
+-			fclose(file);
+-			return -1;
+-		} else {
+-			memcpy(*data, uncompress, size);
+-		}
+-		free(uncompress);
+-		*compressed = 1;
+-	} else {
+-		struct stat sb;
+-		if (fstat(fd, &sb) == -1 ||
+-		    (*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
+-		    MAP_FAILED) {
+-			size = -1;
+-		} else {
+-			size = sb.st_size;
+-		}
+-		*compressed = 0;
+-	} 
+-
+-	fclose(file);
+-
+-	return size;
+-}
+-
+ /* Writes a block of data to a file.  Returns 0 on success, -1 on
+  * error. */
+ static int write_file(semanage_handle_t * sh,
+@@ -1045,15 +858,12 @@ static int semanage_compile_module(semanage_handle_t *sh,
+ 	char *compiler_path = NULL;
+ 	char *cil_data = NULL;
+ 	char *err_data = NULL;
+-	char *hll_data = NULL;
+ 	char *start = NULL;
+ 	char *end = NULL;
+-	ssize_t hll_data_len = 0;
+-	ssize_t bzip_status;
+ 	int status = 0;
+-	int compressed;
+ 	size_t cil_data_len = 0;
+ 	size_t err_data_len = 0;
++	struct file_contents hll_contents = {};
+ 
+ 	if (!strcasecmp(modinfo->lang_ext, "cil")) {
+ 		goto cleanup;
+@@ -1084,13 +894,15 @@ static int semanage_compile_module(semanage_handle_t *sh,
+ 		goto cleanup;
+ 	}
+ 
+-	if ((hll_data_len = map_file(sh, hll_path, &hll_data, &compressed)) <= 0) {
++	status = map_compressed_file(sh, hll_path, &hll_contents);
++	if (status < 0) {
+ 		ERR(sh, "Unable to read file %s\n", hll_path);
+-		status = -1;
+ 		goto cleanup;
+ 	}
+ 
+-	status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
++	status = semanage_pipe_data(sh, compiler_path, hll_contents.data,
++				    hll_contents.len, &cil_data, &cil_data_len,
++				    &err_data, &err_data_len);
+ 	if (err_data_len > 0) {
+ 		for (start = end = err_data; end < err_data + err_data_len; end++) {
+ 			if (*end == '\n') {
+@@ -1110,10 +922,9 @@ static int semanage_compile_module(semanage_handle_t *sh,
+ 		goto cleanup;
+ 	}
+ 
+-	bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
+-	if (bzip_status == -1) {
+-		ERR(sh, "Failed to bzip %s\n", cil_path);
+-		status = -1;
++	status = write_compressed_file(sh, cil_path, cil_data, cil_data_len);
++	if (status == -1) {
++		ERR(sh, "Failed to write %s\n", cil_path);
+ 		goto cleanup;
+ 	}
+ 
+@@ -1131,9 +942,7 @@ static int semanage_compile_module(semanage_handle_t *sh,
+ 	}
+ 
+ cleanup:
+-	if (hll_data_len > 0) {
+-		munmap(hll_data, hll_data_len);
+-	}
++	unmap_compressed_file(&hll_contents);
+ 	free(cil_data);
+ 	free(err_data);
+ 	free(compiler_path);
+@@ -1756,19 +1565,17 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
+ {
+ 
+ 	int retval = -1;
+-	char *data = NULL;
+-	ssize_t data_len = 0;
+-	int compressed = 0;
+ 	char *path = NULL;
+ 	char *filename;
+ 	char *lang_ext = NULL;
+ 	char *module_name = NULL;
+ 	char *separator;
+ 	char *version = NULL;
++	struct file_contents contents = {};
+ 
+-	if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 0) {
++	retval = map_compressed_file(sh, install_filename, &contents);
++	if (retval < 0) {
+ 		ERR(sh, "Unable to read file %s\n", install_filename);
+-		retval = -1;
+ 		goto cleanup;
+ 	}
+ 
+@@ -1781,7 +1588,7 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
+ 
+ 	filename = basename(path);
+ 
+-	if (compressed) {
++	if (contents.compressed) {
+ 		separator = strrchr(filename, '.');
+ 		if (separator == NULL) {
+ 			ERR(sh, "Compressed module does not have a valid extension.");
+@@ -1805,7 +1612,8 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
+ 	}
+ 
+ 	if (strcmp(lang_ext, "pp") == 0) {
+-		retval = parse_module_headers(sh, data, data_len, &module_name, &version);
++		retval = parse_module_headers(sh, contents.data, contents.len,
++					      &module_name, &version);
+ 		free(version);
+ 		if (retval != 0)
+ 			goto cleanup;
+@@ -1822,10 +1630,11 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
+ 		fprintf(stderr, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s\n", install_filename, module_name, filename);
+ 	}
+ 
+-	retval = semanage_direct_install(sh, data, data_len, module_name, lang_ext);
++	retval = semanage_direct_install(sh, contents.data, contents.len,
++					 module_name, lang_ext);
+ 
+ cleanup:
+-	if (data_len > 0) munmap(data, data_len);
++	unmap_compressed_file(&contents);
+ 	free(module_name);
+ 	free(path);
+ 
+@@ -1844,10 +1653,8 @@ static int semanage_direct_extract(semanage_handle_t * sh,
+ 	enum semanage_module_path_type file_type;
+ 	int rc = -1;
+ 	semanage_module_info_t *_modinfo = NULL;
+-	ssize_t _data_len;
+-	char *_data;
+-	int compressed;
+ 	struct stat sb;
++	struct file_contents contents = {};
+ 
+ 	/* get path of module */
+ 	rc = semanage_module_get_path(
+@@ -1903,19 +1710,33 @@ static int semanage_direct_extract(semanage_handle_t * sh,
+ 		}
+ 	}
+ 
+-	_data_len = map_file(sh, input_file, &_data, &compressed);
+-	if (_data_len <= 0) {
++	rc = map_compressed_file(sh, input_file, &contents);
++	if (rc < 0) {
+ 		ERR(sh, "Error mapping file: %s", input_file);
+-		rc = -1;
+ 		goto cleanup;
+ 	}
+ 
++	/* The API promises an mmap'ed pointer */
++	if (contents.compressed) {
++		*mapped_data = mmap(NULL, contents.len, PROT_READ|PROT_WRITE,
++				    MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
++		if (*mapped_data == MAP_FAILED) {
++			ERR(sh, "Unable to map memory");
++			rc = -1;
++			goto cleanup;
++		}
++		memcpy(*mapped_data, contents.data, contents.len);
++		free(contents.data);
++	} else {
++		*mapped_data = contents.data;
++	}
++
+ 	*modinfo = _modinfo;
+-	*data_len = (size_t)_data_len;
+-	*mapped_data = _data;
++	*data_len = contents.len;
+ 
+ cleanup:
+ 	if (rc != 0) {
++		unmap_compressed_file(&contents);
+ 		semanage_module_info_destroy(sh, _modinfo);
+ 		free(_modinfo);
+ 	}
+@@ -2864,8 +2685,8 @@ static int semanage_direct_install_info(semanage_handle_t *sh,
+ 		goto cleanup;
+ 	}
+ 
+-	ret = bzip(sh, path, data, data_len);
+-	if (ret <= 0) {
++	ret = write_compressed_file(sh, path, data, data_len);
++	if (ret < 0) {
+ 		ERR(sh, "Error while writing to %s.", path);
+ 		status = -3;
+ 		goto cleanup;
+diff --git a/libsemanage/src/direct_api.h b/libsemanage/src/direct_api.h
+index e56107b27573..ffd428eb82ba 100644
+--- a/libsemanage/src/direct_api.h
++++ b/libsemanage/src/direct_api.h
+@@ -39,8 +39,4 @@ int semanage_direct_access_check(struct semanage_handle *sh);
+ 
+ int semanage_direct_mls_enabled(struct semanage_handle *sh);
+ 
+-#include <stdio.h>
+-#include <unistd.h>
+-ssize_t bunzip(struct semanage_handle *sh, FILE *f, char **data);
+-
+ #endif
+diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
+index c6a736fe2d26..633ee73165fb 100644
+--- a/libsemanage/src/semanage_store.c
++++ b/libsemanage/src/semanage_store.c
+@@ -59,6 +59,7 @@ typedef struct dbase_policydb dbase_t;
+ 
+ #include "debug.h"
+ #include "utilities.h"
++#include "compressed_file.h"
+ 
+ #define SEMANAGE_CONF_FILE "semanage.conf"
+ /* relative path names to enum semanage_paths to special files and
+@@ -2054,60 +2055,27 @@ int semanage_direct_get_serial(semanage_handle_t * sh)
+ 
+ int semanage_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filenames, int numfiles)
+ {
+-	int retval = 0;
+-	FILE *fp;
+-	ssize_t size;
+-	char *data = NULL;
++	int i, retval = 0;
+ 	char *filename;
+-	int i;
++	struct file_contents contents = {};
+ 
+ 	for (i = 0; i < numfiles; i++) {
+ 		filename = filenames[i];
+ 
+-		if ((fp = fopen(filename, "rb")) == NULL) {
+-			ERR(sh, "Could not open module file %s for reading.", filename);
+-			goto cleanup;
+-		}
+-
+-		if ((size = bunzip(sh, fp, &data)) <= 0) {
+-			rewind(fp);
+-			__fsetlocking(fp, FSETLOCKING_BYCALLER);
+-
+-			if (fseek(fp, 0, SEEK_END) != 0) {
+-				ERR(sh, "Failed to determine size of file %s.", filename);
+-				goto cleanup;
+-			}
+-			size = ftell(fp);
+-			rewind(fp);
+-
+-			data = malloc(size);
+-			if (fread(data, size, 1, fp) != 1) {
+-				ERR(sh, "Failed to read file %s.", filename);
+-				goto cleanup;
+-			}
+-		}
++		retval = map_compressed_file(sh, filename, &contents);
++		if (retval < 0)
++			return -1;
+ 
+-		fclose(fp);
+-		fp = NULL;
++		retval = cil_add_file(cildb, filename, contents.data, contents.len);
++		unmap_compressed_file(&contents);
+ 
+-		retval = cil_add_file(cildb, filename, data, size);
+ 		if (retval != SEPOL_OK) {
+ 			ERR(sh, "Error while reading from file %s.", filename);
+-			goto cleanup;
++			return -1;
+ 		}
+-	
+-		free(data);
+-		data = NULL;
+ 	}
+ 
+-	return retval;
+-
+-      cleanup:
+-	if (fp != NULL) {
+-		fclose(fp);
+-	}
+-	free(data);
+-	return -1;
++	return 0;
+ }
+ 
+ /* 
+-- 
+2.34.1
+
diff --git a/SOURCES/0005-libsemanage-clean-up-semanage_direct_commit-a-bit.patch b/SOURCES/0005-libsemanage-clean-up-semanage_direct_commit-a-bit.patch
new file mode 100644
index 0000000..8a05532
--- /dev/null
+++ b/SOURCES/0005-libsemanage-clean-up-semanage_direct_commit-a-bit.patch
@@ -0,0 +1,150 @@
+From b3c63ad0f9c5c35d80fabeb0ca7abd86f34aad0e Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Thu, 3 Feb 2022 17:53:25 +0100
+Subject: [PATCH] libsemanage: clean up semanage_direct_commit() a bit
+
+Do some minor cosmetic cleanup, mainly to eliminate the 'rebuilt' goto
+label.
+
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+---
+ libsemanage/src/direct_api.c | 91 ++++++++++++++++++------------------
+ 1 file changed, 45 insertions(+), 46 deletions(-)
+
+diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
+index aa2bfcf35016..bed1e1eda78f 100644
+--- a/libsemanage/src/direct_api.c
++++ b/libsemanage/src/direct_api.c
+@@ -994,6 +994,16 @@ cleanup:
+ 	return status;
+ }
+ 
++/* Files that must exist in order to skip policy rebuild. */
++static const int semanage_computed_files[] = {
++	SEMANAGE_STORE_KERNEL,
++	SEMANAGE_STORE_FC,
++	SEMANAGE_STORE_SEUSERS,
++	SEMANAGE_LINKED,
++	SEMANAGE_SEUSERS_LINKED,
++	SEMANAGE_USERS_EXTRA_LINKED
++};
++
+ /* Copies a file from src to dst. If dst already exists then
+  * overwrite it. If source doesn't exist then return success.
+  * Returns 0 on success, -1 on error. */
+@@ -1053,6 +1063,14 @@ static int semanage_direct_commit(semanage_handle_t * sh)
+ 	seusers_modified = seusers->dtable->is_modified(seusers->dbase);
+ 	fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
+ 
++	/* Before we do anything else, flush the join to its component parts.
++	 * This *does not* flush to disk automatically */
++	if (users->dtable->is_modified(users->dbase)) {
++		retval = users->dtable->flush(sh, users->dbase);
++		if (retval < 0)
++			goto cleanup;
++	}
++
+ 	/* Rebuild if explicitly requested or any module changes occurred. */
+ 	do_rebuild = sh->do_rebuild | sh->modules_modified;
+ 
+@@ -1119,14 +1137,6 @@ static int semanage_direct_commit(semanage_handle_t * sh)
+ 		}
+ 	}
+ 
+-	/* Before we do anything else, flush the join to its component parts.
+-	 * This *does not* flush to disk automatically */
+-	if (users->dtable->is_modified(users->dbase)) {
+-		retval = users->dtable->flush(sh, users->dbase);
+-		if (retval < 0)
+-			goto cleanup;
+-	}
+-
+ 	/*
+ 	 * This is for systems that have already migrated with an older version
+ 	 * of semanage_migrate_store. The older version did not copy
+@@ -1135,48 +1145,20 @@ static int semanage_direct_commit(semanage_handle_t * sh)
+ 	 * in order to skip re-linking are present; otherwise, we force
+ 	 * a rebuild.
+ 	 */
+-	if (!do_rebuild) {
+-		int files[] = {SEMANAGE_STORE_KERNEL,
+-					   SEMANAGE_STORE_FC,
+-					   SEMANAGE_STORE_SEUSERS,
+-					   SEMANAGE_LINKED,
+-					   SEMANAGE_SEUSERS_LINKED,
+-					   SEMANAGE_USERS_EXTRA_LINKED};
+-
+-		for (i = 0; i < (int) ARRAY_SIZE(files); i++) {
+-			path = semanage_path(SEMANAGE_TMP, files[i]);
+-			if (stat(path, &sb) != 0) {
+-				if (errno != ENOENT) {
+-					ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
+-					retval = -1;
+-					goto cleanup;
+-				}
+-
+-				do_rebuild = 1;
+-				goto rebuild;
++	for (i = 0; !do_rebuild && i < (int)ARRAY_SIZE(semanage_computed_files); i++) {
++		path = semanage_path(SEMANAGE_TMP, semanage_computed_files[i]);
++		if (stat(path, &sb) != 0) {
++			if (errno != ENOENT) {
++				ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
++				retval = -1;
++				goto cleanup;
+ 			}
++
++			do_rebuild = 1;
++			break;
+ 		}
+ 	}
+ 
+-rebuild:
+-	/*
+-	 * Now that we know whether or not a rebuild is required,
+-	 * we can determine what else needs to be done.
+-	 * We need to write the kernel policy if we are rebuilding
+-	 * or if any other policy component that lives in the kernel
+-	 * policy has been modified.
+-	 * We need to install the policy files if any of the managed files
+-	 * that live under /etc/selinux (kernel policy, seusers, file contexts)
+-	 * will be modified.
+-	 */
+-	do_write_kernel = do_rebuild | ports_modified | ibpkeys_modified |
+-		ibendports_modified |
+-		bools->dtable->is_modified(bools->dbase) |
+-		ifaces->dtable->is_modified(ifaces->dbase) |
+-		nodes->dtable->is_modified(nodes->dbase) |
+-		users->dtable->is_modified(users_base->dbase);
+-	do_install = do_write_kernel | seusers_modified | fcontexts_modified;
+-
+ 	/*
+ 	 * If there were policy changes, or explicitly requested, or
+ 	 * any required files are missing, rebuild the policy.
+@@ -1330,6 +1312,23 @@ rebuild:
+ 		}
+ 	}
+ 
++	/*
++	 * Determine what else needs to be done.
++	 * We need to write the kernel policy if we are rebuilding
++	 * or if any other policy component that lives in the kernel
++	 * policy has been modified.
++	 * We need to install the policy files if any of the managed files
++	 * that live under /etc/selinux (kernel policy, seusers, file contexts)
++	 * will be modified.
++	 */
++	do_write_kernel = do_rebuild | ports_modified | ibpkeys_modified |
++		ibendports_modified |
++		bools->dtable->is_modified(bools->dbase) |
++		ifaces->dtable->is_modified(ifaces->dbase) |
++		nodes->dtable->is_modified(nodes->dbase) |
++		users->dtable->is_modified(users_base->dbase);
++	do_install = do_write_kernel | seusers_modified | fcontexts_modified;
++
+ 	/* Attach our databases to the policydb we just created or loaded. */
+ 	dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out);
+ 	dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out);
+-- 
+2.34.1
+
diff --git a/SOURCES/0006-libsemanage-optionally-rebuild-policy-when-modules-a.patch b/SOURCES/0006-libsemanage-optionally-rebuild-policy-when-modules-a.patch
new file mode 100644
index 0000000..6cada7b
--- /dev/null
+++ b/SOURCES/0006-libsemanage-optionally-rebuild-policy-when-modules-a.patch
@@ -0,0 +1,492 @@
+From e8251a69e9f8386a232c999c068ed2daf02a8370 Mon Sep 17 00:00:00 2001
+From: Ondrej Mosnacek <omosnace@redhat.com>
+Date: Thu, 3 Feb 2022 17:53:26 +0100
+Subject: [PATCH] libsemanage: optionally rebuild policy when modules are
+ changed externally
+
+In Fedora/RHEL's selinux-policy package we ship a pre-built SELinux
+policy store in the RPMs. When updating the main policy RPM, care must
+be taken to rebuild the policy using `semodule -B` if there are any
+other SELinux modules installed (whether shipped via another RPM or
+manually installed locally).
+
+However, this way of shipping/managing the policy creates complications
+on systems, where system files are managed by rpm-ostree (such as Fedora
+CoreOS or Red Hat CoreOS), where the "package update" process is more
+sophisticated.
+
+(Disclaimer: The following is written according to my current limited
+understanding of rpm-ostree and may not be entirely accurate, but the
+gist of it should match the reality.)
+
+Basically, one can think of rpm-ostree as a kind of Git for system
+files. The package content is provided on a "branch", where each
+"commit" represents a set of package updates layered on top of the
+previous commit (i.e. it is a rolling release with some defined
+package content snapshots). The user can then maintain their own branch
+with additional package updates/installations/... and "rebase" it on top
+of the main branch as needed. On top of that, the user can also have
+additional configuration files (or modifications to existing files) in
+/etc, which represent an additional layer on top of the package content.
+
+When updating the system (i.e. rebasing on a new "commit" of the "main
+branch"), the files on the running system are not touched and the new
+system state is prepared under a new root directory, which is chrooted
+into on the next reboot.
+
+When an rpm-ostree system is updated, there are three moments when the
+SELinux module store needs to be rebuilt to ensure that all modules are
+included in the binary policy:
+1. When the local RPM installations are applied on top of the base
+   system snapshot.
+2. When local user configuartion is applied on top of that.
+3. On system shutdown, to ensure that any changes in local configuration
+   performed since (2.) are reflected in the final new system image.
+
+Forcing a full rebuild at each step is not optimal and in many cases is
+not necessary, as the user may not have any custom modules installed.
+
+Thus, this patch extends libsemanage to compute a checksum of the
+content of all enabled modules, which is stored in the store, and adds a
+flag to the libsemanage handle that instructs it to check the module
+content checksum against the one from the last successful transaction
+and force a full policy rebuild if they don't match.
+
+This will allow rpm-ostree systems to potentially reduce delays when
+reconciling the module store when applying updates.
+
+I wasn't able to measure any noticeable overhead of the hash
+computation, which is now added for every transaction (both before and
+after this change a full policy rebuild took about 7 seconds on my test
+x86 VM). With the new option check_ext_changes enabled, rebuilding a
+policy store with unchanged modules took only about 0.96 seconds.
+
+Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
+---
+ libsemanage/include/semanage/handle.h |   5 +
+ libsemanage/src/direct_api.c          | 187 +++++++++++++++++++++-----
+ libsemanage/src/handle.c              |  11 +-
+ libsemanage/src/handle.h              |   1 +
+ libsemanage/src/libsemanage.map       |   1 +
+ libsemanage/src/modules.c             |   4 +-
+ libsemanage/src/modules.h             |   3 +
+ libsemanage/src/semanage_store.c      |   1 +
+ libsemanage/src/semanage_store.h      |   1 +
+ 9 files changed, 175 insertions(+), 39 deletions(-)
+
+diff --git a/libsemanage/include/semanage/handle.h b/libsemanage/include/semanage/handle.h
+index 946d69bc91fe..0157be4fbc46 100644
+--- a/libsemanage/include/semanage/handle.h
++++ b/libsemanage/include/semanage/handle.h
+@@ -66,6 +66,11 @@ extern void semanage_set_reload(semanage_handle_t * handle, int do_reload);
+  * 1 for yes, 0 for no (default) */
+ extern void semanage_set_rebuild(semanage_handle_t * handle, int do_rebuild);
+ 
++/* set whether to rebuild the policy on commit when potential changes
++ * to module files since last rebuild are detected,
++ * 1 for yes (default), 0 for no */
++extern void semanage_set_check_ext_changes(semanage_handle_t * handle, int do_check);
++
+ /* Fills *compiler_path with the location of the hll compiler sh->conf->compiler_directory_path
+  * corresponding to lang_ext.
+  * Upon success returns 0, -1 on error. */
+diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
+index bed1e1eda78f..e0255310395b 100644
+--- a/libsemanage/src/direct_api.c
++++ b/libsemanage/src/direct_api.c
+@@ -33,6 +33,8 @@
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
++#include <sys/mman.h>
++#include <sys/wait.h>
+ #include <limits.h>
+ #include <errno.h>
+ #include <dirent.h>
+@@ -56,8 +58,7 @@
+ #include "semanage_store.h"
+ #include "database_policydb.h"
+ #include "policy.h"
+-#include <sys/mman.h>
+-#include <sys/wait.h>
++#include "sha256.h"
+ 
+ #define PIPE_READ 0
+ #define PIPE_WRITE 1
+@@ -450,7 +451,7 @@ static int parse_module_headers(semanage_handle_t * sh, char *module_data,
+ /* Writes a block of data to a file.  Returns 0 on success, -1 on
+  * error. */
+ static int write_file(semanage_handle_t * sh,
+-		      const char *filename, char *data, size_t num_bytes)
++		      const char *filename, const char *data, size_t num_bytes)
+ {
+ 	int out;
+ 
+@@ -850,8 +851,21 @@ cleanup:
+ 	return ret;
+ }
+ 
++static void update_checksum_with_len(Sha256Context *context, size_t s)
++{
++	int i;
++	uint8_t buffer[8];
++
++	for (i = 0; i < 8; i++) {
++		buffer[i] = s & 0xff;
++		s >>= 8;
++	}
++	Sha256Update(context, buffer, 8);
++}
++
+ static int semanage_compile_module(semanage_handle_t *sh,
+-				semanage_module_info_t *modinfo)
++				   semanage_module_info_t *modinfo,
++				   Sha256Context *context)
+ {
+ 	char cil_path[PATH_MAX];
+ 	char hll_path[PATH_MAX];
+@@ -922,6 +936,11 @@ static int semanage_compile_module(semanage_handle_t *sh,
+ 		goto cleanup;
+ 	}
+ 
++	if (context) {
++		update_checksum_with_len(context, cil_data_len);
++		Sha256Update(context, cil_data, cil_data_len);
++	}
++
+ 	status = write_compressed_file(sh, cil_path, cil_data, cil_data_len);
+ 	if (status == -1) {
+ 		ERR(sh, "Failed to write %s\n", cil_path);
+@@ -950,18 +969,40 @@ cleanup:
+ 	return status;
+ }
+ 
++static int modinfo_cmp(const void *a, const void *b)
++{
++	const semanage_module_info_t *ma = a;
++	const semanage_module_info_t *mb = b;
++
++	return strcmp(ma->name, mb->name);
++}
++
+ static int semanage_compile_hll_modules(semanage_handle_t *sh,
+-				semanage_module_info_t *modinfos,
+-				int num_modinfos)
++					semanage_module_info_t *modinfos,
++					int num_modinfos,
++					char *cil_checksum)
+ {
+-	int status = 0;
+-	int i;
++	/* to be incremented when checksum input data format changes */
++	static const size_t CHECKSUM_EPOCH = 1;
++
++	int i, status = 0;
+ 	char cil_path[PATH_MAX];
+ 	struct stat sb;
++	Sha256Context context;
++	SHA256_HASH hash;
++	struct file_contents contents = {};
+ 
+ 	assert(sh);
+ 	assert(modinfos);
+ 
++	/* Sort modules by name to get consistent ordering. */
++	qsort(modinfos, num_modinfos, sizeof(*modinfos), &modinfo_cmp);
++
++	Sha256Initialise(&context);
++	update_checksum_with_len(&context, CHECKSUM_EPOCH);
++
++	/* prefix with module count to avoid collisions */
++	update_checksum_with_len(&context, num_modinfos);
+ 	for (i = 0; i < num_modinfos; i++) {
+ 		status = semanage_module_get_path(
+ 				sh,
+@@ -969,29 +1010,91 @@ static int semanage_compile_hll_modules(semanage_handle_t *sh,
+ 				SEMANAGE_MODULE_PATH_CIL,
+ 				cil_path,
+ 				sizeof(cil_path));
+-		if (status != 0) {
+-			goto cleanup;
+-		}
++		if (status != 0)
++			return -1;
+ 
+-		if (semanage_get_ignore_module_cache(sh) == 0 &&
+-				(status = stat(cil_path, &sb)) == 0) {
+-			continue;
+-		}
+-		if (status != 0 && errno != ENOENT) {
+-			ERR(sh, "Unable to access %s: %s\n", cil_path, strerror(errno));
+-			goto cleanup; //an error in the "stat" call
++		if (!semanage_get_ignore_module_cache(sh)) {
++			status = stat(cil_path, &sb);
++			if (status == 0) {
++				status = map_compressed_file(sh, cil_path, &contents);
++				if (status < 0) {
++					ERR(sh, "Error mapping file: %s", cil_path);
++					return -1;
++				}
++
++				/* prefix with length to avoid collisions */
++				update_checksum_with_len(&context, contents.len);
++				Sha256Update(&context, contents.data, contents.len);
++
++				unmap_compressed_file(&contents);
++				continue;
++			} else if (errno != ENOENT) {
++				ERR(sh, "Unable to access %s: %s\n", cil_path,
++				    strerror(errno));
++				return -1; //an error in the "stat" call
++			}
+ 		}
+ 
+-		status = semanage_compile_module(sh, &modinfos[i]);
+-		if (status < 0) {
+-			goto cleanup;
++		status = semanage_compile_module(sh, &modinfos[i], &context);
++		if (status < 0)
++			return -1;
++	}
++	Sha256Finalise(&context, &hash);
++
++	semanage_hash_to_checksum_string(hash.bytes, cil_checksum);
++	return 0;
++}
++
++static int semanage_compare_checksum(semanage_handle_t *sh, const char *reference)
++{
++	const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM);
++	struct stat sb;
++	int fd, retval;
++	char *data;
++
++	fd = open(path, O_RDONLY);
++	if (fd == -1) {
++		if (errno != ENOENT) {
++			ERR(sh, "Unable to open %s: %s\n", path, strerror(errno));
++			return -1;
+ 		}
++		/* Checksum file not present - force a rebuild. */
++		return 1;
++	}
++
++	if (fstat(fd, &sb) == -1) {
++		ERR(sh, "Unable to stat %s\n", path);
++		retval = -1;
++		goto out_close;
+ 	}
+ 
+-	status = 0;
++	if (sb.st_size != (off_t)CHECKSUM_CONTENT_SIZE) {
++		/* Incompatible/invalid hash type - just force a rebuild. */
++		WARN(sh, "Module checksum invalid - forcing a rebuild\n");
++		retval = 1;
++		goto out_close;
++	}
+ 
+-cleanup:
+-	return status;
++	data = mmap(NULL, CHECKSUM_CONTENT_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
++	if (data == MAP_FAILED) {
++		ERR(sh, "Unable to mmap %s\n", path);
++		retval = -1;
++		goto out_close;
++	}
++
++	retval = memcmp(data, reference, CHECKSUM_CONTENT_SIZE) != 0;
++	munmap(data, sb.st_size);
++out_close:
++	close(fd);
++	return retval;
++}
++
++static int semanage_write_modules_checksum(semanage_handle_t *sh,
++					   const char *checksum)
++{
++	const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM);
++
++	return write_file(sh, path, checksum, CHECKSUM_CONTENT_SIZE);
+ }
+ 
+ /* Files that must exist in order to skip policy rebuild. */
+@@ -1030,6 +1133,7 @@ static int semanage_direct_commit(semanage_handle_t * sh)
+ 	semanage_module_info_t *modinfos = NULL;
+ 	mode_t mask = umask(0077);
+ 	struct stat sb;
++	char modules_checksum[CHECKSUM_CONTENT_SIZE + 1 /* '\0' */];
+ 
+ 	int do_rebuild, do_write_kernel, do_install;
+ 	int fcontexts_modified, ports_modified, seusers_modified,
+@@ -1159,28 +1263,45 @@ static int semanage_direct_commit(semanage_handle_t * sh)
+ 		}
+ 	}
+ 
+-	/*
+-	 * If there were policy changes, or explicitly requested, or
+-	 * any required files are missing, rebuild the policy.
+-	 */
+-	if (do_rebuild) {
+-		/* =================== Module expansion =============== */
+-
++	if (do_rebuild || sh->check_ext_changes) {
+ 		retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos);
+ 		if (retval < 0) {
+ 			goto cleanup;
+ 		}
+ 
++		/* No modules - nothing to rebuild. */
+ 		if (num_modinfos == 0) {
+ 			goto cleanup;
+ 		}
+ 
+-		retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos);
++		retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos,
++						      modules_checksum);
+ 		if (retval < 0) {
+ 			ERR(sh, "Failed to compile hll files into cil files.\n");
+ 			goto cleanup;
+ 		}
+ 
++		if (!do_rebuild && sh->check_ext_changes) {
++			retval = semanage_compare_checksum(sh, modules_checksum);
++			if (retval < 0)
++				goto cleanup;
++			do_rebuild = retval;
++		}
++
++		retval = semanage_write_modules_checksum(sh, modules_checksum);
++		if (retval < 0) {
++			ERR(sh, "Failed to write module checksum file.\n");
++			goto cleanup;
++		}
++	}
++
++	/*
++	 * If there were policy changes, or explicitly requested, or
++	 * any required files are missing, rebuild the policy.
++	 */
++	if (do_rebuild) {
++		/* =================== Module expansion =============== */
++
+ 		retval = semanage_get_cil_paths(sh, modinfos, num_modinfos, &mod_filenames);
+ 		if (retval < 0)
+ 			goto cleanup;
+@@ -1703,7 +1824,7 @@ static int semanage_direct_extract(semanage_handle_t * sh,
+ 			goto cleanup;
+ 		}
+ 
+-		rc = semanage_compile_module(sh, _modinfo);
++		rc = semanage_compile_module(sh, _modinfo, NULL);
+ 		if (rc < 0) {
+ 			goto cleanup;
+ 		}
+diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c
+index bb1e61400760..b2201ee346dc 100644
+--- a/libsemanage/src/handle.c
++++ b/libsemanage/src/handle.c
+@@ -116,20 +116,23 @@ semanage_handle_t *semanage_handle_create(void)
+ 
+ void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild)
+ {
+-
+ 	assert(sh != NULL);
+ 
+ 	sh->do_rebuild = do_rebuild;
+-	return;
+ }
+ 
+ void semanage_set_reload(semanage_handle_t * sh, int do_reload)
+ {
+-
+ 	assert(sh != NULL);
+ 
+ 	sh->do_reload = do_reload;
+-	return;
++}
++
++void semanage_set_check_ext_changes(semanage_handle_t * sh, int do_check)
++{
++	assert(sh != NULL);
++
++	sh->check_ext_changes = do_check;
+ }
+ 
+ int semanage_get_hll_compiler_path(semanage_handle_t *sh,
+diff --git a/libsemanage/src/handle.h b/libsemanage/src/handle.h
+index e1ce83ba2d08..4d2aae8f69cc 100644
+--- a/libsemanage/src/handle.h
++++ b/libsemanage/src/handle.h
+@@ -61,6 +61,7 @@ struct semanage_handle {
+ 	int is_in_transaction;
+ 	int do_reload;		/* whether to reload policy after commit */
+ 	int do_rebuild;		/* whether to rebuild policy if there were no changes */
++	int check_ext_changes;	/* whether to rebuild if external changes are detected via checksum */
+ 	int commit_err;		/* set by semanage_direct_commit() if there are
+ 				 * any errors when building or committing the
+ 				 * sandbox to kernel policy at /etc/selinux
+diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
+index 00259fc817f5..c8214b26fc03 100644
+--- a/libsemanage/src/libsemanage.map
++++ b/libsemanage/src/libsemanage.map
+@@ -348,4 +348,5 @@ LIBSEMANAGE_1.1 {
+ 
+ LIBSEMANAGE_3.4 {
+     semanage_module_compute_checksum;
++    semanage_set_check_ext_changes;
+ } LIBSEMANAGE_1.1;
+diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
+index 5dbb28fdbaa5..94bf884bf45d 100644
+--- a/libsemanage/src/modules.c
++++ b/libsemanage/src/modules.c
+@@ -978,9 +978,9 @@ int semanage_module_remove_key(semanage_handle_t *sh,
+ }
+ 
+ static const char CHECKSUM_TYPE[] = "sha256";
+-static const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE;
++const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE;
+ 
+-static void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum)
++void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum)
+ {
+ 	size_t i;
+ 
+diff --git a/libsemanage/src/modules.h b/libsemanage/src/modules.h
+index 64d4a157f5ca..cf2432c5b64d 100644
+--- a/libsemanage/src/modules.h
++++ b/libsemanage/src/modules.h
+@@ -102,4 +102,7 @@ int semanage_module_get_path(semanage_handle_t *sh,
+ 			     char *path,
+ 			     size_t len);
+ 
++extern const size_t CHECKSUM_CONTENT_SIZE;
++void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum);
++
+ #endif
+diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
+index 633ee73165fb..767f05cb2853 100644
+--- a/libsemanage/src/semanage_store.c
++++ b/libsemanage/src/semanage_store.c
+@@ -115,6 +115,7 @@ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
+ 	"/disable_dontaudit",
+ 	"/preserve_tunables",
+ 	"/modules/disabled",
++	"/modules_checksum",
+ 	"/policy.kern",
+ 	"/file_contexts.local",
+ 	"/file_contexts.homedirs",
+diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
+index b9ec566427a4..1fc77da83df0 100644
+--- a/libsemanage/src/semanage_store.h
++++ b/libsemanage/src/semanage_store.h
+@@ -60,6 +60,7 @@ enum semanage_sandbox_defs {
+ 	SEMANAGE_DISABLE_DONTAUDIT,
+ 	SEMANAGE_PRESERVE_TUNABLES,
+ 	SEMANAGE_MODULES_DISABLED,
++	SEMANAGE_MODULES_CHECKSUM,
+ 	SEMANAGE_STORE_KERNEL,
+ 	SEMANAGE_STORE_FC_LOCAL,
+ 	SEMANAGE_STORE_FC_HOMEDIRS,
+-- 
+2.34.1
+
diff --git a/SOURCES/semanage.conf b/SOURCES/semanage.conf
new file mode 100644
index 0000000..406f16f
--- /dev/null
+++ b/SOURCES/semanage.conf
@@ -0,0 +1,60 @@
+# Authors: Jason Tang <jtang@tresys.com>
+#
+# Copyright (C) 2004-2005 Tresys Technology, LLC
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+# Specify how libsemanage will interact with a SELinux policy manager.
+# The four options are:
+#
+#  "source"     - libsemanage manipulates a source SELinux policy
+#  "direct"     - libsemanage will write directly to a module store.
+#  /foo/bar     - Write by way of a policy management server, whose
+#                 named socket is at /foo/bar.  The path must begin
+#                 with a '/'.
+#  foo.com:4242 - Establish a TCP connection to a remote policy
+#                 management server at foo.com.  If there is a colon
+#                 then the remainder is interpreted as a port number;
+#                 otherwise default to port 4242.
+module-store = direct
+
+# When generating the final linked and expanded policy, by default
+# semanage will set the policy version to POLICYDB_VERSION_MAX, as
+# given in <sepol/policydb.h>.  Change this setting if a different
+# version is necessary.
+#policy-version = 19
+
+# expand-check check neverallow rules when executing all semanage
+# commands. There might be a penalty in execution time if this
+# option is enabled.
+expand-check=0
+
+# usepasswd check tells semanage to scan all pass word records for home directories
+# and setup the labeling correctly. If this is turned off, SELinux will label only /home
+# and home directories of users with SELinux login mappings defined, see
+# semanage login -l for the list of such users.
+# If you want to use a different home directory, you will need to use semanage fcontext command.
+# For example, if you had home dirs in /althome directory you would have to execute
+# semanage fcontext -a -e /home /althome
+usepasswd=False
+bzip-small=true
+bzip-blocksize=5
+ignoredirs=/root;/bin;/boot;/dev;/etc;/lib;/lib64;/proc;/run;/sbin;/sys;/tmp;/usr;/var
+optimize-policy=true
+
+[sefcontext_compile]
+path = /usr/sbin/sefcontext_compile
+args = -r $@
+[end]
diff --git a/SPECS/libsemanage.spec b/SPECS/libsemanage.spec
new file mode 100644
index 0000000..d255dc0
--- /dev/null
+++ b/SPECS/libsemanage.spec
@@ -0,0 +1,1584 @@
+%define libsepolver 3.3-1
+%define libselinuxver 3.3-1
+
+Summary: SELinux binary policy manipulation library
+Name: libsemanage
+Version: 3.3
+Release: 2%{?dist}
+License: LGPLv2+
+Source0: https://github.com/SELinuxProject/selinux/releases/download/3.3/libsemanage-3.3.tar.gz
+# fedora-selinux/selinux: git format-patch -N 3.3 -- libsemanage
+# i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done
+# Patch list start
+Patch0001: 0001-libsemanage-Fix-RESOURCE_LEAK-and-USE_AFTER_FREE-cov.patch
+Patch0002: 0002-libsemanage-add-missing-include-to-boolean_record.c.patch
+Patch0003: 0003-semodule-libsemanage-move-module-hashing-into-libsem.patch
+Patch0004: 0004-libsemanage-move-compressed-file-handling-into-a-sep.patch
+Patch0005: 0005-libsemanage-clean-up-semanage_direct_commit-a-bit.patch
+Patch0006: 0006-libsemanage-optionally-rebuild-policy-when-modules-a.patch
+# Patch list end
+URL: https://github.com/SELinuxProject/selinux/wiki
+Source1: semanage.conf
+
+BuildRequires: gcc make
+BuildRequires: libselinux-devel >= %{libselinuxver} swig
+BuildRequires: libsepol-devel >= %{libsepolver} 
+BuildRequires: audit-libs-devel
+BuildRequires: bison flex bzip2-devel
+
+BuildRequires: python3
+BuildRequires: python3-devel
+
+Requires: bzip2-libs audit-libs
+Requires: libselinux%{?_isa} >= %{libselinuxver}
+Obsoletes: libsemanage-compat = 3.1-4
+
+%description
+Security-enhanced Linux is a feature of the Linux® kernel and a number
+of utilities with enhanced security functionality designed to add
+mandatory access controls to Linux.  The Security-enhanced Linux
+kernel contains new architectural components originally developed to
+improve the security of the Flask operating system. These
+architectural components provide general support for the enforcement
+of many kinds of mandatory access control policies, including those
+based on the concepts of Type Enforcement®, Role-based Access
+Control, and Multi-level Security.
+
+libsemanage provides an API for the manipulation of SELinux binary policies.
+It is used by checkpolicy (the policy compiler) and similar tools, as well
+as by programs like load_policy that need to perform specific transformations
+on binary policies such as customizing policy boolean settings.
+
+%package static
+Summary: Static library used to build policy manipulation tools
+Requires: libsemanage-devel%{_isa} = %{version}-%{release}
+
+%description static
+The semanage-static package contains the static libraries 
+needed for developing applications that manipulate binary policies. 
+
+%package devel
+Summary: Header files and libraries used to build policy manipulation tools
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description devel
+The semanage-devel package contains the libraries and header files
+needed for developing applications that manipulate binary policies. 
+
+%package -n python3-libsemanage
+Summary: semanage python 3 bindings for libsemanage
+Requires: %{name}%{?_isa} = %{version}-%{release}
+Requires: libselinux-python3
+%{?python_provide:%python_provide python3-libsemanage}
+# Remove before F30
+Provides: %{name}-python3 = %{version}-%{release}
+Provides: %{name}-python3%{?_isa} = %{version}-%{release}
+Obsoletes: %{name}-python3 < %{version}-%{release}
+
+%description -n python3-libsemanage
+The libsemanage-python3 package contains the python 3 bindings for developing
+SELinux management applications.
+
+%prep
+%autosetup -n libsemanage-%{version} -p 2
+
+
+%build
+%set_build_flags
+CFLAGS="$CFLAGS -fno-semantic-interposition"
+
+# To support building the Python wrapper against multiple Python runtimes
+# Define a function, for how to perform a "build" of the python wrapper against
+# a specific runtime:
+BuildPythonWrapper() {
+  BinaryName=$1
+
+  # Perform the build from the upstream Makefile:
+  make \
+    PYTHON=$BinaryName \
+    LIBDIR="%{_libdir}" SHLIBDIR="%{_lib}" \
+    pywrap
+}
+
+make clean
+make swigify
+%make_build LIBDIR="%{_libdir}" SHLIBDIR="%{_lib}" all
+
+BuildPythonWrapper \
+  %{__python3}
+
+%install
+InstallPythonWrapper() {
+  BinaryName=$1
+
+  make \
+    PYTHON=$BinaryName \
+    DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" \
+    install-pywrap
+}
+
+mkdir -p ${RPM_BUILD_ROOT}%{_libdir}
+mkdir -p ${RPM_BUILD_ROOT}%{_includedir} 
+mkdir -p ${RPM_BUILD_ROOT}%{_sharedstatedir}/selinux
+mkdir -p ${RPM_BUILD_ROOT}%{_sharedstatedir}/selinux/tmp
+%make_install LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}"
+
+InstallPythonWrapper \
+  %{__python3} \
+  $(python3-config --extension-suffix)
+  
+cp %{SOURCE1} ${RPM_BUILD_ROOT}%{_sysconfdir}/selinux/semanage.conf
+
+%files
+%license COPYING
+%dir %{_sysconfdir}/selinux
+%config(noreplace) %{_sysconfdir}/selinux/semanage.conf
+%{_libdir}/libsemanage.so.2
+%{_mandir}/man5/*
+%{_mandir}/ru/man5/*
+%dir %{_libexecdir}/selinux
+%dir %{_sharedstatedir}/selinux
+%dir %{_sharedstatedir}/selinux/tmp
+
+%ldconfig_scriptlets
+
+%files static
+%{_libdir}/libsemanage.a
+
+%files devel
+%{_libdir}/libsemanage.so
+%{_libdir}/pkgconfig/libsemanage.pc
+%dir %{_includedir}/semanage
+%{_includedir}/semanage/*.h
+%{_mandir}/man3/*
+
+%files -n python3-libsemanage
+%{python3_sitearch}/*.so
+%{python3_sitearch}/semanage.py*
+%{python3_sitearch}/__pycache__/semanage*
+%{_libexecdir}/selinux/semanage_migrate_store
+
+%changelog
+* Tue Feb 15 2022 Petr Lautrbach <plautrba@redhat.com> - 3.3-2
+- optionally rebuild policy when modules are changed externally
+
+* Fri Oct 22 2021 Petr Lautrbach <plautrba@redhat.com> - 3.3-1
+- SELinux userspace 3.3 release
+
+* Sun Oct 10 2021 Petr Lautrbach <plautrba@redhat.com> - 3.3-0.rc3.1
+- SELinux userspace 3.3-rc3 release
+
+* Wed Sep 29 2021 Petr Lautrbach <plautrba@redhat.com> - 3.3-0.rc2.1
+- SELinux userspace 3.3-rc2 release
+
+* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3.2-4
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+  Related: rhbz#1991688
+
+* Wed Jul 28 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-4
+- Rebase on upstream commit 32611aea6543
+
+* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.2-2
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* Mon Mar  8 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-1
+- SELinux userspace 3.2 release
+
+* Fri Feb  5 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-0.rc2.1
+- SELinux userspace 3.2-rc2 release
+
+* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.2-0.rc1.1.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Wed Jan 20 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-0.rc1.1
+- SELinux userspace 3.2-rc1 release
+
+* Fri Dec 18 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-6
+- Drop "genhomedircon: check usepasswd" patch
+- genhomedircon to ignore
+  /root;/bin;/boot;/dev;/etc;/lib;/lib64;/proc;/run;/sbin;/sys;/tmp;/usr;/var by default
+- Fix usepasswd=False explanation in semanage.conf
+
+* Fri Nov 20 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-5
+- Drop and obsolete libsemanage-compat
+- genhomedircon: check usepasswd
+
+* Fri Oct 30 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-4
+- Drop deprecated functions and duplicated symbols
+- Change library version to libsemanage.so.2
+- Temporary ship -compat with libsemanage.so.1
+- Based on upstream db0f2f382e31
+- Re-enable lto flags
+
+* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> - 3.1-2
+- Use make macros
+- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
+- Use -fno-semantic-interposition and more make macros
+
+* Fri Jul 10 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-1
+- SELinux userspace 3.1 release
+
+* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 3.0-4
+- Rebuilt for Python 3.9
+
+* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Wed Jan 22 2020 Ondrej Mosnacek <omosnace@redhat.com> - 3.0-2
+- Enable policy optimization
+
+* Fri Dec  6 2019 Petr Lautrbach <plautrba@redhat.com> - 3.0-1
+- SELinux userspace 3.0 release
+
+* Mon Nov 11 2019 Petr Lautrbach <plautrba@redhat.com> - 3.0-0.rc1.1
+- SELinux userspace 3.0-rc1 release candidate
+
+* Thu Oct 03 2019 Miro Hrončok <mhroncok@redhat.com> - 2.9-5
+- Rebuilt for Python 3.8.0rc1 (#1748018)
+
+* Sun Aug 18 2019 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.9-4
+- Rebuilt for Python 3.8
+
+* Tue Aug 13 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-3
+- Drop python2-libsemanage (#1738466)
+
+* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.9-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Mon Mar 18 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-1
+- SELinux userspace 2.9 release
+
+* Mon Mar 11 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-0.rc2.1
+- SELinux userspace 2.9-rc2 release
+
+* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.9-0.rc1.1.1
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Fri Jan 25 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-0.rc1.1
+- SELinux userspace 2.9-rc1 release
+
+* Mon Jan 21 2019 Petr Lautrbach <plautrba@redhat.com> - 2.8-8
+- Always set errno to 0 before calling getpwent()
+- Set selinux policy root around calls to selinux_boolean_sub
+
+* Mon Dec 10 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-7
+- genhomedircon - improve handling large groups
+
+* Tue Nov 13 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-6
+- Fix RESOURCE_LEAK and USE_AFTER_FREE coverity scan defects
+
+* Mon Sep 17 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-5
+- Include user name in ROLE_REMOVE audit events
+
+* Tue Sep  4 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-4
+- Reset umask before creating directories (#1186422)
+
+* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.8-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Tue Jun 19 2018 Miro Hrončok <mhroncok@redhat.com> - 2.8-2
+- Rebuilt for Python 3.7
+
+* Fri May 25 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-1
+- SELinux userspace 2.8 release
+
+* Mon May 14 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-0.rc3.1
+- SELinux userspace 2.8-rc3 release candidate
+
+* Fri May  4 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-0.rc2.1
+- SELinux userspace 2.8-rc2 release candidate
+
+* Mon Apr 23 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-0.rc1.1
+- SELinux userspace 2.8-rc1 release candidate
+
+* Wed Mar 21 2018 Petr Lautrbach <plautrba@redhat.com> - 2.7-12
+- build: Replace PYSITEDIR with PYTHONLIBDIR
+- direct_api.c: Fix iterating over array (#1557468)
+
+* Fri Mar 16 2018 Petr Lautrbach <plautrba@workstation> - 2.7-11
+- Revert "remove access() check to make setuid programs work" (#1557468)
+
+* Tue Mar 13 2018 Petr Lautrbach <plautrba@redhat.com> - 2.7-10
+- properly check return value of iterate function
+- Use umask(0077) for fopen() write operations
+- Return commit number if save-previous false
+- Allow tmp files to be kept if a compile fails
+- build: follow standard semantics for DESTDIR and PREFIX
+- Improve warning for installing disabled module
+- silence clang static analyzer report
+- remove access() check to make setuid programs work
+
+* Fri Feb 09 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 2.7-9
+- Escape macros in %%changelog
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.7-8
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Sat Feb 03 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 2.7-7
+- Switch to %%ldconfig_scriptlets
+
+* Tue Jan 09 2018 Iryna Shcherbina <ishcherb@redhat.com> - 2.7-6
+- Update Python 2 dependency declarations to new packaging standards
+  (See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3)
+
+* Wed Nov 22 2017 Petr Lautrbach <plautrba@redhat.com> - 2.7-5
+- free genhomedircon fallback user
+- Rebuild with libsepol-2.7-3 and libselinux-2.7-6
+
+* Fri Oct 20 2017 Petr Lautrbach <plautrba@redhat.com> - 2.7-4
+- Add support for listing fcontext.homedirs file (#1409813)
+
+* Sun Aug 20 2017 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.7-3
+- Add Provides for the old names without %%_isa
+
+* Thu Aug 10 2017 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.7-2
+- Python 2 binary package renamed to python2-libsemanage
+  See https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3
+- Python 3 binary package renamed to python3-libsemanage
+
+* Mon Aug 07 2017 Petr Lautrbach <plautrba@redhat.com> - 2.7-1
+- Update to upstream release 2017-08-04
+- Use 'sefcontext_compile -r' when it's run during SELinux policy build
+
+* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.6-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.6-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Fri Apr 28 2017 Petr Lautrbach <plautrba@redhat.com> - 2.6-4
+- Follow upstream and rename _semanage.so to _semanage.cpython-36m-x86_64-linux-gnu.so
+
+* Tue Apr 18 2017 Petr Lautrbach <plautrba@redhat.com> - 2.6-3
+- Do not list duplicate port entries after setting a boolean (#1439875)
+
+* Thu Mar 02 2017 Petr Lautrbach <plautrba@redhat.com> - 2.6-2
+- Fix FTBFS - fatal error (#1427903)
+
+* Mon Feb 20 2017 Petr Lautrbach <plautrba@redhat.com> - 2.6-1.1
+- Update to upstream release 2016-10-14
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 2.5-10
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Fri Dec 09 2016 Charalampos Stratakis <cstratak@redhat.com> - 2.5-9
+- Rebuild for Python 3.6
+
+* Mon Oct 03 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-8
+- Fixes bug preventing the installation of base modules
+- make distclean target work
+- Do not always print a module name warning
+- Use pp module name instead of filename when installing module
+- tests: Do not force using gcc
+- genhomedircon: remove hardcoded refpolicy strings
+- genhomedircon: add support for %%group syntax
+- genhomedircon: generate contexts for logins mapped to the default user
+- Validate and compile file contexts before installing
+- Swap tcp and udp protocol numbers
+
+* Mon Aug 01 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-7
+- Rebuilt with libsepol-2.5-9 and libselinux-2.5-11
+
+* Tue Jul 19 2016 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.5-6
+- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages
+
+* Thu Jun 23 2016 Petr Lautrbach <plautrba@redhat.com> - 2.5-5
+- Sort object files for deterministic linking order
+- Support overriding Makefile RANLIB
+- Respect CC and PKG_CONFIG environment variable
+
+* Fri May 06 2016 Petr Lautrbach <plautrba@redhat.com> - 2.5-4
+- Fix multiple spelling errors
+- genhomedircon: %%{USERID} and %%{USERNAME} support and code cleanup
+
+* Mon Mar 21 2016 Petr Lautrbach <plautrba@redhat.com> - 2.5-3
+- Enable expand-check by default (#1319652)
+
+* Sun Feb 28 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-2
+- Use fully versioned arch-specific requires
+
+* Tue Feb 23 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-1
+- Update to upstream release 2016-02-23
+
+* Sun Feb 21 2016 Petr Lautrbach <plautrba@redhat.com> 2.5-0.1.rc1
+- Update to upstream rc1 release 2016-01-07
+
+* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 2.4-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Wed Nov 04 2015 Robert Kuska <rkuska@redhat.com> - 2.4-5
+- Rebuilt for Python3.5 rebuild
+
+* Fri Sep 04 2015 Petr Lautrbach <plautrba@redhat.com> 2.4-4
+- Save homedir_template in the policy store for genhomedircon
+  https://bugs.gentoo.org/558686
+
+* Fri Aug 14 2015 Adam Jackson <ajax@redhat.com> 2.4-3
+- Pass ldflags into the build so hardening works
+
+* Thu Jul 30 2015 Petr Lautrbach <plautrba@redhat.com> 2.4-2
+- semanage_migrate_store: use /usr/bin/python3
+- move semanage_migrate_store script to libsemanage-python3
+
+* Wed Jun 24 2015 Petr Lautrbach <plautrba@redhat.com> 2.4-0.6
+- Allow to use compressed modules without a compression extension
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.3-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Tue Jun 16 2015 Petr Lautrbach <plautrba@redhat.com> 2.4-0.5
+- add /var/lib/selinux/tmp directory
+
+* Tue May 12 2015 Petr Lautrbach <plautrba@redhat.com> 2.4-0.4
+- semanage_migrate_store: add -r <root> option for migrating inside chroots
+
+* Mon Apr 13 2015 Petr Lautrbach <plautrba@redhat.com> 2.4-0.3
+- Update to upstream release 2.4
+
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.3-6
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Wed Jul 30 2014 Miroslav Grepl <mgrepl@fedoraproject.org> - 2.3-5
+- Skip policy module re-link when only setting booleans.
+    * patch from Stephen Smalley
+
+* Fri Jul 18 2014 Tom Callaway <spot@fedoraproject.org> - 2.3-4
+- fix license handling
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Wed May 28 2014 Kalev Lember <kalevlember@gmail.com> - 2.3-2
+- Rebuilt for https://fedoraproject.org/wiki/Changes/Python_3.4
+
+* Tue May 6 2014 Dan Walsh <dwalsh@redhat.com> - 2.3-1
+- Update to upstream 
+	* Fix memory leak in semanage_genhomedircon from Thomas Hurd.
+
+* Sun Mar 30 2014 Dan Walsh <dwalsh@redhat.com> - 2.2-3
+- libsemanage: fix memory leak in semanage_genhomedircon
+- Patch from THomas Hurd
+
+* Tue Feb 11 2014 Dan Walsh <dwalsh@redhat.com> - 2.2-2
+- Move semanage.conf man page from devel package to main package
+
+* Thu Oct 31 2013 Dan Walsh <dwalsh@redhat.com> - 2.2-1
+- Update to upstream 
+	* Avoid duplicate list entries from Dan Walsh.
+	* Add audit support to libsemanage from Dan Walsh.
+	* Remove policy.kern and replace with symlink from Dan Walsh.
+	* Apply a MAX_UID check for genhomedircon from Laurent Bigonville.
+	* Fix man pages from Laurent Bigonville.
+
+* Wed Oct 16 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-14
+- Cleanup handling of missing mls_range to fix problems with useradd -Z
+- Fix auditing of login record changes, roles were not working correctly.
+Resolves: #952237
+
+* Fri Oct 4 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-13
+- Fix errors found by coverity
+Resolves: #952237
+
+* Wed Sep 25 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-12
+- Do not fail on missing SELinux User Record when adding login record
+
+* Mon Sep 23 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-11
+- Add msg to audit records
+
+* Thu Sep 19 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-10
+- Do not write error message to screen when looking for previous record for auditing.
+- Add mls_range from user record if the MLS range is not specified by the seuser add record.
+- Error out if seuser or mls range is not specified when adding user records
+
+* Mon Sep 9 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-9
+- Create symlink from policy.kern to active kernel.
+
+* Fri Sep 6 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-8
+- Unlink policy.kern when done to save space.
+
+* Fri Jul 26 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-7
+- Move handling of role audit records into the library
+- Patch stops semanage from removing user record while in use
+
+* Tue Jul 9 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-6
+- Remove dependance on selinux-policy, /etc/selinux should be owned by libsemanage, and selinux-policy can require it.
+
+* Fri Jun 28 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-5
+- Allways build python3 version
+
+* Mon Apr 22 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-4
+- 
+
+* Thu Apr 11 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-3
+- Fix test suite to build
+
+* Thu Feb 14 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-2
+- Revert some changes which are causing the wrong policy version file to be created
+
+* Thu Feb 7 2013 Dan Walsh <dwalsh@redhat.com> - 2.1.10-1
+- Update to upstream 
+	* Add sefcontext_compile to compile regex everytime policy is rebuilt
+	* Cleanup/fix enable/disable/remove module.
+	* redo genhomedircon minuid
+	* fixes from coverity
+	* semanage_store: do not leak memory in semanage_exec_prog
+	* genhomedircon: remove useless conditional in get_home_dirs
+	* genhomedircon: double free in get_home_dirs
+	* fcontext_record: do not leak on error in semanage_fcontext_key_create
+	* genhomedircon: do not leak on failure in write_gen_home_dir_context
+	* semanage_store: do not leak fd 
+	* genhomedircon: do not leak shells list
+	* semanage_store: do not leak on strdup failure 
+	* semanage_store: rewrite for readability
+
+* Wed Jan 16 2013 Dan Walsh <dwalsh@redhat.com> 2.1.9-4
+- Add selinux-policy as a requires to get /etc/selinux owned
+
+* Sat Jan 5 2013 Dan Walsh <dwalsh@redhat.com> 2.1.9-3
+- Update to latest patches from eparis/Upstream
+-    libsemanage: fixes from coverity
+-    libsemange: redo genhomedircon minuid
+
+* Wed Nov 21 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.9-2
+- Fix handling of missing semanage permissive -d foo, not failing correctly
+- Previous to this fix the first module beginning with foo would get deleted.
+
+* Thu Sep 13 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.9-1
+- Update to upstream 
+	* libsemanage: do not set soname needlessly
+	* libsemanage: remove PYTHONLIBDIR and ruby equivalent
+	* do boolean name substitution
+	* Fix segfault for building standard policies.
+
+* Fri Aug 03 2012 David Malcolm <dmalcolm@redhat.com> - 2.1.8-6
+- rebuild for https://fedoraproject.org/wiki/Features/Python_3.3
+
+* Wed Aug  1 2012 David Malcolm <dmalcolm@redhat.com> - 2.1.8-5
+- remove rhel logic from with_python3 conditional
+
+* Thu Jul 19 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.8-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Fri Jul 13 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.8-3
+- Attempt to allocate memory for selinux_binary_policy_path and free memory 
+- allocated by asprintf.
+
+* Thu Jul 12 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.8-2
+- Fix asprintf within an asprintf call
+
+* Wed Jul 4 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.8-1
+- Update to upstream 
+	* remove build warning when build swig c files
+	* additional makefile support for rubywrap
+	* ignore 80 column limit for readability
+	* semanage_store: fix snprintf length argument by using asprintf
+	* Use default semanage.conf as a fallback
+	* use after free in python bindings
+
+* Tue May 29 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.7-2
+- Apply patch from Sven Vermeulen to fix problem with python3 bindings.
+
+* Thu Mar 29 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.7-1
+- Update to upstream 
+	* Alternate path for semanage.conf
+	* do not link against libpython, this is considered bad in Debian
+	* Allow to build for several ruby version
+	* fallback-user-level
+
+* Wed Feb 15 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.6-3
+- Check in correct patch.
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.1.6-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Fri Jan 6 2012 Dan Walsh <dwalsh@redhat.com> - 2.1.6-2
+- Add patch form Xin Ouyang to make library use private semanage.conf 
+
+* Wed Dec 21 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.6-1
+-Update to upstream
+	* add ignoredirs config for genhomedircon
+	* Fallback_user_level can be NULL if you are not using MLS
+
+* Thu Dec 15 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.5-4
+- Rebuild with latest libsepol
+
+* Thu Dec 15 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.5-3
+- Rebuild with latest libsepol
+
+* Thu Dec 15 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.5-2
+- Add support for ignoredirs param in /etc/selinux/semanage.conf
+
+* Fri Nov 4 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.5-1
+- Upgrade to upstream
+	* regenerate .pc on VERSION change
+	* maintain mode even if umask is tighter
+	* semanage.conf man page
+	* create man5dir if not exist
+
+* Wed Oct 19 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.4-2
+-    Fix handling of umask, so files get created with the correct label.
+
+* Mon Sep 19 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.4-2
+-    Add Guido Trentalancia semanage.conf man page
+
+* Mon Sep 19 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.4-1
+-Update to upstream
+	* Create a new preserve_tunables flag
+	* tree: default make target to all not
+	* fix semanage_store_access_check calling arguments
+
+* Wed Sep 14 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.3-2
+- Add support for preserving tunables
+
+* Tue Aug 30 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.3-1
+-Update to upstream
+	* python wrapper makefile changes
+
+* Thu Aug 18 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.2-1
+-Update to upstream
+2.1.2 2011-08-17
+	* print error debug info for buggy fc
+	* introduce semanage_set_root and friends
+	* throw exceptions in python rather than return
+	* python3 support.
+	* patch for MCS/MLS in user files
+
+2.1.1 2011-08-01
+	* Remove generated files, expand .gitignore
+	* Use -Werror and change a few prototypes to support it
+
+* Thu Jul 28 2011 Dan Walsh <dwalsh@redhat.com> - 2.1.0-1
+- Update to upstream
+	* Release, minor version bump
+
+* Wed Jun 8 2011 Dan Walsh <dwalsh@redhat.com> - 2.0.46-6
+- More fixes for disabled modules
+
+* Tue Jun 7 2011 Dan Walsh <dwalsh@redhat.com> - 2.0.46-5
+- Change libsemanage mechanism for handling disabled modules. Now it will only create a flag for a module 
+indicating the module is disabled.  MODULE.pp.disabled, it will no longer rename the module.  This way we can
+ship active modules in rpm.
+
+* Wed Jun 1 2011 Dan Walsh <dwalsh@redhat.com> - 2.0.46-4
+- Add semanage_set_selinux_path, to allow semodule to work on alternate selinux pools
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.46-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Thu Dec 30 2010 David Malcolm <dmalcolm@redhat.com> - 2.0.46-2
+- big reworking of the support-multiple-python-builds patch to deal with
+PEP 3149: the latest Python 3.2 onwards uses include paths and library names
+that don't fit prior naming patterns, and so we must query python3-config for
+this information.  To complicate things further, python 2's python-config
+doesn't understand all of the options needed ("--extension-suffix").  I've
+thus added new Makefile variables as needed, to be supplied by the specfile by
+invoking the appropriate config tool (or by hardcoding the old value for
+"--extension-suffix" i.e. ".so")
+- rework python3 manifest for PEP 3149, and rebuild for newer python3
+
+* Tue Dec 21 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.46-1
+- Update to upstream
+  * Fix compliation under GCC 4.6 by Justin Mattock
+
+* Wed Aug 25 2010 Thomas Spura <tomspur@fedoraproject.org> - 2.0.45-6
+- rebuild with python3.2
+  http://lists.fedoraproject.org/pipermail/devel/2010-August/141368.html
+
+* Wed Jul 21 2010 David Malcolm <dmalcolm@redhat.com> - 2.0.45-5
+- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild
+
+* Tue Apr 27 2010 David Malcolm <dmalcolm@redhat.com> - 2.0.45-4
+- add python3 subpackage
+
+* Wed Apr 7 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.45-3
+- Fix -devel package to point at the correct shared library
+
+* Fri Mar 26 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.45-2
+- Move shared library to /usr/lib
+
+* Mon Mar 8 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.45-1
+- Update to upstream
+	* Add enable/disable patch support from Dan Walsh.
+	* Add usepasswd flag to semanage.conf to disable genhomedircon using
+	  passwd from Dan Walsh.
+	* regenerate swig wrappers
+
+* Thu Feb 25 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.44-2
+- Allow disable of usepasswd
+
+* Wed Feb 17 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.44-1
+- Update to upstream
+	* Replace usage of fmemopen() with sepol_policy_file_set_mem() since
+	  glibc < 2.9 does not support binary mode ('b') for fmemopen'd
+	  streams.
+
+* Thu Jan 28 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.43-4
+- Cleanup spec file
+
+* Mon Jan 18 2010 Dan Walsh <dwalsh@redhat.com> - 2.0.43-3
+- Splect libsemanage.a into a static subpackage to keep fedora packaging guidelines happy
+
+* Wed Dec 16 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.43-2
+- Rebuild all c programs with -fPIC
+
+* Tue Dec 1 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.43-1
+- Update to upstream
+  * Move libsemanage.so to /usr/lib
+  * Add NAME lines to man pages from Manoj Srivastava<srivasta@debian.org>
+
+* Wed Nov 18 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.42-1
+- Update to upstream
+  * Move load_policy from /usr/sbin to /sbin from Dan Walsh.
+
+* Mon Nov 2 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.41-1
+- Update to upstream
+  * Add pkgconfig file from Eamon Walsh.
+  * Add semanage_set_check_contexts() function to disable calling
+  setfiles
+
+* Mon Sep 28 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.39-1
+- Update to upstream
+  * make swigify
+
+* Sun Sep 20 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.38-2
+- Dont relabel /root with genhomedircon
+
+* Thu Sep 17 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.38-1
+- Update to upstream
+  * Change semodule upgrade behavior to install even if the module
+    is not present from Dan Walsh.
+  * Make genhomedircon trim excess '/' from homedirs from Dan Walsh.
+
+* Wed Sep 9 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.37-1
+- Update to upstream
+  * Fix persistent dontaudit support to rebuild policy if the 
+        dontaudit state is changed from Chad Sellers.
+- Move load_policy to /sbin
+
+* Fri Aug 28 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.36-2
+- Add enable/disable modules
+
+* Wed Aug 26 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.36-1
+- Update to upstream
+  * Changed bzip-blocksize=0 handling to support existing compressed
+  modules in the store.
+
+* Wed Aug 26 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.35-2
+- Make sure /root is not used in genhomedircon
+
+* Wed Aug 5 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.35-1
+- Revert hard linking of files between tmp/active/previous.
+- Enable configuration of bzip behavior from Stephen Smalley.
+-   bzip-blocksize=0 to disable compression and decompression support.
+-   bzip-blocksize=1..9 to set the blocksize for compression.
+-   bzip-small=true to reduce memory usage for decompression.
+
+* Sat Jul 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.33-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Fri Jul 10 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.33-2
+- Put check for /root back into genhomedircon
+
+* Tue Jul 7 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.33-1
+- Update to upstream
+
+* Mon Jun 8 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.32-1
+- Update to upstream
+  * Ruby bindings from David Quigley.
+
+* Thu Apr 9 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.31-5
+- Return error on invalid file
+
+* Wed Mar 11 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.31-4
+- Fix typo
+
+* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 2.0.31-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Thu Jan 15 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.31-2
+- Fix link to only link on sandbox
+
+* Mon Jan 12 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.31-1
+- Update to upstream
+  * Policy module compression (bzip) support from Dan Walsh.
+  * Hard link files between tmp/active/previous from Dan Walsh.
+
+* Mon Jan 12 2009 Dan Walsh <dwalsh@redhat.com> - 2.0.30-3
+- Fix up patch to get it upstreamed
+
+* Thu Dec 04 2008 Ignacio Vazquez-Abrams <ivazqueznet+rpm@gmail.com> - 2.0.30-2
+- Rebuild for Python 2.6
+
+* Thu Dec 4 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.30-1
+- Add semanage_mls_enabled() interface from Stephen Smalley.
+
+* Sat Nov 29 2008 Ignacio Vazquez-Abrams <ivazqueznet+rpm@gmail.com> - 2.0.29-2
+- Rebuild for Python 2.6
+
+* Mon Sep 15 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.28-1
+- Update to upstream
+  * Add USER to lines to homedir_template context file from Chris PeBenito.
+
+* Mon Sep 15 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.28-2
+- Add compression support
+
+* Mon Sep 15 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.28-1
+- Update to upstream
+  * allow fcontext and seuser changes without rebuilding the policy from Dan Walsh
+
+* Wed Sep 10 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.27-3
+- Additional fixes for Don't rebuild on fcontext or seuser modifications
+
+* Tue Sep 2 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.27-2
+- Don't rebuild on fcontext or seuser modifications
+
+* Tue Aug 5 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.27-1
+- Update to upstream
+  * Modify genhomedircon to skip groupname entries.
+  Ultimately we need to expand them to the list of users to support per-role homedir labeling when using the groupname syntax.
+
+* Tue Jul 29 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.26-1
+- Update to upstream
+  * Fix bug in genhomedircon fcontext matches logic from Dan Walsh.
+  Strip any trailing slash before appending /*$.
+
+* Tue Jun 17 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.25-3
+- Another fix for genhomedircon
+
+* Wed May 28 2008 Tom "spot" Callaway <tcallawa@redhat.com> - 2.0.25-2
+- fix license tag
+
+* Tue Feb 5 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.25-1
+- Update to upstream
+  * Do not call genhomedircon if the policy was not rebuilt from Stephen Smalley.
+    Fixes semanage boolean -D seg fault (bug 441379).
+
+* Tue Feb 5 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.24-1
+- Update to upstream
+  * make swigify
+
+* Tue Feb 5 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.23-1
+- Update to upstream
+  * Use vfork rather than fork for libsemanage helpers to reduce memory overhead as suggested by Todd Miller.
+
+* Mon Feb 4 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.22-1
+- Update to upstream
+  * Free policydb before fork from Joshua Brindle.
+  * Drop the base module immediately after expanding to permit memory re-use from Stephen Smalley.
+
+* Sat Feb 2 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.20-1
+- Update to upstream
+  * Use sepol_set_expand_consume_base to reduce peak memory usage when
+  using semodule
+
+* Fri Feb 1 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.19-1
+- Update to upstream
+  * Fix genhomedircon to not override a file context with a homedir context from Todd Miller.
+
+* Tue Jan 29 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.18-1
+- Update to upstream
+  * Fix spurious out of memory error reports.
+  * Merged second version of fix for genhomedircon handling from Caleb Case.
+
+* Tue Jan 22 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.16-1
+- Update to upstream
+  * Merged fix for genhomedircon handling of missing HOME_DIR or HOME_ROOT templates from Caleb Case.
+
+* Tue Jan 22 2008 Dan Walsh <dwalsh@redhat.com> - 2.0.15-2
+- Stop differentiating on user for homedir labeling
+
+* Thu Dec 6 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.15-1
+- Update to upstream
+  * Fix genhomedircon handling of shells and missing user context template from Dan Walsh.
+  * Copy the store path in semanage_select_store from Dan Walsh.
+- Add expand-check=0 to semanage.conf
+
+* Mon Dec 3 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.14-5
+- Fix handling of /etc/shells so genhomedircon will work
+
+* Thu Nov 29 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.14-3
+- Allow semanage_genhomedircon to work with out a USER int homedir.template
+
+* Sat Nov 10 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.14-2
+- Fix semanage_select_store to allocate memory, fixes crash on invalid store
+
+* Tue Nov 6 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.14-1
+- Upgrade to latest from NSA
+  * Call rmdir() rather than remove() on directory removal so that errno isn't polluted from Stephen Smalley.
+  * Allow handle_unknown in base to be overridden by semanage.conf from Stephen Smalley.
+
+* Fri Oct 5 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.12-1
+- Upgrade to latest from NSA
+  * ustr cleanups from James Antill.
+  * Ensure that /root gets labeled even if using the default context from Dan Walsh.
+
+* Fri Sep 28 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.11-1
+- Upgrade to latest from NSA
+  * Fix ordering of file_contexts.homedirs from Todd Miller and Dan Walsh.
+
+* Fri Sep 28 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.10-2
+- Fix sort order on generated homedir context
+
+* Fri Sep 28 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.10-1
+- Upgrade to latest from NSA
+  * Fix error checking on getpw*_r functions from Todd Miller.
+  * Make genhomedircon skip invalid homedir contexts from Todd Miller.
+  * Set default user and prefix from seusers from Dan Walsh.
+  * Add swigify Makefile target from Dan Walsh.
+
+* Wed Sep 26 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.9-1
+- Upgrade to latest from NSA
+  * Pass CFLAGS to CC even on link command, per Dennis Gilmore.
+  * Clear errno on non-fatal errors to avoid reporting them upon a
+    later error that does not set errno.
+  * Improve reporting of system errors, e.g. full filesystem or read-only filesystem from Stephen Smalley.
+
+- Fix segfault in genhomedircon when using bad user names
+
+* Wed Sep 26 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.6-2
+- Fix genhomedircon code to only generate valid context
+- Fixes autorelabel problem
+
+* Thu Sep 13 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.6-1
+- Upgrade to latest from NSA
+  * Change to use getpw* function calls to the _r versions from Todd Miller.
+
+* Thu Aug 23 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.5-1
+- Upgrade to latest from NSA
+
+* Mon Aug 20 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.4-1
+- Upgrade to latest from NSA
+  * Allow dontaudits to be turned off via semanage interface when
+    updating policy
+
+* Sat Aug 11 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.3-5
+- Add ability to load a policy without dontaudit rules
+-
+
+* Tue Jun 26 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.3-4
+- Rebuild to fix segfault on x86 platforms, swigify on each build
+
+* Fri Jun 1 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.3-3
+- Rebuild for rawhide
+
+* Thu May 3 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.3-2
+- Apply patch to fix dependencies in spec file from Robert Scheck
+
+* Wed Apr 25 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.3-1
+- Upgrade to latest from NSA
+  * Fix to libsemanage man patches so whatis will work better from Dan Walsh
+
+* Wed Apr 25 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.2-1
+- Upgrade to latest from NSA
+- Merged optimizations from Stephen Smalley.
+-    do not set all booleans upon commit, only those whose values have changed
+-    only install the sandbox upon commit if something was rebuilt
+
+* Sat Mar 17 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.1-2
+- Add SELinux to Man page Names so man -k will work
+
+* Mon Mar 12 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.1-1
+- Merged dbase_file_flush patch from Dan Walsh.
+- This removes any mention of specific tools (e.g. semanage)
+- from the comment header of the auto-generated files,
+- since there are multiple front-end tools.
+
+* Tue Feb 20 2007 Dan Walsh <dwalsh@redhat.com> - 2.0.0-1
+- Upgrade to latest from NSA
+  * Merged Makefile test target patch from Caleb Case.
+  * Merged get_commit_number function rename patch from Caleb Case.
+  * Merged strnlen -> strlen patch from Todd Miller.
+
+* Wed Feb 7 2007 Dan Walsh <dwalsh@redhat.com> - 1.10.1-1
+- Upgrade to latest from NSA
+  * Merged python binding fix from Dan Walsh.
+  * Updated version for stable branch.
+
+* Fri Dec 22 2006 Dan Walsh <dwalsh@redhat.com> - 1.9.2-1
+- Upgrade to latest from NSA
+  * Merged patch to optionally reduce disk usage by removing 
+    the backup module store and linked policy from Karl MacMillan
+  * Merged patch to correctly propagate return values in libsemanage
+
+* Fri Dec 22 2006 Dan Walsh <dwalsh@redhat.com> - 1.9.1-3
+- Apply Karl MacMillan patch to get proper error codes.
+
+* Thu Dec  7 2006 Jeremy Katz <katzj@redhat.com> - 1.9.1-2
+- rebuild against python 2.5
+
+* Tue Nov 28 2006 Dan Walsh <dwalsh@redhat.com> - 1.9.1-1
+- Upgrade to latest from NSA
+  * Merged patch to compile wit -fPIC instead of -fpic from
+    Manoj Srivastava to prevent hitting the global offest table
+    limit. Patch changed to include libselinux and libsemanage in
+    addition to libsepol.
+
+* Tue Oct 17 2006 Dan Walsh <dwalsh@redhat.com> - 1.8-1
+- Upgrade to latest from NSA
+  * Updated version for release.
+
+* Thu Aug 31 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.17-1
+- Upgrade to latest from NSA
+  * Merged patch to skip reload if no active store exists and
+    the store path doesn't match the active store path from Dan Walsh.
+  * Merged patch to not destroy sepol handle on error path of
+    connect from James Athey.
+  * Merged patch to add genhomedircon path to semanage.conf from
+    James Athey. 
+
+* Thu Aug 31 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.16-3
+- Fix semanage to not load if is not the correct policy type and it is installing
+
+* Thu Aug 31 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.16-2
+- Fix requires lines
+
+* Wed Aug 23 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.16-1
+- Upgrade to latest from NSA
+  * Make most copy errors fatal, but allow exceptions for
+    file_contexts.local, seusers, and netfilter_contexts if
+    the source file does not exist in the store.
+
+* Sat Aug 12 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.15-1
+- Upgrade to latest from NSA
+  * Merged separate local file contexts patch from Chris PeBenito.
+  * Merged patch to make most copy errors non-fatal from Dan Walsh.
+
+* Thu Aug 10 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.13-3
+- Change other updates to be non-fatal
+
+* Wed Aug 9 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.13-2
+- Change netfilter stuff to be non-fatal so update can proceed.
+
+* Thu Aug 3 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.13-1
+- Upgrade to latest from NSA
+  * Merged netfilter contexts support from Chris PeBenito.
+
+* Mon Jul 17 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.12-2
+- Rebuild for new gcc
+
+* Tue Jul 11 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.12-1
+- Upgrade to latest from NSA
+  * Merged support for read operations on read-only fs from 
+    Caleb Case (Tresys Technology).
+
+* Tue Jul 4 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.11-1
+- Upgrade to latest from NSA
+  * Lindent.
+  * Merged setfiles location check patch from Dan Walsh.
+
+* Fri Jun 16 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.9-1
+- Upgrade to latest from NSA
+  * Merged several fixes from Serge Hallyn:
+       dbase_file_cache:  deref of uninit data on error path.
+       dbase_policydb_cache:  clear fp to avoid double fclose
+       semanage_fc_sort:  destroy temp on error paths
+
+* Fri Jun 16 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.8-2
+- Handle setfiles being in /sbin or /usr/sbin
+
+* Mon May 15 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.8-1
+- Upgrade to latest from NSA
+  * Updated default location for setfiles to /sbin to
+    match policycoreutils.  This can also be adjusted via 
+    semanage.conf using the syntax:
+    [setfiles]
+    path = /path/to/setfiles
+    args = -q -c $@ $<
+    [end]
+
+* Mon May 15 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.7-3
+- Spec file cleanup from n0dalus+redhat@gmail.com
+
+* Mon May 15 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.7-2
+- Add /usr/include/semanage to spec file
+
+* Mon May 8 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.7-1
+- Upgrade to latest from NSA
+  * Merged fix warnings patch from Karl MacMillan.
+
+* Fri Apr 14 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.6-1
+- Upgrade to latest from NSA
+  * Merged updated file context sorting patch from Christopher
+    Ashworth, with bug fix for escaped character flag.
+  * Merged file context sorting code from Christopher Ashworth 
+    (Tresys Technology), based on fc_sort.c code in refpolicy.
+  * Merged python binding t_output_helper removal patch from Dan Walsh.
+  * Regenerated swig files.
+
+* Wed Mar 29 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.3-1
+- Fix to work with new version of swig
+- Upgrade to latest from NSA
+  * Merged corrected fix for descriptor leak from Dan Walsh.
+
+* Wed Mar 29 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.2-2
+- Fix leaky descriptor
+
+* Tue Mar 21 2006 Dan Walsh <dwalsh@redhat.com> - 1.6.2-1
+- Upgrade to latest from NSA
+  * Merged Makefile PYLIBVER definition patch from Dan Walsh.
+  * Merged man page reorganization from Ivan Gyurdiev.
+
+* Fri Mar 17 2006 Dan Walsh <dwalsh@redhat.com> - 1.6-1
+- Make work on RHEL4
+- Upgrade to latest from NSA
+  * Merged abort early on merge errors patch from Ivan Gyurdiev.
+  * Cleaned up error handling in semanage_split_fc based on a patch
+    by Serge Hallyn (IBM) and suggestions by Ivan Gyurdiev.
+  * Merged MLS handling fixes from Ivan Gyurdiev.
+
+* Fri Feb 17 2006 Dan Walsh <dwalsh@redhat.com> - 1.5.28-1
+- Upgrade to latest from NSA
+  * Merged bug fix for fcontext validate handler from Ivan Gyurdiev.
+  * Merged base_merge_components changes from Ivan Gyurdiev.
+
+* Thu Feb 16 2006 Dan Walsh <dwalsh@redhat.com> - 1.5.26-1
+- Upgrade to latest from NSA
+  * Merged paths array patch from Ivan Gyurdiev.
+  * Merged bug fix patch from Ivan Gyurdiev.
+  * Merged improve bindings patch from Ivan Gyurdiev.
+  * Merged use PyList patch from Ivan Gyurdiev.  
+  * Merged memory leak fix patch from Ivan Gyurdiev.
+  * Merged nodecon support patch from Ivan Gyurdiev.
+  * Merged cleanups patch from Ivan Gyurdiev.
+  * Merged split swig patch from Ivan Gyurdiev.
+
+* Mon Feb 13 2006 Dan Walsh <dwalsh@redhat.com> - 1.5.23-1
+- Upgrade to latest from NSA
+  * Merged optionals in base patch from Joshua Brindle.
+  * Merged treat seusers/users_extra as optional sections patch from
+    Ivan Gyurdiev.
+  * Merged parse_optional fixes from Ivan Gyurdiev.
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 1.5.21-2.1
+- bump again for double-long bug on ppc(64)
+
+* Fri Feb 10 2006 Dan Walsh <dwalsh@redhat.com> - 1.5.21-2
+- Fix handling of seusers and users_map file
+
+* Tue Feb 07 2006 Dan Walsh <dwalsh@redhat.com> - 1.5.21-1
+- Upgrade to latest from NSA
+  * Merged seuser/user_extra support patch from Joshua Brindle.
+  * Merged remote system dbase patch from Ivan Gyurdiev.  
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 1.5.20-1.1
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Thu Feb 2 2006 Dan Walsh <dwalsh@redhat.com> 1.5.20-1
+- Upgrade to latest from NSA
+  * Merged clone record on set_con patch from Ivan Gyurdiev.  
+
+* Mon Jan 30 2006 Dan Walsh <dwalsh@redhat.com> 1.5.19-1
+- Upgrade to latest from NSA
+  * Merged fname parameter patch from Ivan Gyurdiev.
+  * Merged more size_t -> unsigned int fixes from Ivan Gyurdiev.
+  * Merged seusers.system patch from Ivan Gyurdiev.
+  * Merged improve port/fcontext API patch from Ivan Gyurdiev.  
+
+* Fri Jan 27 2006 Dan Walsh <dwalsh@redhat.com> 1.5.18-1
+- Upgrade to latest from NSA
+  * Merged seuser -> seuser_local rename patch from Ivan Gyurdiev.
+  * Merged set_create_store, access_check, and is_connected interfaces
+    from Joshua Brindle.
+
+* Fri Jan 13 2006 Dan Walsh <dwalsh@redhat.com> 1.5.16-1
+- Upgrade to latest from NSA
+  * Regenerate python wrappers.
+
+* Fri Jan 13 2006 Dan Walsh <dwalsh@redhat.com> 1.5.15-1
+- Upgrade to latest from NSA
+  * Merged pywrap Makefile diff from Dan Walsh.
+  * Merged cache management patch from Ivan Gyurdiev.
+  * Merged bugfix for dbase_llist_clear from Ivan Gyurdiev.
+  * Merged remove apply_local function patch from Ivan Gyurdiev.
+  * Merged only do read locking in direct case patch from Ivan Gyurdiev.
+  * Merged cache error path memory leak fix from Ivan Gyurdiev.
+  * Merged auto-generated file header patch from Ivan Gyurdiev.
+  * Merged pywrap test update from Ivan Gyurdiev.
+  * Merged hidden defs update from Ivan Gyurdiev.
+
+* Fri Jan 13 2006 Dan Walsh <dwalsh@redhat.com> 1.5.14-2
+- Break out python out of regular Makefile
+
+* Fri Jan 13 2006 Dan Walsh <dwalsh@redhat.com> 1.5.14-1
+- Upgrade to latest from NSA
+  * Merged disallow port overlap patch from Ivan Gyurdiev.
+  * Merged join prereq and implementation patches from Ivan Gyurdiev.
+  * Merged join user extra data part 2 patch from Ivan Gyurdiev.
+  * Merged bugfix patch from Ivan Gyurdiev.
+  * Merged remove add_local/set_local patch from Ivan Gyurdiev.
+  * Merged user extra data part 1 patch from Ivan Gyurdiev.
+  * Merged size_t -> unsigned int patch from Ivan Gyurdiev.
+  * Merged calloc check in semanage_store patch from Ivan Gyurdiev,
+    bug noticed by Steve Grubb.
+  * Merged cleanups after add/set removal patch from Ivan Gyurdiev.
+
+* Sat Jan 7 2006 Dan Walsh <dwalsh@redhat.com> 1.5.9-1
+- Upgrade to latest from NSA
+  * Merged const in APIs patch from Ivan Gyurdiev.
+  * Merged validation of local file contexts patch from Ivan Gyurdiev.
+  * Merged compare2 function patch from Ivan Gyurdiev.
+  * Merged hidden def/proto update patch from Ivan Gyurdiev.
+
+* Fri Jan 6 2006 Dan Walsh <dwalsh@redhat.com> 1.5.8-1
+- Upgrade to latest from NSA
+  * Re-applied string and file optimization patch from Russell Coker,
+    with bug fix.
+  * Reverted string and file optimization patch from Russell Coker.
+  * Clarified error messages from parse_module_headers and 
+    parse_base_headers for base/module mismatches.
+
+* Fri Jan 6 2006 Dan Walsh <dwalsh@redhat.com> 1.5.6-1
+- Upgrade to latest from NSA
+  * Clarified error messages from parse_module_headers and 
+    parse_base_headers for base/module mismatches.
+  * Merged string and file optimization patch from Russell Coker.
+  * Merged swig header reordering patch from Ivan Gyurdiev.
+  * Merged toggle modify on add patch from Ivan Gyurdiev.
+  * Merged ports parser bugfix patch from Ivan Gyurdiev.
+  * Merged fcontext swig patch from Ivan Gyurdiev.
+  * Merged remove add/modify/delete for active booleans patch from Ivan Gyurdiev.
+  * Merged man pages for dbase functions patch from Ivan Gyurdiev.
+  * Merged pywrap tests patch from Ivan Gyurdiev.
+
+* Thu Jan 5 2006 Dan Walsh <dwalsh@redhat.com> 1.5.4-2
+- Patch to fix add
+
+* Thu Jan 5 2006 Dan Walsh <dwalsh@redhat.com> 1.5.4-1
+- Upgrade to latest from NSA
+  * Merged patch series from Ivan Gyurdiev.
+    This includes patches to:
+    - separate file rw code from linked list
+    - annotate objects
+    - fold together internal headers
+    - support ordering of records in compare function
+    - add active dbase backend, active booleans
+    - return commit numbers for ro database calls
+    - use modified flags to skip rebuild whenever possible
+    - enable port interfaces
+    - update swig interfaces and typemaps
+    - add an API for file_contexts.local and file_contexts
+    - flip the traversal order in iterate/list
+    - reorganize sandbox_expand
+    - add seusers MLS validation
+    - improve dbase spec/documentation
+    - clone record on set/add/modify
+
+* Tue Dec 27 2005 Dan Walsh <dwalsh@redhat.com> 1.5.3-3
+- Add Ivans patch to turn on ports
+
+* Wed Dec 14 2005 Dan Walsh <dwalsh@redhat.com> 1.5.3-2
+- Remove patch since upstream does the right thing
+
+* Wed Dec 14 2005 Dan Walsh <dwalsh@redhat.com> 1.5.3-1
+- Upgrade to latest from NSA
+  * Merged further header cleanups from Ivan Gyurdiev.
+  * Merged toggle modified flag in policydb_modify, fix memory leak
+    in clear_obsolete, polymorphism vs headers fix, and include guards
+    for internal headers patches from Ivan Gyurdiev.
+
+* Tue Dec 13 2005 Dan Walsh <dwalsh@redhat.com> 1.5.1-2
+- Upgrade to latest from NSA
+  * Merged toggle modified flag in policydb_modify, fix memory leak
+    in clear_obsolete, polymorphism vs headers fix, and include guards
+    for internal headers patches from Ivan Gyurdiev.
+
+* Mon Dec 12 2005 Dan Walsh <dwalsh@redhat.com> 1.5.1-1
+- Upgrade to latest from NSA
+  * Added file-mode= setting to semanage.conf, default to 0644.
+    Changed semanage_copy_file and callers to use this mode when
+    installing policy files to runtime locations.
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Wed Dec 7 2005 Dan Walsh <dwalsh@redhat.com> 1.4-1
+- Fix mode of output seusers file
+
+* Tue Dec 6 2005 Dan Walsh <dwalsh@redhat.com> 1.3.64-1
+- Upgrade to latest from NSA
+  * Changed semanage_handle_create() to set do_reload based on
+    is_selinux_enabled().  This prevents improper attempts to
+    load policy on a non-SELinux system.
+
+* Mon Dec 5 2005 Dan Walsh <dwalsh@redhat.com> 1.3.63-1
+- Upgrade to latest from NSA
+  * Dropped handle from user_del_role interface.
+  * Removed defrole interfaces.
+
+* Tue Nov 29 2005 Dan Walsh <dwalsh@redhat.com> 1.3.61-1
+- Upgrade to latest from NSA
+  * Merged Makefile python definitions patch from Dan Walsh.
+  * Removed is_selinux_mls_enabled() conditionals in seusers and users
+    file parsers. 
+
+* Wed Nov 23 2005 Dan Walsh <dwalsh@redhat.com> 1.3.59-1
+- Add additional swig objects
+  * Merged wrap char*** for user_get_roles patch from Joshua Brindle.
+  * Merged remove defrole from sepol patch from Ivan Gyurdiev.
+  * Merged swig wrappers for modifying users and seusers from Joshua Brindle.
+
+* Wed Nov 23 2005 Dan Walsh <dwalsh@redhat.com> 1.3.56-2
+- Add additional swig objects
+
+* Wed Nov 16 2005 Dan Walsh <dwalsh@redhat.com> 1.3.56-1
+- Upgrade to latest from NSA
+  * Fixed free->key_free bug.
+  * Merged clear obsolete patch from Ivan Gyurdiev.
+  * Merged modified swigify patch from Dan Walsh 
+    (original patch from Joshua Brindle).
+  * Merged move genhomedircon call patch from Chad Sellers.
+
+* Mon Nov 14 2005 Dan Walsh <dwalsh@redhat.com> 1.3.53-3
+- Add genhomedircon patch from Joshua Brindle
+
+* Fri Nov 11 2005 Dan Walsh <dwalsh@redhat.com> 1.3.53-2
+- Add swigify patch from Joshua Brindle
+
+* Fri Nov 11 2005 Dan Walsh <dwalsh@redhat.com> 1.3.53-1
+- Upgrade to latest from NSA
+  * Merged move seuser validation patch from Ivan Gyurdiev.
+  * Merged hidden declaration fixes from Ivan Gyurdiev,
+    with minor corrections.
+
+* Wed Nov 9 2005 Dan Walsh <dwalsh@redhat.com> 1.3.52-1
+- Upgrade to latest from NSA
+  * Merged cleanup patch from Ivan Gyurdiev.
+    This renames semanage_module_conn to semanage_direct_handle,
+    and moves sepol handle create/destroy into semanage handle
+    create/destroy to allow use even when disconnected (for the
+    record interfaces).
+
+* Tue Nov 8 2005 Dan Walsh <dwalsh@redhat.com> 1.3.51-1
+- Upgrade to latest from NSA
+  * Clear modules modified flag upon disconnect and commit.
+        * Added tracking of module modifications and use it to
+    determine whether expand-time checks should be applied
+    on commit.
+  * Reverted semanage_set_reload_bools() interface.
+
+* Tue Nov 8 2005 Dan Walsh <dwalsh@redhat.com> 1.3.48-1
+- Upgrade to latest from NSA
+  * Disabled calls to port dbase for merge and commit and stubbed
+    out calls to sepol_port interfaces since they are not exported.
+  * Merged rename instead of copy patch from Joshua Brindle (Tresys).
+  * Added hidden_def/hidden_proto for exported symbols used within 
+    libsemanage to eliminate relocations.  Wrapped type definitions
+    in exported headers as needed to avoid conflicts.  Added
+    src/context_internal.h and src/iface_internal.h.
+  * Added semanage_is_managed() interface to allow detection of whether
+    the policy is managed via libsemanage.  This enables proper handling
+    in setsebool for non-managed systems.
+  * Merged semanage_set_reload_bools() interface from Ivan Gyurdiev,
+    to enable runtime control over preserving active boolean values
+    versus reloading their saved settings upon commit.
+
+* Mon Nov 7 2005 Dan Walsh <dwalsh@redhat.com> 1.3.43-1
+- Upgrade to latest from NSA
+  * Merged seuser parser resync, dbase tracking and cleanup, strtol
+    bug, copyright, and assert space patches from Ivan Gyurdiev.
+  * Added src/*_internal.h in preparation for other changes.
+   * Added hidden/hidden_proto/hidden_def to src/debug.[hc] and
+          src/seusers.[hc].
+
+
+* Thu Nov 3 2005 Dan Walsh <dwalsh@redhat.com> 1.3.41-1
+- Upgrade to latest from NSA
+  * Merged interface parse/print, context_to_string interface change,
+    move assert_noeof, and order preserving patches from Ivan Gyurdiev.
+        * Added src/dso.h in preparation for other changes.
+  * Merged install seusers, handle/error messages, MLS parsing,
+    and seusers validation patches from Ivan Gyurdiev.
+
+* Mon Oct 31 2005 Dan Walsh <dwalsh@redhat.com> 1.3.39-1
+- Upgrade to latest from NSA
+  * Merged record interface, dbase flush, common database code,
+    and record bugfix patches from Ivan Gyurdiev.
+
+* Fri Oct 28 2005 Dan Walsh <dwalsh@redhat.com> 1.3.38-1
+- Upgrade to latest from NSA
+  * Merged dbase policydb list and count change from Ivan Gyurdiev.
+  * Merged enable dbase and set relay patches from Ivan Gyurdiev.
+
+* Thu Oct 27 2005 Dan Walsh <dwalsh@redhat.com> 1.3.36-1
+- Update from NSA
+  * Merged query APIs and dbase_file_set patches from Ivan Gyurdiev.
+
+* Wed Oct 26 2005 Dan Walsh <dwalsh@redhat.com> 1.3.35-1
+- Update from NSA
+  * Merged sepol handle passing, seusers support, and policydb cache
+    patches from Ivan Gyurdiev.
+
+* Tue Oct 25 2005 Dan Walsh <dwalsh@redhat.com> 1.3.34-1
+- Update from NSA
+  * Merged resync to sepol changes and booleans fixes/improvements 
+    patches from Ivan Gyurdiev.
+  * Merged support for genhomedircon/homedir template, store selection,
+    explicit policy reload, and semanage.conf relocation from Joshua
+    Brindle.
+
+* Mon Oct 24 2005 Dan Walsh <dwalsh@redhat.com> 1.3.32-1
+- Update from NSA
+  * Merged resync to sepol changes and transaction fix patches from
+    Ivan Gyurdiev.
+  * Merged reorganize users patch from Ivan Gyurdiev.
+  * Merged remove unused relay functions patch from Ivan Gyurdiev.
+
+* Fri Oct 21 2005 Dan Walsh <dwalsh@redhat.com> 1.3.30-1
+- Update from NSA
+  * Fixed policy file leaks in semanage_load_module and
+    semanage_write_module.
+  * Merged further database work from Ivan Gyurdiev.
+  * Fixed bug in semanage_direct_disconnect.
+
+* Thu Oct 20 2005 Dan Walsh <dwalsh@redhat.com> 1.3.28-1
+- Update from NSA
+  * Merged interface renaming patch from Ivan Gyurdiev.
+  * Merged policy component patch from Ivan Gyurdiev.
+  * Renamed 'check=' configuration value to 'expand-check=' for 
+    clarity.
+  * Changed semanage_commit_sandbox to check for and report errors 
+    on rename(2) calls performed during rollback.
+  * Added optional check= configuration value to semanage.conf 
+    and updated call to sepol_expand_module to pass its value
+    to control assertion and hierarchy checking on module expansion.
+  * Merged fixes for make DESTDIR= builds from Joshua Brindle.
+
+* Tue Oct 18 2005 Dan Walsh <dwalsh@redhat.com> 1.3.24-1
+- Update from NSA
+  * Merged default database from Ivan Gyurdiev.
+  * Merged removal of connect requirement in policydb backend from
+    Ivan Gyurdiev.
+  * Merged commit locking fix and lock rename from Joshua Brindle.
+  * Merged transaction rollback in lock patch from Joshua Brindle.
+  * Changed default args for load_policy to be null, as it no longer
+    takes a pathname argument and we want to preserve booleans.
+  * Merged move local dbase initialization patch from Ivan Gyurdiev.
+  * Merged acquire/release read lock in databases patch from Ivan Gyurdiev.
+  * Merged rename direct -> policydb as appropriate patch from Ivan Gyurdiev.
+  * Added calls to sepol_policy_file_set_handle interface prior
+    to invoking sepol operations on policy files.
+  * Updated call to sepol_policydb_from_image to pass the handle.
+
+
+* Tue Oct 18 2005 Dan Walsh <dwalsh@redhat.com> 1.3.20-1
+- Update from NSA
+  * Changed default args for load_policy to be null, as it no longer
+    takes a pathname argument and we want to preserve booleans.
+  * Merged move local dbase initialization patch from Ivan Gyurdiev.
+  * Merged acquire/release read lock in databases patch from Ivan Gyurdiev.
+  * Merged rename direct -> policydb as appropriate patch from Ivan Gyurdiev.
+  * Added calls to sepol_policy_file_set_handle interface prior
+    to invoking sepol operations on policy files.
+  * Updated call to sepol_policydb_from_image to pass the handle.
+
+* Tue Oct 18 2005 Dan Walsh <dwalsh@redhat.com> 1.3.20-1
+- Update from NSA
+  * Merged user and port APIs - policy database patch from Ivan
+  Gyurdiev.
+  * Converted calls to sepol link_packages and expand_module interfaces
+  from using buffers to using sepol handles for error reporting, and 
+  changed direct_connect/disconnect to create/destroy sepol handles.
+
+* Sat Oct 15 2005 Dan Walsh <dwalsh@redhat.com> 1.3.18-1
+- Update from NSA
+  * Merged bugfix patch from Ivan Gyurdiev.
+  * Merged seuser database patch from Ivan Gyurdiev.
+  Merged direct user/port databases to the handle from Ivan Gyurdiev.
+  * Removed obsolete include/semanage/commit_api.h (leftover).
+  Merged seuser record patch from Ivan Gyurdiev.
+  * Merged boolean and interface databases from Ivan Gyurdiev.
+
+* Fri Oct 14 2005 Dan Walsh <dwalsh@redhat.com> 1.3.14-1
+- Update from NSA
+  * Updated to use get interfaces for hidden sepol_module_package type.
+  * Changed semanage_expand_sandbox and semanage_install_active
+  to generate/install the latest policy version supported  by libsepol
+  by default (unless overridden by semanage.conf), since libselinux
+  will now downgrade automatically for load_policy.
+  * Merged new callback-based error reporting system and ongoing
+  database work from Ivan Gyurdiev.
+
+* Wed Oct 12 2005 Dan Walsh <dwalsh@redhat.com> 1.3.11-1
+- Update from NSA
+  * Fixed semanage_install_active() to use the same logic for
+  selecting a policy version as semanage_expand_sandbox().  Dropped
+  dead code from semanage_install_sandbox().
+
+* Mon Oct 10 2005 Dan Walsh <dwalsh@redhat.com> 1.3.10-1
+- Update from NSA
+  * Updated for changes to libsepol, and to only use types and interfaces
+  provided by the shared libsepol.
+
+* Fri Oct 7 2005 Dan Walsh <dwalsh@redhat.com> 1.3.9-1
+- Update from NSA
+  * Merged further database work from Ivan Gyurdiev.
+
+* Tue Oct 4 2005 Dan Walsh <dwalsh@redhat.com> 1.3.8-1
+- Update from NSA
+  * Merged iterate, redistribute, and dbase split patches from
+  Ivan Gyurdiev.
+
+* Mon Oct 3 2005 Dan Walsh <dwalsh@redhat.com> 1.3.7-1
+- Update from NSA
+  * Merged patch series from Ivan Gyurdiev.
+    (pointer typedef elimination, file renames, dbase work, backend
+     separation)
+  * Split interfaces from semanage.[hc] into handle.[hc], modules.[hc].
+  * Separated handle create from connect interface.
+  * Added a constructor for initialization.
+  * Moved up src/include/*.h to src.
+  * Created a symbol map file; dropped dso.h and hidden markings.
+
+* Wed Sep 28 2005 Dan Walsh <dwalsh@redhat.com> 1.3.5-1
+- Update from NSA
+  * Split interfaces from semanage.[hc] into handle.[hc], modules.[hc].
+  * Separated handle create from connect interface.
+  * Added a constructor for initialization.
+  * Moved up src/include/*.h to src.
+  * Created a symbol map file; dropped dso.h and hidden markings.
+
+* Fri Sep 23 2005 Dan Walsh <dwalsh@redhat.com> 1.3.4-1
+- Update from NSA
+  * Merged dbase redesign patch from Ivan Gyurdiev.
+
+* Wed Sep 21 2005 Dan Walsh <dwalsh@redhat.com> 1.3.3-1
+- Update from NSA
+  * Merged boolean record, stub record handler, and status codes 
+    patches from Ivan Gyurdiev.
+
+* Tue Sep 20 2005 Dan Walsh <dwalsh@redhat.com> 1.3.2-1
+- Update from NSA
+  * Merged stub iterator functionality from Ivan Gyurdiev.
+  * Merged interface record patch from Ivan Gyurdiev.
+
+* Wed Sep 14 2005 Dan Walsh <dwalsh@redhat.com> 1.3.1-1
+- Update from NSA
+  * Merged stub functionality for managing user and port records,
+  and record table code from Ivan Gyurdiev.
+  * Updated version for release.
+
+* Thu Sep 1 2005 Dan Walsh <dwalsh@redhat.com> 1.1.6-1
+- Update from NSA
+  * Merged semod.conf template patch from Dan Walsh (Red Hat),
+  but restored location to /usr/share/semod/semod.conf.
+  * Fixed several bugs found by valgrind.
+  * Fixed bug in prior patch for the semod_build_module_list leak.
+  * Merged errno fix from Joshua Brindle (Tresys).
+  * Merged fix for semod_build_modules_list leak on error path
+    from Serge Hallyn (IBM).  Bug found by Coverity.
+
+* Thu Aug 25 2005 Dan Walsh <dwalsh@redhat.com> 1.1.3-1
+- Update from NSA
+  * Merged errno fix from Joshua Brindle (Tresys).
+  * Merged fix for semod_build_modules_list leak on error path
+    from Serge Hallyn (IBM).  Bug found by Coverity.
+  * Merged several fixes from Serge Hallyn (IBM).  Bugs found by
+    Coverity.
+  * Fixed several other bugs and warnings.
+  * Merged patch to move module read/write code from libsemanage
+    to libsepol from Jason Tang (Tresys).  
+  * Merged relay records patch from Ivan Gyurdiev.
+  * Merged key extract patch from Ivan Gyurdiev.
+
+- Initial version
+- Created by Stephen Smalley <sds@epoch.ncsc.mil>