[SSSD] [PATCH] Only build extract_and_send_pac on platforms that support it

Jakub Hrozek jhrozek at redhat.com
Mon Oct 29 16:00:36 UTC 2012


Attached is a patch that fixes a compilation problem of the SSSD on
RHEL-5. I split the original function into two to only link the child
process with the client libraries and not all consumers of sss_krb5.c

I have a hard stop today around this time, so I didn't have time to
fully test the patch, unfortunately.
-------------- next part --------------
>From fccde6b6441ed9e6d0927107499ab2b4bb082ac5 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 29 Oct 2012 06:04:30 -0400
Subject: [PATCH] Only build extract_and_send_pac on platforms that support it

---
 src/external/pac_responder.m4   |   4 ++
 src/providers/krb5/krb5_child.c | 122 ++++++----------------------------------
 src/util/sss_krb5.c             | 111 ++++++++++++++++++++++++++++++++++++
 src/util/sss_krb5.h             |   7 +++
 4 files changed, 140 insertions(+), 104 deletions(-)

diff --git a/src/external/pac_responder.m4 b/src/external/pac_responder.m4
index 91c8263ac9821f548bac7d756c70cfdd646b1a29..859e1be4131690dff45676ab6dde0b7db5cec324 100644
--- a/src/external/pac_responder.m4
+++ b/src/external/pac_responder.m4
@@ -30,3 +30,7 @@ then
 fi
 
 AM_CONDITIONAL([BUILD_PAC_RESPONDER], [test x$build_pac_responder = xyes -a x$ndr_krb5pac_ok = xyes -a x$krb5_version_ok = xyes ])
+if test x$build_pac_responder = xyes -a x$ndr_krb5pac_ok = xyes -a x$krb5_version_ok = xyes
+then
+    AC_DEFINE_UNQUOTED(HAVE_PAC_RESPONDER, 1, [Build with the PAC responder])
+fi
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 3e64a86524a7ff98ed46115ecd128ab7d5d8b2c3..b8fc4ecb8c0f6af5cb04a96aead835d3ae6941bd 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -101,94 +101,12 @@ struct krb5_req {
 static krb5_context krb5_error_ctx;
 #define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error)
 
-static krb5_error_code extract_and_send_pac(struct krb5_req *kr,
-                                            krb5_ccache ccache,
-                                            krb5_principal server_principal,
-                                            krb5_principal client_principal,
-                                            krb5_keytab keytab)
+
+static errno_t sss_send_pac(krb5_authdata **pac_authdata)
 {
-    krb5_error_code kerr;
-    krb5_creds mcred;
-    krb5_creds cred;
-    krb5_authdata **pac_authdata = NULL;
-    krb5_pac pac = NULL;
     struct sss_cli_req_data sss_data;
     int ret;
     int errnop;
-    krb5_ticket *ticket = NULL;
-    krb5_keytab_entry entry;
-
-    memset(&entry, 0, sizeof(entry));
-    memset(&mcred, 0, sizeof(mcred));
-    memset(&cred, 0, sizeof(mcred));
-
-    mcred.server = server_principal;
-    mcred.client = client_principal;
-
-    kerr = krb5_cc_retrieve_cred(kr->ctx, ccache, 0, &mcred, &cred);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("krb5_cc_retrieve_cred failed.\n"));
-        goto done;
-    }
-
-    kerr = krb5_decode_ticket(&cred.ticket, &ticket);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("krb5_decode_ticket failed.\n"));
-        goto done;
-    }
-
-    kerr = krb5_server_decrypt_ticket_keytab(kr->ctx, keytab, ticket);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("krb5_server_decrypt_ticket_keytab failed.\n"));
-        goto done;
-    }
-
-    kerr = sss_krb5_find_authdata(kr->ctx,
-                                  ticket->enc_part2->authorization_data, NULL,
-                                  KRB5_AUTHDATA_WIN2K_PAC, &pac_authdata);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("krb5_find_authdata failed.\n"));
-        goto done;
-    }
-
-    if (pac_authdata == NULL || pac_authdata[0] == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, ("No PAC authdata available.\n"));
-        kerr = ENOENT;
-        goto done;
-    }
-
-    if (pac_authdata[1] != NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, ("More than one PAC autdata found.\n"));
-        kerr = EINVAL;
-        goto done;
-    }
-
-    kerr = krb5_pac_parse(kr->ctx, pac_authdata[0]->contents,
-                          pac_authdata[0]->length, &pac);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("krb5_pac_parse failed.\n"));
-        goto done;
-    }
-
-    kerr = krb5_kt_get_entry(kr->ctx, keytab, ticket->server,
-                             ticket->enc_part.kvno, ticket->enc_part.enctype,
-                             &entry);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("krb5_kt_get_entry failed.\n"));
-        goto done;
-    }
-
-    kerr = krb5_pac_verify(kr->ctx, pac, 0, NULL, &entry.key, NULL);
-    if (kerr != 0) {
-        DEBUG(SSSDBG_OP_FAILURE, ("krb5_pac_verify failed.\n"));
-        goto done;
-    }
-
-    ret = unsetenv("_SSS_LOOPS");
-    if (ret != EOK) {
-        DEBUG(1, ("Failed to unset _SSS_LOOPS, "
-                  "sss_pac_make_request will most certainly fail.\n"));
-    }
 
     sss_data.len = pac_authdata[0]->length;
     sss_data.data = pac_authdata[0]->contents;
