|
|
10fa70 |
From 791fe183bf67dcab6d044b23d8daaf4a3a96be48 Mon Sep 17 00:00:00 2001
|
|
|
afd354 |
From: Robbie Harwood <rharwood@redhat.com>
|
|
|
afd354 |
Date: Tue, 23 Aug 2016 16:30:53 -0400
|
|
|
10fa70 |
Subject: [PATCH] [downstream] SELinux integration
|
|
|
afd354 |
|
|
|
afd354 |
SELinux bases access to files on the domain of the requesting process,
|
|
|
afd354 |
the operation being performed, and the context applied to the file.
|
|
|
afd354 |
|
|
|
afd354 |
In many cases, applications needn't be SELinux aware to work properly,
|
|
|
afd354 |
because SELinux can apply a default label to a file based on the label
|
|
|
afd354 |
of the directory in which it's created.
|
|
|
afd354 |
|
|
|
afd354 |
In the case of files such as /etc/krb5.keytab, however, this isn't
|
|
|
afd354 |
sufficient, as /etc/krb5.keytab will almost always need to be given a
|
|
|
afd354 |
label which differs from that of /etc/issue or /etc/resolv.conf. The
|
|
|
afd354 |
the kdb stash file needs a different label than the database for which
|
|
|
afd354 |
it's holding a master key, even though both typically live in the same
|
|
|
afd354 |
directory.
|
|
|
afd354 |
|
|
|
afd354 |
To give the file the correct label, we can either force a "restorecon"
|
|
|
afd354 |
call to fix a file's label after it's created, or create the file with
|
|
|
afd354 |
the right label, as we attempt to do here. We lean on THREEPARAMOPEN
|
|
|
afd354 |
and define a similar macro named WRITABLEFOPEN with which we replace
|
|
|
afd354 |
several uses of fopen().
|
|
|
afd354 |
|
|
|
afd354 |
The file creation context that we're manipulating here is a process-wide
|
|
|
afd354 |
attribute. While for the most part, applications which need to label
|
|
|
afd354 |
files when they're created have tended to be single-threaded, there's
|
|
|
afd354 |
not much we can do to avoid interfering with an application that
|
|
|
afd354 |
manipulates the creation context directly. Right now we're mediating
|
|
|
afd354 |
access using a library-local mutex, but that can only work for consumers
|
|
|
afd354 |
that are part of this package -- an unsuspecting application will still
|
|
|
afd354 |
stomp all over us.
|
|
|
afd354 |
|
|
|
afd354 |
The selabel APIs for looking up the context should be thread-safe (per
|
|
|
afd354 |
Red Hat #273081), so switching to using them instead of matchpathcon(),
|
|
|
afd354 |
which we used earlier, is some improvement.
|
|
|
10fa70 |
|
|
|
10fa70 |
Last-updated: krb5-1.18-beta1
|
|
|
10fa70 |
(cherry picked from commit 0f8851a23a7b6fa0e195e01d0475e9e55707adf2)
|
|
|
afd354 |
---
|
|
|
10fa70 |
src/aclocal.m4 | 48 +++
|
|
|
afd354 |
src/build-tools/krb5-config.in | 3 +-
|
|
|
afd354 |
src/config/pre.in | 3 +-
|
|
|
10fa70 |
src/configure.ac | 2 +
|
|
|
afd354 |
src/include/k5-int.h | 1 +
|
|
|
afd354 |
src/include/k5-label.h | 32 ++
|
|
|
afd354 |
src/include/krb5/krb5.hin | 6 +
|
|
|
afd354 |
src/kadmin/dbutil/dump.c | 11 +-
|
|
|
afd354 |
src/kdc/main.c | 2 +-
|
|
|
afd354 |
src/kprop/kpropd.c | 9 +
|
|
|
afd354 |
src/lib/kadm5/logger.c | 4 +-
|
|
|
afd354 |
src/lib/kdb/kdb_log.c | 2 +-
|
|
|
afd354 |
src/lib/krb5/ccache/cc_dir.c | 26 +-
|
|
|
afd354 |
src/lib/krb5/keytab/kt_file.c | 4 +-
|
|
|
afd354 |
src/lib/krb5/os/trace.c | 2 +-
|
|
|
afd354 |
src/plugins/kdb/db2/adb_openclose.c | 2 +-
|
|
|
afd354 |
src/plugins/kdb/db2/kdb_db2.c | 4 +-
|
|
|
afd354 |
src/plugins/kdb/db2/libdb2/btree/bt_open.c | 3 +-
|
|
|
afd354 |
src/plugins/kdb/db2/libdb2/hash/hash.c | 3 +-
|
|
|
afd354 |
src/plugins/kdb/db2/libdb2/recno/rec_open.c | 4 +-
|
|
|
afd354 |
.../kdb/ldap/ldap_util/kdb5_ldap_services.c | 11 +-
|
|
|
afd354 |
src/util/profile/prof_file.c | 3 +-
|
|
|
afd354 |
src/util/support/Makefile.in | 3 +-
|
|
|
afd354 |
src/util/support/selinux.c | 406 ++++++++++++++++++
|
|
|
10fa70 |
24 files changed, 573 insertions(+), 21 deletions(-)
|
|
|
afd354 |
create mode 100644 src/include/k5-label.h
|
|
|
afd354 |
create mode 100644 src/util/support/selinux.c
|
|
|
afd354 |
|
|
|
afd354 |
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
|
|
10fa70 |
index 830203683..6796fec53 100644
|
|
|
afd354 |
--- a/src/aclocal.m4
|
|
|
afd354 |
+++ b/src/aclocal.m4
|
|
|
afd354 |
@@ -89,6 +89,7 @@ AC_SUBST_FILE(libnodeps_frag)
|
|
|
afd354 |
dnl
|
|
|
afd354 |
KRB5_AC_PRAGMA_WEAK_REF
|
|
|
afd354 |
WITH_LDAP
|
|
|
afd354 |
+KRB5_WITH_SELINUX
|
|
|
afd354 |
KRB5_LIB_PARAMS
|
|
|
afd354 |
KRB5_AC_INITFINI
|
|
|
afd354 |
KRB5_AC_ENABLE_THREADS
|
|
|
10fa70 |
@@ -1743,4 +1744,51 @@ AC_SUBST(PAM_LIBS)
|
|
|
afd354 |
AC_SUBST(PAM_MAN)
|
|
|
afd354 |
AC_SUBST(NON_PAM_MAN)
|
|
|
afd354 |
])dnl
|
|
|
afd354 |
+dnl
|
|
|
afd354 |
+dnl Use libselinux to set file contexts on newly-created files.
|
|
|
afd354 |
+dnl
|
|
|
afd354 |
+AC_DEFUN(KRB5_WITH_SELINUX,[
|
|
|
afd354 |
+AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])],
|
|
|
afd354 |
+ withselinux="$withval",withselinux=auto)
|
|
|
afd354 |
+old_LIBS="$LIBS"
|
|
|
afd354 |
+if test "$withselinux" != no ; then
|
|
|
afd354 |
+ AC_MSG_RESULT([checking for libselinux...])
|
|
|
afd354 |
+ SELINUX_LIBS=
|
|
|
afd354 |
+ AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h)
|
|
|
afd354 |
+ if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then
|
|
|
afd354 |
+ if test "$withselinux" = auto ; then
|
|
|
afd354 |
+ AC_MSG_RESULT([Unable to locate selinux/selinux.h.])
|
|
|
afd354 |
+ withselinux=no
|
|
|
afd354 |
+ else
|
|
|
afd354 |
+ AC_MSG_ERROR([Unable to locate selinux/selinux.h.])
|
|
|
afd354 |
+ fi
|
|
|
afd354 |
+ fi
|
|
|
10fa70 |
|
|
|
afd354 |
+ LIBS=
|
|
|
afd354 |
+ unset ac_cv_func_setfscreatecon
|
|
|
afd354 |
+ AC_CHECK_FUNCS(setfscreatecon selabel_open)
|
|
|
afd354 |
+ if test "x$ac_cv_func_setfscreatecon" = xno ; then
|
|
|
afd354 |
+ AC_CHECK_LIB(selinux,setfscreatecon)
|
|
|
afd354 |
+ unset ac_cv_func_setfscreatecon
|
|
|
afd354 |
+ AC_CHECK_FUNCS(setfscreatecon selabel_open)
|
|
|
afd354 |
+ if test "x$ac_cv_func_setfscreatecon" = xyes ; then
|
|
|
afd354 |
+ SELINUX_LIBS="$LIBS"
|
|
|
afd354 |
+ else
|
|
|
afd354 |
+ if test "$withselinux" = auto ; then
|
|
|
afd354 |
+ AC_MSG_RESULT([Unable to locate libselinux.])
|
|
|
afd354 |
+ withselinux=no
|
|
|
afd354 |
+ else
|
|
|
afd354 |
+ AC_MSG_ERROR([Unable to locate libselinux.])
|
|
|
afd354 |
+ fi
|
|
|
afd354 |
+ fi
|
|
|
afd354 |
+ fi
|
|
|
afd354 |
+ if test "$withselinux" != no ; then
|
|
|
afd354 |
+ AC_MSG_NOTICE([building with SELinux labeling support])
|
|
|
afd354 |
+ AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.])
|
|
|
afd354 |
+ SELINUX_LIBS="$LIBS"
|
|
|
afd354 |
+ EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon"
|
|
|
afd354 |
+ fi
|
|
|
afd354 |
+fi
|
|
|
afd354 |
+LIBS="$old_LIBS"
|
|
|
afd354 |
+AC_SUBST(SELINUX_LIBS)
|
|
|
afd354 |
+])dnl
|
|
|
afd354 |
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
|
|
|
afd354 |
index f6184da3f..c17cb5eb5 100755
|
|
|
afd354 |
--- a/src/build-tools/krb5-config.in
|
|
|
afd354 |
+++ b/src/build-tools/krb5-config.in
|
|
|
afd354 |
@@ -41,6 +41,7 @@ DL_LIB='@DL_LIB@'
|
|
|
afd354 |
DEFCCNAME='@DEFCCNAME@'
|
|
|
afd354 |
DEFKTNAME='@DEFKTNAME@'
|
|
|
afd354 |
DEFCKTNAME='@DEFCKTNAME@'
|
|
|
afd354 |
+SELINUX_LIBS='@SELINUX_LIBS@'
|
|
|
afd354 |
|
|
|
afd354 |
LIBS='@LIBS@'
|
|
|
afd354 |
GEN_LIB=@GEN_LIB@
|
|
|
afd354 |
@@ -255,7 +256,7 @@ if test -n "$do_libs"; then
|
|
|
afd354 |
fi
|
|
|
afd354 |
|
|
|
afd354 |
# If we ever support a flag to generate output suitable for static
|
|
|
afd354 |
- # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB"
|
|
|
afd354 |
+ # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB"
|
|
|
afd354 |
# here.
|
|
|
afd354 |
|
|
|
afd354 |
echo $lib_flags
|
|
|
afd354 |
diff --git a/src/config/pre.in b/src/config/pre.in
|
|
|
afd354 |
index ce87e21ca..917357df9 100644
|
|
|
afd354 |
--- a/src/config/pre.in
|
|
|
afd354 |
+++ b/src/config/pre.in
|
|
|
afd354 |
@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
|
|
|
afd354 |
KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include
|
|
|
afd354 |
LDFLAGS = @LDFLAGS@
|
|
|
afd354 |
LIBS = @LIBS@
|
|
|
afd354 |
+SELINUX_LIBS=@SELINUX_LIBS@
|
|
|
afd354 |
|
|
|
afd354 |
INSTALL=@INSTALL@
|
|
|
afd354 |
INSTALL_STRIP=
|
|
|
afd354 |
@@ -402,7 +403,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
|
|
|
afd354 |
# HESIOD_LIBS is -lhesiod...
|
|
|
afd354 |
HESIOD_LIBS = @HESIOD_LIBS@
|
|
|
afd354 |
|
|
|
afd354 |
-KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB)
|
|
|
afd354 |
+KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
|
|
|
afd354 |
KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS)
|
|
|
afd354 |
GSS_LIBS = $(GSS_KRB5_LIB)
|
|
|
afd354 |
# needs fixing if ever used on macOS!
|
|
|
10fa70 |
diff --git a/src/configure.ac b/src/configure.ac
|
|
|
10fa70 |
index d1f576124..440a22bd9 100644
|
|
|
10fa70 |
--- a/src/configure.ac
|
|
|
10fa70 |
+++ b/src/configure.ac
|
|
|
10fa70 |
@@ -1392,6 +1392,8 @@ AC_PATH_PROG(GROFF, groff)
|
|
|
afd354 |
|
|
|
afd354 |
KRB5_WITH_PAM
|
|
|
afd354 |
|
|
|
afd354 |
+KRB5_WITH_SELINUX
|
|
|
afd354 |
+
|
|
|
afd354 |
# Make localedir work in autoconf 2.5x.
|
|
|
afd354 |
if test "${localedir+set}" != set; then
|
|
|
afd354 |
localedir='$(datadir)/locale'
|
|
|
afd354 |
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
|
|
10fa70 |
index 9616b24bf..0d9af3d95 100644
|
|
|
afd354 |
--- a/src/include/k5-int.h
|
|
|
afd354 |
+++ b/src/include/k5-int.h
|
|
|
afd354 |
@@ -128,6 +128,7 @@ typedef unsigned char u_char;
|
|
|
afd354 |
|
|
|
afd354 |
|
|
|
afd354 |
#include "k5-platform.h"
|
|
|
afd354 |
+#include "k5-label.h"
|
|
|
afd354 |
|
|
|
afd354 |
#define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */
|
|
|
afd354 |
#define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */
|
|
|
afd354 |
diff --git a/src/include/k5-label.h b/src/include/k5-label.h
|
|
|
afd354 |
new file mode 100644
|
|
|
afd354 |
index 000000000..dfaaa847c
|
|
|
afd354 |
--- /dev/null
|
|
|
afd354 |
+++ b/src/include/k5-label.h
|
|
|
afd354 |
@@ -0,0 +1,32 @@
|
|
|
afd354 |
+#ifndef _KRB5_LABEL_H
|
|
|
afd354 |
+#define _KRB5_LABEL_H
|
|
|
afd354 |
+
|
|
|
afd354 |
+#ifdef THREEPARAMOPEN
|
|
|
afd354 |
+#undef THREEPARAMOPEN
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+#ifdef WRITABLEFOPEN
|
|
|
afd354 |
+#undef WRITABLEFOPEN
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+
|
|
|
afd354 |
+/* Wrapper functions which help us create files and directories with the right
|
|
|
afd354 |
+ * context labels. */
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+#include <sys/types.h>
|
|
|
afd354 |
+#include <sys/stat.h>
|
|
|
afd354 |
+#include <fcntl.h>
|
|
|
afd354 |
+#include <stdio.h>
|
|
|
afd354 |
+#include <unistd.h>
|
|
|
afd354 |
+FILE *krb5int_labeled_fopen(const char *path, const char *mode);
|
|
|
afd354 |
+int krb5int_labeled_creat(const char *path, mode_t mode);
|
|
|
afd354 |
+int krb5int_labeled_open(const char *path, int flags, ...);
|
|
|
afd354 |
+int krb5int_labeled_mkdir(const char *path, mode_t mode);
|
|
|
afd354 |
+int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device);
|
|
|
afd354 |
+#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z)
|
|
|
afd354 |
+#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y)
|
|
|
afd354 |
+void *krb5int_push_fscreatecon_for(const char *pathname);
|
|
|
afd354 |
+void krb5int_pop_fscreatecon(void *previous);
|
|
|
afd354 |
+#else
|
|
|
afd354 |
+#define WRITABLEFOPEN(x,y) fopen(x,y)
|
|
|
afd354 |
+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
|
|
10fa70 |
index 79761f6d2..e9435c693 100644
|
|
|
afd354 |
--- a/src/include/krb5/krb5.hin
|
|
|
afd354 |
+++ b/src/include/krb5/krb5.hin
|
|
|
afd354 |
@@ -87,6 +87,12 @@
|
|
|
afd354 |
#define THREEPARAMOPEN(x,y,z) open(x,y,z)
|
|
|
afd354 |
#endif
|
|
|
afd354 |
|
|
|
afd354 |
+#if KRB5_PRIVATE
|
|
|
afd354 |
+#ifndef WRITABLEFOPEN
|
|
|
afd354 |
+#define WRITABLEFOPEN(x,y) fopen(x,y)
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+
|
|
|
afd354 |
#define KRB5_OLD_CRYPTO
|
|
|
afd354 |
|
|
|
afd354 |
#include <stdlib.h>
|
|
|
afd354 |
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
|
|
|
10fa70 |
index 301e3476d..19f2cc230 100644
|
|
|
afd354 |
--- a/src/kadmin/dbutil/dump.c
|
|
|
afd354 |
+++ b/src/kadmin/dbutil/dump.c
|
|
|
afd354 |
@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname)
|
|
|
afd354 |
{
|
|
|
afd354 |
int fd = -1;
|
|
|
afd354 |
FILE *f;
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ void *selabel;
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
|
|
|
afd354 |
*tmpname = NULL;
|
|
|
afd354 |
if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0)
|
|
|
afd354 |
goto error;
|
|
|
afd354 |
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ selabel = krb5int_push_fscreatecon_for(ofile);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
fd = mkstemp(*tmpname);
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ krb5int_pop_fscreatecon(selabel);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
if (fd == -1)
|
|
|
afd354 |
goto error;
|
|
|
afd354 |
|
|
|
afd354 |
@@ -197,7 +206,7 @@ prep_ok_file(krb5_context context, char *file_name, int *fd_out)
|
|
|
afd354 |
goto cleanup;
|
|
|
afd354 |
}
|
|
|
afd354 |
|
|
|
afd354 |
- fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
|
|
afd354 |
+ fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
|
|
afd354 |
if (fd == -1) {
|
|
|
afd354 |
com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
|
|
|
afd354 |
goto cleanup;
|
|
|
afd354 |
diff --git a/src/kdc/main.c b/src/kdc/main.c
|
|
|
10fa70 |
index fdcd694d7..1ede4bf2f 100644
|
|
|
afd354 |
--- a/src/kdc/main.c
|
|
|
afd354 |
+++ b/src/kdc/main.c
|
|
|
10fa70 |
@@ -872,7 +872,7 @@ write_pid_file(const char *path)
|
|
|
afd354 |
FILE *file;
|
|
|
afd354 |
unsigned long pid;
|
|
|
afd354 |
|
|
|
afd354 |
- file = fopen(path, "w");
|
|
|
afd354 |
+ file = WRITABLEFOPEN(path, "w");
|
|
|
afd354 |
if (file == NULL)
|
|
|
afd354 |
return errno;
|
|
|
afd354 |
pid = (unsigned long) getpid();
|
|
|
afd354 |
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
|
|
|
10fa70 |
index 5622d56e1..356e3e0e6 100644
|
|
|
afd354 |
--- a/src/kprop/kpropd.c
|
|
|
afd354 |
+++ b/src/kprop/kpropd.c
|
|
|
10fa70 |
@@ -487,6 +487,9 @@ doit(int fd)
|
|
|
afd354 |
krb5_enctype etype;
|
|
|
afd354 |
int database_fd;
|
|
|
afd354 |
char host[INET6_ADDRSTRLEN + 1];
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ void *selabel;
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
|
|
|
afd354 |
signal_wrapper(SIGALRM, alarm_handler);
|
|
|
afd354 |
alarm(params.iprop_resync_timeout);
|
|
|
10fa70 |
@@ -542,9 +545,15 @@ doit(int fd)
|
|
|
afd354 |
free(name);
|
|
|
afd354 |
exit(1);
|
|
|
afd354 |
}
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ selabel = krb5int_push_fscreatecon_for(file);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
omask = umask(077);
|
|
|
afd354 |
lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600);
|
|
|
afd354 |
(void)umask(omask);
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ krb5int_pop_fscreatecon(selabel);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
retval = krb5_lock_file(kpropd_context, lock_fd,
|
|
|
afd354 |
KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK);
|
|
|
afd354 |
if (retval) {
|
|
|
afd354 |
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
|
|
|
afd354 |
index c6885edf2..9aec3c05e 100644
|
|
|
afd354 |
--- a/src/lib/kadm5/logger.c
|
|
|
afd354 |
+++ b/src/lib/kadm5/logger.c
|
|
|
afd354 |
@@ -309,7 +309,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
|
|
|
afd354 |
*/
|
|
|
afd354 |
append = (cp[4] == ':') ? O_APPEND : 0;
|
|
|
afd354 |
if (append || cp[4] == '=') {
|
|
|
afd354 |
- fd = open(&cp[5], O_CREAT | O_WRONLY | append,
|
|
|
afd354 |
+ fd = THREEPARAMOPEN(&cp[5], O_CREAT | O_WRONLY | append,
|
|
|
afd354 |
S_IRUSR | S_IWUSR | S_IRGRP);
|
|
|
afd354 |
if (fd != -1)
|
|
|
afd354 |
f = fdopen(fd, append ? "a" : "w");
|
|
|
afd354 |
@@ -776,7 +776,7 @@ krb5_klog_reopen(krb5_context kcontext)
|
|
|
afd354 |
* In case the old logfile did not get moved out of the
|
|
|
afd354 |
* way, open for append to prevent squashing the old logs.
|
|
|
afd354 |
*/
|
|
|
afd354 |
- f = fopen(log_control.log_entries[lindex].lfu_fname, "a+");
|
|
|
afd354 |
+ f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+");
|
|
|
afd354 |
if (f) {
|
|
|
afd354 |
set_cloexec_file(f);
|
|
|
afd354 |
log_control.log_entries[lindex].lfu_filep = f;
|
|
|
afd354 |
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
|
|
|
afd354 |
index 2659a2501..e9b95fce5 100644
|
|
|
afd354 |
--- a/src/lib/kdb/kdb_log.c
|
|
|
afd354 |
+++ b/src/lib/kdb/kdb_log.c
|
|
|
afd354 |
@@ -480,7 +480,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
|
|
|
afd354 |
return ENOMEM;
|
|
|
afd354 |
|
|
|
afd354 |
if (stat(logname, &st) == -1) {
|
|
|
afd354 |
- log_ctx->ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
|
|
|
afd354 |
+ log_ctx->ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600);
|
|
|
afd354 |
if (log_ctx->ulogfd == -1) {
|
|
|
afd354 |
retval = errno;
|
|
|
afd354 |
goto cleanup;
|
|
|
afd354 |
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
|
|
|
10fa70 |
index 7b100a0ec..5683a0433 100644
|
|
|
afd354 |
--- a/src/lib/krb5/ccache/cc_dir.c
|
|
|
afd354 |
+++ b/src/lib/krb5/ccache/cc_dir.c
|
|
|
afd354 |
@@ -183,10 +183,19 @@ write_primary_file(const char *primary_path, const char *contents)
|
|
|
afd354 |
char *newpath = NULL;
|
|
|
afd354 |
FILE *fp = NULL;
|
|
|
afd354 |
int fd = -1, status;
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ void *selabel;
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
|
|
|
afd354 |
if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0)
|
|
|
afd354 |
return ENOMEM;
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ selabel = krb5int_push_fscreatecon_for(primary_path);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
fd = mkstemp(newpath);
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ krb5int_pop_fscreatecon(selabel);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
if (fd < 0)
|
|
|
afd354 |
goto cleanup;
|
|
|
afd354 |
#ifdef HAVE_CHMOD
|
|
|
afd354 |
@@ -221,10 +230,23 @@ static krb5_error_code
|
|
|
afd354 |
verify_dir(krb5_context context, const char *dirname)
|
|
|
afd354 |
{
|
|
|
afd354 |
struct stat st;
|
|
|
afd354 |
+ int status;
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ void *selabel;
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
|
|
|
afd354 |
if (stat(dirname, &st) < 0) {
|
|
|
afd354 |
- if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0)
|
|
|
afd354 |
- return 0;
|
|
|
afd354 |
+ if (errno == ENOENT) {
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ selabel = krb5int_push_fscreatecon_for(dirname);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+ status = mkdir(dirname, S_IRWXU);
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ krb5int_pop_fscreatecon(selabel);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+ if (status == 0)
|
|
|
afd354 |
+ return 0;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
k5_setmsg(context, KRB5_FCC_NOFILE,
|
|
|
afd354 |
_("Credential cache directory %s does not exist"),
|
|
|
afd354 |
dirname);
|
|
|
afd354 |
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
|
|
|
10fa70 |
index 021c94398..aaf573439 100644
|
|
|
afd354 |
--- a/src/lib/krb5/keytab/kt_file.c
|
|
|
afd354 |
+++ b/src/lib/krb5/keytab/kt_file.c
|
|
|
10fa70 |
@@ -735,14 +735,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
|
|
|
afd354 |
|
|
|
afd354 |
KTCHECKLOCK(id);
|
|
|
afd354 |
errno = 0;
|
|
|
afd354 |
- KTFILEP(id) = fopen(KTFILENAME(id),
|
|
|
afd354 |
+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id),
|
|
|
afd354 |
(mode == KRB5_LOCKMODE_EXCLUSIVE) ? "rb+" : "rb");
|
|
|
afd354 |
if (!KTFILEP(id)) {
|
|
|
afd354 |
if ((mode == KRB5_LOCKMODE_EXCLUSIVE) && (errno == ENOENT)) {
|
|
|
afd354 |
/* try making it first time around */
|
|
|
afd354 |
k5_create_secure_file(context, KTFILENAME(id));
|
|
|
afd354 |
errno = 0;
|
|
|
afd354 |
- KTFILEP(id) = fopen(KTFILENAME(id), "rb+");
|
|
|
afd354 |
+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), "rb+");
|
|
|
afd354 |
if (!KTFILEP(id))
|
|
|
afd354 |
goto report_errno;
|
|
|
afd354 |
writevno = 1;
|
|
|
afd354 |
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
|
|
|
10fa70 |
index 7073459f0..e9b99f4ca 100644
|
|
|
afd354 |
--- a/src/lib/krb5/os/trace.c
|
|
|
afd354 |
+++ b/src/lib/krb5/os/trace.c
|
|
|
afd354 |
@@ -458,7 +458,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
|
|
|
afd354 |
fd = malloc(sizeof(*fd));
|
|
|
afd354 |
if (fd == NULL)
|
|
|
afd354 |
return ENOMEM;
|
|
|
afd354 |
- *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
|
|
|
afd354 |
+ *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
|
|
|
afd354 |
if (*fd == -1) {
|
|
|
afd354 |
free(fd);
|
|
|
afd354 |
return errno;
|
|
|
afd354 |
diff --git a/src/plugins/kdb/db2/adb_openclose.c b/src/plugins/kdb/db2/adb_openclose.c
|
|
|
afd354 |
index 7db30a33b..2b9d01921 100644
|
|
|
afd354 |
--- a/src/plugins/kdb/db2/adb_openclose.c
|
|
|
afd354 |
+++ b/src/plugins/kdb/db2/adb_openclose.c
|
|
|
afd354 |
@@ -152,7 +152,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename,
|
|
|
afd354 |
* needs be open read/write so that write locking can work with
|
|
|
afd354 |
* POSIX systems
|
|
|
afd354 |
*/
|
|
|
afd354 |
- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) {
|
|
|
afd354 |
+ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) {
|
|
|
afd354 |
/*
|
|
|
afd354 |
* maybe someone took away write permission so we could only
|
|
|
afd354 |
* get shared locks?
|
|
|
afd354 |
diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
|
|
|
afd354 |
index 5106a5c99..e481e8121 100644
|
|
|
afd354 |
--- a/src/plugins/kdb/db2/kdb_db2.c
|
|
|
afd354 |
+++ b/src/plugins/kdb/db2/kdb_db2.c
|
|
|
afd354 |
@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc)
|
|
|
afd354 |
if (retval)
|
|
|
afd354 |
return retval;
|
|
|
afd354 |
|
|
|
afd354 |
- dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC,
|
|
|
afd354 |
- 0600);
|
|
|
afd354 |
+ dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name,
|
|
|
afd354 |
+ O_CREAT | O_RDWR | O_TRUNC, 0600);
|
|
|
afd354 |
if (dbc->db_lf_file < 0) {
|
|
|
afd354 |
retval = errno;
|
|
|
afd354 |
goto cleanup;
|
|
|
afd354 |
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
|
|
afd354 |
index 2977b17f3..d5809a5a9 100644
|
|
|
afd354 |
--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
|
|
afd354 |
+++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
|
|
afd354 |
@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8.11 (Berkeley) 11/2/95";
|
|
|
afd354 |
#include <string.h>
|
|
|
afd354 |
#include <unistd.h>
|
|
|
afd354 |
|
|
|
afd354 |
+#include "k5-int.h"
|
|
|
afd354 |
#include "db-int.h"
|
|
|
afd354 |
#include "btree.h"
|
|
|
afd354 |
|
|
|
afd354 |
@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, dflags)
|
|
|
afd354 |
goto einval;
|
|
|
afd354 |
}
|
|
|
afd354 |
|
|
|
afd354 |
- if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0)
|
|
|
afd354 |
+ if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
|
|
|
afd354 |
goto err;
|
|
|
afd354 |
|
|
|
afd354 |
} else {
|
|
|
afd354 |
diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c
|
|
|
afd354 |
index 862dbb164..686a960c9 100644
|
|
|
afd354 |
--- a/src/plugins/kdb/db2/libdb2/hash/hash.c
|
|
|
afd354 |
+++ b/src/plugins/kdb/db2/libdb2/hash/hash.c
|
|
|
afd354 |
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 (Berkeley) 11/7/95";
|
|
|
afd354 |
#include <assert.h>
|
|
|
afd354 |
#endif
|
|
|
afd354 |
|
|
|
afd354 |
+#include "k5-int.h"
|
|
|
afd354 |
#include "db-int.h"
|
|
|
afd354 |
#include "hash.h"
|
|
|
afd354 |
#include "page.h"
|
|
|
afd354 |
@@ -129,7 +130,7 @@ __kdb2_hash_open(file, flags, mode, info, dflags)
|
|
|
afd354 |
new_table = 1;
|
|
|
afd354 |
}
|
|
|
afd354 |
if (file) {
|
|
|
afd354 |
- if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1)
|
|
|
afd354 |
+ if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1)
|
|
|
afd354 |
RETURN_ERROR(errno, error0);
|
|
|
afd354 |
(void)fcntl(hashp->fp, F_SETFD, 1);
|
|
|
afd354 |
}
|
|
|
afd354 |
diff --git a/src/plugins/kdb/db2/libdb2/recno/rec_open.c b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
|
|
afd354 |
index d8b26e701..b0daa7c02 100644
|
|
|
afd354 |
--- a/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
|
|
afd354 |
+++ b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
|
|
afd354 |
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c 8.12 (Berkeley) 11/18/94";
|
|
|
afd354 |
#include <stdio.h>
|
|
|
afd354 |
#include <unistd.h>
|
|
|
afd354 |
|
|
|
afd354 |
+#include "k5-int.h"
|
|
|
afd354 |
#include "db-int.h"
|
|
|
afd354 |
#include "recno.h"
|
|
|
afd354 |
|
|
|
afd354 |
@@ -68,7 +69,8 @@ __rec_open(fname, flags, mode, openinfo, dflags)
|
|
|
afd354 |
int rfd = -1, sverrno;
|
|
|
afd354 |
|
|
|
afd354 |
/* Open the user's file -- if this fails, we're done. */
|
|
|
afd354 |
- if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0)
|
|
|
afd354 |
+ if (fname != NULL &&
|
|
|
afd354 |
+ (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
|
|
|
afd354 |
return (NULL);
|
|
|
afd354 |
|
|
|
afd354 |
if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
|
|
|
afd354 |
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
|
|
|
10fa70 |
index b92cb58c7..0a95101ad 100644
|
|
|
afd354 |
--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
|
|
|
afd354 |
+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
|
|
|
10fa70 |
@@ -190,7 +190,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
|
|
|
afd354 |
|
|
|
afd354 |
/* set password in the file */
|
|
|
afd354 |
old_mode = umask(0177);
|
|
|
afd354 |
- pfile = fopen(file_name, "a+");
|
|
|
afd354 |
+ pfile = WRITABLEFOPEN(file_name, "a+");
|
|
|
afd354 |
if (pfile == NULL) {
|
|
|
afd354 |
com_err(me, errno, _("Failed to open file %s: %s"), file_name,
|
|
|
afd354 |
strerror (errno));
|
|
|
10fa70 |
@@ -231,6 +231,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
|
|
|
afd354 |
* Delete the existing entry and add the new entry
|
|
|
afd354 |
*/
|
|
|
afd354 |
FILE *newfile;
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ void *selabel;
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
|
|
|
afd354 |
mode_t omask;
|
|
|
afd354 |
|
|
|
10fa70 |
@@ -242,7 +245,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv)
|
|
|
afd354 |
}
|
|
|
afd354 |
|
|
|
afd354 |
omask = umask(077);
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ selabel = krb5int_push_fscreatecon_for(file_name);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
newfile = fopen(tmp_file, "w");
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+ krb5int_pop_fscreatecon(selabel);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
umask (omask);
|
|
|
afd354 |
if (newfile == NULL) {
|
|
|
afd354 |
com_err(me, errno, _("Error creating file %s"), tmp_file);
|
|
|
afd354 |
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
|
|
|
10fa70 |
index aa951df05..79f9500f6 100644
|
|
|
afd354 |
--- a/src/util/profile/prof_file.c
|
|
|
afd354 |
+++ b/src/util/profile/prof_file.c
|
|
|
afd354 |
@@ -33,6 +33,7 @@
|
|
|
afd354 |
#endif
|
|
|
afd354 |
|
|
|
afd354 |
#include "k5-platform.h"
|
|
|
afd354 |
+#include "k5-label.h"
|
|
|
afd354 |
|
|
|
afd354 |
struct global_shared_profile_data {
|
|
|
afd354 |
/* This is the head of the global list of shared trees */
|
|
|
afd354 |
@@ -391,7 +392,7 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile,
|
|
|
afd354 |
|
|
|
afd354 |
errno = 0;
|
|
|
afd354 |
|
|
|
afd354 |
- f = fopen(new_file, "w");
|
|
|
afd354 |
+ f = WRITABLEFOPEN(new_file, "w");
|
|
|
afd354 |
if (!f) {
|
|
|
afd354 |
retval = errno;
|
|
|
afd354 |
if (retval == 0)
|
|
|
afd354 |
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
|
|
|
10fa70 |
index 86d5a950a..1052d53a1 100644
|
|
|
afd354 |
--- a/src/util/support/Makefile.in
|
|
|
afd354 |
+++ b/src/util/support/Makefile.in
|
|
|
10fa70 |
@@ -74,6 +74,7 @@ IPC_SYMS= \
|
|
|
afd354 |
|
|
|
afd354 |
STLIBOBJS= \
|
|
|
afd354 |
threads.o \
|
|
|
afd354 |
+ selinux.o \
|
|
|
afd354 |
init-addrinfo.o \
|
|
|
afd354 |
plugins.o \
|
|
|
afd354 |
errors.o \
|
|
|
10fa70 |
@@ -168,7 +169,7 @@ SRCS=\
|
|
|
afd354 |
|
|
|
afd354 |
SHLIB_EXPDEPS =
|
|
|
afd354 |
# Add -lm if dumping thread stats, for sqrt.
|
|
|
afd354 |
-SHLIB_EXPLIBS= $(LIBS) $(DL_LIB)
|
|
|
afd354 |
+SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
|
|
|
afd354 |
|
|
|
afd354 |
DEPLIBS=
|
|
|
afd354 |
|
|
|
afd354 |
diff --git a/src/util/support/selinux.c b/src/util/support/selinux.c
|
|
|
afd354 |
new file mode 100644
|
|
|
afd354 |
index 000000000..6d41f3244
|
|
|
afd354 |
--- /dev/null
|
|
|
afd354 |
+++ b/src/util/support/selinux.c
|
|
|
afd354 |
@@ -0,0 +1,406 @@
|
|
|
afd354 |
+/*
|
|
|
afd354 |
+ * Copyright 2007,2008,2009,2011,2012,2013,2016 Red Hat, Inc. All Rights Reserved.
|
|
|
afd354 |
+ *
|
|
|
afd354 |
+ * Redistribution and use in source and binary forms, with or without
|
|
|
afd354 |
+ * modification, are permitted provided that the following conditions are met:
|
|
|
afd354 |
+ *
|
|
|
afd354 |
+ * Redistributions of source code must retain the above copyright notice, this
|
|
|
afd354 |
+ * list of conditions and the following disclaimer.
|
|
|
afd354 |
+ *
|
|
|
afd354 |
+ * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
afd354 |
+ * this list of conditions and the following disclaimer in the documentation
|
|
|
afd354 |
+ * and/or other materials provided with the distribution.
|
|
|
afd354 |
+ *
|
|
|
afd354 |
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
|
|
|
afd354 |
+ * used to endorse or promote products derived from this software without
|
|
|
afd354 |
+ * specific prior written permission.
|
|
|
afd354 |
+ *
|
|
|
afd354 |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
afd354 |
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
afd354 |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
afd354 |
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
afd354 |
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
afd354 |
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
afd354 |
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
afd354 |
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
afd354 |
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
afd354 |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
afd354 |
+ * POSSIBILITY OF SUCH DAMAGE.
|
|
|
afd354 |
+ *
|
|
|
afd354 |
+ * File-opening wrappers for creating correctly-labeled files. So far, we can
|
|
|
afd354 |
+ * assume that this is Linux-specific, so we make many simplifying assumptions.
|
|
|
afd354 |
+ */
|
|
|
afd354 |
+
|
|
|
afd354 |
+#include "../../include/autoconf.h"
|
|
|
afd354 |
+
|
|
|
afd354 |
+#ifdef USE_SELINUX
|
|
|
afd354 |
+
|
|
|
afd354 |
+#include <k5-label.h>
|
|
|
afd354 |
+#include <k5-platform.h>
|
|
|
afd354 |
+
|
|
|
afd354 |
+#include <sys/types.h>
|
|
|
afd354 |
+#include <sys/stat.h>
|
|
|
afd354 |
+
|
|
|
afd354 |
+#include <errno.h>
|
|
|
afd354 |
+#include <fcntl.h>
|
|
|
afd354 |
+#include <limits.h>
|
|
|
afd354 |
+#include <pthread.h>
|
|
|
afd354 |
+#include <stdarg.h>
|
|
|
afd354 |
+#include <stdio.h>
|
|
|
afd354 |
+#include <stdlib.h>
|
|
|
afd354 |
+#include <string.h>
|
|
|
afd354 |
+#include <unistd.h>
|
|
|
afd354 |
+
|
|
|
afd354 |
+#include <selinux/selinux.h>
|
|
|
afd354 |
+#include <selinux/context.h>
|
|
|
afd354 |
+#include <selinux/label.h>
|
|
|
afd354 |
+
|
|
|
afd354 |
+/* #define DEBUG 1 */
|
|
|
afd354 |
+static void
|
|
|
afd354 |
+debug_log(const char *fmt, ...)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+#ifdef DEBUG
|
|
|
afd354 |
+ va_list ap;
|
|
|
afd354 |
+ va_start(ap, fmt);
|
|
|
afd354 |
+ if (isatty(fileno(stderr))) {
|
|
|
afd354 |
+ vfprintf(stderr, fmt, ap);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+ va_end(ap);
|
|
|
afd354 |
+#endif
|
|
|
afd354 |
+
|
|
|
afd354 |
+ return;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+/* Mutex used to serialize use of the process-global file creation context. */
|
|
|
afd354 |
+k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
|
|
|
afd354 |
+
|
|
|
afd354 |
+/* Make sure we finish initializing that mutex before attempting to use it. */
|
|
|
afd354 |
+k5_once_t labeled_once = K5_ONCE_INIT;
|
|
|
afd354 |
+static void
|
|
|
afd354 |
+label_mutex_init(void)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ k5_mutex_finish_init(&labeled_mutex);
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+static struct selabel_handle *selabel_ctx;
|
|
|
afd354 |
+static time_t selabel_last_changed;
|
|
|
afd354 |
+
|
|
|
afd354 |
+MAKE_FINI_FUNCTION(cleanup_fscreatecon);
|
|
|
afd354 |
+
|
|
|
afd354 |
+static void
|
|
|
afd354 |
+cleanup_fscreatecon(void)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ if (selabel_ctx != NULL) {
|
|
|
afd354 |
+ selabel_close(selabel_ctx);
|
|
|
afd354 |
+ selabel_ctx = NULL;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+static security_context_t
|
|
|
afd354 |
+push_fscreatecon(const char *pathname, mode_t mode)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ security_context_t previous, configuredsc, currentsc, derivedsc;
|
|
|
afd354 |
+ context_t current, derived;
|
|
|
afd354 |
+ const char *fullpath, *currentuser;
|
|
|
afd354 |
+ char *genpath;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ previous = configuredsc = currentsc = derivedsc = NULL;
|
|
|
afd354 |
+ current = derived = NULL;
|
|
|
afd354 |
+ genpath = NULL;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ fullpath = pathname;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (!is_selinux_enabled()) {
|
|
|
afd354 |
+ goto fail;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (getfscreatecon(&previous) != 0) {
|
|
|
afd354 |
+ goto fail;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ /* Canonicalize pathname */
|
|
|
afd354 |
+ if (pathname[0] != '/') {
|
|
|
afd354 |
+ char *wd;
|
|
|
afd354 |
+ size_t len;
|
|
|
afd354 |
+ len = 0;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ wd = getcwd(NULL, len);
|
|
|
afd354 |
+ if (wd == NULL) {
|
|
|
afd354 |
+ goto fail;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ len = strlen(wd) + 1 + strlen(pathname) + 1;
|
|
|
afd354 |
+ genpath = malloc(len);
|
|
|
afd354 |
+ if (genpath == NULL) {
|
|
|
afd354 |
+ free(wd);
|
|
|
afd354 |
+ goto fail;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ sprintf(genpath, "%s/%s", wd, pathname);
|
|
|
afd354 |
+ free(wd);
|
|
|
afd354 |
+ fullpath = genpath;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ debug_log("Looking up context for \"%s\"(%05o).\n", fullpath, mode);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ /* Check whether context file has changed under us */
|
|
|
afd354 |
+ if (selabel_ctx != NULL || selabel_last_changed == 0) {
|
|
|
afd354 |
+ const char *cpath;
|
|
|
afd354 |
+ struct stat st;
|
|
|
afd354 |
+ int i = -1;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ cpath = selinux_file_context_path();
|
|
|
afd354 |
+ if (cpath == NULL || (i = stat(cpath, &st)) != 0 ||
|
|
|
afd354 |
+ st.st_mtime != selabel_last_changed) {
|
|
|
afd354 |
+ cleanup_fscreatecon();
|
|
|
afd354 |
+
|
|
|
afd354 |
+ selabel_last_changed = i ? time(NULL) : st.st_mtime;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (selabel_ctx == NULL) {
|
|
|
afd354 |
+ selabel_ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (selabel_ctx != NULL &&
|
|
|
afd354 |
+ selabel_lookup(selabel_ctx, &configuredsc, fullpath, mode) != 0) {
|
|
|
afd354 |
+ goto fail;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (genpath != NULL) {
|
|
|
afd354 |
+ free(genpath);
|
|
|
afd354 |
+ genpath = NULL;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (configuredsc == NULL) {
|
|
|
afd354 |
+ goto fail;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ getcon(¤tsc);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ /* AAAAAAAA */
|
|
|
afd354 |
+ if (currentsc != NULL) {
|
|
|
afd354 |
+ derived = context_new(configuredsc);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (derived != NULL) {
|
|
|
afd354 |
+ current = context_new(currentsc);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (current != NULL) {
|
|
|
afd354 |
+ currentuser = context_user_get(current);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (currentuser != NULL) {
|
|
|
afd354 |
+ if (context_user_set(derived,
|
|
|
afd354 |
+ currentuser) == 0) {
|
|
|
afd354 |
+ derivedsc = context_str(derived);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (derivedsc != NULL) {
|
|
|
afd354 |
+ freecon(configuredsc);
|
|
|
afd354 |
+ configuredsc = strdup(derivedsc);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ context_free(current);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ context_free(derived);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ freecon(currentsc);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ debug_log("Setting file creation context to \"%s\".\n", configuredsc);
|
|
|
afd354 |
+ if (setfscreatecon(configuredsc) != 0) {
|
|
|
afd354 |
+ debug_log("Unable to determine current context.\n");
|
|
|
afd354 |
+ goto fail;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ freecon(configuredsc);
|
|
|
afd354 |
+ return previous;
|
|
|
afd354 |
+
|
|
|
afd354 |
+fail:
|
|
|
afd354 |
+ if (previous != NULL) {
|
|
|
afd354 |
+ freecon(previous);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+ if (genpath != NULL) {
|
|
|
afd354 |
+ free(genpath);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+ if (configuredsc != NULL) {
|
|
|
afd354 |
+ freecon(configuredsc);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ cleanup_fscreatecon();
|
|
|
afd354 |
+ return NULL;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+static void
|
|
|
afd354 |
+pop_fscreatecon(security_context_t previous)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ if (!is_selinux_enabled()) {
|
|
|
afd354 |
+ return;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (previous != NULL) {
|
|
|
afd354 |
+ debug_log("Resetting file creation context to \"%s\".\n", previous);
|
|
|
afd354 |
+ } else {
|
|
|
afd354 |
+ debug_log("Resetting file creation context to default.\n");
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ /* NULL resets to default */
|
|
|
afd354 |
+ setfscreatecon(previous);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (previous != NULL) {
|
|
|
afd354 |
+ freecon(previous);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ /* Need to clean this up here otherwise it leaks */
|
|
|
afd354 |
+ cleanup_fscreatecon();
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+void *
|
|
|
afd354 |
+krb5int_push_fscreatecon_for(const char *pathname)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ struct stat st;
|
|
|
afd354 |
+ void *retval;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ k5_once(&labeled_once, label_mutex_init);
|
|
|
afd354 |
+ k5_mutex_lock(&labeled_mutex);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if (stat(pathname, &st) != 0) {
|
|
|
afd354 |
+ st.st_mode = S_IRUSR | S_IWUSR;
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ retval = push_fscreatecon(pathname, st.st_mode);
|
|
|
afd354 |
+ return retval ? retval : (void *) -1;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+void
|
|
|
afd354 |
+krb5int_pop_fscreatecon(void *con)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ if (con != NULL) {
|
|
|
afd354 |
+ pop_fscreatecon((con == (void *) -1) ? NULL : con);
|
|
|
afd354 |
+ k5_mutex_unlock(&labeled_mutex);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+FILE *
|
|
|
afd354 |
+krb5int_labeled_fopen(const char *path, const char *mode)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ FILE *fp;
|
|
|
afd354 |
+ int errno_save;
|
|
|
afd354 |
+ security_context_t ctx;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if ((strcmp(mode, "r") == 0) ||
|
|
|
afd354 |
+ (strcmp(mode, "rb") == 0)) {
|
|
|
afd354 |
+ return fopen(path, mode);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ k5_once(&labeled_once, label_mutex_init);
|
|
|
afd354 |
+ k5_mutex_lock(&labeled_mutex);
|
|
|
afd354 |
+ ctx = push_fscreatecon(path, 0);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ fp = fopen(path, mode);
|
|
|
afd354 |
+ errno_save = errno;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ pop_fscreatecon(ctx);
|
|
|
afd354 |
+ k5_mutex_unlock(&labeled_mutex);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ errno = errno_save;
|
|
|
afd354 |
+ return fp;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+int
|
|
|
afd354 |
+krb5int_labeled_creat(const char *path, mode_t mode)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ int fd;
|
|
|
afd354 |
+ int errno_save;
|
|
|
afd354 |
+ security_context_t ctx;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ k5_once(&labeled_once, label_mutex_init);
|
|
|
afd354 |
+ k5_mutex_lock(&labeled_mutex);
|
|
|
afd354 |
+ ctx = push_fscreatecon(path, 0);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ fd = creat(path, mode);
|
|
|
afd354 |
+ errno_save = errno;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ pop_fscreatecon(ctx);
|
|
|
afd354 |
+ k5_mutex_unlock(&labeled_mutex);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ errno = errno_save;
|
|
|
afd354 |
+ return fd;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+int
|
|
|
afd354 |
+krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ int ret;
|
|
|
afd354 |
+ int errno_save;
|
|
|
afd354 |
+ security_context_t ctx;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ k5_once(&labeled_once, label_mutex_init);
|
|
|
afd354 |
+ k5_mutex_lock(&labeled_mutex);
|
|
|
afd354 |
+ ctx = push_fscreatecon(path, mode);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ ret = mknod(path, mode, dev);
|
|
|
afd354 |
+ errno_save = errno;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ pop_fscreatecon(ctx);
|
|
|
afd354 |
+ k5_mutex_unlock(&labeled_mutex);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ errno = errno_save;
|
|
|
afd354 |
+ return ret;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+int
|
|
|
afd354 |
+krb5int_labeled_mkdir(const char *path, mode_t mode)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ int ret;
|
|
|
afd354 |
+ int errno_save;
|
|
|
afd354 |
+ security_context_t ctx;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ k5_once(&labeled_once, label_mutex_init);
|
|
|
afd354 |
+ k5_mutex_lock(&labeled_mutex);
|
|
|
afd354 |
+ ctx = push_fscreatecon(path, S_IFDIR);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ ret = mkdir(path, mode);
|
|
|
afd354 |
+ errno_save = errno;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ pop_fscreatecon(ctx);
|
|
|
afd354 |
+ k5_mutex_unlock(&labeled_mutex);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ errno = errno_save;
|
|
|
afd354 |
+ return ret;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+int
|
|
|
afd354 |
+krb5int_labeled_open(const char *path, int flags, ...)
|
|
|
afd354 |
+{
|
|
|
afd354 |
+ int fd;
|
|
|
afd354 |
+ int errno_save;
|
|
|
afd354 |
+ security_context_t ctx;
|
|
|
afd354 |
+ mode_t mode;
|
|
|
afd354 |
+ va_list ap;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ if ((flags & O_CREAT) == 0) {
|
|
|
afd354 |
+ return open(path, flags);
|
|
|
afd354 |
+ }
|
|
|
afd354 |
+
|
|
|
afd354 |
+ k5_once(&labeled_once, label_mutex_init);
|
|
|
afd354 |
+ k5_mutex_lock(&labeled_mutex);
|
|
|
afd354 |
+ ctx = push_fscreatecon(path, 0);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ va_start(ap, flags);
|
|
|
afd354 |
+ mode = va_arg(ap, mode_t);
|
|
|
afd354 |
+ fd = open(path, flags, mode);
|
|
|
afd354 |
+ va_end(ap);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ errno_save = errno;
|
|
|
afd354 |
+
|
|
|
afd354 |
+ pop_fscreatecon(ctx);
|
|
|
afd354 |
+ k5_mutex_unlock(&labeled_mutex);
|
|
|
afd354 |
+
|
|
|
afd354 |
+ errno = errno_save;
|
|
|
afd354 |
+ return fd;
|
|
|
afd354 |
+}
|
|
|
afd354 |
+
|
|
|
afd354 |
+#endif /* USE_SELINUX */
|