Blob Blame History Raw
diff --git libsemanage-2.5/ChangeLog libsemanage-2.5/ChangeLog
index 9b4d5b7..10fc784 100644
--- libsemanage-2.5/ChangeLog
+++ libsemanage-2.5/ChangeLog
@@ -1,3 +1,13 @@
+	* genhomedircon: add support for %group syntax, from Gary Tierney.
+	* genhomedircon: generate contexts for logins mapped to the default user, from Gary Tierney.
+	* Validate and compile file contexts before installing, from Stephen Smalley.
+	* Swap tcp and udp protocol numbers, from Miroslav Vadkerti.
+	* Sort object files for deterministic linking order, from Laurent Bigonville.
+	* Support overriding Makefile RANLIB, from Julien Pivotto.
+	* Respect CC and PKG_CONFIG environment variable, from Julien Pivotto.
+	* Fix multiple spelling errors, from Laurent Bigonville.
+	* genhomedircon: %{USERID} and %{USERNAME} support and code cleanups, from Jason Zaman.
+
 2.5 2016-02-23
 	* Do not overwrite CFLAGS in test Makefile, from Nicolas Iooss.
 	* Fix uninitialized variable in direct_commit and direct_api, from Nicolas Iooss.
diff --git libsemanage-2.5/include/semanage/fcontexts_policy.h libsemanage-2.5/include/semanage/fcontexts_policy.h
index a50db2b..199a1e1 100644
--- libsemanage-2.5/include/semanage/fcontexts_policy.h
+++ libsemanage-2.5/include/semanage/fcontexts_policy.h
@@ -26,4 +26,8 @@ extern int semanage_fcontext_list(semanage_handle_t * handle,
 				  semanage_fcontext_t *** records,
 				  unsigned int *count);
 
+extern int semanage_fcontext_list_homedirs(semanage_handle_t * handle,
+				  semanage_fcontext_t *** records,
+				  unsigned int *count);
+
 #endif
diff --git libsemanage-2.5/include/semanage/handle.h libsemanage-2.5/include/semanage/handle.h
index 6cad529..c816590 100644
--- libsemanage-2.5/include/semanage/handle.h
+++ libsemanage-2.5/include/semanage/handle.h
@@ -130,7 +130,7 @@ int semanage_commit(semanage_handle_t *);
 #define SEMANAGE_CAN_READ 1
 #define SEMANAGE_CAN_WRITE 2
 /* returns SEMANAGE_CAN_READ or SEMANAGE_CAN_WRITE if the store is readable
- * or writable, respectively. <0 if an error occured */
+ * or writable, respectively. <0 if an error occurred */
 int semanage_access_check(semanage_handle_t * sh);
 
 /* returns 0 if not connected, 1 if connected */
diff --git libsemanage-2.5/include/semanage/ibendport_record.h libsemanage-2.5/include/semanage/ibendport_record.h
new file mode 100644
index 0000000..153eea0
--- /dev/null
+++ libsemanage-2.5/include/semanage/ibendport_record.h
@@ -0,0 +1,62 @@
+/*Copyright (C) 2005 Red Hat, Inc. */
+
+#ifndef _SEMANAGE_IBENDPORT_RECORD_H_
+#define _SEMANAGE_IBENDPORT_RECORD_H_
+
+#include <semanage/context_record.h>
+#include <semanage/handle.h>
+#include <stddef.h>
+
+#ifndef _SEMANAGE_IBENDPORT_DEFINED_
+struct semanage_ibendport;
+struct semanage_ibendport_key;
+typedef struct semanage_ibendport semanage_ibendport_t;
+typedef struct semanage_ibendport_key semanage_ibendport_key_t;
+#define _SEMANAGE_IBENDPORT_DEFINED_
+#endif
+
+extern int semanage_ibendport_compare(const semanage_ibendport_t *ibendport,
+				      const semanage_ibendport_key_t *key);
+
+extern int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport,
+				       const semanage_ibendport_t *ibendport2);
+
+extern int semanage_ibendport_key_create(semanage_handle_t *handle,
+					 const char *ibdev_name,
+					 int port,
+					 semanage_ibendport_key_t **key_ptr);
+
+extern int semanage_ibendport_key_extract(semanage_handle_t *handle,
+					  const semanage_ibendport_t *ibendport,
+					  semanage_ibendport_key_t **key_ptr);
+
+extern void semanage_ibendport_key_free(semanage_ibendport_key_t *key);
+
+extern int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle,
+					     const semanage_ibendport_t *ibendport,
+					     char **ibdev_name_ptr);
+
+extern int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle,
+					     semanage_ibendport_t *ibendport,
+					     const char *ibdev_name);
+
+extern int semanage_ibendport_get_port(const semanage_ibendport_t *ibendport);
+
+extern void semanage_ibendport_set_port(semanage_ibendport_t *ibendport, int port);
+
+extern semanage_context_t *semanage_ibendport_get_con(const semanage_ibendport_t *ibendport);
+
+extern int semanage_ibendport_set_con(semanage_handle_t *handle,
+				      semanage_ibendport_t *ibendport,
+				      semanage_context_t *con);
+
+extern int semanage_ibendport_create(semanage_handle_t *handle,
+				     semanage_ibendport_t **ibendport_ptr);
+
+extern int semanage_ibendport_clone(semanage_handle_t *handle,
+				    const semanage_ibendport_t *ibendport,
+				    semanage_ibendport_t **ibendport_ptr);
+
+extern void semanage_ibendport_free(semanage_ibendport_t *ibendport);
+
+#endif
diff --git libsemanage-2.5/include/semanage/ibendports_local.h libsemanage-2.5/include/semanage/ibendports_local.h
new file mode 100644
index 0000000..641dd35
--- /dev/null
+++ libsemanage-2.5/include/semanage/ibendports_local.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc */
+
+#ifndef _SEMANAGE_IBENDPORTS_LOCAL_H_
+#define _SEMANAGE_IBENDPORTS_LOCAL_H_
+
+#include <semanage/ibendport_record.h>
+#include <semanage/handle.h>
+
+extern int semanage_ibendport_modify_local(semanage_handle_t *handle,
+					   const semanage_ibendport_key_t *key,
+					   const semanage_ibendport_t *data);
+
+extern int semanage_ibendport_del_local(semanage_handle_t *handle,
+					const semanage_ibendport_key_t *key);
+
+extern int semanage_ibendport_query_local(semanage_handle_t *handle,
+					  const semanage_ibendport_key_t *key,
+					  semanage_ibendport_t **response);
+
+extern int semanage_ibendport_exists_local(semanage_handle_t *handle,
+					   const semanage_ibendport_key_t *key,
+					   int *response);
+
+extern int semanage_ibendport_count_local(semanage_handle_t *handle,
+					  unsigned int *response);
+
+extern int semanage_ibendport_iterate_local(semanage_handle_t *handle,
+					    int (*handler)(const semanage_ibendport_t *record,
+							   void *varg),
+					    void *handler_arg);
+
+extern int semanage_ibendport_list_local(semanage_handle_t *handle,
+					 semanage_ibendport_t ***records,
+					 unsigned int *count);
+
+#endif
diff --git libsemanage-2.5/include/semanage/ibendports_policy.h libsemanage-2.5/include/semanage/ibendports_policy.h
new file mode 100644
index 0000000..3fc1976
--- /dev/null
+++ libsemanage-2.5/include/semanage/ibendports_policy.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2017 Mellanox Techonologies Inc */
+
+#ifndef _SEMANAGE_IBENDPORTS_POLICY_H_
+#define _SEMANAGE_IBENDPORTS_POLICY_H_
+
+#include <semanage/handle.h>
+#include <semanage/ibendport_record.h>
+
+extern int semanage_ibendport_query(semanage_handle_t *handle,
+				    const semanage_ibendport_key_t *key,
+				    semanage_ibendport_t **response);
+
+extern int semanage_ibendport_exists(semanage_handle_t *handle,
+				     const semanage_ibendport_key_t *key, int *response);
+
+extern int semanage_ibendport_count(semanage_handle_t *handle,
+				    unsigned int *response);
+
+extern int semanage_ibendport_iterate(semanage_handle_t *handle,
+				      int (*handler)(const semanage_ibendport_t *record,
+						     void *varg),
+				      void *handler_arg);
+
+extern int semanage_ibendport_list(semanage_handle_t *handle,
+				   semanage_ibendport_t ***records,
+				   unsigned int *count);
+
+#endif
diff --git libsemanage-2.5/include/semanage/ibpkey_record.h libsemanage-2.5/include/semanage/ibpkey_record.h
new file mode 100644
index 0000000..9da7dc5
--- /dev/null
+++ libsemanage-2.5/include/semanage/ibpkey_record.h
@@ -0,0 +1,72 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc */
+
+#ifndef _SEMANAGE_IBPKEY_RECORD_H_
+#define _SEMANAGE_IBPKEY_RECORD_H_
+
+#include <semanage/context_record.h>
+#include <semanage/handle.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef _SEMANAGE_IBPKEY_DEFINED_
+struct semanage_ibpkey;
+struct semanage_ibpkey_key;
+typedef struct semanage_ibpkey semanage_ibpkey_t;
+typedef struct semanage_ibpkey_key semanage_ibpkey_key_t;
+#define _SEMANAGE_IBPKEY_DEFINED_
+#endif
+
+extern int semanage_ibpkey_compare(const semanage_ibpkey_t *ibpkey,
+				   const semanage_ibpkey_key_t *key);
+
+extern int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey,
+				    const semanage_ibpkey_t *ibpkey2);
+
+extern int semanage_ibpkey_key_create(semanage_handle_t *handle,
+				      const char *subnet_prefix,
+				      int low, int high,
+				      semanage_ibpkey_key_t **key_ptr);
+
+extern int semanage_ibpkey_key_extract(semanage_handle_t *handle,
+				       const semanage_ibpkey_t *ibpkey,
+				       semanage_ibpkey_key_t **key_ptr);
+
+extern void semanage_ibpkey_key_free(semanage_ibpkey_key_t *key);
+
+extern int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle,
+					     const semanage_ibpkey_t *ibpkey,
+					     char **subnet_prefix_ptr);
+
+extern uint64_t semanage_ibpkey_get_subnet_prefix_bytes(const semanage_ibpkey_t *ibpkey);
+
+extern int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle,
+					     semanage_ibpkey_t *ibpkey,
+					     const char *subnet_prefix);
+
+extern void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey,
+						    uint64_t subnet_prefix);
+
+extern int semanage_ibpkey_get_low(const semanage_ibpkey_t *ibpkey);
+
+extern int semanage_ibpkey_get_high(const semanage_ibpkey_t *ibpkey);
+
+extern void semanage_ibpkey_set_pkey(semanage_ibpkey_t *ibpkey, int pkey_num);
+
+extern void semanage_ibpkey_set_range(semanage_ibpkey_t *ibpkey, int low, int high);
+
+extern semanage_context_t *semanage_ibpkey_get_con(const semanage_ibpkey_t *ibpkey);
+
+extern int semanage_ibpkey_set_con(semanage_handle_t *handle,
+				   semanage_ibpkey_t *ibpkey,
+				   semanage_context_t *con);
+
+extern int semanage_ibpkey_create(semanage_handle_t *handle,
+				  semanage_ibpkey_t **ibpkey_ptr);
+
+extern int semanage_ibpkey_clone(semanage_handle_t *handle,
+				 const semanage_ibpkey_t *ibpkey,
+				 semanage_ibpkey_t **ibpkey_ptr);
+
+extern void semanage_ibpkey_free(semanage_ibpkey_t *ibpkey);
+
+#endif
diff --git libsemanage-2.5/include/semanage/ibpkeys_local.h libsemanage-2.5/include/semanage/ibpkeys_local.h
new file mode 100644
index 0000000..079a642
--- /dev/null
+++ libsemanage-2.5/include/semanage/ibpkeys_local.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc */
+
+#ifndef _SEMANAGE_IBPKEYS_LOCAL_H_
+#define _SEMANAGE_IBPKEYS_LOCAL_H_
+
+#include <semanage/ibpkey_record.h>
+#include <semanage/handle.h>
+
+extern int semanage_ibpkey_modify_local(semanage_handle_t *handle,
+					const semanage_ibpkey_key_t *key,
+					const semanage_ibpkey_t *data);
+
+extern int semanage_ibpkey_del_local(semanage_handle_t *handle,
+				     const semanage_ibpkey_key_t *key);
+
+extern int semanage_ibpkey_query_local(semanage_handle_t *handle,
+				       const semanage_ibpkey_key_t *key,
+				       semanage_ibpkey_t **response);
+
+extern int semanage_ibpkey_exists_local(semanage_handle_t *handle,
+					const semanage_ibpkey_key_t *key,
+					int *response);
+
+extern int semanage_ibpkey_count_local(semanage_handle_t *handle,
+				       unsigned int *response);
+
+extern int semanage_ibpkey_iterate_local(semanage_handle_t *handle,
+					 int (*handler)(const semanage_ibpkey_t *
+							record, void *varg),
+					 void *handler_arg);
+
+extern int semanage_ibpkey_list_local(semanage_handle_t *handle,
+				      semanage_ibpkey_t ***records,
+				      unsigned int *count);
+
+#endif
diff --git libsemanage-2.5/include/semanage/ibpkeys_policy.h libsemanage-2.5/include/semanage/ibpkeys_policy.h
new file mode 100644
index 0000000..c287ac0
--- /dev/null
+++ libsemanage-2.5/include/semanage/ibpkeys_policy.h
@@ -0,0 +1,28 @@
+/* Copyright (C) 2017 Mellanox Technolgies Inc. */
+
+#ifndef _SEMANAGE_IBPKEYS_POLICY_H_
+#define _SEMANAGE_IBPKEYS_POLICY_H_
+
+#include <semanage/handle.h>
+#include <semanage/ibpkey_record.h>
+
+extern int semanage_ibpkey_query(semanage_handle_t *handle,
+				 const semanage_ibpkey_key_t *key,
+				 semanage_ibpkey_t **response);
+
+extern int semanage_ibpkey_exists(semanage_handle_t *handle,
+				  const semanage_ibpkey_key_t *key, int *response);
+
+extern int semanage_ibpkey_count(semanage_handle_t *handle,
+				 unsigned int *response);
+
+extern int semanage_ibpkey_iterate(semanage_handle_t *handle,
+				   int (*handler)(const semanage_ibpkey_t *record,
+						  void *varg),
+				   void *handler_arg);
+
+extern int semanage_ibpkey_list(semanage_handle_t *handle,
+				semanage_ibpkey_t ***records,
+				unsigned int *count);
+
+#endif
diff --git libsemanage-2.5/include/semanage/modules.h libsemanage-2.5/include/semanage/modules.h
index 4b93e54..50940e2 100644
--- libsemanage-2.5/include/semanage/modules.h
+++ libsemanage-2.5/include/semanage/modules.h
@@ -39,7 +39,7 @@ int semanage_module_install_file(semanage_handle_t *,
 int semanage_module_remove(semanage_handle_t *, char *module_name);
 
 /* semanage_module_info is for getting information on installed
-   modules, only name at this time */
+   modules, only name and version at this time */
 typedef struct semanage_module_info semanage_module_info_t;
 
 /* Look up a module using @modkey. The module's raw data is returned as a
@@ -64,6 +64,7 @@ void semanage_module_info_datum_destroy(semanage_module_info_t *);
 semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list,
 						 int n);
 const char *semanage_module_get_name(semanage_module_info_t *);
+const char *semanage_module_get_version(semanage_module_info_t *);
 
 /* Module Info */
 
@@ -104,6 +105,14 @@ int semanage_module_info_get_name(semanage_handle_t *sh,
 				  semanage_module_info_t *modinfo,
 				  const char **name);
 
+/* Get @module_version from @modinfo. Caller should not free @module_version.
+ *
+ * Returns 0 on success and -1 on error.
+ */
+int semanage_module_info_get_version(semanage_handle_t *sh,
+				      semanage_module_info_t *modinfo,
+				      const char **version);
+
 /* Get @lang_ext from @modinfo. Caller should not free @lang_ext.
  *
  * Returns 0 on success and -1 on error.
@@ -138,6 +147,14 @@ int semanage_module_info_set_name(semanage_handle_t *sh,
 				  semanage_module_info_t *modinfo,
 				  const char *name);
 
+/* Set @version in @modinfo.
+ *
+ * Returns 0 on success and -1 on error.
+ */
+int semanage_module_info_set_version(semanage_handle_t *sh,
+				      semanage_module_info_t *modinfo,
+				      const char *version);
+
 /* Set @lang_ext in @modinfo.
  *
  * Returns 0 on success and -1 on error.
diff --git libsemanage-2.5/include/semanage/semanage.h libsemanage-2.5/include/semanage/semanage.h
index f417ce4..0489014 100644
--- libsemanage-2.5/include/semanage/semanage.h
+++ libsemanage-2.5/include/semanage/semanage.h
@@ -33,6 +33,8 @@
 #include <semanage/context_record.h>
 #include <semanage/iface_record.h>
 #include <semanage/port_record.h>
+#include <semanage/ibpkey_record.h>
+#include <semanage/ibendport_record.h>
 #include <semanage/node_record.h>
 
 /* Dbase */
@@ -47,6 +49,10 @@
 #include <semanage/seusers_policy.h>
 #include <semanage/ports_local.h>
 #include <semanage/ports_policy.h>
+#include <semanage/ibpkeys_local.h>
+#include <semanage/ibendports_local.h>
+#include <semanage/ibendports_policy.h>
+#include <semanage/ibpkeys_policy.h>
 #include <semanage/interfaces_local.h>
 #include <semanage/interfaces_policy.h>
 #include <semanage/nodes_local.h>
diff --git libsemanage-2.5/man/man5/semanage.conf.5 libsemanage-2.5/man/man5/semanage.conf.5
index 8f8de55..1009d97 100644
--- libsemanage-2.5/man/man5/semanage.conf.5
+++ libsemanage-2.5/man/man5/semanage.conf.5
@@ -33,7 +33,7 @@ Specify an alternative root path to use for the store. The default is "/"
 
 .TP
 .B store-root
-Specify an alternative store_root path to use. The default is "/var/lib/selinux"
+Specify an alternative store_root path to use. The default is "/etc/selinux"
 
 .TP
 .B compiler-directory
diff --git libsemanage-2.5/src/Makefile libsemanage-2.5/src/Makefile
index d1fcc0b..96ee652 100644
--- libsemanage-2.5/src/Makefile
+++ libsemanage-2.5/src/Makefile
@@ -5,6 +5,7 @@ PYTHON ?= python
 PYPREFIX ?= $(notdir $(PYTHON))
 RUBY ?= ruby
 RUBYPREFIX ?= $(notdir $(RUBY))
+PKG_CONFIG ?= pkg-config
 
 # Installation directories.
 PREFIX ?= $(DESTDIR)/usr
@@ -12,11 +13,11 @@ LIBDIR ?= $(PREFIX)/lib
 SHLIBDIR ?= $(DESTDIR)/lib
 INCLUDEDIR ?= $(PREFIX)/include
 PYLIBVER ?= $(shell $(PYTHON) -c 'import sys;print("python%d.%d" % sys.version_info[0:2])')
-PYINC ?= $(shell pkg-config --cflags $(PYPREFIX))
+PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX))
 PYLIBDIR ?= $(LIBDIR)/$(PYLIBVER)
 RUBYLIBVER ?= $(shell $(RUBY) -e 'print RUBY_VERSION.split(".")[0..1].join(".")')
 RUBYPLATFORM ?= $(shell $(RUBY) -e 'print RUBY_PLATFORM')
-RUBYINC ?= $(shell pkg-config --cflags ruby-$(RUBYLIBVER))
+RUBYINC ?= $(shell $(PKG_CONFIG) --cflags ruby-$(RUBYLIBVER))
 RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM)
 
 LIBBASE=$(shell basename $(LIBDIR))
