Hello community,

here is the log from the commit of package libsemanage for openSUSE:Factory 
checked in at 2017-12-06 08:46:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libsemanage (Old)
 and      /work/SRC/openSUSE:Factory/.libsemanage.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libsemanage"

Wed Dec  6 08:46:44 2017 rev:42 rq:545898 version:2.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/libsemanage/libsemanage.changes  2016-12-17 
09:45:48.895045418 +0100
+++ /work/SRC/openSUSE:Factory/.libsemanage.new/libsemanage.changes     
2017-12-06 08:46:45.598968171 +0100
@@ -1,0 +2,15 @@
+Fri Nov 24 09:14:13 UTC 2017 - [email protected]
+
+- Update to version 2.6. Notable changes:
+  * genhomedircon: do not suppress logging from libsepol
+  * genhomedircon: use userprefix as the role for homedir
+  * Fix bug preventing the installation of base modules
+  * Use pp module name instead of filename when installing module
+  * genhomedircon: remove hardcoded refpolicy strings
+  * genhomedircon: add support for %group syntax
+  * genhomedircon: generate contexts for logins mapped to the default user
+  * Validate and compile file contexts before installing
+  * Swap tcp and udp protocol numbers
+  * genhomedircon: %{USERID} and %{USERNAME} support and code cleanups
+
+-------------------------------------------------------------------
python-semanage.changes: same change

Old:
----
  libsemanage-2.5.tar.gz

New:
----
  libsemanage-2.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libsemanage.spec ++++++
--- /var/tmp/diff_new_pack.ZWyhZr/_old  2017-12-06 08:46:46.586931999 +0100
+++ /var/tmp/diff_new_pack.ZWyhZr/_new  2017-12-06 08:46:46.590931852 +0100
@@ -17,13 +17,13 @@
 
 
 Name:           libsemanage
-Version:        2.5
+Version:        2.6
 Release:        0
 Summary:        SELinux policy management library
 License:        LGPL-2.1+
 Group:          Development/Libraries/C and C++
 Url:            https://github.com/SELinuxProject/selinux/wiki/Releases
-Source:         
https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20160223/%{name}-%{version}.tar.gz
+Source:         
https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20161014/%{name}-%{version}.tar.gz
 Source1:        baselibs.conf
 Source2:        semanage.conf
 Patch0:         suse_path.patch

++++++ python-semanage.spec ++++++
--- /var/tmp/diff_new_pack.ZWyhZr/_old  2017-12-06 08:46:46.610931120 +0100
+++ /var/tmp/diff_new_pack.ZWyhZr/_new  2017-12-06 08:46:46.614930973 +0100
@@ -18,13 +18,13 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-semanage
-Version:        2.5
+Version:        2.6
 Release:        0
 Summary:        Python bindings for SELinux's policy management library
 License:        LGPL-2.1
 Group:          Development/Languages/Python
 Url:            https://github.com/SELinuxProject/selinux
-Source:         
https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20160223/libsemanage-%{version}.tar.gz
+Source:         
https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20161014/libsemanage-%{version}.tar.gz
 Source1:        baselibs.conf
 Patch0:         suse_path.patch
 BuildRequires:  %{python_module devel}

