diff options
author | Patrick J Volkerding <volkerdi@slackware.com> | 2020-01-21 21:23:01 +0000 |
---|---|---|
committer | Eric Hameleers <alien@slackware.com> | 2020-01-21 23:32:58 +0100 |
commit | f6348b0bc1f332196f8a8c73fa6ba48ee3cb9310 (patch) | |
tree | acd350c3910603b17ce1ba77027df00a4e761eb4 /source/n/krb5/patches | |
parent | ad9f88ee031d17270554ccca814496cf55f25bc5 (diff) | |
download | current-f6348b0bc1f332196f8a8c73fa6ba48ee3cb9310.tar.gz |
Tue Jan 21 21:23:01 UTC 202020200121212301
a/aaa_elflibs-15.0-x86_64-19.txz: Rebuilt.
Upgraded: libcap.so.2.31, libgmp.so.10.4.0, libgmpxx.so.4.6.0.
Added: libgssapi_krb5.so.2.2, libk5crypto.so.3.1, libkrb5.so.3.3,
libkrb5support.so.0.1.
a/util-linux-2.35-x86_64-1.txz: Upgraded.
d/python-pip-20.0.1-x86_64-1.txz: Upgraded.
l/Mako-1.1.1-x86_64-1.txz: Upgraded.
l/keyutils-1.6.1-x86_64-1.txz: Upgraded.
n/krb5-1.17-x86_64-1.txz: Added.
Nothing links to this yet, but we'll need it soon enough. :-)
n/php-7.4.2-x86_64-1.txz: Upgraded.
This update fixes bugs and security issues:
Standard: OOB read in php_strip_tags_ex
Mbstring: global buffer-overflow in 'mbfl_filt_conv_big5_wchar'
For more information, see:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7059
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7060
(* Security fix *)
n/samba-4.11.5-x86_64-1.txz: Upgraded.
This update fixes the following security issues:
Replication of ACLs set to inherit down a subtree on AD Directory
not automatic.
Crash after failed character conversion at log level 3 or above.
Use after free during DNS zone scavenging in Samba AD DC.
For more information, see:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14902
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14907
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19344
(* Security fix *)
xap/gparted-1.1.0-x86_64-1.txz: Upgraded.
Diffstat (limited to 'source/n/krb5/patches')
-rw-r--r-- | source/n/krb5/patches/Build-with-Werror-implicit-int-where-supported.patch | 23 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.11-kpasswdtest.patch | 21 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.11-run_user_0.patch | 44 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.12-api.patch | 37 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.12-ksu-path.patch | 22 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.12-ktany.patch | 366 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.12.1-pam.patch | 770 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.13-dirsrv-accountlock.patch | 75 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.15-beta1-buildconf.patch | 70 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.15-beta1-selinux-label.patch | 1065 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.3.1-dns.patch | 22 | ||||
-rw-r--r-- | source/n/krb5/patches/krb5-1.9-debuginfo.patch | 39 |
12 files changed, 2554 insertions, 0 deletions
diff --git a/source/n/krb5/patches/Build-with-Werror-implicit-int-where-supported.patch b/source/n/krb5/patches/Build-with-Werror-implicit-int-where-supported.patch new file mode 100644 index 00000000..4244dcee --- /dev/null +++ b/source/n/krb5/patches/Build-with-Werror-implicit-int-where-supported.patch @@ -0,0 +1,23 @@ +From 6c5c66b807cabaf71a56d1a630ea3b47344f81b4 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Thu, 10 Nov 2016 13:20:49 -0500 +Subject: [PATCH] Build with -Werror-implicit-int where supported + +(cherry picked from commit 873d864230c9c64c65ff12a24199bac3adf3bc2f) +--- + src/aclocal.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 2bfb994..da1d6d8 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -529,7 +529,7 @@ if test "$GCC" = yes ; then + TRY_WARN_CC_FLAG(-Wno-format-zero-length) + # Other flags here may not be supported on some versions of + # gcc that people want to use. +- for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers ; do ++ for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers error=implicit-int ; do + TRY_WARN_CC_FLAG(-W$flag) + done + # old-style-definition? generates many, many warnings diff --git a/source/n/krb5/patches/krb5-1.11-kpasswdtest.patch b/source/n/krb5/patches/krb5-1.11-kpasswdtest.patch new file mode 100644 index 00000000..8419cdf2 --- /dev/null +++ b/source/n/krb5/patches/krb5-1.11-kpasswdtest.patch @@ -0,0 +1,21 @@ +From 0fb88f451f25c4bf923248c9e13dd79f658c743a Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:52:01 -0400 +Subject: [PATCH] krb5-1.11-kpasswdtest.patch + +--- + src/kadmin/testing/proto/krb5.conf.proto | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto +index 00c4429..9c4bc1d 100644 +--- a/src/kadmin/testing/proto/krb5.conf.proto ++++ b/src/kadmin/testing/proto/krb5.conf.proto +@@ -9,6 +9,7 @@ + __REALM__ = { + kdc = __KDCHOST__:1750 + admin_server = __KDCHOST__:1751 ++ kpasswd_server = __KDCHOST__:1752 + database_module = foobar_db2_module_blah + } + diff --git a/source/n/krb5/patches/krb5-1.11-run_user_0.patch b/source/n/krb5/patches/krb5-1.11-run_user_0.patch new file mode 100644 index 00000000..10af564b --- /dev/null +++ b/source/n/krb5/patches/krb5-1.11-run_user_0.patch @@ -0,0 +1,44 @@ +From 308f3826d44ab9ee114fc7d1c4fb61e9005025ad Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:49:57 -0400 +Subject: [PATCH] krb5-1.11-run_user_0.patch + +A hack: if we're looking at creating a ccache directory directly below +the /run/user/0 directory, and /run/user/0 doesn't exist, try to create +it, too. +--- + src/lib/krb5/ccache/cc_dir.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c +index 73f0fe6..4850c0d 100644 +--- a/src/lib/krb5/ccache/cc_dir.c ++++ b/src/lib/krb5/ccache/cc_dir.c +@@ -61,6 +61,8 @@ + + #include <dirent.h> + ++#define ROOT_SPECIAL_DCC_PARENT "/run/user/0" ++ + extern const krb5_cc_ops krb5_dcc_ops; + extern const krb5_cc_ops krb5_fcc_ops; + +@@ -237,6 +239,18 @@ verify_dir(krb5_context context, const char *dirname) + + if (stat(dirname, &st) < 0) { + if (errno == ENOENT) { ++ if (strncmp(dirname, ROOT_SPECIAL_DCC_PARENT "/", ++ sizeof(ROOT_SPECIAL_DCC_PARENT)) == 0 && ++ stat(ROOT_SPECIAL_DCC_PARENT, &st) < 0 && ++ errno == ENOENT) { ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(ROOT_SPECIAL_DCC_PARENT); ++#endif ++ status = mkdir(ROOT_SPECIAL_DCC_PARENT, S_IRWXU); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif ++ } + #ifdef USE_SELINUX + selabel = krb5int_push_fscreatecon_for(dirname); + #endif diff --git a/source/n/krb5/patches/krb5-1.12-api.patch b/source/n/krb5/patches/krb5-1.12-api.patch new file mode 100644 index 00000000..3bf695e7 --- /dev/null +++ b/source/n/krb5/patches/krb5-1.12-api.patch @@ -0,0 +1,37 @@ +From e08681c1315628c8202d103de09325ed4881d1a5 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:47:00 -0400 +Subject: [PATCH] krb5-1.12-api.patch + +Reference docs don't define what happens if you call krb5_realm_compare() with +malformed krb5_principal structures. Define a behavior which keeps it from +crashing if applications don't check ahead of time. +--- + src/lib/krb5/krb/princ_comp.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/lib/krb5/krb/princ_comp.c b/src/lib/krb5/krb/princ_comp.c +index a693610..0ed7883 100644 +--- a/src/lib/krb5/krb/princ_comp.c ++++ b/src/lib/krb5/krb/princ_comp.c +@@ -36,6 +36,10 @@ realm_compare_flags(krb5_context context, + const krb5_data *realm1 = &princ1->realm; + const krb5_data *realm2 = &princ2->realm; + ++ if (princ1 == NULL || princ2 == NULL) ++ return FALSE; ++ if (realm1 == NULL || realm2 == NULL) ++ return FALSE; + if (realm1->length != realm2->length) + return FALSE; + if (realm1->length == 0) +@@ -88,6 +92,9 @@ krb5_principal_compare_flags(krb5_context context, + krb5_principal upn2 = NULL; + krb5_boolean ret = FALSE; + ++ if (princ1 == NULL || princ2 == NULL) ++ return FALSE; ++ + if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) { + /* Treat UPNs as if they were real principals */ + if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) { diff --git a/source/n/krb5/patches/krb5-1.12-ksu-path.patch b/source/n/krb5/patches/krb5-1.12-ksu-path.patch new file mode 100644 index 00000000..a2ef1868 --- /dev/null +++ b/source/n/krb5/patches/krb5-1.12-ksu-path.patch @@ -0,0 +1,22 @@ +From 13918214c30b97aaef5d816a3d266be0ec13147e Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:32:09 -0400 +Subject: [PATCH] krb5-1.12-ksu-path.patch + +Set the default PATH to the one set by login. +--- + src/clients/ksu/Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in +index 5755bb5..9d58f29 100644 +--- a/src/clients/ksu/Makefile.in ++++ b/src/clients/ksu/Makefile.in +@@ -1,6 +1,6 @@ + mydir=clients$(S)ksu + BUILDTOP=$(REL)..$(S).. +-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"' ++DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"' + + KSU_LIBS=@KSU_LIBS@ + PAM_LIBS=@PAM_LIBS@ diff --git a/source/n/krb5/patches/krb5-1.12-ktany.patch b/source/n/krb5/patches/krb5-1.12-ktany.patch new file mode 100644 index 00000000..6bd6bd8a --- /dev/null +++ b/source/n/krb5/patches/krb5-1.12-ktany.patch @@ -0,0 +1,366 @@ +From e2f52b93c6a6257a76ac37d3c7d63ea3099dd89c Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:33:53 -0400 +Subject: [PATCH] krb5-1.12-ktany.patch + +Adds an "ANY" keytab type which is a list of other keytab locations to search +when searching for a specific entry. When iterated through, it only presents +the contents of the first keytab. +--- + src/lib/krb5/keytab/Makefile.in | 3 + + src/lib/krb5/keytab/kt_any.c | 292 ++++++++++++++++++++++++++++++++++++++++ + src/lib/krb5/keytab/ktbase.c | 7 +- + 3 files changed, 301 insertions(+), 1 deletion(-) + create mode 100644 src/lib/krb5/keytab/kt_any.c + +diff --git a/src/lib/krb5/keytab/Makefile.in b/src/lib/krb5/keytab/Makefile.in +index 2a8fceb..ffd179f 100644 +--- a/src/lib/krb5/keytab/Makefile.in ++++ b/src/lib/krb5/keytab/Makefile.in +@@ -12,6 +12,7 @@ STLIBOBJS= \ + ktfr_entry.o \ + ktremove.o \ + ktfns.o \ ++ kt_any.o \ + kt_file.o \ + kt_memory.o \ + kt_srvtab.o \ +@@ -24,6 +25,7 @@ OBJS= \ + $(OUTPRE)ktfr_entry.$(OBJEXT) \ + $(OUTPRE)ktremove.$(OBJEXT) \ + $(OUTPRE)ktfns.$(OBJEXT) \ ++ $(OUTPRE)kt_any.$(OBJEXT) \ + $(OUTPRE)kt_file.$(OBJEXT) \ + $(OUTPRE)kt_memory.$(OBJEXT) \ + $(OUTPRE)kt_srvtab.$(OBJEXT) \ +@@ -36,6 +38,7 @@ SRCS= \ + $(srcdir)/ktfr_entry.c \ + $(srcdir)/ktremove.c \ + $(srcdir)/ktfns.c \ ++ $(srcdir)/kt_any.c \ + $(srcdir)/kt_file.c \ + $(srcdir)/kt_memory.c \ + $(srcdir)/kt_srvtab.c \ +diff --git a/src/lib/krb5/keytab/kt_any.c b/src/lib/krb5/keytab/kt_any.c +new file mode 100644 +index 0000000..1b9b776 +--- /dev/null ++++ b/src/lib/krb5/keytab/kt_any.c +@@ -0,0 +1,292 @@ ++/* ++ * lib/krb5/keytab/kt_any.c ++ * ++ * Copyright 1998, 1999 by the Massachusetts Institute of Technology. ++ * All Rights Reserved. ++ * ++ * Export of this software from the United States of America may ++ * require a specific license from the United States Government. ++ * It is the responsibility of any person or organization contemplating ++ * export to obtain such a license before exporting. ++ * ++ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and ++ * distribute this software and its documentation for any purpose and ++ * without fee is hereby granted, provided that the above copyright ++ * notice appear in all copies and that both that copyright notice and ++ * this permission notice appear in supporting documentation, and that ++ * the name of M.I.T. not be used in advertising or publicity pertaining ++ * to distribution of the software without specific, written prior ++ * permission. M.I.T. makes no representations about the suitability of ++ * this software for any purpose. It is provided "as is" without express ++ * or implied warranty. ++ * ++ * ++ * krb5_kta_ops ++ */ ++ ++#include "k5-int.h" ++ ++typedef struct _krb5_ktany_data { ++ char *name; ++ krb5_keytab *choices; ++ int nchoices; ++} krb5_ktany_data; ++ ++typedef struct _krb5_ktany_cursor_data { ++ int which; ++ krb5_kt_cursor cursor; ++} krb5_ktany_cursor_data; ++ ++static krb5_error_code krb5_ktany_resolve ++ (krb5_context, ++ const char *, ++ krb5_keytab *); ++static krb5_error_code krb5_ktany_get_name ++ (krb5_context context, ++ krb5_keytab id, ++ char *name, ++ unsigned int len); ++static krb5_error_code krb5_ktany_close ++ (krb5_context context, ++ krb5_keytab id); ++static krb5_error_code krb5_ktany_get_entry ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_const_principal principal, ++ krb5_kvno kvno, ++ krb5_enctype enctype, ++ krb5_keytab_entry *entry); ++static krb5_error_code krb5_ktany_start_seq_get ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_kt_cursor *cursorp); ++static krb5_error_code krb5_ktany_next_entry ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_keytab_entry *entry, ++ krb5_kt_cursor *cursor); ++static krb5_error_code krb5_ktany_end_seq_get ++ (krb5_context context, ++ krb5_keytab id, ++ krb5_kt_cursor *cursor); ++static void cleanup ++ (krb5_context context, ++ krb5_ktany_data *data, ++ int nchoices); ++ ++struct _krb5_kt_ops krb5_kta_ops = { ++ 0, ++ "ANY", /* Prefix -- this string should not appear anywhere else! */ ++ krb5_ktany_resolve, ++ krb5_ktany_get_name, ++ krb5_ktany_close, ++ krb5_ktany_get_entry, ++ krb5_ktany_start_seq_get, ++ krb5_ktany_next_entry, ++ krb5_ktany_end_seq_get, ++ NULL, ++ NULL, ++ NULL, ++}; ++ ++static krb5_error_code ++krb5_ktany_resolve(context, name, id) ++ krb5_context context; ++ const char *name; ++ krb5_keytab *id; ++{ ++ const char *p, *q; ++ char *copy; ++ krb5_error_code kerror; ++ krb5_ktany_data *data; ++ int i; ++ ++ /* Allocate space for our data and remember a copy of the name. */ ++ if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL) ++ return(ENOMEM); ++ if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) { ++ free(data); ++ return(ENOMEM); ++ } ++ strcpy(data->name, name); ++ ++ /* Count the number of choices and allocate memory for them. */ ++ data->nchoices = 1; ++ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) ++ data->nchoices++; ++ if ((data->choices = (krb5_keytab *) ++ malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) { ++ free(data->name); ++ free(data); ++ return(ENOMEM); ++ } ++ ++ /* Resolve each of the choices. */ ++ i = 0; ++ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) { ++ /* Make a copy of the choice name so we can terminate it. */ ++ if ((copy = (char *)malloc(q - p + 1)) == NULL) { ++ cleanup(context, data, i); ++ return(ENOMEM); ++ } ++ memcpy(copy, p, q - p); ++ copy[q - p] = 0; ++ ++ /* Try resolving the choice name. */ ++ kerror = krb5_kt_resolve(context, copy, &data->choices[i]); ++ free(copy); ++ if (kerror) { ++ cleanup(context, data, i); ++ return(kerror); ++ } ++ i++; ++ } ++ if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) { ++ cleanup(context, data, i); ++ return(kerror); ++ } ++ ++ /* Allocate and fill in an ID for the caller. */ ++ if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) { ++ cleanup(context, data, i); ++ return(ENOMEM); ++ } ++ (*id)->ops = &krb5_kta_ops; ++ (*id)->data = (krb5_pointer)data; ++ (*id)->magic = KV5M_KEYTAB; ++ ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_get_name(context, id, name, len) ++ krb5_context context; ++ krb5_keytab id; ++ char *name; ++ unsigned int len; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ ++ if (len < strlen(data->name) + 1) ++ return(KRB5_KT_NAME_TOOLONG); ++ strcpy(name, data->name); ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_close(context, id) ++ krb5_context context; ++ krb5_keytab id; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ ++ cleanup(context, data, data->nchoices); ++ id->ops = 0; ++ free(id); ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_const_principal principal; ++ krb5_kvno kvno; ++ krb5_enctype enctype; ++ krb5_keytab_entry *entry; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_error_code kerror = KRB5_KT_NOTFOUND; ++ int i; ++ ++ for (i = 0; i < data->nchoices; i++) { ++ if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal, ++ kvno, enctype, entry)) != ENOENT) ++ return kerror; ++ } ++ return kerror; ++} ++ ++static krb5_error_code ++krb5_ktany_start_seq_get(context, id, cursorp) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_kt_cursor *cursorp; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_ktany_cursor_data *cdata; ++ krb5_error_code kerror = ENOENT; ++ int i; ++ ++ if ((cdata = (krb5_ktany_cursor_data *) ++ malloc(sizeof(krb5_ktany_cursor_data))) == NULL) ++ return(ENOMEM); ++ ++ /* Find a choice which can handle the serialization request. */ ++ for (i = 0; i < data->nchoices; i++) { ++ if ((kerror = krb5_kt_start_seq_get(context, data->choices[i], ++ &cdata->cursor)) == 0) ++ break; ++ else if (kerror != ENOENT) { ++ free(cdata); ++ return(kerror); ++ } ++ } ++ ++ if (i == data->nchoices) { ++ /* Everyone returned ENOENT, so no go. */ ++ free(cdata); ++ return(kerror); ++ } ++ ++ cdata->which = i; ++ *cursorp = (krb5_kt_cursor)cdata; ++ return(0); ++} ++ ++static krb5_error_code ++krb5_ktany_next_entry(context, id, entry, cursor) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_keytab_entry *entry; ++ krb5_kt_cursor *cursor; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; ++ krb5_keytab choice_id; ++ ++ choice_id = data->choices[cdata->which]; ++ return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor)); ++} ++ ++static krb5_error_code ++krb5_ktany_end_seq_get(context, id, cursor) ++ krb5_context context; ++ krb5_keytab id; ++ krb5_kt_cursor *cursor; ++{ ++ krb5_ktany_data *data = (krb5_ktany_data *)id->data; ++ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; ++ krb5_keytab choice_id; ++ krb5_error_code kerror; ++ ++ choice_id = data->choices[cdata->which]; ++ kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor); ++ free(cdata); ++ return(kerror); ++} ++ ++static void ++cleanup(context, data, nchoices) ++ krb5_context context; ++ krb5_ktany_data *data; ++ int nchoices; ++{ ++ int i; ++ ++ free(data->name); ++ for (i = 0; i < nchoices; i++) ++ krb5_kt_close(context, data->choices[i]); ++ free(data->choices); ++ free(data); ++} +diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c +index 0d39b29..6534d7c 100644 +--- a/src/lib/krb5/keytab/ktbase.c ++++ b/src/lib/krb5/keytab/ktbase.c +@@ -57,14 +57,19 @@ extern const krb5_kt_ops krb5_ktf_ops; + extern const krb5_kt_ops krb5_ktf_writable_ops; + extern const krb5_kt_ops krb5_kts_ops; + extern const krb5_kt_ops krb5_mkt_ops; ++extern const krb5_kt_ops krb5_kta_ops; + + struct krb5_kt_typelist { + const krb5_kt_ops *ops; + const struct krb5_kt_typelist *next; + }; ++static struct krb5_kt_typelist krb5_kt_typelist_any = { ++ &krb5_kta_ops, ++ NULL ++}; + const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = { + &krb5_kts_ops, +- NULL ++ &krb5_kt_typelist_any + }; + const static struct krb5_kt_typelist krb5_kt_typelist_memory = { + &krb5_mkt_ops, diff --git a/source/n/krb5/patches/krb5-1.12.1-pam.patch b/source/n/krb5/patches/krb5-1.12.1-pam.patch new file mode 100644 index 00000000..17d29b0d --- /dev/null +++ b/source/n/krb5/patches/krb5-1.12.1-pam.patch @@ -0,0 +1,770 @@ +From 977d51ce9a5bb37255e87db37353f0d70d6b293d Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:29:58 -0400 +Subject: [PATCH] krb5-1.12.1-pam.patch + +Modify ksu so that it performs account and session management on behalf of +the target user account, mimicking the action of regular su. The default +service name is "ksu", because on Fedora at least the configuration used +is determined by whether or not a login shell is being opened, and so +this may need to vary, too. At run-time, ksu's behavior can be reset to +the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu] +section of /etc/krb5.conf. + +When enabled, ksu gains a dependency on libpam. + +Originally RT#5939, though it's changed since then to perform the account +and session management before dropping privileges, and to apply on top of +changes we're proposing for how it handles cache collections. +--- + src/aclocal.m4 | 67 ++++++++ + src/clients/ksu/Makefile.in | 8 +- + src/clients/ksu/main.c | 88 +++++++++- + src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++++++++++ + src/clients/ksu/pam.h | 57 +++++++ + src/configure.in | 2 + + 6 files changed, 608 insertions(+), 3 deletions(-) + create mode 100644 src/clients/ksu/pam.c + create mode 100644 src/clients/ksu/pam.h + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 9c46da4..508e5fe 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -1675,3 +1675,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[ + ])) + ])dnl + dnl ++dnl ++dnl Use PAM instead of local crypt() compare for checking local passwords, ++dnl and perform PAM account, session management, and password-changing where ++dnl appropriate. ++dnl ++AC_DEFUN(KRB5_WITH_PAM,[ ++AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])], ++ withpam="$withval",withpam=auto) ++AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])], ++ withksupamservice="$withval",withksupamservice=ksu) ++old_LIBS="$LIBS" ++if test "$withpam" != no ; then ++ AC_MSG_RESULT([checking for PAM...]) ++ PAM_LIBS= ++ ++ AC_CHECK_HEADERS(security/pam_appl.h) ++ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then ++ if test "$withpam" = auto ; then ++ AC_MSG_RESULT([Unable to locate security/pam_appl.h.]) ++ withpam=no ++ else ++ AC_MSG_ERROR([Unable to locate security/pam_appl.h.]) ++ fi ++ fi ++ ++ LIBS= ++ unset ac_cv_func_pam_start ++ AC_CHECK_FUNCS(putenv pam_start) ++ if test "x$ac_cv_func_pam_start" = xno ; then ++ unset ac_cv_func_pam_start ++ AC_CHECK_LIB(dl,dlopen) ++ AC_CHECK_FUNCS(pam_start) ++ if test "x$ac_cv_func_pam_start" = xno ; then ++ AC_CHECK_LIB(pam,pam_start) ++ unset ac_cv_func_pam_start ++ unset ac_cv_func_pam_getenvlist ++ AC_CHECK_FUNCS(pam_start pam_getenvlist) ++ if test "x$ac_cv_func_pam_start" = xyes ; then ++ PAM_LIBS="$LIBS" ++ else ++ if test "$withpam" = auto ; then ++ AC_MSG_RESULT([Unable to locate libpam.]) ++ withpam=no ++ else ++ AC_MSG_ERROR([Unable to locate libpam.]) ++ fi ++ fi ++ fi ++ fi ++ if test "$withpam" != no ; then ++ AC_MSG_NOTICE([building with PAM support]) ++ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM]) ++ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice", ++ [Define to the name of the PAM service name to be used by ksu.]) ++ PAM_LIBS="$LIBS" ++ NON_PAM_MAN=".\\\" " ++ PAM_MAN= ++ else ++ PAM_MAN=".\\\" " ++ NON_PAM_MAN= ++ fi ++fi ++LIBS="$old_LIBS" ++AC_SUBST(PAM_LIBS) ++AC_SUBST(PAM_MAN) ++AC_SUBST(NON_PAM_MAN) ++])dnl +diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in +index b2fcbf2..5755bb5 100644 +--- a/src/clients/ksu/Makefile.in ++++ b/src/clients/ksu/Makefile.in +@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S).. + DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"' + + KSU_LIBS=@KSU_LIBS@ ++PAM_LIBS=@PAM_LIBS@ + + SRCS = \ + $(srcdir)/krb_auth_su.c \ + $(srcdir)/ccache.c \ + $(srcdir)/authorization.c \ + $(srcdir)/main.c \ ++ $(srcdir)/pam.c \ + $(srcdir)/heuristic.c \ + $(srcdir)/xmalloc.c \ + $(srcdir)/setenv.c +@@ -17,13 +19,17 @@ OBJS = \ + ccache.o \ + authorization.o \ + main.o \ ++ pam.o \ + heuristic.o \ + xmalloc.o @SETENVOBJ@ + + all: ksu + + ksu: $(OBJS) $(KRB5_BASE_DEPLIBS) +- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) ++ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS) ++ ++pam.o: pam.c ++ $(CC) $(ALL_CFLAGS) -c $< + + clean: + $(RM) ksu +diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c +index 28342c2..cab0c18 100644 +--- a/src/clients/ksu/main.c ++++ b/src/clients/ksu/main.c +@@ -26,6 +26,7 @@ + * KSU was writen by: Ari Medvinsky, ari@isi.edu + */ + ++#include "autoconf.h" + #include "ksu.h" + #include "adm_proto.h" + #include <sys/types.h> +@@ -33,6 +34,10 @@ + #include <signal.h> + #include <grp.h> + ++#ifdef USE_PAM ++#include "pam.h" ++#endif ++ + /* globals */ + char * prog_name; + int auth_debug =0; +@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN]; + char k5users_path[MAXPATHLEN]; + char * gb_err = NULL; + int quiet = 0; ++int force_fork = 0; + /***********/ + + #define KS_TEMPORARY_CACHE "MEMORY:_ksu" +@@ -515,6 +521,23 @@ main (argc, argv) + prog_name,target_user,client_name, + source_user,ontty()); + ++#ifdef USE_PAM ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, ++ NULL, source_user, ++ ttyname(STDERR_FILENO)) != 0) { ++ fprintf(stderr, "Access denied for %s.\n", target_user); ++ exit(1); ++ } ++ if (appl_pam_requires_chauthtok()) { ++ fprintf(stderr, "Password change required for %s.\n", ++ target_user); ++ exit(1); ++ } ++ force_fork++; ++ } ++#endif ++ + /* Run authorization as target.*/ + if (krb5_seteuid(target_uid)) { + com_err(prog_name, errno, _("while switching to target for " +@@ -575,6 +598,24 @@ main (argc, argv) + + exit(1); + } ++#ifdef USE_PAM ++ } else { ++ /* we always do PAM account management, even for root */ ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, ++ NULL, source_user, ++ ttyname(STDERR_FILENO)) != 0) { ++ fprintf(stderr, "Access denied for %s.\n", target_user); ++ exit(1); ++ } ++ if (appl_pam_requires_chauthtok()) { ++ fprintf(stderr, "Password change required for %s.\n", ++ target_user); ++ exit(1); ++ } ++ force_fork++; ++ } ++#endif + } + + if( some_rest_copy){ +@@ -632,6 +673,30 @@ main (argc, argv) + exit(1); + } + ++#ifdef USE_PAM ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_session_open() != 0) { ++ fprintf(stderr, "Error opening session for %s.\n", target_user); ++ exit(1); ++ } ++#ifdef DEBUG ++ if (auth_debug){ ++ printf(" Opened PAM session.\n"); ++ } ++#endif ++ if (appl_pam_cred_init()) { ++ fprintf(stderr, "Error initializing credentials for %s.\n", ++ target_user); ++ exit(1); ++ } ++#ifdef DEBUG ++ if (auth_debug){ ++ printf(" Initialized PAM credentials.\n"); ++ } ++#endif ++ } ++#endif ++ + /* set permissions */ + if (setgid(target_pwd->pw_gid) < 0) { + perror("ksu: setgid"); +@@ -729,7 +794,7 @@ main (argc, argv) + fprintf(stderr, "program to be execed %s\n",params[0]); + } + +- if( keep_target_cache ) { ++ if( keep_target_cache && !force_fork ) { + execv(params[0], params); + com_err(prog_name, errno, _("while trying to execv %s"), params[0]); + sweep_up(ksu_context, cc_target); +@@ -759,16 +824,35 @@ main (argc, argv) + if (ret_pid == -1) { + com_err(prog_name, errno, _("while calling waitpid")); + } +- sweep_up(ksu_context, cc_target); ++ if( !keep_target_cache ) { ++ sweep_up(ksu_context, cc_target); ++ } + exit (statusp); + case -1: + com_err(prog_name, errno, _("while trying to fork.")); + sweep_up(ksu_context, cc_target); + exit (1); + case 0: ++#ifdef USE_PAM ++ if (appl_pam_enabled(ksu_context, "ksu")) { ++ if (appl_pam_setenv() != 0) { ++ fprintf(stderr, "Error setting up environment for %s.\n", ++ target_user); ++ exit (1); ++ } ++#ifdef DEBUG ++ if (auth_debug){ ++ printf(" Set up PAM environment.\n"); ++ } ++#endif ++ } ++#endif + execv(params[0], params); + com_err(prog_name, errno, _("while trying to execv %s"), + params[0]); ++ if( keep_target_cache ) { ++ sweep_up(ksu_context, cc_target); ++ } + exit (1); + } + } +diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c +new file mode 100644 +index 0000000..cbfe487 +--- /dev/null ++++ b/src/clients/ksu/pam.c +@@ -0,0 +1,389 @@ ++/* ++ * src/clients/ksu/pam.c ++ * ++ * Copyright 2007,2009,2010 Red Hat, Inc. ++ * ++ * All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * Neither the name of Red Hat, Inc. nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Convenience wrappers for using PAM. ++ */ ++ ++#include "autoconf.h" ++#ifdef USE_PAM ++#include <sys/types.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++#include "k5-int.h" ++#include "pam.h" ++ ++#ifndef MAXPWSIZE ++#define MAXPWSIZE 128 ++#endif ++ ++static int appl_pam_started; ++static pid_t appl_pam_starter = -1; ++static int appl_pam_session_opened; ++static int appl_pam_creds_initialized; ++static int appl_pam_pwchange_required; ++static pam_handle_t *appl_pamh; ++static struct pam_conv appl_pam_conv; ++static char *appl_pam_user; ++struct appl_pam_non_interactive_args { ++ const char *user; ++ const char *password; ++}; ++ ++int ++appl_pam_enabled(krb5_context context, const char *section) ++{ ++ int enabled = 1; ++ if ((context != NULL) && (context->profile != NULL)) { ++ if (profile_get_boolean(context->profile, ++ section, ++ USE_PAM_CONFIGURATION_KEYWORD, ++ NULL, ++ enabled, &enabled) != 0) { ++ enabled = 1; ++ } ++ } ++ return enabled; ++} ++ ++void ++appl_pam_cleanup(void) ++{ ++ if (getpid() != appl_pam_starter) { ++ return; ++ } ++#ifdef DEBUG ++ printf("Called to clean up PAM.\n"); ++#endif ++ if (appl_pam_creds_initialized) { ++#ifdef DEBUG ++ printf("Deleting PAM credentials.\n"); ++#endif ++ pam_setcred(appl_pamh, PAM_DELETE_CRED); ++ appl_pam_creds_initialized = 0; ++ } ++ if (appl_pam_session_opened) { ++#ifdef DEBUG ++ printf("Closing PAM session.\n"); ++#endif ++ pam_close_session(appl_pamh, 0); ++ appl_pam_session_opened = 0; ++ } ++ appl_pam_pwchange_required = 0; ++ if (appl_pam_started) { ++#ifdef DEBUG ++ printf("Shutting down PAM.\n"); ++#endif ++ pam_end(appl_pamh, 0); ++ appl_pam_started = 0; ++ appl_pam_starter = -1; ++ free(appl_pam_user); ++ appl_pam_user = NULL; ++ } ++} ++static int ++appl_pam_interactive_converse(int num_msg, const struct pam_message **msg, ++ struct pam_response **presp, void *appdata_ptr) ++{ ++ const struct pam_message *message; ++ struct pam_response *resp; ++ int i, code; ++ char *pwstring, pwbuf[MAXPWSIZE]; ++ unsigned int pwsize; ++ resp = malloc(sizeof(struct pam_response) * num_msg); ++ if (resp == NULL) { ++ return PAM_BUF_ERR; ++ } ++ memset(resp, 0, sizeof(struct pam_response) * num_msg); ++ code = PAM_SUCCESS; ++ for (i = 0; i < num_msg; i++) { ++ message = &(msg[0][i]); /* XXX */ ++ message = msg[i]; /* XXX */ ++ pwstring = NULL; ++ switch (message->msg_style) { ++ case PAM_TEXT_INFO: ++ case PAM_ERROR_MSG: ++ printf("[%s]\n", message->msg ? message->msg : ""); ++ fflush(stdout); ++ resp[i].resp = NULL; ++ resp[i].resp_retcode = PAM_SUCCESS; ++ break; ++ case PAM_PROMPT_ECHO_ON: ++ case PAM_PROMPT_ECHO_OFF: ++ if (message->msg_style == PAM_PROMPT_ECHO_ON) { ++ if (fgets(pwbuf, sizeof(pwbuf), ++ stdin) != NULL) { ++ pwbuf[strcspn(pwbuf, "\r\n")] = '\0'; ++ pwstring = pwbuf; ++ } ++ } else { ++ pwstring = getpass(message->msg ? ++ message->msg : ++ ""); ++ } ++ if ((pwstring != NULL) && (pwstring[0] != '\0')) { ++ pwsize = strlen(pwstring); ++ resp[i].resp = malloc(pwsize + 1); ++ if (resp[i].resp == NULL) { ++ resp[i].resp_retcode = PAM_BUF_ERR; ++ } else { ++ memcpy(resp[i].resp, pwstring, pwsize); ++ resp[i].resp[pwsize] = '\0'; ++ resp[i].resp_retcode = PAM_SUCCESS; ++ } ++ } else { ++ resp[i].resp_retcode = PAM_CONV_ERR; ++ code = PAM_CONV_ERR; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ *presp = resp; ++ return code; ++} ++static int ++appl_pam_non_interactive_converse(int num_msg, ++ const struct pam_message **msg, ++ struct pam_response **presp, ++ void *appdata_ptr) ++{ ++ const struct pam_message *message; ++ struct pam_response *resp; ++ int i, code; ++ unsigned int pwsize; ++ struct appl_pam_non_interactive_args *args; ++ const char *pwstring; ++ resp = malloc(sizeof(struct pam_response) * num_msg); ++ if (resp == NULL) { ++ return PAM_BUF_ERR; ++ } ++ args = appdata_ptr; ++ memset(resp, 0, sizeof(struct pam_response) * num_msg); ++ code = PAM_SUCCESS; ++ for (i = 0; i < num_msg; i++) { ++ message = &((*msg)[i]); ++ message = msg[i]; ++ pwstring = NULL; ++ switch (message->msg_style) { ++ case PAM_TEXT_INFO: ++ case PAM_ERROR_MSG: ++ break; ++ case PAM_PROMPT_ECHO_ON: ++ case PAM_PROMPT_ECHO_OFF: ++ if (message->msg_style == PAM_PROMPT_ECHO_ON) { ++ /* assume "user" */ ++ pwstring = args->user; ++ } else { ++ /* assume "password" */ ++ pwstring = args->password; ++ } ++ if ((pwstring != NULL) && (pwstring[0] != '\0')) { ++ pwsize = strlen(pwstring); ++ resp[i].resp = malloc(pwsize + 1); ++ if (resp[i].resp == NULL) { ++ resp[i].resp_retcode = PAM_BUF_ERR; ++ } else { ++ memcpy(resp[i].resp, pwstring, pwsize); ++ resp[i].resp[pwsize] = '\0'; ++ resp[i].resp_retcode = PAM_SUCCESS; ++ } ++ } else { ++ resp[i].resp_retcode = PAM_CONV_ERR; ++ code = PAM_CONV_ERR; ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ *presp = resp; ++ return code; ++} ++static int ++appl_pam_start(const char *service, int interactive, ++ const char *login_username, ++ const char *non_interactive_password, ++ const char *hostname, ++ const char *ruser, ++ const char *tty) ++{ ++ static int exit_handler_registered; ++ static struct appl_pam_non_interactive_args args; ++ int ret = 0; ++ if (appl_pam_started && ++ (strcmp(login_username, appl_pam_user) != 0)) { ++ appl_pam_cleanup(); ++ appl_pam_user = NULL; ++ } ++ if (!appl_pam_started) { ++#ifdef DEBUG ++ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n", ++ service, login_username); ++#endif ++ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv)); ++ appl_pam_conv.conv = interactive ? ++ &appl_pam_interactive_converse : ++ &appl_pam_non_interactive_converse; ++ memset(&args, 0, sizeof(args)); ++ args.user = strdup(login_username); ++ args.password = non_interactive_password ? ++ strdup(non_interactive_password) : ++ NULL; ++ appl_pam_conv.appdata_ptr = &args; ++ ret = pam_start(service, login_username, ++ &appl_pam_conv, &appl_pamh); ++ if (ret == 0) { ++ if (hostname != NULL) { ++#ifdef DEBUG ++ printf("Setting PAM_RHOST to \"%s\".\n", hostname); ++#endif ++ pam_set_item(appl_pamh, PAM_RHOST, hostname); ++ } ++ if (ruser != NULL) { ++#ifdef DEBUG ++ printf("Setting PAM_RUSER to \"%s\".\n", ruser); ++#endif ++ pam_set_item(appl_pamh, PAM_RUSER, ruser); ++ } ++ if (tty != NULL) { ++#ifdef DEBUG ++ printf("Setting PAM_TTY to \"%s\".\n", tty); ++#endif ++ pam_set_item(appl_pamh, PAM_TTY, tty); ++ } ++ if (!exit_handler_registered && ++ (atexit(appl_pam_cleanup) != 0)) { ++ pam_end(appl_pamh, 0); ++ appl_pamh = NULL; ++ ret = -1; ++ } else { ++ appl_pam_started = 1; ++ appl_pam_starter = getpid(); ++ appl_pam_user = strdup(login_username); ++ exit_handler_registered = 1; ++ } ++ } ++ } ++ return ret; ++} ++int ++appl_pam_acct_mgmt(const char *service, int interactive, ++ const char *login_username, ++ const char *non_interactive_password, ++ const char *hostname, ++ const char *ruser, ++ const char *tty) ++{ ++ int ret; ++ appl_pam_pwchange_required = 0; ++ ret = appl_pam_start(service, interactive, login_username, ++ non_interactive_password, hostname, ruser, tty); ++ if (ret == 0) { ++#ifdef DEBUG ++ printf("Calling pam_acct_mgmt().\n"); ++#endif ++ ret = pam_acct_mgmt(appl_pamh, 0); ++ switch (ret) { ++ case PAM_IGNORE: ++ ret = 0; ++ break; ++ case PAM_NEW_AUTHTOK_REQD: ++ appl_pam_pwchange_required = 1; ++ ret = 0; ++ break; ++ default: ++ break; ++ } ++ } ++ return ret; ++} ++int ++appl_pam_requires_chauthtok(void) ++{ ++ return appl_pam_pwchange_required; ++} ++int ++appl_pam_session_open(void) ++{ ++ int ret = 0; ++ if (appl_pam_started) { ++#ifdef DEBUG ++ printf("Opening PAM session.\n"); ++#endif ++ ret = pam_open_session(appl_pamh, 0); ++ if (ret == 0) { ++ appl_pam_session_opened = 1; ++ } ++ } ++ return ret; ++} ++int ++appl_pam_setenv(void) ++{ ++ int ret = 0; ++#ifdef HAVE_PAM_GETENVLIST ++#ifdef HAVE_PUTENV ++ int i; ++ char **list; ++ if (appl_pam_started) { ++ list = pam_getenvlist(appl_pamh); ++ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) { ++#ifdef DEBUG ++ printf("Setting \"%s\" in environment.\n", list[i]); ++#endif ++ putenv(list[i]); ++ } ++ } ++#endif ++#endif ++ return ret; ++} ++int ++appl_pam_cred_init(void) ++{ ++ int ret = 0; ++ if (appl_pam_started) { ++#ifdef DEBUG ++ printf("Initializing PAM credentials.\n"); ++#endif ++ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED); ++ if (ret == 0) { ++ appl_pam_creds_initialized = 1; ++ } ++ } ++ return ret; ++} ++#endif +diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h +new file mode 100644 +index 0000000..0ab7656 +--- /dev/null ++++ b/src/clients/ksu/pam.h +@@ -0,0 +1,57 @@ ++/* ++ * src/clients/ksu/pam.h ++ * ++ * Copyright 2007,2009,2010 Red Hat, Inc. ++ * ++ * All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * Neither the name of Red Hat, Inc. nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Convenience wrappers for using PAM. ++ */ ++ ++#include <krb5.h> ++#ifdef HAVE_SECURITY_PAM_APPL_H ++#include <security/pam_appl.h> ++#endif ++ ++#define USE_PAM_CONFIGURATION_KEYWORD "use_pam" ++ ++#ifdef USE_PAM ++int appl_pam_enabled(krb5_context context, const char *section); ++int appl_pam_acct_mgmt(const char *service, int interactive, ++ const char *local_username, ++ const char *non_interactive_password, ++ const char *hostname, ++ const char *ruser, ++ const char *tty); ++int appl_pam_requires_chauthtok(void); ++int appl_pam_session_open(void); ++int appl_pam_setenv(void); ++int appl_pam_cred_init(void); ++void appl_pam_cleanup(void); ++#endif +diff --git a/src/configure.in b/src/configure.in +index 037c9f3..daabd12 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1336,6 +1336,8 @@ AC_SUBST([VERTO_VERSION]) + + AC_PATH_PROG(GROFF, groff) + ++KRB5_WITH_PAM ++ + # Make localedir work in autoconf 2.5x. + if test "${localedir+set}" != set; then + localedir='$(datadir)/locale' diff --git a/source/n/krb5/patches/krb5-1.13-dirsrv-accountlock.patch b/source/n/krb5/patches/krb5-1.13-dirsrv-accountlock.patch new file mode 100644 index 00000000..168b9ba0 --- /dev/null +++ b/source/n/krb5/patches/krb5-1.13-dirsrv-accountlock.patch @@ -0,0 +1,75 @@ +From 0a33cb5ff8f80c62a652bc60860fad375ee58a85 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:47:44 -0400 +Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch + +Treat 'nsAccountLock: true' the same as 'loginDisabled: true'. Updated from +original version filed as RT#5891. +--- + src/aclocal.m4 | 9 +++++++++ + src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 17 +++++++++++++++++ + src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c | 3 +++ + 3 files changed, 29 insertions(+) + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index f5667c3..2bfb994 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -1656,6 +1656,15 @@ if test "$with_ldap" = yes; then + AC_MSG_NOTICE(enabling OpenLDAP database backend module support) + OPENLDAP_PLUGIN=yes + fi ++AC_ARG_WITH([dirsrv-account-locking], ++[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module], ++[case "$withval" in ++ yes | no) ;; ++ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;; ++esac], with_dirsrv_account_locking=no) ++if test $with_dirsrv_account_locking = yes; then ++ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.]) ++fi + ])dnl + dnl + dnl If libkeyutils exists (on Linux) include it and use keyring ccache +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +index 32efc4f..af8b2db 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +@@ -1674,6 +1674,23 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context, + ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data); + if (ret) + goto cleanup; ++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING ++ { ++ krb5_timestamp expiretime=0; ++ char *is_login_disabled=NULL; ++ ++ /* LOGIN DISABLED */ ++ ret = krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled, ++ &attr_present); ++ if (ret) ++ goto cleanup; ++ if (attr_present == TRUE) { ++ if (strcasecmp(is_login_disabled, "TRUE")== 0) ++ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX; ++ free (is_login_disabled); ++ } ++ } ++#endif + + ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname); + if (ret) +diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c +index d722dbf..5e8e9a8 100644 +--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c ++++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c +@@ -54,6 +54,9 @@ char *principal_attributes[] = { "krbprincipalname", + "krbLastFailedAuth", + "krbLoginFailedCount", + "krbLastSuccessfulAuth", ++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING ++ "nsAccountLock", ++#endif + "krbLastPwdChange", + "krbLastAdminUnlock", + "krbPrincipalAuthInd", diff --git a/source/n/krb5/patches/krb5-1.15-beta1-buildconf.patch b/source/n/krb5/patches/krb5-1.15-beta1-buildconf.patch new file mode 100644 index 00000000..d5737508 --- /dev/null +++ b/source/n/krb5/patches/krb5-1.15-beta1-buildconf.patch @@ -0,0 +1,70 @@ +From 302fdf788fe4d3895a9dcc0e86f98c09a34ea82a Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:45:26 -0400 +Subject: [PATCH] krb5-1.15-beta1-buildconf.patch + +Build binaries in this package as RELRO PIEs, libraries as partial RELRO, +and install shared libraries with the execute bit set on them. Prune out +the -L/usr/lib* and PIE flags where they might leak out and affect +apps which just want to link with the libraries. FIXME: needs to check and +not just assume that the compiler supports using these flags. +--- + src/build-tools/krb5-config.in | 7 +++++++ + src/config/pre.in | 2 +- + src/config/shlib.conf | 5 +++-- + 3 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in +index c17cb5e..1891dea 100755 +--- a/src/build-tools/krb5-config.in ++++ b/src/build-tools/krb5-config.in +@@ -226,6 +226,13 @@ if test -n "$do_libs"; then + -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \ + -e 's#\$(CFLAGS)##'` + ++ if test `dirname $libdir` = /usr ; then ++ lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"` ++ fi ++ lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"` ++ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"` ++ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"` ++ + if test $library = 'kdb'; then + lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB" + library=krb5 +diff --git a/src/config/pre.in b/src/config/pre.in +index fcea229..d961b56 100644 +--- a/src/config/pre.in ++++ b/src/config/pre.in +@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP) + INSTALL_SCRIPT=@INSTALL_PROGRAM@ + INSTALL_DATA=@INSTALL_DATA@ + INSTALL_SHLIB=@INSTALL_SHLIB@ +-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root ++INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 + ## This is needed because autoconf will sometimes define @exec_prefix@ to be + ## ${prefix}. + prefix=@prefix@ +diff --git a/src/config/shlib.conf b/src/config/shlib.conf +index 3e4af6c..2b20c3f 100644 +--- a/src/config/shlib.conf ++++ b/src/config/shlib.conf +@@ -423,7 +423,7 @@ mips-*-netbsd*) + # Linux ld doesn't default to stuffing the SONAME field... + # Use objdump -x to examine the fields of the library + # UNDEF_CHECK is suppressed by --enable-asan +- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)' ++ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK) -Wl,-z,relro -Wl,--warn-shared-textrel' + UNDEF_CHECK='-Wl,--no-undefined' + # $(EXPORT_CHECK) runs export-check.pl when in maintainer mode. + LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)' +@@ -435,7 +435,8 @@ mips-*-netbsd*) + SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' + PROFFLAGS=-pg + PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' +- CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' ++ CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)' ++ INSTALL_SHLIB='${INSTALL} -m755' + CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' + CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' + CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' diff --git a/source/n/krb5/patches/krb5-1.15-beta1-selinux-label.patch b/source/n/krb5/patches/krb5-1.15-beta1-selinux-label.patch new file mode 100644 index 00000000..d743c3be --- /dev/null +++ b/source/n/krb5/patches/krb5-1.15-beta1-selinux-label.patch @@ -0,0 +1,1065 @@ +From a2e0aed3d390ded3a7724fa223a3dc1102ec6221 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:30:53 -0400 +Subject: [PATCH] krb5-1.15-beta1-selinux-label.patch + +SELinux bases access to files on the domain of the requesting process, +the operation being performed, and the context applied to the file. + +In many cases, applications needn't be SELinux aware to work properly, +because SELinux can apply a default label to a file based on the label +of the directory in which it's created. + +In the case of files such as /etc/krb5.keytab, however, this isn't +sufficient, as /etc/krb5.keytab will almost always need to be given a +label which differs from that of /etc/issue or /etc/resolv.conf. The +the kdb stash file needs a different label than the database for which +it's holding a master key, even though both typically live in the same +directory. + +To give the file the correct label, we can either force a "restorecon" +call to fix a file's label after it's created, or create the file with +the right label, as we attempt to do here. We lean on THREEPARAMOPEN +and define a similar macro named WRITABLEFOPEN with which we replace +several uses of fopen(). + +The file creation context that we're manipulating here is a process-wide +attribute. While for the most part, applications which need to label +files when they're created have tended to be single-threaded, there's +not much we can do to avoid interfering with an application that +manipulates the creation context directly. Right now we're mediating +access using a library-local mutex, but that can only work for consumers +that are part of this package -- an unsuspecting application will still +stomp all over us. + +The selabel APIs for looking up the context should be thread-safe (per +Red Hat #273081), so switching to using them instead of matchpathcon(), +which we used earlier, is some improvement. +--- + src/aclocal.m4 | 49 +++ + src/build-tools/krb5-config.in | 3 +- + src/config/pre.in | 3 +- + src/configure.in | 2 + + src/include/k5-int.h | 1 + + src/include/k5-label.h | 32 ++ + src/include/krb5/krb5.hin | 6 + + src/kadmin/dbutil/dump.c | 11 +- + src/kdc/main.c | 2 +- + src/lib/kadm5/logger.c | 4 +- + src/lib/kdb/kdb_log.c | 2 +- + src/lib/krb5/ccache/cc_dir.c | 26 +- + src/lib/krb5/keytab/kt_file.c | 4 +- + src/lib/krb5/os/trace.c | 2 +- + src/lib/krb5/rcache/rc_dfl.c | 13 + + src/plugins/kdb/db2/adb_openclose.c | 2 +- + src/plugins/kdb/db2/kdb_db2.c | 4 +- + src/plugins/kdb/db2/libdb2/btree/bt_open.c | 3 +- + src/plugins/kdb/db2/libdb2/hash/hash.c | 3 +- + src/plugins/kdb/db2/libdb2/recno/rec_open.c | 4 +- + .../kdb/ldap/ldap_util/kdb5_ldap_services.c | 11 +- + src/slave/kpropd.c | 9 + + src/util/profile/prof_file.c | 3 +- + src/util/support/Makefile.in | 3 +- + src/util/support/selinux.c | 406 +++++++++++++++++++++ + 25 files changed, 587 insertions(+), 21 deletions(-) + create mode 100644 src/include/k5-label.h + create mode 100644 src/util/support/selinux.c + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 508e5fe..607859f 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -89,6 +89,7 @@ AC_SUBST_FILE(libnodeps_frag) + dnl + KRB5_AC_PRAGMA_WEAK_REF + WITH_LDAP ++KRB5_WITH_SELINUX + KRB5_LIB_PARAMS + KRB5_AC_INITFINI + KRB5_AC_ENABLE_THREADS +@@ -1742,3 +1743,51 @@ AC_SUBST(PAM_LIBS) + AC_SUBST(PAM_MAN) + AC_SUBST(NON_PAM_MAN) + ])dnl ++dnl ++dnl Use libselinux to set file contexts on newly-created files. ++dnl ++AC_DEFUN(KRB5_WITH_SELINUX,[ ++AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])], ++ withselinux="$withval",withselinux=auto) ++old_LIBS="$LIBS" ++if test "$withselinux" != no ; then ++ AC_MSG_RESULT([checking for libselinux...]) ++ SELINUX_LIBS= ++ AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h) ++ if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then ++ if test "$withselinux" = auto ; then ++ AC_MSG_RESULT([Unable to locate selinux/selinux.h.]) ++ withselinux=no ++ else ++ AC_MSG_ERROR([Unable to locate selinux/selinux.h.]) ++ fi ++ fi ++ ++ LIBS= ++ unset ac_cv_func_setfscreatecon ++ AC_CHECK_FUNCS(setfscreatecon selabel_open) ++ if test "x$ac_cv_func_setfscreatecon" = xno ; then ++ AC_CHECK_LIB(selinux,setfscreatecon) ++ unset ac_cv_func_setfscreatecon ++ AC_CHECK_FUNCS(setfscreatecon selabel_open) ++ if test "x$ac_cv_func_setfscreatecon" = xyes ; then ++ SELINUX_LIBS="$LIBS" ++ else ++ if test "$withselinux" = auto ; then ++ AC_MSG_RESULT([Unable to locate libselinux.]) ++ withselinux=no ++ else ++ AC_MSG_ERROR([Unable to locate libselinux.]) ++ fi ++ fi ++ fi ++ if test "$withselinux" != no ; then ++ AC_MSG_NOTICE([building with SELinux labeling support]) ++ AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.]) ++ SELINUX_LIBS="$LIBS" ++ EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon" ++ fi ++fi ++LIBS="$old_LIBS" ++AC_SUBST(SELINUX_LIBS) ++])dnl +diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in +index f6184da..c17cb5e 100755 +--- a/src/build-tools/krb5-config.in ++++ b/src/build-tools/krb5-config.in +@@ -41,6 +41,7 @@ DL_LIB='@DL_LIB@' + DEFCCNAME='@DEFCCNAME@' + DEFKTNAME='@DEFKTNAME@' + DEFCKTNAME='@DEFCKTNAME@' ++SELINUX_LIBS='@SELINUX_LIBS@' + + LIBS='@LIBS@' + GEN_LIB=@GEN_LIB@ +@@ -255,7 +256,7 @@ if test -n "$do_libs"; then + fi + + # If we ever support a flag to generate output suitable for static +- # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB" ++ # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB" + # here. + + echo $lib_flags +diff --git a/src/config/pre.in b/src/config/pre.in +index e062632..fcea229 100644 +--- a/src/config/pre.in ++++ b/src/config/pre.in +@@ -177,6 +177,7 @@ LD = $(PURE) @LD@ + KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include + LDFLAGS = @LDFLAGS@ + LIBS = @LIBS@ ++SELINUX_LIBS=@SELINUX_LIBS@ + + INSTALL=@INSTALL@ + INSTALL_STRIP= +@@ -399,7 +400,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME) + # HESIOD_LIBS is -lhesiod... + HESIOD_LIBS = @HESIOD_LIBS@ + +-KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB) ++KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB) + KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) + GSS_LIBS = $(GSS_KRB5_LIB) + # needs fixing if ever used on Mac OS X! +diff --git a/src/configure.in b/src/configure.in +index daabd12..acf3a45 100644 +--- a/src/configure.in ++++ b/src/configure.in +@@ -1338,6 +1338,8 @@ AC_PATH_PROG(GROFF, groff) + + KRB5_WITH_PAM + ++KRB5_WITH_SELINUX ++ + # Make localedir work in autoconf 2.5x. + if test "${localedir+set}" != set; then + localedir='$(datadir)/locale' +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index 6499173..173cb02 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -128,6 +128,7 @@ typedef unsigned char u_char; + + + #include "k5-platform.h" ++#include "k5-label.h" + + #define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */ + #define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */ +diff --git a/src/include/k5-label.h b/src/include/k5-label.h +new file mode 100644 +index 0000000..dfaaa84 +--- /dev/null ++++ b/src/include/k5-label.h +@@ -0,0 +1,32 @@ ++#ifndef _KRB5_LABEL_H ++#define _KRB5_LABEL_H ++ ++#ifdef THREEPARAMOPEN ++#undef THREEPARAMOPEN ++#endif ++#ifdef WRITABLEFOPEN ++#undef WRITABLEFOPEN ++#endif ++ ++/* Wrapper functions which help us create files and directories with the right ++ * context labels. */ ++#ifdef USE_SELINUX ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <stdio.h> ++#include <unistd.h> ++FILE *krb5int_labeled_fopen(const char *path, const char *mode); ++int krb5int_labeled_creat(const char *path, mode_t mode); ++int krb5int_labeled_open(const char *path, int flags, ...); ++int krb5int_labeled_mkdir(const char *path, mode_t mode); ++int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device); ++#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z) ++#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y) ++void *krb5int_push_fscreatecon_for(const char *pathname); ++void krb5int_pop_fscreatecon(void *previous); ++#else ++#define WRITABLEFOPEN(x,y) fopen(x,y) ++#define THREEPARAMOPEN(x,y,z) open(x,y,z) ++#endif ++#endif +diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin +index ac22f4c..cf60d6c 100644 +--- a/src/include/krb5/krb5.hin ++++ b/src/include/krb5/krb5.hin +@@ -87,6 +87,12 @@ + #define THREEPARAMOPEN(x,y,z) open(x,y,z) + #endif + ++#if KRB5_PRIVATE ++#ifndef WRITABLEFOPEN ++#define WRITABLEFOPEN(x,y) fopen(x,y) ++#endif ++#endif ++ + #define KRB5_OLD_CRYPTO + + #include <stdlib.h> +diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c +index f7889bd..cad53cf 100644 +--- a/src/kadmin/dbutil/dump.c ++++ b/src/kadmin/dbutil/dump.c +@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname) + { + int fd = -1; + FILE *f; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + *tmpname = NULL; + if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0) + goto error; + ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(ofile); ++#endif + fd = mkstemp(*tmpname); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (fd == -1) + goto error; + +@@ -194,7 +203,7 @@ prep_ok_file(krb5_context context, char *file_name, int *fd) + return 0; + } + +- *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); ++ *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (*fd == -1) { + com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok); + exit_status++; +diff --git a/src/kdc/main.c b/src/kdc/main.c +index ebc852b..a4dffb2 100644 +--- a/src/kdc/main.c ++++ b/src/kdc/main.c +@@ -872,7 +872,7 @@ write_pid_file(const char *path) + FILE *file; + unsigned long pid; + +- file = fopen(path, "w"); ++ file = WRITABLEFOPEN(path, "w"); + if (file == NULL) + return errno; + pid = (unsigned long) getpid(); +diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c +index ce79fab..c53a574 100644 +--- a/src/lib/kadm5/logger.c ++++ b/src/lib/kadm5/logger.c +@@ -414,7 +414,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do + */ + append = (cp[4] == ':') ? O_APPEND : 0; + if (append || cp[4] == '=') { +- fd = open(&cp[5], O_CREAT | O_WRONLY | append, ++ fd = THREEPARAMOPEN(&cp[5], O_CREAT | O_WRONLY | append, + S_IRUSR | S_IWUSR | S_IRGRP); + if (fd != -1) + f = fdopen(fd, append ? "a" : "w"); +@@ -918,7 +918,7 @@ krb5_klog_reopen(krb5_context kcontext) + * In case the old logfile did not get moved out of the + * way, open for append to prevent squashing the old logs. + */ +- f = fopen(log_control.log_entries[lindex].lfu_fname, "a+"); ++ f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+"); + if (f) { + set_cloexec_file(f); + log_control.log_entries[lindex].lfu_filep = f; +diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c +index 766d300..6466417 100644 +--- a/src/lib/kdb/kdb_log.c ++++ b/src/lib/kdb/kdb_log.c +@@ -476,7 +476,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries) + int ulogfd = -1; + + if (stat(logname, &st) == -1) { +- ulogfd = open(logname, O_RDWR | O_CREAT, 0600); ++ ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600); + if (ulogfd == -1) + return errno; + +diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c +index bba64e5..73f0fe6 100644 +--- a/src/lib/krb5/ccache/cc_dir.c ++++ b/src/lib/krb5/ccache/cc_dir.c +@@ -183,10 +183,19 @@ write_primary_file(const char *primary_path, const char *contents) + char *newpath = NULL; + FILE *fp = NULL; + int fd = -1, status; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0) + return ENOMEM; ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(primary_path); ++#endif + fd = mkstemp(newpath); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (fd < 0) + goto cleanup; + #ifdef HAVE_CHMOD +@@ -221,10 +230,23 @@ static krb5_error_code + verify_dir(krb5_context context, const char *dirname) + { + struct stat st; ++ int status; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (stat(dirname, &st) < 0) { +- if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0) +- return 0; ++ if (errno == ENOENT) { ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(dirname); ++#endif ++ status = mkdir(dirname, S_IRWXU); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif ++ if (status == 0) ++ return 0; ++ } + k5_setmsg(context, KRB5_FCC_NOFILE, + _("Credential cache directory %s does not exist"), + dirname); +diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c +index 6a42f26..674d88b 100644 +--- a/src/lib/krb5/keytab/kt_file.c ++++ b/src/lib/krb5/keytab/kt_file.c +@@ -1022,14 +1022,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode) + + KTCHECKLOCK(id); + errno = 0; +- KTFILEP(id) = fopen(KTFILENAME(id), ++ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), + (mode == KRB5_LOCKMODE_EXCLUSIVE) ? "rb+" : "rb"); + if (!KTFILEP(id)) { + if ((mode == KRB5_LOCKMODE_EXCLUSIVE) && (errno == ENOENT)) { + /* try making it first time around */ + k5_create_secure_file(context, KTFILENAME(id)); + errno = 0; +- KTFILEP(id) = fopen(KTFILENAME(id), "rb+"); ++ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), "rb+"); + if (!KTFILEP(id)) + goto report_errno; + writevno = 1; +diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c +index 83c8d4d..a192461 100644 +--- a/src/lib/krb5/os/trace.c ++++ b/src/lib/krb5/os/trace.c +@@ -397,7 +397,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename) + fd = malloc(sizeof(*fd)); + if (fd == NULL) + return ENOMEM; +- *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); ++ *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); + if (*fd == -1) { + free(fd); + return errno; +diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c +index c4d2c74..c0f12ed 100644 +--- a/src/lib/krb5/rcache/rc_dfl.c ++++ b/src/lib/krb5/rcache/rc_dfl.c +@@ -794,6 +794,9 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id) + krb5_error_code retval = 0; + krb5_rcache tmp; + krb5_deltat lifespan = t->lifespan; /* save original lifespan */ ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (! t->recovering) { + name = t->name; +@@ -815,7 +818,17 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id) + retval = krb5_rc_resolve(context, tmp, 0); + if (retval) + goto cleanup; ++#ifdef USE_SELINUX ++ if (t->d.fn != NULL) ++ selabel = krb5int_push_fscreatecon_for(t->d.fn); ++ else ++ selabel = NULL; ++#endif + retval = krb5_rc_initialize(context, tmp, lifespan); ++#ifdef USE_SELINUX ++ if (selabel != NULL) ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (retval) + goto cleanup; + for (q = t->a; q; q = q->na) { +diff --git a/src/plugins/kdb/db2/adb_openclose.c b/src/plugins/kdb/db2/adb_openclose.c +index 7db30a3..2b9d019 100644 +--- a/src/plugins/kdb/db2/adb_openclose.c ++++ b/src/plugins/kdb/db2/adb_openclose.c +@@ -152,7 +152,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename, + * needs be open read/write so that write locking can work with + * POSIX systems + */ +- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { ++ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) { + /* + * maybe someone took away write permission so we could only + * get shared locks? +diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c +index 4c4036e..d90bdea 100644 +--- a/src/plugins/kdb/db2/kdb_db2.c ++++ b/src/plugins/kdb/db2/kdb_db2.c +@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc) + if (retval) + return retval; + +- dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC, +- 0600); ++ dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name, ++ O_CREAT | O_RDWR | O_TRUNC, 0600); + if (dbc->db_lf_file < 0) { + retval = errno; + goto cleanup; +diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c +index 2977b17..d5809a5 100644 +--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c ++++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c +@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8.11 (Berkeley) 11/2/95"; + #include <string.h> + #include <unistd.h> + ++#include "k5-int.h" + #include "db-int.h" + #include "btree.h" + +@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, dflags) + goto einval; + } + +- if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0) ++ if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) + goto err; + + } else { +diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c +index 76f5d47..1fa8b83 100644 +--- a/src/plugins/kdb/db2/libdb2/hash/hash.c ++++ b/src/plugins/kdb/db2/libdb2/hash/hash.c +@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 (Berkeley) 11/7/95"; + #include <assert.h> + #endif + ++#include "k5-int.h" + #include "db-int.h" + #include "hash.h" + #include "page.h" +@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info, dflags) + new_table = 1; + } + if (file) { +- if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1) ++ if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1) + RETURN_ERROR(errno, error0); + (void)fcntl(hashp->fp, F_SETFD, 1); + } +diff --git a/src/plugins/kdb/db2/libdb2/recno/rec_open.c b/src/plugins/kdb/db2/libdb2/recno/rec_open.c +index d8b26e7..b0daa7c 100644 +--- a/src/plugins/kdb/db2/libdb2/recno/rec_open.c ++++ b/src/plugins/kdb/db2/libdb2/recno/rec_open.c +@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c 8.12 (Berkeley) 11/18/94"; + #include <stdio.h> + #include <unistd.h> + ++#include "k5-int.h" + #include "db-int.h" + #include "recno.h" + +@@ -68,7 +69,8 @@ __rec_open(fname, flags, mode, openinfo, dflags) + int rfd = -1, sverrno; + + /* Open the user's file -- if this fails, we're done. */ +- if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0) ++ if (fname != NULL && ++ (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) + return (NULL); + + if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) { +diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c +index 022156a..3d6994c 100644 +--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c ++++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c +@@ -203,7 +203,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv) + + /* set password in the file */ + old_mode = umask(0177); +- pfile = fopen(file_name, "a+"); ++ pfile = WRITABLEFOPEN(file_name, "a+"); + if (pfile == NULL) { + com_err(me, errno, _("Failed to open file %s: %s"), file_name, + strerror (errno)); +@@ -244,6 +244,9 @@ kdb5_ldap_stash_service_password(int argc, char **argv) + * Delete the existing entry and add the new entry + */ + FILE *newfile; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + mode_t omask; + +@@ -255,7 +258,13 @@ kdb5_ldap_stash_service_password(int argc, char **argv) + } + + omask = umask(077); ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(file_name); ++#endif + newfile = fopen(tmp_file, "w"); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + umask (omask); + if (newfile == NULL) { + com_err(me, errno, _("Error creating file %s"), tmp_file); +diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c +index 056c31a..b78c3d9 100644 +--- a/src/slave/kpropd.c ++++ b/src/slave/kpropd.c +@@ -464,6 +464,9 @@ doit(int fd) + krb5_enctype etype; + int database_fd; + char host[INET6_ADDRSTRLEN + 1]; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + signal_wrapper(SIGALRM, alarm_handler); + alarm(params.iprop_resync_timeout); +@@ -520,9 +523,15 @@ doit(int fd) + free(name); + exit(1); + } ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(file); ++#endif + omask = umask(077); + lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600); + (void)umask(omask); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + retval = krb5_lock_file(kpropd_context, lock_fd, + KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK); + if (retval) { +diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c +index 907c119..0f5462a 100644 +--- a/src/util/profile/prof_file.c ++++ b/src/util/profile/prof_file.c +@@ -33,6 +33,7 @@ + #endif + + #include "k5-platform.h" ++#include "k5-label.h" + + struct global_shared_profile_data { + /* This is the head of the global list of shared trees */ +@@ -423,7 +424,7 @@ static errcode_t write_data_to_file(prf_data_t data, const char *outfile, + + errno = 0; + +- f = fopen(new_file, "w"); ++ f = WRITABLEFOPEN(new_file, "w"); + if (!f) { + retval = errno; + if (retval == 0) +diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in +index 6239e41..17bcd2a 100644 +--- a/src/util/support/Makefile.in ++++ b/src/util/support/Makefile.in +@@ -69,6 +69,7 @@ IPC_SYMS= \ + + STLIBOBJS= \ + threads.o \ ++ selinux.o \ + init-addrinfo.o \ + plugins.o \ + errors.o \ +@@ -148,7 +149,7 @@ SRCS=\ + + SHLIB_EXPDEPS = + # Add -lm if dumping thread stats, for sqrt. +-SHLIB_EXPLIBS= $(LIBS) $(DL_LIB) ++SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB) + + DEPLIBS= + +diff --git a/src/util/support/selinux.c b/src/util/support/selinux.c +new file mode 100644 +index 0000000..2302634 +--- /dev/null ++++ b/src/util/support/selinux.c +@@ -0,0 +1,406 @@ ++/* ++ * Copyright 2007,2008,2009,2011,2012,2013,2016 Red Hat, Inc. All Rights Reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions are met: ++ * ++ * Redistributions of source code must retain the above copyright notice, this ++ * list of conditions and the following disclaimer. ++ * ++ * Redistributions in binary form must reproduce the above copyright notice, ++ * this list of conditions and the following disclaimer in the documentation ++ * and/or other materials provided with the distribution. ++ * ++ * Neither the name of Red Hat, Inc. nor the names of its contributors may be ++ * used to endorse or promote products derived from this software without ++ * specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ * ++ * File-opening wrappers for creating correctly-labeled files. So far, we can ++ * assume that this is Linux-specific, so we make many simplifying assumptions. ++ */ ++ ++#include "../../include/autoconf.h" ++ ++#ifdef USE_SELINUX ++ ++#include <k5-label.h> ++#include <k5-platform.h> ++ ++#include <sys/types.h> ++#include <sys/stat.h> ++ ++#include <errno.h> ++#include <fcntl.h> ++#include <limits.h> ++#include <pthread.h> ++#include <stdarg.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++ ++#include <selinux/selinux.h> ++#include <selinux/context.h> ++#include <selinux/label.h> ++ ++/* #define DEBUG 1 */ ++static void ++debug_log(const char *fmt, ...) ++{ ++#ifdef DEBUG ++ va_list ap; ++ va_start(ap, str); ++ if (isatty(fileno(stderr))) { ++ vfprintf(stderr, fmt, ap); ++ } ++ va_end(ap); ++#endif ++ ++ return; ++} ++ ++/* Mutex used to serialize use of the process-global file creation context. */ ++k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER; ++ ++/* Make sure we finish initializing that mutex before attempting to use it. */ ++k5_once_t labeled_once = K5_ONCE_INIT; ++static void ++label_mutex_init(void) ++{ ++ k5_mutex_finish_init(&labeled_mutex); ++} ++ ++static struct selabel_handle *selabel_ctx; ++static time_t selabel_last_changed; ++ ++MAKE_FINI_FUNCTION(cleanup_fscreatecon); ++ ++static void ++cleanup_fscreatecon(void) ++{ ++ if (selabel_ctx != NULL) { ++ selabel_close(selabel_ctx); ++ selabel_ctx = NULL; ++ } ++} ++ ++static security_context_t ++push_fscreatecon(const char *pathname, mode_t mode) ++{ ++ security_context_t previous, configuredsc, currentsc, derivedsc; ++ context_t current, derived; ++ const char *fullpath, *currentuser; ++ char *genpath; ++ ++ previous = configuredsc = currentsc = derivedsc = NULL; ++ current = derived = NULL; ++ genpath = NULL; ++ ++ fullpath = pathname; ++ ++ if (!is_selinux_enabled()) { ++ goto fail; ++ } ++ ++ if (getfscreatecon(&previous) != 0) { ++ goto fail; ++ } ++ ++ /* Canonicalize pathname */ ++ if (pathname[0] != '/') { ++ char *wd; ++ size_t len; ++ len = 0; ++ ++ wd = getcwd(NULL, len); ++ if (wd == NULL) { ++ goto fail; ++ } ++ ++ len = strlen(wd) + 1 + strlen(pathname) + 1; ++ genpath = malloc(len); ++ if (genpath == NULL) { ++ free(wd); ++ goto fail; ++ } ++ ++ sprintf(genpath, "%s/%s", wd, pathname); ++ free(wd); ++ fullpath = genpath; ++ } ++ ++ debug_log("Looking up context for \"%s\"(%05o).\n", fullpath, mode); ++ ++ /* Check whether context file has changed under us */ ++ if (selabel_ctx != NULL || selabel_last_changed == 0) { ++ const char *cpath; ++ struct stat st; ++ int i = -1; ++ ++ cpath = selinux_file_context_path(); ++ if (cpath == NULL || (i = stat(cpath, &st)) != 0 || ++ st.st_mtime != selabel_last_changed) { ++ cleanup_fscreatecon(); ++ ++ selabel_last_changed = i ? time(NULL) : st.st_mtime; ++ } ++ } ++ ++ if (selabel_ctx == NULL) { ++ selabel_ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0); ++ } ++ ++ if (selabel_ctx != NULL && ++ selabel_lookup(selabel_ctx, &configuredsc, fullpath, mode) != 0) { ++ goto fail; ++ } ++ ++ if (genpath != NULL) { ++ free(genpath); ++ genpath = NULL; ++ } ++ ++ if (configuredsc == NULL) { ++ goto fail; ++ } ++ ++ getcon(¤tsc); ++ ++ /* AAAAAAAA */ ++ if (currentsc != NULL) { ++ derived = context_new(configuredsc); ++ ++ if (derived != NULL) { ++ current = context_new(currentsc); ++ ++ if (current != NULL) { ++ currentuser = context_user_get(current); ++ ++ if (currentuser != NULL) { ++ if (context_user_set(derived, ++ currentuser) == 0) { ++ derivedsc = context_str(derived); ++ ++ if (derivedsc != NULL) { ++ freecon(configuredsc); ++ configuredsc = strdup(derivedsc); ++ } ++ } ++ } ++ ++ context_free(current); ++ } ++ ++ context_free(derived); ++ } ++ ++ freecon(currentsc); ++ } ++ ++ debug_log("Setting file creation context to \"%s\".\n", configuredsc); ++ if (setfscreatecon(configuredsc) != 0) { ++ debug_log("Unable to determine current context.\n"); ++ goto fail; ++ } ++ ++ freecon(configuredsc); ++ return previous; ++ ++fail: ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ if (genpath != NULL) { ++ free(genpath); ++ } ++ if (configuredsc != NULL) { ++ freecon(configuredsc); ++ } ++ ++ cleanup_fscreatecon(); ++ return NULL; ++} ++ ++static void ++pop_fscreatecon(security_context_t previous) ++{ ++ if (!is_selinux_enabled()) { ++ return; ++ } ++ ++ if (previous != NULL) { ++ debug_log("Resetting file creation context to \"%s\".\n", previous); ++ } else { ++ debug_log("Resetting file creation context to default.\n"); ++ } ++ ++ /* NULL resets to default */ ++ setfscreatecon(previous); ++ ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ ++ /* Need to clean this up here otherwise it leaks */ ++ cleanup_fscreatecon(); ++} ++ ++void * ++krb5int_push_fscreatecon_for(const char *pathname) ++{ ++ struct stat st; ++ void *retval; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ++ if (stat(pathname, &st) != 0) { ++ st.st_mode = S_IRUSR | S_IWUSR; ++ } ++ ++ retval = push_fscreatecon(pathname, st.st_mode); ++ return retval ? retval : (void *) -1; ++} ++ ++void ++krb5int_pop_fscreatecon(void *con) ++{ ++ if (con != NULL) { ++ pop_fscreatecon((con == (void *) -1) ? NULL : con); ++ k5_mutex_unlock(&labeled_mutex); ++ } ++} ++ ++FILE * ++krb5int_labeled_fopen(const char *path, const char *mode) ++{ ++ FILE *fp; ++ int errno_save; ++ security_context_t ctx; ++ ++ if ((strcmp(mode, "r") == 0) || ++ (strcmp(mode, "rb") == 0)) { ++ return fopen(path, mode); ++ } ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ ++ fp = fopen(path, mode); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return fp; ++} ++ ++int ++krb5int_labeled_creat(const char *path, mode_t mode) ++{ ++ int fd; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ ++ fd = creat(path, mode); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return fd; ++} ++ ++int ++krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev) ++{ ++ int ret; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, mode); ++ ++ ret = mknod(path, mode, dev); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return ret; ++} ++ ++int ++krb5int_labeled_mkdir(const char *path, mode_t mode) ++{ ++ int ret; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, S_IFDIR); ++ ++ ret = mkdir(path, mode); ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return ret; ++} ++ ++int ++krb5int_labeled_open(const char *path, int flags, ...) ++{ ++ int fd; ++ int errno_save; ++ security_context_t ctx; ++ mode_t mode; ++ va_list ap; ++ ++ if ((flags & O_CREAT) == 0) { ++ return open(path, flags); ++ } ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ ++ va_start(ap, flags); ++ mode = va_arg(ap, mode_t); ++ fd = open(path, flags, mode); ++ va_end(ap); ++ ++ errno_save = errno; ++ ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ ++ errno = errno_save; ++ return fd; ++} ++ ++#endif /* USE_SELINUX */ diff --git a/source/n/krb5/patches/krb5-1.3.1-dns.patch b/source/n/krb5/patches/krb5-1.3.1-dns.patch new file mode 100644 index 00000000..211e6614 --- /dev/null +++ b/source/n/krb5/patches/krb5-1.3.1-dns.patch @@ -0,0 +1,22 @@ +From 285e023d996ed1a9dbe77239967b3f56ed2c8075 Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:46:21 -0400 +Subject: [PATCH] krb5-1.3.1-dns.patch + +We want to be able to use --with-netlib and --enable-dns at the same time. +--- + src/aclocal.m4 | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/aclocal.m4 b/src/aclocal.m4 +index 607859f..f5667c3 100644 +--- a/src/aclocal.m4 ++++ b/src/aclocal.m4 +@@ -703,6 +703,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library), + LIBS="$LIBS $withval" + AC_MSG_RESULT("netlib will use \'$withval\'") + fi ++ KRB5_AC_ENABLE_DNS + ],dnl + [AC_LIBRARY_NET] + )])dnl diff --git a/source/n/krb5/patches/krb5-1.9-debuginfo.patch b/source/n/krb5/patches/krb5-1.9-debuginfo.patch new file mode 100644 index 00000000..a67ecd34 --- /dev/null +++ b/source/n/krb5/patches/krb5-1.9-debuginfo.patch @@ -0,0 +1,39 @@ +From 792c6e3ce90f8cb374df41abbf3da1631d64045f Mon Sep 17 00:00:00 2001 +From: Robbie Harwood <rharwood@redhat.com> +Date: Tue, 23 Aug 2016 16:49:25 -0400 +Subject: [PATCH] krb5-1.9-debuginfo.patch + +We want to keep these y.tab.c files around because the debuginfo points to +them. It would be more elegant at the end to use symbolic links, but that +could mess up people working in the tree on other things. +--- + src/kadmin/cli/Makefile.in | 5 +++++ + src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in +index adfea6e..d1327e4 100644 +--- a/src/kadmin/cli/Makefile.in ++++ b/src/kadmin/cli/Makefile.in +@@ -37,3 +37,8 @@ clean-unix:: + # CC_LINK is not meant for compilation and this use may break in the future. + datetest: getdate.c + $(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c ++ ++%.c: %.y ++ $(RM) y.tab.c $@ ++ $(YACC.y) $< ++ $(CP) y.tab.c $@ +diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in +index 8669c24..a22f23c 100644 +--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in ++++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in +@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE) + getdate.c: $(GETDATE) + $(RM) getdate.c y.tab.c + $(YACC) $(GETDATE) +- $(MV) y.tab.c getdate.c ++ $(CP) y.tab.c getdate.c + + install: + $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG) |