From 9a8e30d04b1cfc53e8c8949a56d4f1cf5aa26501 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 24 Mar 2004 17:32:55 +0000 Subject: Fix bugzilla # 1208 Winbind tickets expired. We now check the expiration time, and acquire new tickets. We couln't rely on renewing them, because if we didn't get a request before they expired, we wouldn't have renewed them. Also, there is a one-week limit in MS on renewal life, so new tickets would have been needed after a week anyway. Default is 10 hours, so we should only be acquiring them that often, unless the configuration on the DC is changed (and the minimum is 1 hour). (This used to be commit c2436c433afaab4006554a86307f76b6689d6929) --- source3/include/ads.h | 1 + source3/libads/kerberos.c | 39 +++++++++++++++++++++++++++++++++++++-- source3/libads/krb5_setpw.c | 2 +- source3/libsmb/cliconnect.c | 2 +- source3/nsswitch/winbindd_ads.c | 6 +++++- source3/utils/ntlm_auth.c | 3 ++- 6 files changed, 47 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/include/ads.h b/source3/include/ads.h index 5ae577efe7..4daa65e796 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -29,6 +29,7 @@ typedef struct { char *kdc_server; unsigned flags; int time_offset; + time_t expire; } auth; /* info derived from the servers config */ diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index bef2febaef..70f6f3386c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -54,7 +54,7 @@ kerb_prompter(krb5_context ctx, void *data, simulate a kinit, putting the tgt in the default cache location remus@snapserver.com */ -int kerberos_kinit_password(const char *principal, const char *password, int time_offset) +int kerberos_kinit_password(const char *principal, const char *password, int time_offset, time_t *expire_time) { krb5_context ctx; krb5_error_code code = 0; @@ -102,6 +102,9 @@ int kerberos_kinit_password(const char *principal, const char *password, int tim return code; } + if (expire_time) + *expire_time = (time_t) my_creds.times.endtime; + krb5_cc_close(ctx, cc); krb5_free_cred_contents(ctx, &my_creds); krb5_free_principal(ctx, me); @@ -126,7 +129,7 @@ int ads_kinit_password(ADS_STRUCT *ads) return KRB5_LIBOS_CANTREADPWD; } - ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset); + ret = kerberos_kinit_password(s, ads->auth.password, ads->auth.time_offset, &ads->auth.expire); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", @@ -136,5 +139,37 @@ int ads_kinit_password(ADS_STRUCT *ads) return ret; } +int ads_kdestroy(const char *cc_name) +{ + krb5_error_code code; + krb5_context ctx; + krb5_ccache cc; + + if ((code = krb5_init_context (&ctx))) { + DEBUG(3, ("ads_kdestroy: kdb5_init_context rc=%d\n", code)); + return code; + } + + if (!cc_name) { + if ((code = krb5_cc_default(ctx, &cc))) { + krb5_free_context(ctx); + return code; + } + } else { + if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_resolve rc=%d\n", + code)); + krb5_free_context(ctx); + return code; + } + } + + if ((code = krb5_cc_destroy (ctx, cc))) { + DEBUG(3, ("ads_kdestroy: krb5_cc_destroy rc=%d\n", code)); + } + + krb5_free_context (ctx); + return code; +} #endif diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 9cf15221a8..16d3df83e9 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -642,7 +642,7 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, { int ret; - if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset))) { + if ((ret = kerberos_kinit_password(auth_principal, auth_password, time_offset, NULL))) { DEBUG(1,("Failed kinit for principal %s (%s)\n", auth_principal, error_message(ret))); return ADS_ERROR_KRB5(ret); } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e75a361e25..3f87119ce2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -718,7 +718,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, int ret; use_in_memory_ccache(); - ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL); if (ret){ DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 889d72293e..47e898fea7 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -43,13 +43,17 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) ads = (ADS_STRUCT *)domain->private; /* check for a valid structure */ - if ( ads->config.realm ) { + + DEBUG(7, ("Current tickets expire at %d\n, time is now %d\n", + (uint32) ads->auth.expire, (uint32) time(NULL))); + if ( ads->config.realm && (ads->auth.expire > time(NULL))) { return ads; } else { /* we own this ADS_STRUCT so make sure it goes away */ ads->is_mine = True; ads_destroy( &ads ); + ads_kdestroy("MEMORY:winbind_ccache"); domain->private = NULL; } } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index ec0f404176..2213a9bae3 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1111,7 +1111,8 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) pstr_sprintf(user, "%s@%s", opt_username, opt_domain); - if ((retval = kerberos_kinit_password(user, opt_password, 0))) { + if ((retval = kerberos_kinit_password(user, opt_password, + 0, NULL))) { DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval))); x_fprintf(x_stdout, "NA\n"); return True; -- cgit