++++++ libsemanage-2.5.tar.gz -> libsemanage-2.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/ChangeLog 
new/libsemanage-2.6/ChangeLog
--- old/libsemanage-2.5/ChangeLog       2016-02-23 17:31:41.000000000 +0100
+++ new/libsemanage-2.6/ChangeLog       2016-10-14 17:31:26.000000000 +0200
@@ -1,3 +1,23 @@
+2.6 2016-10-14
+       * genhomedircon: do not suppress logging from libsepol, from Stephen 
Smaley.
+       * genhomedircon: use userprefix as the role for homedir, from Gary 
Tierney.
+       * Fix linker scripts / map files, from Stephen Smalley.
+       * Fix bug preventing the installation of base modules, from James 
Carter.
+       * make distclean target work, from Nicolas Iooss.
+       * Do not always print a module name warning, from Miroslav Grepl.
+       * Use pp module name instead of filename when installing module, from 
Petr Lautrbach.
+       * tests: Do not force using gcc, from Nicolas Iooss.
+       * genhomedircon: remove hardcoded refpolicy strings, from Gary Tierney.
+       * 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/VERSION new/libsemanage-2.6/VERSION
--- old/libsemanage-2.5/VERSION 2016-02-23 17:31:41.000000000 +0100
+++ new/libsemanage-2.6/VERSION 2016-10-14 17:31:26.000000000 +0200
@@ -1 +1 @@
-2.5
+2.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/include/semanage/handle.h 
new/libsemanage-2.6/include/semanage/handle.h
--- old/libsemanage-2.5/include/semanage/handle.h       2016-02-23 
17:31:41.000000000 +0100
+++ new/libsemanage-2.6/include/semanage/handle.h       2016-10-14 
17:31:26.000000000 +0200
@@ -130,7 +130,7 @@
 #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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/Makefile 
new/libsemanage-2.6/src/Makefile
--- old/libsemanage-2.5/src/Makefile    2016-02-23 17:31:41.000000000 +0100
+++ new/libsemanage-2.6/src/Makefile    2016-10-14 17:31:26.000000000 +0200
@@ -5,6 +5,7 @@
 PYPREFIX ?= $(notdir $(PYTHON))
 RUBY ?= ruby
 RUBYPREFIX ?= $(notdir $(RUBY))
+PKG_CONFIG ?= pkg-config
 
 # Installation directories.
 PREFIX ?= $(DESTDIR)/usr
@@ -12,11 +13,11 @@
 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))
@@ -50,8 +51,8 @@
 SWIGRUBYSO=$(RUBYPREFIX)_semanage.so
 LIBSO=$(TARGET).$(LIBVERSION)
 
-GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i
-SRCS= $(filter-out $(GENERATED),$(wildcard *.c))
+GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i 
$(wildcard conf-*.[ch])
+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,14 +62,12 @@
                -Wno-unused-parameter
 
 override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE 
-RANLIB=ranlib
+RANLIB ?= ranlib
 
 SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./
 
 SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./
 
-GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) $(wildcard conf-*.[ch])
-
 all: $(LIBA) $(LIBSO) $(LIBPC)
 
 pywrap: all $(SWIGSO)
@@ -162,7 +161,7 @@
        -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) 
