>From 5205a5163cb9542f05f3ad90c6666a8f21c1f81b Mon Sep 17 00:00:00 2001 From: eindenbom Date: Mon, 5 Apr 2010 15:38:19 +0400 Subject: [PATCH 1/4] GSSAPI ticket expiry time is returned from ldap_child and stored in sdap_handle for future reference. --- src/providers/ldap/ldap_child.c | 28 ++++++++++++------- src/providers/ldap/sdap.h | 2 + src/providers/ldap/sdap_async.h | 2 +- src/providers/ldap/sdap_async_connection.c | 15 ++++++++-- src/providers/ldap/sdap_async_private.h | 3 +- src/providers/ldap/sdap_child_helpers.c | 40 +++++++++++++++++++++------ 6 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c index 6a78ca0..8ae1735 100644 --- a/src/providers/ldap/ldap_child.c +++ b/src/providers/ldap/ldap_child.c @@ -89,13 +89,13 @@ 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) +static int pack_buffer(struct response *r, int result, const char *msg, time_t expire_time) { int len; size_t p = 0; len = strlen(msg); - r->size = 2 * sizeof(uint32_t) + len; + r->size = 2 * sizeof(uint32_t) + len + sizeof(time_t); r->buf = talloc_array(r, uint8_t, r->size); if(!r->buf) { @@ -110,6 +110,9 @@ static int pack_buffer(struct response *r, int result, const char *msg) /* message itself */ safealign_memcpy(&r->buf[p], msg, len, &p); + + /* ticket expiration time */ + safealign_memcpy(&r->buf[p], &expire_time, sizeof(expire_time), &p); return EOK; } @@ -118,7 +121,8 @@ static int ldap_child_get_tgt_sync(TALLOC_CTX *memctx, const char *realm_str, const char *princ_str, const char *keytab_name, - const char **ccname_out) + const char **ccname_out, + time_t *expire_time_out) { char *ccname; char *realm_name = NULL; @@ -220,8 +224,6 @@ static int ldap_child_get_tgt_sync(TALLOC_CTX *memctx, krb5_get_init_creds_opt_set_address_list(&options, NULL); krb5_get_init_creds_opt_set_forwardable(&options, 0); krb5_get_init_creds_opt_set_proxiable(&options, 0); - /* set a very short lifetime, we don't keep the ticket around */ - krb5_get_init_creds_opt_set_tkt_life(&options, 300); krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc, keytab, 0, NULL, &options); @@ -240,7 +242,7 @@ static int ldap_child_get_tgt_sync(TALLOC_CTX *memctx, ret = EFAULT; goto done; } - + krberr = krb5_cc_store_cred(context, ccache, &my_creds); if (krberr) { DEBUG(2, ("Failed to store creds: %s\n", @@ -248,9 +250,11 @@ static int ldap_child_get_tgt_sync(TALLOC_CTX *memctx, ret = EFAULT; goto done; } - + + ret = EOK; *ccname_out = ccname; + *expire_time_out = my_creds.times.endtime; done: if (keytab) krb5_kt_close(context, keytab); @@ -260,6 +264,7 @@ done: static int prepare_response(TALLOC_CTX *mem_ctx, const char *ccname, + time_t expire_time, krb5_error_code kerr, struct response **rsp) { @@ -274,7 +279,7 @@ static int prepare_response(TALLOC_CTX *mem_ctx, r->size = 0; if (kerr == 0) { - ret = pack_buffer(r, EOK, ccname); + ret = pack_buffer(r, EOK, ccname, expire_time); } else { krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr); if (krb5_msg == NULL) { @@ -282,7 +287,7 @@ static int prepare_response(TALLOC_CTX *mem_ctx, return ENOMEM; } - ret = pack_buffer(r, EFAULT, krb5_msg); + ret = pack_buffer(r, EFAULT, krb5_msg, 0); sss_krb5_free_error_message(krb5_error_ctx, krb5_msg); } @@ -306,6 +311,7 @@ int main(int argc, const char *argv[]) uint8_t *buf = NULL; ssize_t len = 0; const char *ccname = NULL; + time_t expire_time = 0; struct input_buffer *ibuf = NULL; struct response *resp = NULL; size_t written; @@ -392,13 +398,13 @@ int main(int argc, const char *argv[]) kerr = ldap_child_get_tgt_sync(main_ctx, ibuf->realm_str, ibuf->princ_str, - ibuf->keytab_name, &ccname); + ibuf->keytab_name, &ccname, &expire_time); if (kerr != EOK) { DEBUG(1, ("ldap_child_get_tgt_sync failed.\n")); /* Do not return, must report failure */ } - ret = prepare_response(main_ctx, ccname, kerr, &resp); + ret = prepare_response(main_ctx, ccname, expire_time, kerr, &resp); if (ret != EOK) { DEBUG(1, ("prepare_response failed. [%d][%s].\n", ret, strerror(ret))); return ENOMEM; diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 007185f..8d025ba 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -70,6 +70,8 @@ struct ldap_cb_data { struct sdap_handle { LDAP *ldap; bool connected; + /* Authentication ticket expiration time (if any) */ + time_t expire_time; #ifdef HAVE_LDAP_CONNCB struct ldap_conncb *conncb; diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index 3c52d23..020165e 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -66,7 +66,7 @@ struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx, const char *keytab, const char *principal, const char *realm); -int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result); +int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result, time_t *expire_time); struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx, struct tevent_context *ev, diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c index ad3d241..b52764e 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -607,6 +607,7 @@ static int sasl_bind_recv(struct tevent_req *req, int *ldaperr) struct sdap_kinit_state { int result; + time_t expire_time; }; static void sdap_kinit_done(struct tevent_req *subreq); @@ -659,8 +660,9 @@ static void sdap_kinit_done(struct tevent_req *subreq) int ret; int result; char *ccname = NULL; + time_t expire_time; - ret = sdap_get_tgt_recv(subreq, state, &result, &ccname); + ret = sdap_get_tgt_recv(subreq, state, &result, &ccname, &expire_time); talloc_zfree(subreq); if (ret != EOK) { state->result = SDAP_AUTH_FAILED; @@ -677,6 +679,7 @@ static void sdap_kinit_done(struct tevent_req *subreq) tevent_req_error(req, EFAULT); } + state->expire_time = expire_time; state->result = SDAP_AUTH_SUCCESS; tevent_req_done(req); return; @@ -687,7 +690,7 @@ static void sdap_kinit_done(struct tevent_req *subreq) tevent_req_error(req, EIO); } -int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result) +int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result, time_t *expire_time) { struct sdap_kinit_state *state = tevent_req_data(req, struct sdap_kinit_state); @@ -702,6 +705,7 @@ int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result) } *result = state->result; + *expire_time = state->expire_time; return EOK; } @@ -1035,10 +1039,14 @@ static void sdap_cli_kinit_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); + struct sdap_cli_connect_state *state = tevent_req_data(req, + struct sdap_cli_connect_state); + enum sdap_result result; + time_t expire_time; int ret; - ret = sdap_kinit_recv(subreq, &result); + ret = sdap_kinit_recv(subreq, &result, &expire_time); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); @@ -1048,6 +1056,7 @@ static void sdap_cli_kinit_done(struct tevent_req *subreq) tevent_req_error(req, EACCES); return; } + state->sh->expire_time = expire_time; sdap_cli_auth_step(req); } diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h index 55f76ed..a676364 100644 --- a/src/providers/ldap/sdap_async_private.h +++ b/src/providers/ldap/sdap_async_private.h @@ -63,6 +63,7 @@ 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, - char **ccname); + char **ccname, + time_t *expire_time); #endif /* _SDAP_ASYNC_PRIVATE_H_ */ diff --git a/src/providers/ldap/sdap_child_helpers.c b/src/providers/ldap/sdap_child_helpers.c index 273fc67..af5c408 100644 --- a/src/providers/ldap/sdap_child_helpers.c +++ b/src/providers/ldap/sdap_child_helpers.c @@ -30,6 +30,7 @@ #include "util/util.h" #include "providers/ldap/ldap_common.h" +#include "providers/ldap/sdap_async_private.h" #include "providers/child_common.h" #ifndef SSSD_LIBEXEC_PATH @@ -194,12 +195,15 @@ 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) + int *result, char **ccache, + time_t *expire_time_out) { size_t p = 0; uint32_t len; uint32_t res; - char *ccn; + char *ccn = 0; + time_t expire_time; + int retval = EOK; /* operation result code */ SAFEALIGN_COPY_UINT32_CHECK(&res, buf + p, size, &p); @@ -207,19 +211,34 @@ static int parse_child_response(TALLOC_CTX *mem_ctx, /* ccache name size */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); - if ((p + len ) > size) return EINVAL; - + if ((p + len ) > size) + return EINVAL; + ccn = talloc_size(mem_ctx, sizeof(char) * (len + 1)); if (ccn == NULL) { DEBUG(1, ("talloc_size failed.\n")); return ENOMEM; } - memcpy(ccn, buf+p, sizeof(char) * (len + 1)); + safealign_memcpy(ccn, buf+p, sizeof(char) * len, &p); ccn[len] = '\0'; + + if (p + sizeof(time_t) > size) { + retval = EINVAL; + goto cleanup; + } + safealign_memcpy(&expire_time, buf+p, sizeof(time_t), &p); *result = res; *ccache = ccn; - return EOK; + *expire_time_out = expire_time; + return retval; + +cleanup: + if (ccn != 0) { + talloc_free(ccn); + } + + return retval; } /* ==The-public-async-interface============================================*/ @@ -352,25 +371,28 @@ 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) + char **ccname, + time_t *expire_time_out) { struct sdap_get_tgt_state *state = tevent_req_data(req, struct sdap_get_tgt_state); char *ccn; + time_t expire_time; int res; int ret; TEVENT_REQ_RETURN_ON_ERROR(req); - ret = parse_child_response(mem_ctx, state->buf, state->len, &res, &ccn); + ret = parse_child_response(mem_ctx, state->buf, state->len, &res, &ccn, &expire_time); if (ret != EOK) { DEBUG(1, ("Cannot parse child response: [%d][%s]\n", ret, strerror(ret))); return ret; } - DEBUG(6, ("Child responded: %d [%s]\n", res, ccn)); + DEBUG(6, ("Child responded: %d [%s], expired on [%ld]\n", res, ccn, (long)expire_time)); *result = res; *ccname = ccn; + *expire_time_out = expire_time; return EOK; } -- 1.6.6.1