@@ -51,7 +52,7 @@ SWIGRUBYSO=$(RUBYPREFIX)_semanage.so
 LIBSO=$(TARGET).$(LIBVERSION)
 
 GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i
-SRCS= $(filter-out $(GENERATED),$(wildcard *.c))
+SRCS= $(filter-out $(GENERATED),$(sort $(wildcard *.c)))
 
 OBJS= $(patsubst %.c,%.o,$(SRCS)) conf-scan.o conf-parse.o
 LOBJS= $(patsubst %.c,%.lo,$(SRCS)) conf-scan.lo conf-parse.lo
@@ -61,7 +62,7 @@ SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno
 		-Wno-unused-parameter
 
 override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE 
-RANLIB=ranlib
+RANLIB ?= ranlib
 
 SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./
 
diff --git libsemanage-2.5/src/conf-parse.y libsemanage-2.5/src/conf-parse.y
index b527e89..e2b6028 100644
--- libsemanage-2.5/src/conf-parse.y
+++ libsemanage-2.5/src/conf-parse.y
@@ -340,7 +340,7 @@ static int semanage_conf_init(semanage_conf_t * conf)
 	conf->store_type = SEMANAGE_CON_DIRECT;
 	conf->store_path = strdup(basename(selinux_policy_root()));
 	conf->ignoredirs = NULL;
-	conf->store_root_path = strdup("/var/lib/selinux");
+	conf->store_root_path = strdup("/etc/selinux");
 	conf->compiler_directory_path = strdup("/usr/libexec/selinux/hll");
 	conf->policyvers = sepol_policy_kern_vers_max();
 	conf->target_platform = SEPOL_TARGET_SELINUX;
diff --git libsemanage-2.5/src/database.h libsemanage-2.5/src/database.h
index e460379..6a4a164 100644
--- libsemanage-2.5/src/database.h
+++ libsemanage-2.5/src/database.h
@@ -148,7 +148,7 @@ typedef struct dbase_table {
 	 * This function must be invoked before using
 	 * any of the database functions above. It may be invoked
 	 * multiple times, and will update the cache if a commit
-	 * occured between invocations */
+	 * occurred between invocations */
 	int (*cache) (struct semanage_handle * handle, dbase_t * dbase);
 
 	/* Forgets all changes that haven't been written
diff --git libsemanage-2.5/src/database_file.c libsemanage-2.5/src/database_file.c
index a21b3ee..a51269e 100644
--- libsemanage-2.5/src/database_file.c
+++ libsemanage-2.5/src/database_file.c
@@ -119,13 +119,16 @@ static int dbase_file_flush(semanage_handle_t * handle, dbase_file_t * dbase)
 	cache_entry_t *ptr;
 	const char *fname = NULL;
 	FILE *str = NULL;
+	mode_t mask;
 
 	if (!dbase_llist_is_modified(&dbase->llist))
 		return STATUS_SUCCESS;
 
 	fname = dbase->path[handle->is_in_transaction];
 
+	mask = umask(0077);
 	str = fopen(fname, "w");
+	umask(mask);
 	if (!str) {
 		ERR(handle, "could not open %s for writing: %s",
 		    fname, strerror(errno));
diff --git libsemanage-2.5/src/direct_api.c libsemanage-2.5/src/direct_api.c
index 2187b65..fea6572 100644
--- libsemanage-2.5/src/direct_api.c
+++ libsemanage-2.5/src/direct_api.c
@@ -40,6 +40,8 @@
 #include "user_internal.h"
 #include "seuser_internal.h"
 #include "port_internal.h"
+#include "ibpkey_internal.h"
+#include "ibendport_internal.h"
 #include "iface_internal.h"
 #include "boolean_internal.h"
 #include "fcontext_internal.h"
@@ -146,9 +148,6 @@ int semanage_direct_connect(semanage_handle_t * sh)
 		if (semanage_create_store(sh, 1))
 			goto err;
 
-	if (semanage_access_check(sh) < SEMANAGE_CAN_READ)
-		goto err;
-
 	sh->u.direct.translock_file_fd = -1;
 	sh->u.direct.activelock_file_fd = -1;
 
@@ -208,6 +207,12 @@ int semanage_direct_connect(semanage_handle_t * sh)
 				     semanage_fcontext_dbase_local(sh)) < 0)
 		goto err;
 
+	if (fcontext_file_dbase_init(sh,
+				     semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_HOMEDIRS),
+				     semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
+				     semanage_fcontext_dbase_homedirs(sh)) < 0)
+		goto err;
+
 	if (seuser_file_dbase_init(sh,
 				   semanage_path(SEMANAGE_ACTIVE,
 						 SEMANAGE_SEUSERS_LOCAL),
@@ -224,6 +229,22 @@ int semanage_direct_connect(semanage_handle_t * sh)
 				 semanage_node_dbase_local(sh)) < 0)
 		goto err;
 
+	if (ibpkey_file_dbase_init(sh,
+				   semanage_path(SEMANAGE_ACTIVE,
+					         SEMANAGE_IBPKEYS_LOCAL),
+				   semanage_path(SEMANAGE_TMP,
+					         SEMANAGE_IBPKEYS_LOCAL),
+				   semanage_ibpkey_dbase_local(sh)) < 0)
+		goto err;
+
+	if (ibendport_file_dbase_init(sh,
+				      semanage_path(SEMANAGE_ACTIVE,
+						    SEMANAGE_IBENDPORTS_LOCAL),
+				      semanage_path(SEMANAGE_TMP,
+						    SEMANAGE_IBENDPORTS_LOCAL),
+				      semanage_ibendport_dbase_local(sh)) < 0)
+		goto err;
+
 	/* Object databases: local modifications + policy */
 	if (user_base_policydb_dbase_init(sh,
 					  semanage_user_base_dbase_policy(sh)) <
@@ -248,6 +269,12 @@ int semanage_direct_connect(semanage_handle_t * sh)
 	if (port_policydb_dbase_init(sh, semanage_port_dbase_policy(sh)) < 0)
 		goto err;
 
+	if (ibpkey_policydb_dbase_init(sh, semanage_ibpkey_dbase_policy(sh)) < 0)
+		goto err;
+
+	if (ibendport_policydb_dbase_init(sh, semanage_ibendport_dbase_policy(sh)) < 0)
+		goto err;
+
 	if (iface_policydb_dbase_init(sh, semanage_iface_dbase_policy(sh)) < 0)
 		goto err;
 
@@ -275,7 +302,9 @@ int semanage_direct_connect(semanage_handle_t * sh)
 
 	/* set the disable dontaudit value */
 	path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_DISABLE_DONTAUDIT);
-	if (access(path, F_OK) == 0)
+
+	struct stat sb;
+	if (stat(path, &sb) == 0)
 		sepol_set_disable_dontaudit(sh->sepolh, 1);
 	else
 		sepol_set_disable_dontaudit(sh->sepolh, 0);
@@ -320,9 +349,12 @@ static int semanage_direct_disconnect(semanage_handle_t * sh)
 	user_extra_file_dbase_release(semanage_user_extra_dbase_local(sh));
 	user_join_dbase_release(semanage_user_dbase_local(sh));
 	port_file_dbase_release(semanage_port_dbase_local(sh));
+	ibpkey_file_dbase_release(semanage_ibpkey_dbase_local(sh));
+	ibendport_file_dbase_release(semanage_ibendport_dbase_local(sh));
 	iface_file_dbase_release(semanage_iface_dbase_local(sh));
 	bool_file_dbase_release(semanage_bool_dbase_local(sh));
 	fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh));
+	fcontext_file_dbase_release(semanage_fcontext_dbase_homedirs(sh));
 	seuser_file_dbase_release(semanage_seuser_dbase_local(sh));
 	node_file_dbase_release(semanage_node_dbase_local(sh));
 
@@ -331,6 +363,8 @@ static int semanage_direct_disconnect(semanage_handle_t * sh)
 	user_extra_file_dbase_release(semanage_user_extra_dbase_policy(sh));
 	user_join_dbase_release(semanage_user_dbase_policy(sh));
 	port_policydb_dbase_release(semanage_port_dbase_policy(sh));
+	ibpkey_policydb_dbase_release(semanage_ibpkey_dbase_policy(sh));
+	ibendport_policydb_dbase_release(semanage_ibendport_dbase_policy(sh));
 	iface_policydb_dbase_release(semanage_iface_dbase_policy(sh));
 	bool_policydb_dbase_release(semanage_bool_dbase_policy(sh));
 	fcontext_file_dbase_release(semanage_fcontext_dbase_policy(sh));
@@ -345,10 +379,6 @@ static int semanage_direct_disconnect(semanage_handle_t * sh)
 
 static int semanage_direct_begintrans(semanage_handle_t * sh)
 {
-
-	if (semanage_access_check(sh) != SEMANAGE_CAN_WRITE) {
-		return -1;
-	}
 	if (semanage_get_trans_lock(sh) < 0) {
 		return -1;
 	}
@@ -363,6 +393,35 @@ static int semanage_direct_begintrans(semanage_handle_t * sh)
 
 /********************* utility functions *********************/
 
+/* Takes a module stored in 'module_data' and parses its headers.
+ * Sets reference variables 'module_name' to module's name, and
+ * 'version' to module's version.  The caller is responsible for
+ * free()ing 'module_name', and 'version'; they will be
+ * set to NULL upon entering this function.  Returns 0 on success, -1
+ * if out of memory.
+ */
+static int parse_module_headers(semanage_handle_t * sh, char *module_data,
+                               size_t data_len, char **module_name,
+                               char **version)
+{
+       struct sepol_policy_file *pf;
+       int file_type;
+       *module_name = *version = NULL;
+
+       if (sepol_policy_file_create(&pf)) {
+               ERR(sh, "Out of memory!");
+               return -1;
+       }
+       sepol_policy_file_set_mem(pf, module_data, data_len);
+       sepol_policy_file_set_handle(pf, sh->sepolh);
+       if (module_data != NULL && data_len > 0)
+           sepol_module_package_info(pf, &file_type, module_name,
+                                     version);
+       sepol_policy_file_free(pf);
+
+       return 0;
+}
+
 #include <stdlib.h>
 #include <bzlib.h>
 #include <string.h>
@@ -588,13 +647,33 @@ static int semanage_direct_update_user_extra(semanage_handle_t * sh, cil_db_t *c
 	}
 
 	if (size > 0) {
+		/*
+		 * Write the users_extra entries from CIL modules.
+		 * This file is used as our baseline when we do not require
+		 * re-linking.
+		 */
+		ofilename = semanage_path(SEMANAGE_TMP,
+					  SEMANAGE_USERS_EXTRA_LINKED);
+		if (ofilename == NULL) {
+			retval = -1;
+			goto cleanup;
+		}
+		retval = write_file(sh, ofilename, data, size);
+		if (retval < 0)
+			goto cleanup;
+
+		/*
+		 * Write the users_extra file; users_extra.local
+		 * will be merged into this file.
+		 */
 		ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA);
 		if (ofilename == NULL) {
-			return retval;
+			retval = -1;
+			goto cleanup;
 		}
 		retval = write_file(sh, ofilename, data, size);
 		if (retval < 0)
-			return retval;
+			goto cleanup;
 
 		pusers_extra->dtable->drop_cache(pusers_extra->dbase);
 		
@@ -623,11 +702,33 @@ static int semanage_direct_update_seuser(semanage_handle_t * sh, cil_db_t *cildb
 	}
 
 	if (size > 0) {
+		/*
+		 * Write the seusers entries from CIL modules.
+		 * This file is used as our baseline when we do not require
+		 * re-linking.
+		 */
+		ofilename = semanage_path(SEMANAGE_TMP,
+					  SEMANAGE_SEUSERS_LINKED);
+		if (ofilename == NULL) {
+			retval = -1;
+			goto cleanup;
+		}
+		retval = write_file(sh, ofilename, data, size);
+		if (retval < 0)
+			goto cleanup;
+
+		/*
+		 * Write the seusers file; seusers.local will be merged into
+		 * this file.
+		 */
 		ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
 		if (ofilename == NULL) {
-			return -1;
+			retval = -1;
+			goto cleanup;
 		}
 		retval = write_file(sh, ofilename, data, size);
+		if (retval < 0)
+			goto cleanup;
 
 		pseusers->dtable->drop_cache(pseusers->dbase);
 	} else {
@@ -1037,8 +1138,9 @@ static int semanage_compile_hll_modules(semanage_handle_t *sh,
 			goto cleanup;
 		}
 
+		struct stat sb;
 		if (semanage_get_ignore_module_cache(sh) == 0 &&
-				access(cil_path, F_OK) == 0) {
+				stat(cil_path, &sb) == 0) {
 			continue;
 		}
 
@@ -1066,23 +1168,26 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 	size_t fc_buffer_len = 0;
 	const char *ofilename = NULL;
 	const char *path;
-	int retval = -1, num_modinfos = 0, i, missing_policy_kern = 0,
-		missing_seusers = 0, missing_fc = 0, missing = 0;
+	int retval = -1, num_modinfos = 0, i;
 	sepol_policydb_t *out = NULL;
 	struct cil_db *cildb = NULL;
 	semanage_module_info_t *modinfos = NULL;
+	mode_t mask = umask(0077);
 
-	/* Declare some variables */
-	int modified = 0, fcontexts_modified, ports_modified,
-	    seusers_modified, users_extra_modified, dontaudit_modified,
-	    preserve_tunables_modified, bools_modified = 0,
-		disable_dontaudit, preserve_tunables;
+	int do_rebuild, do_write_kernel, do_install;
+	int fcontexts_modified, ports_modified, seusers_modified,
+		disable_dontaudit, preserve_tunables, ibpkeys_modified,
+		ibendports_modified;
 	dbase_config_t *users = semanage_user_dbase_local(sh);
 	dbase_config_t *users_base = semanage_user_base_dbase_local(sh);
 	dbase_config_t *pusers_base = semanage_user_base_dbase_policy(sh);
-	dbase_config_t *users_extra = semanage_user_extra_dbase_local(sh);
+	dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh);
 	dbase_config_t *ports = semanage_port_dbase_local(sh);
 	dbase_config_t *pports = semanage_port_dbase_policy(sh);
+	dbase_config_t *ibpkeys = semanage_ibpkey_dbase_local(sh);
+	dbase_config_t *pibpkeys = semanage_ibpkey_dbase_policy(sh);
+	dbase_config_t *ibendports = semanage_ibendport_dbase_local(sh);
+	dbase_config_t *pibendports = semanage_ibendport_dbase_policy(sh);
 	dbase_config_t *bools = semanage_bool_dbase_local(sh);
 	dbase_config_t *pbools = semanage_bool_dbase_policy(sh);
 	dbase_config_t *ifaces = semanage_iface_dbase_local(sh);
@@ -1092,13 +1197,25 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 	dbase_config_t *fcontexts = semanage_fcontext_dbase_local(sh);
 	dbase_config_t *pfcontexts = semanage_fcontext_dbase_policy(sh);
 	dbase_config_t *seusers = semanage_seuser_dbase_local(sh);
+	dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh);
+
+	/* Modified flags that we need to use more than once. */
+	ports_modified = ports->dtable->is_modified(ports->dbase);
+	ibpkeys_modified = ibpkeys->dtable->is_modified(ibpkeys->dbase);
+	ibendports_modified = ibendports->dtable->is_modified(ibendports->dbase);
+	seusers_modified = seusers->dtable->is_modified(seusers->dbase);
+	fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
+
+	/* Rebuild if explicitly requested or any module changes occurred. */
+	do_rebuild = sh->do_rebuild | sh->modules_modified;
 
 	/* Create or remove the disable_dontaudit flag file. */
 	path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT);
-	if (access(path, F_OK) == 0)
-		dontaudit_modified = !(sepol_get_disable_dontaudit(sh->sepolh) == 1);
+	struct stat sb;
+	if (stat(path, &sb) == 0)
+		do_rebuild |= !(sepol_get_disable_dontaudit(sh->sepolh) == 1);
 	else
-		dontaudit_modified = (sepol_get_disable_dontaudit(sh->sepolh) == 1);
+		do_rebuild |= (sepol_get_disable_dontaudit(sh->sepolh) == 1);
 	if (sepol_get_disable_dontaudit(sh->sepolh) == 1) {
 		FILE *touch;
 		touch = fopen(path, "w");
@@ -1120,10 +1237,10 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 
 	/* Create or remove the preserve_tunables flag file. */
 	path = semanage_path(SEMANAGE_TMP, SEMANAGE_PRESERVE_TUNABLES);
-	if (access(path, F_OK) == 0)
-		preserve_tunables_modified = !(sepol_get_preserve_tunables(sh->sepolh) == 1);
+	if (stat(path, &sb) == 0)
+		do_rebuild |= !(sepol_get_preserve_tunables(sh->sepolh) == 1);
 	else
-		preserve_tunables_modified = (sepol_get_preserve_tunables(sh->sepolh) == 1);
+		do_rebuild |= (sepol_get_preserve_tunables(sh->sepolh) == 1);
 	if (sepol_get_preserve_tunables(sh->sepolh) == 1) {
 		FILE *touch;
 		touch = fopen(path, "w");
@@ -1151,54 +1268,76 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 			goto cleanup;
 	}
 
-	/* Decide if anything was modified */
-	fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
-	seusers_modified = seusers->dtable->is_modified(seusers->dbase);
-	users_extra_modified =
-	    users_extra->dtable->is_modified(users_extra->dbase);
-	ports_modified = ports->dtable->is_modified(ports->dbase);
-	bools_modified = bools->dtable->is_modified(bools->dbase);
-
-	modified = sh->modules_modified;
-	modified |= seusers_modified;
-	modified |= users_extra_modified;
-	modified |= ports_modified;
-	modified |= users->dtable->is_modified(users_base->dbase);
-	modified |= ifaces->dtable->is_modified(ifaces->dbase);
-	modified |= nodes->dtable->is_modified(nodes->dbase);
-	modified |= dontaudit_modified;
-	modified |= preserve_tunables_modified;
-
-	/* This is for systems that have already migrated with an older version
-	 * of semanage_migrate_store. The older version did not copy policy.kern so
-	 * the policy binary must be rebuilt here.
+	/*
+	 * This is for systems that have already migrated with an older version
+	 * of semanage_migrate_store. The older version did not copy
+	 * policy.kern so the policy binary must be rebuilt here.
+	 * This also ensures that any linked files that are required
+	 * in order to skip re-linking are present; otherwise, we force
+	 * a rebuild.
 	 */
-	if (!sh->do_rebuild && !modified) {
+	if (!do_rebuild) {
 		path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL);
-
-		if (access(path, F_OK) != 0) {
-			missing_policy_kern = 1;
+		if (stat(path, &sb) != 0) {
+			do_rebuild = 1;
+			goto rebuild;
 		}
 
 		path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC);
-
-		if (access(path, F_OK) != 0) {
-			missing_fc = 1;
+		if (stat(path, &sb) != 0) {
+			do_rebuild = 1;
+			goto rebuild;
 		}
 
 		path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
+		if (stat(path, &sb) != 0) {
+			do_rebuild = 1;
+			goto rebuild;
+		}
 
-		if (access(path, F_OK) != 0) {
-			missing_seusers = 1;
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED);
+		if (stat(path, &sb) != 0) {
+			do_rebuild = 1;
+			goto rebuild;
+		}
+
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED);
+		if (stat(path, &sb) != 0) {
+			do_rebuild = 1;
+			goto rebuild;
 		}
-	}
 
-	missing |= missing_policy_kern;
-	missing |= missing_fc;
-	missing |= missing_seusers;
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED);
+		if (stat(path, &sb) != 0) {
+			do_rebuild = 1;
+			goto rebuild;
+		}
+	}
 
-	/* If there were policy changes, or explicitly requested, rebuild the policy */
-	if (sh->do_rebuild || modified || missing) {
+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.
+	 */
+	if (do_rebuild) {
 		/* =================== Module expansion =============== */
 
 		retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos);
@@ -1287,43 +1426,74 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 			goto cleanup;
 
 		cil_db_destroy(&cildb);
-	
+
+		/* Write the linked policy before merging local changes. */
+		retval = semanage_write_policydb(sh, out,
+						 SEMANAGE_LINKED);
+		if (retval < 0)
+			goto cleanup;
 	} else {
-		/* Load already linked policy */
+		/* Load the existing linked policy, w/o local changes */
 		retval = sepol_policydb_create(&out);
 		if (retval < 0)
 			goto cleanup;
 
-		retval = semanage_read_policydb(sh, out);
+		retval = semanage_read_policydb(sh, out, SEMANAGE_LINKED);
 		if (retval < 0)
 			goto cleanup;
-	}
 
-	if (sh->do_rebuild || modified || bools_modified) {
-		/* Attach to policy databases that work with a policydb. */
-		dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out);
-		dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out);
-		dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out);
-		dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out);
-		dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out);
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED);
+		if (stat(path, &sb) == 0) {
+			retval = semanage_copy_file(path,
+						    semanage_path(SEMANAGE_TMP,
+								  SEMANAGE_STORE_SEUSERS),
+						    sh->conf->file_mode);
+			if (retval < 0)
+				goto cleanup;
+			pseusers->dtable->drop_cache(pseusers->dbase);
+		} else {
+			pseusers->dtable->clear(sh, pseusers->dbase);
+		}
+
+		path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED);
+		if (stat(path, &sb) == 0) {
+			retval = semanage_copy_file(path,
+						    semanage_path(SEMANAGE_TMP,
+								  SEMANAGE_USERS_EXTRA),
+						    sh->conf->file_mode);
+			if (retval < 0)
+				goto cleanup;
+			pusers_extra->dtable->drop_cache(pusers_extra->dbase);
+		} else {
+			pusers_extra->dtable->clear(sh, pusers_extra->dbase);
+		}
+	}
 
-		/* ============= Apply changes, and verify  =============== */
+	/* 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);
+	dbase_policydb_attach((dbase_policydb_t *) pibpkeys->dbase, out);
+	dbase_policydb_attach((dbase_policydb_t *) pibendports->dbase, out);
+	dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out);
+	dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out);
+	dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out);
 
-		retval = semanage_base_merge_components(sh);
-		if (retval < 0)
-			goto cleanup;
+	/* Merge local changes */
+	retval = semanage_base_merge_components(sh);
+	if (retval < 0)
+		goto cleanup;
 
-		retval = semanage_write_policydb(sh, out);
+	if (do_write_kernel) {
+		/* Write new kernel policy. */
+		retval = semanage_write_policydb(sh, out,
+						 SEMANAGE_STORE_KERNEL);
 		if (retval < 0)
 			goto cleanup;
 
+		/* Run the kernel policy verifier, if any. */
 		retval = semanage_verify_kernel(sh);
 		if (retval < 0)
 			goto cleanup;
-	} else {
-		retval = semanage_base_merge_components(sh);
-		if (retval < 0)
-			goto cleanup;
 	}
 
 	/* ======= Post-process: Validate non-policydb components ===== */
@@ -1332,26 +1502,39 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 	 * Note: those are still cached, even though they've been 
 	 * merged into the main file_contexts. We won't check the 
 	 * large file_contexts - checked at compile time */
-	if (sh->do_rebuild || modified || fcontexts_modified) {
+	if (do_rebuild || fcontexts_modified) {
 		retval = semanage_fcontext_validate_local(sh, out);
 		if (retval < 0)
 			goto cleanup;
 	}
 
 	/* Validate local seusers against policy */
-	if (sh->do_rebuild || modified || seusers_modified) {
+	if (do_rebuild || seusers_modified) {
 		retval = semanage_seuser_validate_local(sh, out);
 		if (retval < 0)
 			goto cleanup;
 	}
 
 	/* Validate local ports for overlap */
-	if (sh->do_rebuild || modified || ports_modified) {
+	if (do_rebuild || ports_modified) {
 		retval = semanage_port_validate_local(sh);
 		if (retval < 0)
 			goto cleanup;
 	}
 
+	/* Validate local ibpkeys for overlap */
+	if (do_rebuild || ibpkeys_modified) {
+		retval = semanage_ibpkey_validate_local(sh);
+		if (retval < 0)
+			goto cleanup;
+	}
+
+	/* Validate local ibendports */
+	if (do_rebuild || ibendports_modified) {
+		retval = semanage_ibendport_validate_local(sh);
+		if (retval < 0)
+			goto cleanup;
+	}
 	/* ================== Write non-policydb components ========= */
 
 	/* Commit changes to components */
@@ -1367,43 +1550,46 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 	}
 
 	path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL);
-	if (access(path, F_OK) == 0) {
-		retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
-							semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL),
-							sh->conf->file_mode);
-		if (retval < 0) {
-			goto cleanup;
-		}
+	retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL),
+						semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL),
+						sh->conf->file_mode);
+	if (retval < 0 && errno != ENOENT) {
+		goto cleanup;
 	}
 
 	path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC);
-	if (access(path, F_OK) == 0) {
-		retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
-							semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
-							sh->conf->file_mode);
-		if (retval < 0) {
-			goto cleanup;
-		}
+	retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC),
+						semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC),
+						sh->conf->file_mode);
+	if (retval < 0 && errno != ENOENT) {
+		goto cleanup;
 	}
 
 	path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS);
-	if (access(path, F_OK) == 0) {
-		retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
-							semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS),
-							sh->conf->file_mode);
-		if (retval < 0) {
-			goto cleanup;
-		}
+	retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS),
+						semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS),
+						sh->conf->file_mode);
+	if (retval < 0 && errno != ENOENT) {
+		goto cleanup;
 	}
 
 	/* run genhomedircon if its enabled, this should be the last operation
 	 * which requires the out policydb */
 	if (!sh->conf->disable_genhomedircon) {
-		if (out && (retval =
-			semanage_genhomedircon(sh, out, sh->conf->usepasswd, sh->conf->ignoredirs)) != 0) {
-			ERR(sh, "semanage_genhomedircon returned error code %d.",
-			    retval);
-			goto cleanup;
+		if (out){
+			if ((retval = semanage_genhomedircon(sh, out, sh->conf->usepasswd,
+								sh->conf->ignoredirs)) != 0) {
+				ERR(sh, "semanage_genhomedircon returned error code %d.", retval);
+				goto cleanup;
+			}
+			/* file_contexts.homedirs was created in SEMANAGE_TMP store */
+			retval = semanage_copy_file(
+						semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
+						semanage_final_path(SEMANAGE_FINAL_TMP,	SEMANAGE_FC_HOMEDIRS),
+						sh->conf->file_mode);
+			if (retval < 0) {
+				goto cleanup;
+			}
 		}
 	} else {
 		WARN(sh, "WARNING: genhomedircon is disabled. \
@@ -1415,9 +1601,8 @@ static int semanage_direct_commit(semanage_handle_t * sh)
 	sepol_policydb_free(out);
 	out = NULL;
 
-	if (sh->do_rebuild || modified || bools_modified || fcontexts_modified) {
+	if (do_install)
 		retval = semanage_install_sandbox(sh);
-	}
 
 cleanup:
 	for (i = 0; i < num_modinfos; i++) {
@@ -1429,14 +1614,14 @@ cleanup:
 		free(mod_filenames[i]);
 	}
 
-	if (modified || bools_modified) {
-		/* Detach from policydb, so it can be freed */
-		dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase);
-		dbase_policydb_detach((dbase_policydb_t *) pports->dbase);
-		dbase_policydb_detach((dbase_policydb_t *) pifaces->dbase);
-		dbase_policydb_detach((dbase_policydb_t *) pnodes->dbase);
-		dbase_policydb_detach((dbase_policydb_t *) pbools->dbase);
-	}
+	/* Detach from policydb, so it can be freed */
+	dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase);
+	dbase_policydb_detach((dbase_policydb_t *) pports->dbase);
+	dbase_policydb_detach((dbase_policydb_t *) pibpkeys->dbase);
+	dbase_policydb_detach((dbase_policydb_t *) pibendports->dbase);
+	dbase_policydb_detach((dbase_policydb_t *) pifaces->dbase);
+	dbase_policydb_detach((dbase_policydb_t *) pnodes->dbase);
+	dbase_policydb_detach((dbase_policydb_t *) pbools->dbase);
 
 	free(mod_filenames);
 	sepol_policydb_free(out);
@@ -1452,6 +1637,8 @@ cleanup:
 	semanage_remove_directory(semanage_final_path
 				  (SEMANAGE_FINAL_TMP,
 				   SEMANAGE_FINAL_TOPLEVEL));
+	umask(mask);
+
 	return retval;
 }
 
@@ -1600,7 +1787,8 @@ static int semanage_direct_extract(semanage_handle_t * sh,
 		goto cleanup;
 	}
 
-	if (access(module_path, F_OK) != 0) {
+	struct stat sb;
+	if (stat(module_path, &sb) != 0) {
 		ERR(sh, "Module does not exist: %s", module_path);
 		rc = -1;
 		goto cleanup;
@@ -1630,7 +1818,7 @@ static int semanage_direct_extract(semanage_handle_t * sh,
 		goto cleanup;
 	}
 
-	if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && access(input_file, F_OK) != 0) {
+	if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && stat(input_file, &sb) != 0) {
 		rc = semanage_compile_module(sh, _modinfo);
 		if (rc < 0) {
 			goto cleanup;
@@ -1802,6 +1990,7 @@ static int semanage_direct_set_enabled(semanage_handle_t *sh,
 	const char *path = NULL;
 	FILE *fp = NULL;
 	semanage_module_info_t *modinfo = NULL;
+	mode_t mask;
 
 	/* check transaction */
 	if (!sh->is_in_transaction) {
@@ -1862,7 +2051,9 @@ static int semanage_direct_set_enabled(semanage_handle_t *sh,
 
 	switch (enabled) {
 		case 0: /* disable the module */
+			mask = umask(0077);
 			fp = fopen(fn, "w");
+			umask(mask);
 
 			if (fp == NULL) {
 				ERR(sh,
@@ -1931,7 +2122,7 @@ int semanage_direct_mls_enabled(semanage_handle_t * sh)
 	if (retval < 0)
 		goto cleanup;
 
-	retval = semanage_read_policydb(sh, p);
+	retval = semanage_read_policydb(sh, p, SEMANAGE_STORE_KERNEL);
 	if (retval < 0)
 		goto cleanup;
 
@@ -2075,6 +2266,31 @@ static int semanage_direct_get_module_info(semanage_handle_t *sh,
 	free(tmp);
 	tmp = NULL;
 
+	if (strcmp((*modinfo)->lang_ext, "pp") == 0) {
+		/* try to get a module_version from hll file */
+		int data_len, compressed = 0;
+		char *data = NULL;
+		char fhll[PATH_MAX];
+		ret = semanage_module_get_path(sh,
+					       *modinfo,
+					       SEMANAGE_MODULE_PATH_HLL,
+					       fhll,
+					       sizeof(fhll));
+		if (ret == 0 && (access(fhll, R_OK) == 0)) {
+			if ((data_len = map_file(sh, fhll, &data, &compressed)) > 0) {
+
+				char *module_name = NULL;
+				char *version = NULL;
+				ret = parse_module_headers(sh, data, data_len, &module_name, &version);
+				if (ret == 0 && version != NULL) {
+					ret = semanage_module_info_set_version(sh, *modinfo, version);
+				}
+				free(module_name);
+				free(version);
+				munmap(data, data_len);
+			}
+		}
+	}
 	if (fclose(fp) != 0) {
 		ERR(sh,
 		    "Unable to close %s module lang ext file.",
@@ -2516,6 +2732,7 @@ static int semanage_direct_install_info(semanage_handle_t *sh,
 	int type;
 
 	char path[PATH_MAX];
+	mode_t mask = umask(0077);
 
 	semanage_module_info_t *higher_info = NULL;
 	semanage_module_key_t higher_key;
@@ -2613,7 +2830,8 @@ static int semanage_direct_install_info(semanage_handle_t *sh,
 			goto cleanup;
 		}
 
-		if (access(path, F_OK) == 0) {
+		struct stat sb;
+		if (stat(path, &sb) == 0) {
 			ret = unlink(path);
 			if (ret != 0) {
 				ERR(sh, "Error while removing cached CIL file %s: %s", path, strerror(errno));
@@ -2627,6 +2845,7 @@ cleanup:
 	semanage_module_key_destroy(sh, &higher_key);
 	semanage_module_info_destroy(sh, higher_info);
 	free(higher_info);
+	umask(mask);
 
 	return status;
 }
diff --git libsemanage-2.5/src/exception.sh libsemanage-2.5/src/exception.sh
index 94619d2..d18959c 100644
--- libsemanage-2.5/src/exception.sh
+++ libsemanage-2.5/src/exception.sh
@@ -9,6 +9,6 @@ echo "
 }
 "
 }
-gcc -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h
+${CC:-gcc} -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h
 for i in `awk '/extern int/ { print $6 }' temp.aux`; do except $i ; done
 rm -f -- temp.aux -.o
diff --git libsemanage-2.5/src/fcontexts_policy.c libsemanage-2.5/src/fcontexts_policy.c
index 0b063b1..98490ab 100644
--- libsemanage-2.5/src/fcontexts_policy.c
+++ libsemanage-2.5/src/fcontexts_policy.c
@@ -51,3 +51,11 @@ int semanage_fcontext_list(semanage_handle_t * handle,
 	dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle);
 	return dbase_list(handle, dconfig, records, count);
 }
+
+int semanage_fcontext_list_homedirs(semanage_handle_t * handle,
+			   semanage_fcontext_t *** records, unsigned int *count)
+{
+
+	dbase_config_t *dconfig = semanage_fcontext_dbase_homedirs(handle);
+	return dbase_list(handle, dconfig, records, count);
+}
diff --git libsemanage-2.5/src/genhomedircon.c libsemanage-2.5/src/genhomedircon.c
index 1a9e87e..d32c147 100644
--- libsemanage-2.5/src/genhomedircon.c
+++ libsemanage-2.5/src/genhomedircon.c
@@ -48,6 +48,8 @@
 #include <errno.h>
 #include <unistd.h>
 #include <regex.h>
+#include <grp.h>
+#include <search.h>
 
 /* paths used in get_home_dirs() */
 #define PATH_ETC_USERADD "/etc/default/useradd"
@@ -73,36 +75,44 @@
    which are searched for and replaced */
 #define TEMPLATE_HOME_ROOT "HOME_ROOT"
 #define TEMPLATE_HOME_DIR "HOME_DIR"
+/* these are legacy */
 #define TEMPLATE_USER "USER"
 #define TEMPLATE_ROLE "ROLE"
+/* new names */
+#define TEMPLATE_USERNAME "%{USERNAME}"
+#define TEMPLATE_USERID "%{USERID}"
+
 #define TEMPLATE_SEUSER "system_u"
 #define TEMPLATE_LEVEL "s0"
 
-#define FALLBACK_USER "user_u"
-#define FALLBACK_USER_PREFIX "user"
-#define FALLBACK_USER_LEVEL "s0"
+#define FALLBACK_SENAME "user_u"
+#define FALLBACK_PREFIX "user"
+#define FALLBACK_LEVEL "s0"
+#define FALLBACK_NAME "[^/]+"
+#define FALLBACK_UIDGID "[0-9]+"
 #define DEFAULT_LOGIN "__default__"
 
-typedef struct {
-	const char *fcfilepath;
-	int usepasswd;
-	const char *homedir_template_path;
-	char *fallback_user;
-	char *fallback_user_prefix;
-	char *fallback_user_level;
-	semanage_handle_t *h_semanage;
-	sepol_policydb_t *policydb;
-} genhomedircon_settings_t;
-
 typedef struct user_entry {
 	char *name;
+	char *uid;
+	char *gid;
 	char *sename;
 	char *prefix;
 	char *home;
 	char *level;
+	char *login;
 	struct user_entry *next;
 } genhomedircon_user_entry_t;
 
+typedef struct {
+	const char *fcfilepath;
+	int usepasswd;
+	const char *homedir_template_path;
+	genhomedircon_user_entry_t *fallback;
+	semanage_handle_t *h_semanage;
+	sepol_policydb_t *policydb;
+} genhomedircon_settings_t;
+
 typedef struct {
 	const char *search_for;
 	const char *replace_with;
@@ -461,11 +471,29 @@ static int HOME_DIR_PRED(const char *string)
 	return semanage_is_prefix(string, TEMPLATE_HOME_DIR);
 }
 
+/* new names */
+static int USERNAME_CONTEXT_PRED(const char *string)
+{
+	return (int)(
+		(strstr(string, TEMPLATE_USERNAME) != NULL) ||
+		(strstr(string, TEMPLATE_USERID) != NULL)
+	);
+}
+
+/* This will never match USER if USERNAME or USERID are found. */
 static int USER_CONTEXT_PRED(const char *string)
 {
+	if (USERNAME_CONTEXT_PRED(string))
+		return 0;
+
 	return (int)(strstr(string, TEMPLATE_USER) != NULL);
 }
 
+static int STR_COMPARATOR(const void *a, const void *b)
+{
+	return strcmp((const char *) a, (const char *) b);
+}
+
 /* make_tempate
  * @param	s	  the settings holding the paths to various files
  * @param	pred	function pointer to function to use as filter for slurp
@@ -548,23 +576,12 @@ static int check_line(genhomedircon_settings_t * s, Ustr *line)
 	return result;
 }
 
-static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out,
-				  semanage_list_t * tpl, const char *user,
-				  const char *seuser, const char *home,
-				  const char *role_prefix, const char *level)
+static int write_replacements(genhomedircon_settings_t * s, FILE * out,
+			      const semanage_list_t * tpl,
+			      const replacement_pair_t *repl)
 {
-	replacement_pair_t repl[] = {
-		{.search_for = TEMPLATE_SEUSER,.replace_with = seuser},
-		{.search_for = TEMPLATE_HOME_DIR,.replace_with = home},
-		{.search_for = TEMPLATE_ROLE,.replace_with = role_prefix},
-		{.search_for = TEMPLATE_LEVEL,.replace_with = level},
-		{NULL, NULL}
-	};
 	Ustr *line = USTR_NULL;
 
-	if (fprintf(out, COMMENT_USER_HOME_CONTEXT, user) < 0)
-		return STATUS_ERR;
-
 	for (; tpl; tpl = tpl->next) {
 		line = replace_all(tpl->data, repl);
 		if (!line)
@@ -582,6 +599,28 @@ static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out,
 	return STATUS_ERR;
 }
 
+static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out,
+				  semanage_list_t * tpl, const genhomedircon_user_entry_t *user)
+{
+	replacement_pair_t repl[] = {
+		{.search_for = TEMPLATE_SEUSER,.replace_with = user->sename},
+		{.search_for = TEMPLATE_HOME_DIR,.replace_with = user->home},
+		{.search_for = TEMPLATE_ROLE,.replace_with = user->prefix},
+		{.search_for = TEMPLATE_LEVEL,.replace_with = user->level},
+		{NULL, NULL}
+	};
+
+	if (strcmp(user->name, FALLBACK_NAME) == 0) {
+		if (fprintf(out, COMMENT_USER_HOME_CONTEXT, FALLBACK_SENAME) < 0)
+			return STATUS_ERR;
+	} else {
+		if (fprintf(out, COMMENT_USER_HOME_CONTEXT, user->name) < 0)
+			return STATUS_ERR;
+	}
+
+	return write_replacements(s, out, tpl, repl);
+}
+
 static int write_home_root_context(genhomedircon_settings_t * s, FILE * out,
 				   semanage_list_t * tpl, char *homedir)
 {
@@ -589,52 +628,54 @@ static int write_home_root_context(genhomedircon_settings_t * s, FILE * out,
 		{.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir},
 		{NULL, NULL}
 	};
-	Ustr *line = USTR_NULL;
 
-	for (; tpl; tpl = tpl->next) {
-		line = replace_all(tpl->data, repl);
-		if (!line)
-			goto fail;
-		if (check_line(s, line) == STATUS_SUCCESS) {
-			if (!ustr_io_putfileline(&line, out))
-				goto fail;
-		}
-		ustr_sc_free(&line);
-	}
-	return STATUS_SUCCESS;
+	return write_replacements(s, out, tpl, repl);
+}
 
-      fail:
-	ustr_sc_free(&line);
-	return STATUS_ERR;
+static int write_username_context(genhomedircon_settings_t * s, FILE * out,
+				  semanage_list_t * tpl,
+				  const genhomedircon_user_entry_t *user)
+{
+	replacement_pair_t repl[] = {
+		{.search_for = TEMPLATE_USERNAME,.replace_with = user->name},
+		{.search_for = TEMPLATE_USERID,.replace_with = user->uid},
+		{.search_for = TEMPLATE_ROLE,.replace_with = user->prefix},
+		{.search_for = TEMPLATE_SEUSER,.replace_with = user->sename},
+		{NULL, NULL}
+	};
+
+	return write_replacements(s, out, tpl, repl);
 }
 
 static int write_user_context(genhomedircon_settings_t * s, FILE * out,
-			      semanage_list_t * tpl, const char *user,
-			      const char *seuser, const char *role_prefix)
+			      semanage_list_t * tpl, const genhomedircon_user_entry_t *user)
 {
 	replacement_pair_t repl[] = {
-		{.search_for = TEMPLATE_USER,.replace_with = user},
-		{.search_for = TEMPLATE_ROLE,.replace_with = role_prefix},
-		{.search_for = TEMPLATE_SEUSER,.replace_with = seuser},
+		{.search_for = TEMPLATE_USER,.replace_with = user->name},
+		{.search_for = TEMPLATE_ROLE,.replace_with = user->prefix},
+		{.search_for = TEMPLATE_SEUSER,.replace_with = user->sename},
 		{NULL, NULL}
 	};
-	Ustr *line = USTR_NULL;
 
-	for (; tpl; tpl = tpl->next) {
-		line = replace_all(tpl->data, repl);
-		if (!line)
-			goto fail;
-		if (check_line(s, line) == STATUS_SUCCESS) {
-			if (!ustr_io_putfileline(&line, out))
-				goto fail;
-		}
-		ustr_sc_free(&line);
+	return write_replacements(s, out, tpl, repl);
+}
+
+static int seuser_sort_func(const void *arg1, const void *arg2)
+{
+	const semanage_seuser_t **u1 = (const semanage_seuser_t **) arg1;
+	const semanage_seuser_t **u2 = (const semanage_seuser_t **) arg2;;
+	const char *name1 = semanage_seuser_get_name(*u1);
+	const char *name2 = semanage_seuser_get_name(*u2);
+
+	if (name1[0] == '%' && name2[0] == '%') {
+		return 0;
+	} else if (name1[0] == '%') {
+		return 1;
+	} else if (name2[0] == '%') {
+		return -1;
 	}
-	return STATUS_SUCCESS;
 
-      fail:
-	ustr_sc_free(&line);
-	return STATUS_ERR;
+	return strcmp(name1, name2);
 }
 
 static int user_sort_func(semanage_user_t ** arg1, semanage_user_t ** arg2)
@@ -649,15 +690,19 @@ static int name_user_cmp(char *key, semanage_user_t ** val)
 }
 
 static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
-			   const char *sen, const char *pre, const char *h,
-			   const char *l)
+			   const char *u, const char *g, const char *sen,
+			   const char *pre, const char *h, const char *l,
+			   const char *ln)
 {
 	genhomedircon_user_entry_t *temp = NULL;
 	char *name = NULL;
+	char *uid = NULL;
+	char *gid = NULL;
 	char *sename = NULL;
 	char *prefix = NULL;
 	char *home = NULL;
 	char *level = NULL;
+	char *lname = NULL;
 
 	temp = malloc(sizeof(genhomedircon_user_entry_t));
 	if (!temp)
@@ -665,6 +710,12 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
 	name = strdup(n);
 	if (!name)
 		goto cleanup;
+	uid = strdup(u);
+	if (!uid)
+		goto cleanup;
+	gid = strdup(g);
+	if (!gid)
+		goto cleanup;
 	sename = strdup(sen);
 	if (!sename)
 		goto cleanup;
@@ -677,12 +728,18 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
 	level = strdup(l);
 	if (!level)
 		goto cleanup;
+	lname = strdup(ln);
+	if (!lname)
+		goto cleanup;
 
 	temp->name = name;
+	temp->uid = uid;
+	temp->gid = gid;
 	temp->sename = sename;
 	temp->prefix = prefix;
 	temp->home = home;
 	temp->level = level;
+	temp->login = lname;
 	temp->next = (*list);
 	(*list) = temp;
 
@@ -690,10 +747,13 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n,
 
       cleanup:
 	free(name);
+	free(uid);
+	free(gid);
 	free(sename);
 	free(prefix);
 	free(home);
 	free(level);
+	free(lname);
 	free(temp);
 	return STATUS_ERR;
 }
@@ -708,39 +768,16 @@ static void pop_user_entry(genhomedircon_user_entry_t ** list)
 	temp = *list;
 	*list = temp->next;
 	free(temp->name);
+	free(temp->uid);
+	free(temp->gid);
 	free(temp->sename);
 	free(temp->prefix);
 	free(temp->home);
 	free(temp->level);
+	free(temp->login);
 	free(temp);
 }
 
-static int set_fallback_user(genhomedircon_settings_t *s, const char *user,
-			     const char *prefix, const char *level)
-{
-	char *fallback_user = strdup(user);
-	char *fallback_user_prefix = strdup(prefix);
-	char *fallback_user_level = NULL;
-	if (level) 
-		fallback_user_level = strdup(level);
-
-	if (fallback_user == NULL || fallback_user_prefix == NULL ||
-	    (fallback_user_level == NULL && level != NULL)) {
-		free(fallback_user);
-		free(fallback_user_prefix);
-		free(fallback_user_level);
-		return STATUS_ERR;
-	}
-
-	free(s->fallback_user);
-	free(s->fallback_user_prefix);
-	free(s->fallback_user_level);
-	s->fallback_user = fallback_user;
-	s->fallback_user_prefix = fallback_user_prefix;
-	s->fallback_user_level = fallback_user_level;
-	return STATUS_SUCCESS;
-}
-
 static int setup_fallback_user(genhomedircon_settings_t * s)
 {
 	semanage_seuser_t **seuser_list = NULL;
@@ -775,17 +812,20 @@ static int setup_fallback_user(genhomedircon_settings_t * s)
 			if (semanage_user_query(s->h_semanage, key, &u) < 0)
 			{
 				prefix = name;
-				level = FALLBACK_USER_LEVEL;
+				level = FALLBACK_LEVEL;
 			}
 			else
 			{
 				prefix = semanage_user_get_prefix(u);
 				level = semanage_user_get_mlslevel(u);
 				if (!level)
-					level = FALLBACK_USER_LEVEL;
+					level = FALLBACK_LEVEL;
 			}
 
-			if (set_fallback_user(s, seuname, prefix, level) != 0)
+			if (push_user_entry(&(s->fallback), FALLBACK_NAME,
+					    FALLBACK_UIDGID, FALLBACK_UIDGID,
+					    seuname, prefix, "", level,
+					    FALLBACK_NAME) != 0)
 				errors = STATUS_ERR;
 			semanage_user_key_free(key);
 			if (u)
@@ -801,6 +841,212 @@ static int setup_fallback_user(genhomedircon_settings_t * s)
 	return errors;
 }
 
+static genhomedircon_user_entry_t *find_user(genhomedircon_user_entry_t *head,
+					     const char *name)
+{
+	for(; head; head = head->next) {
+		if (strcmp(head->name, name) == 0) {
+			return head;
+		}
+	}
+
+	return NULL;
+}
+
+static int add_user(genhomedircon_settings_t * s,
+		    genhomedircon_user_entry_t **head,
+		    semanage_user_t *user,
+		    const char *name,
+		    const char *sename,
+		    const char *selogin)
+{
+	if (selogin[0] == '%') {
+		genhomedircon_user_entry_t *orig = find_user(*head, name);
+		if (orig != NULL && orig->login[0] == '%') {
+			ERR(s->h_semanage, "User %s is already mapped to"
+			    " group %s, but also belongs to group %s. Add an"
+			    " explicit mapping for this user to"
+			    " override group mappings.",
+			    name, orig->login + 1, selogin + 1);
+			return STATUS_ERR;
+		} else if (orig != NULL) {
+			// user mappings take precedence
+			return STATUS_SUCCESS;
+		}
+	}
+
+	int retval = STATUS_ERR;
+
+	char *rbuf = NULL;
+	long rbuflen;
+	struct passwd pwstorage, *pwent = NULL;
+	const char *prefix = NULL;
+	const char *level = NULL;
+	char uid[11];
+	char gid[11];
+
+	/* Allocate space for the getpwnam_r buffer */
+	rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+	if (rbuflen <= 0)
+		goto cleanup;
+	rbuf = malloc(rbuflen);
+	if (rbuf == NULL)
+		goto cleanup;
+
+	if (user) {
+		prefix = semanage_user_get_prefix(user);
+		level = semanage_user_get_mlslevel(user);
+
+		if (!level) {
+			level = FALLBACK_LEVEL;
+		}
+	} else {
+		prefix = name;
+		level = FALLBACK_LEVEL;
+	}
+
+	retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent);
+	if (retval != 0 || pwent == NULL) {
+		if (retval != 0 && retval != ENOENT) {
+			goto cleanup;
+		}
+
+		WARN(s->h_semanage,
+		     "user %s not in password file", name);
+		retval = STATUS_SUCCESS;
+		goto cleanup;
+	}
+
+	int len = strlen(pwent->pw_dir) -1;
+	for(; len > 0 && pwent->pw_dir[len] == '/'; len--) {
+		pwent->pw_dir[len] = '\0';
+	}
+
+	if (strcmp(pwent->pw_dir, "/") == 0) {
+		/* don't relabel / genhomdircon checked to see if root
+		 * was the user and if so, set his home directory to
+		 * /root */
+		retval = STATUS_SUCCESS;
+		goto cleanup;
+	}
+
+	if (ignore(pwent->pw_dir)) {
+		retval = STATUS_SUCCESS;
+		goto cleanup;
+	}
+
+	len = snprintf(uid, sizeof(uid), "%u", pwent->pw_uid);
+	if (len < 0 || len >= (int)sizeof(uid)) {
+		goto cleanup;
+	}
+
+	len = snprintf(gid, sizeof(gid), "%u", pwent->pw_gid);
+	if (len < 0 || len >= (int)sizeof(gid)) {
+		goto cleanup;
+	}
+
+	retval = push_user_entry(head, name, uid, gid, sename, prefix,
+				pwent->pw_dir, level, selogin);
+cleanup:
+	free(rbuf);
+	return retval;
+}
+
+static int get_group_users(genhomedircon_settings_t * s,
+			  genhomedircon_user_entry_t **head,
+			  semanage_user_t *user,
+			  const char *sename,
+			  const char *selogin)
+{
+	int retval = STATUS_ERR;
+	unsigned int i;
+
+	long grbuflen;
+	char *grbuf = NULL;
+	struct group grstorage, *group = NULL;
+
+	long prbuflen;
+	char *pwbuf = NULL;
+	struct passwd pwstorage, *pw = NULL;
+
+	grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
+	if (grbuflen <= 0)
+		goto cleanup;
+	grbuf = malloc(grbuflen);
+	if (grbuf == NULL)
+		goto cleanup;
+
+	const char *grname = selogin + 1;
+
+	errno = 0;
+	while (
+		(retval = getgrnam_r(grname, &grstorage, grbuf, (size_t) grbuflen, &group)) != 0 &&
+		errno == ERANGE
+	) {
+		char *new_grbuf;
+		grbuflen *= 2;
+		new_grbuf = realloc(grbuf, grbuflen);
+		if (new_grbuf == NULL)
+			goto cleanup;
+		grbuf = new_grbuf;
+	}
+	if (retval == -1)
+		goto cleanup;
+
+	if (group == NULL) {
+		ERR(s->h_semanage, "Can't find group named %s\n", grname);
+		goto cleanup;
+	}
+
+	size_t nmembers = 0;
+	char **members = group->gr_mem;
+
+	while (*members != NULL) {
+		nmembers++;
+		members++;
+	}
+
+	for (i = 0; i < nmembers; i++) {
+		const char *uname = group->gr_mem[i];
+
+		if (add_user(s, head, user, uname, sename, selogin) < 0) {
+			goto cleanup;
+		}
+	}
+
+	prbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+	if (prbuflen <= 0)
+		goto cleanup;
+	pwbuf = malloc(prbuflen);
+	if (pwbuf == NULL)
+		goto cleanup;
+
+	setpwent();
+	while ((retval = getpwent_r(&pwstorage, pwbuf, prbuflen, &pw)) == 0) {
+		// skip users who also have this group as their
+		// primary group
+		if (lfind(pw->pw_name, group->gr_mem, &nmembers,
+			  sizeof(char *), &STR_COMPARATOR)) {
+			continue;
+		}
+
+		if (group->gr_gid == pw->pw_gid) {
+			if (add_user(s, head, user, pw->pw_name,
+				     sename, selogin) < 0) {
+				goto cleanup;
+			}
+		}
+	}
+
+	retval = STATUS_SUCCESS;
+cleanup:
+	endpwent();
+	free(pwbuf);
+	free(grbuf);
+
+	return retval;
+}
+
 static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s,
 					     int *errors)
 {
@@ -812,12 +1058,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s,
 	semanage_user_t **u = NULL;
 	const char *name = NULL;
 	const char *seuname = NULL;
-	const char *prefix = NULL;
-	const char *level = NULL;
-	struct passwd pwstorage, *pwent = NULL;
 	unsigned int i;
-	long rbuflen;
-	char *rbuf = NULL;
 	int retval;
 
 	*errors = 0;
@@ -831,82 +1072,42 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s,
 		nusers = 0;
 	}
 
+	qsort(seuser_list, nseusers, sizeof(semanage_seuser_t *),
+	      &seuser_sort_func);
 	qsort(user_list, nusers, sizeof(semanage_user_t *),
 	      (int (*)(const void *, const void *))&user_sort_func);
 
-	/* Allocate space for the getpwnam_r buffer */
-	rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
-	if (rbuflen <= 0)
-		goto cleanup;
-	rbuf = malloc(rbuflen);
-	if (rbuf == NULL)
-		goto cleanup;
-
 	for (i = 0; i < nseusers; i++) {
 		seuname = semanage_seuser_get_sename(seuser_list[i]);
 		name = semanage_seuser_get_name(seuser_list[i]);
 
-		if (strcmp(name,"root") && strcmp(seuname, s->fallback_user) == 0)
-			continue;
-
 		if (strcmp(name, DEFAULT_LOGIN) == 0)
 			continue;
 
 		if (strcmp(name, TEMPLATE_SEUSER) == 0)
 			continue;
 
-		/* %groupname syntax */
-		if (name[0] == '%')
-			continue;
-
 		/* find the user structure given the name */
 		u = bsearch(seuname, user_list, nusers, sizeof(semanage_user_t *),
 			    (int (*)(const void *, const void *))
 			    &name_user_cmp);
-		if (u) {
-			prefix = semanage_user_get_prefix(*u);
-			level = semanage_user_get_mlslevel(*u);
-			if (!level)
-				level = FALLBACK_USER_LEVEL;
-		} else {
-			prefix = name;
-			level = FALLBACK_USER_LEVEL;
-		}
-
-		retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent);
-		if (retval != 0 || pwent == NULL) {
-			if (retval != 0 && retval != ENOENT) {
-				*errors = STATUS_ERR;
-				goto cleanup;
-			}
-
-			WARN(s->h_semanage,
-			     "user %s not in password file", name);
-			continue;
-		}
 
-		int len = strlen(pwent->pw_dir) -1;
-		for(; len > 0 && pwent->pw_dir[len] == '/'; len--) {
-			pwent->pw_dir[len] = '\0';
+		/* %groupname syntax */
+		if (name[0] == '%') {
+			retval = get_group_users(s, &head, *u, seuname,
+						name);
+		} else {
+			retval = add_user(s, &head, *u, name,
+					  seuname, name);
 		}
 
-		if (strcmp(pwent->pw_dir, "/") == 0) {
-			/* don't relabel / genhomdircon checked to see if root
-			 * was the user and if so, set his home directory to
-			 * /root */
-			continue;
-		}
-		if (ignore(pwent->pw_dir))
-			continue;
-		if (push_user_entry(&head, name, seuname,
-				    prefix, pwent->pw_dir, level) != STATUS_SUCCESS) {
+		if (retval != 0) {
 			*errors = STATUS_ERR;
-			break;
+			goto cleanup;
 		}
 	}
 
       cleanup:
-	free(rbuf);
 	if (*errors) {
 		for (; head; pop_user_entry(&head)) {
 			/* the pop function takes care of all the cleanup
@@ -927,6 +1128,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s,
 }
 
 static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out,
+				      semanage_list_t * username_context_tpl,
 				      semanage_list_t * user_context_tpl,
 				      semanage_list_t * homedir_context_tpl)
 {
@@ -939,13 +1141,11 @@ static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out,
 	}
 
 	for (; users; pop_user_entry(&users)) {
-		if (write_home_dir_context(s, out, homedir_context_tpl,
-					   users->name,
-					   users->sename, users->home,
-					   users->prefix, users->level))
+		if (write_home_dir_context(s, out, homedir_context_tpl, users))
 			goto err;
-		if (write_user_context(s, out, user_context_tpl, users->name,
-				       users->sename, users->prefix))
+		if (write_username_context(s, out, username_context_tpl, users))
+			goto err;
+		if (write_user_context(s, out, user_context_tpl, users))
 			goto err;
 	}
 
@@ -968,16 +1168,21 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out)
 {
 	semanage_list_t *homedirs = NULL;
 	semanage_list_t *h = NULL;
-	semanage_list_t *user_context_tpl = NULL;
 	semanage_list_t *homedir_context_tpl = NULL;
 	semanage_list_t *homeroot_context_tpl = NULL;
+	semanage_list_t *username_context_tpl = NULL;
+	semanage_list_t *user_context_tpl = NULL;
 	int retval = STATUS_SUCCESS;
 
 	homedir_context_tpl = make_template(s, &HOME_DIR_PRED);
 	homeroot_context_tpl = make_template(s, &HOME_ROOT_PRED);
+	username_context_tpl = make_template(s, &USERNAME_CONTEXT_PRED);
 	user_context_tpl = make_template(s, &USER_CONTEXT_PRED);
 
-	if (!homedir_context_tpl && !homeroot_context_tpl && !user_context_tpl)
+	if (!homedir_context_tpl
+	 && !homeroot_context_tpl
+	 && !username_context_tpl
+	 && !user_context_tpl)
 		goto done;
 
 	if (write_file_context_header(out) != STATUS_SUCCESS) {
@@ -1001,19 +1206,19 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out)
 		for (h = homedirs; h; h = h->next) {
 			Ustr *temp = ustr_dup_cstr(h->data);
 
-			if (!temp || !ustr_add_cstr(&temp, "/[^/]*")) {
+			if (!temp || !ustr_add_cstr(&temp, "/" FALLBACK_NAME)) {
 				ustr_sc_free(&temp);
 				retval = STATUS_ERR;
 				goto done;
 			}
 
-			if (write_home_dir_context(s, out,
-						   homedir_context_tpl,
-						   s->fallback_user, s->fallback_user,
-						   ustr_cstr(temp),
-						   s->fallback_user_prefix, s->fallback_user_level) !=
-			    STATUS_SUCCESS) {
+			free(s->fallback->home);
+			s->fallback->home = (char*) ustr_cstr(temp);
+
+			if (write_home_dir_context(s, out, homedir_context_tpl,
+						   s->fallback) != STATUS_SUCCESS) {
 				ustr_sc_free(&temp);
+				s->fallback->home = NULL;
 				retval = STATUS_ERR;
 				goto done;
 			}
@@ -1021,23 +1226,31 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out)
 						    homeroot_context_tpl,
 						    h->data) != STATUS_SUCCESS) {
 				ustr_sc_free(&temp);
+				s->fallback->home = NULL;
 				retval = STATUS_ERR;
 				goto done;
 			}
 
 			ustr_sc_free(&temp);
+			s->fallback->home = NULL;
 		}
 	}
-	if (user_context_tpl) {
+	if (user_context_tpl || username_context_tpl) {
+		if (write_username_context(s, out, username_context_tpl,
+					   s->fallback) != STATUS_SUCCESS) {
+			retval = STATUS_ERR;
+			goto done;
+		}
+
 		if (write_user_context(s, out, user_context_tpl,
-				       ".*", s->fallback_user,
-				       s->fallback_user_prefix) != STATUS_SUCCESS) {
+				       s->fallback) != STATUS_SUCCESS) {
 			retval = STATUS_ERR;
 			goto done;
 		}
 
-		if (write_gen_home_dir_context(s, out, user_context_tpl,
-					       homedir_context_tpl) != STATUS_SUCCESS) {
+		if (write_gen_home_dir_context(s, out, username_context_tpl,
+					       user_context_tpl, homedir_context_tpl)
+				!= STATUS_SUCCESS) {
 			retval = STATUS_ERR;
 		}
 	}
@@ -1045,6 +1258,7 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out)
 done:
 	/* Cleanup */
 	semanage_list_destroy(&homedirs);
+	semanage_list_destroy(&username_context_tpl);
 	semanage_list_destroy(&user_context_tpl);
 	semanage_list_destroy(&homedir_context_tpl);
 	semanage_list_destroy(&homeroot_context_tpl);
@@ -1065,13 +1279,23 @@ int semanage_genhomedircon(semanage_handle_t * sh,
 
 	s.homedir_template_path =
 	    semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL);
-	s.fcfilepath = semanage_final_path(SEMANAGE_FINAL_TMP,
-					   SEMANAGE_FC_HOMEDIRS);
+	s.fcfilepath =
+		semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS);
+
+	s.fallback = calloc(1, sizeof(genhomedircon_user_entry_t));
+	if (s.fallback == NULL) {
+		retval = STATUS_ERR;
+		goto done;
+	}
 
-	s.fallback_user = strdup(FALLBACK_USER);
-	s.fallback_user_prefix = strdup(FALLBACK_USER_PREFIX);
-	s.fallback_user_level = strdup(FALLBACK_USER_LEVEL);
-	if (s.fallback_user == NULL || s.fallback_user_prefix == NULL || s.fallback_user_level == NULL) {
+	s.fallback->name = strdup(FALLBACK_NAME);
+	s.fallback->sename = strdup(FALLBACK_SENAME);
+	s.fallback->prefix = strdup(FALLBACK_PREFIX);
+	s.fallback->level = strdup(FALLBACK_LEVEL);
+	if (s.fallback->name == NULL
+	 || s.fallback->sename == NULL
+	 || s.fallback->prefix == NULL
+	 || s.fallback->level == NULL) {
 		retval = STATUS_ERR;
 		goto done;
 	}
@@ -1095,9 +1319,7 @@ done:
 	if (out != NULL)
 		fclose(out);
 
-	free(s.fallback_user);
-	free(s.fallback_user_prefix);
-	free(s.fallback_user_level);
+	pop_user_entry(&(s.fallback));
 	ignore_free();
 
 	return retval;
diff --git libsemanage-2.5/src/handle.h libsemanage-2.5/src/handle.h
index 64175c4..1780ac8 100644
--- libsemanage-2.5/src/handle.h
+++ libsemanage-2.5/src/handle.h
@@ -79,7 +79,7 @@ struct semanage_handle {
 	struct semanage_policy_table *funcs;
 
 	/* Object databases */
-#define DBASE_COUNT      19
+#define DBASE_COUNT      24
 
 /* Local modifications */
 #define DBASE_LOCAL_USERS_BASE  0
@@ -91,20 +91,25 @@ struct semanage_handle {
 #define DBASE_LOCAL_FCONTEXTS	6
 #define DBASE_LOCAL_SEUSERS     7
 #define DBASE_LOCAL_NODES       8
+#define DBASE_LOCAL_IBPKEYS     9
+#define DBASE_LOCAL_IBENDPORTS  10
 
 /* Policy + Local modifications */
-#define DBASE_POLICY_USERS_BASE  9
-#define DBASE_POLICY_USERS_EXTRA 10
-#define DBASE_POLICY_USERS       11
-#define DBASE_POLICY_PORTS       12
-#define DBASE_POLICY_INTERFACES  13
-#define DBASE_POLICY_BOOLEANS    14
-#define DBASE_POLICY_FCONTEXTS   15
-#define DBASE_POLICY_SEUSERS     16
-#define DBASE_POLICY_NODES       17
+#define DBASE_POLICY_USERS_BASE  11
+#define DBASE_POLICY_USERS_EXTRA 12
+#define DBASE_POLICY_USERS       13
+#define DBASE_POLICY_PORTS       14
+#define DBASE_POLICY_INTERFACES  15
+#define DBASE_POLICY_BOOLEANS    16
+#define DBASE_POLICY_FCONTEXTS   17
+#define DBASE_POLICY_FCONTEXTS_H 18
+#define DBASE_POLICY_SEUSERS     19
+#define DBASE_POLICY_NODES       20
+#define DBASE_POLICY_IBPKEYS     21
+#define DBASE_POLICY_IBENDPORTS  22
 
 /* Active kernel policy */
-#define DBASE_ACTIVE_BOOLEANS    18
+#define DBASE_ACTIVE_BOOLEANS    23
 	dbase_config_t dbase[DBASE_COUNT];
 };
 
@@ -133,6 +138,18 @@ static inline
 	return &handle->dbase[DBASE_LOCAL_PORTS];
 }
 
+static inline
+    dbase_config_t * semanage_ibpkey_dbase_local(semanage_handle_t * handle)
+{
+	return &handle->dbase[DBASE_LOCAL_IBPKEYS];
+}
+
+static inline
+    dbase_config_t * semanage_ibendport_dbase_local(semanage_handle_t * handle)
+{
+	return &handle->dbase[DBASE_LOCAL_IBENDPORTS];
+}
+
 static inline
     dbase_config_t * semanage_iface_dbase_local(semanage_handle_t * handle)
 {
@@ -189,6 +206,18 @@ static inline
 	return &handle->dbase[DBASE_POLICY_PORTS];
 }
 
+static inline
+    dbase_config_t * semanage_ibpkey_dbase_policy(semanage_handle_t * handle)
+{
+	return &handle->dbase[DBASE_POLICY_IBPKEYS];
+}
+
+static inline
+    dbase_config_t * semanage_ibendport_dbase_policy(semanage_handle_t * handle)
+{
+	return &handle->dbase[DBASE_POLICY_IBENDPORTS];
+}
+
 static inline
     dbase_config_t * semanage_iface_dbase_policy(semanage_handle_t * handle)
 {
@@ -207,6 +236,12 @@ static inline
 	return &handle->dbase[DBASE_POLICY_FCONTEXTS];
 }
 
+static inline
+    dbase_config_t * semanage_fcontext_dbase_homedirs(semanage_handle_t * handle)
+{
+	return &handle->dbase[DBASE_POLICY_FCONTEXTS_H];
+}
+
 static inline
     dbase_config_t * semanage_seuser_dbase_policy(semanage_handle_t * handle)
 {
diff --git libsemanage-2.5/src/ibendport_internal.h libsemanage-2.5/src/ibendport_internal.h
new file mode 100644
index 0000000..970fbdb
--- /dev/null
+++ libsemanage-2.5/src/ibendport_internal.h
@@ -0,0 +1,48 @@
+#ifndef _SEMANAGE_IBENDPORT_INTERNAL_H_
+#define _SEMANAGE_IBENDPORT_INTERNAL_H_
+
+#include <semanage/ibendport_record.h>
+#include <semanage/ibendports_local.h>
+#include <semanage/ibendports_policy.h>
+#include "database.h"
+#include "handle.h"
+#include "dso.h"
+
+hidden_proto(semanage_ibendport_create)
+hidden_proto(semanage_ibendport_compare)
+hidden_proto(semanage_ibendport_compare2)
+hidden_proto(semanage_ibendport_clone)
+hidden_proto(semanage_ibendport_free)
+hidden_proto(semanage_ibendport_key_extract)
+hidden_proto(semanage_ibendport_key_free)
+hidden_proto(semanage_ibendport_get_port)
+hidden_proto(semanage_ibendport_set_port)
+hidden_proto(semanage_ibendport_get_con)
+hidden_proto(semanage_ibendport_set_con)
+hidden_proto(semanage_ibendport_list_local)
+hidden_proto(semanage_ibendport_get_ibdev_name)
+hidden_proto(semanage_ibendport_set_ibdev_name)
+
+/* IBENDPORT RECORD: method table */
+extern record_table_t SEMANAGE_IBENDPORT_RTABLE;
+
+extern int ibendport_file_dbase_init(semanage_handle_t *handle,
+				     const char *path_ro,
+				     const char *path_rw,
+				     dbase_config_t *dconfig);
+
+extern void ibendport_file_dbase_release(dbase_config_t *dconfig);
+
+extern int ibendport_policydb_dbase_init(semanage_handle_t *handle,
+					 dbase_config_t *dconfig);
+
+extern void ibendport_policydb_dbase_release(dbase_config_t *dconfig);
+
+extern int hidden semanage_ibendport_validate_local(semanage_handle_t *handle);
+
+/* ==== Internal (to ibendports) API === */
+
+hidden int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport,
+					     const semanage_ibendport_t **ibendport2);
+
+#endif
diff --git libsemanage-2.5/src/ibendport_record.c libsemanage-2.5/src/ibendport_record.c
new file mode 100644
index 0000000..955067e
--- /dev/null
+++ libsemanage-2.5/src/ibendport_record.c
@@ -0,0 +1,154 @@
+/*Copyright (C) 2005 Red Hat, Inc. */
+
+/*Object: semanage_ibendport_t (Infiniband Pkey)
+ *Object: semanage_ibendport_key_t (Infiniband Pkey Key)
+ *Implements: record_t (Database Record)
+ *Implements: record_key_t (Database Record Key)
+ */
+
+#include <sepol/context_record.h>
+#include <sepol/ibendport_record.h>
+
+typedef sepol_context_t semanage_context_t;
+typedef sepol_ibendport_t semanage_ibendport_t;
+typedef sepol_ibendport_key_t semanage_ibendport_key_t;
+#define _SEMANAGE_IBENDPORT_DEFINED_
+#define _SEMANAGE_CONTEXT_DEFINED_
+
+typedef semanage_ibendport_t record_t;
+typedef semanage_ibendport_key_t record_key_t;
+#define DBASE_RECORD_DEFINED
+
+#include "ibendport_internal.h"
+#include "handle.h"
+#include "database.h"
+
+int semanage_ibendport_compare(const semanage_ibendport_t *ibendport,
+			       const semanage_ibendport_key_t *key)
+{
+	return sepol_ibendport_compare(ibendport, key);
+}
+
+hidden_def(semanage_ibendport_compare)
+
+int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport,
+				const semanage_ibendport_t *ibendport2)
+{
+	return sepol_ibendport_compare2(ibendport, ibendport2);
+}
+
+hidden_def(semanage_ibendport_compare2)
+
+hidden int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport,
+					     const semanage_ibendport_t **ibendport2)
+{
+	return sepol_ibendport_compare2(*ibendport, *ibendport2);
+}
+
+int semanage_ibendport_key_create(semanage_handle_t *handle,
+				  const char *ibdev_name,
+				  int port,
+				  semanage_ibendport_key_t **key_ptr)
+{
+	return sepol_ibendport_key_create(handle->sepolh, ibdev_name, port, key_ptr);
+}
+
+int semanage_ibendport_key_extract(semanage_handle_t *handle,
+				   const semanage_ibendport_t *ibendport,
+				   semanage_ibendport_key_t **key_ptr)
+{
+	return sepol_ibendport_key_extract(handle->sepolh, ibendport, key_ptr);
+}
+
+hidden_def(semanage_ibendport_key_extract)
+
+void semanage_ibendport_key_free(semanage_ibendport_key_t *key)
+{
+	sepol_ibendport_key_free(key);
+}
+
+hidden_def(semanage_ibendport_key_free)
+
+int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle,
+				      const semanage_ibendport_t *ibendport,
+				      char **ibdev_name_ptr)
+{
+	return sepol_ibendport_get_ibdev_name(handle->sepolh, ibendport, ibdev_name_ptr);
+}
+
+hidden_def(semanage_ibendport_get_ibdev_name)
+
+int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle,
+				      semanage_ibendport_t *ibendport,
+				      const char *ibdev_name)
+{
+	return sepol_ibendport_set_ibdev_name(handle->sepolh, ibendport, ibdev_name);
+}
+
+hidden_def(semanage_ibendport_set_ibdev_name)
+
+int semanage_ibendport_get_port(const semanage_ibendport_t *ibendport)
+{
+	return sepol_ibendport_get_port(ibendport);
+}
+
+hidden_def(semanage_ibendport_get_port)
+
+void semanage_ibendport_set_port(semanage_ibendport_t *ibendport, int port)
+{
+	sepol_ibendport_set_port(ibendport, port);
+}
+
+hidden_def(semanage_ibendport_set_port)
+
+semanage_context_t *semanage_ibendport_get_con(const semanage_ibendport_t *ibendport)
+{
+	return sepol_ibendport_get_con(ibendport);
+}
+
+hidden_def(semanage_ibendport_get_con)
+
+int semanage_ibendport_set_con(semanage_handle_t *handle,
+			       semanage_ibendport_t *ibendport,
+			       semanage_context_t *con)
+{
+	return sepol_ibendport_set_con(handle->sepolh, ibendport, con);
+}
+
+hidden_def(semanage_ibendport_set_con)
+
+int semanage_ibendport_create(semanage_handle_t *handle,
+			      semanage_ibendport_t **ibendport_ptr)
+{
+	return sepol_ibendport_create(handle->sepolh, ibendport_ptr);
+}
+
+hidden_def(semanage_ibendport_create)
+
+int semanage_ibendport_clone(semanage_handle_t *handle,
+			     const semanage_ibendport_t *ibendport,
+			     semanage_ibendport_t **ibendport_ptr)
+{
+	return sepol_ibendport_clone(handle->sepolh, ibendport, ibendport_ptr);
+}
+
+hidden_def(semanage_ibendport_clone)
+
+void semanage_ibendport_free(semanage_ibendport_t *ibendport)
+{
+	sepol_ibendport_free(ibendport);
+}
+
+hidden_def(semanage_ibendport_free)
+
+/*key base functions */
+record_table_t SEMANAGE_IBENDPORT_RTABLE = {
+	.create = semanage_ibendport_create,
+	.key_extract = semanage_ibendport_key_extract,
+	.key_free = semanage_ibendport_key_free,
+	.clone = semanage_ibendport_clone,
+	.compare = semanage_ibendport_compare,
+	.compare2 = semanage_ibendport_compare2,
+	.compare2_qsort = semanage_ibendport_compare2_qsort,
+	.free = semanage_ibendport_free,
+};
diff --git libsemanage-2.5/src/ibendports_file.c libsemanage-2.5/src/ibendports_file.c
new file mode 100644
index 0000000..402c7a5
--- /dev/null
+++ libsemanage-2.5/src/ibendports_file.c
@@ -0,0 +1,157 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc. */
+
+struct semanage_ibendport;
+struct semanage_ibendport_key;
+typedef struct semanage_ibendport record_t;
+typedef struct semanage_ibendport_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "ibendport_internal.h"
+#include "context_internal.h"
+#include "database_file.h"
+#include "parse_utils.h"
+#include "debug.h"
+
+static int ibendport_print(semanage_handle_t *handle,
+			   semanage_ibendport_t *ibendport,
+			   FILE *str)
+{
+	char *con_str = NULL;
+	char *ibdev_name_str = NULL;
+	int port = semanage_ibendport_get_port(ibendport);
+
+	if (semanage_ibendport_get_ibdev_name(handle, ibendport, &ibdev_name_str) != 0)
+		goto err;
+
+	semanage_context_t *con = semanage_ibendport_get_con(ibendport);
+
+	if (fprintf(str, "ibendportcon %s ", ibdev_name_str) < 0)
+		goto err;
+
+	if (fprintf(str, "%d ", port) < 0)
+		goto err;
+
+	if (semanage_context_to_string(handle, con, &con_str) < 0)
+		goto err;
+	if (fprintf(str, "%s\n", con_str) < 0)
+		goto err;
+
+	free(ibdev_name_str);
+	free(con_str);
+	return STATUS_SUCCESS;
+
+err:
+	ERR(handle, "could not print ibendport (%s) %u to stream",
+	    ibdev_name_str, port);
+	free(ibdev_name_str);
+	free(con_str);
+	return STATUS_ERR;
+}
+
+static int ibendport_parse(semanage_handle_t *handle,
+			   parse_info_t *info,
+			   semanage_ibendport_t *ibendport)
+{
+	int port;
+	char *str = NULL;
+	semanage_context_t *con = NULL;
+
+	if (parse_skip_space(handle, info) < 0)
+		goto err;
+	if (!info->ptr)
+		goto last;
+
+	/* Header */
+	if (parse_assert_str(handle, info, "ibendportcon") < 0)
+		goto err;
+	if (parse_assert_space(handle, info) < 0)
+		goto err;
+
+	/* IB Device Name */
+	if (parse_fetch_string(handle, info, &str, ' ') < 0)
+		goto err;
+	if (semanage_ibendport_set_ibdev_name(handle, ibendport, str) < 0)
+		goto err;
+	free(str);
+	str = NULL;
+
+	/* Port */
+	if (parse_assert_space(handle, info) < 0)
+		goto err;
+	if (parse_fetch_int(handle, info, &port, ' ') < 0)
+		goto err;
+	semanage_ibendport_set_port(ibendport, port);
+
+	/* context */
+	if (parse_assert_space(handle, info) < 0)
+		goto err;
+	if (parse_fetch_string(handle, info, &str, ' ') < 0)
+		goto err;
+	if (semanage_context_from_string(handle, str, &con) < 0) {
+		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
+		    str, info->filename, info->lineno, info->orig_line);
+		goto err;
+	}
+	if (!con) {
+		ERR(handle, "<<none>> context is not valid for ibendport (%s: %u):\n%s",
+		    info->filename, info->lineno, info->orig_line);
+		goto err;
+	}
+	free(str);
+	str = NULL;
+
+	if (semanage_ibendport_set_con(handle, ibendport, con) < 0)
+		goto err;
+
+	if (parse_assert_space(handle, info) < 0)
+		goto err;
+
+	semanage_context_free(con);
+	return STATUS_SUCCESS;
+
+last:
+	parse_dispose_line(info);
+	return STATUS_NODATA;
+
+err:
+	ERR(handle, "could not parse ibendport record");
+	free(str);
+	semanage_context_free(con);
+	parse_dispose_line(info);
+	return STATUS_ERR;
+}
+
+/* IBENDPORT RECORD: FILE extension: method table */
+record_file_table_t SEMANAGE_IBENDPORT_FILE_RTABLE = {
+	.parse = ibendport_parse,
+	.print = ibendport_print,
+};
+
+int ibendport_file_dbase_init(semanage_handle_t *handle,
+			      const char *path_ro,
+			      const char *path_rw,
+			      dbase_config_t *dconfig)
+{
+	if (dbase_file_init(handle,
+			    path_ro,
+			    path_rw,
+			    &SEMANAGE_IBENDPORT_RTABLE,
+			    &SEMANAGE_IBENDPORT_FILE_RTABLE, &dconfig->dbase) < 0)
+		return STATUS_ERR;
+
+	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
+	return STATUS_SUCCESS;
+}
+
+void ibendport_file_dbase_release(dbase_config_t *dconfig)
+{
+	dbase_file_release(dconfig->dbase);
+}
diff --git libsemanage-2.5/src/ibendports_local.c libsemanage-2.5/src/ibendports_local.c
new file mode 100644
index 0000000..8b5567d
--- /dev/null
+++ libsemanage-2.5/src/ibendports_local.c
@@ -0,0 +1,153 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc */
+
+struct semanage_ibendport;
+struct semanage_ibendport_key;
+typedef struct semanage_ibendport_key record_key_t;
+typedef struct semanage_ibendport record_t;
+#define DBASE_RECORD_DEFINED
+
+#include <stdlib.h>
+#include <string.h>
+#include <sepol/policydb.h>
+#include "ibendport_internal.h"
+#include "debug.h"
+#include "handle.h"
+#include "database.h"
+
+int semanage_ibendport_modify_local(semanage_handle_t *handle,
+				    const semanage_ibendport_key_t *key,
+				    const semanage_ibendport_t *data)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
+
+	return dbase_modify(handle, dconfig, key, data);
+}
+
+int semanage_ibendport_del_local(semanage_handle_t *handle,
+				 const semanage_ibendport_key_t *key)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
+
+	return dbase_del(handle, dconfig, key);
+}
+
+int semanage_ibendport_query_local(semanage_handle_t *handle,
+				   const semanage_ibendport_key_t *key,
+				   semanage_ibendport_t **response)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
+
+	return dbase_query(handle, dconfig, key, response);
+}
+
+int semanage_ibendport_exists_local(semanage_handle_t *handle,
+				    const semanage_ibendport_key_t *key,
+				    int *response)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
+
+	return dbase_exists(handle, dconfig, key, response);
+}
+
+int semanage_ibendport_count_local(semanage_handle_t *handle,
+				   unsigned int *response)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
+
+	return dbase_count(handle, dconfig, response);
+}
+
+int semanage_ibendport_iterate_local(semanage_handle_t *handle,
+				     int (*handler)(const semanage_ibendport_t *record,
+						    void *varg), void *handler_arg)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
+	return dbase_iterate(handle, dconfig, handler, handler_arg);
+}
+
+int semanage_ibendport_list_local(semanage_handle_t *handle,
+				  semanage_ibendport_t ***records,
+				  unsigned int *count)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle);
+
+	return dbase_list(handle, dconfig, records, count);
+}
+
+hidden_def(semanage_ibendport_list_local)
+
+int hidden semanage_ibendport_validate_local(semanage_handle_t *handle)
+{
+	semanage_ibendport_t **ibendports = NULL;
+	unsigned int nibendports = 0;
+	unsigned int i = 0, j = 0;
+	char *ibdev_name;
+	char *ibdev_name2;
+	int port;
+	int port2;
+
+	/* List and sort the ibendports */
+	if (semanage_ibendport_list_local(handle, &ibendports, &nibendports) < 0)
+		goto err;
+
+	qsort(ibendports, nibendports, sizeof(semanage_ibendport_t *),
+	      (int (*)(const void *, const void *))
+	      &semanage_ibendport_compare2_qsort);
+
+	/* Test each ibendport */
+	while (i < nibendports) {
+		int stop = 0;
+
+		if (STATUS_SUCCESS !=
+				semanage_ibendport_get_ibdev_name(handle,
+								  ibendports[i],
+								  &ibdev_name)) {
+			ERR(handle, "Couldn't get IB device name");
+			goto err;
+		}
+
+		port = semanage_ibendport_get_port(ibendports[i]);
+
+		/* Find the first ibendport with matching
+		 * ibdev_name to compare against
+		 */
+		do {
+			if (j == nibendports - 1)
+				goto next;
+			j++;
+			if (STATUS_SUCCESS !=
+				semanage_ibendport_get_ibdev_name(handle,
+								  ibendports[j],
+								  &ibdev_name2)) {
+				ERR(handle, "Couldn't get IB device name.");
+				goto err;
+			}
+			port2 = semanage_ibendport_get_port(ibendports[j]);
+
+			stop = !strcmp(ibdev_name, ibdev_name2);
+		} while (!stop);
+
+		if (port == port2) {
+			ERR(handle, "ibendport %s/%u already exists.",
+			    ibdev_name2, port2);
+			goto invalid;
+		}
+next:
+		i++;
+		j = i;
+	}
+
+	for (i = 0; i < nibendports; i++)
+		semanage_ibendport_free(ibendports[i]);
+	free(ibendports);
+	return STATUS_SUCCESS;
+
+err:
+	ERR(handle, "could not complete ibendports validity check");
+
+invalid:
+	for (i = 0; i < nibendports; i++)
+		semanage_ibendport_free(ibendports[i]);
+	free(ibendports);
+	return STATUS_ERR;
+}
diff --git libsemanage-2.5/src/ibendports_policy.c libsemanage-2.5/src/ibendports_policy.c
new file mode 100644
index 0000000..1347b67
--- /dev/null
+++ libsemanage-2.5/src/ibendports_policy.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc */
+
+struct semanage_ibendport;
+struct semanage_ibendport_key;
+typedef struct semanage_ibendport_key record_key_t;
+typedef struct semanage_ibendport record_t;
+#define DBASE_RECORD_DEFINED
+
+#include "ibendport_internal.h"
+#include "handle.h"
+#include "database.h"
+
+int semanage_ibendport_query(semanage_handle_t *handle,
+			     const semanage_ibendport_key_t *key,
+			     semanage_ibendport_t **response)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle);
+
+	return dbase_query(handle, dconfig, key, response);
+}
+
+int semanage_ibendport_exists(semanage_handle_t *handle,
+			      const semanage_ibendport_key_t *key,
+			      int *response)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle);
+
+	return dbase_exists(handle, dconfig, key, response);
+}
+
+int semanage_ibendport_count(semanage_handle_t *handle,
+			     unsigned int *response)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle);
+
+	return dbase_count(handle, dconfig, response);
+}
+
+int semanage_ibendport_iterate(semanage_handle_t *handle,
+			       int (*handler)(const semanage_ibendport_t *record,
+					      void *varg), void *handler_arg)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle);
+
+	return dbase_iterate(handle, dconfig, handler, handler_arg);
+}
+
+int semanage_ibendport_list(semanage_handle_t *handle,
+			    semanage_ibendport_t ***records,
+			    unsigned int *count)
+{
+	dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle);
+
+	return dbase_list(handle, dconfig, records, count);
+}
diff --git libsemanage-2.5/src/ibendports_policydb.c libsemanage-2.5/src/ibendports_policydb.c
new file mode 100644
index 0000000..1029810
--- /dev/null
+++ libsemanage-2.5/src/ibendports_policydb.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 Mellanox Technologies 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.
+ */
+
+struct semanage_ibendport;
+struct semanage_ibendport_key;
+typedef struct semanage_ibendport record_t;
+typedef struct semanage_ibendport_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_policydb;
+typedef struct dbase_policydb dbase_t;
+#define DBASE_DEFINED
+
+#include <sepol/ibendports.h>
+#include <semanage/handle.h>
+#include "ibendport_internal.h"
+#include "debug.h"
+#include "database_policydb.h"
+#include "semanage_store.h"
+
+/* IBENDPORT RECORD (SEPOL): POLICYDB extension : method table */
+record_policydb_table_t SEMANAGE_IBENDPORT_POLICYDB_RTABLE = {
+	.add = NULL,
+	.modify = (record_policydb_table_modify_t)sepol_ibendport_modify,
+	.set = NULL,
+	.query = (record_policydb_table_query_t)sepol_ibendport_query,
+	.count = (record_policydb_table_count_t)sepol_ibendport_count,
+	.exists = (record_policydb_table_exists_t)sepol_ibendport_exists,
+	.iterate = (record_policydb_table_iterate_t)sepol_ibendport_iterate,
+};
+
+int ibendport_policydb_dbase_init(semanage_handle_t *handle,
+				  dbase_config_t *dconfig)
+{
+	if (dbase_policydb_init(handle,
+				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
+				&SEMANAGE_IBENDPORT_RTABLE,
+				&SEMANAGE_IBENDPORT_POLICYDB_RTABLE,
+				&dconfig->dbase) < 0)
+		return STATUS_ERR;
+
+	dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE;
+
+	return STATUS_SUCCESS;
+}
+
+void ibendport_policydb_dbase_release(dbase_config_t *dconfig)
+{
+	dbase_policydb_release(dconfig->dbase);
+}
diff --git libsemanage-2.5/src/ibpkey_internal.h libsemanage-2.5/src/ibpkey_internal.h
new file mode 100644
index 0000000..9465bb8
--- /dev/null
+++ libsemanage-2.5/src/ibpkey_internal.h
@@ -0,0 +1,52 @@
+#ifndef _SEMANAGE_IBPKEY_INTERNAL_H_
+#define _SEMANAGE_IBPKEY_INTERNAL_H_
+
+#include <semanage/ibpkey_record.h>
+#include <semanage/ibpkeys_local.h>
+#include <semanage/ibpkeys_policy.h>
+#include "database.h"
+#include "handle.h"
+#include "dso.h"
+
+hidden_proto(semanage_ibpkey_create)
+hidden_proto(semanage_ibpkey_compare)
+hidden_proto(semanage_ibpkey_compare2)
+hidden_proto(semanage_ibpkey_clone)
+hidden_proto(semanage_ibpkey_free)
+hidden_proto(semanage_ibpkey_key_extract)
+hidden_proto(semanage_ibpkey_key_free)
+hidden_proto(semanage_ibpkey_get_high)
+hidden_proto(semanage_ibpkey_get_low)
+hidden_proto(semanage_ibpkey_set_pkey)
+hidden_proto(semanage_ibpkey_set_range)
+hidden_proto(semanage_ibpkey_get_con)
+hidden_proto(semanage_ibpkey_set_con)
+hidden_proto(semanage_ibpkey_list_local)
+hidden_proto(semanage_ibpkey_get_subnet_prefix)
+hidden_proto(semanage_ibpkey_get_subnet_prefix_bytes)
+hidden_proto(semanage_ibpkey_set_subnet_prefix)
+hidden_proto(semanage_ibpkey_set_subnet_prefix_bytes)
+
+/* PKEY RECORD: method table */
+extern record_table_t SEMANAGE_IBPKEY_RTABLE;
+
+extern int ibpkey_file_dbase_init(semanage_handle_t *handle,
+				  const char *path_ro,
+				  const char *path_rw,
+				  dbase_config_t *dconfig);
+
+extern void ibpkey_file_dbase_release(dbase_config_t *dconfig);
+
+extern int ibpkey_policydb_dbase_init(semanage_handle_t *handle,
+				      dbase_config_t *dconfig);
+
+extern void ibpkey_policydb_dbase_release(dbase_config_t *dconfig);
+
+extern int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle);
+
+/* ==== Internal (to ibpkeys) API === */
+
+hidden int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey,
+					  const semanage_ibpkey_t **ibpkey2);
+
+#endif
diff --git libsemanage-2.5/src/ibpkey_record.c libsemanage-2.5/src/ibpkey_record.c
new file mode 100644
index 0000000..ca5bc76
--- /dev/null
+++ libsemanage-2.5/src/ibpkey_record.c
@@ -0,0 +1,182 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc. */
+
+/* Object: semanage_ibpkey_t (Infiniband Pkey)
+ * Object: semanage_ibpkey_key_t (Infiniband Pkey Key)
+ * Implements: record_t (Database Record)
+ * Implements: record_key_t (Database Record Key)
+ */
+
+#include <sepol/context_record.h>
+#include <sepol/ibpkey_record.h>
+
+typedef sepol_context_t semanage_context_t;
+typedef sepol_ibpkey_t semanage_ibpkey_t;
+typedef sepol_ibpkey_key_t semanage_ibpkey_key_t;
+#define _SEMANAGE_IBPKEY_DEFINED_
+#define _SEMANAGE_CONTEXT_DEFINED_
+
+typedef semanage_ibpkey_t record_t;
+typedef semanage_ibpkey_key_t record_key_t;
+#define DBASE_RECORD_DEFINED
+
+#include "ibpkey_internal.h"
+#include "handle.h"
+#include "database.h"
+
+int semanage_ibpkey_compare(const semanage_ibpkey_t *ibpkey,
+			    const semanage_ibpkey_key_t *key)
+{
+	return sepol_ibpkey_compare(ibpkey, key);
+}
+
+hidden_def(semanage_ibpkey_compare)
+
+int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey,
+			     const semanage_ibpkey_t *ibpkey2)
+{
+	return sepol_ibpkey_compare2(ibpkey, ibpkey2);
+}
+
+hidden_def(semanage_ibpkey_compare2)
+
+hidden int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey,
+					  const semanage_ibpkey_t **ibpkey2)
+{
+	return sepol_ibpkey_compare2(*ibpkey, *ibpkey2);
+}
+
+int semanage_ibpkey_key_create(semanage_handle_t *handle,
+			       const char *subnet_prefix,
+			       int low, int high,
+			       semanage_ibpkey_key_t **key_ptr)
+{
+	return sepol_ibpkey_key_create(handle->sepolh, subnet_prefix, low, high, key_ptr);
+}
+
+int semanage_ibpkey_key_extract(semanage_handle_t *handle,
+				const semanage_ibpkey_t *ibpkey,
+				semanage_ibpkey_key_t **key_ptr)
+{
+	return sepol_ibpkey_key_extract(handle->sepolh, ibpkey, key_ptr);
+}
+
+hidden_def(semanage_ibpkey_key_extract)
+
+void semanage_ibpkey_key_free(semanage_ibpkey_key_t *key)
+{
+	sepol_ibpkey_key_free(key);
+}
+
+hidden_def(semanage_ibpkey_key_free)
+
+int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle,
+				      const semanage_ibpkey_t *ibpkey,
+				      char **subnet_prefix_ptr)
+{
+	return sepol_ibpkey_get_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix_ptr);
+}
+
+hidden_def(semanage_ibpkey_get_subnet_prefix)
+
+uint64_t semanage_ibpkey_get_subnet_prefix_bytes(const semanage_ibpkey_t *ibpkey)
+{
+	return sepol_ibpkey_get_subnet_prefix_bytes(ibpkey);
+}
+
+hidden_def(semanage_ibpkey_get_subnet_prefix_bytes)
+
+int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle,
+				      semanage_ibpkey_t *ibpkey,
+				      const char *subnet_prefix)
+{
+	return sepol_ibpkey_set_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix);
+}
+
+hidden_def(semanage_ibpkey_set_subnet_prefix)
+
+void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey,
+					     uint64_t subnet_prefix)
+{
+	return sepol_ibpkey_set_subnet_prefix_bytes(ibpkey, subnet_prefix);
+}
+
+hidden_def(semanage_ibpkey_set_subnet_prefix_bytes)
+
+int semanage_ibpkey_get_low(const semanage_ibpkey_t *ibpkey)
+{
+	return sepol_ibpkey_get_low(ibpkey);
+}
+
+hidden_def(semanage_ibpkey_get_low)
+
+int semanage_ibpkey_get_high(const semanage_ibpkey_t *ibpkey)
+{
+	return sepol_ibpkey_get_high(ibpkey);
+}
+
+hidden_def(semanage_ibpkey_get_high)
+
+void semanage_ibpkey_set_pkey(semanage_ibpkey_t *ibpkey, int ibpkey_num)
+{
+	sepol_ibpkey_set_pkey(ibpkey, ibpkey_num);
+}
+
+hidden_def(semanage_ibpkey_set_pkey)
+
+void semanage_ibpkey_set_range(semanage_ibpkey_t *ibpkey, int low, int high)
+{
+	sepol_ibpkey_set_range(ibpkey, low, high);
+}
+
+hidden_def(semanage_ibpkey_set_range)
+
+semanage_context_t *semanage_ibpkey_get_con(const semanage_ibpkey_t *ibpkey)
+{
+	return sepol_ibpkey_get_con(ibpkey);
+}
+
+hidden_def(semanage_ibpkey_get_con)
+
+int semanage_ibpkey_set_con(semanage_handle_t *handle,
+			    semanage_ibpkey_t *ibpkey, semanage_context_t *con)
+{
+	return sepol_ibpkey_set_con(handle->sepolh, ibpkey, con);
+}
+
+hidden_def(semanage_ibpkey_set_con)
+
+int semanage_ibpkey_create(semanage_handle_t *handle,
+			   semanage_ibpkey_t **ibpkey_ptr)
+{
+	return sepol_ibpkey_create(handle->sepolh, ibpkey_ptr);
+}
+
+hidden_def(semanage_ibpkey_create)
+
+int semanage_ibpkey_clone(semanage_handle_t *handle,
+			  const semanage_ibpkey_t *ibpkey,
+			  semanage_ibpkey_t **ibpkey_ptr)
+{
+	return sepol_ibpkey_clone(handle->sepolh, ibpkey, ibpkey_ptr);
+}
+
+hidden_def(semanage_ibpkey_clone)
+
+void semanage_ibpkey_free(semanage_ibpkey_t *ibpkey)
+{
+	sepol_ibpkey_free(ibpkey);
+}
+
+hidden_def(semanage_ibpkey_free)
+
+/* key base functions */
+record_table_t SEMANAGE_IBPKEY_RTABLE = {
+	.create = semanage_ibpkey_create,
+	.key_extract = semanage_ibpkey_key_extract,
+	.key_free = semanage_ibpkey_key_free,
+	.clone = semanage_ibpkey_clone,
+	.compare = semanage_ibpkey_compare,
+	.compare2 = semanage_ibpkey_compare2,
+	.compare2_qsort = semanage_ibpkey_compare2_qsort,
+	.free = semanage_ibpkey_free,
+};
diff --git libsemanage-2.5/src/ibpkeys_file.c libsemanage-2.5/src/ibpkeys_file.c
new file mode 100644
index 0000000..ceaea7a
--- /dev/null
+++ libsemanage-2.5/src/ibpkeys_file.c
@@ -0,0 +1,181 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc. */
+
+struct semanage_ibpkey;
+struct semanage_ibpkey_key;
+typedef struct semanage_ibpkey record_t;
+typedef struct semanage_ibpkey_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_file;
+typedef struct dbase_file dbase_t;
+#define DBASE_DEFINED
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <semanage/handle.h>
+#include "ibpkey_internal.h"
+#include "context_internal.h"
+#include "database_file.h"
+#include "parse_utils.h"
+#include "debug.h"
+
+static int ibpkey_print(semanage_handle_t *handle,
+			semanage_ibpkey_t *ibpkey, FILE *str)
+{
+	char *con_str = NULL;
+	char *subnet_prefix_str = NULL;
+
+	int low = semanage_ibpkey_get_low(ibpkey);
+	int high = semanage_ibpkey_get_high(ibpkey);
+
+	if (semanage_ibpkey_get_subnet_prefix(handle, ibpkey, &subnet_prefix_str) != 0)
+		goto err;
+
+	semanage_context_t *con = semanage_ibpkey_get_con(ibpkey);
+
+	if (fprintf(str, "ibpkeycon %s ", subnet_prefix_str) < 0)
+		goto err;
+
+	if (low == high) {
+		if (fprintf(str, "%d ", low) < 0)
+			goto err;
+	} else {
+		if (fprintf(str, "%d - %d ", low, high) < 0)
+			goto err;
+	}
+
+	if (semanage_context_to_string(handle, con, &con_str) < 0)
+		goto err;
+	if (fprintf(str, "%s\n", con_str) < 0)
+		goto err;
+
+	free(subnet_prefix_str);
+	free(con_str);
+	return STATUS_SUCCESS;
+
+err:
+	ERR(handle, "could not print ibpkey range (%s) %u - %u to stream",
+	    subnet_prefix_str, low, high);
+	free(subnet_prefix_str);
+	free(con_str);
+	return STATUS_ERR;
+}
+
+static int ibpkey_parse(semanage_handle_t *handle,
+			parse_info_t *info, semanage_ibpkey_t *ibpkey)
+{
+	int low, high;
+	char *str = NULL;
+	semanage_context_t *con = NULL;
+
+	if (parse_skip_space(handle, info) < 0)
+		goto err;
+	if (!info->ptr)
+		goto last;
+
+	/* Header */
+	if (parse_assert_str(handle, info, "ibpkeycon") < 0)
+		goto err;
+	if (parse_assert_space(handle, info) < 0)
+		goto err;
+
+	/* Subnet Prefix */
+	if (parse_fetch_string(handle, info, &str, ' ') < 0)
+		goto err;
+	if (semanage_ibpkey_set_subnet_prefix(handle, ibpkey, str) < 0)
+		goto err;
+	free(str);
+	str = NULL;
+
+	/* Range/Pkey */
+	if (parse_assert_space(handle, info) < 0)
+		goto err;
+	if (parse_fetch_int(handle, info, &low, '-') < 0)
+		goto err;
+
+	/* If range (-) does not follow immediately, require a space
+	 * In other words, the space here is optional, but only
+	 * in the ranged case, not in the single ibpkey case,
+	 * so do a custom test
+	 */
+	if (*info->ptr && *info->ptr != '-') {
+		if (parse_assert_space(handle, info) < 0)
+			goto err;
+	}
+
+	if (parse_optional_ch(info, '-') != STATUS_NODATA) {
+		if (parse_skip_space(handle, info) < 0)
+			goto err;
+		if (parse_fetch_int(handle, info, &high, ' ') < 0)
+			goto err;
+		if (parse_assert_space(handle, info) < 0)
+			goto err;
+		semanage_ibpkey_set_range(ibpkey, low, high);
+	} else {
+		semanage_ibpkey_set_pkey(ibpkey, low);
+	}
+	/* Pkey context */
+	if (parse_fetch_string(handle, info, &str, ' ') < 0)
+		goto err;
+	if (semanage_context_from_string(handle, str, &con) < 0) {
+		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
+		    str, info->filename, info->lineno, info->orig_line);
+		goto err;
+	}
+	if (!con) {
+		ERR(handle, "<<none>> context is not valid for ibpkeys (%s: %u):\n%s",
+		    info->filename,
+		    info->lineno, info->orig_line);
+		goto err;
+	}
+	free(str);
+	str = NULL;
+
+	if (semanage_ibpkey_set_con(handle, ibpkey, con) < 0)
+		goto err;
+
+	if (parse_assert_space(handle, info) < 0)
+		goto err;
+
+	semanage_context_free(con);
+	return STATUS_SUCCESS;
+
+last:
+	parse_dispose_line(info);
+	return STATUS_NODATA;
+
+err:
+	ERR(handle, "could not parse ibpkey record");
+	free(str);
+	semanage_context_free(con);
+	parse_dispose_line(info);
+	return STATUS_ERR;
+}
+
+/* IBPKEY RECORD: FILE extension: method table */
+record_file_table_t SEMANAGE_IBPKEY_FILE_RTABLE = {
+	.parse = ibpkey_parse,
+	.print = ibpkey_print,
+};
+
+int ibpkey_file_dbase_init(semanage_handle_t *handle,
+			   const char *path_ro,
+			   const char *path_rw,
+			   dbase_config_t *dconfig)
+{
+	if (dbase_file_init(handle,
+			    path_ro,
+			    path_rw,
+			    &SEMANAGE_IBPKEY_RTABLE,
+			    &SEMANAGE_IBPKEY_FILE_RTABLE, &dconfig->dbase) < 0)
+		return STATUS_ERR;
+
+	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
+	return STATUS_SUCCESS;
+}
+
+void ibpkey_file_dbase_release(dbase_config_t *dconfig)
+{
+	dbase_file_release(dconfig->dbase);
+}
diff --git libsemanage-2.5/src/ibpkeys_local.c libsemanage-2.5/src/ibpkeys_local.c
new file mode 100644
index 0000000..e194ee0
--- /dev/null
+++ libsemanage-2.5/src/ibpkeys_local.c
@@ -0,0 +1,164 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc. */
+
+struct semanage_ibpkey;
+struct semanage_ibpkey_key;
+typedef struct semanage_ibpkey_key record_key_t;
+typedef struct semanage_ibpkey record_t;
+#define DBASE_RECORD_DEFINED
+
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include "ibpkey_internal.h"
+#include "debug.h"
+#include "handle.h"
+#include "database.h"
+
+int semanage_ibpkey_modify_local(semanage_handle_t *handle,
+				 const semanage_ibpkey_key_t *key,
+				 const semanage_ibpkey_t *data)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
+
+	return dbase_modify(handle, dconfig, key, data);
+}
+
+int semanage_ibpkey_del_local(semanage_handle_t *handle,
+			      const semanage_ibpkey_key_t *key)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
+
+	return dbase_del(handle, dconfig, key);
+}
+
+int semanage_ibpkey_query_local(semanage_handle_t *handle,
+				const semanage_ibpkey_key_t *key,
+				semanage_ibpkey_t **response)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
+
+	return dbase_query(handle, dconfig, key, response);
+}
+
+int semanage_ibpkey_exists_local(semanage_handle_t *handle,
+				 const semanage_ibpkey_key_t *key,
+				 int *response)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
+
+	return dbase_exists(handle, dconfig, key, response);
+}
+
+int semanage_ibpkey_count_local(semanage_handle_t *handle,
+				unsigned int *response)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
+
+	return dbase_count(handle, dconfig, response);
+}
+
+int semanage_ibpkey_iterate_local(semanage_handle_t *handle,
+				  int (*handler)(const semanage_ibpkey_t *record,
+						 void *varg), void *handler_arg)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
+
+	return dbase_iterate(handle, dconfig, handler, handler_arg);
+}
+
+int semanage_ibpkey_list_local(semanage_handle_t *handle,
+			       semanage_ibpkey_t ***records, unsigned int *count)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle);
+
+	return dbase_list(handle, dconfig, records, count);
+}
+
+hidden_def(semanage_ibpkey_list_local)
+
+int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle)
+{
+	semanage_ibpkey_t **ibpkeys = NULL;
+	unsigned int nibpkeys = 0;
+	unsigned int i = 0, j = 0;
+	uint64_t subnet_prefix;
+	uint64_t subnet_prefix2;
+	char *subnet_prefix_str;
+	char *subnet_prefix_str2;
+	int low, high;
+	int low2, high2;
+
+	/* List and sort the ibpkeys */
+	if (semanage_ibpkey_list_local(handle, &ibpkeys, &nibpkeys) < 0)
+		goto err;
+
+	qsort(ibpkeys, nibpkeys, sizeof(semanage_ibpkey_t *),
+	      (int (*)(const void *, const void *))
+	      &semanage_ibpkey_compare2_qsort);
+
+	/* Test each ibpkey for overlap */
+	while (i < nibpkeys) {
+		if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle,
+									ibpkeys[i],
+									&subnet_prefix_str)) {
+			ERR(handle, "Couldn't get subnet prefix string");
+			goto err;
+		}
+
+		subnet_prefix = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[i]);
+		low = semanage_ibpkey_get_low(ibpkeys[i]);
+		high = semanage_ibpkey_get_high(ibpkeys[i]);
+
+		/* Find the first ibpkey with matching
+		 * subnet_prefix to compare against
+		 */
+		do {
+			if (j == nibpkeys - 1)
+				goto next;
+			j++;
+
+			if (STATUS_SUCCESS !=
+				semanage_ibpkey_get_subnet_prefix(handle,
+								  ibpkeys[j],
+								  &subnet_prefix_str2)) {
+				ERR(handle, "Couldn't get subnet prefix string");
+				goto err;
+			}
+			subnet_prefix2 = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[j]);
+			low2 = semanage_ibpkey_get_low(ibpkeys[j]);
+			high2 = semanage_ibpkey_get_high(ibpkeys[j]);
+		} while (subnet_prefix != subnet_prefix2);
+
+		/* Overlap detected */
+		if (low2 <= high) {
+			ERR(handle, "ibpkey overlap between ranges "
+			    "(%s) %u - %u <--> (%s) %u - %u.",
+			    subnet_prefix_str, low, high,
+			    subnet_prefix_str2, low2, high2);
+			goto invalid;
+		}
+
+		/* If closest ibpkey of matching subnet prefix doesn't overlap
+		 * with test ibpkey, neither do the rest of them, because that's
+		 * how the sort function works on ibpkeys - lower bound
+		 * ibpkeys come first
+		 */
+next:
+		i++;
+		j = i;
+	}
+
+	for (i = 0; i < nibpkeys; i++)
+		semanage_ibpkey_free(ibpkeys[i]);
+	free(ibpkeys);
+	return STATUS_SUCCESS;
+
+err:
+	ERR(handle, "could not complete ibpkeys validity check");
+
+invalid:
+	for (i = 0; i < nibpkeys; i++)
+		semanage_ibpkey_free(ibpkeys[i]);
+	free(ibpkeys);
+	return STATUS_ERR;
+}
diff --git libsemanage-2.5/src/ibpkeys_policy.c libsemanage-2.5/src/ibpkeys_policy.c
new file mode 100644
index 0000000..0956230
--- /dev/null
+++ libsemanage-2.5/src/ibpkeys_policy.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2017 Mellanox Technologies Inc. */
+
+struct semanage_ibpkey;
+struct semanage_ibpkey_key;
+typedef struct semanage_ibpkey_key record_key_t;
+typedef struct semanage_ibpkey record_t;
+#define DBASE_RECORD_DEFINED
+
+#include "ibpkey_internal.h"
+#include "handle.h"
+#include "database.h"
+
+int semanage_ibpkey_query(semanage_handle_t *handle,
+			  const semanage_ibpkey_key_t *key,
+			  semanage_ibpkey_t **response)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle);
+
+	return dbase_query(handle, dconfig, key, response);
+}
+
+int semanage_ibpkey_exists(semanage_handle_t *handle,
+			   const semanage_ibpkey_key_t *key, int *response)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle);
+
+	return dbase_exists(handle, dconfig, key, response);
+}
+
+int semanage_ibpkey_count(semanage_handle_t *handle, unsigned int *response)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle);
+
+	return dbase_count(handle, dconfig, response);
+}
+
+int semanage_ibpkey_iterate(semanage_handle_t *handle,
+			    int (*handler)(const semanage_ibpkey_t *record,
+					   void *varg), void *handler_arg)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle);
+
+	return dbase_iterate(handle, dconfig, handler, handler_arg);
+}
+
+int semanage_ibpkey_list(semanage_handle_t *handle,
+			 semanage_ibpkey_t ***records, unsigned int *count)
+{
+	dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle);
+
+	return dbase_list(handle, dconfig, records, count);
+}
diff --git libsemanage-2.5/src/ibpkeys_policydb.c libsemanage-2.5/src/ibpkeys_policydb.c
new file mode 100644
index 0000000..8d73cf6
--- /dev/null
+++ libsemanage-2.5/src/ibpkeys_policydb.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 Mellanox Technologies 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.
+ */
+
+struct semanage_ibpkey;
+struct semanage_ibpkey_key;
+typedef struct semanage_ibpkey record_t;
+typedef struct semanage_ibpkey_key record_key_t;
+#define DBASE_RECORD_DEFINED
+
+struct dbase_policydb;
+typedef struct dbase_policydb dbase_t;
+#define DBASE_DEFINED
+
+#include <sepol/ibpkeys.h>
+#include <semanage/handle.h>
+#include "ibpkey_internal.h"
+#include "debug.h"
+#include "database_policydb.h"
+#include "semanage_store.h"
+
+/* PKEY RECORD (SEPOL): POLICYDB extension : method table */
+record_policydb_table_t SEMANAGE_IBPKEY_POLICYDB_RTABLE = {
+	.add = NULL,
+	.modify = (record_policydb_table_modify_t)sepol_ibpkey_modify,
+	.set = NULL,
+	.query = (record_policydb_table_query_t)sepol_ibpkey_query,
+	.count = (record_policydb_table_count_t)sepol_ibpkey_count,
+	.exists = (record_policydb_table_exists_t)sepol_ibpkey_exists,
+	.iterate = (record_policydb_table_iterate_t)sepol_ibpkey_iterate,
+};
+
+int ibpkey_policydb_dbase_init(semanage_handle_t *handle,
+			       dbase_config_t *dconfig)
+{
+	if (dbase_policydb_init(handle,
+				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
+				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
+				&SEMANAGE_IBPKEY_RTABLE,
+				&SEMANAGE_IBPKEY_POLICYDB_RTABLE,
+				&dconfig->dbase) < 0)
+		return STATUS_ERR;
+
+	dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE;
+
+	return STATUS_SUCCESS;
+}
+
+void ibpkey_policydb_dbase_release(dbase_config_t *dconfig)
+{
+	dbase_policydb_release(dconfig->dbase);
+}
diff --git libsemanage-2.5/src/libsemanage.map libsemanage-2.5/src/libsemanage.map
index 34b553d..ce5b34f 100644
--- libsemanage-2.5/src/libsemanage.map
+++ libsemanage-2.5/src/libsemanage.map
@@ -18,6 +18,8 @@ LIBSEMANAGE_1.0 {
 	  semanage_root;
 	  semanage_user_*; semanage_bool_*; semanage_seuser_*;
 	  semanage_iface_*; semanage_port_*; semanage_context_*;
+	  semanage_ibpkey_*;
+	  semanage_ibendport_*;
 	  semanage_node_*;
 	  semanage_fcontext_*; semanage_access_check; semanage_set_create_store;
 	  semanage_is_connected; semanage_get_disable_dontaudit; semanage_set_disable_dontaudit;
@@ -40,10 +42,12 @@ LIBSEMANAGE_1.1 {
 	  semanage_module_info_destroy;
 	  semanage_module_info_get_priority;
 	  semanage_module_info_get_name;
+	  semanage_module_info_get_version;
 	  semanage_module_info_get_lang_ext;
 	  semanage_module_info_get_enabled;
 	  semanage_module_info_set_priority;
 	  semanage_module_info_set_name;
+	  semanage_module_info_set_version;
 	  semanage_module_info_set_lang_ext;
 	  semanage_module_info_set_enabled;
 	  semanage_module_key_create;
diff --git libsemanage-2.5/src/module_internal.h libsemanage-2.5/src/module_internal.h
index c99f6c2..d62091a 100644
--- libsemanage-2.5/src/module_internal.h
+++ libsemanage-2.5/src/module_internal.h
@@ -11,10 +11,12 @@ hidden_proto(semanage_module_get_name)
     hidden_proto(semanage_module_info_destroy)
     hidden_proto(semanage_module_info_get_priority)
     hidden_proto(semanage_module_info_get_name)
+    hidden_proto(semanage_module_info_get_version)
     hidden_proto(semanage_module_info_get_lang_ext)
     hidden_proto(semanage_module_info_get_enabled)
     hidden_proto(semanage_module_info_set_priority)
     hidden_proto(semanage_module_info_set_name)
+    hidden_proto(semanage_module_info_set_version)
     hidden_proto(semanage_module_info_set_lang_ext)
     hidden_proto(semanage_module_info_set_enabled)
     hidden_proto(semanage_module_key_create)
diff --git libsemanage-2.5/src/modules.c libsemanage-2.5/src/modules.c
index 90c5e49..85285a1 100644
--- libsemanage-2.5/src/modules.c
+++ libsemanage-2.5/src/modules.c
@@ -291,6 +291,7 @@ int semanage_module_info_destroy(semanage_handle_t *sh,
 	}
 
 	free(modinfo->name);
+	free(modinfo->module_version);
 	free(modinfo->lang_ext);
 
 	return semanage_module_info_init(sh, modinfo);
@@ -306,6 +307,7 @@ int semanage_module_info_init(semanage_handle_t *sh,
 
 	modinfo->priority = 0;
 	modinfo->name = NULL;
+	modinfo->module_version = NULL;
 	modinfo->lang_ext = NULL;
 	modinfo->enabled = -1;
 
@@ -341,6 +343,14 @@ int semanage_module_info_clone(semanage_handle_t *sh,
 		goto cleanup;
 	}
 
+	if (source->module_version != NULL) {
+		ret = semanage_module_info_set_version(sh, target, source->module_version);
+		if (ret != 0) {
+			status = -1;
+			goto cleanup;
+		}
+	}
+
 	ret = semanage_module_info_set_lang_ext(sh, target, source->lang_ext);
 	if (ret != 0) {
 		status = -1;
@@ -388,6 +398,21 @@ int semanage_module_info_get_name(semanage_handle_t *sh,
 
 hidden_def(semanage_module_info_get_name)
 
+int semanage_module_info_get_version(semanage_handle_t *sh,
+				  semanage_module_info_t *modinfo,
+				  const char **version)
+{
+	assert(sh);
+	assert(modinfo);
+	assert(version);
+
+	*version = modinfo->module_version;
+
+	return 0;
+}
+
+hidden_def(semanage_module_info_get_version)
+
 int semanage_module_info_get_lang_ext(semanage_handle_t *sh,
 				      semanage_module_info_t *modinfo,
 				      const char **lang_ext)
@@ -470,6 +495,37 @@ int semanage_module_info_set_name(semanage_handle_t *sh,
 
 hidden_def(semanage_module_info_set_name)
 
+int semanage_module_info_set_version(semanage_handle_t *sh,
+                                    semanage_module_info_t *modinfo,
+                                    const char *version)
+{
+       assert(sh);
+       assert(modinfo);
+       assert(version);
+
+       char * tmp;
+
+       /* Verify version */
+
+       if (semanage_module_validate_version(version) < 0) {
+               errno = 0;
+               return -1;
+       }
+
+       tmp = strdup(version);
+       if (!tmp) {
+               return -1;
+       }
+
+       free(modinfo->module_version);
+       modinfo->module_version = tmp;
+
+       return 0;
+}
+
+hidden_def(semanage_module_info_set_version)
+
+
 int semanage_module_info_set_lang_ext(semanage_handle_t *sh,
 				      semanage_module_info_t *modinfo,
 				      const char *lang_ext)
@@ -1064,6 +1120,49 @@ exit:
 	return status;
 }
 
+/* Validate version.
+ *
+ * A version must match the following regular expression to be
+ * considered valid:
+ *
+ * ^[:print:]+$
+ *
+ * returns 0 if version is valid, returns -1 otherwise.
+ */
+int semanage_module_validate_version(const char *version)
+{
+	int status = 0;
+
+	if (version == NULL) {
+		status = -1;
+		goto exit;
+	}
+
+	/* must start with a printable char */
+	if (!isprint(*version)) {
+		status = -1;
+		goto exit;
+	}
+
+	/* everything else must be printable */
+#define ISVALIDCHAR(c) (isprint(c))
+
+	for (version++; *version; version++) {
+		if (ISVALIDCHAR(*version)) {
+			continue;
+		}
+		status = -1;
+		goto exit;
+	}
+
+#undef ISVALIDCHAR
+
+exit:
+	return status;
+}
+
+
+
 int semanage_module_get_module_info(semanage_handle_t *sh,
 				    const semanage_module_key_t *modkey,
 				    semanage_module_info_t **modinfo)
diff --git libsemanage-2.5/src/modules.h libsemanage-2.5/src/modules.h
index 8a5c01f..ee3d51d 100644
--- libsemanage-2.5/src/modules.h
+++ libsemanage-2.5/src/modules.h
@@ -44,6 +44,7 @@ struct semanage_module_info {
 	uint16_t priority;	/* key, module priority */
 	char *name;		/* key, module name */
 	char *lang_ext;		/* module source language extension */
+	char *module_version;	/* module version, applies only for pp modules  */
 	int enabled;		/* module enabled/disabled status */
 };
 
diff --git libsemanage-2.5/src/policy_components.c libsemanage-2.5/src/policy_components.c
index d31bd48..896ac51 100644
--- libsemanage-2.5/src/policy_components.c
+++ libsemanage-2.5/src/policy_components.c
@@ -137,12 +137,17 @@ int semanage_base_merge_components(semanage_handle_t * handle)
 
 		{semanage_node_dbase_local(handle),
 		 semanage_node_dbase_policy(handle), MODE_MODIFY | MODE_SORT},
+
+		{semanage_ibpkey_dbase_local(handle),
+		 semanage_ibpkey_dbase_policy(handle), MODE_MODIFY},
+
+		{semanage_ibendport_dbase_local(handle),
+		 semanage_ibendport_dbase_policy(handle), MODE_MODIFY},
 	};
 	const unsigned int CCOUNT = sizeof(components) / sizeof(components[0]);
 
 	/* Merge components into policy (and validate) */
 	for (i = 0; i < CCOUNT; i++) {
-
 		record_t **records = NULL;
 		unsigned int nrecords = 0;
 
@@ -218,6 +223,8 @@ int semanage_commit_components(semanage_handle_t * handle)
 		semanage_seuser_dbase_policy(handle),
 		semanage_bool_dbase_active(handle),
 		semanage_node_dbase_local(handle),
+		semanage_ibpkey_dbase_local(handle),
+		semanage_ibendport_dbase_local(handle),
 	};
 	const int CCOUNT = sizeof(components) / sizeof(components[0]);
 
diff --git libsemanage-2.5/src/semanage_store.c libsemanage-2.5/src/semanage_store.c
index fa0876f..c13b763 100644
--- libsemanage-2.5/src/semanage_store.c
+++ libsemanage-2.5/src/semanage_store.c
@@ -95,23 +95,28 @@ static const char *semanage_store_paths[SEMANAGE_NUM_STORES] = {
 static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
 	"",
 	"/modules",
-	"/base.linked",
+	"/policy.linked",
 	"/homedir_template",
 	"/file_contexts.template",
 	"/commit_num",
+	"/pkeys.local",
+	"/ibendports.local",
 	"/ports.local",
 	"/interfaces.local",
 	"/nodes.local",
 	"/booleans.local",
 	"/seusers.local",
+	"/seusers.linked",
 	"/users.local",
 	"/users_extra.local",
+	"/users_extra.linked",
 	"/users_extra",
 	"/disable_dontaudit",
 	"/preserve_tunables",
 	"/modules/disabled",
 	"/policy.kern",
 	"/file_contexts.local",
+	"/file_contexts.homedirs",
 	"/file_contexts",
 	"/seusers"
 };
@@ -292,6 +297,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh)
 		goto cleanup;
 	}
 
+	if (asprintf(&semanage_final_suffix[SEMANAGE_FC_BIN], "%s.bin",
+		     semanage_final_suffix[SEMANAGE_FC]) < 0) {
+		ERR(sh, "Unable to allocate space for file context path.");
+		status = -1;
+		goto cleanup;
+	}
+
 	semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] =
 		strdup(selinux_file_context_homedir_path() + offset);
 	if (semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] == NULL) {
@@ -300,6 +312,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh)
 		goto cleanup;
 	}
 
+	if (asprintf(&semanage_final_suffix[SEMANAGE_FC_HOMEDIRS_BIN], "%s.bin",
+		     semanage_final_suffix[SEMANAGE_FC_HOMEDIRS]) < 0) {
+		ERR(sh, "Unable to allocate space for file context home directory path.");
+		status = -1;
+		goto cleanup;
+	}
+
 	semanage_final_suffix[SEMANAGE_FC_LOCAL] =
 		strdup(selinux_file_context_local_path() + offset);
 	if (semanage_final_suffix[SEMANAGE_FC_LOCAL] == NULL) {
@@ -308,6 +327,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh)
 		goto cleanup;
 	}
 
+	if (asprintf(&semanage_final_suffix[SEMANAGE_FC_LOCAL_BIN], "%s.bin",
+		     semanage_final_suffix[SEMANAGE_FC_LOCAL]) < 0) {
+		ERR(sh, "Unable to allocate space for local file context path.");
+		status = -1;
+		goto cleanup;
+	}
+
 	semanage_final_suffix[SEMANAGE_NC] =
 		strdup(selinux_netfilter_context_path() + offset);
 	if (semanage_final_suffix[SEMANAGE_NC] == NULL) {
@@ -512,7 +538,6 @@ char *semanage_conf_path(void)
 int semanage_create_store(semanage_handle_t * sh, int create)
 {
 	struct stat sb;
-	int mode_mask = R_OK | W_OK | X_OK;
 	const char *path = semanage_files[SEMANAGE_ROOT];
 	int fd;
 
@@ -531,9 +556,9 @@ int semanage_create_store(semanage_handle_t * sh, int create)
 			return -1;
 		}
 	} else {
-		if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) {
+		if (!S_ISDIR(sb.st_mode)) {
 			ERR(sh,
-			    "Could not access module store at %s, or it is not a directory.",
+			    "Module store at %s is not a directory.",
 			    path);
 			return -1;
 		}
@@ -554,9 +579,9 @@ int semanage_create_store(semanage_handle_t * sh, int create)
 			return -1;
 		}
 	} else {
-		if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) {
+		if (!S_ISDIR(sb.st_mode)) {
 			ERR(sh,
-			    "Could not access module store active subdirectory at %s, or it is not a directory.",
+			    "Module store active subdirectory at %s is not a directory.",
 			    path);
 			return -1;
 		}
@@ -577,9 +602,9 @@ int semanage_create_store(semanage_handle_t * sh, int create)
 			return -1;
 		}
 	} else {
-		if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) {
+		if (!S_ISDIR(sb.st_mode)) {
 			ERR(sh,
-			    "Could not access module store active modules subdirectory at %s, or it is not a directory.",
+			    "Module store active modules subdirectory at %s is not a directory.",
 			    path);
 			return -1;
 		}
@@ -598,8 +623,8 @@ int semanage_create_store(semanage_handle_t * sh, int create)
 			return -1;
 		}
 	} else {
-		if (!S_ISREG(sb.st_mode) || access(path, R_OK | W_OK) == -1) {
-			ERR(sh, "Could not access lock file at %s.", path);
+		if (!S_ISREG(sb.st_mode)) {
+			ERR(sh, "Lock file at %s missing.", path);
 			return -1;
 		}
 	}
@@ -1137,7 +1162,7 @@ cleanup:
 	free(all_modinfos);
 
 	if (status != 0) {
-		for (i = 0; i < j; j++) {
+		for (i = 0; i < j; i++) {
 			semanage_module_info_destroy(sh, &(*modinfo)[i]);
 		}
 		free(*modinfo);
@@ -1491,6 +1516,45 @@ static int sefcontext_compile(semanage_handle_t * sh, const char *path) {
 	return 0;
 }
 
+static int semanage_validate_and_compile_fcontexts(semanage_handle_t * sh)
+{
+	int status = -1;
+
+	if (sh->do_check_contexts) {
+		int ret;
+		ret = semanage_exec_prog(
+			sh,
+			sh->conf->setfiles,
+			semanage_final_path(SEMANAGE_FINAL_TMP,
+					    SEMANAGE_KERNEL),
+			semanage_final_path(SEMANAGE_FINAL_TMP,
+					    SEMANAGE_FC));
+		if (ret != 0) {
+			ERR(sh, "setfiles returned error code %d.", ret);
+			goto cleanup;
+		}
+	}
+
+	if (sefcontext_compile(sh,
+		    semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)) != 0) {
+		goto cleanup;
+	}
+
+	if (sefcontext_compile(sh,
+		    semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL)) != 0) {
+		goto cleanup;
+	}
+
+	if (sefcontext_compile(sh,
+		    semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS)) != 0) {
+		goto cleanup;
+	}
+
+	status = 0;
+cleanup:
+	return status;
+}
+
 /* Load the contexts of the final tmp into the final selinux directory.
  * Return 0 on success, -3 on error.
  */
