authselect/SOURCES/0037-lib-make-selinux-funct...

268 lines
7.1 KiB
Diff

From 29add823913b66e0637d27d962ad5c5f9c85de70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
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 <selinux/label.h>
#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