From 5dd2f665987a2916bcf527d0ff1613d2e50a84bf Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Thu, 2 Sep 2010 16:11:10 -0400
Subject: [PATCH 3/4] Make ldap_child report kerberos return code to parent

---
 src/providers/ldap/ldap_child.c            |   13 +++++++++----
 src/providers/ldap/sdap_async_connection.c |    4 +++-
 src/providers/ldap/sdap_async_private.h    |    4 +++-
 src/providers/ldap/sdap_child_helpers.c    |   23 ++++++++++++++++-------
 4 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c
index 5d784b1..f4be185 100644
--- a/src/providers/ldap/ldap_child.c
+++ b/src/providers/ldap/ldap_child.c
@@ -94,13 +94,15 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size,
     return EOK;
 }
 
-static int pack_buffer(struct response *r, int result, const char *msg, time_t expire_time)
+static int pack_buffer(struct response *r, int result, krb5_error_code krberr,
+                       const char *msg, time_t expire_time)
 {
     int len;
     size_t p = 0;
 
     len = strlen(msg);
-    r->size = 2 * sizeof(uint32_t) + len + sizeof(time_t);
+    r->size = 2 * sizeof(uint32_t) + sizeof(krb5_error_code) +
+              len + sizeof(time_t);
 
     r->buf = talloc_array(r, uint8_t, r->size);
     if(!r->buf) {
@@ -110,6 +112,9 @@ static int pack_buffer(struct response *r, int result, const char *msg, time_t e
     /* result */
     SAFEALIGN_SET_UINT32(&r->buf[p], result, &p);
 
+    /* krb5 error code */
+    safealign_memcpy(&r->buf[p], &krberr, sizeof(krberr), &p);
+
     /* message size */
     SAFEALIGN_SET_UINT32(&r->buf[p], len, &p);
 
@@ -311,7 +316,7 @@ static int prepare_response(TALLOC_CTX *mem_ctx,
     r->size = 0;
 
     if (kerr == 0) {
-        ret = pack_buffer(r, EOK, ccname, expire_time);
+        ret = pack_buffer(r, EOK, kerr, ccname, expire_time);
     } else {
         krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr);
         if (krb5_msg == NULL) {
@@ -319,7 +324,7 @@ static int prepare_response(TALLOC_CTX *mem_ctx,
             return ENOMEM;
         }
 
-        ret = pack_buffer(r, EFAULT, krb5_msg, 0);
+        ret = pack_buffer(r, EFAULT, kerr, krb5_msg, 0);
         sss_krb5_free_error_message(krb5_error_ctx, krb5_msg);
     }
 
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index d2ca356..d4dcef5 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -723,8 +723,10 @@ static void sdap_kinit_done(struct tevent_req *subreq)
     int result;
     char *ccname = NULL;
     time_t expire_time;
+    krb5_error_code kerr;
 
-    ret = sdap_get_tgt_recv(subreq, state, &result, &ccname, &expire_time);
+    ret = sdap_get_tgt_recv(subreq, state, &result,
+                            &kerr, &ccname, &expire_time);
     talloc_zfree(subreq);
     if (ret != EOK) {
         state->result = SDAP_AUTH_FAILED;
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index 0f8acd8..ddc3e56 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -23,6 +23,7 @@
 #define _SDAP_ASYNC_PRIVATE_H_
 
 #include "config.h"
+#include "util/sss_krb5.h"
 #include "providers/ldap/sdap_async.h"
 
 void make_realm_upper_case(const char *upn);
@@ -73,7 +74,8 @@ struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx,
 int sdap_get_tgt_recv(struct tevent_req *req,
                       TALLOC_CTX *mem_ctx,
                       int  *result,
+                      krb5_error_code *kerr,
                       char **ccname,
-                      time_t *expire_time);
+                      time_t *expire_time_out);
 
 #endif /* _SDAP_ASYNC_PRIVATE_H_ */
diff --git a/src/providers/ldap/sdap_child_helpers.c b/src/providers/ldap/sdap_child_helpers.c
index 1b12248..5a15e66 100644
--- a/src/providers/ldap/sdap_child_helpers.c
+++ b/src/providers/ldap/sdap_child_helpers.c
@@ -206,18 +206,22 @@ static errno_t create_tgt_req_send_buffer(TALLOC_CTX *mem_ctx,
 
 static int parse_child_response(TALLOC_CTX *mem_ctx,
                                 uint8_t *buf, ssize_t size,
-                                int  *result, char **ccache,
-                                time_t *expire_time_out)
+                                int  *result, krb5_error_code *kerr,
+                                char **ccache, time_t *expire_time_out)
 {
     size_t p = 0;
     uint32_t len;
     uint32_t res;
     char *ccn;
     time_t expire_time;
+    krb5_error_code krberr;
 
     /* operation result code */
     SAFEALIGN_COPY_UINT32_CHECK(&res, buf + p, size, &p);
 
+    /* krb5 error code */
+    safealign_memcpy(&krberr, buf+p, sizeof(krberr), &p);
+
     /* ccache name size */
     SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
 
@@ -240,6 +244,7 @@ static int parse_child_response(TALLOC_CTX *mem_ctx,
     *result = res;
     *ccache = ccn;
     *expire_time_out = expire_time;
+    *kerr = krberr;
     return EOK;
 }
 
@@ -372,10 +377,11 @@ static void sdap_get_tgt_done(struct tevent_req *subreq)
 }
 
 int sdap_get_tgt_recv(struct tevent_req *req,
-                           TALLOC_CTX *mem_ctx,
-                           int  *result,
-                           char **ccname,
-                           time_t *expire_time_out)
+                      TALLOC_CTX *mem_ctx,
+                      int  *result,
+                      krb5_error_code *kerr,
+                      char **ccname,
+                      time_t *expire_time_out)
 {
     struct sdap_get_tgt_state *state = tevent_req_data(req,
                                              struct sdap_get_tgt_state);
@@ -383,10 +389,12 @@ int sdap_get_tgt_recv(struct tevent_req *req,
     time_t expire_time;
     int  res;
     int ret;
+    krb5_error_code krberr;
 
     TEVENT_REQ_RETURN_ON_ERROR(req);
 
-    ret = parse_child_response(mem_ctx, state->buf, state->len, &res, &ccn, &expire_time);
+    ret = parse_child_response(mem_ctx, state->buf, state->len,
+                               &res, &krberr, &ccn, &expire_time);
     if (ret != EOK) {
         DEBUG(1, ("Cannot parse child response: [%d][%s]\n", ret, strerror(ret)));
         return ret;
@@ -394,6 +402,7 @@ int sdap_get_tgt_recv(struct tevent_req *req,
 
     DEBUG(6, ("Child responded: %d [%s], expired on [%ld]\n", res, ccn, (long)expire_time));
     *result = res;
+    *kerr = krberr;
     *ccname = ccn;
     *expire_time_out = expire_time;
     return EOK;
-- 
1.7.2.2