@@ -1566,35 +1630,6 @@ static int semanage_install_final_tmp(semanage_handle_t * sh)
 	}
 
 skip_reload:
-	if (sh->do_check_contexts) {
-		ret = semanage_exec_prog(
-			sh,
-			sh->conf->setfiles,
-			semanage_final_path(SEMANAGE_FINAL_SELINUX,
-					    SEMANAGE_KERNEL),
-			semanage_final_path(SEMANAGE_FINAL_SELINUX,
-					    SEMANAGE_FC));
-		if (ret != 0) {
-			ERR(sh, "setfiles returned error code %d.", ret);
-			goto cleanup;
-		}
-	}
-
-	if (sefcontext_compile(sh,
-		    semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC)) != 0) {
-		goto cleanup;
-	}
-
-	if (sefcontext_compile(sh,
-		    semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_LOCAL)) != 0) {
-		goto cleanup;
-	}
-
-	if (sefcontext_compile(sh,
-		    semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_HOMEDIRS)) != 0) {
-		goto cleanup;
-	}
-
 	status = 0;
 cleanup:
 	return status;
@@ -1737,6 +1772,9 @@ int semanage_install_sandbox(semanage_handle_t * sh)
 		goto cleanup;
 	}
 
+	if (semanage_validate_and_compile_fcontexts(sh) < 0)
+		goto cleanup;
+
 	if ((commit_num = semanage_commit_sandbox(sh)) < 0) {
 		retval = commit_num;
 		goto cleanup;
@@ -2003,9 +2041,10 @@ int semanage_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filename
  */
 
 /**
- * Read the policy from the sandbox (kernel)
+ * Read the policy from the sandbox (linked or kernel)
  */
-int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in)
+int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in,
+			   enum semanage_sandbox_defs file)
 {
 
 	int retval = STATUS_ERR;
@@ -2014,7 +2053,7 @@ int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in)
 	FILE *infile = NULL;
 
 	if ((kernel_filename =
-	     semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL)) == NULL) {
+	     semanage_path(SEMANAGE_ACTIVE, file)) == NULL) {
 		goto cleanup;
 	}
 	if ((infile = fopen(kernel_filename, "r")) == NULL) {
@@ -2044,18 +2083,20 @@ int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in)
 	return retval;
 }
 /**
- * Writes the final policy to the sandbox (kernel)
+ * Writes the policy to the sandbox (linked or kernel)
  */
