cd1d849
SELinux bases access to files on the domain of the requesting process,
cd1d849
the operation being performed, and the context applied to the file.
55c161b
55c161b
In many cases, applications needn't be SELinux aware to work properly,
55c161b
because SELinux can apply a default label to a file based on the label
55c161b
of the directory in which it's created.
55c161b
55c161b
In the case of files such as /etc/krb5.keytab, however, this isn't
3f291ca
sufficient, as /etc/krb5.keytab will almost always need to be given a
3f291ca
label which differs from that of /etc/issue or /etc/resolv.conf.  The
3f291ca
the kdb stash file needs a different label than the database for which
3f291ca
it's holding a master key, even though both typically live in the same
3f291ca
directory.
55c161b
55c161b
To give the file the correct label, we can either force a "restorecon"
55c161b
call to fix a file's label after it's created, or create the file with
cd1d849
the right label, as we attempt to do here.  We lean on THREEPARAMOPEN
cd1d849
and define a similar macro named WRITABLEFOPEN with which we replace
cd1d849
several uses of fopen().
cd1d849
cd1d849
The file creation context that we're manipulating here is a process-wide
cd1d849
attribute.  While for the most part, applications which need to label
cd1d849
files when they're created have tended to be single-threaded, there's
cd1d849
not much we can do to avoid interfering with an application that
cd1d849
manipulates the creation context directly.  Right now we're mediating
cd1d849
access using a library-local mutex, but that can only work for consumers
cd1d849
that are part of this package -- an unsuspecting application will still
cd1d849
stomp all over us.
cd1d849
cd1d849
The selabel APIs for looking up the context should be thread-safe (per
cd1d849
Red Hat #273081), so switching to using them instead of matchpathcon(),
cd1d849
which we used earlier, is some improvement.
55c161b
Nalin Dahyabhai efdfc3a
--- krb5/src/aclocal.m4
Nalin Dahyabhai efdfc3a
+++ krb5/src/aclocal.m4
55c161b
@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag)
55c161b
 dnl
55c161b
 KRB5_AC_PRAGMA_WEAK_REF
55c161b
 WITH_LDAP
55c161b
+KRB5_WITH_SELINUX
55c161b
 KRB5_LIB_PARAMS
55c161b
 KRB5_AC_INITFINI
55c161b
 KRB5_AC_ENABLE_THREADS
6a7a118
@@ -1791,3 +1792,51 @@ AC_SUBST(manlocalstatedir)
777f196
 AC_SUBST(PAM_MAN)
777f196
 AC_SUBST(NON_PAM_MAN)
777f196
 ])dnl
55c161b
+dnl
55c161b
+dnl Use libselinux to set file contexts on newly-created files.
55c161b
+dnl 
55c161b
+AC_DEFUN(KRB5_WITH_SELINUX,[
55c161b
+AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])],
55c161b
+           withselinux="$withval",withselinux=auto)
55c161b
+old_LIBS="$LIBS"
55c161b
+if test "$withselinux" != no ; then
55c161b
+       AC_MSG_RESULT([checking for libselinux...])
55c161b
+       SELINUX_LIBS=
c6f29fd
+       AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h)
55c161b
+       if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then
55c161b
+               if test "$withselinux" = auto ; then
55c161b
+                       AC_MSG_RESULT([Unable to locate selinux/selinux.h.])
55c161b
+                       withselinux=no
55c161b
+               else
55c161b
+                       AC_MSG_ERROR([Unable to locate selinux/selinux.h.])
55c161b
+               fi
55c161b
+       fi
55c161b
+
55c161b
+       LIBS=
55c161b
+       unset ac_cv_func_setfscreatecon
c6f29fd
+       AC_CHECK_FUNCS(setfscreatecon selabel_open)
55c161b
+       if test "x$ac_cv_func_setfscreatecon" = xno ; then
55c161b
+               AC_CHECK_LIB(selinux,setfscreatecon)
55c161b
+               unset ac_cv_func_setfscreatecon
c6f29fd
+               AC_CHECK_FUNCS(setfscreatecon selabel_open)
55c161b
+               if test "x$ac_cv_func_setfscreatecon" = xyes ; then
55c161b
+                       SELINUX_LIBS="$LIBS"
55c161b
+               else
55c161b
+                       if test "$withselinux" = auto ; then
55c161b
+                               AC_MSG_RESULT([Unable to locate libselinux.])
55c161b
+                               withselinux=no
55c161b
+                       else
55c161b
+                               AC_MSG_ERROR([Unable to locate libselinux.])
55c161b
+                       fi
55c161b
+               fi
55c161b
+       fi
55c161b
+       if test "$withselinux" != no ; then
612cb4a
+               AC_MSG_NOTICE([building with SELinux labeling support])
55c161b
+               AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.])
55c161b
+               SELINUX_LIBS="$LIBS"
6a7a118
+		EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon"
55c161b
+       fi
55c161b
+fi
55c161b
+LIBS="$old_LIBS"
55c161b
+AC_SUBST(SELINUX_LIBS)
55c161b
+])dnl
Nalin Dahyabhai efdfc3a
--- krb5/src/config/pre.in
Nalin Dahyabhai efdfc3a
+++ krb5/src/config/pre.in
75b0804
@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@
75b0804
 LD_SHLIBDIR_PREFIX = @LD_SHLIBDIR_PREFIX@
55c161b
 LDARGS = @LDARGS@
55c161b
 LIBS = @LIBS@
55c161b
+SELINUX_LIBS=@SELINUX_LIBS@
55c161b
 
55c161b
 INSTALL=@INSTALL@
55c161b
 INSTALL_STRIP=
75b0804
@@ -379,7 +380,7 @@ SUPPORT_LIB			= -l$(SUPPORT_LIBNAME)
55c161b
 # HESIOD_LIBS is -lhesiod...
55c161b
 HESIOD_LIBS	= @HESIOD_LIBS@
55c161b
 
55c161b
-KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB)
55c161b
+KRB5_BASE_LIBS	= $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
55c161b
 KDB5_LIBS	= $(KDB5_LIB) $(GSSRPC_LIBS)
55c161b
 GSS_LIBS	= $(GSS_KRB5_LIB)
55c161b
 # needs fixing if ever used on Mac OS X!
Nalin Dahyabhai efdfc3a
--- krb5/src/configure.in
Nalin Dahyabhai efdfc3a
+++ krb5/src/configure.in
75b0804
@@ -1053,6 +1053,8 @@ fi
55c161b
 
55c161b
 KRB5_WITH_PAM
55c161b
 
55c161b
+KRB5_WITH_SELINUX
55c161b
+
Nalin Dahyabhai b8b7185
 # Make localedir work in autoconf 2.5x.
Nalin Dahyabhai b8b7185
 if test "${localedir+set}" != set; then
Nalin Dahyabhai b8b7185
     localedir='$(datadir)/locale'
Nalin Dahyabhai efdfc3a
--- krb5/src/include/k5-int.h
Nalin Dahyabhai efdfc3a
+++ krb5/src/include/k5-int.h
75b0804
@@ -133,6 +133,7 @@ typedef unsigned char   u_char;
55c161b
 typedef UINT64_TYPE krb5_ui_8;
55c161b
 typedef INT64_TYPE krb5_int64;
55c161b
 
55c161b
+#include "k5-label.h"
55c161b
 
55c161b
 #define DEFAULT_PWD_STRING1 "Enter password"
55c161b
 #define DEFAULT_PWD_STRING2 "Re-enter password for verification"
Nalin Dahyabhai efdfc3a
--- krb5/src/include/k5-label.h
Nalin Dahyabhai efdfc3a
+++ krb5/src/include/k5-label.h
6a7a118
@@ -0,0 +1,32 @@
55c161b
+#ifndef _KRB5_LABEL_H
55c161b
+#define _KRB5_LABEL_H
55c161b
+
55c161b
+#ifdef THREEPARAMOPEN
55c161b
+#undef THREEPARAMOPEN
55c161b
+#endif
75b0804
+#ifdef WRITABLEFOPEN
75b0804
+#undef WRITABLEFOPEN
75b0804
+#endif
55c161b
+
55c161b
+/* Wrapper functions which help us create files and directories with the right
55c161b
+ * context labels. */
55c161b
+#ifdef USE_SELINUX
55c161b
+#include <sys/types.h>
55c161b
+#include <sys/stat.h>
55c161b
+#include <fcntl.h>
55c161b
+#include <stdio.h>
55c161b
+#include <unistd.h>
55c161b
+FILE *krb5int_labeled_fopen(const char *path, const char *mode);
55c161b
+int krb5int_labeled_creat(const char *path, mode_t mode);
55c161b
+int krb5int_labeled_open(const char *path, int flags, ...);
55c161b
+int krb5int_labeled_mkdir(const char *path, mode_t mode);
55c161b
+int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device);
55c161b
+#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z)
55c161b
+#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y)
6a7a118
+void *krb5int_push_fscreatecon_for(const char *pathname);
6a7a118
+void krb5int_pop_fscreatecon(void *previous);
55c161b
+#else
55c161b
+#define WRITABLEFOPEN(x,y) fopen(x,y)
55c161b
+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
55c161b
+#endif
55c161b
+#endif
Nalin Dahyabhai efdfc3a
--- krb5/src/include/krb5/krb5.hin
Nalin Dahyabhai efdfc3a
+++ krb5/src/include/krb5/krb5.hin
55c161b
@@ -87,6 +87,12 @@
55c161b
 #define THREEPARAMOPEN(x,y,z) open(x,y,z)
55c161b
 #endif
55c161b
 
55c161b
+#if KRB5_PRIVATE
55c161b
+#ifndef WRITABLEFOPEN
55c161b
+#define WRITABLEFOPEN(x,y) fopen(x,y)
55c161b
+#endif
55c161b
+#endif
55c161b
+
55c161b
 #define KRB5_OLD_CRYPTO
55c161b
 
55c161b
 #include <stdlib.h>
Nalin Dahyabhai efdfc3a
--- krb5/src/kadmin/dbutil/dump.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/kadmin/dbutil/dump.c
8a943cb
@@ -376,12 +376,21 @@ create_ofile(char *ofile, char **tmpname
8a943cb
 {
8a943cb
     int fd = -1;
8a943cb
     FILE *f;
8a943cb
+#ifdef USE_SELINUX
8a943cb
+    void *selabel;
8a943cb
+#endif
8a943cb
 
8a943cb
     *tmpname = NULL;
8a943cb
     if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0)
8a943cb
         goto error;
8a943cb
 
8a943cb
+#ifdef USE_SELINUX
8a943cb
+    selabel = krb5int_push_fscreatecon_for(ofile);
8a943cb
+#endif
8a943cb
     fd = mkstemp(*tmpname);
8a943cb
+#ifdef USE_SELINUX
8a943cb
+    krb5int_pop_fscreatecon(selabel);
8a943cb
+#endif
8a943cb
     if (fd == -1)
8a943cb
         goto error;
8a943cb
 
8a943cb
@@ -514,7 +514,7 @@ prep_ok_file(krb5_context context, char
8a943cb
         return 0;
Nalin Dahyabhai efdfc3a
     }
8a943cb
 
8a943cb
-    *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
8a943cb
+    *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600);
8a943cb
     if (*fd == -1) {
8a943cb
         com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
Nalin Dahyabhai efdfc3a
         exit_status++;
Nalin Dahyabhai efdfc3a
--- krb5/src/krb5-config.in
Nalin Dahyabhai efdfc3a
+++ krb5/src/krb5-config.in
55c161b
@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@'
8a943cb
 DEFCCNAME='@DEFCCNAME@'
8a943cb
 DEFKTNAME='@DEFKTNAME@'
8a943cb
 DEFCKTNAME='@DEFCKTNAME@'
55c161b
+SELINUX_LIBS='@SELINUX_LIBS@'
55c161b
 
55c161b
 LIBS='@LIBS@'
55c161b
 GEN_LIB=@GEN_LIB@
Nalin Dahyabhai efdfc3a
@@ -218,7 +219,7 @@
55c161b
     fi
55c161b
 
Nalin Dahyabhai efdfc3a
     # If we ever support a flag to generate output suitable for static
Nalin Dahyabhai efdfc3a
-    # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB"
Nalin Dahyabhai efdfc3a
+    # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB"
Nalin Dahyabhai efdfc3a
     # here.
55c161b
 
55c161b
     echo $lib_flags
Nalin Dahyabhai efdfc3a
--- krb5/src/lib/kadm5/logger.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/lib/kadm5/logger.c
75b0804
@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch
75b0804
                      * Check for append/overwrite, then open the file.
75b0804
                      */
75b0804
                     if (cp[4] == ':' || cp[4] == '=') {
75b0804
-                        f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w");
75b0804
+                        f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w");
75b0804
                         if (f) {
75b0804
                             set_cloexec_file(f);
75b0804
                             log_control.log_entries[i].lfu_filep = f;
75b0804
@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext)
75b0804
              * In case the old logfile did not get moved out of the
75b0804
              * way, open for append to prevent squashing the old logs.
75b0804
              */
75b0804
-            f = fopen(log_control.log_entries[lindex].lfu_fname, "a+");
75b0804
+            f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+");
75b0804
             if (f) {
75b0804
                 set_cloexec_file(f);
75b0804
                 log_control.log_entries[lindex].lfu_filep = f;
Nalin Dahyabhai efdfc3a
--- krb5/src/lib/krb5/keytab/kt_file.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/lib/krb5/keytab/kt_file.c
75b0804
@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context
55c161b
 
55c161b
     KTCHECKLOCK(id);
55c161b
     errno = 0;
55c161b
-    KTFILEP(id) = fopen(KTFILENAME(id),
55c161b
+    KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id),
75b0804
                         (mode == KRB5_LOCKMODE_EXCLUSIVE) ?
75b0804
                         fopen_mode_rbplus : fopen_mode_rb);
55c161b
     if (!KTFILEP(id)) {
75b0804
@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context
75b0804
             /* try making it first time around */
55c161b
             krb5_create_secure_file(context, KTFILENAME(id));
75b0804
             errno = 0;
75b0804
-            KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus);
75b0804
+            KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus);
75b0804
             if (!KTFILEP(id))
75b0804
                 goto report_errno;
75b0804
             writevno = 1;
Nalin Dahyabhai efdfc3a
--- krb5/src/plugins/kdb/db2/adb_openclose.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/plugins/kdb/db2/adb_openclose.c
75b0804
@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char 
75b0804
          * POSIX systems
75b0804
          */
75b0804
         lockp->lockinfo.filename = strdup(lockfilename);
75b0804
-        if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) {
75b0804
+        if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) {
75b0804
             /*
75b0804
              * maybe someone took away write permission so we could only
75b0804
              * get shared locks?
Nalin Dahyabhai efdfc3a
--- krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
55c161b
@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c	8.
55c161b
 
55c161b
 #include "k5-platform.h"	/* mkstemp? */
55c161b
 
55c161b
+#include "k5-int.h"
55c161b
 #include "db-int.h"
55c161b
 #include "btree.h"
55c161b
 
55c161b
@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, 
55c161b
 			goto einval;
55c161b
 		}
