From 8c5253066029b7140442bf77ab7ed5fddaaf0f75 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Fri, 15 Jun 2012 09:27:14 -0400
Subject: [PATCH 2/2] KRB5: Auto-detect DIR cache support in configure

We can't support the DIR cache features in systems with kerberos
libraries older than 1.10. Make sure we don't build it on those
systems.
---
 src/external/krb5.m4             |    4 +++-
 src/providers/krb5/krb5_child.c  |    8 ++++++++
 src/providers/krb5/krb5_common.c |    3 +++
 src/providers/krb5/krb5_utils.c  |   10 ++++++++++
 src/providers/krb5/krb5_utils.h  |   19 +++++++++++++++----
 src/tests/krb5_child-test.c      |    2 ++
 src/tests/krb5_utils-tests.c     |    5 +++++
 7 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/src/external/krb5.m4 b/src/external/krb5.m4
index ee96626140a6918cad5553c245e7f67c42171b97..b87ec5c8ec57f19643f8419405d6a119117d6d16 100644
--- a/src/external/krb5.m4
+++ b/src/external/krb5.m4
@@ -56,7 +56,9 @@ AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc krb5_get_error_message \
                 krb5_kt_free_entry \
                 krb5_princ_realm \
                 krb5_get_time_offsets \
-                krb5_principal_get_realm])
+                krb5_principal_get_realm \
+                krb5_cc_cache_match \
+                krb5_cc_get_full_name])
 CFLAGS=$SAVE_CFLAGS
 LIBS=$SAVE_LIBS
 
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index bfec956b672045e7be98c4c002f5889c7817130d..c434c97ff1993f566a63b2a6d7a36fd7acaddfc8 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -244,11 +244,13 @@ store_creds_in_ccache(krb5_context ctx, krb5_principal princ,
         goto done;
     }
 
+#ifdef HAVE_KRB5_DIRCACHE
     kerr = krb5_cc_switch(ctx, cc);
     if (kerr != 0) {
         KRB5_CHILD_DEBUG(SSSDBG_OP_FAILURE, kerr);
         goto done;
     }
+#endif /* HAVE_KRB5_DIRCACHE */
 
     kerr = krb5_cc_close(ctx, cc);
     if (kerr != 0) {
@@ -366,6 +368,8 @@ done:
     return kerr;
 }
 
+#ifdef HAVE_KRB5_DIRCACHE
+
 static errno_t
 create_ccdir(const char *dirname, uid_t uid, gid_t gid)
 {
@@ -491,6 +495,8 @@ done:
     return kerr;
 }
 
+#endif /* HAVE_KRB5_DIRCACHE */
+
 static krb5_error_code
 create_ccache(uid_t uid, gid_t gid, krb5_context ctx,
               krb5_principal princ, char *ccname, krb5_creds *creds)
