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)