diff options
-rw-r--r-- | source/include/ads.h | 3 | ||||
-rw-r--r-- | source/include/includes.h | 2 | ||||
-rw-r--r-- | source/libads/kerberos.c | 6 | ||||
-rw-r--r-- | source/libads/ldap_utils.c | 4 | ||||
-rw-r--r-- | source/libads/sasl.c | 8 | ||||
-rw-r--r-- | source/libsmb/cliconnect.c | 2 | ||||
-rw-r--r-- | source/libsmb/clikrb5.c | 20 | ||||
-rw-r--r-- | source/libsmb/clispnego.c | 6 | ||||
-rw-r--r-- | source/nsswitch/idmap_ad.c | 13 | ||||
-rw-r--r-- | source/nsswitch/winbindd_ads.c | 32 | ||||
-rw-r--r-- | source/nsswitch/winbindd_pam.c | 3 | ||||
-rw-r--r-- | source/rpc_client/cli_pipe.c | 2 | ||||
-rw-r--r-- | source/utils/ntlm_auth.c | 4 |
13 files changed, 72 insertions, 33 deletions
diff --git a/source/include/ads.h b/source/include/ads.h index d97ae1531f9..29df0d2f353 100644 --- a/source/include/ads.h +++ b/source/include/ads.h @@ -42,7 +42,8 @@ typedef struct { char *kdc_server; unsigned flags; int time_offset; - time_t expire; + time_t tgt_expire; + time_t tgs_expire; time_t renewable; } auth; diff --git a/source/include/includes.h b/source/include/includes.h index d419529986f..7a6064d8264 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -1167,7 +1167,7 @@ BOOL smb_krb5_principal_compare_any_realm(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2); int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, const char *ccname); + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, const char *ccname, time_t *tgs_expire); PAC_LOGON_INFO *get_logon_info_from_pac(PAC_DATA *pac_data); krb5_error_code smb_krb5_renew_ticket(const char *ccache_string, const char *client_string, const char *service_string, time_t *new_start_time); krb5_error_code kpasswd_err_to_krb5_err(krb5_error_code res_code); diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c index 92461bd9c1e..8e8297b07e5 100644 --- a/source/libads/kerberos.c +++ b/source/libads/kerberos.c @@ -110,6 +110,10 @@ int kerberos_kinit_password_ext(const char *principal, krb5_get_init_creds_opt_set_renew_life(opt, renewable_time); krb5_get_init_creds_opt_set_forwardable(opt, True); +#if 0 + /* insane testing */ + krb5_get_init_creds_opt_set_tkt_life(opt, 60); +#endif #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PAC_REQUEST if (request_pac) { @@ -216,7 +220,7 @@ int ads_kinit_password(ADS_STRUCT *ads) } ret = kerberos_kinit_password_ext(s, ads->auth.password, ads->auth.time_offset, - &ads->auth.expire, NULL, NULL, False, False, ads->auth.renewable); + &ads->auth.tgt_expire, NULL, NULL, False, False, ads->auth.renewable); if (ret) { DEBUG(0,("kerberos_kinit_password %s failed: %s\n", diff --git a/source/libads/ldap_utils.c b/source/libads/ldap_utils.c index 13782309c72..4edd73c18d7 100644 --- a/source/libads/ldap_utils.c +++ b/source/libads/ldap_utils.c @@ -110,10 +110,10 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind } SAFE_FREE(bp); - if (!ADS_ERR_OK(status)) + if (!ADS_ERR_OK(status)) { DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(status))); - + } return status; } diff --git a/source/libads/sasl.c b/source/libads/sasl.c index 7d1fd0d1a83..61fd54da1da 100644 --- a/source/libads/sasl.c +++ b/source/libads/sasl.c @@ -147,7 +147,8 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip DATA_BLOB session_key = data_blob(NULL, 0); int rc; - rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0); + rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0, + &ads->auth.tgs_expire); if (rc) { return ADS_ERROR_KRB5(rc); @@ -218,7 +219,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) #endif free(OIDs[i]); } - DEBUG(3,("ads_sasl_spnego_bind: got server principal name =%s\n", principal)); + DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal)); #ifdef HAVE_KRB5 if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) && @@ -229,6 +230,9 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) return status; } + DEBUG(10,("ads_sasl_spnego_krb5_bind failed with: %s, " + "calling kinit\n", ads_errstr(status))); + status = ADS_ERROR_KRB5(ads_kinit_password(ads)); if (ADS_ERR_OK(status)) { diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c index f29449cfb22..2742d70194b 100644 --- a/source/libsmb/cliconnect.c +++ b/source/libsmb/cliconnect.c @@ -554,7 +554,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0); + rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL); if (rc) { DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc))); diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index 305139e1f47..f06a19b345c 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -551,7 +551,8 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, const krb5_flags ap_req_options, const char *principal, krb5_ccache ccache, - krb5_data *outbuf) + krb5_data *outbuf, + time_t *expire_time) { krb5_error_code retval; krb5_principal server; @@ -584,6 +585,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, } while (!creds_ready && (i < maxtries)) { + if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", @@ -599,8 +601,9 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_set_real_time(context, t + time_offset + 1, 0); } - if (!ads_cleanup_expired_creds(context, ccache, credsp)) + if (!ads_cleanup_expired_creds(context, ccache, credsp)) { creds_ready = True; + } i++; } @@ -610,6 +613,10 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, http_timestring((unsigned)credsp->times.endtime), (unsigned)credsp->times.endtime)); + if (expire_time) { + *expire_time = (time_t)credsp->times.endtime; + } + in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); @@ -634,7 +641,9 @@ cleanup_princ: */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, - uint32 extra_ap_opts, const char *ccname) + uint32 extra_ap_opts, const char *ccname, + time_t *tgs_expire) + { krb5_error_code retval; krb5_data packet; @@ -678,7 +687,8 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, &auth_context, AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts, principal, - ccdef, &packet))) { + ccdef, &packet, + tgs_expire))) { goto failed; } @@ -1409,7 +1419,7 @@ done: /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, - const char *ccname) + const char *ccname, time_t *tgs_expire) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return 1; diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c index a01c009b6e3..6aca217e259 100644 --- a/source/libsmb/clispnego.c +++ b/source/libsmb/clispnego.c @@ -343,7 +343,8 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) */ int spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *targ, - DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) + DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, + time_t *expire_time) { int retval; DATA_BLOB tkt, tkt_wrapped; @@ -351,7 +352,8 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, /* get a kerberos ticket for the service and extract the session key */ retval = cli_krb5_get_ticket(principal, time_offset, - &tkt, session_key_krb5, extra_ap_opts, NULL); + &tkt, session_key_krb5, extra_ap_opts, NULL, + expire_time); if (retval) return retval; diff --git a/source/nsswitch/idmap_ad.c b/source/nsswitch/idmap_ad.c index a0ed0847657..fee53a0539e 100644 --- a/source/nsswitch/idmap_ad.c +++ b/source/nsswitch/idmap_ad.c @@ -64,16 +64,23 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void) struct in_addr dc_ip; if (ad_idmap_ads != NULL) { + + time_t expire; + time_t now = time(NULL); + ads = ad_idmap_ads; + expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire); + /* check for a valid structure */ + DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n", + (uint32)expire-(uint32)now, (uint32) expire, (uint32) now)); - DEBUG(7, ("Current tickets expire at %d, time is now %d\n", - (uint32) ads->auth.expire, (uint32) time(NULL))); - if ( ads->config.realm && (ads->auth.expire > time(NULL))) { + if ( ads->config.realm && (expire > time(NULL))) { return ads; } else { /* we own this ADS_STRUCT so make sure it goes away */ + DEBUG(7,("Deleting expired krb5 credential cache\n")); ads->is_mine = True; ads_destroy( &ads ); ads_kdestroy(WINBIND_CCACHE_NAME); diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c index c582ff730b7..5b0a13afa28 100644 --- a/source/nsswitch/winbindd_ads.c +++ b/source/nsswitch/winbindd_ads.c @@ -44,17 +44,23 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) DEBUG(10,("ads_cached_connection\n")); if (domain->private_data) { - ads = (ADS_STRUCT *)domain->private_data; + + time_t expire; + time_t now = time(NULL); /* check for a valid structure */ + ads = (ADS_STRUCT *)domain->private_data; - DEBUG(7, ("Current tickets expire at %d, time is now %d\n", - (uint32) ads->auth.expire, (uint32) time(NULL))); - if ( ads->config.realm && (ads->auth.expire > time(NULL))) { + expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire); + + DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n", + (uint32)expire-(uint32)now, (uint32) expire, (uint32) now)); + + if ( ads->config.realm && (expire > now)) { return ads; - } - else { + } else { /* we own this ADS_STRUCT so make sure it goes away */ + DEBUG(7,("Deleting expired krb5 credential cache\n")); ads->is_mine = True; ads_destroy( &ads ); ads_kdestroy("MEMORY:winbind_ccache"); @@ -998,11 +1004,15 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) if (!ADS_ERR_OK(rc)) { - /* its a dead connection ; don't destroy it - through since ads_USN() has already done - that indirectly */ - - domain->private_data = NULL; + /* its a dead connection, destroy it */ + + if (domain->private_data) { + ads = (ADS_STRUCT *)domain->private_data; + ads->is_mine = True; + ads_destroy(&ads); + ads_kdestroy("MEMORY:winbind_ccache"); + domain->private_data = NULL; + } } return ads_ntstatus(rc); } diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c index fcaad1fb1f8..2a5ca40125e 100644 --- a/source/nsswitch/winbindd_pam.c +++ b/source/nsswitch/winbindd_pam.c @@ -598,7 +598,8 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, &tkt, &session_key_krb5, 0, - cc); + cc, + NULL); if (krb5_ret) { DEBUG(1,("winbindd_raw_kerberos_login: failed to get ticket for %s: %s\n", local_service, error_message(krb5_ret))); diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c index 467e652ca99..547f300f3ae 100644 --- a/source/rpc_client/cli_pipe.c +++ b/source/rpc_client/cli_pipe.c @@ -927,7 +927,7 @@ static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli, /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */ ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt, - &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL); + &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL); if (ret) { DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s " diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c index 28de39c4f45..1e7b361e860 100644 --- a/source/utils/ntlm_auth.c +++ b/source/utils/ntlm_auth.c @@ -1424,7 +1424,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) spnego.negTokenInit.mechListMIC.length); principal[spnego.negTokenInit.mechListMIC.length] = '\0'; - retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL); + retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL); if (retval) { @@ -1446,7 +1446,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego) return False; } - retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL); + retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL); if (retval) { DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval))); |