-int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out)
+int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out,
+			    enum semanage_sandbox_defs file)
 {
 
 	int retval = STATUS_ERR;
 	const char *kernel_filename = NULL;
 	struct sepol_policy_file *pf = NULL;
 	FILE *outfile = NULL;
+	mode_t mask = umask(0077);
 
 	if ((kernel_filename =
-	     semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL)) == NULL) {
+	     semanage_path(SEMANAGE_TMP, file)) == NULL) {
 		goto cleanup;
 	}
 	if ((outfile = fopen(kernel_filename, "wb")) == NULL) {
@@ -2081,6 +2122,7 @@ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out)
 	if (outfile != NULL) {
 		fclose(outfile);
 	}
+	umask(mask);
 	sepol_policy_file_free(pf);
 	return retval;
 }
diff --git libsemanage-2.5/src/semanage_store.h libsemanage-2.5/src/semanage_store.h
index acb6e3f..34bf852 100644
--- libsemanage-2.5/src/semanage_store.h
+++ libsemanage-2.5/src/semanage_store.h
@@ -44,19 +44,24 @@ enum semanage_sandbox_defs {
 	SEMANAGE_HOMEDIR_TMPL,
 	SEMANAGE_FC_TMPL,
 	SEMANAGE_COMMIT_NUM_FILE,
+	SEMANAGE_IBPKEYS_LOCAL,
+	SEMANAGE_IBENDPORTS_LOCAL,
 	SEMANAGE_PORTS_LOCAL,
 	SEMANAGE_INTERFACES_LOCAL,
 	SEMANAGE_NODES_LOCAL,
 	SEMANAGE_BOOLEANS_LOCAL,
 	SEMANAGE_SEUSERS_LOCAL,
+	SEMANAGE_SEUSERS_LINKED,
 	SEMANAGE_USERS_BASE_LOCAL,
 	SEMANAGE_USERS_EXTRA_LOCAL,
+	SEMANAGE_USERS_EXTRA_LINKED,
 	SEMANAGE_USERS_EXTRA,
 	SEMANAGE_DISABLE_DONTAUDIT,
 	SEMANAGE_PRESERVE_TUNABLES,
 	SEMANAGE_MODULES_DISABLED,
 	SEMANAGE_STORE_KERNEL,
 	SEMANAGE_STORE_FC_LOCAL,
+	SEMANAGE_STORE_FC_HOMEDIRS,
 	SEMANAGE_STORE_FC,
 	SEMANAGE_STORE_SEUSERS,
 	SEMANAGE_STORE_NUM_PATHS
@@ -71,8 +76,11 @@ enum semanage_final_defs {
 enum semanage_final_path_defs {
 	SEMANAGE_FINAL_TOPLEVEL,
 	SEMANAGE_FC,
+	SEMANAGE_FC_BIN,
 	SEMANAGE_FC_HOMEDIRS,
+	SEMANAGE_FC_HOMEDIRS_BIN,
 	SEMANAGE_FC_LOCAL,
+	SEMANAGE_FC_LOCAL_BIN,
 	SEMANAGE_KERNEL,
 	SEMANAGE_NC,
 	SEMANAGE_SEUSERS,
@@ -126,10 +134,12 @@ int semanage_load_files(semanage_handle_t * sh,
 			    cil_db_t *cildb, char **filenames, int num_modules);
 
 int semanage_read_policydb(semanage_handle_t * sh,
-			    sepol_policydb_t * policydb);
+			   sepol_policydb_t * policydb,
+			   enum semanage_sandbox_defs file);
 
 int semanage_write_policydb(semanage_handle_t * sh,
-			    sepol_policydb_t * policydb);
+			    sepol_policydb_t * policydb,
+			    enum semanage_sandbox_defs file);
 
 int semanage_install_sandbox(semanage_handle_t * sh);
 
diff --git libsemanage-2.5/src/semanageswig.i libsemanage-2.5/src/semanageswig.i
index 583b7d8..ebf39cf 100644
--- libsemanage-2.5/src/semanageswig.i
+++ libsemanage-2.5/src/semanageswig.i
@@ -39,6 +39,12 @@
 %include "../include/semanage/port_record.h"
 %include "../include/semanage/ports_local.h"
 %include "../include/semanage/ports_policy.h"
+%include "../include/semanage/ibpkey_record.h"
+%include "../include/semanage/ibpkeys_local.h"
+%include "../include/semanage/ibpkeys_policy.h"
+%include "../include/semanage/ibendport_record.h"
+%include "../include/semanage/ibendports_local.h"
+%include "../include/semanage/ibendports_policy.h"
 %include "../include/semanage/fcontext_record.h"
 %include "../include/semanage/fcontexts_local.h"
 %include "../include/semanage/fcontexts_policy.h"
diff --git libsemanage-2.5/src/semanageswig_python.i libsemanage-2.5/src/semanageswig_python.i
index 1346b2e..8604b8a 100644
--- libsemanage-2.5/src/semanageswig_python.i
+++ libsemanage-2.5/src/semanageswig_python.i
@@ -437,6 +437,92 @@
 	$1 = &temp;
 }
 
