1From 7bad6a24160e34bce8f10e73dbbf9e5fbbcd1904 Mon Sep 17 00:00:00 2001 2From: Timo Sirainen <timo.sirainen@open-xchange.com> 3Date: Mon, 9 May 2022 15:23:33 +0300 4Subject: [PATCH] auth: Fix handling passdbs with identical driver/args but 5 different mechanisms/username_filter 6 7The passdb was wrongly deduplicated in this situation, causing wrong 8mechanisms or username_filter setting to be used. This would be a rather 9unlikely configuration though. 10 11Fixed by moving mechanisms and username_filter from struct passdb_module 12to struct auth_passdb, which is where they should have been in the first 13place. 14 15Signed-off-by: Peter Korsgaard <peter@korsgaard.com> 16--- 17 src/auth/auth-request.c | 6 +++--- 18 src/auth/auth.c | 18 ++++++++++++++++++ 19 src/auth/auth.h | 5 +++++ 20 src/auth/passdb.c | 15 ++------------- 21 src/auth/passdb.h | 4 ---- 22 5 files changed, 28 insertions(+), 20 deletions(-) 23 24diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c 25index cd08b1fa02..0ca29f3674 100644 26--- a/src/auth/auth-request.c 27+++ b/src/auth/auth-request.c 28@@ -534,8 +534,8 @@ auth_request_want_skip_passdb(struct auth_request *request, 29 struct auth_passdb *passdb) 30 { 31 /* if mechanism is not supported, skip */ 32- const char *const *mechs = passdb->passdb->mechanisms; 33- const char *const *username_filter = passdb->passdb->username_filter; 34+ const char *const *mechs = passdb->mechanisms; 35+ const char *const *username_filter = passdb->username_filter; 36 const char *username; 37 38 username = request->fields.user; 39@@ -548,7 +548,7 @@ auth_request_want_skip_passdb(struct auth_request *request, 40 return TRUE; 41 } 42 43- if (passdb->passdb->username_filter != NULL && 44+ if (passdb->username_filter != NULL && 45 !auth_request_username_accepted(username_filter, username)) { 46 auth_request_log_debug(request, 47 request->mech != NULL ? AUTH_SUBSYS_MECH 48diff --git a/src/auth/auth.c b/src/auth/auth.c 49index f2f3fda20c..9f6c4ba60c 100644 50--- a/src/auth/auth.c 51+++ b/src/auth/auth.c 52@@ -99,6 +99,24 @@ auth_passdb_preinit(struct auth *auth, const struct auth_passdb_settings *set, 53 auth_passdb->override_fields_tmpl = 54 passdb_template_build(auth->pool, set->override_fields); 55 56+ if (*set->mechanisms == '\0') { 57+ auth_passdb->mechanisms = NULL; 58+ } else if (strcasecmp(set->mechanisms, "none") == 0) { 59+ auth_passdb->mechanisms = (const char *const[]){ NULL }; 60+ } else { 61+ auth_passdb->mechanisms = 62+ (const char *const *)p_strsplit_spaces(auth->pool, 63+ set->mechanisms, " ,"); 64+ } 65+ 66+ if (*set->username_filter == '\0') { 67+ auth_passdb->username_filter = NULL; 68+ } else { 69+ auth_passdb->username_filter = 70+ (const char *const *)p_strsplit_spaces(auth->pool, 71+ set->username_filter, " ,"); 72+ } 73+ 74 /* for backwards compatibility: */ 75 if (set->pass) 76 auth_passdb->result_success = AUTH_DB_RULE_CONTINUE; 77diff --git a/src/auth/auth.h b/src/auth/auth.h 78index f700e29d5c..460a179765 100644 79--- a/src/auth/auth.h 80+++ b/src/auth/auth.h 81@@ -41,6 +41,11 @@ struct auth_passdb { 82 struct passdb_template *default_fields_tmpl; 83 struct passdb_template *override_fields_tmpl; 84 85+ /* Supported authentication mechanisms, NULL is all, {NULL} is none */ 86+ const char *const *mechanisms; 87+ /* Username filter, NULL is no filter */ 88+ const char *const *username_filter; 89+ 90 enum auth_passdb_skip skip; 91 enum auth_db_rule result_success; 92 enum auth_db_rule result_failure; 93diff --git a/src/auth/passdb.c b/src/auth/passdb.c 94index eb4ac8ae82..f5eed1af4f 100644 95--- a/src/auth/passdb.c 96+++ b/src/auth/passdb.c 97@@ -224,19 +224,8 @@ passdb_preinit(pool_t pool, const struct auth_passdb_settings *set) 98 passdb->id = ++auth_passdb_id; 99 passdb->iface = *iface; 100 passdb->args = p_strdup(pool, set->args); 101- if (*set->mechanisms == '\0') { 102- passdb->mechanisms = NULL; 103- } else if (strcasecmp(set->mechanisms, "none") == 0) { 104- passdb->mechanisms = (const char *const[]){NULL}; 105- } else { 106- passdb->mechanisms = (const char* const*)p_strsplit_spaces(pool, set->mechanisms, " ,"); 107- } 108- 109- if (*set->username_filter == '\0') { 110- passdb->username_filter = NULL; 111- } else { 112- passdb->username_filter = (const char* const*)p_strsplit_spaces(pool, set->username_filter, " ,"); 113- } 114+ /* NOTE: if anything else than driver & args are added here, 115+ passdb_find() also needs to be updated. */ 116 array_push_back(&passdb_modules, &passdb); 117 return passdb; 118 } 119diff --git a/src/auth/passdb.h b/src/auth/passdb.h 120index 2e95328e5c..e466a9fdb6 100644 121--- a/src/auth/passdb.h 122+++ b/src/auth/passdb.h 123@@ -63,10 +63,6 @@ struct passdb_module { 124 /* Default password scheme for this module. 125 If default_cache_key is set, must not be NULL. */ 126 const char *default_pass_scheme; 127- /* Supported authentication mechanisms, NULL is all, [NULL] is none*/ 128- const char *const *mechanisms; 129- /* Username filter, NULL is no filter */ 130- const char *const *username_filter; 131 132 /* If blocking is set to TRUE, use child processes to access 133 this passdb. */ 134-- 1352.30.2 136 137