diff --git a/SOURCES/libsemanage-rhel.patch b/SOURCES/libsemanage-rhel.patch new file mode 100644 index 00000000..5ae063c0 --- /dev/null +++ b/SOURCES/libsemanage-rhel.patch @@ -0,0 +1,4419 @@ +diff --git libsemanage-2.5/ChangeLog libsemanage-2.5/ChangeLog +index 9b4d5b7..10fc784 100644 +--- libsemanage-2.5/ChangeLog ++++ libsemanage-2.5/ChangeLog +@@ -1,3 +1,13 @@ ++ * genhomedircon: add support for %group syntax, from Gary Tierney. ++ * genhomedircon: generate contexts for logins mapped to the default user, from Gary Tierney. ++ * Validate and compile file contexts before installing, from Stephen Smalley. ++ * Swap tcp and udp protocol numbers, from Miroslav Vadkerti. ++ * Sort object files for deterministic linking order, from Laurent Bigonville. ++ * Support overriding Makefile RANLIB, from Julien Pivotto. ++ * Respect CC and PKG_CONFIG environment variable, from Julien Pivotto. ++ * Fix multiple spelling errors, from Laurent Bigonville. ++ * genhomedircon: %{USERID} and %{USERNAME} support and code cleanups, from Jason Zaman. ++ + 2.5 2016-02-23 + * Do not overwrite CFLAGS in test Makefile, from Nicolas Iooss. + * Fix uninitialized variable in direct_commit and direct_api, from Nicolas Iooss. +diff --git libsemanage-2.5/include/semanage/fcontexts_policy.h libsemanage-2.5/include/semanage/fcontexts_policy.h +index a50db2b..199a1e1 100644 +--- libsemanage-2.5/include/semanage/fcontexts_policy.h ++++ libsemanage-2.5/include/semanage/fcontexts_policy.h +@@ -26,4 +26,8 @@ extern int semanage_fcontext_list(semanage_handle_t * handle, + semanage_fcontext_t *** records, + unsigned int *count); + ++extern int semanage_fcontext_list_homedirs(semanage_handle_t * handle, ++ semanage_fcontext_t *** records, ++ unsigned int *count); ++ + #endif +diff --git libsemanage-2.5/include/semanage/handle.h libsemanage-2.5/include/semanage/handle.h +index 6cad529..c816590 100644 +--- libsemanage-2.5/include/semanage/handle.h ++++ libsemanage-2.5/include/semanage/handle.h +@@ -130,7 +130,7 @@ int semanage_commit(semanage_handle_t *); + #define SEMANAGE_CAN_READ 1 + #define SEMANAGE_CAN_WRITE 2 + /* returns SEMANAGE_CAN_READ or SEMANAGE_CAN_WRITE if the store is readable +- * or writable, respectively. <0 if an error occured */ ++ * or writable, respectively. <0 if an error occurred */ + int semanage_access_check(semanage_handle_t * sh); + + /* returns 0 if not connected, 1 if connected */ +diff --git libsemanage-2.5/include/semanage/ibendport_record.h libsemanage-2.5/include/semanage/ibendport_record.h +new file mode 100644 +index 0000000..153eea0 +--- /dev/null ++++ libsemanage-2.5/include/semanage/ibendport_record.h +@@ -0,0 +1,62 @@ ++/*Copyright (C) 2005 Red Hat, Inc. */ ++ ++#ifndef _SEMANAGE_IBENDPORT_RECORD_H_ ++#define _SEMANAGE_IBENDPORT_RECORD_H_ ++ ++#include ++#include ++#include ++ ++#ifndef _SEMANAGE_IBENDPORT_DEFINED_ ++struct semanage_ibendport; ++struct semanage_ibendport_key; ++typedef struct semanage_ibendport semanage_ibendport_t; ++typedef struct semanage_ibendport_key semanage_ibendport_key_t; ++#define _SEMANAGE_IBENDPORT_DEFINED_ ++#endif ++ ++extern int semanage_ibendport_compare(const semanage_ibendport_t *ibendport, ++ const semanage_ibendport_key_t *key); ++ ++extern int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport, ++ const semanage_ibendport_t *ibendport2); ++ ++extern int semanage_ibendport_key_create(semanage_handle_t *handle, ++ const char *ibdev_name, ++ int port, ++ semanage_ibendport_key_t **key_ptr); ++ ++extern int semanage_ibendport_key_extract(semanage_handle_t *handle, ++ const semanage_ibendport_t *ibendport, ++ semanage_ibendport_key_t **key_ptr); ++ ++extern void semanage_ibendport_key_free(semanage_ibendport_key_t *key); ++ ++extern int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle, ++ const semanage_ibendport_t *ibendport, ++ char **ibdev_name_ptr); ++ ++extern int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle, ++ semanage_ibendport_t *ibendport, ++ const char *ibdev_name); ++ ++extern int semanage_ibendport_get_port(const semanage_ibendport_t *ibendport); ++ ++extern void semanage_ibendport_set_port(semanage_ibendport_t *ibendport, int port); ++ ++extern semanage_context_t *semanage_ibendport_get_con(const semanage_ibendport_t *ibendport); ++ ++extern int semanage_ibendport_set_con(semanage_handle_t *handle, ++ semanage_ibendport_t *ibendport, ++ semanage_context_t *con); ++ ++extern int semanage_ibendport_create(semanage_handle_t *handle, ++ semanage_ibendport_t **ibendport_ptr); ++ ++extern int semanage_ibendport_clone(semanage_handle_t *handle, ++ const semanage_ibendport_t *ibendport, ++ semanage_ibendport_t **ibendport_ptr); ++ ++extern void semanage_ibendport_free(semanage_ibendport_t *ibendport); ++ ++#endif +diff --git libsemanage-2.5/include/semanage/ibendports_local.h libsemanage-2.5/include/semanage/ibendports_local.h +new file mode 100644 +index 0000000..641dd35 +--- /dev/null ++++ libsemanage-2.5/include/semanage/ibendports_local.h +@@ -0,0 +1,36 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc */ ++ ++#ifndef _SEMANAGE_IBENDPORTS_LOCAL_H_ ++#define _SEMANAGE_IBENDPORTS_LOCAL_H_ ++ ++#include ++#include ++ ++extern int semanage_ibendport_modify_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ const semanage_ibendport_t *data); ++ ++extern int semanage_ibendport_del_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key); ++ ++extern int semanage_ibendport_query_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ semanage_ibendport_t **response); ++ ++extern int semanage_ibendport_exists_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ int *response); ++ ++extern int semanage_ibendport_count_local(semanage_handle_t *handle, ++ unsigned int *response); ++ ++extern int semanage_ibendport_iterate_local(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibendport_t *record, ++ void *varg), ++ void *handler_arg); ++ ++extern int semanage_ibendport_list_local(semanage_handle_t *handle, ++ semanage_ibendport_t ***records, ++ unsigned int *count); ++ ++#endif +diff --git libsemanage-2.5/include/semanage/ibendports_policy.h libsemanage-2.5/include/semanage/ibendports_policy.h +new file mode 100644 +index 0000000..3fc1976 +--- /dev/null ++++ libsemanage-2.5/include/semanage/ibendports_policy.h +@@ -0,0 +1,28 @@ ++/* Copyright (C) 2017 Mellanox Techonologies Inc */ ++ ++#ifndef _SEMANAGE_IBENDPORTS_POLICY_H_ ++#define _SEMANAGE_IBENDPORTS_POLICY_H_ ++ ++#include ++#include ++ ++extern int semanage_ibendport_query(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ semanage_ibendport_t **response); ++ ++extern int semanage_ibendport_exists(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, int *response); ++ ++extern int semanage_ibendport_count(semanage_handle_t *handle, ++ unsigned int *response); ++ ++extern int semanage_ibendport_iterate(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibendport_t *record, ++ void *varg), ++ void *handler_arg); ++ ++extern int semanage_ibendport_list(semanage_handle_t *handle, ++ semanage_ibendport_t ***records, ++ unsigned int *count); ++ ++#endif +diff --git libsemanage-2.5/include/semanage/ibpkey_record.h libsemanage-2.5/include/semanage/ibpkey_record.h +new file mode 100644 +index 0000000..9da7dc5 +--- /dev/null ++++ libsemanage-2.5/include/semanage/ibpkey_record.h +@@ -0,0 +1,72 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc */ ++ ++#ifndef _SEMANAGE_IBPKEY_RECORD_H_ ++#define _SEMANAGE_IBPKEY_RECORD_H_ ++ ++#include ++#include ++#include ++#include ++ ++#ifndef _SEMANAGE_IBPKEY_DEFINED_ ++struct semanage_ibpkey; ++struct semanage_ibpkey_key; ++typedef struct semanage_ibpkey semanage_ibpkey_t; ++typedef struct semanage_ibpkey_key semanage_ibpkey_key_t; ++#define _SEMANAGE_IBPKEY_DEFINED_ ++#endif ++ ++extern int semanage_ibpkey_compare(const semanage_ibpkey_t *ibpkey, ++ const semanage_ibpkey_key_t *key); ++ ++extern int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey, ++ const semanage_ibpkey_t *ibpkey2); ++ ++extern int semanage_ibpkey_key_create(semanage_handle_t *handle, ++ const char *subnet_prefix, ++ int low, int high, ++ semanage_ibpkey_key_t **key_ptr); ++ ++extern int semanage_ibpkey_key_extract(semanage_handle_t *handle, ++ const semanage_ibpkey_t *ibpkey, ++ semanage_ibpkey_key_t **key_ptr); ++ ++extern void semanage_ibpkey_key_free(semanage_ibpkey_key_t *key); ++ ++extern int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle, ++ const semanage_ibpkey_t *ibpkey, ++ char **subnet_prefix_ptr); ++ ++extern uint64_t semanage_ibpkey_get_subnet_prefix_bytes(const semanage_ibpkey_t *ibpkey); ++ ++extern int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle, ++ semanage_ibpkey_t *ibpkey, ++ const char *subnet_prefix); ++ ++extern void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey, ++ uint64_t subnet_prefix); ++ ++extern int semanage_ibpkey_get_low(const semanage_ibpkey_t *ibpkey); ++ ++extern int semanage_ibpkey_get_high(const semanage_ibpkey_t *ibpkey); ++ ++extern void semanage_ibpkey_set_pkey(semanage_ibpkey_t *ibpkey, int pkey_num); ++ ++extern void semanage_ibpkey_set_range(semanage_ibpkey_t *ibpkey, int low, int high); ++ ++extern semanage_context_t *semanage_ibpkey_get_con(const semanage_ibpkey_t *ibpkey); ++ ++extern int semanage_ibpkey_set_con(semanage_handle_t *handle, ++ semanage_ibpkey_t *ibpkey, ++ semanage_context_t *con); ++ ++extern int semanage_ibpkey_create(semanage_handle_t *handle, ++ semanage_ibpkey_t **ibpkey_ptr); ++ ++extern int semanage_ibpkey_clone(semanage_handle_t *handle, ++ const semanage_ibpkey_t *ibpkey, ++ semanage_ibpkey_t **ibpkey_ptr); ++ ++extern void semanage_ibpkey_free(semanage_ibpkey_t *ibpkey); ++ ++#endif +diff --git libsemanage-2.5/include/semanage/ibpkeys_local.h libsemanage-2.5/include/semanage/ibpkeys_local.h +new file mode 100644 +index 0000000..079a642 +--- /dev/null ++++ libsemanage-2.5/include/semanage/ibpkeys_local.h +@@ -0,0 +1,36 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc */ ++ ++#ifndef _SEMANAGE_IBPKEYS_LOCAL_H_ ++#define _SEMANAGE_IBPKEYS_LOCAL_H_ ++ ++#include ++#include ++ ++extern int semanage_ibpkey_modify_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ const semanage_ibpkey_t *data); ++ ++extern int semanage_ibpkey_del_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key); ++ ++extern int semanage_ibpkey_query_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ semanage_ibpkey_t **response); ++ ++extern int semanage_ibpkey_exists_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ int *response); ++ ++extern int semanage_ibpkey_count_local(semanage_handle_t *handle, ++ unsigned int *response); ++ ++extern int semanage_ibpkey_iterate_local(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibpkey_t * ++ record, void *varg), ++ void *handler_arg); ++ ++extern int semanage_ibpkey_list_local(semanage_handle_t *handle, ++ semanage_ibpkey_t ***records, ++ unsigned int *count); ++ ++#endif +diff --git libsemanage-2.5/include/semanage/ibpkeys_policy.h libsemanage-2.5/include/semanage/ibpkeys_policy.h +new file mode 100644 +index 0000000..c287ac0 +--- /dev/null ++++ libsemanage-2.5/include/semanage/ibpkeys_policy.h +@@ -0,0 +1,28 @@ ++/* Copyright (C) 2017 Mellanox Technolgies Inc. */ ++ ++#ifndef _SEMANAGE_IBPKEYS_POLICY_H_ ++#define _SEMANAGE_IBPKEYS_POLICY_H_ ++ ++#include ++#include ++ ++extern int semanage_ibpkey_query(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ semanage_ibpkey_t **response); ++ ++extern int semanage_ibpkey_exists(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, int *response); ++ ++extern int semanage_ibpkey_count(semanage_handle_t *handle, ++ unsigned int *response); ++ ++extern int semanage_ibpkey_iterate(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibpkey_t *record, ++ void *varg), ++ void *handler_arg); ++ ++extern int semanage_ibpkey_list(semanage_handle_t *handle, ++ semanage_ibpkey_t ***records, ++ unsigned int *count); ++ ++#endif +diff --git libsemanage-2.5/include/semanage/modules.h libsemanage-2.5/include/semanage/modules.h +index 4b93e54..50940e2 100644 +--- libsemanage-2.5/include/semanage/modules.h ++++ libsemanage-2.5/include/semanage/modules.h +@@ -39,7 +39,7 @@ int semanage_module_install_file(semanage_handle_t *, + int semanage_module_remove(semanage_handle_t *, char *module_name); + + /* semanage_module_info is for getting information on installed +- modules, only name at this time */ ++ modules, only name and version at this time */ + typedef struct semanage_module_info semanage_module_info_t; + + /* Look up a module using @modkey. The module's raw data is returned as a +@@ -64,6 +64,7 @@ void semanage_module_info_datum_destroy(semanage_module_info_t *); + semanage_module_info_t *semanage_module_list_nth(semanage_module_info_t * list, + int n); + const char *semanage_module_get_name(semanage_module_info_t *); ++const char *semanage_module_get_version(semanage_module_info_t *); + + /* Module Info */ + +@@ -104,6 +105,14 @@ int semanage_module_info_get_name(semanage_handle_t *sh, + semanage_module_info_t *modinfo, + const char **name); + ++/* Get @module_version from @modinfo. Caller should not free @module_version. ++ * ++ * Returns 0 on success and -1 on error. ++ */ ++int semanage_module_info_get_version(semanage_handle_t *sh, ++ semanage_module_info_t *modinfo, ++ const char **version); ++ + /* Get @lang_ext from @modinfo. Caller should not free @lang_ext. + * + * Returns 0 on success and -1 on error. +@@ -138,6 +147,14 @@ int semanage_module_info_set_name(semanage_handle_t *sh, + semanage_module_info_t *modinfo, + const char *name); + ++/* Set @version in @modinfo. ++ * ++ * Returns 0 on success and -1 on error. ++ */ ++int semanage_module_info_set_version(semanage_handle_t *sh, ++ semanage_module_info_t *modinfo, ++ const char *version); ++ + /* Set @lang_ext in @modinfo. + * + * Returns 0 on success and -1 on error. +diff --git libsemanage-2.5/include/semanage/semanage.h libsemanage-2.5/include/semanage/semanage.h +index f417ce4..0489014 100644 +--- libsemanage-2.5/include/semanage/semanage.h ++++ libsemanage-2.5/include/semanage/semanage.h +@@ -33,6 +33,8 @@ + #include + #include + #include ++#include ++#include + #include + + /* Dbase */ +@@ -47,6 +49,10 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + #include + #include + #include +diff --git libsemanage-2.5/man/man5/semanage.conf.5 libsemanage-2.5/man/man5/semanage.conf.5 +index 8f8de55..1009d97 100644 +--- libsemanage-2.5/man/man5/semanage.conf.5 ++++ libsemanage-2.5/man/man5/semanage.conf.5 +@@ -33,7 +33,7 @@ Specify an alternative root path to use for the store. The default is "/" + + .TP + .B store-root +-Specify an alternative store_root path to use. The default is "/var/lib/selinux" ++Specify an alternative store_root path to use. The default is "/etc/selinux" + + .TP + .B compiler-directory +diff --git libsemanage-2.5/src/Makefile libsemanage-2.5/src/Makefile +index d1fcc0b..96ee652 100644 +--- libsemanage-2.5/src/Makefile ++++ libsemanage-2.5/src/Makefile +@@ -5,6 +5,7 @@ PYTHON ?= python + PYPREFIX ?= $(notdir $(PYTHON)) + RUBY ?= ruby + RUBYPREFIX ?= $(notdir $(RUBY)) ++PKG_CONFIG ?= pkg-config + + # Installation directories. + PREFIX ?= $(DESTDIR)/usr +@@ -12,11 +13,11 @@ LIBDIR ?= $(PREFIX)/lib + SHLIBDIR ?= $(DESTDIR)/lib + INCLUDEDIR ?= $(PREFIX)/include + PYLIBVER ?= $(shell $(PYTHON) -c 'import sys;print("python%d.%d" % sys.version_info[0:2])') +-PYINC ?= $(shell pkg-config --cflags $(PYPREFIX)) ++PYINC ?= $(shell $(PKG_CONFIG) --cflags $(PYPREFIX)) + PYLIBDIR ?= $(LIBDIR)/$(PYLIBVER) + RUBYLIBVER ?= $(shell $(RUBY) -e 'print RUBY_VERSION.split(".")[0..1].join(".")') + RUBYPLATFORM ?= $(shell $(RUBY) -e 'print RUBY_PLATFORM') +-RUBYINC ?= $(shell pkg-config --cflags ruby-$(RUBYLIBVER)) ++RUBYINC ?= $(shell $(PKG_CONFIG) --cflags ruby-$(RUBYLIBVER)) + RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM) + + LIBBASE=$(shell basename $(LIBDIR)) +@@ -51,7 +52,7 @@ SWIGRUBYSO=$(RUBYPREFIX)_semanage.so + LIBSO=$(TARGET).$(LIBVERSION) + + GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i +-SRCS= $(filter-out $(GENERATED),$(wildcard *.c)) ++SRCS= $(filter-out $(GENERATED),$(sort $(wildcard *.c))) + + OBJS= $(patsubst %.c,%.o,$(SRCS)) conf-scan.o conf-parse.o + LOBJS= $(patsubst %.c,%.lo,$(SRCS)) conf-scan.lo conf-parse.lo +@@ -61,7 +62,7 @@ SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno + -Wno-unused-parameter + + override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE +-RANLIB=ranlib ++RANLIB ?= ranlib + + SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./ + +diff --git libsemanage-2.5/src/conf-parse.y libsemanage-2.5/src/conf-parse.y +index b527e89..e2b6028 100644 +--- libsemanage-2.5/src/conf-parse.y ++++ libsemanage-2.5/src/conf-parse.y +@@ -340,7 +340,7 @@ static int semanage_conf_init(semanage_conf_t * conf) + conf->store_type = SEMANAGE_CON_DIRECT; + conf->store_path = strdup(basename(selinux_policy_root())); + conf->ignoredirs = NULL; +- conf->store_root_path = strdup("/var/lib/selinux"); ++ conf->store_root_path = strdup("/etc/selinux"); + conf->compiler_directory_path = strdup("/usr/libexec/selinux/hll"); + conf->policyvers = sepol_policy_kern_vers_max(); + conf->target_platform = SEPOL_TARGET_SELINUX; +diff --git libsemanage-2.5/src/database.h libsemanage-2.5/src/database.h +index e460379..6a4a164 100644 +--- libsemanage-2.5/src/database.h ++++ libsemanage-2.5/src/database.h +@@ -148,7 +148,7 @@ typedef struct dbase_table { + * This function must be invoked before using + * any of the database functions above. It may be invoked + * multiple times, and will update the cache if a commit +- * occured between invocations */ ++ * occurred between invocations */ + int (*cache) (struct semanage_handle * handle, dbase_t * dbase); + + /* Forgets all changes that haven't been written +diff --git libsemanage-2.5/src/database_file.c libsemanage-2.5/src/database_file.c +index a21b3ee..a51269e 100644 +--- libsemanage-2.5/src/database_file.c ++++ libsemanage-2.5/src/database_file.c +@@ -119,13 +119,16 @@ static int dbase_file_flush(semanage_handle_t * handle, dbase_file_t * dbase) + cache_entry_t *ptr; + const char *fname = NULL; + FILE *str = NULL; ++ mode_t mask; + + if (!dbase_llist_is_modified(&dbase->llist)) + return STATUS_SUCCESS; + + fname = dbase->path[handle->is_in_transaction]; + ++ mask = umask(0077); + str = fopen(fname, "w"); ++ umask(mask); + if (!str) { + ERR(handle, "could not open %s for writing: %s", + fname, strerror(errno)); +diff --git libsemanage-2.5/src/direct_api.c libsemanage-2.5/src/direct_api.c +index 2187b65..fea6572 100644 +--- libsemanage-2.5/src/direct_api.c ++++ libsemanage-2.5/src/direct_api.c +@@ -40,6 +40,8 @@ + #include "user_internal.h" + #include "seuser_internal.h" + #include "port_internal.h" ++#include "ibpkey_internal.h" ++#include "ibendport_internal.h" + #include "iface_internal.h" + #include "boolean_internal.h" + #include "fcontext_internal.h" +@@ -146,9 +148,6 @@ int semanage_direct_connect(semanage_handle_t * sh) + if (semanage_create_store(sh, 1)) + goto err; + +- if (semanage_access_check(sh) < SEMANAGE_CAN_READ) +- goto err; +- + sh->u.direct.translock_file_fd = -1; + sh->u.direct.activelock_file_fd = -1; + +@@ -208,6 +207,12 @@ int semanage_direct_connect(semanage_handle_t * sh) + semanage_fcontext_dbase_local(sh)) < 0) + goto err; + ++ if (fcontext_file_dbase_init(sh, ++ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_FC_HOMEDIRS), ++ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS), ++ semanage_fcontext_dbase_homedirs(sh)) < 0) ++ goto err; ++ + if (seuser_file_dbase_init(sh, + semanage_path(SEMANAGE_ACTIVE, + SEMANAGE_SEUSERS_LOCAL), +@@ -224,6 +229,22 @@ int semanage_direct_connect(semanage_handle_t * sh) + semanage_node_dbase_local(sh)) < 0) + goto err; + ++ if (ibpkey_file_dbase_init(sh, ++ semanage_path(SEMANAGE_ACTIVE, ++ SEMANAGE_IBPKEYS_LOCAL), ++ semanage_path(SEMANAGE_TMP, ++ SEMANAGE_IBPKEYS_LOCAL), ++ semanage_ibpkey_dbase_local(sh)) < 0) ++ goto err; ++ ++ if (ibendport_file_dbase_init(sh, ++ semanage_path(SEMANAGE_ACTIVE, ++ SEMANAGE_IBENDPORTS_LOCAL), ++ semanage_path(SEMANAGE_TMP, ++ SEMANAGE_IBENDPORTS_LOCAL), ++ semanage_ibendport_dbase_local(sh)) < 0) ++ goto err; ++ + /* Object databases: local modifications + policy */ + if (user_base_policydb_dbase_init(sh, + semanage_user_base_dbase_policy(sh)) < +@@ -248,6 +269,12 @@ int semanage_direct_connect(semanage_handle_t * sh) + if (port_policydb_dbase_init(sh, semanage_port_dbase_policy(sh)) < 0) + goto err; + ++ if (ibpkey_policydb_dbase_init(sh, semanage_ibpkey_dbase_policy(sh)) < 0) ++ goto err; ++ ++ if (ibendport_policydb_dbase_init(sh, semanage_ibendport_dbase_policy(sh)) < 0) ++ goto err; ++ + if (iface_policydb_dbase_init(sh, semanage_iface_dbase_policy(sh)) < 0) + goto err; + +@@ -275,7 +302,9 @@ int semanage_direct_connect(semanage_handle_t * sh) + + /* set the disable dontaudit value */ + path = semanage_path(SEMANAGE_ACTIVE, SEMANAGE_DISABLE_DONTAUDIT); +- if (access(path, F_OK) == 0) ++ ++ struct stat sb; ++ if (stat(path, &sb) == 0) + sepol_set_disable_dontaudit(sh->sepolh, 1); + else + sepol_set_disable_dontaudit(sh->sepolh, 0); +@@ -320,9 +349,12 @@ static int semanage_direct_disconnect(semanage_handle_t * sh) + user_extra_file_dbase_release(semanage_user_extra_dbase_local(sh)); + user_join_dbase_release(semanage_user_dbase_local(sh)); + port_file_dbase_release(semanage_port_dbase_local(sh)); ++ ibpkey_file_dbase_release(semanage_ibpkey_dbase_local(sh)); ++ ibendport_file_dbase_release(semanage_ibendport_dbase_local(sh)); + iface_file_dbase_release(semanage_iface_dbase_local(sh)); + bool_file_dbase_release(semanage_bool_dbase_local(sh)); + fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh)); ++ fcontext_file_dbase_release(semanage_fcontext_dbase_homedirs(sh)); + seuser_file_dbase_release(semanage_seuser_dbase_local(sh)); + node_file_dbase_release(semanage_node_dbase_local(sh)); + +@@ -331,6 +363,8 @@ static int semanage_direct_disconnect(semanage_handle_t * sh) + user_extra_file_dbase_release(semanage_user_extra_dbase_policy(sh)); + user_join_dbase_release(semanage_user_dbase_policy(sh)); + port_policydb_dbase_release(semanage_port_dbase_policy(sh)); ++ ibpkey_policydb_dbase_release(semanage_ibpkey_dbase_policy(sh)); ++ ibendport_policydb_dbase_release(semanage_ibendport_dbase_policy(sh)); + iface_policydb_dbase_release(semanage_iface_dbase_policy(sh)); + bool_policydb_dbase_release(semanage_bool_dbase_policy(sh)); + fcontext_file_dbase_release(semanage_fcontext_dbase_policy(sh)); +@@ -345,10 +379,6 @@ static int semanage_direct_disconnect(semanage_handle_t * sh) + + static int semanage_direct_begintrans(semanage_handle_t * sh) + { +- +- if (semanage_access_check(sh) != SEMANAGE_CAN_WRITE) { +- return -1; +- } + if (semanage_get_trans_lock(sh) < 0) { + return -1; + } +@@ -363,6 +393,35 @@ static int semanage_direct_begintrans(semanage_handle_t * sh) + + /********************* utility functions *********************/ + ++/* Takes a module stored in 'module_data' and parses its headers. ++ * Sets reference variables 'module_name' to module's name, and ++ * 'version' to module's version. The caller is responsible for ++ * free()ing 'module_name', and 'version'; they will be ++ * set to NULL upon entering this function. Returns 0 on success, -1 ++ * if out of memory. ++ */ ++static int parse_module_headers(semanage_handle_t * sh, char *module_data, ++ size_t data_len, char **module_name, ++ char **version) ++{ ++ struct sepol_policy_file *pf; ++ int file_type; ++ *module_name = *version = NULL; ++ ++ if (sepol_policy_file_create(&pf)) { ++ ERR(sh, "Out of memory!"); ++ return -1; ++ } ++ sepol_policy_file_set_mem(pf, module_data, data_len); ++ sepol_policy_file_set_handle(pf, sh->sepolh); ++ if (module_data != NULL && data_len > 0) ++ sepol_module_package_info(pf, &file_type, module_name, ++ version); ++ sepol_policy_file_free(pf); ++ ++ return 0; ++} ++ + #include + #include + #include +@@ -588,13 +647,33 @@ static int semanage_direct_update_user_extra(semanage_handle_t * sh, cil_db_t *c + } + + if (size > 0) { ++ /* ++ * Write the users_extra entries from CIL modules. ++ * This file is used as our baseline when we do not require ++ * re-linking. ++ */ ++ ofilename = semanage_path(SEMANAGE_TMP, ++ SEMANAGE_USERS_EXTRA_LINKED); ++ if (ofilename == NULL) { ++ retval = -1; ++ goto cleanup; ++ } ++ retval = write_file(sh, ofilename, data, size); ++ if (retval < 0) ++ goto cleanup; ++ ++ /* ++ * Write the users_extra file; users_extra.local ++ * will be merged into this file. ++ */ + ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA); + if (ofilename == NULL) { +- return retval; ++ retval = -1; ++ goto cleanup; + } + retval = write_file(sh, ofilename, data, size); + if (retval < 0) +- return retval; ++ goto cleanup; + + pusers_extra->dtable->drop_cache(pusers_extra->dbase); + +@@ -623,11 +702,33 @@ static int semanage_direct_update_seuser(semanage_handle_t * sh, cil_db_t *cildb + } + + if (size > 0) { ++ /* ++ * Write the seusers entries from CIL modules. ++ * This file is used as our baseline when we do not require ++ * re-linking. ++ */ ++ ofilename = semanage_path(SEMANAGE_TMP, ++ SEMANAGE_SEUSERS_LINKED); ++ if (ofilename == NULL) { ++ retval = -1; ++ goto cleanup; ++ } ++ retval = write_file(sh, ofilename, data, size); ++ if (retval < 0) ++ goto cleanup; ++ ++ /* ++ * Write the seusers file; seusers.local will be merged into ++ * this file. ++ */ + ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS); + if (ofilename == NULL) { +- return -1; ++ retval = -1; ++ goto cleanup; + } + retval = write_file(sh, ofilename, data, size); ++ if (retval < 0) ++ goto cleanup; + + pseusers->dtable->drop_cache(pseusers->dbase); + } else { +@@ -1037,8 +1138,9 @@ static int semanage_compile_hll_modules(semanage_handle_t *sh, + goto cleanup; + } + ++ struct stat sb; + if (semanage_get_ignore_module_cache(sh) == 0 && +- access(cil_path, F_OK) == 0) { ++ stat(cil_path, &sb) == 0) { + continue; + } + +@@ -1066,23 +1168,26 @@ static int semanage_direct_commit(semanage_handle_t * sh) + size_t fc_buffer_len = 0; + const char *ofilename = NULL; + const char *path; +- int retval = -1, num_modinfos = 0, i, missing_policy_kern = 0, +- missing_seusers = 0, missing_fc = 0, missing = 0; ++ int retval = -1, num_modinfos = 0, i; + sepol_policydb_t *out = NULL; + struct cil_db *cildb = NULL; + semanage_module_info_t *modinfos = NULL; ++ mode_t mask = umask(0077); + +- /* Declare some variables */ +- int modified = 0, fcontexts_modified, ports_modified, +- seusers_modified, users_extra_modified, dontaudit_modified, +- preserve_tunables_modified, bools_modified = 0, +- disable_dontaudit, preserve_tunables; ++ int do_rebuild, do_write_kernel, do_install; ++ int fcontexts_modified, ports_modified, seusers_modified, ++ disable_dontaudit, preserve_tunables, ibpkeys_modified, ++ ibendports_modified; + dbase_config_t *users = semanage_user_dbase_local(sh); + dbase_config_t *users_base = semanage_user_base_dbase_local(sh); + dbase_config_t *pusers_base = semanage_user_base_dbase_policy(sh); +- dbase_config_t *users_extra = semanage_user_extra_dbase_local(sh); ++ dbase_config_t *pusers_extra = semanage_user_extra_dbase_policy(sh); + dbase_config_t *ports = semanage_port_dbase_local(sh); + dbase_config_t *pports = semanage_port_dbase_policy(sh); ++ dbase_config_t *ibpkeys = semanage_ibpkey_dbase_local(sh); ++ dbase_config_t *pibpkeys = semanage_ibpkey_dbase_policy(sh); ++ dbase_config_t *ibendports = semanage_ibendport_dbase_local(sh); ++ dbase_config_t *pibendports = semanage_ibendport_dbase_policy(sh); + dbase_config_t *bools = semanage_bool_dbase_local(sh); + dbase_config_t *pbools = semanage_bool_dbase_policy(sh); + dbase_config_t *ifaces = semanage_iface_dbase_local(sh); +@@ -1092,13 +1197,25 @@ static int semanage_direct_commit(semanage_handle_t * sh) + dbase_config_t *fcontexts = semanage_fcontext_dbase_local(sh); + dbase_config_t *pfcontexts = semanage_fcontext_dbase_policy(sh); + dbase_config_t *seusers = semanage_seuser_dbase_local(sh); ++ dbase_config_t *pseusers = semanage_seuser_dbase_policy(sh); ++ ++ /* Modified flags that we need to use more than once. */ ++ ports_modified = ports->dtable->is_modified(ports->dbase); ++ ibpkeys_modified = ibpkeys->dtable->is_modified(ibpkeys->dbase); ++ ibendports_modified = ibendports->dtable->is_modified(ibendports->dbase); ++ seusers_modified = seusers->dtable->is_modified(seusers->dbase); ++ fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase); ++ ++ /* Rebuild if explicitly requested or any module changes occurred. */ ++ do_rebuild = sh->do_rebuild | sh->modules_modified; + + /* Create or remove the disable_dontaudit flag file. */ + path = semanage_path(SEMANAGE_TMP, SEMANAGE_DISABLE_DONTAUDIT); +- if (access(path, F_OK) == 0) +- dontaudit_modified = !(sepol_get_disable_dontaudit(sh->sepolh) == 1); ++ struct stat sb; ++ if (stat(path, &sb) == 0) ++ do_rebuild |= !(sepol_get_disable_dontaudit(sh->sepolh) == 1); + else +- dontaudit_modified = (sepol_get_disable_dontaudit(sh->sepolh) == 1); ++ do_rebuild |= (sepol_get_disable_dontaudit(sh->sepolh) == 1); + if (sepol_get_disable_dontaudit(sh->sepolh) == 1) { + FILE *touch; + touch = fopen(path, "w"); +@@ -1120,10 +1237,10 @@ static int semanage_direct_commit(semanage_handle_t * sh) + + /* Create or remove the preserve_tunables flag file. */ + path = semanage_path(SEMANAGE_TMP, SEMANAGE_PRESERVE_TUNABLES); +- if (access(path, F_OK) == 0) +- preserve_tunables_modified = !(sepol_get_preserve_tunables(sh->sepolh) == 1); ++ if (stat(path, &sb) == 0) ++ do_rebuild |= !(sepol_get_preserve_tunables(sh->sepolh) == 1); + else +- preserve_tunables_modified = (sepol_get_preserve_tunables(sh->sepolh) == 1); ++ do_rebuild |= (sepol_get_preserve_tunables(sh->sepolh) == 1); + if (sepol_get_preserve_tunables(sh->sepolh) == 1) { + FILE *touch; + touch = fopen(path, "w"); +@@ -1151,54 +1268,76 @@ static int semanage_direct_commit(semanage_handle_t * sh) + goto cleanup; + } + +- /* Decide if anything was modified */ +- fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase); +- seusers_modified = seusers->dtable->is_modified(seusers->dbase); +- users_extra_modified = +- users_extra->dtable->is_modified(users_extra->dbase); +- ports_modified = ports->dtable->is_modified(ports->dbase); +- bools_modified = bools->dtable->is_modified(bools->dbase); +- +- modified = sh->modules_modified; +- modified |= seusers_modified; +- modified |= users_extra_modified; +- modified |= ports_modified; +- modified |= users->dtable->is_modified(users_base->dbase); +- modified |= ifaces->dtable->is_modified(ifaces->dbase); +- modified |= nodes->dtable->is_modified(nodes->dbase); +- modified |= dontaudit_modified; +- modified |= preserve_tunables_modified; +- +- /* This is for systems that have already migrated with an older version +- * of semanage_migrate_store. The older version did not copy policy.kern so +- * the policy binary must be rebuilt here. ++ /* ++ * This is for systems that have already migrated with an older version ++ * of semanage_migrate_store. The older version did not copy ++ * policy.kern so the policy binary must be rebuilt here. ++ * This also ensures that any linked files that are required ++ * in order to skip re-linking are present; otherwise, we force ++ * a rebuild. + */ +- if (!sh->do_rebuild && !modified) { ++ if (!do_rebuild) { + path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL); +- +- if (access(path, F_OK) != 0) { +- missing_policy_kern = 1; ++ if (stat(path, &sb) != 0) { ++ do_rebuild = 1; ++ goto rebuild; + } + + path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC); +- +- if (access(path, F_OK) != 0) { +- missing_fc = 1; ++ if (stat(path, &sb) != 0) { ++ do_rebuild = 1; ++ goto rebuild; + } + + path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS); ++ if (stat(path, &sb) != 0) { ++ do_rebuild = 1; ++ goto rebuild; ++ } + +- if (access(path, F_OK) != 0) { +- missing_seusers = 1; ++ path = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED); ++ if (stat(path, &sb) != 0) { ++ do_rebuild = 1; ++ goto rebuild; ++ } ++ ++ path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED); ++ if (stat(path, &sb) != 0) { ++ do_rebuild = 1; ++ goto rebuild; + } +- } + +- missing |= missing_policy_kern; +- missing |= missing_fc; +- missing |= missing_seusers; ++ path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED); ++ if (stat(path, &sb) != 0) { ++ do_rebuild = 1; ++ goto rebuild; ++ } ++ } + +- /* If there were policy changes, or explicitly requested, rebuild the policy */ +- if (sh->do_rebuild || modified || missing) { ++rebuild: ++ /* ++ * Now that we know whether or not a rebuild is required, ++ * we can determine what else needs to be done. ++ * We need to write the kernel policy if we are rebuilding ++ * or if any other policy component that lives in the kernel ++ * policy has been modified. ++ * We need to install the policy files if any of the managed files ++ * that live under /etc/selinux (kernel policy, seusers, file contexts) ++ * will be modified. ++ */ ++ do_write_kernel = do_rebuild | ports_modified | ibpkeys_modified | ++ ibendports_modified | ++ bools->dtable->is_modified(bools->dbase) | ++ ifaces->dtable->is_modified(ifaces->dbase) | ++ nodes->dtable->is_modified(nodes->dbase) | ++ users->dtable->is_modified(users_base->dbase); ++ do_install = do_write_kernel | seusers_modified | fcontexts_modified; ++ ++ /* ++ * If there were policy changes, or explicitly requested, or ++ * any required files are missing, rebuild the policy. ++ */ ++ if (do_rebuild) { + /* =================== Module expansion =============== */ + + retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos); +@@ -1287,43 +1426,74 @@ static int semanage_direct_commit(semanage_handle_t * sh) + goto cleanup; + + cil_db_destroy(&cildb); +- ++ ++ /* Write the linked policy before merging local changes. */ ++ retval = semanage_write_policydb(sh, out, ++ SEMANAGE_LINKED); ++ if (retval < 0) ++ goto cleanup; + } else { +- /* Load already linked policy */ ++ /* Load the existing linked policy, w/o local changes */ + retval = sepol_policydb_create(&out); + if (retval < 0) + goto cleanup; + +- retval = semanage_read_policydb(sh, out); ++ retval = semanage_read_policydb(sh, out, SEMANAGE_LINKED); + if (retval < 0) + goto cleanup; +- } + +- if (sh->do_rebuild || modified || bools_modified) { +- /* Attach to policy databases that work with a policydb. */ +- dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out); +- dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out); +- dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out); +- dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out); +- dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out); ++ path = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS_LINKED); ++ if (stat(path, &sb) == 0) { ++ retval = semanage_copy_file(path, ++ semanage_path(SEMANAGE_TMP, ++ SEMANAGE_STORE_SEUSERS), ++ sh->conf->file_mode); ++ if (retval < 0) ++ goto cleanup; ++ pseusers->dtable->drop_cache(pseusers->dbase); ++ } else { ++ pseusers->dtable->clear(sh, pseusers->dbase); ++ } ++ ++ path = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA_LINKED); ++ if (stat(path, &sb) == 0) { ++ retval = semanage_copy_file(path, ++ semanage_path(SEMANAGE_TMP, ++ SEMANAGE_USERS_EXTRA), ++ sh->conf->file_mode); ++ if (retval < 0) ++ goto cleanup; ++ pusers_extra->dtable->drop_cache(pusers_extra->dbase); ++ } else { ++ pusers_extra->dtable->clear(sh, pusers_extra->dbase); ++ } ++ } + +- /* ============= Apply changes, and verify =============== */ ++ /* Attach our databases to the policydb we just created or loaded. */ ++ dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out); ++ dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out); ++ dbase_policydb_attach((dbase_policydb_t *) pibpkeys->dbase, out); ++ dbase_policydb_attach((dbase_policydb_t *) pibendports->dbase, out); ++ dbase_policydb_attach((dbase_policydb_t *) pifaces->dbase, out); ++ dbase_policydb_attach((dbase_policydb_t *) pbools->dbase, out); ++ dbase_policydb_attach((dbase_policydb_t *) pnodes->dbase, out); + +- retval = semanage_base_merge_components(sh); +- if (retval < 0) +- goto cleanup; ++ /* Merge local changes */ ++ retval = semanage_base_merge_components(sh); ++ if (retval < 0) ++ goto cleanup; + +- retval = semanage_write_policydb(sh, out); ++ if (do_write_kernel) { ++ /* Write new kernel policy. */ ++ retval = semanage_write_policydb(sh, out, ++ SEMANAGE_STORE_KERNEL); + if (retval < 0) + goto cleanup; + ++ /* Run the kernel policy verifier, if any. */ + retval = semanage_verify_kernel(sh); + if (retval < 0) + goto cleanup; +- } else { +- retval = semanage_base_merge_components(sh); +- if (retval < 0) +- goto cleanup; + } + + /* ======= Post-process: Validate non-policydb components ===== */ +@@ -1332,26 +1502,39 @@ static int semanage_direct_commit(semanage_handle_t * sh) + * Note: those are still cached, even though they've been + * merged into the main file_contexts. We won't check the + * large file_contexts - checked at compile time */ +- if (sh->do_rebuild || modified || fcontexts_modified) { ++ if (do_rebuild || fcontexts_modified) { + retval = semanage_fcontext_validate_local(sh, out); + if (retval < 0) + goto cleanup; + } + + /* Validate local seusers against policy */ +- if (sh->do_rebuild || modified || seusers_modified) { ++ if (do_rebuild || seusers_modified) { + retval = semanage_seuser_validate_local(sh, out); + if (retval < 0) + goto cleanup; + } + + /* Validate local ports for overlap */ +- if (sh->do_rebuild || modified || ports_modified) { ++ if (do_rebuild || ports_modified) { + retval = semanage_port_validate_local(sh); + if (retval < 0) + goto cleanup; + } + ++ /* Validate local ibpkeys for overlap */ ++ if (do_rebuild || ibpkeys_modified) { ++ retval = semanage_ibpkey_validate_local(sh); ++ if (retval < 0) ++ goto cleanup; ++ } ++ ++ /* Validate local ibendports */ ++ if (do_rebuild || ibendports_modified) { ++ retval = semanage_ibendport_validate_local(sh); ++ if (retval < 0) ++ goto cleanup; ++ } + /* ================== Write non-policydb components ========= */ + + /* Commit changes to components */ +@@ -1367,43 +1550,46 @@ static int semanage_direct_commit(semanage_handle_t * sh) + } + + path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL); +- if (access(path, F_OK) == 0) { +- retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL), +- semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL), +- sh->conf->file_mode); +- if (retval < 0) { +- goto cleanup; +- } ++ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_LOCAL), ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL), ++ sh->conf->file_mode); ++ if (retval < 0 && errno != ENOENT) { ++ goto cleanup; + } + + path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC); +- if (access(path, F_OK) == 0) { +- retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC), +- semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC), +- sh->conf->file_mode); +- if (retval < 0) { +- goto cleanup; +- } ++ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC), ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC), ++ sh->conf->file_mode); ++ if (retval < 0 && errno != ENOENT) { ++ goto cleanup; + } + + path = semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS); +- if (access(path, F_OK) == 0) { +- retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), +- semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS), +- sh->conf->file_mode); +- if (retval < 0) { +- goto cleanup; +- } ++ retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_SEUSERS), ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_SEUSERS), ++ sh->conf->file_mode); ++ if (retval < 0 && errno != ENOENT) { ++ goto cleanup; + } + + /* run genhomedircon if its enabled, this should be the last operation + * which requires the out policydb */ + if (!sh->conf->disable_genhomedircon) { +- if (out && (retval = +- semanage_genhomedircon(sh, out, sh->conf->usepasswd, sh->conf->ignoredirs)) != 0) { +- ERR(sh, "semanage_genhomedircon returned error code %d.", +- retval); +- goto cleanup; ++ if (out){ ++ if ((retval = semanage_genhomedircon(sh, out, sh->conf->usepasswd, ++ sh->conf->ignoredirs)) != 0) { ++ ERR(sh, "semanage_genhomedircon returned error code %d.", retval); ++ goto cleanup; ++ } ++ /* file_contexts.homedirs was created in SEMANAGE_TMP store */ ++ retval = semanage_copy_file( ++ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS), ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS), ++ sh->conf->file_mode); ++ if (retval < 0) { ++ goto cleanup; ++ } + } + } else { + WARN(sh, "WARNING: genhomedircon is disabled. \ +@@ -1415,9 +1601,8 @@ static int semanage_direct_commit(semanage_handle_t * sh) + sepol_policydb_free(out); + out = NULL; + +- if (sh->do_rebuild || modified || bools_modified || fcontexts_modified) { ++ if (do_install) + retval = semanage_install_sandbox(sh); +- } + + cleanup: + for (i = 0; i < num_modinfos; i++) { +@@ -1429,14 +1614,14 @@ cleanup: + free(mod_filenames[i]); + } + +- if (modified || bools_modified) { +- /* Detach from policydb, so it can be freed */ +- dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase); +- dbase_policydb_detach((dbase_policydb_t *) pports->dbase); +- dbase_policydb_detach((dbase_policydb_t *) pifaces->dbase); +- dbase_policydb_detach((dbase_policydb_t *) pnodes->dbase); +- dbase_policydb_detach((dbase_policydb_t *) pbools->dbase); +- } ++ /* Detach from policydb, so it can be freed */ ++ dbase_policydb_detach((dbase_policydb_t *) pusers_base->dbase); ++ dbase_policydb_detach((dbase_policydb_t *) pports->dbase); ++ dbase_policydb_detach((dbase_policydb_t *) pibpkeys->dbase); ++ dbase_policydb_detach((dbase_policydb_t *) pibendports->dbase); ++ dbase_policydb_detach((dbase_policydb_t *) pifaces->dbase); ++ dbase_policydb_detach((dbase_policydb_t *) pnodes->dbase); ++ dbase_policydb_detach((dbase_policydb_t *) pbools->dbase); + + free(mod_filenames); + sepol_policydb_free(out); +@@ -1452,6 +1637,8 @@ cleanup: + semanage_remove_directory(semanage_final_path + (SEMANAGE_FINAL_TMP, + SEMANAGE_FINAL_TOPLEVEL)); ++ umask(mask); ++ + return retval; + } + +@@ -1600,7 +1787,8 @@ static int semanage_direct_extract(semanage_handle_t * sh, + goto cleanup; + } + +- if (access(module_path, F_OK) != 0) { ++ struct stat sb; ++ if (stat(module_path, &sb) != 0) { + ERR(sh, "Module does not exist: %s", module_path); + rc = -1; + goto cleanup; +@@ -1630,7 +1818,7 @@ static int semanage_direct_extract(semanage_handle_t * sh, + goto cleanup; + } + +- if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && access(input_file, F_OK) != 0) { ++ if (extract_cil == 1 && strcmp(_modinfo->lang_ext, "cil") && stat(input_file, &sb) != 0) { + rc = semanage_compile_module(sh, _modinfo); + if (rc < 0) { + goto cleanup; +@@ -1802,6 +1990,7 @@ static int semanage_direct_set_enabled(semanage_handle_t *sh, + const char *path = NULL; + FILE *fp = NULL; + semanage_module_info_t *modinfo = NULL; ++ mode_t mask; + + /* check transaction */ + if (!sh->is_in_transaction) { +@@ -1862,7 +2051,9 @@ static int semanage_direct_set_enabled(semanage_handle_t *sh, + + switch (enabled) { + case 0: /* disable the module */ ++ mask = umask(0077); + fp = fopen(fn, "w"); ++ umask(mask); + + if (fp == NULL) { + ERR(sh, +@@ -1931,7 +2122,7 @@ int semanage_direct_mls_enabled(semanage_handle_t * sh) + if (retval < 0) + goto cleanup; + +- retval = semanage_read_policydb(sh, p); ++ retval = semanage_read_policydb(sh, p, SEMANAGE_STORE_KERNEL); + if (retval < 0) + goto cleanup; + +@@ -2075,6 +2266,31 @@ static int semanage_direct_get_module_info(semanage_handle_t *sh, + free(tmp); + tmp = NULL; + ++ if (strcmp((*modinfo)->lang_ext, "pp") == 0) { ++ /* try to get a module_version from hll file */ ++ int data_len, compressed = 0; ++ char *data = NULL; ++ char fhll[PATH_MAX]; ++ ret = semanage_module_get_path(sh, ++ *modinfo, ++ SEMANAGE_MODULE_PATH_HLL, ++ fhll, ++ sizeof(fhll)); ++ if (ret == 0 && (access(fhll, R_OK) == 0)) { ++ if ((data_len = map_file(sh, fhll, &data, &compressed)) > 0) { ++ ++ char *module_name = NULL; ++ char *version = NULL; ++ ret = parse_module_headers(sh, data, data_len, &module_name, &version); ++ if (ret == 0 && version != NULL) { ++ ret = semanage_module_info_set_version(sh, *modinfo, version); ++ } ++ free(module_name); ++ free(version); ++ munmap(data, data_len); ++ } ++ } ++ } + if (fclose(fp) != 0) { + ERR(sh, + "Unable to close %s module lang ext file.", +@@ -2516,6 +2732,7 @@ static int semanage_direct_install_info(semanage_handle_t *sh, + int type; + + char path[PATH_MAX]; ++ mode_t mask = umask(0077); + + semanage_module_info_t *higher_info = NULL; + semanage_module_key_t higher_key; +@@ -2613,7 +2830,8 @@ static int semanage_direct_install_info(semanage_handle_t *sh, + goto cleanup; + } + +- if (access(path, F_OK) == 0) { ++ struct stat sb; ++ if (stat(path, &sb) == 0) { + ret = unlink(path); + if (ret != 0) { + ERR(sh, "Error while removing cached CIL file %s: %s", path, strerror(errno)); +@@ -2627,6 +2845,7 @@ cleanup: + semanage_module_key_destroy(sh, &higher_key); + semanage_module_info_destroy(sh, higher_info); + free(higher_info); ++ umask(mask); + + return status; + } +diff --git libsemanage-2.5/src/exception.sh libsemanage-2.5/src/exception.sh +index 94619d2..d18959c 100644 +--- libsemanage-2.5/src/exception.sh ++++ libsemanage-2.5/src/exception.sh +@@ -9,6 +9,6 @@ echo " + } + " + } +-gcc -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h ++${CC:-gcc} -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h + for i in `awk '/extern int/ { print $6 }' temp.aux`; do except $i ; done + rm -f -- temp.aux -.o +diff --git libsemanage-2.5/src/fcontexts_policy.c libsemanage-2.5/src/fcontexts_policy.c +index 0b063b1..98490ab 100644 +--- libsemanage-2.5/src/fcontexts_policy.c ++++ libsemanage-2.5/src/fcontexts_policy.c +@@ -51,3 +51,11 @@ int semanage_fcontext_list(semanage_handle_t * handle, + dbase_config_t *dconfig = semanage_fcontext_dbase_policy(handle); + return dbase_list(handle, dconfig, records, count); + } ++ ++int semanage_fcontext_list_homedirs(semanage_handle_t * handle, ++ semanage_fcontext_t *** records, unsigned int *count) ++{ ++ ++ dbase_config_t *dconfig = semanage_fcontext_dbase_homedirs(handle); ++ return dbase_list(handle, dconfig, records, count); ++} +diff --git libsemanage-2.5/src/genhomedircon.c libsemanage-2.5/src/genhomedircon.c +index 1a9e87e..d32c147 100644 +--- libsemanage-2.5/src/genhomedircon.c ++++ libsemanage-2.5/src/genhomedircon.c +@@ -48,6 +48,8 @@ + #include + #include + #include ++#include ++#include + + /* paths used in get_home_dirs() */ + #define PATH_ETC_USERADD "/etc/default/useradd" +@@ -73,36 +75,44 @@ + which are searched for and replaced */ + #define TEMPLATE_HOME_ROOT "HOME_ROOT" + #define TEMPLATE_HOME_DIR "HOME_DIR" ++/* these are legacy */ + #define TEMPLATE_USER "USER" + #define TEMPLATE_ROLE "ROLE" ++/* new names */ ++#define TEMPLATE_USERNAME "%{USERNAME}" ++#define TEMPLATE_USERID "%{USERID}" ++ + #define TEMPLATE_SEUSER "system_u" + #define TEMPLATE_LEVEL "s0" + +-#define FALLBACK_USER "user_u" +-#define FALLBACK_USER_PREFIX "user" +-#define FALLBACK_USER_LEVEL "s0" ++#define FALLBACK_SENAME "user_u" ++#define FALLBACK_PREFIX "user" ++#define FALLBACK_LEVEL "s0" ++#define FALLBACK_NAME "[^/]+" ++#define FALLBACK_UIDGID "[0-9]+" + #define DEFAULT_LOGIN "__default__" + +-typedef struct { +- const char *fcfilepath; +- int usepasswd; +- const char *homedir_template_path; +- char *fallback_user; +- char *fallback_user_prefix; +- char *fallback_user_level; +- semanage_handle_t *h_semanage; +- sepol_policydb_t *policydb; +-} genhomedircon_settings_t; +- + typedef struct user_entry { + char *name; ++ char *uid; ++ char *gid; + char *sename; + char *prefix; + char *home; + char *level; ++ char *login; + struct user_entry *next; + } genhomedircon_user_entry_t; + ++typedef struct { ++ const char *fcfilepath; ++ int usepasswd; ++ const char *homedir_template_path; ++ genhomedircon_user_entry_t *fallback; ++ semanage_handle_t *h_semanage; ++ sepol_policydb_t *policydb; ++} genhomedircon_settings_t; ++ + typedef struct { + const char *search_for; + const char *replace_with; +@@ -461,11 +471,29 @@ static int HOME_DIR_PRED(const char *string) + return semanage_is_prefix(string, TEMPLATE_HOME_DIR); + } + ++/* new names */ ++static int USERNAME_CONTEXT_PRED(const char *string) ++{ ++ return (int)( ++ (strstr(string, TEMPLATE_USERNAME) != NULL) || ++ (strstr(string, TEMPLATE_USERID) != NULL) ++ ); ++} ++ ++/* This will never match USER if USERNAME or USERID are found. */ + static int USER_CONTEXT_PRED(const char *string) + { ++ if (USERNAME_CONTEXT_PRED(string)) ++ return 0; ++ + return (int)(strstr(string, TEMPLATE_USER) != NULL); + } + ++static int STR_COMPARATOR(const void *a, const void *b) ++{ ++ return strcmp((const char *) a, (const char *) b); ++} ++ + /* make_tempate + * @param s the settings holding the paths to various files + * @param pred function pointer to function to use as filter for slurp +@@ -548,23 +576,12 @@ static int check_line(genhomedircon_settings_t * s, Ustr *line) + return result; + } + +-static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, +- semanage_list_t * tpl, const char *user, +- const char *seuser, const char *home, +- const char *role_prefix, const char *level) ++static int write_replacements(genhomedircon_settings_t * s, FILE * out, ++ const semanage_list_t * tpl, ++ const replacement_pair_t *repl) + { +- replacement_pair_t repl[] = { +- {.search_for = TEMPLATE_SEUSER,.replace_with = seuser}, +- {.search_for = TEMPLATE_HOME_DIR,.replace_with = home}, +- {.search_for = TEMPLATE_ROLE,.replace_with = role_prefix}, +- {.search_for = TEMPLATE_LEVEL,.replace_with = level}, +- {NULL, NULL} +- }; + Ustr *line = USTR_NULL; + +- if (fprintf(out, COMMENT_USER_HOME_CONTEXT, user) < 0) +- return STATUS_ERR; +- + for (; tpl; tpl = tpl->next) { + line = replace_all(tpl->data, repl); + if (!line) +@@ -582,6 +599,28 @@ static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, + return STATUS_ERR; + } + ++static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, ++ semanage_list_t * tpl, const genhomedircon_user_entry_t *user) ++{ ++ replacement_pair_t repl[] = { ++ {.search_for = TEMPLATE_SEUSER,.replace_with = user->sename}, ++ {.search_for = TEMPLATE_HOME_DIR,.replace_with = user->home}, ++ {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, ++ {.search_for = TEMPLATE_LEVEL,.replace_with = user->level}, ++ {NULL, NULL} ++ }; ++ ++ if (strcmp(user->name, FALLBACK_NAME) == 0) { ++ if (fprintf(out, COMMENT_USER_HOME_CONTEXT, FALLBACK_SENAME) < 0) ++ return STATUS_ERR; ++ } else { ++ if (fprintf(out, COMMENT_USER_HOME_CONTEXT, user->name) < 0) ++ return STATUS_ERR; ++ } ++ ++ return write_replacements(s, out, tpl, repl); ++} ++ + static int write_home_root_context(genhomedircon_settings_t * s, FILE * out, + semanage_list_t * tpl, char *homedir) + { +@@ -589,52 +628,54 @@ static int write_home_root_context(genhomedircon_settings_t * s, FILE * out, + {.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir}, + {NULL, NULL} + }; +- Ustr *line = USTR_NULL; + +- for (; tpl; tpl = tpl->next) { +- line = replace_all(tpl->data, repl); +- if (!line) +- goto fail; +- if (check_line(s, line) == STATUS_SUCCESS) { +- if (!ustr_io_putfileline(&line, out)) +- goto fail; +- } +- ustr_sc_free(&line); +- } +- return STATUS_SUCCESS; ++ return write_replacements(s, out, tpl, repl); ++} + +- fail: +- ustr_sc_free(&line); +- return STATUS_ERR; ++static int write_username_context(genhomedircon_settings_t * s, FILE * out, ++ semanage_list_t * tpl, ++ const genhomedircon_user_entry_t *user) ++{ ++ replacement_pair_t repl[] = { ++ {.search_for = TEMPLATE_USERNAME,.replace_with = user->name}, ++ {.search_for = TEMPLATE_USERID,.replace_with = user->uid}, ++ {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, ++ {.search_for = TEMPLATE_SEUSER,.replace_with = user->sename}, ++ {NULL, NULL} ++ }; ++ ++ return write_replacements(s, out, tpl, repl); + } + + static int write_user_context(genhomedircon_settings_t * s, FILE * out, +- semanage_list_t * tpl, const char *user, +- const char *seuser, const char *role_prefix) ++ semanage_list_t * tpl, const genhomedircon_user_entry_t *user) + { + replacement_pair_t repl[] = { +- {.search_for = TEMPLATE_USER,.replace_with = user}, +- {.search_for = TEMPLATE_ROLE,.replace_with = role_prefix}, +- {.search_for = TEMPLATE_SEUSER,.replace_with = seuser}, ++ {.search_for = TEMPLATE_USER,.replace_with = user->name}, ++ {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, ++ {.search_for = TEMPLATE_SEUSER,.replace_with = user->sename}, + {NULL, NULL} + }; +- Ustr *line = USTR_NULL; + +- for (; tpl; tpl = tpl->next) { +- line = replace_all(tpl->data, repl); +- if (!line) +- goto fail; +- if (check_line(s, line) == STATUS_SUCCESS) { +- if (!ustr_io_putfileline(&line, out)) +- goto fail; +- } +- ustr_sc_free(&line); ++ return write_replacements(s, out, tpl, repl); ++} ++ ++static int seuser_sort_func(const void *arg1, const void *arg2) ++{ ++ const semanage_seuser_t **u1 = (const semanage_seuser_t **) arg1; ++ const semanage_seuser_t **u2 = (const semanage_seuser_t **) arg2;; ++ const char *name1 = semanage_seuser_get_name(*u1); ++ const char *name2 = semanage_seuser_get_name(*u2); ++ ++ if (name1[0] == '%' && name2[0] == '%') { ++ return 0; ++ } else if (name1[0] == '%') { ++ return 1; ++ } else if (name2[0] == '%') { ++ return -1; + } +- return STATUS_SUCCESS; + +- fail: +- ustr_sc_free(&line); +- return STATUS_ERR; ++ return strcmp(name1, name2); + } + + static int user_sort_func(semanage_user_t ** arg1, semanage_user_t ** arg2) +@@ -649,15 +690,19 @@ static int name_user_cmp(char *key, semanage_user_t ** val) + } + + static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, +- const char *sen, const char *pre, const char *h, +- const char *l) ++ const char *u, const char *g, const char *sen, ++ const char *pre, const char *h, const char *l, ++ const char *ln) + { + genhomedircon_user_entry_t *temp = NULL; + char *name = NULL; ++ char *uid = NULL; ++ char *gid = NULL; + char *sename = NULL; + char *prefix = NULL; + char *home = NULL; + char *level = NULL; ++ char *lname = NULL; + + temp = malloc(sizeof(genhomedircon_user_entry_t)); + if (!temp) +@@ -665,6 +710,12 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, + name = strdup(n); + if (!name) + goto cleanup; ++ uid = strdup(u); ++ if (!uid) ++ goto cleanup; ++ gid = strdup(g); ++ if (!gid) ++ goto cleanup; + sename = strdup(sen); + if (!sename) + goto cleanup; +@@ -677,12 +728,18 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, + level = strdup(l); + if (!level) + goto cleanup; ++ lname = strdup(ln); ++ if (!lname) ++ goto cleanup; + + temp->name = name; ++ temp->uid = uid; ++ temp->gid = gid; + temp->sename = sename; + temp->prefix = prefix; + temp->home = home; + temp->level = level; ++ temp->login = lname; + temp->next = (*list); + (*list) = temp; + +@@ -690,10 +747,13 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, + + cleanup: + free(name); ++ free(uid); ++ free(gid); + free(sename); + free(prefix); + free(home); + free(level); ++ free(lname); + free(temp); + return STATUS_ERR; + } +@@ -708,39 +768,16 @@ static void pop_user_entry(genhomedircon_user_entry_t ** list) + temp = *list; + *list = temp->next; + free(temp->name); ++ free(temp->uid); ++ free(temp->gid); + free(temp->sename); + free(temp->prefix); + free(temp->home); + free(temp->level); ++ free(temp->login); + free(temp); + } + +-static int set_fallback_user(genhomedircon_settings_t *s, const char *user, +- const char *prefix, const char *level) +-{ +- char *fallback_user = strdup(user); +- char *fallback_user_prefix = strdup(prefix); +- char *fallback_user_level = NULL; +- if (level) +- fallback_user_level = strdup(level); +- +- if (fallback_user == NULL || fallback_user_prefix == NULL || +- (fallback_user_level == NULL && level != NULL)) { +- free(fallback_user); +- free(fallback_user_prefix); +- free(fallback_user_level); +- return STATUS_ERR; +- } +- +- free(s->fallback_user); +- free(s->fallback_user_prefix); +- free(s->fallback_user_level); +- s->fallback_user = fallback_user; +- s->fallback_user_prefix = fallback_user_prefix; +- s->fallback_user_level = fallback_user_level; +- return STATUS_SUCCESS; +-} +- + static int setup_fallback_user(genhomedircon_settings_t * s) + { + semanage_seuser_t **seuser_list = NULL; +@@ -775,17 +812,20 @@ static int setup_fallback_user(genhomedircon_settings_t * s) + if (semanage_user_query(s->h_semanage, key, &u) < 0) + { + prefix = name; +- level = FALLBACK_USER_LEVEL; ++ level = FALLBACK_LEVEL; + } + else + { + prefix = semanage_user_get_prefix(u); + level = semanage_user_get_mlslevel(u); + if (!level) +- level = FALLBACK_USER_LEVEL; ++ level = FALLBACK_LEVEL; + } + +- if (set_fallback_user(s, seuname, prefix, level) != 0) ++ if (push_user_entry(&(s->fallback), FALLBACK_NAME, ++ FALLBACK_UIDGID, FALLBACK_UIDGID, ++ seuname, prefix, "", level, ++ FALLBACK_NAME) != 0) + errors = STATUS_ERR; + semanage_user_key_free(key); + if (u) +@@ -801,6 +841,212 @@ static int setup_fallback_user(genhomedircon_settings_t * s) + return errors; + } + ++static genhomedircon_user_entry_t *find_user(genhomedircon_user_entry_t *head, ++ const char *name) ++{ ++ for(; head; head = head->next) { ++ if (strcmp(head->name, name) == 0) { ++ return head; ++ } ++ } ++ ++ return NULL; ++} ++ ++static int add_user(genhomedircon_settings_t * s, ++ genhomedircon_user_entry_t **head, ++ semanage_user_t *user, ++ const char *name, ++ const char *sename, ++ const char *selogin) ++{ ++ if (selogin[0] == '%') { ++ genhomedircon_user_entry_t *orig = find_user(*head, name); ++ if (orig != NULL && orig->login[0] == '%') { ++ ERR(s->h_semanage, "User %s is already mapped to" ++ " group %s, but also belongs to group %s. Add an" ++ " explicit mapping for this user to" ++ " override group mappings.", ++ name, orig->login + 1, selogin + 1); ++ return STATUS_ERR; ++ } else if (orig != NULL) { ++ // user mappings take precedence ++ return STATUS_SUCCESS; ++ } ++ } ++ ++ int retval = STATUS_ERR; ++ ++ char *rbuf = NULL; ++ long rbuflen; ++ struct passwd pwstorage, *pwent = NULL; ++ const char *prefix = NULL; ++ const char *level = NULL; ++ char uid[11]; ++ char gid[11]; ++ ++ /* Allocate space for the getpwnam_r buffer */ ++ rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); ++ if (rbuflen <= 0) ++ goto cleanup; ++ rbuf = malloc(rbuflen); ++ if (rbuf == NULL) ++ goto cleanup; ++ ++ if (user) { ++ prefix = semanage_user_get_prefix(user); ++ level = semanage_user_get_mlslevel(user); ++ ++ if (!level) { ++ level = FALLBACK_LEVEL; ++ } ++ } else { ++ prefix = name; ++ level = FALLBACK_LEVEL; ++ } ++ ++ retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); ++ if (retval != 0 || pwent == NULL) { ++ if (retval != 0 && retval != ENOENT) { ++ goto cleanup; ++ } ++ ++ WARN(s->h_semanage, ++ "user %s not in password file", name); ++ retval = STATUS_SUCCESS; ++ goto cleanup; ++ } ++ ++ int len = strlen(pwent->pw_dir) -1; ++ for(; len > 0 && pwent->pw_dir[len] == '/'; len--) { ++ pwent->pw_dir[len] = '\0'; ++ } ++ ++ if (strcmp(pwent->pw_dir, "/") == 0) { ++ /* don't relabel / genhomdircon checked to see if root ++ * was the user and if so, set his home directory to ++ * /root */ ++ retval = STATUS_SUCCESS; ++ goto cleanup; ++ } ++ ++ if (ignore(pwent->pw_dir)) { ++ retval = STATUS_SUCCESS; ++ goto cleanup; ++ } ++ ++ len = snprintf(uid, sizeof(uid), "%u", pwent->pw_uid); ++ if (len < 0 || len >= (int)sizeof(uid)) { ++ goto cleanup; ++ } ++ ++ len = snprintf(gid, sizeof(gid), "%u", pwent->pw_gid); ++ if (len < 0 || len >= (int)sizeof(gid)) { ++ goto cleanup; ++ } ++ ++ retval = push_user_entry(head, name, uid, gid, sename, prefix, ++ pwent->pw_dir, level, selogin); ++cleanup: ++ free(rbuf); ++ return retval; ++} ++ ++static int get_group_users(genhomedircon_settings_t * s, ++ genhomedircon_user_entry_t **head, ++ semanage_user_t *user, ++ const char *sename, ++ const char *selogin) ++{ ++ int retval = STATUS_ERR; ++ unsigned int i; ++ ++ long grbuflen; ++ char *grbuf = NULL; ++ struct group grstorage, *group = NULL; ++ ++ long prbuflen; ++ char *pwbuf = NULL; ++ struct passwd pwstorage, *pw = NULL; ++ ++ grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); ++ if (grbuflen <= 0) ++ goto cleanup; ++ grbuf = malloc(grbuflen); ++ if (grbuf == NULL) ++ goto cleanup; ++ ++ const char *grname = selogin + 1; ++ ++ errno = 0; ++ while ( ++ (retval = getgrnam_r(grname, &grstorage, grbuf, (size_t) grbuflen, &group)) != 0 && ++ errno == ERANGE ++ ) { ++ char *new_grbuf; ++ grbuflen *= 2; ++ new_grbuf = realloc(grbuf, grbuflen); ++ if (new_grbuf == NULL) ++ goto cleanup; ++ grbuf = new_grbuf; ++ } ++ if (retval == -1) ++ goto cleanup; ++ ++ if (group == NULL) { ++ ERR(s->h_semanage, "Can't find group named %s\n", grname); ++ goto cleanup; ++ } ++ ++ size_t nmembers = 0; ++ char **members = group->gr_mem; ++ ++ while (*members != NULL) { ++ nmembers++; ++ members++; ++ } ++ ++ for (i = 0; i < nmembers; i++) { ++ const char *uname = group->gr_mem[i]; ++ ++ if (add_user(s, head, user, uname, sename, selogin) < 0) { ++ goto cleanup; ++ } ++ } ++ ++ prbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); ++ if (prbuflen <= 0) ++ goto cleanup; ++ pwbuf = malloc(prbuflen); ++ if (pwbuf == NULL) ++ goto cleanup; ++ ++ setpwent(); ++ while ((retval = getpwent_r(&pwstorage, pwbuf, prbuflen, &pw)) == 0) { ++ // skip users who also have this group as their ++ // primary group ++ if (lfind(pw->pw_name, group->gr_mem, &nmembers, ++ sizeof(char *), &STR_COMPARATOR)) { ++ continue; ++ } ++ ++ if (group->gr_gid == pw->pw_gid) { ++ if (add_user(s, head, user, pw->pw_name, ++ sename, selogin) < 0) { ++ goto cleanup; ++ } ++ } ++ } ++ ++ retval = STATUS_SUCCESS; ++cleanup: ++ endpwent(); ++ free(pwbuf); ++ free(grbuf); ++ ++ return retval; ++} ++ + static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, + int *errors) + { +@@ -812,12 +1058,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, + semanage_user_t **u = NULL; + const char *name = NULL; + const char *seuname = NULL; +- const char *prefix = NULL; +- const char *level = NULL; +- struct passwd pwstorage, *pwent = NULL; + unsigned int i; +- long rbuflen; +- char *rbuf = NULL; + int retval; + + *errors = 0; +@@ -831,82 +1072,42 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, + nusers = 0; + } + ++ qsort(seuser_list, nseusers, sizeof(semanage_seuser_t *), ++ &seuser_sort_func); + qsort(user_list, nusers, sizeof(semanage_user_t *), + (int (*)(const void *, const void *))&user_sort_func); + +- /* Allocate space for the getpwnam_r buffer */ +- rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); +- if (rbuflen <= 0) +- goto cleanup; +- rbuf = malloc(rbuflen); +- if (rbuf == NULL) +- goto cleanup; +- + for (i = 0; i < nseusers; i++) { + seuname = semanage_seuser_get_sename(seuser_list[i]); + name = semanage_seuser_get_name(seuser_list[i]); + +- if (strcmp(name,"root") && strcmp(seuname, s->fallback_user) == 0) +- continue; +- + if (strcmp(name, DEFAULT_LOGIN) == 0) + continue; + + if (strcmp(name, TEMPLATE_SEUSER) == 0) + continue; + +- /* %groupname syntax */ +- if (name[0] == '%') +- continue; +- + /* find the user structure given the name */ + u = bsearch(seuname, user_list, nusers, sizeof(semanage_user_t *), + (int (*)(const void *, const void *)) + &name_user_cmp); +- if (u) { +- prefix = semanage_user_get_prefix(*u); +- level = semanage_user_get_mlslevel(*u); +- if (!level) +- level = FALLBACK_USER_LEVEL; +- } else { +- prefix = name; +- level = FALLBACK_USER_LEVEL; +- } +- +- retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); +- if (retval != 0 || pwent == NULL) { +- if (retval != 0 && retval != ENOENT) { +- *errors = STATUS_ERR; +- goto cleanup; +- } +- +- WARN(s->h_semanage, +- "user %s not in password file", name); +- continue; +- } + +- int len = strlen(pwent->pw_dir) -1; +- for(; len > 0 && pwent->pw_dir[len] == '/'; len--) { +- pwent->pw_dir[len] = '\0'; ++ /* %groupname syntax */ ++ if (name[0] == '%') { ++ retval = get_group_users(s, &head, *u, seuname, ++ name); ++ } else { ++ retval = add_user(s, &head, *u, name, ++ seuname, name); + } + +- if (strcmp(pwent->pw_dir, "/") == 0) { +- /* don't relabel / genhomdircon checked to see if root +- * was the user and if so, set his home directory to +- * /root */ +- continue; +- } +- if (ignore(pwent->pw_dir)) +- continue; +- if (push_user_entry(&head, name, seuname, +- prefix, pwent->pw_dir, level) != STATUS_SUCCESS) { ++ if (retval != 0) { + *errors = STATUS_ERR; +- break; ++ goto cleanup; + } + } + + cleanup: +- free(rbuf); + if (*errors) { + for (; head; pop_user_entry(&head)) { + /* the pop function takes care of all the cleanup +@@ -927,6 +1128,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, + } + + static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out, ++ semanage_list_t * username_context_tpl, + semanage_list_t * user_context_tpl, + semanage_list_t * homedir_context_tpl) + { +@@ -939,13 +1141,11 @@ static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out, + } + + for (; users; pop_user_entry(&users)) { +- if (write_home_dir_context(s, out, homedir_context_tpl, +- users->name, +- users->sename, users->home, +- users->prefix, users->level)) ++ if (write_home_dir_context(s, out, homedir_context_tpl, users)) + goto err; +- if (write_user_context(s, out, user_context_tpl, users->name, +- users->sename, users->prefix)) ++ if (write_username_context(s, out, username_context_tpl, users)) ++ goto err; ++ if (write_user_context(s, out, user_context_tpl, users)) + goto err; + } + +@@ -968,16 +1168,21 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) + { + semanage_list_t *homedirs = NULL; + semanage_list_t *h = NULL; +- semanage_list_t *user_context_tpl = NULL; + semanage_list_t *homedir_context_tpl = NULL; + semanage_list_t *homeroot_context_tpl = NULL; ++ semanage_list_t *username_context_tpl = NULL; ++ semanage_list_t *user_context_tpl = NULL; + int retval = STATUS_SUCCESS; + + homedir_context_tpl = make_template(s, &HOME_DIR_PRED); + homeroot_context_tpl = make_template(s, &HOME_ROOT_PRED); ++ username_context_tpl = make_template(s, &USERNAME_CONTEXT_PRED); + user_context_tpl = make_template(s, &USER_CONTEXT_PRED); + +- if (!homedir_context_tpl && !homeroot_context_tpl && !user_context_tpl) ++ if (!homedir_context_tpl ++ && !homeroot_context_tpl ++ && !username_context_tpl ++ && !user_context_tpl) + goto done; + + if (write_file_context_header(out) != STATUS_SUCCESS) { +@@ -1001,19 +1206,19 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) + for (h = homedirs; h; h = h->next) { + Ustr *temp = ustr_dup_cstr(h->data); + +- if (!temp || !ustr_add_cstr(&temp, "/[^/]*")) { ++ if (!temp || !ustr_add_cstr(&temp, "/" FALLBACK_NAME)) { + ustr_sc_free(&temp); + retval = STATUS_ERR; + goto done; + } + +- if (write_home_dir_context(s, out, +- homedir_context_tpl, +- s->fallback_user, s->fallback_user, +- ustr_cstr(temp), +- s->fallback_user_prefix, s->fallback_user_level) != +- STATUS_SUCCESS) { ++ free(s->fallback->home); ++ s->fallback->home = (char*) ustr_cstr(temp); ++ ++ if (write_home_dir_context(s, out, homedir_context_tpl, ++ s->fallback) != STATUS_SUCCESS) { + ustr_sc_free(&temp); ++ s->fallback->home = NULL; + retval = STATUS_ERR; + goto done; + } +@@ -1021,23 +1226,31 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) + homeroot_context_tpl, + h->data) != STATUS_SUCCESS) { + ustr_sc_free(&temp); ++ s->fallback->home = NULL; + retval = STATUS_ERR; + goto done; + } + + ustr_sc_free(&temp); ++ s->fallback->home = NULL; + } + } +- if (user_context_tpl) { ++ if (user_context_tpl || username_context_tpl) { ++ if (write_username_context(s, out, username_context_tpl, ++ s->fallback) != STATUS_SUCCESS) { ++ retval = STATUS_ERR; ++ goto done; ++ } ++ + if (write_user_context(s, out, user_context_tpl, +- ".*", s->fallback_user, +- s->fallback_user_prefix) != STATUS_SUCCESS) { ++ s->fallback) != STATUS_SUCCESS) { + retval = STATUS_ERR; + goto done; + } + +- if (write_gen_home_dir_context(s, out, user_context_tpl, +- homedir_context_tpl) != STATUS_SUCCESS) { ++ if (write_gen_home_dir_context(s, out, username_context_tpl, ++ user_context_tpl, homedir_context_tpl) ++ != STATUS_SUCCESS) { + retval = STATUS_ERR; + } + } +@@ -1045,6 +1258,7 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) + done: + /* Cleanup */ + semanage_list_destroy(&homedirs); ++ semanage_list_destroy(&username_context_tpl); + semanage_list_destroy(&user_context_tpl); + semanage_list_destroy(&homedir_context_tpl); + semanage_list_destroy(&homeroot_context_tpl); +@@ -1065,13 +1279,23 @@ int semanage_genhomedircon(semanage_handle_t * sh, + + s.homedir_template_path = + semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL); +- s.fcfilepath = semanage_final_path(SEMANAGE_FINAL_TMP, +- SEMANAGE_FC_HOMEDIRS); ++ s.fcfilepath = ++ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS); ++ ++ s.fallback = calloc(1, sizeof(genhomedircon_user_entry_t)); ++ if (s.fallback == NULL) { ++ retval = STATUS_ERR; ++ goto done; ++ } + +- s.fallback_user = strdup(FALLBACK_USER); +- s.fallback_user_prefix = strdup(FALLBACK_USER_PREFIX); +- s.fallback_user_level = strdup(FALLBACK_USER_LEVEL); +- if (s.fallback_user == NULL || s.fallback_user_prefix == NULL || s.fallback_user_level == NULL) { ++ s.fallback->name = strdup(FALLBACK_NAME); ++ s.fallback->sename = strdup(FALLBACK_SENAME); ++ s.fallback->prefix = strdup(FALLBACK_PREFIX); ++ s.fallback->level = strdup(FALLBACK_LEVEL); ++ if (s.fallback->name == NULL ++ || s.fallback->sename == NULL ++ || s.fallback->prefix == NULL ++ || s.fallback->level == NULL) { + retval = STATUS_ERR; + goto done; + } +@@ -1095,9 +1319,7 @@ done: + if (out != NULL) + fclose(out); + +- free(s.fallback_user); +- free(s.fallback_user_prefix); +- free(s.fallback_user_level); ++ pop_user_entry(&(s.fallback)); + ignore_free(); + + return retval; +diff --git libsemanage-2.5/src/handle.h libsemanage-2.5/src/handle.h +index 64175c4..1780ac8 100644 +--- libsemanage-2.5/src/handle.h ++++ libsemanage-2.5/src/handle.h +@@ -79,7 +79,7 @@ struct semanage_handle { + struct semanage_policy_table *funcs; + + /* Object databases */ +-#define DBASE_COUNT 19 ++#define DBASE_COUNT 24 + + /* Local modifications */ + #define DBASE_LOCAL_USERS_BASE 0 +@@ -91,20 +91,25 @@ struct semanage_handle { + #define DBASE_LOCAL_FCONTEXTS 6 + #define DBASE_LOCAL_SEUSERS 7 + #define DBASE_LOCAL_NODES 8 ++#define DBASE_LOCAL_IBPKEYS 9 ++#define DBASE_LOCAL_IBENDPORTS 10 + + /* Policy + Local modifications */ +-#define DBASE_POLICY_USERS_BASE 9 +-#define DBASE_POLICY_USERS_EXTRA 10 +-#define DBASE_POLICY_USERS 11 +-#define DBASE_POLICY_PORTS 12 +-#define DBASE_POLICY_INTERFACES 13 +-#define DBASE_POLICY_BOOLEANS 14 +-#define DBASE_POLICY_FCONTEXTS 15 +-#define DBASE_POLICY_SEUSERS 16 +-#define DBASE_POLICY_NODES 17 ++#define DBASE_POLICY_USERS_BASE 11 ++#define DBASE_POLICY_USERS_EXTRA 12 ++#define DBASE_POLICY_USERS 13 ++#define DBASE_POLICY_PORTS 14 ++#define DBASE_POLICY_INTERFACES 15 ++#define DBASE_POLICY_BOOLEANS 16 ++#define DBASE_POLICY_FCONTEXTS 17 ++#define DBASE_POLICY_FCONTEXTS_H 18 ++#define DBASE_POLICY_SEUSERS 19 ++#define DBASE_POLICY_NODES 20 ++#define DBASE_POLICY_IBPKEYS 21 ++#define DBASE_POLICY_IBENDPORTS 22 + + /* Active kernel policy */ +-#define DBASE_ACTIVE_BOOLEANS 18 ++#define DBASE_ACTIVE_BOOLEANS 23 + dbase_config_t dbase[DBASE_COUNT]; + }; + +@@ -133,6 +138,18 @@ static inline + return &handle->dbase[DBASE_LOCAL_PORTS]; + } + ++static inline ++ dbase_config_t * semanage_ibpkey_dbase_local(semanage_handle_t * handle) ++{ ++ return &handle->dbase[DBASE_LOCAL_IBPKEYS]; ++} ++ ++static inline ++ dbase_config_t * semanage_ibendport_dbase_local(semanage_handle_t * handle) ++{ ++ return &handle->dbase[DBASE_LOCAL_IBENDPORTS]; ++} ++ + static inline + dbase_config_t * semanage_iface_dbase_local(semanage_handle_t * handle) + { +@@ -189,6 +206,18 @@ static inline + return &handle->dbase[DBASE_POLICY_PORTS]; + } + ++static inline ++ dbase_config_t * semanage_ibpkey_dbase_policy(semanage_handle_t * handle) ++{ ++ return &handle->dbase[DBASE_POLICY_IBPKEYS]; ++} ++ ++static inline ++ dbase_config_t * semanage_ibendport_dbase_policy(semanage_handle_t * handle) ++{ ++ return &handle->dbase[DBASE_POLICY_IBENDPORTS]; ++} ++ + static inline + dbase_config_t * semanage_iface_dbase_policy(semanage_handle_t * handle) + { +@@ -207,6 +236,12 @@ static inline + return &handle->dbase[DBASE_POLICY_FCONTEXTS]; + } + ++static inline ++ dbase_config_t * semanage_fcontext_dbase_homedirs(semanage_handle_t * handle) ++{ ++ return &handle->dbase[DBASE_POLICY_FCONTEXTS_H]; ++} ++ + static inline + dbase_config_t * semanage_seuser_dbase_policy(semanage_handle_t * handle) + { +diff --git libsemanage-2.5/src/ibendport_internal.h libsemanage-2.5/src/ibendport_internal.h +new file mode 100644 +index 0000000..970fbdb +--- /dev/null ++++ libsemanage-2.5/src/ibendport_internal.h +@@ -0,0 +1,48 @@ ++#ifndef _SEMANAGE_IBENDPORT_INTERNAL_H_ ++#define _SEMANAGE_IBENDPORT_INTERNAL_H_ ++ ++#include ++#include ++#include ++#include "database.h" ++#include "handle.h" ++#include "dso.h" ++ ++hidden_proto(semanage_ibendport_create) ++hidden_proto(semanage_ibendport_compare) ++hidden_proto(semanage_ibendport_compare2) ++hidden_proto(semanage_ibendport_clone) ++hidden_proto(semanage_ibendport_free) ++hidden_proto(semanage_ibendport_key_extract) ++hidden_proto(semanage_ibendport_key_free) ++hidden_proto(semanage_ibendport_get_port) ++hidden_proto(semanage_ibendport_set_port) ++hidden_proto(semanage_ibendport_get_con) ++hidden_proto(semanage_ibendport_set_con) ++hidden_proto(semanage_ibendport_list_local) ++hidden_proto(semanage_ibendport_get_ibdev_name) ++hidden_proto(semanage_ibendport_set_ibdev_name) ++ ++/* IBENDPORT RECORD: method table */ ++extern record_table_t SEMANAGE_IBENDPORT_RTABLE; ++ ++extern int ibendport_file_dbase_init(semanage_handle_t *handle, ++ const char *path_ro, ++ const char *path_rw, ++ dbase_config_t *dconfig); ++ ++extern void ibendport_file_dbase_release(dbase_config_t *dconfig); ++ ++extern int ibendport_policydb_dbase_init(semanage_handle_t *handle, ++ dbase_config_t *dconfig); ++ ++extern void ibendport_policydb_dbase_release(dbase_config_t *dconfig); ++ ++extern int hidden semanage_ibendport_validate_local(semanage_handle_t *handle); ++ ++/* ==== Internal (to ibendports) API === */ ++ ++hidden int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport, ++ const semanage_ibendport_t **ibendport2); ++ ++#endif +diff --git libsemanage-2.5/src/ibendport_record.c libsemanage-2.5/src/ibendport_record.c +new file mode 100644 +index 0000000..955067e +--- /dev/null ++++ libsemanage-2.5/src/ibendport_record.c +@@ -0,0 +1,154 @@ ++/*Copyright (C) 2005 Red Hat, Inc. */ ++ ++/*Object: semanage_ibendport_t (Infiniband Pkey) ++ *Object: semanage_ibendport_key_t (Infiniband Pkey Key) ++ *Implements: record_t (Database Record) ++ *Implements: record_key_t (Database Record Key) ++ */ ++ ++#include ++#include ++ ++typedef sepol_context_t semanage_context_t; ++typedef sepol_ibendport_t semanage_ibendport_t; ++typedef sepol_ibendport_key_t semanage_ibendport_key_t; ++#define _SEMANAGE_IBENDPORT_DEFINED_ ++#define _SEMANAGE_CONTEXT_DEFINED_ ++ ++typedef semanage_ibendport_t record_t; ++typedef semanage_ibendport_key_t record_key_t; ++#define DBASE_RECORD_DEFINED ++ ++#include "ibendport_internal.h" ++#include "handle.h" ++#include "database.h" ++ ++int semanage_ibendport_compare(const semanage_ibendport_t *ibendport, ++ const semanage_ibendport_key_t *key) ++{ ++ return sepol_ibendport_compare(ibendport, key); ++} ++ ++hidden_def(semanage_ibendport_compare) ++ ++int semanage_ibendport_compare2(const semanage_ibendport_t *ibendport, ++ const semanage_ibendport_t *ibendport2) ++{ ++ return sepol_ibendport_compare2(ibendport, ibendport2); ++} ++ ++hidden_def(semanage_ibendport_compare2) ++ ++hidden int semanage_ibendport_compare2_qsort(const semanage_ibendport_t **ibendport, ++ const semanage_ibendport_t **ibendport2) ++{ ++ return sepol_ibendport_compare2(*ibendport, *ibendport2); ++} ++ ++int semanage_ibendport_key_create(semanage_handle_t *handle, ++ const char *ibdev_name, ++ int port, ++ semanage_ibendport_key_t **key_ptr) ++{ ++ return sepol_ibendport_key_create(handle->sepolh, ibdev_name, port, key_ptr); ++} ++ ++int semanage_ibendport_key_extract(semanage_handle_t *handle, ++ const semanage_ibendport_t *ibendport, ++ semanage_ibendport_key_t **key_ptr) ++{ ++ return sepol_ibendport_key_extract(handle->sepolh, ibendport, key_ptr); ++} ++ ++hidden_def(semanage_ibendport_key_extract) ++ ++void semanage_ibendport_key_free(semanage_ibendport_key_t *key) ++{ ++ sepol_ibendport_key_free(key); ++} ++ ++hidden_def(semanage_ibendport_key_free) ++ ++int semanage_ibendport_get_ibdev_name(semanage_handle_t *handle, ++ const semanage_ibendport_t *ibendport, ++ char **ibdev_name_ptr) ++{ ++ return sepol_ibendport_get_ibdev_name(handle->sepolh, ibendport, ibdev_name_ptr); ++} ++ ++hidden_def(semanage_ibendport_get_ibdev_name) ++ ++int semanage_ibendport_set_ibdev_name(semanage_handle_t *handle, ++ semanage_ibendport_t *ibendport, ++ const char *ibdev_name) ++{ ++ return sepol_ibendport_set_ibdev_name(handle->sepolh, ibendport, ibdev_name); ++} ++ ++hidden_def(semanage_ibendport_set_ibdev_name) ++ ++int semanage_ibendport_get_port(const semanage_ibendport_t *ibendport) ++{ ++ return sepol_ibendport_get_port(ibendport); ++} ++ ++hidden_def(semanage_ibendport_get_port) ++ ++void semanage_ibendport_set_port(semanage_ibendport_t *ibendport, int port) ++{ ++ sepol_ibendport_set_port(ibendport, port); ++} ++ ++hidden_def(semanage_ibendport_set_port) ++ ++semanage_context_t *semanage_ibendport_get_con(const semanage_ibendport_t *ibendport) ++{ ++ return sepol_ibendport_get_con(ibendport); ++} ++ ++hidden_def(semanage_ibendport_get_con) ++ ++int semanage_ibendport_set_con(semanage_handle_t *handle, ++ semanage_ibendport_t *ibendport, ++ semanage_context_t *con) ++{ ++ return sepol_ibendport_set_con(handle->sepolh, ibendport, con); ++} ++ ++hidden_def(semanage_ibendport_set_con) ++ ++int semanage_ibendport_create(semanage_handle_t *handle, ++ semanage_ibendport_t **ibendport_ptr) ++{ ++ return sepol_ibendport_create(handle->sepolh, ibendport_ptr); ++} ++ ++hidden_def(semanage_ibendport_create) ++ ++int semanage_ibendport_clone(semanage_handle_t *handle, ++ const semanage_ibendport_t *ibendport, ++ semanage_ibendport_t **ibendport_ptr) ++{ ++ return sepol_ibendport_clone(handle->sepolh, ibendport, ibendport_ptr); ++} ++ ++hidden_def(semanage_ibendport_clone) ++ ++void semanage_ibendport_free(semanage_ibendport_t *ibendport) ++{ ++ sepol_ibendport_free(ibendport); ++} ++ ++hidden_def(semanage_ibendport_free) ++ ++/*key base functions */ ++record_table_t SEMANAGE_IBENDPORT_RTABLE = { ++ .create = semanage_ibendport_create, ++ .key_extract = semanage_ibendport_key_extract, ++ .key_free = semanage_ibendport_key_free, ++ .clone = semanage_ibendport_clone, ++ .compare = semanage_ibendport_compare, ++ .compare2 = semanage_ibendport_compare2, ++ .compare2_qsort = semanage_ibendport_compare2_qsort, ++ .free = semanage_ibendport_free, ++}; +diff --git libsemanage-2.5/src/ibendports_file.c libsemanage-2.5/src/ibendports_file.c +new file mode 100644 +index 0000000..402c7a5 +--- /dev/null ++++ libsemanage-2.5/src/ibendports_file.c +@@ -0,0 +1,157 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc. */ ++ ++struct semanage_ibendport; ++struct semanage_ibendport_key; ++typedef struct semanage_ibendport record_t; ++typedef struct semanage_ibendport_key record_key_t; ++#define DBASE_RECORD_DEFINED ++ ++struct dbase_file; ++typedef struct dbase_file dbase_t; ++#define DBASE_DEFINED ++ ++#include ++#include ++#include ++#include ++#include "ibendport_internal.h" ++#include "context_internal.h" ++#include "database_file.h" ++#include "parse_utils.h" ++#include "debug.h" ++ ++static int ibendport_print(semanage_handle_t *handle, ++ semanage_ibendport_t *ibendport, ++ FILE *str) ++{ ++ char *con_str = NULL; ++ char *ibdev_name_str = NULL; ++ int port = semanage_ibendport_get_port(ibendport); ++ ++ if (semanage_ibendport_get_ibdev_name(handle, ibendport, &ibdev_name_str) != 0) ++ goto err; ++ ++ semanage_context_t *con = semanage_ibendport_get_con(ibendport); ++ ++ if (fprintf(str, "ibendportcon %s ", ibdev_name_str) < 0) ++ goto err; ++ ++ if (fprintf(str, "%d ", port) < 0) ++ goto err; ++ ++ if (semanage_context_to_string(handle, con, &con_str) < 0) ++ goto err; ++ if (fprintf(str, "%s\n", con_str) < 0) ++ goto err; ++ ++ free(ibdev_name_str); ++ free(con_str); ++ return STATUS_SUCCESS; ++ ++err: ++ ERR(handle, "could not print ibendport (%s) %u to stream", ++ ibdev_name_str, port); ++ free(ibdev_name_str); ++ free(con_str); ++ return STATUS_ERR; ++} ++ ++static int ibendport_parse(semanage_handle_t *handle, ++ parse_info_t *info, ++ semanage_ibendport_t *ibendport) ++{ ++ int port; ++ char *str = NULL; ++ semanage_context_t *con = NULL; ++ ++ if (parse_skip_space(handle, info) < 0) ++ goto err; ++ if (!info->ptr) ++ goto last; ++ ++ /* Header */ ++ if (parse_assert_str(handle, info, "ibendportcon") < 0) ++ goto err; ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ ++ /* IB Device Name */ ++ if (parse_fetch_string(handle, info, &str, ' ') < 0) ++ goto err; ++ if (semanage_ibendport_set_ibdev_name(handle, ibendport, str) < 0) ++ goto err; ++ free(str); ++ str = NULL; ++ ++ /* Port */ ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ if (parse_fetch_int(handle, info, &port, ' ') < 0) ++ goto err; ++ semanage_ibendport_set_port(ibendport, port); ++ ++ /* context */ ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ if (parse_fetch_string(handle, info, &str, ' ') < 0) ++ goto err; ++ if (semanage_context_from_string(handle, str, &con) < 0) { ++ ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", ++ str, info->filename, info->lineno, info->orig_line); ++ goto err; ++ } ++ if (!con) { ++ ERR(handle, "<> context is not valid for ibendport (%s: %u):\n%s", ++ info->filename, info->lineno, info->orig_line); ++ goto err; ++ } ++ free(str); ++ str = NULL; ++ ++ if (semanage_ibendport_set_con(handle, ibendport, con) < 0) ++ goto err; ++ ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ ++ semanage_context_free(con); ++ return STATUS_SUCCESS; ++ ++last: ++ parse_dispose_line(info); ++ return STATUS_NODATA; ++ ++err: ++ ERR(handle, "could not parse ibendport record"); ++ free(str); ++ semanage_context_free(con); ++ parse_dispose_line(info); ++ return STATUS_ERR; ++} ++ ++/* IBENDPORT RECORD: FILE extension: method table */ ++record_file_table_t SEMANAGE_IBENDPORT_FILE_RTABLE = { ++ .parse = ibendport_parse, ++ .print = ibendport_print, ++}; ++ ++int ibendport_file_dbase_init(semanage_handle_t *handle, ++ const char *path_ro, ++ const char *path_rw, ++ dbase_config_t *dconfig) ++{ ++ if (dbase_file_init(handle, ++ path_ro, ++ path_rw, ++ &SEMANAGE_IBENDPORT_RTABLE, ++ &SEMANAGE_IBENDPORT_FILE_RTABLE, &dconfig->dbase) < 0) ++ return STATUS_ERR; ++ ++ dconfig->dtable = &SEMANAGE_FILE_DTABLE; ++ return STATUS_SUCCESS; ++} ++ ++void ibendport_file_dbase_release(dbase_config_t *dconfig) ++{ ++ dbase_file_release(dconfig->dbase); ++} +diff --git libsemanage-2.5/src/ibendports_local.c libsemanage-2.5/src/ibendports_local.c +new file mode 100644 +index 0000000..8b5567d +--- /dev/null ++++ libsemanage-2.5/src/ibendports_local.c +@@ -0,0 +1,153 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc */ ++ ++struct semanage_ibendport; ++struct semanage_ibendport_key; ++typedef struct semanage_ibendport_key record_key_t; ++typedef struct semanage_ibendport record_t; ++#define DBASE_RECORD_DEFINED ++ ++#include ++#include ++#include ++#include "ibendport_internal.h" ++#include "debug.h" ++#include "handle.h" ++#include "database.h" ++ ++int semanage_ibendport_modify_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ const semanage_ibendport_t *data) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); ++ ++ return dbase_modify(handle, dconfig, key, data); ++} ++ ++int semanage_ibendport_del_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); ++ ++ return dbase_del(handle, dconfig, key); ++} ++ ++int semanage_ibendport_query_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ semanage_ibendport_t **response) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); ++ ++ return dbase_query(handle, dconfig, key, response); ++} ++ ++int semanage_ibendport_exists_local(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); ++ ++ return dbase_exists(handle, dconfig, key, response); ++} ++ ++int semanage_ibendport_count_local(semanage_handle_t *handle, ++ unsigned int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); ++ ++ return dbase_count(handle, dconfig, response); ++} ++ ++int semanage_ibendport_iterate_local(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibendport_t *record, ++ void *varg), void *handler_arg) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); ++ return dbase_iterate(handle, dconfig, handler, handler_arg); ++} ++ ++int semanage_ibendport_list_local(semanage_handle_t *handle, ++ semanage_ibendport_t ***records, ++ unsigned int *count) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_local(handle); ++ ++ return dbase_list(handle, dconfig, records, count); ++} ++ ++hidden_def(semanage_ibendport_list_local) ++ ++int hidden semanage_ibendport_validate_local(semanage_handle_t *handle) ++{ ++ semanage_ibendport_t **ibendports = NULL; ++ unsigned int nibendports = 0; ++ unsigned int i = 0, j = 0; ++ char *ibdev_name; ++ char *ibdev_name2; ++ int port; ++ int port2; ++ ++ /* List and sort the ibendports */ ++ if (semanage_ibendport_list_local(handle, &ibendports, &nibendports) < 0) ++ goto err; ++ ++ qsort(ibendports, nibendports, sizeof(semanage_ibendport_t *), ++ (int (*)(const void *, const void *)) ++ &semanage_ibendport_compare2_qsort); ++ ++ /* Test each ibendport */ ++ while (i < nibendports) { ++ int stop = 0; ++ ++ if (STATUS_SUCCESS != ++ semanage_ibendport_get_ibdev_name(handle, ++ ibendports[i], ++ &ibdev_name)) { ++ ERR(handle, "Couldn't get IB device name"); ++ goto err; ++ } ++ ++ port = semanage_ibendport_get_port(ibendports[i]); ++ ++ /* Find the first ibendport with matching ++ * ibdev_name to compare against ++ */ ++ do { ++ if (j == nibendports - 1) ++ goto next; ++ j++; ++ if (STATUS_SUCCESS != ++ semanage_ibendport_get_ibdev_name(handle, ++ ibendports[j], ++ &ibdev_name2)) { ++ ERR(handle, "Couldn't get IB device name."); ++ goto err; ++ } ++ port2 = semanage_ibendport_get_port(ibendports[j]); ++ ++ stop = !strcmp(ibdev_name, ibdev_name2); ++ } while (!stop); ++ ++ if (port == port2) { ++ ERR(handle, "ibendport %s/%u already exists.", ++ ibdev_name2, port2); ++ goto invalid; ++ } ++next: ++ i++; ++ j = i; ++ } ++ ++ for (i = 0; i < nibendports; i++) ++ semanage_ibendport_free(ibendports[i]); ++ free(ibendports); ++ return STATUS_SUCCESS; ++ ++err: ++ ERR(handle, "could not complete ibendports validity check"); ++ ++invalid: ++ for (i = 0; i < nibendports; i++) ++ semanage_ibendport_free(ibendports[i]); ++ free(ibendports); ++ return STATUS_ERR; ++} +diff --git libsemanage-2.5/src/ibendports_policy.c libsemanage-2.5/src/ibendports_policy.c +new file mode 100644 +index 0000000..1347b67 +--- /dev/null ++++ libsemanage-2.5/src/ibendports_policy.c +@@ -0,0 +1,55 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc */ ++ ++struct semanage_ibendport; ++struct semanage_ibendport_key; ++typedef struct semanage_ibendport_key record_key_t; ++typedef struct semanage_ibendport record_t; ++#define DBASE_RECORD_DEFINED ++ ++#include "ibendport_internal.h" ++#include "handle.h" ++#include "database.h" ++ ++int semanage_ibendport_query(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ semanage_ibendport_t **response) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); ++ ++ return dbase_query(handle, dconfig, key, response); ++} ++ ++int semanage_ibendport_exists(semanage_handle_t *handle, ++ const semanage_ibendport_key_t *key, ++ int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); ++ ++ return dbase_exists(handle, dconfig, key, response); ++} ++ ++int semanage_ibendport_count(semanage_handle_t *handle, ++ unsigned int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); ++ ++ return dbase_count(handle, dconfig, response); ++} ++ ++int semanage_ibendport_iterate(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibendport_t *record, ++ void *varg), void *handler_arg) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); ++ ++ return dbase_iterate(handle, dconfig, handler, handler_arg); ++} ++ ++int semanage_ibendport_list(semanage_handle_t *handle, ++ semanage_ibendport_t ***records, ++ unsigned int *count) ++{ ++ dbase_config_t *dconfig = semanage_ibendport_dbase_policy(handle); ++ ++ return dbase_list(handle, dconfig, records, count); ++} +diff --git libsemanage-2.5/src/ibendports_policydb.c libsemanage-2.5/src/ibendports_policydb.c +new file mode 100644 +index 0000000..1029810 +--- /dev/null ++++ libsemanage-2.5/src/ibendports_policydb.c +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2017 Mellanox Technologies Inc ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ */ ++ ++struct semanage_ibendport; ++struct semanage_ibendport_key; ++typedef struct semanage_ibendport record_t; ++typedef struct semanage_ibendport_key record_key_t; ++#define DBASE_RECORD_DEFINED ++ ++struct dbase_policydb; ++typedef struct dbase_policydb dbase_t; ++#define DBASE_DEFINED ++ ++#include ++#include ++#include "ibendport_internal.h" ++#include "debug.h" ++#include "database_policydb.h" ++#include "semanage_store.h" ++ ++/* IBENDPORT RECORD (SEPOL): POLICYDB extension : method table */ ++record_policydb_table_t SEMANAGE_IBENDPORT_POLICYDB_RTABLE = { ++ .add = NULL, ++ .modify = (record_policydb_table_modify_t)sepol_ibendport_modify, ++ .set = NULL, ++ .query = (record_policydb_table_query_t)sepol_ibendport_query, ++ .count = (record_policydb_table_count_t)sepol_ibendport_count, ++ .exists = (record_policydb_table_exists_t)sepol_ibendport_exists, ++ .iterate = (record_policydb_table_iterate_t)sepol_ibendport_iterate, ++}; ++ ++int ibendport_policydb_dbase_init(semanage_handle_t *handle, ++ dbase_config_t *dconfig) ++{ ++ if (dbase_policydb_init(handle, ++ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), ++ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), ++ &SEMANAGE_IBENDPORT_RTABLE, ++ &SEMANAGE_IBENDPORT_POLICYDB_RTABLE, ++ &dconfig->dbase) < 0) ++ return STATUS_ERR; ++ ++ dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; ++ ++ return STATUS_SUCCESS; ++} ++ ++void ibendport_policydb_dbase_release(dbase_config_t *dconfig) ++{ ++ dbase_policydb_release(dconfig->dbase); ++} +diff --git libsemanage-2.5/src/ibpkey_internal.h libsemanage-2.5/src/ibpkey_internal.h +new file mode 100644 +index 0000000..9465bb8 +--- /dev/null ++++ libsemanage-2.5/src/ibpkey_internal.h +@@ -0,0 +1,52 @@ ++#ifndef _SEMANAGE_IBPKEY_INTERNAL_H_ ++#define _SEMANAGE_IBPKEY_INTERNAL_H_ ++ ++#include ++#include ++#include ++#include "database.h" ++#include "handle.h" ++#include "dso.h" ++ ++hidden_proto(semanage_ibpkey_create) ++hidden_proto(semanage_ibpkey_compare) ++hidden_proto(semanage_ibpkey_compare2) ++hidden_proto(semanage_ibpkey_clone) ++hidden_proto(semanage_ibpkey_free) ++hidden_proto(semanage_ibpkey_key_extract) ++hidden_proto(semanage_ibpkey_key_free) ++hidden_proto(semanage_ibpkey_get_high) ++hidden_proto(semanage_ibpkey_get_low) ++hidden_proto(semanage_ibpkey_set_pkey) ++hidden_proto(semanage_ibpkey_set_range) ++hidden_proto(semanage_ibpkey_get_con) ++hidden_proto(semanage_ibpkey_set_con) ++hidden_proto(semanage_ibpkey_list_local) ++hidden_proto(semanage_ibpkey_get_subnet_prefix) ++hidden_proto(semanage_ibpkey_get_subnet_prefix_bytes) ++hidden_proto(semanage_ibpkey_set_subnet_prefix) ++hidden_proto(semanage_ibpkey_set_subnet_prefix_bytes) ++ ++/* PKEY RECORD: method table */ ++extern record_table_t SEMANAGE_IBPKEY_RTABLE; ++ ++extern int ibpkey_file_dbase_init(semanage_handle_t *handle, ++ const char *path_ro, ++ const char *path_rw, ++ dbase_config_t *dconfig); ++ ++extern void ibpkey_file_dbase_release(dbase_config_t *dconfig); ++ ++extern int ibpkey_policydb_dbase_init(semanage_handle_t *handle, ++ dbase_config_t *dconfig); ++ ++extern void ibpkey_policydb_dbase_release(dbase_config_t *dconfig); ++ ++extern int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle); ++ ++/* ==== Internal (to ibpkeys) API === */ ++ ++hidden int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey, ++ const semanage_ibpkey_t **ibpkey2); ++ ++#endif +diff --git libsemanage-2.5/src/ibpkey_record.c libsemanage-2.5/src/ibpkey_record.c +new file mode 100644 +index 0000000..ca5bc76 +--- /dev/null ++++ libsemanage-2.5/src/ibpkey_record.c +@@ -0,0 +1,182 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc. */ ++ ++/* Object: semanage_ibpkey_t (Infiniband Pkey) ++ * Object: semanage_ibpkey_key_t (Infiniband Pkey Key) ++ * Implements: record_t (Database Record) ++ * Implements: record_key_t (Database Record Key) ++ */ ++ ++#include ++#include ++ ++typedef sepol_context_t semanage_context_t; ++typedef sepol_ibpkey_t semanage_ibpkey_t; ++typedef sepol_ibpkey_key_t semanage_ibpkey_key_t; ++#define _SEMANAGE_IBPKEY_DEFINED_ ++#define _SEMANAGE_CONTEXT_DEFINED_ ++ ++typedef semanage_ibpkey_t record_t; ++typedef semanage_ibpkey_key_t record_key_t; ++#define DBASE_RECORD_DEFINED ++ ++#include "ibpkey_internal.h" ++#include "handle.h" ++#include "database.h" ++ ++int semanage_ibpkey_compare(const semanage_ibpkey_t *ibpkey, ++ const semanage_ibpkey_key_t *key) ++{ ++ return sepol_ibpkey_compare(ibpkey, key); ++} ++ ++hidden_def(semanage_ibpkey_compare) ++ ++int semanage_ibpkey_compare2(const semanage_ibpkey_t *ibpkey, ++ const semanage_ibpkey_t *ibpkey2) ++{ ++ return sepol_ibpkey_compare2(ibpkey, ibpkey2); ++} ++ ++hidden_def(semanage_ibpkey_compare2) ++ ++hidden int semanage_ibpkey_compare2_qsort(const semanage_ibpkey_t **ibpkey, ++ const semanage_ibpkey_t **ibpkey2) ++{ ++ return sepol_ibpkey_compare2(*ibpkey, *ibpkey2); ++} ++ ++int semanage_ibpkey_key_create(semanage_handle_t *handle, ++ const char *subnet_prefix, ++ int low, int high, ++ semanage_ibpkey_key_t **key_ptr) ++{ ++ return sepol_ibpkey_key_create(handle->sepolh, subnet_prefix, low, high, key_ptr); ++} ++ ++int semanage_ibpkey_key_extract(semanage_handle_t *handle, ++ const semanage_ibpkey_t *ibpkey, ++ semanage_ibpkey_key_t **key_ptr) ++{ ++ return sepol_ibpkey_key_extract(handle->sepolh, ibpkey, key_ptr); ++} ++ ++hidden_def(semanage_ibpkey_key_extract) ++ ++void semanage_ibpkey_key_free(semanage_ibpkey_key_t *key) ++{ ++ sepol_ibpkey_key_free(key); ++} ++ ++hidden_def(semanage_ibpkey_key_free) ++ ++int semanage_ibpkey_get_subnet_prefix(semanage_handle_t *handle, ++ const semanage_ibpkey_t *ibpkey, ++ char **subnet_prefix_ptr) ++{ ++ return sepol_ibpkey_get_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix_ptr); ++} ++ ++hidden_def(semanage_ibpkey_get_subnet_prefix) ++ ++uint64_t semanage_ibpkey_get_subnet_prefix_bytes(const semanage_ibpkey_t *ibpkey) ++{ ++ return sepol_ibpkey_get_subnet_prefix_bytes(ibpkey); ++} ++ ++hidden_def(semanage_ibpkey_get_subnet_prefix_bytes) ++ ++int semanage_ibpkey_set_subnet_prefix(semanage_handle_t *handle, ++ semanage_ibpkey_t *ibpkey, ++ const char *subnet_prefix) ++{ ++ return sepol_ibpkey_set_subnet_prefix(handle->sepolh, ibpkey, subnet_prefix); ++} ++ ++hidden_def(semanage_ibpkey_set_subnet_prefix) ++ ++void semanage_ibpkey_set_subnet_prefix_bytes(semanage_ibpkey_t *ibpkey, ++ uint64_t subnet_prefix) ++{ ++ return sepol_ibpkey_set_subnet_prefix_bytes(ibpkey, subnet_prefix); ++} ++ ++hidden_def(semanage_ibpkey_set_subnet_prefix_bytes) ++ ++int semanage_ibpkey_get_low(const semanage_ibpkey_t *ibpkey) ++{ ++ return sepol_ibpkey_get_low(ibpkey); ++} ++ ++hidden_def(semanage_ibpkey_get_low) ++ ++int semanage_ibpkey_get_high(const semanage_ibpkey_t *ibpkey) ++{ ++ return sepol_ibpkey_get_high(ibpkey); ++} ++ ++hidden_def(semanage_ibpkey_get_high) ++ ++void semanage_ibpkey_set_pkey(semanage_ibpkey_t *ibpkey, int ibpkey_num) ++{ ++ sepol_ibpkey_set_pkey(ibpkey, ibpkey_num); ++} ++ ++hidden_def(semanage_ibpkey_set_pkey) ++ ++void semanage_ibpkey_set_range(semanage_ibpkey_t *ibpkey, int low, int high) ++{ ++ sepol_ibpkey_set_range(ibpkey, low, high); ++} ++ ++hidden_def(semanage_ibpkey_set_range) ++ ++semanage_context_t *semanage_ibpkey_get_con(const semanage_ibpkey_t *ibpkey) ++{ ++ return sepol_ibpkey_get_con(ibpkey); ++} ++ ++hidden_def(semanage_ibpkey_get_con) ++ ++int semanage_ibpkey_set_con(semanage_handle_t *handle, ++ semanage_ibpkey_t *ibpkey, semanage_context_t *con) ++{ ++ return sepol_ibpkey_set_con(handle->sepolh, ibpkey, con); ++} ++ ++hidden_def(semanage_ibpkey_set_con) ++ ++int semanage_ibpkey_create(semanage_handle_t *handle, ++ semanage_ibpkey_t **ibpkey_ptr) ++{ ++ return sepol_ibpkey_create(handle->sepolh, ibpkey_ptr); ++} ++ ++hidden_def(semanage_ibpkey_create) ++ ++int semanage_ibpkey_clone(semanage_handle_t *handle, ++ const semanage_ibpkey_t *ibpkey, ++ semanage_ibpkey_t **ibpkey_ptr) ++{ ++ return sepol_ibpkey_clone(handle->sepolh, ibpkey, ibpkey_ptr); ++} ++ ++hidden_def(semanage_ibpkey_clone) ++ ++void semanage_ibpkey_free(semanage_ibpkey_t *ibpkey) ++{ ++ sepol_ibpkey_free(ibpkey); ++} ++ ++hidden_def(semanage_ibpkey_free) ++ ++/* key base functions */ ++record_table_t SEMANAGE_IBPKEY_RTABLE = { ++ .create = semanage_ibpkey_create, ++ .key_extract = semanage_ibpkey_key_extract, ++ .key_free = semanage_ibpkey_key_free, ++ .clone = semanage_ibpkey_clone, ++ .compare = semanage_ibpkey_compare, ++ .compare2 = semanage_ibpkey_compare2, ++ .compare2_qsort = semanage_ibpkey_compare2_qsort, ++ .free = semanage_ibpkey_free, ++}; +diff --git libsemanage-2.5/src/ibpkeys_file.c libsemanage-2.5/src/ibpkeys_file.c +new file mode 100644 +index 0000000..ceaea7a +--- /dev/null ++++ libsemanage-2.5/src/ibpkeys_file.c +@@ -0,0 +1,181 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc. */ ++ ++struct semanage_ibpkey; ++struct semanage_ibpkey_key; ++typedef struct semanage_ibpkey record_t; ++typedef struct semanage_ibpkey_key record_key_t; ++#define DBASE_RECORD_DEFINED ++ ++struct dbase_file; ++typedef struct dbase_file dbase_t; ++#define DBASE_DEFINED ++ ++#include ++#include ++#include ++#include ++#include "ibpkey_internal.h" ++#include "context_internal.h" ++#include "database_file.h" ++#include "parse_utils.h" ++#include "debug.h" ++ ++static int ibpkey_print(semanage_handle_t *handle, ++ semanage_ibpkey_t *ibpkey, FILE *str) ++{ ++ char *con_str = NULL; ++ char *subnet_prefix_str = NULL; ++ ++ int low = semanage_ibpkey_get_low(ibpkey); ++ int high = semanage_ibpkey_get_high(ibpkey); ++ ++ if (semanage_ibpkey_get_subnet_prefix(handle, ibpkey, &subnet_prefix_str) != 0) ++ goto err; ++ ++ semanage_context_t *con = semanage_ibpkey_get_con(ibpkey); ++ ++ if (fprintf(str, "ibpkeycon %s ", subnet_prefix_str) < 0) ++ goto err; ++ ++ if (low == high) { ++ if (fprintf(str, "%d ", low) < 0) ++ goto err; ++ } else { ++ if (fprintf(str, "%d - %d ", low, high) < 0) ++ goto err; ++ } ++ ++ if (semanage_context_to_string(handle, con, &con_str) < 0) ++ goto err; ++ if (fprintf(str, "%s\n", con_str) < 0) ++ goto err; ++ ++ free(subnet_prefix_str); ++ free(con_str); ++ return STATUS_SUCCESS; ++ ++err: ++ ERR(handle, "could not print ibpkey range (%s) %u - %u to stream", ++ subnet_prefix_str, low, high); ++ free(subnet_prefix_str); ++ free(con_str); ++ return STATUS_ERR; ++} ++ ++static int ibpkey_parse(semanage_handle_t *handle, ++ parse_info_t *info, semanage_ibpkey_t *ibpkey) ++{ ++ int low, high; ++ char *str = NULL; ++ semanage_context_t *con = NULL; ++ ++ if (parse_skip_space(handle, info) < 0) ++ goto err; ++ if (!info->ptr) ++ goto last; ++ ++ /* Header */ ++ if (parse_assert_str(handle, info, "ibpkeycon") < 0) ++ goto err; ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ ++ /* Subnet Prefix */ ++ if (parse_fetch_string(handle, info, &str, ' ') < 0) ++ goto err; ++ if (semanage_ibpkey_set_subnet_prefix(handle, ibpkey, str) < 0) ++ goto err; ++ free(str); ++ str = NULL; ++ ++ /* Range/Pkey */ ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ if (parse_fetch_int(handle, info, &low, '-') < 0) ++ goto err; ++ ++ /* If range (-) does not follow immediately, require a space ++ * In other words, the space here is optional, but only ++ * in the ranged case, not in the single ibpkey case, ++ * so do a custom test ++ */ ++ if (*info->ptr && *info->ptr != '-') { ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ } ++ ++ if (parse_optional_ch(info, '-') != STATUS_NODATA) { ++ if (parse_skip_space(handle, info) < 0) ++ goto err; ++ if (parse_fetch_int(handle, info, &high, ' ') < 0) ++ goto err; ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ semanage_ibpkey_set_range(ibpkey, low, high); ++ } else { ++ semanage_ibpkey_set_pkey(ibpkey, low); ++ } ++ /* Pkey context */ ++ if (parse_fetch_string(handle, info, &str, ' ') < 0) ++ goto err; ++ if (semanage_context_from_string(handle, str, &con) < 0) { ++ ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s", ++ str, info->filename, info->lineno, info->orig_line); ++ goto err; ++ } ++ if (!con) { ++ ERR(handle, "<> context is not valid for ibpkeys (%s: %u):\n%s", ++ info->filename, ++ info->lineno, info->orig_line); ++ goto err; ++ } ++ free(str); ++ str = NULL; ++ ++ if (semanage_ibpkey_set_con(handle, ibpkey, con) < 0) ++ goto err; ++ ++ if (parse_assert_space(handle, info) < 0) ++ goto err; ++ ++ semanage_context_free(con); ++ return STATUS_SUCCESS; ++ ++last: ++ parse_dispose_line(info); ++ return STATUS_NODATA; ++ ++err: ++ ERR(handle, "could not parse ibpkey record"); ++ free(str); ++ semanage_context_free(con); ++ parse_dispose_line(info); ++ return STATUS_ERR; ++} ++ ++/* IBPKEY RECORD: FILE extension: method table */ ++record_file_table_t SEMANAGE_IBPKEY_FILE_RTABLE = { ++ .parse = ibpkey_parse, ++ .print = ibpkey_print, ++}; ++ ++int ibpkey_file_dbase_init(semanage_handle_t *handle, ++ const char *path_ro, ++ const char *path_rw, ++ dbase_config_t *dconfig) ++{ ++ if (dbase_file_init(handle, ++ path_ro, ++ path_rw, ++ &SEMANAGE_IBPKEY_RTABLE, ++ &SEMANAGE_IBPKEY_FILE_RTABLE, &dconfig->dbase) < 0) ++ return STATUS_ERR; ++ ++ dconfig->dtable = &SEMANAGE_FILE_DTABLE; ++ return STATUS_SUCCESS; ++} ++ ++void ibpkey_file_dbase_release(dbase_config_t *dconfig) ++{ ++ dbase_file_release(dconfig->dbase); ++} +diff --git libsemanage-2.5/src/ibpkeys_local.c libsemanage-2.5/src/ibpkeys_local.c +new file mode 100644 +index 0000000..e194ee0 +--- /dev/null ++++ libsemanage-2.5/src/ibpkeys_local.c +@@ -0,0 +1,164 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc. */ ++ ++struct semanage_ibpkey; ++struct semanage_ibpkey_key; ++typedef struct semanage_ibpkey_key record_key_t; ++typedef struct semanage_ibpkey record_t; ++#define DBASE_RECORD_DEFINED ++ ++#include ++#include ++#include ++#include "ibpkey_internal.h" ++#include "debug.h" ++#include "handle.h" ++#include "database.h" ++ ++int semanage_ibpkey_modify_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ const semanage_ibpkey_t *data) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); ++ ++ return dbase_modify(handle, dconfig, key, data); ++} ++ ++int semanage_ibpkey_del_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); ++ ++ return dbase_del(handle, dconfig, key); ++} ++ ++int semanage_ibpkey_query_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ semanage_ibpkey_t **response) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); ++ ++ return dbase_query(handle, dconfig, key, response); ++} ++ ++int semanage_ibpkey_exists_local(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); ++ ++ return dbase_exists(handle, dconfig, key, response); ++} ++ ++int semanage_ibpkey_count_local(semanage_handle_t *handle, ++ unsigned int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); ++ ++ return dbase_count(handle, dconfig, response); ++} ++ ++int semanage_ibpkey_iterate_local(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibpkey_t *record, ++ void *varg), void *handler_arg) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); ++ ++ return dbase_iterate(handle, dconfig, handler, handler_arg); ++} ++ ++int semanage_ibpkey_list_local(semanage_handle_t *handle, ++ semanage_ibpkey_t ***records, unsigned int *count) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_local(handle); ++ ++ return dbase_list(handle, dconfig, records, count); ++} ++ ++hidden_def(semanage_ibpkey_list_local) ++ ++int hidden semanage_ibpkey_validate_local(semanage_handle_t *handle) ++{ ++ semanage_ibpkey_t **ibpkeys = NULL; ++ unsigned int nibpkeys = 0; ++ unsigned int i = 0, j = 0; ++ uint64_t subnet_prefix; ++ uint64_t subnet_prefix2; ++ char *subnet_prefix_str; ++ char *subnet_prefix_str2; ++ int low, high; ++ int low2, high2; ++ ++ /* List and sort the ibpkeys */ ++ if (semanage_ibpkey_list_local(handle, &ibpkeys, &nibpkeys) < 0) ++ goto err; ++ ++ qsort(ibpkeys, nibpkeys, sizeof(semanage_ibpkey_t *), ++ (int (*)(const void *, const void *)) ++ &semanage_ibpkey_compare2_qsort); ++ ++ /* Test each ibpkey for overlap */ ++ while (i < nibpkeys) { ++ if (STATUS_SUCCESS != semanage_ibpkey_get_subnet_prefix(handle, ++ ibpkeys[i], ++ &subnet_prefix_str)) { ++ ERR(handle, "Couldn't get subnet prefix string"); ++ goto err; ++ } ++ ++ subnet_prefix = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[i]); ++ low = semanage_ibpkey_get_low(ibpkeys[i]); ++ high = semanage_ibpkey_get_high(ibpkeys[i]); ++ ++ /* Find the first ibpkey with matching ++ * subnet_prefix to compare against ++ */ ++ do { ++ if (j == nibpkeys - 1) ++ goto next; ++ j++; ++ ++ if (STATUS_SUCCESS != ++ semanage_ibpkey_get_subnet_prefix(handle, ++ ibpkeys[j], ++ &subnet_prefix_str2)) { ++ ERR(handle, "Couldn't get subnet prefix string"); ++ goto err; ++ } ++ subnet_prefix2 = semanage_ibpkey_get_subnet_prefix_bytes(ibpkeys[j]); ++ low2 = semanage_ibpkey_get_low(ibpkeys[j]); ++ high2 = semanage_ibpkey_get_high(ibpkeys[j]); ++ } while (subnet_prefix != subnet_prefix2); ++ ++ /* Overlap detected */ ++ if (low2 <= high) { ++ ERR(handle, "ibpkey overlap between ranges " ++ "(%s) %u - %u <--> (%s) %u - %u.", ++ subnet_prefix_str, low, high, ++ subnet_prefix_str2, low2, high2); ++ goto invalid; ++ } ++ ++ /* If closest ibpkey of matching subnet prefix doesn't overlap ++ * with test ibpkey, neither do the rest of them, because that's ++ * how the sort function works on ibpkeys - lower bound ++ * ibpkeys come first ++ */ ++next: ++ i++; ++ j = i; ++ } ++ ++ for (i = 0; i < nibpkeys; i++) ++ semanage_ibpkey_free(ibpkeys[i]); ++ free(ibpkeys); ++ return STATUS_SUCCESS; ++ ++err: ++ ERR(handle, "could not complete ibpkeys validity check"); ++ ++invalid: ++ for (i = 0; i < nibpkeys; i++) ++ semanage_ibpkey_free(ibpkeys[i]); ++ free(ibpkeys); ++ return STATUS_ERR; ++} +diff --git libsemanage-2.5/src/ibpkeys_policy.c libsemanage-2.5/src/ibpkeys_policy.c +new file mode 100644 +index 0000000..0956230 +--- /dev/null ++++ libsemanage-2.5/src/ibpkeys_policy.c +@@ -0,0 +1,52 @@ ++/* Copyright (C) 2017 Mellanox Technologies Inc. */ ++ ++struct semanage_ibpkey; ++struct semanage_ibpkey_key; ++typedef struct semanage_ibpkey_key record_key_t; ++typedef struct semanage_ibpkey record_t; ++#define DBASE_RECORD_DEFINED ++ ++#include "ibpkey_internal.h" ++#include "handle.h" ++#include "database.h" ++ ++int semanage_ibpkey_query(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, ++ semanage_ibpkey_t **response) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); ++ ++ return dbase_query(handle, dconfig, key, response); ++} ++ ++int semanage_ibpkey_exists(semanage_handle_t *handle, ++ const semanage_ibpkey_key_t *key, int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); ++ ++ return dbase_exists(handle, dconfig, key, response); ++} ++ ++int semanage_ibpkey_count(semanage_handle_t *handle, unsigned int *response) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); ++ ++ return dbase_count(handle, dconfig, response); ++} ++ ++int semanage_ibpkey_iterate(semanage_handle_t *handle, ++ int (*handler)(const semanage_ibpkey_t *record, ++ void *varg), void *handler_arg) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); ++ ++ return dbase_iterate(handle, dconfig, handler, handler_arg); ++} ++ ++int semanage_ibpkey_list(semanage_handle_t *handle, ++ semanage_ibpkey_t ***records, unsigned int *count) ++{ ++ dbase_config_t *dconfig = semanage_ibpkey_dbase_policy(handle); ++ ++ return dbase_list(handle, dconfig, records, count); ++} +diff --git libsemanage-2.5/src/ibpkeys_policydb.c libsemanage-2.5/src/ibpkeys_policydb.c +new file mode 100644 +index 0000000..8d73cf6 +--- /dev/null ++++ libsemanage-2.5/src/ibpkeys_policydb.c +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2017 Mellanox Technologies Inc ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ */ ++ ++struct semanage_ibpkey; ++struct semanage_ibpkey_key; ++typedef struct semanage_ibpkey record_t; ++typedef struct semanage_ibpkey_key record_key_t; ++#define DBASE_RECORD_DEFINED ++ ++struct dbase_policydb; ++typedef struct dbase_policydb dbase_t; ++#define DBASE_DEFINED ++ ++#include ++#include ++#include "ibpkey_internal.h" ++#include "debug.h" ++#include "database_policydb.h" ++#include "semanage_store.h" ++ ++/* PKEY RECORD (SEPOL): POLICYDB extension : method table */ ++record_policydb_table_t SEMANAGE_IBPKEY_POLICYDB_RTABLE = { ++ .add = NULL, ++ .modify = (record_policydb_table_modify_t)sepol_ibpkey_modify, ++ .set = NULL, ++ .query = (record_policydb_table_query_t)sepol_ibpkey_query, ++ .count = (record_policydb_table_count_t)sepol_ibpkey_count, ++ .exists = (record_policydb_table_exists_t)sepol_ibpkey_exists, ++ .iterate = (record_policydb_table_iterate_t)sepol_ibpkey_iterate, ++}; ++ ++int ibpkey_policydb_dbase_init(semanage_handle_t *handle, ++ dbase_config_t *dconfig) ++{ ++ if (dbase_policydb_init(handle, ++ semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL), ++ semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL), ++ &SEMANAGE_IBPKEY_RTABLE, ++ &SEMANAGE_IBPKEY_POLICYDB_RTABLE, ++ &dconfig->dbase) < 0) ++ return STATUS_ERR; ++ ++ dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE; ++ ++ return STATUS_SUCCESS; ++} ++ ++void ibpkey_policydb_dbase_release(dbase_config_t *dconfig) ++{ ++ dbase_policydb_release(dconfig->dbase); ++} +diff --git libsemanage-2.5/src/libsemanage.map libsemanage-2.5/src/libsemanage.map +index 34b553d..ce5b34f 100644 +--- libsemanage-2.5/src/libsemanage.map ++++ libsemanage-2.5/src/libsemanage.map +@@ -18,6 +18,8 @@ LIBSEMANAGE_1.0 { + semanage_root; + semanage_user_*; semanage_bool_*; semanage_seuser_*; + semanage_iface_*; semanage_port_*; semanage_context_*; ++ semanage_ibpkey_*; ++ semanage_ibendport_*; + semanage_node_*; + semanage_fcontext_*; semanage_access_check; semanage_set_create_store; + semanage_is_connected; semanage_get_disable_dontaudit; semanage_set_disable_dontaudit; +@@ -40,10 +42,12 @@ LIBSEMANAGE_1.1 { + semanage_module_info_destroy; + semanage_module_info_get_priority; + semanage_module_info_get_name; ++ semanage_module_info_get_version; + semanage_module_info_get_lang_ext; + semanage_module_info_get_enabled; + semanage_module_info_set_priority; + semanage_module_info_set_name; ++ semanage_module_info_set_version; + semanage_module_info_set_lang_ext; + semanage_module_info_set_enabled; + semanage_module_key_create; +diff --git libsemanage-2.5/src/module_internal.h libsemanage-2.5/src/module_internal.h +index c99f6c2..d62091a 100644 +--- libsemanage-2.5/src/module_internal.h ++++ libsemanage-2.5/src/module_internal.h +@@ -11,10 +11,12 @@ hidden_proto(semanage_module_get_name) + hidden_proto(semanage_module_info_destroy) + hidden_proto(semanage_module_info_get_priority) + hidden_proto(semanage_module_info_get_name) ++ hidden_proto(semanage_module_info_get_version) + hidden_proto(semanage_module_info_get_lang_ext) + hidden_proto(semanage_module_info_get_enabled) + hidden_proto(semanage_module_info_set_priority) + hidden_proto(semanage_module_info_set_name) ++ hidden_proto(semanage_module_info_set_version) + hidden_proto(semanage_module_info_set_lang_ext) + hidden_proto(semanage_module_info_set_enabled) + hidden_proto(semanage_module_key_create) +diff --git libsemanage-2.5/src/modules.c libsemanage-2.5/src/modules.c +index 90c5e49..85285a1 100644 +--- libsemanage-2.5/src/modules.c ++++ libsemanage-2.5/src/modules.c +@@ -291,6 +291,7 @@ int semanage_module_info_destroy(semanage_handle_t *sh, + } + + free(modinfo->name); ++ free(modinfo->module_version); + free(modinfo->lang_ext); + + return semanage_module_info_init(sh, modinfo); +@@ -306,6 +307,7 @@ int semanage_module_info_init(semanage_handle_t *sh, + + modinfo->priority = 0; + modinfo->name = NULL; ++ modinfo->module_version = NULL; + modinfo->lang_ext = NULL; + modinfo->enabled = -1; + +@@ -341,6 +343,14 @@ int semanage_module_info_clone(semanage_handle_t *sh, + goto cleanup; + } + ++ if (source->module_version != NULL) { ++ ret = semanage_module_info_set_version(sh, target, source->module_version); ++ if (ret != 0) { ++ status = -1; ++ goto cleanup; ++ } ++ } ++ + ret = semanage_module_info_set_lang_ext(sh, target, source->lang_ext); + if (ret != 0) { + status = -1; +@@ -388,6 +398,21 @@ int semanage_module_info_get_name(semanage_handle_t *sh, + + hidden_def(semanage_module_info_get_name) + ++int semanage_module_info_get_version(semanage_handle_t *sh, ++ semanage_module_info_t *modinfo, ++ const char **version) ++{ ++ assert(sh); ++ assert(modinfo); ++ assert(version); ++ ++ *version = modinfo->module_version; ++ ++ return 0; ++} ++ ++hidden_def(semanage_module_info_get_version) ++ + int semanage_module_info_get_lang_ext(semanage_handle_t *sh, + semanage_module_info_t *modinfo, + const char **lang_ext) +@@ -470,6 +495,37 @@ int semanage_module_info_set_name(semanage_handle_t *sh, + + hidden_def(semanage_module_info_set_name) + ++int semanage_module_info_set_version(semanage_handle_t *sh, ++ semanage_module_info_t *modinfo, ++ const char *version) ++{ ++ assert(sh); ++ assert(modinfo); ++ assert(version); ++ ++ char * tmp; ++ ++ /* Verify version */ ++ ++ if (semanage_module_validate_version(version) < 0) { ++ errno = 0; ++ return -1; ++ } ++ ++ tmp = strdup(version); ++ if (!tmp) { ++ return -1; ++ } ++ ++ free(modinfo->module_version); ++ modinfo->module_version = tmp; ++ ++ return 0; ++} ++ ++hidden_def(semanage_module_info_set_version) ++ ++ + int semanage_module_info_set_lang_ext(semanage_handle_t *sh, + semanage_module_info_t *modinfo, + const char *lang_ext) +@@ -1064,6 +1120,49 @@ exit: + return status; + } + ++/* Validate version. ++ * ++ * A version must match the following regular expression to be ++ * considered valid: ++ * ++ * ^[:print:]+$ ++ * ++ * returns 0 if version is valid, returns -1 otherwise. ++ */ ++int semanage_module_validate_version(const char *version) ++{ ++ int status = 0; ++ ++ if (version == NULL) { ++ status = -1; ++ goto exit; ++ } ++ ++ /* must start with a printable char */ ++ if (!isprint(*version)) { ++ status = -1; ++ goto exit; ++ } ++ ++ /* everything else must be printable */ ++#define ISVALIDCHAR(c) (isprint(c)) ++ ++ for (version++; *version; version++) { ++ if (ISVALIDCHAR(*version)) { ++ continue; ++ } ++ status = -1; ++ goto exit; ++ } ++ ++#undef ISVALIDCHAR ++ ++exit: ++ return status; ++} ++ ++ ++ + int semanage_module_get_module_info(semanage_handle_t *sh, + const semanage_module_key_t *modkey, + semanage_module_info_t **modinfo) +diff --git libsemanage-2.5/src/modules.h libsemanage-2.5/src/modules.h +index 8a5c01f..ee3d51d 100644 +--- libsemanage-2.5/src/modules.h ++++ libsemanage-2.5/src/modules.h +@@ -44,6 +44,7 @@ struct semanage_module_info { + uint16_t priority; /* key, module priority */ + char *name; /* key, module name */ + char *lang_ext; /* module source language extension */ ++ char *module_version; /* module version, applies only for pp modules */ + int enabled; /* module enabled/disabled status */ + }; + +diff --git libsemanage-2.5/src/policy_components.c libsemanage-2.5/src/policy_components.c +index d31bd48..896ac51 100644 +--- libsemanage-2.5/src/policy_components.c ++++ libsemanage-2.5/src/policy_components.c +@@ -137,12 +137,17 @@ int semanage_base_merge_components(semanage_handle_t * handle) + + {semanage_node_dbase_local(handle), + semanage_node_dbase_policy(handle), MODE_MODIFY | MODE_SORT}, ++ ++ {semanage_ibpkey_dbase_local(handle), ++ semanage_ibpkey_dbase_policy(handle), MODE_MODIFY}, ++ ++ {semanage_ibendport_dbase_local(handle), ++ semanage_ibendport_dbase_policy(handle), MODE_MODIFY}, + }; + const unsigned int CCOUNT = sizeof(components) / sizeof(components[0]); + + /* Merge components into policy (and validate) */ + for (i = 0; i < CCOUNT; i++) { +- + record_t **records = NULL; + unsigned int nrecords = 0; + +@@ -218,6 +223,8 @@ int semanage_commit_components(semanage_handle_t * handle) + semanage_seuser_dbase_policy(handle), + semanage_bool_dbase_active(handle), + semanage_node_dbase_local(handle), ++ semanage_ibpkey_dbase_local(handle), ++ semanage_ibendport_dbase_local(handle), + }; + const int CCOUNT = sizeof(components) / sizeof(components[0]); + +diff --git libsemanage-2.5/src/semanage_store.c libsemanage-2.5/src/semanage_store.c +index fa0876f..c13b763 100644 +--- libsemanage-2.5/src/semanage_store.c ++++ libsemanage-2.5/src/semanage_store.c +@@ -95,23 +95,28 @@ static const char *semanage_store_paths[SEMANAGE_NUM_STORES] = { + static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = { + "", + "/modules", +- "/base.linked", ++ "/policy.linked", + "/homedir_template", + "/file_contexts.template", + "/commit_num", ++ "/pkeys.local", ++ "/ibendports.local", + "/ports.local", + "/interfaces.local", + "/nodes.local", + "/booleans.local", + "/seusers.local", ++ "/seusers.linked", + "/users.local", + "/users_extra.local", ++ "/users_extra.linked", + "/users_extra", + "/disable_dontaudit", + "/preserve_tunables", + "/modules/disabled", + "/policy.kern", + "/file_contexts.local", ++ "/file_contexts.homedirs", + "/file_contexts", + "/seusers" + }; +@@ -292,6 +297,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh) + goto cleanup; + } + ++ if (asprintf(&semanage_final_suffix[SEMANAGE_FC_BIN], "%s.bin", ++ semanage_final_suffix[SEMANAGE_FC]) < 0) { ++ ERR(sh, "Unable to allocate space for file context path."); ++ status = -1; ++ goto cleanup; ++ } ++ + semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] = + strdup(selinux_file_context_homedir_path() + offset); + if (semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] == NULL) { +@@ -300,6 +312,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh) + goto cleanup; + } + ++ if (asprintf(&semanage_final_suffix[SEMANAGE_FC_HOMEDIRS_BIN], "%s.bin", ++ semanage_final_suffix[SEMANAGE_FC_HOMEDIRS]) < 0) { ++ ERR(sh, "Unable to allocate space for file context home directory path."); ++ status = -1; ++ goto cleanup; ++ } ++ + semanage_final_suffix[SEMANAGE_FC_LOCAL] = + strdup(selinux_file_context_local_path() + offset); + if (semanage_final_suffix[SEMANAGE_FC_LOCAL] == NULL) { +@@ -308,6 +327,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh) + goto cleanup; + } + ++ if (asprintf(&semanage_final_suffix[SEMANAGE_FC_LOCAL_BIN], "%s.bin", ++ semanage_final_suffix[SEMANAGE_FC_LOCAL]) < 0) { ++ ERR(sh, "Unable to allocate space for local file context path."); ++ status = -1; ++ goto cleanup; ++ } ++ + semanage_final_suffix[SEMANAGE_NC] = + strdup(selinux_netfilter_context_path() + offset); + if (semanage_final_suffix[SEMANAGE_NC] == NULL) { +@@ -512,7 +538,6 @@ char *semanage_conf_path(void) + int semanage_create_store(semanage_handle_t * sh, int create) + { + struct stat sb; +- int mode_mask = R_OK | W_OK | X_OK; + const char *path = semanage_files[SEMANAGE_ROOT]; + int fd; + +@@ -531,9 +556,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) + return -1; + } + } else { +- if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) { ++ if (!S_ISDIR(sb.st_mode)) { + ERR(sh, +- "Could not access module store at %s, or it is not a directory.", ++ "Module store at %s is not a directory.", + path); + return -1; + } +@@ -554,9 +579,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) + return -1; + } + } else { +- if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) { ++ if (!S_ISDIR(sb.st_mode)) { + ERR(sh, +- "Could not access module store active subdirectory at %s, or it is not a directory.", ++ "Module store active subdirectory at %s is not a directory.", + path); + return -1; + } +@@ -577,9 +602,9 @@ int semanage_create_store(semanage_handle_t * sh, int create) + return -1; + } + } else { +- if (!S_ISDIR(sb.st_mode) || access(path, mode_mask) == -1) { ++ if (!S_ISDIR(sb.st_mode)) { + ERR(sh, +- "Could not access module store active modules subdirectory at %s, or it is not a directory.", ++ "Module store active modules subdirectory at %s is not a directory.", + path); + return -1; + } +@@ -598,8 +623,8 @@ int semanage_create_store(semanage_handle_t * sh, int create) + return -1; + } + } else { +- if (!S_ISREG(sb.st_mode) || access(path, R_OK | W_OK) == -1) { +- ERR(sh, "Could not access lock file at %s.", path); ++ if (!S_ISREG(sb.st_mode)) { ++ ERR(sh, "Lock file at %s missing.", path); + return -1; + } + } +@@ -1137,7 +1162,7 @@ cleanup: + free(all_modinfos); + + if (status != 0) { +- for (i = 0; i < j; j++) { ++ for (i = 0; i < j; i++) { + semanage_module_info_destroy(sh, &(*modinfo)[i]); + } + free(*modinfo); +@@ -1491,6 +1516,45 @@ static int sefcontext_compile(semanage_handle_t * sh, const char *path) { + return 0; + } + ++static int semanage_validate_and_compile_fcontexts(semanage_handle_t * sh) ++{ ++ int status = -1; ++ ++ if (sh->do_check_contexts) { ++ int ret; ++ ret = semanage_exec_prog( ++ sh, ++ sh->conf->setfiles, ++ semanage_final_path(SEMANAGE_FINAL_TMP, ++ SEMANAGE_KERNEL), ++ semanage_final_path(SEMANAGE_FINAL_TMP, ++ SEMANAGE_FC)); ++ if (ret != 0) { ++ ERR(sh, "setfiles returned error code %d.", ret); ++ goto cleanup; ++ } ++ } ++ ++ if (sefcontext_compile(sh, ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)) != 0) { ++ goto cleanup; ++ } ++ ++ if (sefcontext_compile(sh, ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL)) != 0) { ++ goto cleanup; ++ } ++ ++ if (sefcontext_compile(sh, ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS)) != 0) { ++ goto cleanup; ++ } ++ ++ status = 0; ++cleanup: ++ return status; ++} ++ + /* Load the contexts of the final tmp into the final selinux directory. + * Return 0 on success, -3 on error. + */ +@@ -1566,35 +1630,6 @@ static int semanage_install_final_tmp(semanage_handle_t * sh) + } + + skip_reload: +- if (sh->do_check_contexts) { +- ret = semanage_exec_prog( +- sh, +- sh->conf->setfiles, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, +- SEMANAGE_KERNEL), +- semanage_final_path(SEMANAGE_FINAL_SELINUX, +- SEMANAGE_FC)); +- if (ret != 0) { +- ERR(sh, "setfiles returned error code %d.", ret); +- goto cleanup; +- } +- } +- +- if (sefcontext_compile(sh, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC)) != 0) { +- goto cleanup; +- } +- +- if (sefcontext_compile(sh, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_LOCAL)) != 0) { +- goto cleanup; +- } +- +- if (sefcontext_compile(sh, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_HOMEDIRS)) != 0) { +- goto cleanup; +- } +- + status = 0; + cleanup: + return status; +@@ -1737,6 +1772,9 @@ int semanage_install_sandbox(semanage_handle_t * sh) + goto cleanup; + } + ++ if (semanage_validate_and_compile_fcontexts(sh) < 0) ++ goto cleanup; ++ + if ((commit_num = semanage_commit_sandbox(sh)) < 0) { + retval = commit_num; + goto cleanup; +@@ -2003,9 +2041,10 @@ int semanage_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filename + */ + + /** +- * Read the policy from the sandbox (kernel) ++ * Read the policy from the sandbox (linked or kernel) + */ +-int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in) ++int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in, ++ enum semanage_sandbox_defs file) + { + + int retval = STATUS_ERR; +@@ -2014,7 +2053,7 @@ int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in) + FILE *infile = NULL; + + if ((kernel_filename = +- semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL)) == NULL) { ++ semanage_path(SEMANAGE_ACTIVE, file)) == NULL) { + goto cleanup; + } + if ((infile = fopen(kernel_filename, "r")) == NULL) { +@@ -2044,18 +2083,20 @@ int semanage_read_policydb(semanage_handle_t * sh, sepol_policydb_t * in) + return retval; + } + /** +- * Writes the final policy to the sandbox (kernel) ++ * Writes the policy to the sandbox (linked or kernel) + */ +-int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out) ++int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out, ++ enum semanage_sandbox_defs file) + { + + int retval = STATUS_ERR; + const char *kernel_filename = NULL; + struct sepol_policy_file *pf = NULL; + FILE *outfile = NULL; ++ mode_t mask = umask(0077); + + if ((kernel_filename = +- semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL)) == NULL) { ++ semanage_path(SEMANAGE_TMP, file)) == NULL) { + goto cleanup; + } + if ((outfile = fopen(kernel_filename, "wb")) == NULL) { +@@ -2081,6 +2122,7 @@ int semanage_write_policydb(semanage_handle_t * sh, sepol_policydb_t * out) + if (outfile != NULL) { + fclose(outfile); + } ++ umask(mask); + sepol_policy_file_free(pf); + return retval; + } +diff --git libsemanage-2.5/src/semanage_store.h libsemanage-2.5/src/semanage_store.h +index acb6e3f..34bf852 100644 +--- libsemanage-2.5/src/semanage_store.h ++++ libsemanage-2.5/src/semanage_store.h +@@ -44,19 +44,24 @@ enum semanage_sandbox_defs { + SEMANAGE_HOMEDIR_TMPL, + SEMANAGE_FC_TMPL, + SEMANAGE_COMMIT_NUM_FILE, ++ SEMANAGE_IBPKEYS_LOCAL, ++ SEMANAGE_IBENDPORTS_LOCAL, + SEMANAGE_PORTS_LOCAL, + SEMANAGE_INTERFACES_LOCAL, + SEMANAGE_NODES_LOCAL, + SEMANAGE_BOOLEANS_LOCAL, + SEMANAGE_SEUSERS_LOCAL, ++ SEMANAGE_SEUSERS_LINKED, + SEMANAGE_USERS_BASE_LOCAL, + SEMANAGE_USERS_EXTRA_LOCAL, ++ SEMANAGE_USERS_EXTRA_LINKED, + SEMANAGE_USERS_EXTRA, + SEMANAGE_DISABLE_DONTAUDIT, + SEMANAGE_PRESERVE_TUNABLES, + SEMANAGE_MODULES_DISABLED, + SEMANAGE_STORE_KERNEL, + SEMANAGE_STORE_FC_LOCAL, ++ SEMANAGE_STORE_FC_HOMEDIRS, + SEMANAGE_STORE_FC, + SEMANAGE_STORE_SEUSERS, + SEMANAGE_STORE_NUM_PATHS +@@ -71,8 +76,11 @@ enum semanage_final_defs { + enum semanage_final_path_defs { + SEMANAGE_FINAL_TOPLEVEL, + SEMANAGE_FC, ++ SEMANAGE_FC_BIN, + SEMANAGE_FC_HOMEDIRS, ++ SEMANAGE_FC_HOMEDIRS_BIN, + SEMANAGE_FC_LOCAL, ++ SEMANAGE_FC_LOCAL_BIN, + SEMANAGE_KERNEL, + SEMANAGE_NC, + SEMANAGE_SEUSERS, +@@ -126,10 +134,12 @@ int semanage_load_files(semanage_handle_t * sh, + cil_db_t *cildb, char **filenames, int num_modules); + + int semanage_read_policydb(semanage_handle_t * sh, +- sepol_policydb_t * policydb); ++ sepol_policydb_t * policydb, ++ enum semanage_sandbox_defs file); + + int semanage_write_policydb(semanage_handle_t * sh, +- sepol_policydb_t * policydb); ++ sepol_policydb_t * policydb, ++ enum semanage_sandbox_defs file); + + int semanage_install_sandbox(semanage_handle_t * sh); + +diff --git libsemanage-2.5/src/semanageswig.i libsemanage-2.5/src/semanageswig.i +index 583b7d8..ebf39cf 100644 +--- libsemanage-2.5/src/semanageswig.i ++++ libsemanage-2.5/src/semanageswig.i +@@ -39,6 +39,12 @@ + %include "../include/semanage/port_record.h" + %include "../include/semanage/ports_local.h" + %include "../include/semanage/ports_policy.h" ++%include "../include/semanage/ibpkey_record.h" ++%include "../include/semanage/ibpkeys_local.h" ++%include "../include/semanage/ibpkeys_policy.h" ++%include "../include/semanage/ibendport_record.h" ++%include "../include/semanage/ibendports_local.h" ++%include "../include/semanage/ibendports_policy.h" + %include "../include/semanage/fcontext_record.h" + %include "../include/semanage/fcontexts_local.h" + %include "../include/semanage/fcontexts_policy.h" +diff --git libsemanage-2.5/src/semanageswig_python.i libsemanage-2.5/src/semanageswig_python.i +index 1346b2e..8604b8a 100644 +--- libsemanage-2.5/src/semanageswig_python.i ++++ libsemanage-2.5/src/semanageswig_python.i +@@ -437,6 +437,92 @@ + $1 = &temp; + } + ++/** ibpkey typemaps **/ ++ ++/* the wrapper will setup this parameter for passing... the resulting python functions ++ will not take the semanage_ibpkey_t *** parameter */ ++%typemap(in, numinputs=0) semanage_ibpkey_t ***(semanage_ibpkey_t **temp=NULL) { ++ $1 = &temp; ++} ++ ++%typemap(argout) ( ++ semanage_handle_t* handle, ++ semanage_ibpkey_t*** records, ++ unsigned int* count) { ++ ++ if ($result) { ++ int value; ++ SWIG_AsVal_int($result, &value); ++ if (value >= 0) { ++ PyObject* plist = NULL; ++ if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_ibpkey, ++ (void (*) (void*)) &semanage_ibpkey_free, &plist) < 0) ++ $result = SWIG_From_int(STATUS_ERR); ++ else ++ $result = SWIG_Python_AppendOutput($result, plist); ++ } ++ } ++} ++ ++%typemap(in, numinputs=0) semanage_ibpkey_t **(semanage_ibpkey_t *temp=NULL) { ++ $1 = &temp; ++} ++ ++%typemap(argout) semanage_ibpkey_t ** { ++ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); ++} ++ ++%typemap(argout) semanage_ibpkey_key_t ** { ++ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); ++} ++ ++%typemap(in, numinputs=0) semanage_ibpkey_key_t **(semanage_ibpkey_key_t *temp=NULL) { ++ $1 = &temp; ++} ++ ++/** ibendport typemaps **/ ++ ++/* the wrapper will setup this parameter for passing... the resulting python functions ++ will not take the semanage_ibendport_t *** parameter */ ++%typemap(in, numinputs=0) semanage_ibendport_t ***(semanage_ibendport_t **temp=NULL) { ++ $1 = &temp; ++} ++ ++%typemap(argout) ( ++ semanage_handle_t* handle, ++ semanage_ibendport_t*** records, ++ unsigned int* count) { ++ ++ if ($result) { ++ int value; ++ SWIG_AsVal_int($result, &value); ++ if (value >= 0) { ++ PyObject* plist = NULL; ++ if (semanage_array2plist($1, (void**) *$2, *$3, SWIGTYPE_p_semanage_ibendport, ++ (void (*) (void*)) &semanage_ibendport_free, &plist) < 0) ++ $result = SWIG_From_int(STATUS_ERR); ++ else ++ $result = SWIG_Python_AppendOutput($result, plist); ++ } ++ } ++} ++ ++%typemap(in, numinputs=0) semanage_ibendport_t **(semanage_ibendport_t *temp=NULL) { ++ $1 = &temp; ++} ++ ++%typemap(argout) semanage_ibendport_t ** { ++ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); ++} ++ ++%typemap(argout) semanage_ibendport_key_t ** { ++ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0)); ++} ++ ++%typemap(in, numinputs=0) semanage_ibendport_key_t **(semanage_ibendport_key_t *temp=NULL) { ++ $1 = &temp; ++} ++ + /** node typemaps **/ + + /* the wrapper will setup this parameter for passing... the resulting python functions +diff --git libsemanage-2.5/tests/.gitignore libsemanage-2.5/tests/.gitignore +new file mode 100644 +index 0000000..f07111d +--- /dev/null ++++ libsemanage-2.5/tests/.gitignore +@@ -0,0 +1 @@ ++libsemanage-tests +diff --git libsemanage-2.5/utils/semanage_migrate_store libsemanage-2.5/utils/semanage_migrate_store +index 0ebd285..fe6b5a9 100755 +--- libsemanage-2.5/utils/semanage_migrate_store ++++ libsemanage-2.5/utils/semanage_migrate_store +@@ -218,7 +218,7 @@ if __name__ == "__main__": + parser.add_option("-n", "--norebuild", dest="norebuild", action="store_true", default=False, + help="Disable rebuilding policy after migration (default: no)") + parser.add_option("-P", "--path", dest="path", +- help="Set path for the policy store (default: /var/lib/selinux)") ++ help="Set path for the policy store (default: /etc/selinux)") + parser.add_option("-r", "--root", dest="root", + help="Set an alternative root for the migration (default: /)") + +@@ -231,7 +231,7 @@ if __name__ == "__main__": + NOREBUILD = options.norebuild + PATH = options.path + if PATH is None: +- PATH = "/var/lib/selinux" ++ PATH = "/etc/selinux" + + ROOT = options.root + if ROOT is None: +@@ -253,7 +253,9 @@ if __name__ == "__main__": + "preserve_tunables", + "policy.kern", + "file_contexts", +- "homedir_template"] ++ "homedir_template", ++ "pkeys.local", ++ "ibendports.local"] + + + create_dir(newroot_path(), 0o755) diff --git a/SOURCES/semanage.conf b/SOURCES/semanage.conf new file mode 100644 index 00000000..bc9d4ac9 --- /dev/null +++ b/SOURCES/semanage.conf @@ -0,0 +1,51 @@ +# Authors: Jason Tang +# +# Copyright (C) 2004-2005 Tresys Technology, LLC +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +# Specify how libsemanage will interact with a SELinux policy manager. +# The four options are: +# +# "source" - libsemanage manipulates a source SELinux policy +# "direct" - libsemanage will write directly to a module store. +# /foo/bar - Write by way of a policy management server, whose +# named socket is at /foo/bar. The path must begin +# with a '/'. +# foo.com:4242 - Establish a TCP connection to a remote policy +# management server at foo.com. If there is a colon +# then the remainder is interpreted as a port number; +# otherwise default to port 4242. +module-store = direct + +# When generating the final linked and expanded policy, by default +# semanage will set the policy version to POLICYDB_VERSION_MAX, as +# given in . Change this setting if a different +# version is necessary. +#policy-version = 19 + +# expand-check check neverallow rules when executing all semanage commands. +# Large penalty in time if you turn this on. +expand-check=0 + +# usepasswd check tells semanage to scan all pass word records for home directories +# and setup the labeling correctly. If this is turned off, SELinux will label /home +# correctly only. You will need to use semanage fcontext command. +# For example, if you had home dirs in /althome directory you would have to execute +# semanage fcontext -a -e /home /althome +usepasswd=False +bzip-small=true +bzip-blocksize=5 +ignoredirs=/root diff --git a/SPECS/libsemanage.spec b/SPECS/libsemanage.spec new file mode 100644 index 00000000..eb09964d --- /dev/null +++ b/SPECS/libsemanage.spec @@ -0,0 +1,1365 @@ +%global with_python3 0 +%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print (get_python_lib(1))")} + +%define libsepolver 2.5-8 +%define libselinuxver 2.5-12 + +Summary: SELinux binary policy manipulation library +Name: libsemanage +Version: 2.5 +Release: 11%{?dist} +License: LGPLv2+ +Group: System Environment/Libraries +Source: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20160223/libsemanage-2.5.tar.gz +# HEAD 5a336c116e3808e21a2334671fffed73348111c9 +Patch1: libsemanage-rhel.patch +URL: https://github.com/SELinuxProject/selinux/wiki +Source1: semanage.conf + +BuildRequires: libselinux-devel >= %{libselinuxver} swig ustr-devel +BuildRequires: libsepol-devel >= %{libsepolver} +BuildRequires: audit-libs-devel +BuildRequires: python python-devel bison flex bzip2-devel + +%if 0%{?with_python3} +BuildRequires: python3 python3-devel +%endif # if with_python3 + +Requires: bzip2-libs audit-libs +Requires: libselinux >= %{libselinuxver} +Requires: libsepol >= %{libsepolver} +Conflicts: selinux-policy-base < 3.13.1-66 + +%description +Security-enhanced Linux is a feature of the Linux® kernel and a number +of utilities with enhanced security functionality designed to add +mandatory access controls to Linux. The Security-enhanced Linux +kernel contains new architectural components originally developed to +improve the security of the Flask operating system. These +architectural components provide general support for the enforcement +of many kinds of mandatory access control policies, including those +based on the concepts of Type Enforcement®, Role-based Access +Control, and Multi-level Security. + +libsemanage provides an API for the manipulation of SELinux binary policies. +It is used by checkpolicy (the policy compiler) and similar tools, as well +as by programs like load_policy that need to perform specific transformations +on binary policies such as customizing policy boolean settings. + +%package static +Summary: Static library used to build policy manipulation tools +Group: Development/Libraries +Requires: libsemanage-devel = %{version}-%{release} + +%description static +The semanage-static package contains the static libraries +needed for developing applications that manipulate binary policies. + +%package devel +Summary: Header files and libraries used to build policy manipulation tools +Group: Development/Libraries +Requires: libsemanage = %{version}-%{release} ustr + +%description devel +The semanage-devel package contains the libraries and header files +needed for developing applications that manipulate binary policies. + +%package python +Summary: semanage python bindings for libsemanage +Group: Development/Libraries +Requires: libsemanage = %{version}-%{release} + +%description python +The libsemanage-python package contains the python bindings for developing +SELinux management applications. + +%if 0%{?with_python3} +%package python3 +Summary: semanage python 3 bindings for libsemanage +Group: Development/Libraries +Requires: libsemanage = %{version}-%{release} +Requires: libselinux-python3 + +%description python3 +The libsemanage-python3 package contains the python 3 bindings for developing +SELinux management applications. +%endif # if with_python3 + +%prep +%setup -q -n libsemanage-2.5 +%patch1 -p1 -b .rhel + + +%build +export LDFLAGS="%{?__global_ldflags}" + +# To support building the Python wrapper against multiple Python runtimes +# Define a function, for how to perform a "build" of the python wrapper against +# a specific runtime: +BuildPythonWrapper() { + BinaryName=$1 + + # Perform the build from the upstream Makefile: + make \ + PYTHON=$BinaryName \ + CFLAGS="%{optflags}" LIBDIR="%{_libdir}" SHLIBDIR="%{_lib}" \ + pywrap +} + +make clean +make CFLAGS="%{optflags}" swigify +make CFLAGS="%{optflags}" LIBDIR="%{_libdir}" SHLIBDIR="%{_lib}" all + +BuildPythonWrapper \ + %{__python} + +%if 0%{?with_python3} +BuildPythonWrapper \ + %{__python3} +%endif # with_python3 + +%install +InstallPythonWrapper() { + BinaryName=$1 + + make \ + PYTHON=$BinaryName \ + DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="${RPM_BUILD_ROOT}%{_libdir}" SHLIBDIR="${RPM_BUILD_ROOT}/%{_libdir}" \ + install-pywrap +} + +rm -rf ${RPM_BUILD_ROOT} +mkdir -p ${RPM_BUILD_ROOT}%{_libdir} +mkdir -p ${RPM_BUILD_ROOT}%{_includedir} +mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/selinux/tmp +make DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="${RPM_BUILD_ROOT}%{_libdir}" SHLIBDIR="${RPM_BUILD_ROOT}/%{_libdir}" install + +InstallPythonWrapper \ + %{__python} \ + .so + +%if 0%{?with_python3} +InstallPythonWrapper \ + %{__python3} \ + $(python3-config --extension-suffix) +%endif # with_python3 + +cp %{SOURCE1} ${RPM_BUILD_ROOT}/etc/selinux/semanage.conf +ln -sf %{_libdir}/libsemanage.so.1 ${RPM_BUILD_ROOT}/%{_libdir}/libsemanage.so + +%clean +rm -rf ${RPM_BUILD_ROOT} + +%files +%defattr(-,root,root) +%{!?_licensedir:%global license %%doc} +%license COPYING +%dir %{_sysconfdir}/selinux +%dir %{_sysconfdir}/selinux/tmp +%config(noreplace) %{_sysconfdir}/selinux/semanage.conf +%{_libdir}/libsemanage.so.1 +%{_mandir}/man5/* +%dir %{_libexecdir}/selinux + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files static +%defattr(-,root,root) +%{_libdir}/libsemanage.a + +%files devel +%defattr(-,root,root) +%{_libdir}/libsemanage.so +%{_libdir}/pkgconfig/libsemanage.pc +%dir %{_includedir}/semanage +%{_includedir}/semanage/*.h +%{_mandir}/man3/* +%{_mandir}/man5/* + +%files python +%defattr(-,root,root) +%{python_sitearch}/_semanage.so +%{python_sitearch}/semanage.py* +%{_libexecdir}/selinux/semanage_migrate_store + +%if 0%{?with_python3} +%files python3 +%defattr(-,root,root) +%{python3_sitearch}/*.so +%{python3_sitearch}/semanage.py* +%{python3_sitearch}/__pycache__/semanage* +%endif # if with_python3 + +%changelog +* Tue Feb 27 2018 Vit Mojzis - 2.5-11 +- Add dependencies on libselinux and libsemanage (#1548020) + +* Wed Nov 29 2017 Petr Lautrbach - 2.5-10 +- Use umask(0077) for fopen() write operations (#1512639, #1512014) + +* Wed Oct 18 2017 Vit Mojzis - 2.5-9 +- Update semanage to allow runtime labeling of Infiniband Pkeys (#1466274) +- Update semanage to allow runtime labeling of ibendports (#1466274) +- Keep copy of file_contexts.homedirs in policy store (#1409813) +- Add support for listing fcontext.homedirs file (#1409813) + +* Wed May 03 2017 Petr Lautrbach - 2.5-8 +- Save linked policy, skip re-link when possible +- Replace access(,F_OK) checks to make setuid programs work (#1186431) + +* Thu Mar 30 2017 Petr Lautrbach - 2.5-7.1 +- genhomedircon - improve handling large groups (#1379685) + +* Mon Mar 27 2017 Petr Lautrbach - 2.5-6.1 +- Remove access() check to make setuid programs work (#1186431) + +* Mon Nov 21 2016 Petr Lautrbach - 2.5-5.1 +- Re-add get/set_version functions needed for semodule -l (#1392573) + +* Fri Aug 26 2016 Petr Lautrbach 2.5-4 +- genhomedircon: add support for %group syntax +- genhomedircon: generate contexts for logins mapped to the default user +- Validate and compile file contexts before installing +- Swap tcp and udp protocol numbers + +* Mon Jun 27 2016 Petr Lautrbach - 2.5-3 +- Sort object files for deterministic linking order +- Support overriding Makefile RANLIB +- Respect CC and PKG_CONFIG environment variable +- Fix multiple spelling errors +- genhomedircon: %{USERID} and %{USERNAME} support and code cleanups + +* Thu Mar 17 2016 Petr Lautrbach - 2.5-2.1 +- Set the default store to /etc/selinux + +* Tue Feb 23 2016 Petr Lautrbach 2.5-1 +- Update to upstream release 2016-02-23 + +* Wed Jul 22 2015 Petr Lautrbach 2.1.10-18 +- Add semanage.conf(5) man page +Resolves: rhbz#915651 + +* Tue Jul 07 2015 Petr Lautrbach 2.1.10-17 +- Skip policy module re-link when only setting booleans. +Resolves: rhbz#1098446 + +* Fri Jan 24 2014 Daniel Mach - 2.1.10-16 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 2.1.10-15 +- Mass rebuild 2013-12-27 + +* Wed Oct 16 2013 Dan Walsh - 2.1.10-14 +- Cleanup handling of missing mls_range to fix problems with useradd -Z +- Fix auditing of login record changes, roles were not working correctly. +Resolves: #1018840 + +* Fri Oct 4 2013 Dan Walsh - 2.1.10-13 +- Fix errors found by coverity +Resolves: #952237 + +* Wed Sep 25 2013 Dan Walsh - 2.1.10-12 +- Do not fail on missing SELinux User Record when adding login record + +* Mon Sep 23 2013 Dan Walsh - 2.1.10-11 +- Add msg to audit records + +* Thu Sep 19 2013 Dan Walsh - 2.1.10-10 +- Do not write error message to screen when looking for previous record for auditing. +- Add mls_range from user record if the MLS range is not specified by the seuser add record. +- Error out if seuser or mls range is not specified when adding user records + +* Mon Sep 9 2013 Dan Walsh - 2.1.10-9 +- Create symlink from policy.kern to active kernel. + +* Fri Sep 6 2013 Dan Walsh - 2.1.10-8 +- Unlink policy.kern when done to save space. + +* Fri Jul 26 2013 Dan Walsh - 2.1.10-7 +- Move handling of role audit records into the library +- Patch stops semanage from removing user record while in use + +* Tue Jul 9 2013 Dan Walsh - 2.1.10-6 +- Remove dependance on selinux-policy, /etc/selinux should be owned by libsemanage, and selinux-policy can require it. + +* Fri Jun 28 2013 Dan Walsh - 2.1.10-5 +- Allways build python3 version + +* Mon Apr 22 2013 Dan Walsh - 2.1.10-4 +- + +* Thu Apr 11 2013 Dan Walsh - 2.1.10-3 +- Fix test suite to build + +* Thu Feb 14 2013 Dan Walsh - 2.1.10-2 +- Revert some changes which are causing the wrong policy version file to be created + +* Thu Feb 7 2013 Dan Walsh - 2.1.10-1 +- Update to upstream + * Add sefcontext_compile to compile regex everytime policy is rebuilt + * Cleanup/fix enable/disable/remove module. + * redo genhomedircon minuid + * fixes from coverity + * semanage_store: do not leak memory in semanage_exec_prog + * genhomedircon: remove useless conditional in get_home_dirs + * genhomedircon: double free in get_home_dirs + * fcontext_record: do not leak on error in semanage_fcontext_key_create + * genhomedircon: do not leak on failure in write_gen_home_dir_context + * semanage_store: do not leak fd + * genhomedircon: do not leak shells list + * semanage_store: do not leak on strdup failure + * semanage_store: rewrite for readability + +* Wed Jan 16 2013 Dan Walsh 2.1.9-4 +- Add selinux-policy as a requires to get /etc/selinux owned + +* Sat Jan 5 2013 Dan Walsh 2.1.9-3 +- Update to latest patches from eparis/Upstream +- libsemanage: fixes from coverity +- libsemange: redo genhomedircon minuid + +* Wed Nov 21 2012 Dan Walsh - 2.1.9-2 +- Fix handling of missing semanage permissive -d foo, not failing correctly +- Previous to this fix the first module beginning with foo would get deleted. + +* Thu Sep 13 2012 Dan Walsh - 2.1.9-1 +- Update to upstream + * libsemanage: do not set soname needlessly + * libsemanage: remove PYTHONLIBDIR and ruby equivalent + * do boolean name substitution + * Fix segfault for building standard policies. + +* Fri Aug 03 2012 David Malcolm - 2.1.8-6 +- rebuild for https://fedoraproject.org/wiki/Features/Python_3.3 + +* Wed Aug 1 2012 David Malcolm - 2.1.8-5 +- remove rhel logic from with_python3 conditional + +* Thu Jul 19 2012 Fedora Release Engineering - 2.1.8-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jul 13 2012 Dan Walsh - 2.1.8-3 +- Attempt to allocate memory for selinux_binary_policy_path and free memory +- allocated by asprintf. + +* Thu Jul 12 2012 Dan Walsh - 2.1.8-2 +- Fix asprintf within an asprintf call + +* Wed Jul 4 2012 Dan Walsh - 2.1.8-1 +- Update to upstream + * remove build warning when build swig c files + * additional makefile support for rubywrap + * ignore 80 column limit for readability + * semanage_store: fix snprintf length argument by using asprintf + * Use default semanage.conf as a fallback + * use after free in python bindings + +* Tue May 29 2012 Dan Walsh - 2.1.7-2 +- Apply patch from Sven Vermeulen to fix problem with python3 bindings. + +* Thu Mar 29 2012 Dan Walsh - 2.1.7-1 +- Update to upstream + * Alternate path for semanage.conf + * do not link against libpython, this is considered bad in Debian + * Allow to build for several ruby version + * fallback-user-level + +* Wed Feb 15 2012 Dan Walsh - 2.1.6-3 +- Check in correct patch. + +* Fri Jan 13 2012 Fedora Release Engineering - 2.1.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Jan 6 2012 Dan Walsh - 2.1.6-2 +- Add patch form Xin Ouyang to make library use private semanage.conf + +* Wed Dec 21 2011 Dan Walsh - 2.1.6-1 +-Update to upstream + * add ignoredirs config for genhomedircon + * Fallback_user_level can be NULL if you are not using MLS + +* Thu Dec 15 2011 Dan Walsh - 2.1.5-4 +- Rebuild with latest libsepol + +* Thu Dec 15 2011 Dan Walsh - 2.1.5-3 +- Rebuild with latest libsepol + +* Thu Dec 15 2011 Dan Walsh - 2.1.5-2 +- Add support for ignoredirs param in /etc/selinux/semanage.conf + +* Fri Nov 4 2011 Dan Walsh - 2.1.5-1 +- Upgrade to upstream + * regenerate .pc on VERSION change + * maintain mode even if umask is tighter + * semanage.conf man page + * create man5dir if not exist + +* Wed Oct 19 2011 Dan Walsh - 2.1.4-2 +- Fix handling of umask, so files get created with the correct label. + +* Mon Sep 19 2011 Dan Walsh - 2.1.4-2 +- Add Guido Trentalancia semanage.conf man page + +* Mon Sep 19 2011 Dan Walsh - 2.1.4-1 +-Update to upstream + * Create a new preserve_tunables flag + * tree: default make target to all not + * fix semanage_store_access_check calling arguments + +* Wed Sep 14 2011 Dan Walsh - 2.1.3-2 +- Add support for preserving tunables + +* Tue Aug 30 2011 Dan Walsh - 2.1.3-1 +-Update to upstream + * python wrapper makefile changes + +* Thu Aug 18 2011 Dan Walsh - 2.1.2-1 +-Update to upstream +2.1.2 2011-08-17 + * print error debug info for buggy fc + * introduce semanage_set_root and friends + * throw exceptions in python rather than return + * python3 support. + * patch for MCS/MLS in user files + +2.1.1 2011-08-01 + * Remove generated files, expand .gitignore + * Use -Werror and change a few prototypes to support it + +* Thu Jul 28 2011 Dan Walsh - 2.1.0-1 +- Update to upstream + * Release, minor version bump + +* Wed Jun 8 2011 Dan Walsh - 2.0.46-6 +- More fixes for disabled modules + +* Tue Jun 7 2011 Dan Walsh - 2.0.46-5 +- Change libsemanage mechanism for handling disabled modules. Now it will only create a flag for a module +indicating the module is disabled. MODULE.pp.disabled, it will no longer rename the module. This way we can +ship active modules in rpm. + +* Wed Jun 1 2011 Dan Walsh - 2.0.46-4 +- Add semanage_set_selinux_path, to allow semodule to work on alternate selinux pools + +* Tue Feb 08 2011 Fedora Release Engineering - 2.0.46-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Dec 30 2010 David Malcolm - 2.0.46-2 +- big reworking of the support-multiple-python-builds patch to deal with +PEP 3149: the latest Python 3.2 onwards uses include paths and library names +that don't fit prior naming patterns, and so we must query python3-config for +this information. To complicate things further, python 2's python-config +doesn't understand all of the options needed ("--extension-suffix"). I've +thus added new Makefile variables as needed, to be supplied by the specfile by +invoking the appropriate config tool (or by hardcoding the old value for +"--extension-suffix" i.e. ".so") +- rework python3 manifest for PEP 3149, and rebuild for newer python3 + +* Tue Dec 21 2010 Dan Walsh - 2.0.46-1 +- Update to upstream + * Fix compliation under GCC 4.6 by Justin Mattock + +* Wed Aug 25 2010 Thomas Spura - 2.0.45-6 +- rebuild with python3.2 + http://lists.fedoraproject.org/pipermail/devel/2010-August/141368.html + +* Wed Jul 21 2010 David Malcolm - 2.0.45-5 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Tue Apr 27 2010 David Malcolm - 2.0.45-4 +- add python3 subpackage + +* Wed Apr 7 2010 Dan Walsh - 2.0.45-3 +- Fix -devel package to point at the correct shared library + +* Fri Mar 26 2010 Dan Walsh - 2.0.45-2 +- Move shared library to /usr/lib + +* Mon Mar 8 2010 Dan Walsh - 2.0.45-1 +- Update to upstream + * Add enable/disable patch support from Dan Walsh. + * Add usepasswd flag to semanage.conf to disable genhomedircon using + passwd from Dan Walsh. + * regenerate swig wrappers + +* Thu Feb 25 2010 Dan Walsh - 2.0.44-2 +- Allow disable of usepasswd + +* Wed Feb 17 2010 Dan Walsh - 2.0.44-1 +- Update to upstream + * Replace usage of fmemopen() with sepol_policy_file_set_mem() since + glibc < 2.9 does not support binary mode ('b') for fmemopen'd + streams. + +* Thu Jan 28 2010 Dan Walsh - 2.0.43-4 +- Cleanup spec file + +* Mon Jan 18 2010 Dan Walsh - 2.0.43-3 +- Splect libsemanage.a into a static subpackage to keep fedora packaging guidelines happy + +* Wed Dec 16 2009 Dan Walsh - 2.0.43-2 +- Rebuild all c programs with -fPIC + +* Tue Dec 1 2009 Dan Walsh - 2.0.43-1 +- Update to upstream + * Move libsemanage.so to /usr/lib + * Add NAME lines to man pages from Manoj Srivastava + +* Wed Nov 18 2009 Dan Walsh - 2.0.42-1 +- Update to upstream + * Move load_policy from /usr/sbin to /sbin from Dan Walsh. + +* Mon Nov 2 2009 Dan Walsh - 2.0.41-1 +- Update to upstream + * Add pkgconfig file from Eamon Walsh. + * Add semanage_set_check_contexts() function to disable calling + setfiles + +* Mon Sep 28 2009 Dan Walsh - 2.0.39-1 +- Update to upstream + * make swigify + +* Sun Sep 20 2009 Dan Walsh - 2.0.38-2 +- Dont relabel /root with genhomedircon + +* Thu Sep 17 2009 Dan Walsh - 2.0.38-1 +- Update to upstream + * Change semodule upgrade behavior to install even if the module + is not present from Dan Walsh. + * Make genhomedircon trim excess '/' from homedirs from Dan Walsh. + +* Wed Sep 9 2009 Dan Walsh - 2.0.37-1 +- Update to upstream + * Fix persistent dontaudit support to rebuild policy if the + dontaudit state is changed from Chad Sellers. +- Move load_policy to /sbin + +* Fri Aug 28 2009 Dan Walsh - 2.0.36-2 +- Add enable/disable modules + +* Wed Aug 26 2009 Dan Walsh - 2.0.36-1 +- Update to upstream + * Changed bzip-blocksize=0 handling to support existing compressed + modules in the store. + +* Wed Aug 26 2009 Dan Walsh - 2.0.35-2 +- Make sure /root is not used in genhomedircon + +* Wed Aug 5 2009 Dan Walsh - 2.0.35-1 +- Revert hard linking of files between tmp/active/previous. +- Enable configuration of bzip behavior from Stephen Smalley. +- bzip-blocksize=0 to disable compression and decompression support. +- bzip-blocksize=1..9 to set the blocksize for compression. +- bzip-small=true to reduce memory usage for decompression. + +* Sat Jul 25 2009 Fedora Release Engineering - 2.0.33-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri Jul 10 2009 Dan Walsh - 2.0.33-2 +- Put check for /root back into genhomedircon + +* Tue Jul 7 2009 Dan Walsh - 2.0.33-1 +- Update to upstream + +* Mon Jun 8 2009 Dan Walsh - 2.0.32-1 +- Update to upstream + * Ruby bindings from David Quigley. + +* Thu Apr 9 2009 Dan Walsh - 2.0.31-5 +- Return error on invalid file + +* Wed Mar 11 2009 Dan Walsh - 2.0.31-4 +- Fix typo + +* Wed Feb 25 2009 Fedora Release Engineering - 2.0.31-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Jan 15 2009 Dan Walsh - 2.0.31-2 +- Fix link to only link on sandbox + +* Mon Jan 12 2009 Dan Walsh - 2.0.31-1 +- Update to upstream + * Policy module compression (bzip) support from Dan Walsh. + * Hard link files between tmp/active/previous from Dan Walsh. + +* Mon Jan 12 2009 Dan Walsh - 2.0.30-3 +- Fix up patch to get it upstreamed + +* Thu Dec 04 2008 Ignacio Vazquez-Abrams - 2.0.30-2 +- Rebuild for Python 2.6 + +* Thu Dec 4 2008 Dan Walsh - 2.0.30-1 +- Add semanage_mls_enabled() interface from Stephen Smalley. + +* Sat Nov 29 2008 Ignacio Vazquez-Abrams - 2.0.29-2 +- Rebuild for Python 2.6 + +* Mon Sep 15 2008 Dan Walsh - 2.0.28-1 +- Update to upstream + * Add USER to lines to homedir_template context file from Chris PeBenito. + +* Mon Sep 15 2008 Dan Walsh - 2.0.28-2 +- Add compression support + +* Mon Sep 15 2008 Dan Walsh - 2.0.28-1 +- Update to upstream + * allow fcontext and seuser changes without rebuilding the policy from Dan Walsh + +* Wed Sep 10 2008 Dan Walsh - 2.0.27-3 +- Additional fixes for Don't rebuild on fcontext or seuser modifications + +* Tue Sep 2 2008 Dan Walsh - 2.0.27-2 +- Don't rebuild on fcontext or seuser modifications + +* Tue Aug 5 2008 Dan Walsh - 2.0.27-1 +- Update to upstream + * Modify genhomedircon to skip groupname entries. + Ultimately we need to expand them to the list of users to support per-role homedir labeling when using the groupname syntax. + +* Tue Jul 29 2008 Dan Walsh - 2.0.26-1 +- Update to upstream + * Fix bug in genhomedircon fcontext matches logic from Dan Walsh. + Strip any trailing slash before appending /*$. + +* Tue Jun 17 2008 Dan Walsh - 2.0.25-3 +- Another fix for genhomedircon + +* Wed May 28 2008 Tom "spot" Callaway - 2.0.25-2 +- fix license tag + +* Tue Feb 5 2008 Dan Walsh - 2.0.25-1 +- Update to upstream + * Do not call genhomedircon if the policy was not rebuilt from Stephen Smalley. + Fixes semanage boolean -D seg fault (bug 441379). + +* Tue Feb 5 2008 Dan Walsh - 2.0.24-1 +- Update to upstream + * make swigify + +* Tue Feb 5 2008 Dan Walsh - 2.0.23-1 +- Update to upstream + * Use vfork rather than fork for libsemanage helpers to reduce memory overhead as suggested by Todd Miller. + +* Mon Feb 4 2008 Dan Walsh - 2.0.22-1 +- Update to upstream + * Free policydb before fork from Joshua Brindle. + * Drop the base module immediately after expanding to permit memory re-use from Stephen Smalley. + +* Sat Feb 2 2008 Dan Walsh - 2.0.20-1 +- Update to upstream + * Use sepol_set_expand_consume_base to reduce peak memory usage when + using semodule + +* Fri Feb 1 2008 Dan Walsh - 2.0.19-1 +- Update to upstream + * Fix genhomedircon to not override a file context with a homedir context from Todd Miller. + +* Tue Jan 29 2008 Dan Walsh - 2.0.18-1 +- Update to upstream + * Fix spurious out of memory error reports. + * Merged second version of fix for genhomedircon handling from Caleb Case. + +* Tue Jan 22 2008 Dan Walsh - 2.0.16-1 +- Update to upstream + * Merged fix for genhomedircon handling of missing HOME_DIR or HOME_ROOT templates from Caleb Case. + +* Tue Jan 22 2008 Dan Walsh - 2.0.15-2 +- Stop differentiating on user for homedir labeling + +* Thu Dec 6 2007 Dan Walsh - 2.0.15-1 +- Update to upstream + * Fix genhomedircon handling of shells and missing user context template from Dan Walsh. + * Copy the store path in semanage_select_store from Dan Walsh. +- Add expand-check=0 to semanage.conf + +* Mon Dec 3 2007 Dan Walsh - 2.0.14-5 +- Fix handling of /etc/shells so genhomedircon will work + +* Thu Nov 29 2007 Dan Walsh - 2.0.14-3 +- Allow semanage_genhomedircon to work with out a USER int homedir.template + +* Sat Nov 10 2007 Dan Walsh - 2.0.14-2 +- Fix semanage_select_store to allocate memory, fixes crash on invalid store + +* Tue Nov 6 2007 Dan Walsh - 2.0.14-1 +- Upgrade to latest from NSA + * Call rmdir() rather than remove() on directory removal so that errno isn't polluted from Stephen Smalley. + * Allow handle_unknown in base to be overridden by semanage.conf from Stephen Smalley. + +* Fri Oct 5 2007 Dan Walsh - 2.0.12-1 +- Upgrade to latest from NSA + * ustr cleanups from James Antill. + * Ensure that /root gets labeled even if using the default context from Dan Walsh. + +* Fri Sep 28 2007 Dan Walsh - 2.0.11-1 +- Upgrade to latest from NSA + * Fix ordering of file_contexts.homedirs from Todd Miller and Dan Walsh. + +* Fri Sep 28 2007 Dan Walsh - 2.0.10-2 +- Fix sort order on generated homedir context + +* Fri Sep 28 2007 Dan Walsh - 2.0.10-1 +- Upgrade to latest from NSA + * Fix error checking on getpw*_r functions from Todd Miller. + * Make genhomedircon skip invalid homedir contexts from Todd Miller. + * Set default user and prefix from seusers from Dan Walsh. + * Add swigify Makefile target from Dan Walsh. + +* Wed Sep 26 2007 Dan Walsh - 2.0.9-1 +- Upgrade to latest from NSA + * Pass CFLAGS to CC even on link command, per Dennis Gilmore. + * Clear errno on non-fatal errors to avoid reporting them upon a + later error that does not set errno. + * Improve reporting of system errors, e.g. full filesystem or read-only filesystem from Stephen Smalley. + +- Fix segfault in genhomedircon when using bad user names + +* Wed Sep 26 2007 Dan Walsh - 2.0.6-2 +- Fix genhomedircon code to only generate valid context +- Fixes autorelabel problem + +* Thu Sep 13 2007 Dan Walsh - 2.0.6-1 +- Upgrade to latest from NSA + * Change to use getpw* function calls to the _r versions from Todd Miller. + +* Thu Aug 23 2007 Dan Walsh - 2.0.5-1 +- Upgrade to latest from NSA + +* Mon Aug 20 2007 Dan Walsh - 2.0.4-1 +- Upgrade to latest from NSA + * Allow dontaudits to be turned off via semanage interface when + updating policy + +* Sat Aug 11 2007 Dan Walsh - 2.0.3-5 +- Add ability to load a policy without dontaudit rules +- + +* Tue Jun 26 2007 Dan Walsh - 2.0.3-4 +- Rebuild to fix segfault on x86 platforms, swigify on each build + +* Fri Jun 1 2007 Dan Walsh - 2.0.3-3 +- Rebuild for rawhide + +* Thu May 3 2007 Dan Walsh - 2.0.3-2 +- Apply patch to fix dependencies in spec file from Robert Scheck + +* Wed Apr 25 2007 Dan Walsh - 2.0.3-1 +- Upgrade to latest from NSA + * Fix to libsemanage man patches so whatis will work better from Dan Walsh + +* Wed Apr 25 2007 Dan Walsh - 2.0.2-1 +- Upgrade to latest from NSA +- Merged optimizations from Stephen Smalley. +- do not set all booleans upon commit, only those whose values have changed +- only install the sandbox upon commit if something was rebuilt + +* Sat Mar 17 2007 Dan Walsh - 2.0.1-2 +- Add SELinux to Man page Names so man -k will work + +* Mon Mar 12 2007 Dan Walsh - 2.0.1-1 +- Merged dbase_file_flush patch from Dan Walsh. +- This removes any mention of specific tools (e.g. semanage) +- from the comment header of the auto-generated files, +- since there are multiple front-end tools. + +* Tue Feb 20 2007 Dan Walsh - 2.0.0-1 +- Upgrade to latest from NSA + * Merged Makefile test target patch from Caleb Case. + * Merged get_commit_number function rename patch from Caleb Case. + * Merged strnlen -> strlen patch from Todd Miller. + +* Wed Feb 7 2007 Dan Walsh - 1.10.1-1 +- Upgrade to latest from NSA + * Merged python binding fix from Dan Walsh. + * Updated version for stable branch. + +* Fri Dec 22 2006 Dan Walsh - 1.9.2-1 +- Upgrade to latest from NSA + * Merged patch to optionally reduce disk usage by removing + the backup module store and linked policy from Karl MacMillan + * Merged patch to correctly propagate return values in libsemanage + +* Fri Dec 22 2006 Dan Walsh - 1.9.1-3 +- Apply Karl MacMillan patch to get proper error codes. + +* Thu Dec 7 2006 Jeremy Katz - 1.9.1-2 +- rebuild against python 2.5 + +* Tue Nov 28 2006 Dan Walsh - 1.9.1-1 +- Upgrade to latest from NSA + * Merged patch to compile wit -fPIC instead of -fpic from + Manoj Srivastava to prevent hitting the global offest table + limit. Patch changed to include libselinux and libsemanage in + addition to libsepol. + +* Tue Oct 17 2006 Dan Walsh - 1.8-1 +- Upgrade to latest from NSA + * Updated version for release. + +* Thu Aug 31 2006 Dan Walsh - 1.6.17-1 +- Upgrade to latest from NSA + * Merged patch to skip reload if no active store exists and + the store path doesn't match the active store path from Dan Walsh. + * Merged patch to not destroy sepol handle on error path of + connect from James Athey. + * Merged patch to add genhomedircon path to semanage.conf from + James Athey. + +* Thu Aug 31 2006 Dan Walsh - 1.6.16-3 +- Fix semanage to not load if is not the correct policy type and it is installing + +* Thu Aug 31 2006 Dan Walsh - 1.6.16-2 +- Fix requires lines + +* Wed Aug 23 2006 Dan Walsh - 1.6.16-1 +- Upgrade to latest from NSA + * Make most copy errors fatal, but allow exceptions for + file_contexts.local, seusers, and netfilter_contexts if + the source file does not exist in the store. + +* Sat Aug 12 2006 Dan Walsh - 1.6.15-1 +- Upgrade to latest from NSA + * Merged separate local file contexts patch from Chris PeBenito. + * Merged patch to make most copy errors non-fatal from Dan Walsh. + +* Thu Aug 10 2006 Dan Walsh - 1.6.13-3 +- Change other updates to be non-fatal + +* Wed Aug 9 2006 Dan Walsh - 1.6.13-2 +- Change netfilter stuff to be non-fatal so update can proceed. + +* Thu Aug 3 2006 Dan Walsh - 1.6.13-1 +- Upgrade to latest from NSA + * Merged netfilter contexts support from Chris PeBenito. + +* Mon Jul 17 2006 Dan Walsh - 1.6.12-2 +- Rebuild for new gcc + +* Tue Jul 11 2006 Dan Walsh - 1.6.12-1 +- Upgrade to latest from NSA + * Merged support for read operations on read-only fs from + Caleb Case (Tresys Technology). + +* Tue Jul 4 2006 Dan Walsh - 1.6.11-1 +- Upgrade to latest from NSA + * Lindent. + * Merged setfiles location check patch from Dan Walsh. + +* Fri Jun 16 2006 Dan Walsh - 1.6.9-1 +- Upgrade to latest from NSA + * Merged several fixes from Serge Hallyn: + dbase_file_cache: deref of uninit data on error path. + dbase_policydb_cache: clear fp to avoid double fclose + semanage_fc_sort: destroy temp on error paths + +* Fri Jun 16 2006 Dan Walsh - 1.6.8-2 +- Handle setfiles being in /sbin or /usr/sbin + +* Mon May 15 2006 Dan Walsh - 1.6.8-1 +- Upgrade to latest from NSA + * Updated default location for setfiles to /sbin to + match policycoreutils. This can also be adjusted via + semanage.conf using the syntax: + [setfiles] + path = /path/to/setfiles + args = -q -c $@ $< + [end] + +* Mon May 15 2006 Dan Walsh - 1.6.7-3 +- Spec file cleanup from n0dalus+redhat@gmail.com + +* Mon May 15 2006 Dan Walsh - 1.6.7-2 +- Add /usr/include/semanage to spec file + +* Mon May 8 2006 Dan Walsh - 1.6.7-1 +- Upgrade to latest from NSA + * Merged fix warnings patch from Karl MacMillan. + +* Fri Apr 14 2006 Dan Walsh - 1.6.6-1 +- Upgrade to latest from NSA + * Merged updated file context sorting patch from Christopher + Ashworth, with bug fix for escaped character flag. + * Merged file context sorting code from Christopher Ashworth + (Tresys Technology), based on fc_sort.c code in refpolicy. + * Merged python binding t_output_helper removal patch from Dan Walsh. + * Regenerated swig files. + +* Wed Mar 29 2006 Dan Walsh - 1.6.3-1 +- Fix to work with new version of swig +- Upgrade to latest from NSA + * Merged corrected fix for descriptor leak from Dan Walsh. + +* Wed Mar 29 2006 Dan Walsh - 1.6.2-2 +- Fix leaky descriptor + +* Tue Mar 21 2006 Dan Walsh - 1.6.2-1 +- Upgrade to latest from NSA + * Merged Makefile PYLIBVER definition patch from Dan Walsh. + * Merged man page reorganization from Ivan Gyurdiev. + +* Fri Mar 17 2006 Dan Walsh - 1.6-1 +- Make work on RHEL4 +- Upgrade to latest from NSA + * Merged abort early on merge errors patch from Ivan Gyurdiev. + * Cleaned up error handling in semanage_split_fc based on a patch + by Serge Hallyn (IBM) and suggestions by Ivan Gyurdiev. + * Merged MLS handling fixes from Ivan Gyurdiev. + +* Fri Feb 17 2006 Dan Walsh - 1.5.28-1 +- Upgrade to latest from NSA + * Merged bug fix for fcontext validate handler from Ivan Gyurdiev. + * Merged base_merge_components changes from Ivan Gyurdiev. + +* Thu Feb 16 2006 Dan Walsh - 1.5.26-1 +- Upgrade to latest from NSA + * Merged paths array patch from Ivan Gyurdiev. + * Merged bug fix patch from Ivan Gyurdiev. + * Merged improve bindings patch from Ivan Gyurdiev. + * Merged use PyList patch from Ivan Gyurdiev. + * Merged memory leak fix patch from Ivan Gyurdiev. + * Merged nodecon support patch from Ivan Gyurdiev. + * Merged cleanups patch from Ivan Gyurdiev. + * Merged split swig patch from Ivan Gyurdiev. + +* Mon Feb 13 2006 Dan Walsh - 1.5.23-1 +- Upgrade to latest from NSA + * Merged optionals in base patch from Joshua Brindle. + * Merged treat seusers/users_extra as optional sections patch from + Ivan Gyurdiev. + * Merged parse_optional fixes from Ivan Gyurdiev. + +* Fri Feb 10 2006 Jesse Keating - 1.5.21-2.1 +- bump again for double-long bug on ppc(64) + +* Fri Feb 10 2006 Dan Walsh - 1.5.21-2 +- Fix handling of seusers and users_map file + +* Tue Feb 07 2006 Dan Walsh - 1.5.21-1 +- Upgrade to latest from NSA + * Merged seuser/user_extra support patch from Joshua Brindle. + * Merged remote system dbase patch from Ivan Gyurdiev. + +* Tue Feb 07 2006 Jesse Keating - 1.5.20-1.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Feb 2 2006 Dan Walsh 1.5.20-1 +- Upgrade to latest from NSA + * Merged clone record on set_con patch from Ivan Gyurdiev. + +* Mon Jan 30 2006 Dan Walsh 1.5.19-1 +- Upgrade to latest from NSA + * Merged fname parameter patch from Ivan Gyurdiev. + * Merged more size_t -> unsigned int fixes from Ivan Gyurdiev. + * Merged seusers.system patch from Ivan Gyurdiev. + * Merged improve port/fcontext API patch from Ivan Gyurdiev. + +* Fri Jan 27 2006 Dan Walsh 1.5.18-1 +- Upgrade to latest from NSA + * Merged seuser -> seuser_local rename patch from Ivan Gyurdiev. + * Merged set_create_store, access_check, and is_connected interfaces + from Joshua Brindle. + +* Fri Jan 13 2006 Dan Walsh 1.5.16-1 +- Upgrade to latest from NSA + * Regenerate python wrappers. + +* Fri Jan 13 2006 Dan Walsh 1.5.15-1 +- Upgrade to latest from NSA + * Merged pywrap Makefile diff from Dan Walsh. + * Merged cache management patch from Ivan Gyurdiev. + * Merged bugfix for dbase_llist_clear from Ivan Gyurdiev. + * Merged remove apply_local function patch from Ivan Gyurdiev. + * Merged only do read locking in direct case patch from Ivan Gyurdiev. + * Merged cache error path memory leak fix from Ivan Gyurdiev. + * Merged auto-generated file header patch from Ivan Gyurdiev. + * Merged pywrap test update from Ivan Gyurdiev. + * Merged hidden defs update from Ivan Gyurdiev. + +* Fri Jan 13 2006 Dan Walsh 1.5.14-2 +- Break out python out of regular Makefile + +* Fri Jan 13 2006 Dan Walsh 1.5.14-1 +- Upgrade to latest from NSA + * Merged disallow port overlap patch from Ivan Gyurdiev. + * Merged join prereq and implementation patches from Ivan Gyurdiev. + * Merged join user extra data part 2 patch from Ivan Gyurdiev. + * Merged bugfix patch from Ivan Gyurdiev. + * Merged remove add_local/set_local patch from Ivan Gyurdiev. + * Merged user extra data part 1 patch from Ivan Gyurdiev. + * Merged size_t -> unsigned int patch from Ivan Gyurdiev. + * Merged calloc check in semanage_store patch from Ivan Gyurdiev, + bug noticed by Steve Grubb. + * Merged cleanups after add/set removal patch from Ivan Gyurdiev. + +* Sat Jan 7 2006 Dan Walsh 1.5.9-1 +- Upgrade to latest from NSA + * Merged const in APIs patch from Ivan Gyurdiev. + * Merged validation of local file contexts patch from Ivan Gyurdiev. + * Merged compare2 function patch from Ivan Gyurdiev. + * Merged hidden def/proto update patch from Ivan Gyurdiev. + +* Fri Jan 6 2006 Dan Walsh 1.5.8-1 +- Upgrade to latest from NSA + * Re-applied string and file optimization patch from Russell Coker, + with bug fix. + * Reverted string and file optimization patch from Russell Coker. + * Clarified error messages from parse_module_headers and + parse_base_headers for base/module mismatches. + +* Fri Jan 6 2006 Dan Walsh 1.5.6-1 +- Upgrade to latest from NSA + * Clarified error messages from parse_module_headers and + parse_base_headers for base/module mismatches. + * Merged string and file optimization patch from Russell Coker. + * Merged swig header reordering patch from Ivan Gyurdiev. + * Merged toggle modify on add patch from Ivan Gyurdiev. + * Merged ports parser bugfix patch from Ivan Gyurdiev. + * Merged fcontext swig patch from Ivan Gyurdiev. + * Merged remove add/modify/delete for active booleans patch from Ivan Gyurdiev. + * Merged man pages for dbase functions patch from Ivan Gyurdiev. + * Merged pywrap tests patch from Ivan Gyurdiev. + +* Thu Jan 5 2006 Dan Walsh 1.5.4-2 +- Patch to fix add + +* Thu Jan 5 2006 Dan Walsh 1.5.4-1 +- Upgrade to latest from NSA + * Merged patch series from Ivan Gyurdiev. + This includes patches to: + - separate file rw code from linked list + - annotate objects + - fold together internal headers + - support ordering of records in compare function + - add active dbase backend, active booleans + - return commit numbers for ro database calls + - use modified flags to skip rebuild whenever possible + - enable port interfaces + - update swig interfaces and typemaps + - add an API for file_contexts.local and file_contexts + - flip the traversal order in iterate/list + - reorganize sandbox_expand + - add seusers MLS validation + - improve dbase spec/documentation + - clone record on set/add/modify + +* Tue Dec 27 2005 Dan Walsh 1.5.3-3 +- Add Ivans patch to turn on ports + +* Wed Dec 14 2005 Dan Walsh 1.5.3-2 +- Remove patch since upstream does the right thing + +* Wed Dec 14 2005 Dan Walsh 1.5.3-1 +- Upgrade to latest from NSA + * Merged further header cleanups from Ivan Gyurdiev. + * Merged toggle modified flag in policydb_modify, fix memory leak + in clear_obsolete, polymorphism vs headers fix, and include guards + for internal headers patches from Ivan Gyurdiev. + +* Tue Dec 13 2005 Dan Walsh 1.5.1-2 +- Upgrade to latest from NSA + * Merged toggle modified flag in policydb_modify, fix memory leak + in clear_obsolete, polymorphism vs headers fix, and include guards + for internal headers patches from Ivan Gyurdiev. + +* Mon Dec 12 2005 Dan Walsh 1.5.1-1 +- Upgrade to latest from NSA + * Added file-mode= setting to semanage.conf, default to 0644. + Changed semanage_copy_file and callers to use this mode when + installing policy files to runtime locations. + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Wed Dec 7 2005 Dan Walsh 1.4-1 +- Fix mode of output seusers file + +* Tue Dec 6 2005 Dan Walsh 1.3.64-1 +- Upgrade to latest from NSA + * Changed semanage_handle_create() to set do_reload based on + is_selinux_enabled(). This prevents improper attempts to + load policy on a non-SELinux system. + +* Mon Dec 5 2005 Dan Walsh 1.3.63-1 +- Upgrade to latest from NSA + * Dropped handle from user_del_role interface. + * Removed defrole interfaces. + +* Tue Nov 29 2005 Dan Walsh 1.3.61-1 +- Upgrade to latest from NSA + * Merged Makefile python definitions patch from Dan Walsh. + * Removed is_selinux_mls_enabled() conditionals in seusers and users + file parsers. + +* Wed Nov 23 2005 Dan Walsh 1.3.59-1 +- Add additional swig objects + * Merged wrap char*** for user_get_roles patch from Joshua Brindle. + * Merged remove defrole from sepol patch from Ivan Gyurdiev. + * Merged swig wrappers for modifying users and seusers from Joshua Brindle. + +* Wed Nov 23 2005 Dan Walsh 1.3.56-2 +- Add additional swig objects + +* Wed Nov 16 2005 Dan Walsh 1.3.56-1 +- Upgrade to latest from NSA + * Fixed free->key_free bug. + * Merged clear obsolete patch from Ivan Gyurdiev. + * Merged modified swigify patch from Dan Walsh + (original patch from Joshua Brindle). + * Merged move genhomedircon call patch from Chad Sellers. + +* Mon Nov 14 2005 Dan Walsh 1.3.53-3 +- Add genhomedircon patch from Joshua Brindle + +* Fri Nov 11 2005 Dan Walsh 1.3.53-2 +- Add swigify patch from Joshua Brindle + +* Fri Nov 11 2005 Dan Walsh 1.3.53-1 +- Upgrade to latest from NSA + * Merged move seuser validation patch from Ivan Gyurdiev. + * Merged hidden declaration fixes from Ivan Gyurdiev, + with minor corrections. + +* Wed Nov 9 2005 Dan Walsh 1.3.52-1 +- Upgrade to latest from NSA + * Merged cleanup patch from Ivan Gyurdiev. + This renames semanage_module_conn to semanage_direct_handle, + and moves sepol handle create/destroy into semanage handle + create/destroy to allow use even when disconnected (for the + record interfaces). + +* Tue Nov 8 2005 Dan Walsh 1.3.51-1 +- Upgrade to latest from NSA + * Clear modules modified flag upon disconnect and commit. + * Added tracking of module modifications and use it to + determine whether expand-time checks should be applied + on commit. + * Reverted semanage_set_reload_bools() interface. + +* Tue Nov 8 2005 Dan Walsh 1.3.48-1 +- Upgrade to latest from NSA + * Disabled calls to port dbase for merge and commit and stubbed + out calls to sepol_port interfaces since they are not exported. + * Merged rename instead of copy patch from Joshua Brindle (Tresys). + * Added hidden_def/hidden_proto for exported symbols used within + libsemanage to eliminate relocations. Wrapped type definitions + in exported headers as needed to avoid conflicts. Added + src/context_internal.h and src/iface_internal.h. + * Added semanage_is_managed() interface to allow detection of whether + the policy is managed via libsemanage. This enables proper handling + in setsebool for non-managed systems. + * Merged semanage_set_reload_bools() interface from Ivan Gyurdiev, + to enable runtime control over preserving active boolean values + versus reloading their saved settings upon commit. + +* Mon Nov 7 2005 Dan Walsh 1.3.43-1 +- Upgrade to latest from NSA + * Merged seuser parser resync, dbase tracking and cleanup, strtol + bug, copyright, and assert space patches from Ivan Gyurdiev. + * Added src/*_internal.h in preparation for other changes. + * Added hidden/hidden_proto/hidden_def to src/debug.[hc] and + src/seusers.[hc]. + + +* Thu Nov 3 2005 Dan Walsh 1.3.41-1 +- Upgrade to latest from NSA + * Merged interface parse/print, context_to_string interface change, + move assert_noeof, and order preserving patches from Ivan Gyurdiev. + * Added src/dso.h in preparation for other changes. + * Merged install seusers, handle/error messages, MLS parsing, + and seusers validation patches from Ivan Gyurdiev. + +* Mon Oct 31 2005 Dan Walsh 1.3.39-1 +- Upgrade to latest from NSA + * Merged record interface, dbase flush, common database code, + and record bugfix patches from Ivan Gyurdiev. + +* Fri Oct 28 2005 Dan Walsh 1.3.38-1 +- Upgrade to latest from NSA + * Merged dbase policydb list and count change from Ivan Gyurdiev. + * Merged enable dbase and set relay patches from Ivan Gyurdiev. + +* Thu Oct 27 2005 Dan Walsh 1.3.36-1 +- Update from NSA + * Merged query APIs and dbase_file_set patches from Ivan Gyurdiev. + +* Wed Oct 26 2005 Dan Walsh 1.3.35-1 +- Update from NSA + * Merged sepol handle passing, seusers support, and policydb cache + patches from Ivan Gyurdiev. + +* Tue Oct 25 2005 Dan Walsh 1.3.34-1 +- Update from NSA + * Merged resync to sepol changes and booleans fixes/improvements + patches from Ivan Gyurdiev. + * Merged support for genhomedircon/homedir template, store selection, + explicit policy reload, and semanage.conf relocation from Joshua + Brindle. + +* Mon Oct 24 2005 Dan Walsh 1.3.32-1 +- Update from NSA + * Merged resync to sepol changes and transaction fix patches from + Ivan Gyurdiev. + * Merged reorganize users patch from Ivan Gyurdiev. + * Merged remove unused relay functions patch from Ivan Gyurdiev. + +* Fri Oct 21 2005 Dan Walsh 1.3.30-1 +- Update from NSA + * Fixed policy file leaks in semanage_load_module and + semanage_write_module. + * Merged further database work from Ivan Gyurdiev. + * Fixed bug in semanage_direct_disconnect. + +* Thu Oct 20 2005 Dan Walsh 1.3.28-1 +- Update from NSA + * Merged interface renaming patch from Ivan Gyurdiev. + * Merged policy component patch from Ivan Gyurdiev. + * Renamed 'check=' configuration value to 'expand-check=' for + clarity. + * Changed semanage_commit_sandbox to check for and report errors + on rename(2) calls performed during rollback. + * Added optional check= configuration value to semanage.conf + and updated call to sepol_expand_module to pass its value + to control assertion and hierarchy checking on module expansion. + * Merged fixes for make DESTDIR= builds from Joshua Brindle. + +* Tue Oct 18 2005 Dan Walsh 1.3.24-1 +- Update from NSA + * Merged default database from Ivan Gyurdiev. + * Merged removal of connect requirement in policydb backend from + Ivan Gyurdiev. + * Merged commit locking fix and lock rename from Joshua Brindle. + * Merged transaction rollback in lock patch from Joshua Brindle. + * Changed default args for load_policy to be null, as it no longer + takes a pathname argument and we want to preserve booleans. + * Merged move local dbase initialization patch from Ivan Gyurdiev. + * Merged acquire/release read lock in databases patch from Ivan Gyurdiev. + * Merged rename direct -> policydb as appropriate patch from Ivan Gyurdiev. + * Added calls to sepol_policy_file_set_handle interface prior + to invoking sepol operations on policy files. + * Updated call to sepol_policydb_from_image to pass the handle. + + +* Tue Oct 18 2005 Dan Walsh 1.3.20-1 +- Update from NSA + * Changed default args for load_policy to be null, as it no longer + takes a pathname argument and we want to preserve booleans. + * Merged move local dbase initialization patch from Ivan Gyurdiev. + * Merged acquire/release read lock in databases patch from Ivan Gyurdiev. + * Merged rename direct -> policydb as appropriate patch from Ivan Gyurdiev. + * Added calls to sepol_policy_file_set_handle interface prior + to invoking sepol operations on policy files. + * Updated call to sepol_policydb_from_image to pass the handle. + +* Tue Oct 18 2005 Dan Walsh 1.3.20-1 +- Update from NSA + * Merged user and port APIs - policy database patch from Ivan + Gyurdiev. + * Converted calls to sepol link_packages and expand_module interfaces + from using buffers to using sepol handles for error reporting, and + changed direct_connect/disconnect to create/destroy sepol handles. + +* Sat Oct 15 2005 Dan Walsh 1.3.18-1 +- Update from NSA + * Merged bugfix patch from Ivan Gyurdiev. + * Merged seuser database patch from Ivan Gyurdiev. + Merged direct user/port databases to the handle from Ivan Gyurdiev. + * Removed obsolete include/semanage/commit_api.h (leftover). + Merged seuser record patch from Ivan Gyurdiev. + * Merged boolean and interface databases from Ivan Gyurdiev. + +* Fri Oct 14 2005 Dan Walsh 1.3.14-1 +- Update from NSA + * Updated to use get interfaces for hidden sepol_module_package type. + * Changed semanage_expand_sandbox and semanage_install_active + to generate/install the latest policy version supported by libsepol + by default (unless overridden by semanage.conf), since libselinux + will now downgrade automatically for load_policy. + * Merged new callback-based error reporting system and ongoing + database work from Ivan Gyurdiev. + +* Wed Oct 12 2005 Dan Walsh 1.3.11-1 +- Update from NSA + * Fixed semanage_install_active() to use the same logic for + selecting a policy version as semanage_expand_sandbox(). Dropped + dead code from semanage_install_sandbox(). + +* Mon Oct 10 2005 Dan Walsh 1.3.10-1 +- Update from NSA + * Updated for changes to libsepol, and to only use types and interfaces + provided by the shared libsepol. + +* Fri Oct 7 2005 Dan Walsh 1.3.9-1 +- Update from NSA + * Merged further database work from Ivan Gyurdiev. + +* Tue Oct 4 2005 Dan Walsh 1.3.8-1 +- Update from NSA + * Merged iterate, redistribute, and dbase split patches from + Ivan Gyurdiev. + +* Mon Oct 3 2005 Dan Walsh 1.3.7-1 +- Update from NSA + * Merged patch series from Ivan Gyurdiev. + (pointer typedef elimination, file renames, dbase work, backend + separation) + * Split interfaces from semanage.[hc] into handle.[hc], modules.[hc]. + * Separated handle create from connect interface. + * Added a constructor for initialization. + * Moved up src/include/*.h to src. + * Created a symbol map file; dropped dso.h and hidden markings. + +* Wed Sep 28 2005 Dan Walsh 1.3.5-1 +- Update from NSA + * Split interfaces from semanage.[hc] into handle.[hc], modules.[hc]. + * Separated handle create from connect interface. + * Added a constructor for initialization. + * Moved up src/include/*.h to src. + * Created a symbol map file; dropped dso.h and hidden markings. + +* Fri Sep 23 2005 Dan Walsh 1.3.4-1 +- Update from NSA + * Merged dbase redesign patch from Ivan Gyurdiev. + +* Wed Sep 21 2005 Dan Walsh 1.3.3-1 +- Update from NSA + * Merged boolean record, stub record handler, and status codes + patches from Ivan Gyurdiev. + +* Tue Sep 20 2005 Dan Walsh 1.3.2-1 +- Update from NSA + * Merged stub iterator functionality from Ivan Gyurdiev. + * Merged interface record patch from Ivan Gyurdiev. + +* Wed Sep 14 2005 Dan Walsh 1.3.1-1 +- Update from NSA + * Merged stub functionality for managing user and port records, + and record table code from Ivan Gyurdiev. + * Updated version for release. + +* Thu Sep 1 2005 Dan Walsh 1.1.6-1 +- Update from NSA + * Merged semod.conf template patch from Dan Walsh (Red Hat), + but restored location to /usr/share/semod/semod.conf. + * Fixed several bugs found by valgrind. + * Fixed bug in prior patch for the semod_build_module_list leak. + * Merged errno fix from Joshua Brindle (Tresys). + * Merged fix for semod_build_modules_list leak on error path + from Serge Hallyn (IBM). Bug found by Coverity. + +* Thu Aug 25 2005 Dan Walsh 1.1.3-1 +- Update from NSA + * Merged errno fix from Joshua Brindle (Tresys). + * Merged fix for semod_build_modules_list leak on error path + from Serge Hallyn (IBM). Bug found by Coverity. + * Merged several fixes from Serge Hallyn (IBM). Bugs found by + Coverity. + * Fixed several other bugs and warnings. + * Merged patch to move module read/write code from libsemanage + to libsepol from Jason Tang (Tresys). + * Merged relay records patch from Ivan Gyurdiev. + * Merged key extract patch from Ivan Gyurdiev. + +- Initial version +- Created by Stephen Smalley