@@ -198,25 +116,10 @@ static krb5_error_code extract_and_send_pac(struct krb5_req *kr,
     if (ret != NSS_STATUS_SUCCESS || errnop != 0) {
         DEBUG(SSSDBG_OP_FAILURE, ("sss_pac_make_request failed [%d][%d].\n",
                                   ret, errnop));
-        kerr = EIO;
-        goto done;
+        return EIO;
     }
 
-    kerr = 0;
-
-done:
-    if (entry.magic != 0) {
-        krb5_free_keytab_entry_contents(kr->ctx, &entry);
-    }
-    krb5_pac_free(kr->ctx, pac);
-    krb5_free_authdata(kr->ctx, pac_authdata);
-    if (ticket != NULL) {
-        krb5_free_ticket(kr->ctx, ticket);
-    }
-
-    krb5_free_cred_contents(kr->ctx, &cred);
-
-    return kerr;
+    return EOK;
 }
 
 static void sss_krb5_expire_callback_func(krb5_context context, void *data,
@@ -835,6 +738,7 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
     krb5_principal validation_princ = NULL;
     bool realm_entry_found = false;
     krb5_ccache validation_ccache = NULL;
+    krb5_authdata **pac_authdata = NULL;
 
     memset(&keytab, 0, sizeof(keytab));
     kerr = krb5_kt_resolve(kr->ctx, kr->keytab, &keytab);
@@ -931,10 +835,20 @@ static krb5_error_code validate_tgt(struct krb5_req *kr)
     /* Try to find and send the PAC to the PAC responder for principals which
      * do not belong to our realm. Failures are not critical. */
     if (kr->upn_from_different_realm) {
-        kerr = extract_and_send_pac(kr, validation_ccache, validation_princ,
-                                    kr->creds->client, keytab);
+        kerr = sss_extract_pac(kr->ctx, validation_ccache, validation_princ,
+                               kr->creds->client, keytab, &pac_authdata);
         if (kerr != 0) {
-            DEBUG(SSSDBG_OP_FAILURE, ("extract_and_send_pac failed, group " \
+            DEBUG(SSSDBG_OP_FAILURE, ("sss_extract_and_send_pac failed, group " \
+                                      "membership for user with principal [%s] " \
+                                      "might not be correct.\n", kr->name));
+            kerr = 0;
+            goto done;
+        }
+
+        kerr = sss_send_pac(pac_authdata);
+        krb5_free_authdata(kr->ctx, pac_authdata);
+        if (kerr != 0) {
+            DEBUG(SSSDBG_OP_FAILURE, ("sss_send_pac failed, group " \
                                       "membership for user with principal [%s] " \
                                       "might not be correct.\n", kr->name));
             kerr = 0;
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index cbee96e86227d51adbc5eb6c12369144db8c5e58..383745787f93eb84901bb29d42d00890864a53c4 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -1004,3 +1004,114 @@ krb5_error_code sss_krb5_find_authdata(krb5_context context,
     return ENOTSUP;
 #endif
 }
+
+krb5_error_code sss_extract_pac(krb5_context ctx,
+                                krb5_ccache ccache,
+                                krb5_principal server_principal,
+                                krb5_principal client_principal,
+                                krb5_keytab keytab,
+                                krb5_authdata ***_pac_authdata)
+{
+#ifdef HAVE_PAC_RESPONDER
+    krb5_error_code kerr;
+    krb5_creds mcred;
+    krb5_creds cred;
+    krb5_authdata **pac_authdata = NULL;
+    krb5_pac pac = NULL;
+    int ret;
+    krb5_ticket *ticket = NULL;
+    krb5_keytab_entry entry;
+
+    memset(&entry, 0, sizeof(entry));
+    memset(&mcred, 0, sizeof(mcred));
+    memset(&cred, 0, sizeof(mcred));
+
+    mcred.server = server_principal;
+    mcred.client = client_principal;
+
+    kerr = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcred, &cred);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("krb5_cc_retrieve_cred failed.\n"));
+        goto done;
+    }
+
+    kerr = krb5_decode_ticket(&cred.ticket, &ticket);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("krb5_decode_ticket failed.\n"));
+        goto done;
+    }
+
+    kerr = krb5_server_decrypt_ticket_keytab(ctx, keytab, ticket);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("krb5_server_decrypt_ticket_keytab failed.\n"));
+        goto done;
+    }
+
+    kerr = sss_krb5_find_authdata(ctx,
+                                  ticket->enc_part2->authorization_data, NULL,
+                                  KRB5_AUTHDATA_WIN2K_PAC, &pac_authdata);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("krb5_find_authdata failed.\n"));
+        goto done;
+    }
+
+    if (pac_authdata == NULL || pac_authdata[0] == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, ("No PAC authdata available.\n"));
+        kerr = ENOENT;
+        goto done;
+    }
+
+    if (pac_authdata[1] != NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, ("More than one PAC autdata found.\n"));
+        kerr = EINVAL;
+        goto done;
+    }
+
+    kerr = krb5_pac_parse(ctx, pac_authdata[0]->contents,
+                          pac_authdata[0]->length, &pac);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("krb5_pac_parse failed.\n"));
+        goto done;
+    }
+
+    kerr = krb5_kt_get_entry(ctx, keytab, ticket->server,
+                             ticket->enc_part.kvno, ticket->enc_part.enctype,
+                             &entry);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("krb5_kt_get_entry failed.\n"));
+        goto done;
+    }
+
+    kerr = krb5_pac_verify(ctx, pac, 0, NULL, &entry.key, NULL);
+    if (kerr != 0) {
+        DEBUG(SSSDBG_OP_FAILURE, ("krb5_pac_verify failed.\n"));
+        goto done;
+    }
+
+    ret = unsetenv("_SSS_LOOPS");
+    if (ret != EOK) {
+        DEBUG(1, ("Failed to unset _SSS_LOOPS, "
+                  "sss_pac_make_request will most certainly fail.\n"));
+    }
+
+    *_pac_authdata = pac_authdata;
+    kerr = 0;
+
+done:
+    if (kerr != 0) {
+        krb5_free_authdata(ctx, pac_authdata);
+    }
+    if (entry.magic != 0) {
+        krb5_free_keytab_entry_contents(ctx, &entry);
+    }
+    krb5_pac_free(ctx, pac);
+    if (ticket != NULL) {
+        krb5_free_ticket(ctx, ticket);
+    }
+
+    krb5_free_cred_contents(ctx, &cred);
+    return kerr;
+#else
+    return ENOTSUP;
+#endif
+}
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
index 6a61f0ea81276ae966297934c94dcb7241521548..deb0cbff776e01e3dda6b6ddf73ceae73df62af7 100644
--- a/src/util/sss_krb5.h
+++ b/src/util/sss_krb5.h
@@ -175,4 +175,11 @@ krb5_error_code sss_krb5_find_authdata(krb5_context context,
                                        krb5_authdata *const *ap_req_authdata,
                                        krb5_authdatatype ad_type,
                                        krb5_authdata ***results);
+
+krb5_error_code sss_extract_pac(krb5_context ctx,
+                                krb5_ccache ccache,
+                                krb5_principal server_principal,
+                                krb5_principal client_principal,
+                                krb5_keytab keytab,
+                                krb5_authdata ***_pac_authdata);
 #endif /* __SSS_KRB5_H__ */
-- 
1.7.12.1



More information about the sssd-devel mailing list