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/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/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/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/direct_api.c libsemanage-2.5/src/direct_api.c
index 2187b65..1efe141 100644
--- libsemanage-2.5/src/direct_api.c
+++ libsemanage-2.5/src/direct_api.c
@@ -146,9 +146,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;
@@ -275,7 +272,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);
@@ -345,10 +344,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 +358,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 +612,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 +667,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 +1103,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,21 +1133,18 @@ 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;
- /* Declare some variables */
- int modified = 0, fcontexts_modified, ports_modified,
- seusers_modified, users_extra_modified, dontaudit_modified,
- preserve_tunables_modified, bools_modified = 0,
+ int do_rebuild, do_write_kernel, do_install;
+ int fcontexts_modified, ports_modified, seusers_modified,
disable_dontaudit, preserve_tunables;
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 *bools = semanage_bool_dbase_local(sh);
@@ -1092,13 +1156,23 @@ 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);
+ 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 +1194,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 +1225,75 @@ 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;
}
- }
- missing |= missing_policy_kern;
- missing |= missing_fc;
- missing |= missing_seusers;
+ path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED);
+ if (stat(path, &sb) != 0) {
+ do_rebuild = 1;
+ goto rebuild;
+ }
+
+ 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 |
+ 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 +1382,72 @@ 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 *) 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,21 +1456,21 @@ 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;
@@ -1367,33 +1491,27 @@ 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
@@ -1415,9 +1533,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 +1546,12 @@ 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 *) 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);
@@ -1600,7 +1715,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 +1746,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;
@@ -1931,7 +2047,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 +2191,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.",
@@ -2613,7 +2754,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));
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/genhomedircon.c libsemanage-2.5/src/genhomedircon.c
index 1a9e87e..32d8d5f 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,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"
+/* 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;
} replacement_pair_t;
@@ -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);
@@ -1068,10 +1282,20 @@ int semanage_genhomedircon(semanage_handle_t * sh,
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 +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/libsemanage.map libsemanage-2.5/src/libsemanage.map
index 34b553d..41841e1 100644
--- libsemanage-2.5/src/libsemanage.map
+++ libsemanage-2.5/src/libsemanage.map
@@ -40,10 +40,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/semanage_store.c libsemanage-2.5/src/semanage_store.c
index fa0876f..4b87d67 100644
--- libsemanage-2.5/src/semanage_store.c
+++ libsemanage-2.5/src/semanage_store.c
@@ -95,7 +95,7 @@ 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",
@@ -104,8 +104,10 @@ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
"/nodes.local",
"/booleans.local",
"/seusers.local",
+ "/seusers.linked",
"/users.local",
"/users_extra.local",
+ "/users_extra.linked",
"/users_extra",
"/disable_dontaudit",
"/preserve_tunables",
@@ -292,6 +294,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 +309,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 +324,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 +535,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 +553,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 +576,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 +599,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 +620,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 +1159,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 +1513,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 +1627,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 +1769,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 +2038,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 +2050,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,9 +2080,10 @@ 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;
@@ -2055,7 +2092,7 @@ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out)
FILE *outfile = NULL;
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) {
diff --git libsemanage-2.5/src/semanage_store.h libsemanage-2.5/src/semanage_store.h
index acb6e3f..0b96fbe 100644
--- libsemanage-2.5/src/semanage_store.h
+++ libsemanage-2.5/src/semanage_store.h
@@ -49,8 +49,10 @@ enum semanage_sandbox_defs {
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,
@@ -71,8 +73,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 +131,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/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..7965980 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: