From cbd8f27e83d92de46e0c43cb9bdc316d282db7f3 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Tue, 11 May 2010 17:51:02 +0200 Subject: [PATCH] Add ldap_krb5_ticket_lifetime option --- src/config/SSSDConfig.py | 1 + src/config/etc/sssd.api.d/sssd-ipa.conf | 1 + src/config/etc/sssd.api.d/sssd-ldap.conf | 1 + src/man/sssd-ldap.5.xml | 13 +++++++++++++ src/providers/ipa/ipa_common.c | 3 ++- src/providers/ipa/ipa_common.h | 2 +- src/providers/ldap/ldap_child.c | 11 ++++++++--- src/providers/ldap/ldap_common.c | 3 ++- src/providers/ldap/sdap.h | 1 + src/providers/ldap/sdap_async.h | 3 ++- src/providers/ldap/sdap_async_connection.c | 18 ++++++++++++++---- src/providers/ldap/sdap_async_private.h | 1 + src/providers/ldap/sdap_child_helpers.c | 9 +++++++-- src/util/util.h | 5 +++++ 14 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index 7082861..6b759d8 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -126,6 +126,7 @@ option_strings = { 'ldap_krb5_keytab' : _('Kerberos service keytab'), 'ldap_krb5_init_creds' : _('Use Kerberos auth for LDAP connection'), 'ldap_referrals' : _('Follow LDAP referrals'), + 'ldap_krb5_ticket_lifetime' : _('Lifetime of TGT for LDAP connection'), # [provider/ldap/id] 'ldap_search_timeout' : _('Length of time to wait for a search request'), diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf index 7fbc312..75a08ac 100644 --- a/src/config/etc/sssd.api.d/sssd-ipa.conf +++ b/src/config/etc/sssd.api.d/sssd-ipa.conf @@ -26,6 +26,7 @@ ldap_krb5_init_creds = bool, None, false ldap_entry_usn = str, None, false ldap_rootdse_last_usn = str, None, false ldap_referrals = bool, None, false +ldap_krb5_ticket_lifetime = int, None, false [provider/ipa/id] ldap_search_timeout = int, None, false diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index d2b47e1..9ce91dc 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -20,6 +20,7 @@ ldap_krb5_init_creds = bool, None, false ldap_entry_usn = str, None, false ldap_rootdse_last_usn = str, None, false ldap_referrals = bool, None, false +ldap_krb5_ticket_lifetime = int, None, false [provider/ldap/id] ldap_search_timeout = int, None, false diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index c119e7f..9b1f14b 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -569,6 +569,19 @@ + ldap_krb5_ticket_lifetime (integer) + + + Specifies the lifetime in seconds of the TGT if + GSSAPI is used. + + + Default: 86400 (24 hours) + + + + + krb5_realm (string) diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index 4b7dfba..47c283e 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -70,7 +70,8 @@ struct dp_option ipa_def_ldap_opts[] = { { "ldap_pwd_policy", DP_OPT_STRING, { "none" } , NULL_STRING }, { "ldap_referrals", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "account_cache_expiration", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, - { "ldap_dns_service_name", DP_OPT_STRING, { SSS_LDAP_SRV_NAME }, NULL_STRING } + { "ldap_dns_service_name", DP_OPT_STRING, { SSS_LDAP_SRV_NAME }, NULL_STRING }, + { "ldap_krb5_ticket_lifetime", DP_OPT_NUMBER, { .number = (24 * 60 * 60) }, NULL_NUMBER } }; struct sdap_attr_map ipa_attr_map[] = { diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 2d87186..9678e0c 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -35,7 +35,7 @@ struct ipa_service { /* the following defines are used to keep track of the options in the ldap * module, so that if they change and ipa is not updated correspondingly * this will trigger a runtime abort error */ -#define IPA_OPTS_BASIC_TEST 33 +#define IPA_OPTS_BASIC_TEST 34 /* the following define is used to keep track of the options in the krb5 * module, so that if they change and ipa is not updated correspondingly diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c index 6a78ca0..3369d70 100644 --- a/src/providers/ldap/ldap_child.c +++ b/src/providers/ldap/ldap_child.c @@ -40,6 +40,7 @@ struct input_buffer { const char *realm_str; const char *princ_str; const char *keytab_name; + krb5_deltat lifetime; }; static errno_t unpack_buffer(uint8_t *buf, size_t size, @@ -86,6 +87,10 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, p += len; } + /* ticket lifetime */ + SAFEALIGN_COPY_INT32_CHECK(&ibuf->lifetime, buf + p, size, &p); + DEBUG(7, ("lifetime: %d\n", ibuf->lifetime)); + return EOK; } @@ -118,6 +123,7 @@ static int ldap_child_get_tgt_sync(TALLOC_CTX *memctx, const char *realm_str, const char *princ_str, const char *keytab_name, + const krb5_deltat lifetime, const char **ccname_out) { char *ccname; @@ -220,8 +226,7 @@ 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); + krb5_get_init_creds_opt_set_tkt_life(&options, lifetime); krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc, keytab, 0, NULL, &options); @@ -392,7 +397,7 @@ 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, ibuf->lifetime, &ccname); if (kerr != EOK) { DEBUG(1, ("ldap_child_get_tgt_sync failed.\n")); /* Do not return, must report failure */ diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index 03b2133..3205718 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -64,7 +64,8 @@ struct dp_option default_basic_opts[] = { { "ldap_pwd_policy", DP_OPT_STRING, { "none" } , NULL_STRING }, { "ldap_referrals", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "account_cache_expiration", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, - { "ldap_dns_service_name", DP_OPT_STRING, { SSS_LDAP_SRV_NAME }, NULL_STRING } + { "ldap_dns_service_name", DP_OPT_STRING, { SSS_LDAP_SRV_NAME }, NULL_STRING }, + { "ldap_krb5_ticket_lifetime", DP_OPT_NUMBER, { .number = (24 * 60 * 60) }, NULL_NUMBER } }; struct sdap_attr_map generic_attr_map[] = { diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index a4da43b..917e601 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -151,6 +151,7 @@ enum sdap_basic_opt { SDAP_REFERRALS, SDAP_ACCOUNT_CACHE_EXPIRATION, SDAP_DNS_SERVICE_NAME, + SDAP_KRB5_TICKET_LIFETIME, SDAP_OPTS_BASIC /* opts counter */ }; diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index 888df6b..1e52c48 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -65,7 +65,8 @@ struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx, int timeout, const char *keytab, const char *principal, - const char *realm); + const char *realm, + int lifetime); int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result); struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx, diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c index bd8d4e9..2748ed5 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -607,14 +607,21 @@ struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx, int timeout, const char *keytab, const char *principal, - const char *realm) + const char *realm, + int lifetime) { struct tevent_req *req; struct tevent_req *subreq; struct sdap_kinit_state *state; int ret; - DEBUG(6, ("Attempting kinit (%s, %s, %s)\n", keytab, principal, realm)); + DEBUG(6, ("Attempting kinit (%s, %s, %s, %d)\n", keytab, principal, realm, + lifetime)); + + if (lifetime < 0 || lifetime > INT32_MAX) { + DEBUG(1, ("Ticket lifetime out of range.\n")); + return NULL; + } req = tevent_req_create(memctx, &state, struct sdap_kinit_state); if (!req) return NULL; @@ -629,7 +636,8 @@ struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx, } } - subreq = sdap_get_tgt_send(state, ev, realm, principal, keytab, timeout); + subreq = sdap_get_tgt_send(state, ev, realm, principal, keytab, lifetime, + timeout); if (!subreq) { talloc_zfree(req); return NULL; @@ -1055,7 +1063,9 @@ static void sdap_cli_kinit_step(struct tevent_req *req) dp_opt_get_string(state->opts->basic, SDAP_SASL_AUTHID), dp_opt_get_string(state->opts->basic, - SDAP_KRB5_REALM)); + SDAP_KRB5_REALM), + dp_opt_get_int(state->opts->basic, + SDAP_KRB5_TICKET_LIFETIME)); if (!subreq) { tevent_req_error(req, ENOMEM); return; diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h index c74a7e6..727cee2 100644 --- a/src/providers/ldap/sdap_async_private.h +++ b/src/providers/ldap/sdap_async_private.h @@ -58,6 +58,7 @@ struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx, const char *realm_str, const char *princ_str, const char *keytab_name, + int32_t lifetime, int timeout); int sdap_get_tgt_recv(struct tevent_req *req, diff --git a/src/providers/ldap/sdap_child_helpers.c b/src/providers/ldap/sdap_child_helpers.c index c61f3cc..b45e4ea 100644 --- a/src/providers/ldap/sdap_child_helpers.c +++ b/src/providers/ldap/sdap_child_helpers.c @@ -137,6 +137,7 @@ static errno_t create_tgt_req_send_buffer(TALLOC_CTX *mem_ctx, const char *realm_str, const char *princ_str, const char *keytab_name, + int32_t lifetime, struct io_buffer **io_buf) { struct io_buffer *buf; @@ -148,7 +149,7 @@ static errno_t create_tgt_req_send_buffer(TALLOC_CTX *mem_ctx, return ENOMEM; } - buf->size = 3 * sizeof(uint32_t); + buf->size = 4 * sizeof(uint32_t); if (realm_str) { buf->size += strlen(realm_str); } @@ -194,6 +195,9 @@ static errno_t create_tgt_req_send_buffer(TALLOC_CTX *mem_ctx, SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp); } + /* lifetime */ + SAFEALIGN_SET_UINT32(&buf->data[rp], lifetime, &rp); + *io_buf = buf; return EOK; } @@ -248,6 +252,7 @@ struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx, const char *realm_str, const char *princ_str, const char *keytab_name, + int32_t lifetime, int timeout) { struct tevent_req *req, *subreq; @@ -274,7 +279,7 @@ struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx, /* prepare the data to pass to child */ ret = create_tgt_req_send_buffer(state, - realm_str, princ_str, keytab_name, + realm_str, princ_str, keytab_name, lifetime, &buf); if (ret != EOK) { DEBUG(1, ("create_tgt_req_send_buffer failed.\n")); diff --git a/src/util/util.h b/src/util/util.h index 25e7b6c..58c51a0 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -198,6 +198,11 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter) safealign_memcpy(dest, src, sizeof(uint32_t), pctr); \ } while(0) +#define SAFEALIGN_COPY_INT32_CHECK(dest, src, len, pctr) do { \ + if ((*(pctr) + sizeof(int32_t)) > (len)) return EINVAL; \ + safealign_memcpy(dest, src, sizeof(int32_t), pctr); \ +} while(0) + #include "util/dlinklist.h" /* From debug.c */ -- 1.6.6.1