char *kdc_server;
unsigned flags;
int time_offset;
- time_t expire;
+ time_t tgt_expire;
+ time_t tgs_expire;
time_t renewable;
} auth;
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);
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) {
}
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",
}
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;
}
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);
#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) &&
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)) {
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)));
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;
}
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",
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++;
}
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);
*/
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;
&auth_context,
AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts,
principal,
- ccdef, &packet))) {
+ ccdef, &packet,
+ tgs_expire))) {
goto failed;
}
/* 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;
*/
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;
/* 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;
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);
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");
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);
}
&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)));
/* 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 "
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) {
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)));