[SSSD] [PATCH] Move ccache operations to krb5_child, allow the krb5_auth code to run unprivileged

Jakub Hrozek jhrozek at redhat.com
Tue Nov 11 21:37:21 UTC 2014


On Tue, Nov 11, 2014 at 09:11:45PM +0100, Jakub Hrozek wrote:
> On Tue, Nov 11, 2014 at 06:23:24PM +0100, Lukas Slebodnik wrote:
> > On (11/11/14 13:45), Jakub Hrozek wrote:
> > >On Tue, Nov 11, 2014 at 11:15:30AM +0100, Jakub Hrozek wrote:
> > >> Can you give me access to a host that reproduces this crash? ccname
> > >> should never be NULL with the new patches ...
> > >
> > >..except on access_provider=krb5...
> > >
> > >Thanks for catching that, new patches are attached.
> > 
> > There is problem with support of enterprise principals.
> > authentication for such users failed.
> 
> Thanks a lot for catching that, I had no trouble logging in as a user
> from a child domain, but I could reproduce the issue when I used a
> completely different suffix.
> 
> I'll work on a fix.

Thanks again for the catch, can you test this additional fix on top of
your patches? (Sorry for sending a separate patch, I want to get a fresh
look at the set tomorrow, some other krb5_ccache.c functions might get
the same treatment)
-------------- next part --------------
>From 5d95f998643d875bcea149dde5e7a16aa42063b4 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 11 Nov 2014 22:33:28 +0100
Subject: [PATCH] sss_krb5_check_ccache_princ fix

---
 src/providers/krb5/krb5_ccache.c | 62 +++++++++++++++-------------------------
 src/providers/krb5/krb5_ccache.h |  5 ++--
 src/providers/krb5/krb5_child.c  |  3 +-
 3 files changed, 27 insertions(+), 43 deletions(-)

diff --git a/src/providers/krb5/krb5_ccache.c b/src/providers/krb5/krb5_ccache.c
index c0f5b7b8ced3fd2d6d8cbbf4e3339caba60888ff..7aa36b744ddcf7e46edcc26405a5101645b8b546 100644
--- a/src/providers/krb5/krb5_ccache.c
+++ b/src/providers/krb5/krb5_ccache.c
@@ -374,49 +374,32 @@ done:
 
 /* This function is called only as a way to validate that we have the
  * right cache */
-errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
-                                    const char *ccname, const char *principal)
+errno_t sss_krb5_check_ccache_princ(krb5_context kctx,
+                                    const char *ccname,
+                                    krb5_principal user_princ)
 {
-    struct sss_krb5_ccache *cc = NULL;
+    krb5_ccache kcc = NULL;
     krb5_principal ccprinc = NULL;
-    krb5_principal kprinc = NULL;
     krb5_error_code kerr;
     const char *cc_type;
-    TALLOC_CTX *tmp_ctx;
     errno_t ret;
 
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
-        return ENOMEM;
-    }
-
-    ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc);
-    if (ret) {
-        goto done;
-    }
-
-    cc_type = krb5_cc_get_type(cc->context, cc->ccache);
-
-    DEBUG(SSSDBG_TRACE_INTERNAL,
-          "Searching for [%s] in cache of type [%s]\n", principal, cc_type);
-
-    kerr = krb5_parse_name(cc->context, principal, &kprinc);
-    if (kerr != 0) {
-        KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
-        DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n");
+    kerr = krb5_cc_resolve(kctx, ccname, &kcc);
+    if (kerr) {
         ret = ERR_INTERNAL;
         goto done;
     }
 
-    kerr = krb5_cc_get_principal(cc->context, cc->ccache, &ccprinc);
+    cc_type = krb5_cc_get_type(kctx, kcc);
+
+    kerr = krb5_cc_get_principal(kctx, kcc, &ccprinc);
     if (kerr != 0) {
-        KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr);
+        KRB5_DEBUG(SSSDBG_OP_FAILURE, kctx, kerr);
         DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_get_principal failed.\n");
     }
 
     if (ccprinc) {
-        if (krb5_principal_compare(cc->context, kprinc, ccprinc) == TRUE) {
+        if (krb5_principal_compare(kctx, user_princ, ccprinc) == TRUE) {
             /* found in the primary ccache */
             ret = EOK;
             goto done;
@@ -425,23 +408,23 @@ errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
 
 #ifdef HAVE_KRB5_CC_COLLECTION
 
-    if (krb5_cc_support_switch(cc->context, cc_type)) {
+    if (krb5_cc_support_switch(kctx, cc_type)) {
 
-        krb5_cc_close(cc->context, cc->ccache);
-        cc->ccache = NULL;
+        krb5_cc_close(kctx, kcc);
+        kcc = NULL;
 
-        kerr = krb5_cc_set_default_name(cc->context, ccname);
+        kerr = krb5_cc_set_default_name(kctx, ccname);
         if (kerr != 0) {
-            KRB5_DEBUG(SSSDBG_MINOR_FAILURE, cc->context, kerr);
+            KRB5_DEBUG(SSSDBG_MINOR_FAILURE, kctx, kerr);
             /* try to continue despite failure */
         }
 
-        kerr = krb5_cc_cache_match(cc->context, kprinc, &cc->ccache);
+        kerr = krb5_cc_cache_match(kctx, user_princ, &kcc);
         if (kerr == 0) {
             ret = EOK;
             goto done;
         }
-        KRB5_DEBUG(SSSDBG_TRACE_INTERNAL, cc->context, kerr);
+        KRB5_DEBUG(SSSDBG_TRACE_INTERNAL, kctx, kerr);
     }
 
 #endif /* HAVE_KRB5_CC_COLLECTION */
@@ -449,11 +432,12 @@ errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
     ret = ERR_NOT_FOUND;
 
 done:
-    if (cc) {
-        krb5_free_principal(cc->context, ccprinc);
-        krb5_free_principal(cc->context, kprinc);
+    if (ccprinc) {
+        krb5_free_principal(kctx, ccprinc);
+    }
+    if (kcc) {
+        krb5_cc_close(kctx, kcc);
     }
-    talloc_free(tmp_ctx);
     return ret;
 }
 
diff --git a/src/providers/krb5/krb5_ccache.h b/src/providers/krb5/krb5_ccache.h
index e39f96cad6f46c4003103dce4eadf007bc0f8920..e47df3665e3f325cc56d34767b416662577cc048 100644
--- a/src/providers/krb5/krb5_ccache.h
+++ b/src/providers/krb5/krb5_ccache.h
@@ -39,8 +39,9 @@ errno_t sss_krb5_precreate_ccache(const char *ccname, uid_t uid, gid_t gid);
 
 errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid);
 
-errno_t sss_krb5_check_ccache_princ(uid_t uid, gid_t gid,
-                                    const char *ccname, const char *principal);
+errno_t sss_krb5_check_ccache_princ(krb5_context kctx,
+                                    const char *ccname,
+                                    krb5_principal user_princ);
 
 errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid,
                                   const char *realm, const char *principal);
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 758e6058de144cd6b7d014f9f80a9003850ec127..b9830685122d30b9d9b0d2d4425dc05c78110c98 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1029,8 +1029,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
     /* Successfull authentication! Check if ccache contains the
      * right principal...
      */
-    kerr = sss_krb5_check_ccache_princ(kr->uid, kr->gid,
-                                       kr->ccname, kr->upn);
+    kerr = sss_krb5_check_ccache_princ(kr->ctx, kr->ccname, kr->creds->client);
     if (kerr) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "No ccache for %s in %s?\n", kr->upn, kr->ccname);
-- 
1.9.3



More information about the sssd-devel mailing list