75b0804
 
55c161b
-		if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0)
55c161b
+		if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
55c161b
 			goto err;
55c161b
 
55c161b
 	} else {
Nalin Dahyabhai efdfc3a
--- krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
55c161b
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c	8.12 
55c161b
 #include <assert.h>
55c161b
 #endif
55c161b
 
55c161b
+#include "k5-int.h"
55c161b
 #include "db-int.h"
55c161b
 #include "hash.h"
55c161b
 #include "page.h"
55c161b
@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info
55c161b
 		new_table = 1;
55c161b
 	}
55c161b
 	if (file) {
55c161b
-		if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1)
55c161b
+		if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1)
55c161b
 			RETURN_ERROR(errno, error0);
55c161b
 		(void)fcntl(hashp->fp, F_SETFD, 1);
55c161b
 	}
Nalin Dahyabhai efdfc3a
--- krb5/src/plugins/kdb/db2/libdb2/test/Makefile.in
Nalin Dahyabhai efdfc3a
+++ krb5/src/plugins/kdb/db2/libdb2/test/Makefile.in
75b0804
@@ -12,7 +12,8 @@ PROG_RPATH=$(KRB5_LIBDIR)
55c161b
 
55c161b
 KRB5_RUN_ENV= @KRB5_RUN_ENV@
55c161b
 
55c161b
-DB_LIB		= -ldb
55c161b
+DB_LIB		= -ldb $(SUPPORT_DEPLIB)
55c161b
+
55c161b
 DB_DEPLIB	= ../libdb$(DEPLIBEXT)
55c161b
 
55c161b
 all::
Nalin Dahyabhai efdfc3a
--- krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
8a943cb
@@ -179,7 +179,7 @@ done:
55c161b
 
55c161b
     /* set password in the file */
55c161b
     old_mode = umask(0177);
55c161b
-    pfile = fopen(file_name, "a+");
55c161b
+    pfile = WRITABLEFOPEN(file_name, "a+");
55c161b
     if (pfile == NULL) {
Nalin Dahyabhai efdfc3a
         com_err(me, errno, _("Failed to open file %s: %s"), file_name,
75b0804
                 strerror (errno));
8a943cb
@@ -220,6 +220,9 @@ done:
8a943cb
          * Delete the existing entry and add the new entry
8a943cb
          */
8a943cb
         FILE *newfile;
8a943cb
+#ifdef USE_SELINUX
8a943cb
+        void *selabel;
8a943cb
+#endif
8a943cb
 
8a943cb
         mode_t omask;
8a943cb
 
8a943cb
@@ -231,7 +234,13 @@ done:
75b0804
         }
75b0804
 
75b0804
         omask = umask(077);
8a943cb
+#ifdef USE_SELINUX
8a943cb
+        selabel = krb5int_push_fscreatecon_for(file_name);
8a943cb
+#endif
8a943cb
         newfile = fopen(tmp_file, "w");
8a943cb
+#ifdef USE_SELINUX
8a943cb
+        krb5int_pop_fscreatecon(selabel);
8a943cb
+#endif
75b0804
         umask (omask);
75b0804
         if (newfile == NULL) {
Nalin Dahyabhai efdfc3a
             com_err(me, errno, _("Error creating file %s"), tmp_file);
Nalin Dahyabhai efdfc3a
--- krb5/src/slave/kpropd.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/slave/kpropd.c
Nalin Dahyabhai efdfc3a
@@ -437,6 +437,9 @@ void doit(fd)
Nalin Dahyabhai efdfc3a
     krb5_enctype etype;
Nalin Dahyabhai efdfc3a
     int database_fd;
Nalin Dahyabhai efdfc3a
     char host[INET6_ADDRSTRLEN+1];
Nalin Dahyabhai efdfc3a
+#ifdef USE_SELINUX
Nalin Dahyabhai efdfc3a
+    void *selabel;
Nalin Dahyabhai efdfc3a
+#endif
Nalin Dahyabhai efdfc3a
 
8a943cb
     signal_wrapper(SIGALRM, alarm_handler);
8a943cb
     alarm(params.iprop_resync_timeout);
Nalin Dahyabhai efdfc3a
@@ -515,9 +518,15 @@ void doit(fd)
Nalin Dahyabhai efdfc3a
         free(name);
Nalin Dahyabhai efdfc3a
         exit(1);
Nalin Dahyabhai efdfc3a
     }
