-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/15/2013 11:50 AM, Stephen Gallagher wrote:
> There was duplicated code in cc_file_check_existing() and in 
> cc_dir_check_existing(). I pulled them into the same function.
> 
> There are two changes made to the original code here: 1) Fixes a
> use-after-free bug in cc_file_check_existing(). In the original
> code, we called krb5_free_context() and then used that context
> immediately after that in krb5_cc_close(). This patch corrects the
> ordering
> 
> 2) The krb5_cc_resolve() call handles KRB5_FCC_NOFILE for all cache
> types. Previously, this was only handled for DIR caches.
> 
> This second part I need someone with Kerberos knowledge to verify.
> Is there a risk of receiving this error for the FILE or KEYRING
> types, and if so is this handling still acceptable or should they
> be special-cased?



Self-nack. New patch attached (I was never actually returning the
validity result).

Interdiff:

diff --git a/src/providers/krb5/krb5_utils.c
b/src/providers/krb5/krb5_utils.c
index 47c45d0..8166435 100644
- --- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -750,6 +750,7 @@ check_cc_validity(const char *location,
     }

     ret = EOK;
+    *_valid = valid;

  done:
      if (ccache) krb5_cc_close(context, ccache);
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.14 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlIWHAwACgkQeiVVYja6o6O4qACdFs9NjmjFD0oq2A3cWkjvbCOT
CSEAn3h+SB/T8H1OguTueRY+UfafjJ/b
=wxng
-----END PGP SIGNATURE-----
>From e55e7a1a25e85428c8174c5b48b8dd9a41efde65 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Thu, 15 Aug 2013 11:40:59 -0400
Subject: [PATCH] KRB5: Refactor cc_*_check_existing

There was duplicated code in cc_file_check_existing() and in
cc_dir_check_existing(). I pulled them into the same function.

There are two changes made to the original code here:
1) Fixes a use-after-free bug in cc_file_check_existing(). In the
original code, we called krb5_free_context() and then used that
context immediately after that in krb5_cc_close(). This patch
corrects the ordering

2) The krb5_cc_resolve() call handles KRB5_FCC_NOFILE for all
cache types. Previously, this was only handled for DIR caches.
---
 src/providers/krb5/krb5_utils.c | 120 ++++++++++++++++++++--------------------
 1 file changed, 59 insertions(+), 61 deletions(-)

diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index 1b6d57c608e56c995dd4e852093e9e045b2d40a8..080e12b158f590488668a8f249052d0ae777b0c0 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -704,6 +704,60 @@ done:
     return ret;
 }
 
+static errno_t
+check_cc_validity(const char *location,
+                  const char *realm,
+                  const char *princ,
+                  bool *_valid)
+{
+    errno_t ret;
+    bool valid = false;
+    krb5_ccache ccache = NULL;
+    krb5_context context = NULL;
+    krb5_error_code krberr;
+
+    krberr = krb5_init_context(&context);
+    if (krberr) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
+        return EIO;
+    }
+
+    krberr = krb5_cc_resolve(context, location, &ccache);
+    if (krberr == KRB5_FCC_NOFILE || ccache == NULL) {
+        /* KRB5_FCC_NOFILE would be returned if the directory components
+         * of the DIR cache do not exist, which is the case in /run
+         * after a reboot
+         */
+        DEBUG(SSSDBG_TRACE_FUNC,
+              ("ccache %s is missing or empty\n", location));
+        valid = false;
+        ret = EOK;
+        goto done;
+    } else if (krberr != 0) {
+        KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
+        DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
+        ret = EIO;
+        goto done;
+    }
+
+    krberr = check_for_valid_tgt(context, ccache, realm, princ, &valid);
+    if (krberr != EOK) {
+        KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              ("Could not check if ccache contains a valid principal\n"));
+        ret = EIO;
+        goto done;
+    }
+
+    ret = EOK;
+    *_valid = valid;
+
+ done:
+     if (ccache) krb5_cc_close(context, ccache);
+     krb5_free_context(context);
+     return ret;
+}
+
 /*======== ccache back end utilities ========*/
 struct sss_krb5_cc_be *
 get_cc_be_ops(enum sss_krb5_cc_type type)