$(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~
 
 distclean: clean
-       rm -f $(SWIGCOUT) $(SWIGFILES)
+       rm -f $(GENERATED) $(SWIGFILES)
 
 indent:
        ../../scripts/Lindent $(filter-out $(GENERATED),$(wildcard *.[ch]))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/database.h 
new/libsemanage-2.6/src/database.h
--- old/libsemanage-2.5/src/database.h  2016-02-23 17:31:41.000000000 +0100
+++ new/libsemanage-2.6/src/database.h  2016-10-14 17:31:26.000000000 +0200
@@ -148,7 +148,7 @@
         * 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/direct_api.c 
new/libsemanage-2.6/src/direct_api.c
--- old/libsemanage-2.5/src/direct_api.c        2016-02-23 17:31:41.000000000 
+0100
+++ new/libsemanage-2.6/src/direct_api.c        2016-10-14 17:31:26.000000000 
+0200
@@ -363,6 +363,35 @@
 
 /********************* 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>
@@ -1524,7 +1553,9 @@
        char *path = NULL;
        char *filename;
        char *lang_ext = NULL;
+       char *module_name = NULL;
        char *separator;
+       char *version = NULL;
 
        if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 
0) {
                ERR(sh, "Unable to read file %s\n", install_filename);
@@ -1564,10 +1595,29 @@
                lang_ext = separator + 1;
        }
 
-       retval = semanage_direct_install(sh, data, data_len, filename, 
lang_ext);
+       if (strcmp(lang_ext, "pp") == 0) {
+               retval = parse_module_headers(sh, data, data_len, &module_name, 
&version);
+               free(version);
+               if (retval != 0)
+                       goto cleanup;
+       }
+
+       if (module_name == NULL) {
+               module_name = strdup(filename);
+               if (module_name == NULL) {
+                       ERR(sh, "No memory available for module_name.\n");
+                       retval = -1;
+                       goto cleanup;
+               }
+       } else if (strcmp(module_name, filename) != 0) {
+               fprintf(stderr, "Warning: SELinux userspace will refer to the 
module from %s as %s rather than %s\n", install_filename, module_name, 
filename);
+       }
+
+       retval = semanage_direct_install(sh, data, data_len, module_name, 
lang_ext);
 
 cleanup:
        if (data_len > 0) munmap(data, data_len);
+       free(module_name);
        free(path);
 
        return retval;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/exception.sh 
new/libsemanage-2.6/src/exception.sh
--- old/libsemanage-2.5/src/exception.sh        2016-02-23 17:31:41.000000000 
+0100
+++ new/libsemanage-2.6/src/exception.sh        2016-10-14 17:31:26.000000000 
+0200
@@ -9,6 +9,6 @@
 }
 "
 }
-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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/genhomedircon.c 
new/libsemanage-2.6/src/genhomedircon.c
--- old/libsemanage-2.5/src/genhomedircon.c     2016-02-23 17:31:41.000000000 
+0100
+++ new/libsemanage-2.6/src/genhomedircon.c     2016-10-14 17:31:26.000000000 
+0200
@@ -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,37 +75,45 @@
    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"
-#define TEMPLATE_SEUSER "system_u"
-#define TEMPLATE_LEVEL "s0"
-
-#define FALLBACK_USER "user_u"
-#define FALLBACK_USER_PREFIX "user"
-#define FALLBACK_USER_LEVEL "s0"
+/* new names */
+#define TEMPLATE_USERNAME "%{USERNAME}"
+#define TEMPLATE_USERID "%{USERID}"
+
+#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;
+#define CONTEXT_NONE "<<none>>"
 
 typedef struct user_entry {
        char *name;
+       char *uid;
+       char *gid;
        char *sename;
        char *prefix;
        char *home;
        char *level;
+       char *login;
+       char *homedir_role;
        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;
 } replacement_pair_t;
@@ -168,6 +178,13 @@
        return 0;
 }
 
+static int prefix_is_homedir_role(const semanage_user_t *user,
+                                 const char *prefix)
+{
+       return strcmp(OBJECT_R, prefix) == 0 ||
+               semanage_user_has_role(user, prefix);
+}
+
 static semanage_list_t *default_shell_list(void)
 {
        semanage_list_t *list = NULL;
@@ -461,11 +478,29 @@
        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
@@ -538,33 +573,19 @@
        result = sepol_context_from_string(s->h_semanage->sepolh,
                                           ctx_str, &ctx_record);
        if (result == STATUS_SUCCESS && ctx_record != NULL) {
-               sepol_msg_set_callback(s->h_semanage->sepolh, NULL, NULL);
                result = sepol_context_check(s->h_semanage->sepolh,
                                             s->policydb, ctx_record);
-               sepol_msg_set_callback(s->h_semanage->sepolh,
-                                      semanage_msg_relay_handler, 
s->h_semanage);
                sepol_context_free(ctx_record);
        }
        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,59 +603,153 @@
        return STATUS_ERR;
 }
 
