#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
+/* uncomment this to to fast debugging on the krb5 ticket renewal event */
+#ifdef DEBUG_KRB5_TKT_RENEWAL
+#undef DEBUG_KRB5_TKT_RENEWAL
+#endif
+
#define MAX_CCACHES 100
static struct WINBINDD_CCACHE_ENTRY *ccache_list;
+/* The Krb5 ticket refresh handler should be scheduled
+ at one-half of the period from now till the tkt
+ expiration */
+#define KRB5_EVENT_REFRESH_TIME(x) ((x) - (((x) - time(NULL))/2))
+
/****************************************************************
Find an entry by name.
****************************************************************/
Do the work of refreshing the ticket.
****************************************************************/
-static void krb5_ticket_refresh_handler(struct timed_event *te,
+static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
"for: %s in ccache: %s\n",
entry->principal_name, entry->ccname));
- new_start = entry->refresh_time;
+#if defined(DEBUG_KRB5_TKT_RENEWAL)
+ new_start = time(NULL) + 30;
+#else
+ /* The tkt should be refreshed at one-half the period
+ from now to the expiration time */
+ new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time);
+#endif
goto done;
}
entry->principal_name,
entry->service,
&new_start);
+#if defined(DEBUG_KRB5_TKT_RENEWAL)
+ new_start = time(NULL) + 30;
+#else
+ new_start = KRB5_EVENT_REFRESH_TIME(new_start);
+#endif
+
gain_root_privilege();
if (ret) {
done:
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
timeval_set(new_start, 0),
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
Do the work of regaining a ticket when coming from offline auth.
****************************************************************/
-static void krb5_ticket_gain_handler(struct timed_event *te,
+static void krb5_ticket_gain_handler(struct event_context *event_ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
talloc_get_type_abort(private_data, struct WINBINDD_CCACHE_ENTRY);
#ifdef HAVE_KRB5
int ret;
- time_t new_start;
struct timeval t;
struct WINBINDD_MEMORY_CREDS *cred_ptr = entry->cred_ptr;
struct winbindd_domain *domain = NULL;
DEBUG(10,("krb5_ticket_gain_handler: successful kinit for: %s in ccache: %s\n",
entry->principal_name, entry->ccname));
- new_start = entry->refresh_time;
-
goto got_ticket;
}
retry_later:
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0),
"krb5_ticket_gain_handler",
krb5_ticket_gain_handler,
got_ticket:
-#if 0 /* TESTING */
+#if defined(DEBUG_KRB5_TKT_RENEWAL)
t = timeval_set(time(NULL) + 30, 0);
#else
- t = timeval_set(new_start, 0);
-#endif /* TESTING */
+ t = timeval_set(KRB5_EVENT_REFRESH_TIME(entry->refresh_time), 0);
+#endif
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
t,
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
#endif
}
+/****************************************************************
+ Check if an ccache entry exists.
+****************************************************************/
+
+BOOL ccache_entry_exists(const char *username)
+{
+ struct WINBINDD_CCACHE_ENTRY *entry = get_ccache_by_username(username);
+ return (entry != NULL);
+}
+
/****************************************************************
Ensure we're changing the correct entry.
****************************************************************/
time_t create_time,
time_t ticket_end,
time_t renew_until,
- BOOL schedule_refresh_event,
BOOL postponed_request)
{
struct WINBINDD_CCACHE_ENTRY *entry = NULL;
entry->ref_count++;
DEBUG(10,("add_ccache_to_list: ref count on entry %s is now %d\n",
username, entry->ref_count));
+ /* FIXME: in this case we still might want to have a krb5 cred
+ * event handler created - gd*/
return NT_STATUS_OK;
}
entry->uid = uid;
entry->ref_count = 1;
- if (schedule_refresh_event && renew_until > 0) {
+ if (lp_winbind_refresh_tickets() && renew_until > 0) {
if (postponed_request) {
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0),
"krb5_ticket_gain_handler",
krb5_ticket_gain_handler,
entry);
} else {
- entry->event = add_timed_event(entry,
- timeval_set((ticket_end - 1), 0),
+ /* Renew at 1/2 the ticket expiration time */
+ entry->event = event_add_timed(winbind_event_context(), entry,
+#if defined(DEBUG_KRB5_TKT_RENEWAL)
+ timeval_set(time(NULL)+30, 0),
+#else
+ timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0),
+#endif
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
entry);
NTSTATUS remove_ccache(const char *username)
{
struct WINBINDD_CCACHE_ENTRY *entry = get_ccache_by_username(username);
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
#ifdef HAVE_KRB5
krb5_error_code ret;
#endif
memcredp->len += strlen(pass)+1;
}
- memcredp->nt_hash = (unsigned char *)TALLOC_ZERO(memcredp, memcredp->len);
+
+#if defined(LINUX)
+ /* aligning the memory on on x86_64 and compiling
+ with gcc 4.1 using -O2 causes a segv in the
+ next memset() --jerry */
+ memcredp->nt_hash = SMB_MALLOC_ARRAY(unsigned char, memcredp->len);
+#else
+ /* On non-linux platforms, mlock()'d memory must be aligned */
+ memcredp->nt_hash = SMB_MEMALIGN_ARRAY(unsigned char,
+ getpagesize(), memcredp->len);
+#endif
if (!memcredp->nt_hash) {
return NT_STATUS_NO_MEMORY;
}
+ memset( memcredp->nt_hash, 0x0, memcredp->len );
memcredp->lm_hash = memcredp->nt_hash + NT_HASH_LEN;
+
#ifdef DEBUG_PASSWORD
DEBUG(10,("mlocking memory: %p\n", memcredp->nt_hash));
#endif
-
if ((mlock(memcredp->nt_hash, memcredp->len)) == -1) {
DEBUG(0,("failed to mlock memory: %s (%d)\n",
strerror(errno), errno));
+ SAFE_FREE(memcredp->nt_hash);
return map_nt_error_from_unix(errno);
}
return map_nt_error_from_unix(errno);
}
memset(memcredp->nt_hash, '\0', memcredp->len);
- TALLOC_FREE(memcredp->nt_hash);
+ SAFE_FREE(memcredp->nt_hash);
+ memcredp->nt_hash = NULL;
memcredp->lm_hash = NULL;
memcredp->pass = NULL;
memcredp->len = 0;