@@ -501,8 +507,10 @@ create_ccache(uid_t uid, gid_t gid, krb5_context ctx,
     switch (cctype) {
         case SSS_KRB5_TYPE_FILE:
             return create_ccache_file(ctx, princ, ccname, creds);
+#ifdef HAVE_KRB5_DIRCACHE
         case SSS_KRB5_TYPE_DIR:
             return create_ccache_in_dir(uid, gid, ctx, princ, ccname, creds);
+#endif /* HAVE_KRB5_DIRCACHE */
         default:
             DEBUG(SSSDBG_CRIT_FAILURE, ("Unknown cache type\n"));
             return EINVAL;
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index f4033d29597661d1a9b4ff66e0ee02b4bf649f21..ebd242cf588f8400ddfba4dc97408baceddd3322 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -204,10 +204,13 @@ errno_t check_and_export_options(struct dp_option *opts,
             return ret;
         }
         break;
+
     case SSS_KRB5_TYPE_DIR:
+#ifdef HAVE_KRB5_DIRCACHE
         DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type DIR\n"));
         krb5_ctx->cc_be = &dir_cc;
         break;
+#endif
     default:
         DEBUG(SSSDBG_OP_FAILURE, ("Unkown ccname database\n"));
         return EINVAL;
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index e6987014fe83860f8a61a9ded43ed0dd9309aae5..9a2f84da4f84bde3607262e04824b9c82cfb3cad 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -570,9 +570,16 @@ get_cc_be_ops(enum sss_krb5_cc_type type)
         case SSS_KRB5_TYPE_FILE:
             be = &file_cc;
             break;
+
         case SSS_KRB5_TYPE_DIR:
+            /* If we don't have DIR cache support,
+             * fall through into UNKNOWN.
+             */
+#ifdef HAVE_KRB5_DIRCACHE
             be = &dir_cc;
             break;
+#endif /* HAVE_KRB5_DIRCACHE */
+
         case SSS_KRB5_TYPE_UNKNOWN:
             be = NULL;
             break;
@@ -776,6 +783,7 @@ struct sss_krb5_cc_be file_cc = {
     .remove             = cc_file_remove,
 };
 
+#ifdef HAVE_KRB5_DIRCACHE
 /*======== Operations on the DIR: back end ========*/
 errno_t
 cc_dir_create(const char *location, pcre *illegal_re,
@@ -987,3 +995,5 @@ struct sss_krb5_cc_be dir_cc = {
     .ccache_for_princ   = cc_dir_cache_for_princ,
     .remove             = cc_dir_remove
 };
+
+#endif /* HAVE_KRB5_DIRCACHE */
diff --git a/src/providers/krb5/krb5_utils.h b/src/providers/krb5/krb5_utils.h
index 5f677cae284b8bf22127b171715c07413fee1bb9..be26a7291c9d4cb9f878b050b86222481efd70cb 100644
--- a/src/providers/krb5/krb5_utils.h
+++ b/src/providers/krb5/krb5_utils.h
@@ -27,6 +27,11 @@
 #define __KRB5_UTILS_H__
 
 #include <talloc.h>
+#include "config.h"
+
+#if defined HAVE_KRB5_CC_CACHE_MATCH && defined HAVE_KRB5_CC_GET_FULL_NAME
+#define HAVE_KRB5_DIRCACHE 1
+#endif
 
 #include "providers/krb5/krb5_auth.h"
 #include "providers/data_provider.h"
@@ -53,7 +58,6 @@ struct sss_krb5_cc_be {
 };
 
 struct sss_krb5_cc_be file_cc;
-struct sss_krb5_cc_be dir_cc;
 
 errno_t create_ccache_dir(const char *dirname, pcre *illegal_re,
                           uid_t uid, gid_t gid, bool private_path);
@@ -61,9 +65,6 @@ errno_t create_ccache_dir(const char *dirname, pcre *illegal_re,
 errno_t cc_file_create(const char *filename, pcre *illegal_re,
                        uid_t uid, gid_t gid, bool private_path);
 
-errno_t cc_dir_create(const char *location, pcre *illegal_re,
-                      uid_t uid, gid_t gid, bool private_path);
-
 struct sss_krb5_cc_be *get_cc_be_ops(enum sss_krb5_cc_type type);
 struct sss_krb5_cc_be *get_cc_be_ops_ccache(const char *ccache);
 
@@ -75,4 +76,14 @@ errno_t become_user(uid_t uid, gid_t gid);
 
 errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
                              struct tgt_times *tgtt);
+
+#ifdef HAVE_KRB5_DIRCACHE
+
+struct sss_krb5_cc_be dir_cc;
+
+errno_t cc_dir_create(const char *location, pcre *illegal_re,
+                      uid_t uid, gid_t gid, bool private_path);
+
+#endif /* HAVE_KRB5_DIRCACHE */
+
 #endif /* __KRB5_UTILS_H__ */
diff --git a/src/tests/krb5_child-test.c b/src/tests/krb5_child-test.c
index fa9374c2ded59abf3ead2c86e4583e368493642e..636f733636f3c7a433472f9a7bc4054e22d0ef97 100644
--- a/src/tests/krb5_child-test.c
+++ b/src/tests/krb5_child-test.c
@@ -260,9 +260,11 @@ create_dummy_req(TALLOC_CTX *mem_ctx, const char *user,
     case SSS_KRB5_TYPE_FILE:
         kr->krb5_ctx->cc_be = &file_cc;
         break;
+#ifdef HAVE_KRB5_DIRCACHE
     case SSS_KRB5_TYPE_DIR:
         kr->krb5_ctx->cc_be = &dir_cc;
         break;
+#endif /* HAVE_KRB5_DIRCACHE */
     default:
         if (tmpl[0] != '/') {
             DEBUG(SSSDBG_OP_FAILURE, ("Unkown ccname database\n"));
diff --git a/src/tests/krb5_utils-tests.c b/src/tests/krb5_utils-tests.c
index bcd9acb193ec9ba5187f9775002adc7bbe970c23..581212997907100ef2de74853eb0eaf2230ec930 100644
--- a/src/tests/krb5_utils-tests.c
+++ b/src/tests/krb5_utils-tests.c
@@ -357,6 +357,7 @@ START_TEST(test_illegal_patterns)
 }
 END_TEST
 
+#ifdef HAVE_KRB5_DIRCACHE
 START_TEST(test_cc_dir_create)
 {
     char *residual;
@@ -405,6 +406,8 @@ START_TEST(test_cc_dir_create)
     free(cwd);
 }
 END_TEST
+#endif /* HAVE_KRB5_DIRCACHE */
+
 
 void setup_talloc_context(void)
 {
@@ -694,7 +697,9 @@ Suite *krb5_utils_suite (void)
     tcase_add_checked_fixture (tc_create_dir, setup_create_dir,
                                teardown_create_dir);
     tcase_add_test (tc_create_dir, test_illegal_patterns);
+#ifdef HAVE_KRB5_DIRCACHE
     tcase_add_test (tc_create_dir, test_cc_dir_create);
+#endif /* HAVE_KRB5_DIRCACHE */
     if (getuid() == 0) {
         tcase_add_test (tc_create_dir, test_priv_ccache_dir);
         tcase_add_test (tc_create_dir, test_private_ccache_dir_in_user_dir);
-- 
1.7.10.2

