#include "includes.h"
#include "winbindd.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "smb_krb5.h"
+
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
static struct WINBINDD_CCACHE_ENTRY *ccache_list;
static void krb5_ticket_gain_handler(struct event_context *,
struct timed_event *,
- const struct timeval *,
+ struct timeval,
void *);
+static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *,
+ struct timeval);
/* The Krb5 ticket refresh handler should be scheduled
at one-half of the period from now till the tkt
static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
struct timed_event *te,
- const struct timeval *now,
+ struct timeval now,
void *private_data)
{
struct WINBINDD_CCACHE_ENTRY *entry =
/* Don't break the ticket refresh chain: retry
* refreshing ticket sometime later when KDC is
- * unreachable -- BoYang
+ * unreachable -- BoYang. More error code handling
+ * here?
* */
if ((ret == KRB5_KDC_UNREACH)
new_start = time(NULL) +
MAX(30, lp_winbind_cache_time());
#endif
- /* try to regain ticket here */
- entry->event = event_add_timed(winbind_event_context(),
- entry,
- timeval_set(new_start, 0),
- "krb5_ticket_gain_handler",
- krb5_ticket_gain_handler,
- entry);
+ add_krb5_ticket_gain_handler_event(entry,
+ timeval_set(new_start, 0));
return;
}
TALLOC_FREE(entry->event);
/* avoid breaking the renewal chain: retry in
* lp_winbind_cache_time() seconds when the KDC was not
* available right now.
- * the return code can be KRB5_REALM_CANT_RESOLVE*/
+ * the return code can be KRB5_REALM_CANT_RESOLVE.
+ * More error code handling here? */
if ((ret == KRB5_KDC_UNREACH)
|| (ret == KRB5_REALM_CANT_RESOLVE)) {
#endif
/* ticket is destroyed here, we have to regain it
* if it is possible */
- entry->event = event_add_timed(winbind_event_context(),
- entry,
- timeval_set(new_start, 0),
- "krb5_ticket_gain_handler",
- krb5_ticket_gain_handler,
- entry);
+ add_krb5_ticket_gain_handler_event(entry,
+ timeval_set(new_start, 0));
return;
}
&& (entry->renew_until <= expire_time)) {
/* try to regain ticket 10 seconds beforre expiration */
expire_time -= 10;
- entry->event = event_add_timed(winbind_event_context(), entry,
- timeval_set(expire_time, 0),
- "krb5_ticket_gain_handler",
- krb5_ticket_gain_handler,
- entry);
+ add_krb5_ticket_gain_handler_event(entry,
+ timeval_set(expire_time, 0));
return;
}
}
entry->event = event_add_timed(winbind_event_context(), entry,
timeval_set(new_start, 0),
- "krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
static void krb5_ticket_gain_handler(struct event_context *event_ctx,
struct timed_event *te,
- const struct timeval *now,
+ struct timeval now,
void *private_data)
{
struct WINBINDD_CCACHE_ENTRY *entry =
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
#endif
- entry->refresh_time = 0;
- entry->event = event_add_timed(winbind_event_context(),
- entry,
- t,
- "krb5_ticket_gain_handler",
- krb5_ticket_gain_handler,
- entry);
-
+ add_krb5_ticket_gain_handler_event(entry, t);
return;
got_ticket:
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
- "krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
#endif
}
+/**************************************************************
+ The gain initial ticket case is recognised as entry->refresh_time
+ is always zero.
+**************************************************************/
+
+static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *entry,
+ struct timeval t)
+{
+ entry->refresh_time = 0;
+ entry->event = event_add_timed(winbind_event_context(),
+ entry,
+ t,
+ krb5_ticket_gain_handler,
+ entry);
+}
+
void ccache_regain_all_now(void)
{
struct WINBINDD_CCACHE_ENTRY *cur;
new_event = event_add_timed(winbind_event_context(),
cur,
t,
- "krb5_ticket_gain_handler",
krb5_ticket_gain_handler,
cur);
} else {
new_event = event_add_timed(winbind_event_context(),
cur,
t,
- "krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
cur);
}
const char *ccname,
const char *service,
const char *username,
+ const char *pass,
const char *realm,
uid_t uid,
time_t create_time,
if (!entry->event) {
if (postponed_request) {
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
- entry->event = event_add_timed(winbind_event_context(),
- entry,
- t,
- "krb5_ticket_gain_handler",
- krb5_ticket_gain_handler,
- entry);
+ add_krb5_ticket_gain_handler_event(entry, t);
} else {
/* Renew at 1/2 the ticket expiration time */
#if defined(DEBUG_KRB5_TKT_RENEWAL)
#else
t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0);
#endif
+ if (!entry->refresh_time) {
+ entry->refresh_time = t.tv_sec;
+ }
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
- "krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
}
DEBUG(10,("add_ccache_to_list: added krb5_ticket handler\n"));
}
-
+
+ /*
+ * If we're set up to renew our krb5 tickets, we must
+ * cache the credentials in memory for the ticket
+ * renew function (or increase the reference count
+ * if we're logging in more than once). Fix inspired
+ * by patch from Ian Gordon <ian.gordon@strath.ac.uk>
+ * for bugid #9098.
+ */
+
+ ntret = winbindd_add_memory_creds(username, uid, pass);
+ DEBUG(10, ("winbindd_add_memory_creds returned: %s\n",
+ nt_errstr(ntret)));
+
return NT_STATUS_OK;
}
if (postponed_request) {
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
- entry->refresh_time = 0;
- entry->event = event_add_timed(winbind_event_context(),
- entry,
- t,
- "krb5_ticket_gain_handler",
- krb5_ticket_gain_handler,
- entry);
+ add_krb5_ticket_gain_handler_event(entry, t);
} else {
/* Renew at 1/2 the ticket expiration time */
#if defined(DEBUG_KRB5_TKT_RENEWAL)
entry->event = event_add_timed(winbind_event_context(),
entry,
t,
- "krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
}
"added ccache [%s] for user [%s] to the list\n",
ccname, username));
+ if (entry->event) {
+ /*
+ * If we're set up to renew our krb5 tickets, we must
+ * cache the credentials in memory for the ticket
+ * renew function. Fix inspired by patch from
+ * Ian Gordon <ian.gordon@strath.ac.uk> for
+ * bugid #9098.
+ */
+
+ ntret = winbindd_add_memory_creds(username, uid, pass);
+ DEBUG(10, ("winbindd_add_memory_creds returned: %s\n",
+ nt_errstr(ntret)));
+ }
+
return NT_STATUS_OK;
no_mem: