user-directory.c revision 79ee504bdf920f01e12e28f238799bf2616489df
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2010-2016 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* n% of timeout_secs */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen/* but min/max. of this many secs */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* unsigned int username_hash => user */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* sorted by time */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* If user's expire time is less than this many seconds away,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen don't assume that other directors haven't yet expired it */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void user_move_iters(struct user_directory *dir, struct user *user)
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenstatic void user_free(struct user_directory *dir, struct user *user)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* director_user_expire is very short. user expired before
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen moving the user finished or timed out. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hash_table_remove(dir->hash, POINTER_CAST(user->username_hash));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic bool user_directory_user_has_connections(struct user_directory *dir,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen time_t expire_timestamp = user->timestamp + dir->timeout_secs;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* don't free this user until the kill is finished */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (expire_timestamp + USER_NEAR_EXPIRING_MAX >= ioloop_time)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_warning("User %u weakness appears to be stuck, removing it",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic void user_directory_drop_expired(struct user_directory *dir)
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen !user_directory_user_has_connections(dir, dir->head))
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenunsigned int user_directory_count(struct user_directory *dir)
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenstruct user *user_directory_lookup(struct user_directory *dir,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen user = hash_table_lookup(dir->hash, POINTER_CAST(username_hash));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (user != NULL && !user_directory_user_has_connections(dir, user)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenuser_directory_insert_backwards(struct user_directory *dir,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen DLLIST2_PREPEND(&dir->head, &dir->tail, user);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenuser_directory_insert_forwards(struct user_directory *dir,
struct user *
user);
user);
return user;
if (users_count == 0) {
const char *username)
struct user_directory *
return dir;
struct user_directory_iter *
return iter;
return NULL;
return user;
unsigned int i, count;
for (i = 0; i < count; i++) {