-static int write_home_root_context(genhomedircon_settings_t * s, FILE * out,
-                                  semanage_list_t * tpl, char *homedir)
+static int write_contexts(genhomedircon_settings_t *s, FILE *out,
+                         semanage_list_t *tpl, const replacement_pair_t *repl,
+                         const genhomedircon_user_entry_t *user)
 {
-       replacement_pair_t repl[] = {
-               {.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir},
-               {NULL, NULL}
-       };
        Ustr *line = USTR_NULL;
+       sepol_context_t *context = NULL;
+       char *new_context_str = NULL;
 
        for (; tpl; tpl = tpl->next) {
                line = replace_all(tpl->data, repl);
-               if (!line)
+               if (!line) {
+                       goto fail;
+               }
+
+               const char *old_context_str = extract_context(line);
+               if (!old_context_str) {
+                       goto fail;
+               }
+
+               if (strcmp(old_context_str, CONTEXT_NONE) == 0) {
+                       if (check_line(s, line) == STATUS_SUCCESS &&
+                           !ustr_io_putfileline(&line, out)) {
+                               goto fail;
+                       }
+
+                       continue;
+               }
+
+               sepol_handle_t *sepolh = s->h_semanage->sepolh;
+
+               if (sepol_context_from_string(sepolh, old_context_str,
+                                             &context) < 0) {
+                       goto fail;
+               }
+
+               if (sepol_context_set_user(sepolh, context, user->sename) < 0 ||
+                   sepol_context_set_mls(sepolh, context, user->level) < 0) {
                        goto fail;
+               }
+
+               if (user->homedir_role &&
+                   sepol_context_set_role(sepolh, context, user->homedir_role) 
< 0) {
+                       goto fail;
+               }
+
+               if (sepol_context_to_string(sepolh, context,
+                                           &new_context_str) < 0) {
+                       goto fail;
+               }
+
+               if (!ustr_replace_cstr(&line, old_context_str,
+                                      new_context_str, 1)) {
+                       goto fail;
+               }
+
                if (check_line(s, line) == STATUS_SUCCESS) {
-                       if (!ustr_io_putfileline(&line, out))
+                       if (!ustr_io_putfileline(&line, out)) {
                                goto fail;
+                       }
                }
+
                ustr_sc_free(&line);
+               sepol_context_free(context);
+               free(new_context_str);
        }
-       return STATUS_SUCCESS;
 
-      fail:
+       return STATUS_SUCCESS;
+fail:
        ustr_sc_free(&line);
+       sepol_context_free(context);
+       free(new_context_str);
        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_HOME_DIR,.replace_with = user->home},
+               {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix},
+               {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_contexts(s, out, tpl, repl, user);
+}
+
+static int write_home_root_context(genhomedircon_settings_t * s, FILE * out,
+                                  semanage_list_t * tpl, char *homedir)
+{
+       replacement_pair_t repl[] = {
+               {.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir},
+               {NULL, NULL}
+       };
+
+       return write_replacements(s, out, tpl, repl);
+}
+
+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},
+               {NULL, NULL}
+       };
+
+       return write_contexts(s, out, tpl, repl, user);
+}
+
 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},
                {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_contexts(s, out, tpl, repl, user);
+}
+
+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 +764,20 @@
 }
 
 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, const char *hd_role)
 {
        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;
+       char *homedir_role = NULL;
 
        temp = malloc(sizeof(genhomedircon_user_entry_t));
        if (!temp)
@@ -665,6 +785,12 @@
        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 +803,24 @@
        level = strdup(l);
        if (!level)
                goto cleanup;
+       lname = strdup(ln);
+       if (!lname)
+               goto cleanup;
+       if (hd_role) {
+               homedir_role = strdup(hd_role);
+               if (!homedir_role)
+                       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->homedir_role = homedir_role;
        temp->next = (*list);
        (*list) = temp;
 
@@ -690,10 +828,14 @@
 
       cleanup:
        free(name);
+       free(uid);
+       free(gid);
        free(sename);
        free(prefix);
        free(home);
        free(level);
+       free(lname);
+       free(homedir_role);
        free(temp);
        return STATUS_ERR;
 }
@@ -708,39 +850,17 @@
        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->homedir_role);
        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;
@@ -751,6 +871,7 @@
        const char *seuname = NULL;
        const char *prefix = NULL;
        const char *level = NULL;
+       const char *homedir_role = NULL;
        unsigned int i;
        int retval;
        int errors = 0;
