summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/include/ads.h3
-rw-r--r--source/include/includes.h2
-rw-r--r--source/libads/kerberos.c6
-rw-r--r--source/libads/ldap_utils.c4
-rw-r--r--source/libads/sasl.c8
-rw-r--r--source/libsmb/cliconnect.c2
-rw-r--r--source/libsmb/clikrb5.c20
-rw-r--r--source/libsmb/clispnego.c6
-rw-r--r--source/nsswitch/idmap_ad.c13
-rw-r--r--source/nsswitch/winbindd_ads.c32
-rw-r--r--source/nsswitch/winbindd_pam.c3
-rw-r--r--source/rpc_client/cli_pipe.c2
-rw-r--r--source/utils/ntlm_auth.c4
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)));