From a7d5aea119599580803bf3e7a515bda730b447dc Mon Sep 17 00:00:00 2001 From: Elizabeth Myers Date: Fri, 25 Mar 2016 20:46:58 -0500 Subject: [PATCH] provider: make blacklist queries come after ident/rdns. --- authd/provider.c | 11 ++++---- authd/provider.h | 18 ++++++++++-- authd/providers/blacklist.c | 56 ++++++++++++++++++++++++++----------- authd/providers/ident.c | 2 +- authd/providers/rdns.c | 2 +- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/authd/provider.c b/authd/provider.c index f0000b1b..e7b07c50 100644 --- a/authd/provider.c +++ b/authd/provider.c @@ -116,7 +116,7 @@ void cancel_providers(struct auth_client *auth) { provider = ptr->data; - if(provider->cancel && is_provider(auth, provider->id)) + if(provider->cancel && is_provider_on(auth, provider->id)) /* Cancel if required */ provider->cancel(auth); } @@ -131,7 +131,8 @@ void provider_done(struct auth_client *auth, provider_t id) rb_dlink_node *ptr; struct auth_provider *provider; - unset_provider(auth, id); + set_provider_off(auth, id); + set_provider_done(auth, id); if(!auth->providers) { @@ -144,7 +145,7 @@ void provider_done(struct auth_client *auth, provider_t id) { provider = ptr->data; - if(provider->completed && is_provider(auth, provider->id)) + if(provider->completed && is_provider_on(auth, provider->id)) /* Notify pending clients who asked for it */ provider->completed(auth, id); } @@ -174,7 +175,7 @@ void reject_client(struct auth_client *auth, provider_t id, const char *reason) /* TODO send back ident */ rb_helper_write(authd_helper, "R %x %c :%s", auth->cid, reject, reason); - unset_provider(auth, id); + set_provider_off(auth, id); cancel_providers(auth); } @@ -185,7 +186,7 @@ void accept_client(struct auth_client *auth, provider_t id) rb_helper_write(authd_helper, "A %x %s %s", auth->cid, auth->username, auth->hostname); - unset_provider(auth, id); + set_provider_off(auth, id); cancel_providers(auth); } diff --git a/authd/provider.h b/authd/provider.h index 01c71cf4..ef96ca84 100644 --- a/authd/provider.h +++ b/authd/provider.h @@ -59,6 +59,7 @@ struct auth_client uint32_t providers; /* Providers at work, * none left when set to 0 */ + uint32_t providers_done; /* Providers completed */ void *data[MAX_PROVIDERS]; /* Provider-specific data slots */ }; @@ -108,21 +109,32 @@ void warn_opers(notice_level_t level, const char *fmt, ...); void handle_new_connection(int parc, char *parv[]); /* Provider is operating on this auth_client (set this if you have async work to do) */ -static inline void set_provider(struct auth_client *auth, provider_t provider) +static inline void set_provider_on(struct auth_client *auth, provider_t provider) { auth->providers |= (1 << provider); } /* Provider is no longer operating on this auth client (you should use provider_done) */ -static inline void unset_provider(struct auth_client *auth, provider_t provider) +static inline void set_provider_off(struct auth_client *auth, provider_t provider) { auth->providers &= ~(1 << provider); } +/* Set the provider to done (you should use provider_done) */ +static inline void set_provider_done(struct auth_client *auth, provider_t provider) +{ + auth->providers_done |= (1 << provider); +} + /* Check if provider is operating on this auth client */ -static inline bool is_provider(struct auth_client *auth, provider_t provider) +static inline bool is_provider_on(struct auth_client *auth, provider_t provider) { return auth->providers & (1 << provider); } +static inline bool is_provider_done(struct auth_client *auth, provider_t provider) +{ + return auth->providers_done & (1 << provider); +} + #endif /* __CHARYBDIS_AUTHD_PROVIDER_H__ */ diff --git a/authd/providers/blacklist.c b/authd/providers/blacklist.c index eaccc33b..ae52bbdc 100644 --- a/authd/providers/blacklist.c +++ b/authd/providers/blacklist.c @@ -258,7 +258,7 @@ blacklist_dns_callback(const char *result, bool status, query_type type, void *d if(!rb_dlink_list_length(&bluser->queries)) { /* Done here */ - provider_done(auth, PROVIDER_BLACKLIST); + provider_done(auth, PROVIDER_BLACKLIST); rb_free(bluser); auth->data[PROVIDER_BLACKLIST] = NULL; } @@ -308,13 +308,27 @@ timeout_blacklist_queries_event(void *notused) } } +static inline void +lookup_all_blacklists(struct auth_client *auth) +{ + struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST]; + rb_dlink_node *ptr; + + RB_DLINK_FOREACH(ptr, blacklist_list.head) + { + struct blacklist *bl = (struct blacklist *)ptr->data; + + if (!bl->delete) + initiate_blacklist_dnsquery(bl, auth); + } + + bluser->timeout = rb_current_time() + blacklist_timeout; +} + /* public interfaces */ static bool blacklists_start(struct auth_client *auth) { - struct blacklist_user *bluser; - rb_dlink_node *nptr; - if(auth->data[PROVIDER_BLACKLIST] != NULL) return true; @@ -322,22 +336,32 @@ blacklists_start(struct auth_client *auth) /* Nothing to do... */ return true; - bluser = auth->data[PROVIDER_BLACKLIST] = rb_malloc(sizeof(struct blacklist_user)); + auth->data[PROVIDER_BLACKLIST] = rb_malloc(sizeof(struct blacklist_user)); - RB_DLINK_FOREACH(nptr, blacklist_list.head) - { - struct blacklist *bl = (struct blacklist *) nptr->data; + if(is_provider_done(auth, PROVIDER_RDNS) && is_provider_done(auth, PROVIDER_IDENT)) + /* This probably can't happen but let's handle this case anyway */ + lookup_all_blacklists(auth); - if (!bl->delete) - initiate_blacklist_dnsquery(bl, auth); - } - - bluser->timeout = rb_current_time() + blacklist_timeout; - - set_provider(auth, PROVIDER_BLACKLIST); + set_provider_on(auth, PROVIDER_BLACKLIST); return true; } +/* This is called every time a provider is completed */ +static void +blacklists_initiate(struct auth_client *auth, provider_t provider) +{ + struct blacklist_user *bluser = auth->data[PROVIDER_BLACKLIST]; + + if(bluser == NULL || is_provider_done(auth, PROVIDER_BLACKLIST) || rb_dlink_list_length(&bluser->queries)) + /* Nothing to do */ + return; + else if(!is_provider_done(auth, PROVIDER_RDNS) && !is_provider_done(auth, PROVIDER_IDENT)) + /* Don't start until we've completed these */ + return; + else + lookup_all_blacklists(auth); +} + static void blacklists_cancel(struct auth_client *auth) { @@ -400,5 +424,5 @@ struct auth_provider blacklist_provider = .destroy = blacklists_destroy, .start = blacklists_start, .cancel = blacklists_cancel, - .completed = NULL, + .completed = blacklists_initiate, }; diff --git a/authd/providers/ident.c b/authd/providers/ident.c index 3e77025f..a19b289e 100644 --- a/authd/providers/ident.c +++ b/authd/providers/ident.c @@ -121,7 +121,7 @@ bool ident_start(struct auth_client *auth) query, ident_timeout); notice_client(auth, messages[REPORT_LOOKUP]); - set_provider(auth, PROVIDER_IDENT); + set_provider_on(auth, PROVIDER_IDENT); return true; } diff --git a/authd/providers/rdns.c b/authd/providers/rdns.c index 96bcea14..ddce08fb 100644 --- a/authd/providers/rdns.c +++ b/authd/providers/rdns.c @@ -88,7 +88,7 @@ bool client_dns_start(struct auth_client *auth) query->query = lookup_hostname(auth->c_ip, dns_answer_callback, auth); notice_client(auth, messages[REPORT_LOOKUP]); - set_provider(auth, PROVIDER_RDNS); + set_provider_on(auth, PROVIDER_RDNS); return true; }