@@ -775,17 +896,24 @@
                        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 (prefix_is_homedir_role(u, prefix)) {
+                               homedir_role = prefix;
                        }
 
-                       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, homedir_role) != 0)
                                errors = STATUS_ERR;
                        semanage_user_key_free(key);
                        if (u)
@@ -801,6 +929,207 @@
        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;
+       const char *homedir_role = 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;
+       }
+
+       if (prefix_is_homedir_role(user, prefix)) {
+               homedir_role = prefix;
+       }
+
+       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, homedir_role);
+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;
+
+       if (getgrnam_r(grname, &grstorage, grbuf,
+                       (size_t) grbuflen, &group) != 0) {
+               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 +1141,7 @@
        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 +1155,39 @@
                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 +1208,7 @@
 }
 
 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 +1221,11 @@
        }
 
        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 +1248,21 @@
 {
        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 +1286,19 @@
                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 +1306,31 @@
                                                    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 +1338,7 @@
 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);
@@ -1068,10 +1362,20 @@
        s.fcfilepath = semanage_final_path(SEMANAGE_FINAL_TMP,
                                           SEMANAGE_FC_HOMEDIRS);
 
-       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 = calloc(1, sizeof(genhomedircon_user_entry_t));
+       if (s.fallback == NULL) {
+               retval = STATUS_ERR;
+               goto done;
+       }
+
+       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 +1399,7 @@
        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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/libsemanage.map 
new/libsemanage-2.6/src/libsemanage.map
--- old/libsemanage-2.5/src/libsemanage.map     2016-02-23 17:31:41.000000000 
+0100
+++ new/libsemanage-2.6/src/libsemanage.map     2016-10-14 17:31:26.000000000 
+0200
@@ -60,5 +60,4 @@
          semanage_module_upgrade_info;
          semanage_module_remove_key;
          semanage_set_store_root;
-  local: *;
 } LIBSEMANAGE_1.0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/semanage_store.c 
new/libsemanage-2.6/src/semanage_store.c
--- old/libsemanage-2.5/src/semanage_store.c    2016-02-23 17:31:41.000000000 
+0100
+++ new/libsemanage-2.6/src/semanage_store.c    2016-10-14 17:31:26.000000000 
+0200
@@ -292,6 +292,13 @@
                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 +307,13 @@
                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 +322,13 @@
                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) {
@@ -1491,6 +1512,45 @@
        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 +1626,6 @@
        }
 
 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 +1768,9 @@
                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;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/src/semanage_store.h 
new/libsemanage-2.6/src/semanage_store.h
--- old/libsemanage-2.5/src/semanage_store.h    2016-02-23 17:31:41.000000000 
+0100
+++ new/libsemanage-2.6/src/semanage_store.h    2016-10-14 17:31:26.000000000 
+0200
@@ -71,8 +71,11 @@
 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,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/tests/.gitignore 
new/libsemanage-2.6/tests/.gitignore
--- old/libsemanage-2.5/tests/.gitignore        1970-01-01 01:00:00.000000000 
+0100
+++ new/libsemanage-2.6/tests/.gitignore        2016-10-14 17:31:26.000000000 
+0200
@@ -0,0 +1 @@
+libsemanage-tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libsemanage-2.5/tests/Makefile 
new/libsemanage-2.6/tests/Makefile
--- old/libsemanage-2.5/tests/Makefile  2016-02-23 17:31:41.000000000 +0100
+++ new/libsemanage-2.6/tests/Makefile  2016-10-14 17:31:26.000000000 +0200
@@ -10,7 +10,6 @@
 ###########################################################################
 
 EXECUTABLE = libsemanage-tests
-CC = gcc
 CFLAGS += -g -O0 -Wall -W -Wundef -Wmissing-noreturn 
-Wmissing-format-attribute -Wno-unused-parameter
 INCLUDE = -I$(TESTSRC) -I$(TESTSRC)/../include
 LDFLAGS += -lcunit -lustr -lbz2 -laudit


Reply via email to