+/** ibpkey typemaps **/
+
+/* the wrapper will setup this parameter for passing... the resulting python functions
+   will not take the semanage_ibpkey_t *** parameter */
+%typemap(in, numinputs=0) semanage_ibpkey_t ***(semanage_ibpkey_t **temp=NULL) {
+	$1 = &temp;
+}
+
+%typemap(argout) (
+	semanage_handle_t* handle,
+	semanage_ibpkey_t*** records,
+	unsigned int* count) {
+
+	if ($result) {
+		int value;
+		SWIG_AsVal_int($result, &value);
+		if (value >= 0) {
+			PyObject* plist = NULL;
+			if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_ibpkey,
+				(void (*) (void*)) &semanage_ibpkey_free, &plist) < 0)
+				$result = SWIG_From_int(STATUS_ERR);
+			else
+				$result = SWIG_Python_AppendOutput($result, plist);
+		}
+	}
+}
+
+%typemap(in, numinputs=0) semanage_ibpkey_t **(semanage_ibpkey_t *temp=NULL) {
+	$1 = &temp;
+}
+
+%typemap(argout) semanage_ibpkey_t ** {
+	$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
+}
+
+%typemap(argout) semanage_ibpkey_key_t ** {
+	$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
+}
+
+%typemap(in, numinputs=0) semanage_ibpkey_key_t **(semanage_ibpkey_key_t *temp=NULL) {
+	$1 = &temp;
+}
+
+/** ibendport typemaps **/
+
+/* the wrapper will setup this parameter for passing... the resulting python functions
+   will not take the semanage_ibendport_t *** parameter */
+%typemap(in, numinputs=0) semanage_ibendport_t ***(semanage_ibendport_t **temp=NULL) {
+	$1 = &temp;
+}
+
+%typemap(argout) (
+	semanage_handle_t* handle,
+	semanage_ibendport_t*** records,
+	unsigned int* count) {
+
+	if ($result) {
+		int value;
+		SWIG_AsVal_int($result, &value);
+		if (value >= 0) {
+			PyObject* plist = NULL;
+			if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_ibendport,
+				(void (*) (void*)) &semanage_ibendport_free, &plist) < 0)
+				$result = SWIG_From_int(STATUS_ERR);
+			else
+				$result = SWIG_Python_AppendOutput($result, plist);
+		}
+	}
+}
+
+%typemap(in, numinputs=0) semanage_ibendport_t **(semanage_ibendport_t *temp=NULL) {
+	$1 = &temp;
+}
+
+%typemap(argout) semanage_ibendport_t ** {
+	$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
+}
+
+%typemap(argout) semanage_ibendport_key_t ** {
+	$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
+}
+
+%typemap(in, numinputs=0) semanage_ibendport_key_t **(semanage_ibendport_key_t *temp=NULL) {
+	$1 = &temp;
+}
+
 /** node typemaps **/
 
 /* the wrapper will setup this parameter for passing... the resulting python functions
diff --git libsemanage-2.5/tests/.gitignore libsemanage-2.5/tests/.gitignore
new file mode 100644
index 0000000..f07111d
--- /dev/null
+++ libsemanage-2.5/tests/.gitignore
@@ -0,0 +1 @@
+libsemanage-tests
diff --git libsemanage-2.5/utils/semanage_migrate_store libsemanage-2.5/utils/semanage_migrate_store
index 0ebd285..fe6b5a9 100755
--- libsemanage-2.5/utils/semanage_migrate_store
+++ libsemanage-2.5/utils/semanage_migrate_store
@@ -218,7 +218,7 @@ if __name__ == "__main__":
 	parser.add_option("-n", "--norebuild", dest="norebuild", action="store_true", default=False,
 			  help="Disable rebuilding policy after migration (default: no)")
 	parser.add_option("-P", "--path", dest="path",
-			  help="Set path for the policy store (default: /var/lib/selinux)")
+			  help="Set path for the policy store (default: /etc/selinux)")
 	parser.add_option("-r", "--root", dest="root",
 			  help="Set an alternative root for the migration (default: /)")
 
@@ -231,7 +231,7 @@ if __name__ == "__main__":
 	NOREBUILD = options.norebuild
 	PATH = options.path
 	if PATH is None:
-		PATH = "/var/lib/selinux"
+		PATH = "/etc/selinux"
 
 	ROOT = options.root
 	if ROOT is None:
@@ -253,7 +253,9 @@ if __name__ == "__main__":
 		"preserve_tunables",
 		"policy.kern",
 		"file_contexts",
-		"homedir_template"]
+		"homedir_template",
+                "pkeys.local",
+                "ibendports.local"]
 
 
 	create_dir(newroot_path(), 0o755)