From 29add823913b66e0637d27d962ad5c5f9c85de70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Mon, 28 Jan 2019 12:13:54 +0100 Subject: [PATCH] lib: make selinux functions work with selinux disabled Resolves: https://github.com/pbrezina/authselect/issues/133 --- src/lib/util/file.c | 38 +++++++++++++++++++++++++++++++++ src/lib/util/file.h | 13 +++++++++++- src/lib/util/selinux.c | 47 ++++++++++++++++------------------------- src/lib/util/selinux.h | 8 ++++--- src/lib/util/template.c | 23 ++++++-------------- 5 files changed, 79 insertions(+), 50 deletions(-) diff --git a/src/lib/util/file.c b/src/lib/util/file.c index fa231f771a7d0cdd449b69c4bf7b00d93aefc375..2e23ce39ec04e6aaf79f16410f9ac08dc3f9d54c 100644 --- a/src/lib/util/file.c +++ b/src/lib/util/file.c @@ -329,3 +329,41 @@ file_make_path(const char *path, mode_t mode) return EOK; } + +errno_t +file_mktmp_for(const char *path, mode_t mode, char **_tmpfile) +{ + mode_t oldmask; + char *tmpfile; + errno_t ret; + int fd; + + oldmask = umask(mode); + + tmpfile = format("%s.XXXXXX", path); + if (tmpfile == NULL) { + ret = ENOMEM; + goto done; + } + + fd = mkstemp(tmpfile); + if (fd == -1) { + ret = errno; + goto done; + } + + close(fd); + + *_tmpfile = tmpfile; + + ret = EOK; + +done: + if (ret != EOK) { + free(tmpfile); + } + + umask(oldmask); + + return ret; +} diff --git a/src/lib/util/file.h b/src/lib/util/file.h index 49ebef37443bf137439bad27fd75283c25c9c3e5..6d5823791bfcc581304200d0c2d37b41c3d7b95d 100644 --- a/src/lib/util/file.h +++ b/src/lib/util/file.h @@ -133,7 +133,7 @@ file_get_parent_directory(const char *filepath); /** * Create all directories in a path. Path must end with a directory not a file. * - * @param filename Path to the file whose directories should be created. + * @param path Path to the file whose directories should be created. * @param mode Directory mode. * * @return EOK on success, other errno code on error. @@ -141,4 +141,15 @@ file_get_parent_directory(const char *filepath); errno_t file_make_path(const char *path, mode_t mode); +/** + * Make temporary file for @path so it can be first written and then safelly + * renamed to @path. + * + * @param path Path to the file whose directories should be created. + * @param mode Temporary file mode. + * @param _tmpfile Path to created temporary file. + */ +errno_t +file_mktmp_for(const char *path, mode_t mode, char **_tmpfile); + #endif /* _FILE_H_ */ diff --git a/src/lib/util/selinux.c b/src/lib/util/selinux.c index 9b0e0ff26b768d88f67a42985c5d5bafb8aa58ec..01b68087b265c0ef1c1087f626df8e20de086338 100644 --- a/src/lib/util/selinux.c +++ b/src/lib/util/selinux.c @@ -26,6 +26,7 @@ #include #include "common/common.h" +#include "lib/util/file.h" errno_t selinux_get_default_context(const char *path, @@ -61,15 +62,19 @@ selinux_get_default_context(const char *path, } errno_t -selinux_mkstemp_of(const char *filepath, - char **_tmpfile) +selinux_mkstemp_for(const char *filepath, + mode_t mode, + char **_tmpfile) { char *original_context = NULL; char *default_context = NULL; - char *tmpfile = NULL; + char *tmpfile; errno_t ret; int seret; - int fd; + + if (is_selinux_enabled() != 1) { + return file_mktmp_for(filepath, mode, _tmpfile); + } seret = getfscreatecon(&original_context); if (seret != 0) { @@ -77,12 +82,6 @@ selinux_mkstemp_of(const char *filepath, return EIO; } - tmpfile = format("%s.XXXXXX", filepath); - if (tmpfile == NULL) { - ret = ENOMEM; - goto done; - } - ret = selinux_get_default_context(filepath, &default_context); if (ret == ENOENT) { default_context = NULL; @@ -92,6 +91,7 @@ selinux_mkstemp_of(const char *filepath, goto done; } + /* Set desired fs create context. */ seret = setfscreatecon(default_context); if (seret != 0) { ERROR("Unable to set fscreate selinux context!"); @@ -99,22 +99,9 @@ selinux_mkstemp_of(const char *filepath, goto done; } - fd = mkstemp(tmpfile); - if (fd == -1) { - ret = errno; - - seret = setfscreatecon(original_context); - if (seret != 0) { - ERROR("Unable to restore fscreate selinux context!"); - ret = EIO; - goto done; - } - - goto done; - } - - close(fd); + ret = file_mktmp_for(filepath, mode, &tmpfile); + /* Restore original fs create context. */ seret = setfscreatecon(original_context); if (seret != 0) { ERROR("Unable to restore fscreate selinux context!"); @@ -122,6 +109,12 @@ selinux_mkstemp_of(const char *filepath, goto done; } + /* Check result of file_mktmp_for() */ + if (ret != EOK) { + free(tmpfile); + goto done; + } + *_tmpfile = tmpfile; ret = EOK; @@ -135,9 +128,5 @@ done: freecon(default_context); } - if (ret != EOK) { - free(tmpfile); - } - return ret; } diff --git a/src/lib/util/selinux.h b/src/lib/util/selinux.h index 26f2374140562dd085145845ed3092a0ddcf924e..8abfb3fb5d244b32570cc9e573b2e12df14177e1 100644 --- a/src/lib/util/selinux.h +++ b/src/lib/util/selinux.h @@ -39,12 +39,14 @@ selinux_get_default_context(const char *path); * set to default security context of @filepath. * * @param filepath File for which a temporary file should be created. - * @param _tmpfile Create temporary file. + * @param mode Temporary file mode. + * @param _tmpfile Created temporary file. * * @return EOK on success, other errno code on failure. */ errno_t -selinux_mkstemp_of(const char *filepath, - char **_tmpfile); +selinux_mkstemp_for(const char *filepath, + mode_t mode, + char **_tmpfile); #endif /* _SELINUX_H_ */ diff --git a/src/lib/util/template.c b/src/lib/util/template.c index 9773dcbf1ecbde4fe2408f1b816dce129747806f..1f3464912d8fe7afe8a7f0920fe31eb5c2dfaba5 100644 --- a/src/lib/util/template.c +++ b/src/lib/util/template.c @@ -592,36 +592,25 @@ template_write_temporary(const char *filepath, mode_t mode, char **_tmpfile) { - mode_t oldmask; char *tmpfile; errno_t ret; - oldmask = umask(mode); - - ret = selinux_mkstemp_of(filepath, &tmpfile); + ret = selinux_mkstemp_for(filepath, mode, &tmpfile); if (ret != EOK) { ERROR("Unable to create temporary file for [%s] [%d]: %s", filepath, ret, strerror(ret)); - goto done; + return ret; } ret = template_write(tmpfile, content, mode); - if (ret != EOK) { - goto done; - } - - *_tmpfile = tmpfile; - - ret = EOK; - -done: - umask(oldmask); - if (ret != EOK) { free(tmpfile); + return ret; } - return ret; + *_tmpfile = tmpfile; + + return EOK; } bool -- 2.17.2