Nalin Dahyabhai efdfc3a
+#ifdef USE_SELINUX
Nalin Dahyabhai efdfc3a
+    selabel = krb5int_push_fscreatecon_for(file);
Nalin Dahyabhai efdfc3a
+#endif
Nalin Dahyabhai efdfc3a
     omask = umask(077);
Nalin Dahyabhai efdfc3a
     lock_fd = open(temp_file_name, O_RDWR|O_CREAT, 0600);
Nalin Dahyabhai efdfc3a
     (void) umask(omask);
Nalin Dahyabhai efdfc3a
+#ifdef USE_SELINUX
Nalin Dahyabhai efdfc3a
+    krb5int_pop_fscreatecon(selabel);
Nalin Dahyabhai efdfc3a
+#endif
Nalin Dahyabhai efdfc3a
     retval = krb5_lock_file(kpropd_context, lock_fd,
Nalin Dahyabhai efdfc3a
                             KRB5_LOCKMODE_EXCLUSIVE|KRB5_LOCKMODE_DONTBLOCK);
Nalin Dahyabhai efdfc3a
     if (retval) {
Nalin Dahyabhai efdfc3a
--- krb5/src/util/profile/prof_file.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/util/profile/prof_file.c
75b0804
@@ -30,6 +30,7 @@
55c161b
 #endif
55c161b
 
55c161b
 #include "k5-platform.h"
55c161b
+#include "k5-label.h"
55c161b
 
55c161b
 struct global_shared_profile_data {
75b0804
     /* This is the head of the global list of shared trees */
75b0804
@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_
55c161b
 
75b0804
     errno = 0;
55c161b
 
75b0804
-    f = fopen(new_file, "w");
75b0804
+    f = WRITABLEFOPEN(new_file, "w");
75b0804
     if (!f) {
75b0804
         retval = errno;
75b0804
         if (retval == 0)
Nalin Dahyabhai efdfc3a
--- krb5/src/util/support/Makefile.in
Nalin Dahyabhai efdfc3a
+++ krb5/src/util/support/Makefile.in
75b0804
@@ -54,6 +54,7 @@ IPC_SYMS= \
55c161b
 
55c161b
 STLIBOBJS= \
55c161b
 	threads.o \
55c161b
+	selinux.o \
55c161b
 	init-addrinfo.o \
55c161b
 	plugins.o \
55c161b
 	errors.o \
75b0804
@@ -108,7 +109,7 @@ SRCS=\
55c161b
 
55c161b
 SHLIB_EXPDEPS =
55c161b
 # Add -lm if dumping thread stats, for sqrt.
55c161b
-SHLIB_EXPLIBS= $(LIBS) $(DL_LIB)
55c161b
+SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
55c161b
 SHLIB_DIRS=
55c161b
 SHLIB_RDIRS=$(KRB5_LIBDIR)
55c161b
 
Nalin Dahyabhai efdfc3a
--- krb5/src/util/support/selinux.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/util/support/selinux.c
Nalin Dahyabhai cf693a2
@@ -0,0 +1,405 @@
55c161b
+/*
Nalin Dahyabhai cd92a2c
+ * Copyright 2007,2008,2009,2011,2012 Red Hat, Inc.  All Rights Reserved.
55c161b
+ *
55c161b
+ * Redistribution and use in source and binary forms, with or without
55c161b
+ * modification, are permitted provided that the following conditions are met:
55c161b
+ *
55c161b
+ *  Redistributions of source code must retain the above copyright notice, this
55c161b
+ *  list of conditions and the following disclaimer.
55c161b
+ *
55c161b
+ *  Redistributions in binary form must reproduce the above copyright notice,
55c161b
+ *  this list of conditions and the following disclaimer in the documentation
55c161b
+ *  and/or other materials provided with the distribution.
55c161b
+ *
55c161b
+ *  Neither the name of Red Hat, Inc. nor the names of its contributors may be
55c161b
+ *  used to endorse or promote products derived from this software without
55c161b
+ *  specific prior written permission.
55c161b
+ *
55c161b
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55c161b
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55c161b
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55c161b
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
55c161b
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55c161b
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
55c161b
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55c161b
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55c161b
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55c161b
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55c161b
+ * POSSIBILITY OF SUCH DAMAGE.
55c161b
+ * 
55c161b
+ * File-opening wrappers for creating correctly-labeled files.  So far, we can
55c161b
+ * assume that this is Linux-specific, so we make many simplifying assumptions.
55c161b
+ */
55c161b
+
55c161b
+#include "../../include/autoconf.h"
55c161b
+
55c161b
+#ifdef USE_SELINUX
55c161b
+
55c161b
+#include <k5-label.h>
5d6308a
+#include <k5-platform.h>
55c161b
+#include <sys/types.h>
55c161b
+#include <sys/stat.h>
55c161b
+#include <errno.h>
55c161b
+#include <fcntl.h>
55c161b
+#include <limits.h>
55c161b
+#include <pthread.h>
55c161b
+#include <stdarg.h>
55c161b
+#include <stdio.h>
55c161b
+#include <stdlib.h>
55c161b
+#include <string.h>
55c161b
+#include <unistd.h>
55c161b
+#include <selinux/selinux.h>
61f3185
+#include <selinux/context.h>
c6f29fd
+#ifdef HAVE_SELINUX_LABEL_H
3f291ca
+#include <selinux/label.h>
c6f29fd
+#endif
55c161b
+
55c161b
+/* #define DEBUG 1 */
55c161b
+
55c161b
+/* Mutex used to serialize use of the process-global file creation context. */
55c161b
+k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
55c161b
+
55c161b
+/* Make sure we finish initializing that mutex before attempting to use it. */
55c161b
+k5_once_t labeled_once = K5_ONCE_INIT;
55c161b
+static void
55c161b
+label_mutex_init(void)
55c161b
+{
55c161b
+	k5_mutex_finish_init(&labeled_mutex);
55c161b
+}
55c161b
+
5d6308a
+#ifdef HAVE_SELINUX_LABEL_H
5d6308a
+static struct selabel_handle *selabel_ctx;
5d6308a
+static time_t selabel_last_changed;
5d6308a
+
5d6308a
+MAKE_FINI_FUNCTION(cleanup_fscreatecon);
5d6308a
+
5d6308a
+static void
5d6308a
+cleanup_fscreatecon(void)
5d6308a
+{
5d6308a
+	if (selabel_ctx != NULL) {
5d6308a
+		selabel_close(selabel_ctx);
5d6308a
+		selabel_ctx = NULL;
5d6308a
+	}
5d6308a
+}
5d6308a
+#endif
5d6308a
+
55c161b
+static security_context_t
55c161b
+push_fscreatecon(const char *pathname, mode_t mode)
55c161b
+{
61f3185
+	security_context_t previous, configuredsc, currentsc, derivedsc;
61f3185
+	context_t current, derived;
16a5c7a
+	const char *fullpath, *currentuser;
55c161b
+
55c161b
+	previous = NULL;
55c161b
+	if (is_selinux_enabled()) {
55c161b
+		if (getfscreatecon(&previous) == 0) {
55c161b
+			char *genpath;
55c161b
+			genpath = NULL;
55c161b
+			if (pathname[0] != '/') {
55c161b
+				char *wd;
55c161b
+				size_t len;
55c161b
+				len = 0;
55c161b
+				wd = getcwd(NULL, len);
55c161b
+				if (wd == NULL) {
55c161b
+					if (previous != NULL) {
55c161b
+						freecon(previous);
55c161b
+					}
55c161b
+					return NULL;
55c161b
+				}
55c161b
+				len = strlen(wd) + 1 + strlen(pathname) + 1;
55c161b
+				genpath = malloc(len);
55c161b
+				if (genpath == NULL) {
55c161b
+					free(wd);
55c161b
+					if (previous != NULL) {
55c161b
+						freecon(previous);
55c161b
+					}
55c161b
+					return NULL;
55c161b
+				}
55c161b
+				sprintf(genpath, "%s/%s", wd, pathname);
55c161b
+				free(wd);
55c161b
+				fullpath = genpath;
55c161b
+			} else {
55c161b
+				fullpath = pathname;
55c161b
+			}
55c161b
+#ifdef DEBUG
55c161b
+			if (isatty(fileno(stderr))) {
55c161b
+				fprintf(stderr, "Looking up context for "
55c161b
+					"\"%s\"(%05o).\n", fullpath, mode);
55c161b
+			}
55c161b
+#endif
61f3185
+			configuredsc = NULL;
c6f29fd
+#ifdef HAVE_SELINUX_LABEL_H
Nalin Dahyabhai cf693a2
+			if ((selabel_ctx != NULL) ||
Nalin Dahyabhai cf693a2
+			    (selabel_last_changed == 0)) {
5d6308a
+				const char *cpath;
5d6308a
+				struct stat st;
5d6308a
+				int i = -1;
5d6308a
+				cpath = selinux_file_context_path();
5d6308a
+				if ((cpath == NULL) ||
5d6308a
+				    ((i = stat(cpath, &st)) != 0) ||
5d6308a
+				    (st.st_mtime != selabel_last_changed)) {
Nalin Dahyabhai cf693a2
+					if (selabel_ctx != NULL) {
Nalin Dahyabhai cf693a2
+						selabel_close(selabel_ctx);
Nalin Dahyabhai cf693a2
+						selabel_ctx = NULL;
Nalin Dahyabhai cf693a2
+					}
5d6308a
+					selabel_last_changed = i ?
5d6308a
+							       time(NULL) :
5d6308a
+							       st.st_mtime;
5d6308a
+				}
5d6308a
+			}
5d6308a
+			if (selabel_ctx == NULL) {
5d6308a
+				selabel_ctx = selabel_open(SELABEL_CTX_FILE,
5d6308a
+							   NULL, 0);
5d6308a
+			}
5d6308a
+			if (selabel_ctx != NULL) {
5d6308a
+				if (selabel_lookup(selabel_ctx, &configuredsc,
3f291ca
+						   fullpath, mode) != 0) {
3f291ca
+					free(genpath);
3f291ca
+					if (previous != NULL) {
3f291ca
+						freecon(previous);
3f291ca
+					}
3f291ca
+					return NULL;
55c161b
+				}
55c161b
+			}
c6f29fd
+#else
61f3185
+			if (matchpathcon(fullpath, mode, &configuredsc) != 0) {
c6f29fd
+				free(genpath);
c6f29fd
+				if (previous != NULL) {
c6f29fd
+					freecon(previous);
c6f29fd
+				}
c6f29fd
+				return NULL;
c6f29fd
+			}
c6f29fd
+#endif
55c161b
+			free(genpath);
ca17214
+			if (configuredsc == NULL) {
ca17214
+				if (previous != NULL) {
ca17214
+					freecon(previous);
ca17214
+				}
ca17214
+				return NULL;
ca17214
+			}
61f3185
+			currentsc = NULL;
61f3185
+			getcon(&currentsc);
61f3185
+			if (currentsc != NULL) {
61f3185
+				derived = context_new(configuredsc);
61f3185
+				if (derived != NULL) {
61f3185
+					current = context_new(currentsc);
61f3185
+					if (current != NULL) {
61f3185
+						currentuser = context_user_get(current);
61f3185
+						if (currentuser != NULL) {
61f3185
+							if (context_user_set(derived,
61f3185
+									     currentuser) == 0) {
16a5c7a
+								derivedsc = context_str(derived);
16a5c7a
+								if (derivedsc != NULL) {
16a5c7a
+									freecon(configuredsc);
16a5c7a
+									configuredsc = strdup(derivedsc);
61f3185
+								}
61f3185
+							}
61f3185
+						}
61f3185
+						context_free(current);
61f3185
+					}
61f3185
+					context_free(derived);
61f3185
+				}
61f3185
+				freecon(currentsc);
61f3185
+			}
55c161b
+#ifdef DEBUG
55c161b
+			if (isatty(fileno(stderr))) {
55c161b
+				fprintf(stderr, "Setting file creation context "
9fed313
+					"to \"%s\".\n", configuredsc);
55c161b
+			}
55c161b
+#endif
61f3185
+			if (setfscreatecon(configuredsc) != 0) {
61f3185
+				freecon(configuredsc);
55c161b
+				if (previous != NULL) {
55c161b
+					freecon(previous);
55c161b
+				}
55c161b
+				return NULL;
55c161b
+			}
61f3185
+			freecon(configuredsc);
55c161b
+#ifdef DEBUG
55c161b
+		} else {
55c161b
+			if (isatty(fileno(stderr))) {
55c161b
+				fprintf(stderr, "Unable to determine "
55c161b
+					"current context.\n");
55c161b
+			}
55c161b
+#endif
55c161b
+		}
55c161b
+	}
55c161b
+	return previous;
55c161b
+}
55c161b
+
55c161b
+static void
55c161b
+pop_fscreatecon(security_context_t previous)
55c161b
+{
55c161b
+	if (is_selinux_enabled()) {
55c161b
+#ifdef DEBUG
55c161b
+		if (isatty(fileno(stderr))) {
55c161b
+			if (previous != NULL) {
55c161b
+				fprintf(stderr, "Resetting file creation "
55c161b
+					"context to \"%s\".\n", previous);
55c161b
+			} else {
55c161b
+				fprintf(stderr, "Resetting file creation "
55c161b
+					"context to default.\n");
55c161b
+			}
55c161b
+		}
55c161b
+#endif
55c161b
+		setfscreatecon(previous);
55c161b
+		if (previous != NULL) {
55c161b
+			freecon(previous);
55c161b
+		}
55c161b
+	}
55c161b
+}
55c161b
+
6a7a118
+void *
6a7a118
+krb5int_push_fscreatecon_for(const char *pathname)
6a7a118
+{
6a7a118
+	struct stat st;
Nalin Dahyabhai efdfc3a
+	void *retval;
Nalin Dahyabhai efdfc3a
+	k5_once(&labeled_once, label_mutex_init);
Nalin Dahyabhai efdfc3a
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
Nalin Dahyabhai efdfc3a
+		if (stat(pathname, &st) != 0) {
Nalin Dahyabhai efdfc3a
+			st.st_mode = S_IRUSR | S_IWUSR;
Nalin Dahyabhai efdfc3a
+		}
Nalin Dahyabhai efdfc3a
+		retval = push_fscreatecon(pathname, st.st_mode);
Nalin Dahyabhai efdfc3a
+		return retval ? retval : (void *) -1;
Nalin Dahyabhai efdfc3a
+	} else {
Nalin Dahyabhai efdfc3a
+		return NULL;
6a7a118
+	}
6a7a118
+}
6a7a118
+
6a7a118
+void
6a7a118
+krb5int_pop_fscreatecon(void *con)
6a7a118
+{
Nalin Dahyabhai efdfc3a
+	if (con != NULL) {
Nalin Dahyabhai 635a422
+		pop_fscreatecon((con == (void *) -1) ? NULL : con);
Nalin Dahyabhai efdfc3a
+		k5_mutex_unlock(&labeled_mutex);
Nalin Dahyabhai efdfc3a
+	}
6a7a118
+}
6a7a118
+
55c161b
+FILE *
55c161b
+krb5int_labeled_fopen(const char *path, const char *mode)
55c161b
+{
55c161b
+	FILE *fp;
55c161b
+	int errno_save;
55c161b
+	security_context_t ctx;
55c161b
+
Nalin Dahyabhai cd92a2c
+	if ((strcmp(mode, "r") == 0) ||
Nalin Dahyabhai cd92a2c
+	    (strcmp(mode, "rb") == 0)) {
55c161b
+		return fopen(path, mode);
55c161b
+	}
55c161b
+
55c161b
+	k5_once(&labeled_once, label_mutex_init);
3f291ca
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
3f291ca
+		ctx = push_fscreatecon(path, 0);
3f291ca
+		fp = fopen(path, mode);
3f291ca
+		errno_save = errno;
3f291ca
+		pop_fscreatecon(ctx);
3f291ca
+		k5_mutex_unlock(&labeled_mutex);
3f291ca
+		errno = errno_save;
3f291ca
+	} else {
3f291ca
+		fp = fopen(path, mode);
3f291ca
+	}
3f291ca
+
55c161b
+	return fp;
55c161b
+}
55c161b
+
55c161b
+int
55c161b
+krb5int_labeled_creat(const char *path, mode_t mode)
55c161b
+{
55c161b
+	int fd;
55c161b
+	int errno_save;
55c161b
+	security_context_t ctx;
55c161b
+
55c161b
+	k5_once(&labeled_once, label_mutex_init);
3f291ca
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
3f291ca
+		ctx = push_fscreatecon(path, 0);
3f291ca
+		fd = creat(path, mode);
3f291ca
+		errno_save = errno;
3f291ca
+		pop_fscreatecon(ctx);
3f291ca
+		k5_mutex_unlock(&labeled_mutex);
3f291ca
+		errno = errno_save;
3f291ca
+	} else {
3f291ca
+		fd = creat(path, mode);
3f291ca
+	}
55c161b
+	return fd;
55c161b
+}
55c161b
+
55c161b
+int
55c161b
+krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev)
55c161b
+{
55c161b
+	int ret;
55c161b
+	int errno_save;
55c161b
+	security_context_t ctx;
55c161b
+
55c161b
+	k5_once(&labeled_once, label_mutex_init);
3f291ca
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
3f291ca
+		ctx = push_fscreatecon(path, mode);
3f291ca
+		ret = mknod(path, mode, dev);
3f291ca
+		errno_save = errno;
3f291ca
+		pop_fscreatecon(ctx);
3f291ca
+		k5_mutex_unlock(&labeled_mutex);
3f291ca
+		errno = errno_save;
3f291ca
+	} else {
3f291ca
+		ret = mknod(path, mode, dev);
3f291ca
+	}
55c161b
+	return ret;
55c161b
+}
55c161b
+
55c161b
+int
55c161b
+krb5int_labeled_mkdir(const char *path, mode_t mode)
55c161b
+{
55c161b
+	int ret;
55c161b
+	int errno_save;
55c161b
+	security_context_t ctx;
55c161b
+
55c161b
+	k5_once(&labeled_once, label_mutex_init);
3f291ca
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
3f291ca
+		ctx = push_fscreatecon(path, S_IFDIR);
3f291ca
+		ret = mkdir(path, mode);
3f291ca
+		errno_save = errno;
3f291ca
+		pop_fscreatecon(ctx);
3f291ca
+		k5_mutex_unlock(&labeled_mutex);
3f291ca
+		errno = errno_save;
3f291ca
+	} else {
3f291ca
+		ret = mkdir(path, mode);
3f291ca
+	}
55c161b
+	return ret;
55c161b
+}
55c161b
+
55c161b
+int
55c161b
+krb5int_labeled_open(const char *path, int flags, ...)
55c161b
+{
55c161b
+	int fd;
55c161b
+	int errno_save;
55c161b
+	security_context_t ctx;
55c161b
+	mode_t mode;
55c161b
+	va_list ap;
55c161b
+
55c161b
+	if ((flags & O_CREAT) == 0) {
55c161b
+		return open(path, flags);
55c161b
+	}
55c161b
+
55c161b
+	k5_once(&labeled_once, label_mutex_init);
3f291ca
+	if (k5_mutex_lock(&labeled_mutex) == 0) {
3f291ca
+		ctx = push_fscreatecon(path, 0);
3f291ca
+
3f291ca
+		va_start(ap, flags);
3f291ca
+		mode = va_arg(ap, mode_t);
3f291ca
+		fd = open(path, flags, mode);
3f291ca
+		va_end(ap);
3f291ca
+
3f291ca
+		errno_save = errno;
3f291ca
+		pop_fscreatecon(ctx);
3f291ca
+		k5_mutex_unlock(&labeled_mutex);
3f291ca
+		errno = errno_save;
3f291ca
+	} else {
3f291ca
+		va_start(ap, flags);
3f291ca
+		mode = va_arg(ap, mode_t);
3f291ca
+		fd = open(path, flags, mode);
3f291ca
+		errno_save = errno;
3f291ca
+		va_end(ap);
3f291ca
+		errno = errno_save;
3f291ca
+	}
55c161b
+	return fd;
55c161b
+}
55c161b
+
55c161b
+#endif
Nalin Dahyabhai efdfc3a
--- krb5/src/lib/krb5/rcache/rc_dfl.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/lib/krb5/rcache/rc_dfl.c
6a7a118
@@ -813,6 +813,9 @@ krb5_rc_dfl_expunge_locked(krb5_context 
6a7a118
     krb5_error_code retval = 0;
6a7a118
     krb5_rcache tmp;
6a7a118
     krb5_deltat lifespan = t->lifespan;  /* save original lifespan */
6a7a118
+#ifdef USE_SELINUX
6a7a118
+    void *selabel;
6a7a118
+#endif
6a7a118
 
6a7a118
     if (! t->recovering) {
6a7a118
         name = t->name;
6a7a118
@@ -834,7 +837,17 @@ krb5_rc_dfl_expunge_locked(krb5_context 
6a7a118
     retval = krb5_rc_resolve(context, tmp, 0);
6a7a118
     if (retval)
6a7a118
         goto cleanup;
6a7a118
+#ifdef USE_SELINUX
6a7a118
+    if (t->d.fn != NULL)
6a7a118
+        selabel = krb5int_push_fscreatecon_for(t->d.fn);
6a7a118
+    else
6a7a118
+        selabel = NULL;
6a7a118
+#endif
6a7a118
     retval = krb5_rc_initialize(context, tmp, lifespan);
6a7a118
+#ifdef USE_SELINUX
6a7a118
+    if (selabel != NULL)
6a7a118
+        krb5int_pop_fscreatecon(selabel);
6a7a118
+#endif
6a7a118
     if (retval)
6a7a118
         goto cleanup;
6a7a118
     for (q = t->a; q; q = q->na) {
8a943cb
--- krb5/src/lib/krb5/ccache/cc_dir.c
8a943cb
+++ krb5/src/lib/krb5/ccache/cc_dir.c
8a943cb
@@ -185,10 +185,19 @@ write_primary_file(const char *primary_p
8a943cb
     char *newpath = NULL;
8a943cb
     FILE *fp = NULL;
8a943cb
     int fd = -1, status;
8a943cb
+#ifdef USE_SELINUX
8a943cb
+    void *selabel;
8a943cb
+#endif
8a943cb
 
8a943cb
     if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0)
8a943cb
         return ENOMEM;
8a943cb
+#ifdef USE_SELINUX
8a943cb
+    selabel = krb5int_push_fscreatecon_for(primary_path);
8a943cb
+#endif
8a943cb
     fd = mkstemp(newpath);
8a943cb
+#ifdef USE_SELINUX
8a943cb
+    krb5int_pop_fscreatecon(selabel);
8a943cb
+#endif
8a943cb
     if (fd < 0)
8a943cb
         goto cleanup;
8a943cb
 #ifdef HAVE_CHMOD
Nalin Dahyabhai 559c78a
@@ -223,10 +232,23 @@
Nalin Dahyabhai 559c78a
 verify_dir(krb5_context context, const char *dirname)
Nalin Dahyabhai 559c78a
 {
Nalin Dahyabhai 559c78a
     struct stat st;
Nalin Dahyabhai 559c78a
+    int status;
Nalin Dahyabhai 559c78a
+#ifdef USE_SELINUX
Nalin Dahyabhai 559c78a
+    void *selabel;
Nalin Dahyabhai 559c78a
+#endif
Nalin Dahyabhai 559c78a
 
Nalin Dahyabhai 559c78a
     if (stat(dirname, &st) < 0) {
Nalin Dahyabhai 559c78a
-        if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0)
Nalin Dahyabhai 559c78a
-            return 0;
Nalin Dahyabhai 559c78a
+        if (errno == ENOENT) {
Nalin Dahyabhai 559c78a
+#ifdef USE_SELINUX
Nalin Dahyabhai 559c78a
+            selabel = krb5int_push_fscreatecon_for(dirname);
Nalin Dahyabhai 559c78a
+#endif
Nalin Dahyabhai 559c78a
+            status = mkdir(dirname, S_IRWXU);
Nalin Dahyabhai 559c78a
+#ifdef USE_SELINUX
Nalin Dahyabhai 559c78a
+            krb5int_pop_fscreatecon(selabel);
Nalin Dahyabhai 559c78a
+#endif
Nalin Dahyabhai 559c78a
+            if (status == 0)
Nalin Dahyabhai 559c78a
+                return 0;
Nalin Dahyabhai 559c78a
+        }
Nalin Dahyabhai 559c78a
         krb5_set_error_message(context, KRB5_FCC_NOFILE,
Nalin Dahyabhai 559c78a
                                _("Credential cache directory %s does not "
Nalin Dahyabhai 559c78a
                                  "exist"), dirname);
8a943cb
--- krb5/src/lib/krb5/os/trace.c
8a943cb
+++ krb5/src/lib/krb5/os/trace.c
8a943cb
@@ -401,7 +401,7 @@ krb5_set_trace_filename(krb5_context con
8a943cb
     fd = malloc(sizeof(*fd));
8a943cb
     if (fd == NULL)
8a943cb
         return ENOMEM;
8a943cb
-    *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
8a943cb
+    *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600);
8a943cb
     if (*fd == -1) {
8a943cb
         free(fd);
8a943cb
         return errno;
Nalin Dahyabhai efdfc3a
--- krb5/src/plugins/kdb/db2/kdb_db2.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/plugins/kdb/db2/kdb_db2.c
Nalin Dahyabhai efdfc3a
@@ -683,8 +683,8 @@
Nalin Dahyabhai efdfc3a
     if (retval)
Nalin Dahyabhai efdfc3a
         return retval;
Nalin Dahyabhai efdfc3a
 
Nalin Dahyabhai efdfc3a
-    dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC,
Nalin Dahyabhai efdfc3a
-                           0600);
Nalin Dahyabhai efdfc3a
+    dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name,
Nalin Dahyabhai efdfc3a
+                                     O_CREAT | O_RDWR | O_TRUNC, 0600);
Nalin Dahyabhai efdfc3a
     if (dbc->db_lf_file < 0) {
Nalin Dahyabhai efdfc3a
         retval = errno;
Nalin Dahyabhai efdfc3a
         goto cleanup;
Nalin Dahyabhai efdfc3a
--- krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
Nalin Dahyabhai efdfc3a
@@ -51,6 +51,7 @@
Nalin Dahyabhai efdfc3a
 #include <stdio.h>
Nalin Dahyabhai efdfc3a
 #include <unistd.h>
Nalin Dahyabhai efdfc3a
 
Nalin Dahyabhai efdfc3a
+#include "k5-int.h"
Nalin Dahyabhai efdfc3a
 #include "db-int.h"
Nalin Dahyabhai efdfc3a
 #include "recno.h"
Nalin Dahyabhai efdfc3a
 
Nalin Dahyabhai efdfc3a
@@ -68,7 +69,8 @@
Nalin Dahyabhai efdfc3a
 	int rfd = -1, sverrno;
Nalin Dahyabhai efdfc3a
 
Nalin Dahyabhai efdfc3a
 	/* Open the user's file -- if this fails, we're done. */
Nalin Dahyabhai efdfc3a
-	if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0)
Nalin Dahyabhai efdfc3a
+	if (fname != NULL &&
Nalin Dahyabhai efdfc3a
+            (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
Nalin Dahyabhai efdfc3a
 		return (NULL);
Nalin Dahyabhai efdfc3a
 
Nalin Dahyabhai efdfc3a
 	if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
Nalin Dahyabhai efdfc3a
--- krb5/src/kdc/main.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/kdc/main.c
Nalin Dahyabhai efdfc3a
@@ -905,7 +905,7 @@ write_pid_file(const char *path)
Nalin Dahyabhai efdfc3a
     FILE *file;
Nalin Dahyabhai efdfc3a
     unsigned long pid;
Nalin Dahyabhai efdfc3a
 
Nalin Dahyabhai efdfc3a
-    file = fopen(path, "w");
Nalin Dahyabhai efdfc3a
+    file = WRITABLEFOPEN(path, "w");
Nalin Dahyabhai efdfc3a
     if (file == NULL)
Nalin Dahyabhai efdfc3a
         return errno;
Nalin Dahyabhai efdfc3a
     pid = (unsigned long) getpid();
Nalin Dahyabhai efdfc3a
--- krb5/src/lib/kdb/kdb_log.c
Nalin Dahyabhai efdfc3a
+++ krb5/src/lib/kdb/kdb_log.c
Nalin Dahyabhai efdfc3a
@@ -566,7 +566,7 @@ ulog_map(krb5_context context, const cha
Nalin Dahyabhai efdfc3a
             return (errno);
Nalin Dahyabhai efdfc3a
         }
Nalin Dahyabhai efdfc3a
 
8a943cb
-        ulogfd = open(logname, O_RDWR | O_CREAT, 0600);
8a943cb
+        ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600);
8a943cb
         if (ulogfd == -1) {
Nalin Dahyabhai efdfc3a
             return (errno);
Nalin Dahyabhai efdfc3a
         }
Nalin Dahyabhai a8e279c
--- krb5/src/util/gss-kernel-lib/Makefile.in
Nalin Dahyabhai a8e279c
+++ krb5/src/util/gss-kernel-lib/Makefile.in
Nalin Dahyabhai a8e279c
@@ -60,6 +60,7 @@ HEADERS= \
Nalin Dahyabhai a8e279c
 	gssapi_err_generic.h \
Nalin Dahyabhai a8e279c
 	k5-int.h \
Nalin Dahyabhai a8e279c
 	k5-int-pkinit.h \
Nalin Dahyabhai a8e279c
+	k5-label.h \
Nalin Dahyabhai a8e279c
 	k5-thread.h \
Nalin Dahyabhai a8e279c
 	k5-platform.h \
Nalin Dahyabhai a8e279c
 	k5-buf.h \
Nalin Dahyabhai a8e279c
@@ -166,10 +167,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_
Nalin Dahyabhai a8e279c
 	$(CP) $(GSS_GENERIC)/gssapi_generic.h $@
Nalin Dahyabhai a8e279c
 gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h
Nalin Dahyabhai a8e279c
 	$(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@
Nalin Dahyabhai a8e279c
-k5-int.h: $(INCLUDE)/k5-int.h
Nalin Dahyabhai a8e279c
+k5-int.h: $(INCLUDE)/k5-int.h k5-label.h
Nalin Dahyabhai a8e279c
 	$(CP) $(INCLUDE)/k5-int.h $@
Nalin Dahyabhai a8e279c
 k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h
Nalin Dahyabhai a8e279c
 	$(CP) $(INCLUDE)/k5-int-pkinit.h $@
Nalin Dahyabhai a8e279c
+k5-label.h: $(INCLUDE)/k5-label.h
Nalin Dahyabhai a8e279c
+	$(CP) $(INCLUDE)/k5-label.h $@
Nalin Dahyabhai a8e279c
 k5-thread.h: $(INCLUDE)/k5-thread.h
Nalin Dahyabhai a8e279c
 	$(CP) $(INCLUDE)/k5-thread.h $@
Nalin Dahyabhai a8e279c
 k5-platform.h: $(INCLUDE)/k5-platform.h