@@ -852,9 +906,6 @@ cc_file_check_existing(const char *location, uid_t uid,
     bool active;
     bool valid;
     const char *filename;
-    krb5_ccache ccache = NULL;
-    krb5_context context = NULL;
-    krb5_error_code kerr;
 
     filename = sss_krb5_residual_check_type(location, SSS_KRB5_TYPE_FILE);
     if (!filename) {
@@ -878,28 +929,9 @@ cc_file_check_existing(const char *location, uid_t uid,
         return ret;
     }
 
-    kerr = krb5_init_context(&context);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
-        return EIO;
-    }
-
-    kerr = krb5_cc_resolve(context, location, &ccache);
-    if (kerr != 0) {
-        KRB5_DEBUG(SSSDBG_OP_FAILURE, context, kerr);
-        krb5_free_context(context);
-        DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
-        return EIO;
-    }
-
-    kerr = check_for_valid_tgt(context, ccache, realm, princ, &valid);
-    krb5_free_context(context);
-    krb5_cc_close(context, ccache);
-    if (kerr != EOK) {
-        KRB5_DEBUG(SSSDBG_OP_FAILURE, context, kerr);
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              ("Could not check if ccache contains a valid principal\n"));
-        return EIO;
+    ret = check_cc_validity(location, realm, princ, &valid);
+    if (ret != EOK) {
+        return ret;
     }
 
     *_active = active;
@@ -977,9 +1009,6 @@ cc_dir_check_existing(const char *location, uid_t uid,
     bool active = false;
     bool active_primary = false;
     bool valid = false;
-    krb5_ccache ccache = NULL;
-    krb5_context context = NULL;
-    krb5_error_code krberr;
     enum sss_krb5_cc_type type;
     const char *filename;
     const char *dir;
@@ -1062,45 +1091,14 @@ cc_dir_check_existing(const char *location, uid_t uid,
         goto done;
     }
 
-    krberr = krb5_init_context(&context);
-    if (krberr) {
-        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to init kerberos context\n"));
-        ret = EIO;
-        goto done;
-    }
-
-    krberr = krb5_cc_resolve(context, location, &ccache);
-    if (krberr == KRB5_FCC_NOFILE || ccache == NULL) {
-        /* KRB5_FCC_NOFILE would be returned if the directory components
-         * of the DIR cache do not exist, which is the case in /run
-         * after a reboot
-         */
-        DEBUG(SSSDBG_TRACE_FUNC,
-              ("ccache %s is missing or empty\n", location));
-        valid = false;
-        ret = EOK;
-        goto done;
-    } else if (krberr != 0) {
-        KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
-        DEBUG(SSSDBG_CRIT_FAILURE, ("krb5_cc_resolve failed.\n"));
-        ret = EIO;
-        goto done;
-    }
-
-    krberr = check_for_valid_tgt(context, ccache, realm, princ, &valid);
-    if (krberr != EOK) {
-        KRB5_DEBUG(SSSDBG_OP_FAILURE, context, krberr);
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              ("Could not check if ccache contains a valid principal\n"));
-        ret = EIO;
+    ret = check_cc_validity(location, realm, princ, &valid);
+    if (ret != EOK) {
         goto done;
     }
 
     ret = EOK;
 done:
     talloc_free(tmp_ctx);
-    if (ccache) krb5_cc_close(context, ccache);
-    krb5_free_context(context);
     *_active = active;
     *_valid = valid;
     return ret;
-- 
1.8.3.1

Attachment: 0001-KRB5-Refactor-cc_-_check_existing.patch.sig
Description: PGP signature

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to