Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
lib: label temporary files with correct selinux context
  • Loading branch information
pbrezina committed Jan 11, 2019
1 parent 42e1686 commit 9451dd5
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 11 deletions.
1 change: 1 addition & 0 deletions configure.ac
Expand Up @@ -37,6 +37,7 @@ m4_include(external/po4a.m4)
dnl Required libraries
REQUIRE_POPT
REQUIRE_CMOCKA
REQUIRE_SELINUX

dnl Optional build dependencies - man pages generation
CHECK_ASCIIDOC_TOOLS
Expand Down
1 change: 1 addition & 0 deletions rpm/authselect.spec.in
Expand Up @@ -24,6 +24,7 @@ BuildRequires: gettext-devel
BuildRequires: po4a
BuildRequires: %{_bindir}/a2x
BuildRequires: libcmocka-devel >= 1.0.0
BuildRequires: libselinux-devel
Requires: authselect-libs%{?_isa} = %{version}-%{release}
Suggests: sssd
Suggests: samba-winbind
Expand Down
13 changes: 13 additions & 0 deletions src/build_macros.m4
Expand Up @@ -28,3 +28,16 @@ AC_DEFUN([REQUIRE_CMOCKA],
)
AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
])

AC_DEFUN([REQUIRE_SELINUX],
[
AC_CHECK_HEADERS(selinux/selinux.h,
[AC_CHECK_LIB(selinux, is_selinux_enabled,
[SELINUX_LIBS="-lselinux"],
[AC_MSG_ERROR([SELinux library is missing])]
)],
[AC_MSG_ERROR([SELinux headers are missing])]
)
AC_SUBST(SELINUX_LIBS)
])

3 changes: 3 additions & 0 deletions src/lib/Makefile.am
Expand Up @@ -15,6 +15,7 @@ noinst_HEADERS = \
files/files.h \
profiles/profiles.h \
util/file.h \
util/selinux.h \
util/string_array.h \
util/string.h \
util/template.h \
Expand Down Expand Up @@ -55,13 +56,15 @@ libauthselect_la_SOURCES = \
profiles/list.c \
profiles/read.c \
util/file.c \
util/selinux.c \
util/string_array.c \
util/string.c \
util/template.c \
util/textfile.c \
$(NULL)
libauthselect_la_LIBADD = \
$(top_builddir)/src/common/libcommon.la \
$(SELINUX_LIBS) \
$(NULL)
libauthselect_la_CFLAGS = \
$(AM_CFLAGS) \
Expand Down
143 changes: 143 additions & 0 deletions src/lib/util/selinux.c
@@ -0,0 +1,143 @@
/*
Authors:
Pavel Březina <pbrezina@redhat.com>
Copyright (C) 2018 Red Hat
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <selinux/selinux.h>
#include <selinux/label.h>

#include "common/common.h"

errno_t
selinux_get_default_context(const char *path,
char **_context)
{
struct selabel_handle *handle;
char *context;
errno_t ret;

handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
if (handle == NULL) {
ret = errno;
ERROR("Unable to create selable context [%d]: %s", ret, strerror(ret));
return ret;
}

ret = selabel_lookup(handle, &context, path, 0);
if (ret != 0) {
ret = errno;
if (ret == ENOENT) {
return ENOENT;
}

ERROR("Unable to lookup selinux context [%d]: %s", ret, strerror(ret));
} else {
*_context = context;
ret = EOK;
}

selabel_close(handle);

return ret;
}

errno_t
selinux_mkstemp_of(const char *filepath,
char **_tmpfile)
{
char *original_context = NULL;
char *default_context = NULL;
char *tmpfile = NULL;
errno_t ret;
int seret;
int fd;

seret = getfscreatecon(&original_context);
if (seret != 0) {
ERROR("Unable to get current fscreate selinux context!");
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;
} else if (ret != EOK) {
ERROR("Unable to get default selinux context for [%s] [%d]: %s!",
filepath, ret, strerror(ret));
goto done;
}

seret = setfscreatecon(default_context);
if (seret != 0) {
ERROR("Unable to set fscreate selinux context!");
ret = EIO;
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);

seret = setfscreatecon(original_context);
if (seret != 0) {
ERROR("Unable to restore fscreate selinux context!");
ret = EIO;
goto done;
}

*_tmpfile = tmpfile;

ret = EOK;

done:
if (original_context != NULL) {
freecon(original_context);
}

if (default_context != NULL) {
freecon(default_context);
}

if (ret != EOK) {
free(tmpfile);
}

return ret;
}
50 changes: 50 additions & 0 deletions src/lib/util/selinux.h
@@ -0,0 +1,50 @@
/*
Authors:
Pavel Březina <pbrezina@redhat.com>
Copyright (C) 2018 Red Hat
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _SELINUX_H_
#define _SELINUX_H_

#include "common/errno_t.h"

/**
* Get default security context for @path.
*
* @param path Path to the file.
*
* @return EOK on success, ENOENT if context was not found, other errno code
* is returned on failure.
*/
errno_t
selinux_get_default_context(const char *path);

/**
* Create temporary file created on @filepath.XXXXXX with security context
* set to default security context of @filepath.
*
* @param filepath File for which a temporary file should be created.
* @param _tmpfile Create temporary file.
*
* @return EOK on success, other errno code on failure.
*/
errno_t
selinux_mkstemp_of(const char *filepath,
char **_tmpfile);

#endif /* _SELINUX_H_ */
16 changes: 5 additions & 11 deletions src/lib/util/template.c
Expand Up @@ -27,6 +27,7 @@
#include "common/common.h"
#include "lib/util/template.h"
#include "lib/util/textfile.h"
#include "lib/util/selinux.h"
#include "lib/util/string.h"
#include "lib/util/string_array.h"

Expand Down Expand Up @@ -594,23 +595,16 @@ template_write_temporary(const char *filepath,
mode_t oldmask;
char *tmpfile;
errno_t ret;
int fd;

tmpfile = format("%s.XXXXXX", filepath);
if (tmpfile == NULL) {
return ENOMEM;
}

oldmask = umask(mode);

fd = mkstemp(tmpfile);;
if (fd == -1) {
ret = errno;
ret = selinux_mkstemp_of(filepath, &tmpfile);
if (ret != EOK) {
ERROR("Unable to create temporary file for [%s] [%d]: %s",
filepath, ret, strerror(ret));
goto done;
}

close(fd);

ret = template_write(tmpfile, content, mode);
if (ret != EOK) {
goto done;
Expand Down
1 change: 1 addition & 0 deletions src/lib/util/util.h
Expand Up @@ -29,6 +29,7 @@

#include "common/common.h"
#include "lib/util/file.h"
#include "lib/util/selinux.h"
#include "lib/util/string.h"
#include "lib/util/string_array.h"
#include "lib/util/template.h"
Expand Down

0 comments on commit 9451dd5

Please sign in to comment.