From: Timo Sirainen Date: Tue, 30 Aug 2011 02:27:54 +0000 (+0300) Subject: auth: Added default_fields and override_fields settings to all passdbs and userdbs. X-Git-Tag: 2.1.alpha1~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04052d7cacaa866a3f00afb4e104fa46c04c1dd7;p=thirdparty%2Fdovecot%2Fcore.git auth: Added default_fields and override_fields settings to all passdbs and userdbs. --- diff --git a/doc/example-config/conf.d/auth-ldap.conf.ext b/doc/example-config/conf.d/auth-ldap.conf.ext index c585280163..3e5c51fb05 100644 --- a/doc/example-config/conf.d/auth-ldap.conf.ext +++ b/doc/example-config/conf.d/auth-ldap.conf.ext @@ -19,6 +19,9 @@ passdb { userdb { driver = ldap args = /etc/dovecot/dovecot-ldap.conf.ext + + # Default fields can be used to specify defaults that LDAP may override + #default_fields = home=/home/virtual/%u } # If you don't have any user-specific settings, you can avoid the userdb LDAP diff --git a/doc/example-config/conf.d/auth-passwdfile.conf.ext b/doc/example-config/conf.d/auth-passwdfile.conf.ext index 3f57ceebdf..555495729d 100644 --- a/doc/example-config/conf.d/auth-passwdfile.conf.ext +++ b/doc/example-config/conf.d/auth-passwdfile.conf.ext @@ -11,4 +11,10 @@ passdb { userdb { driver = passwd-file args = username_format=%u /etc/dovecot/users + + # Default fields that can be overridden by passwd-file + #default_fields = quota_rule=*:storage=1G + + # Override fields from passwd-file + #override_fields = home=/home/virtual/%u } diff --git a/doc/example-config/conf.d/auth-system.conf.ext b/doc/example-config/conf.d/auth-system.conf.ext index 56f4659edf..260c080532 100644 --- a/doc/example-config/conf.d/auth-system.conf.ext +++ b/doc/example-config/conf.d/auth-system.conf.ext @@ -51,6 +51,9 @@ userdb { driver = passwd # [blocking=no] #args = + + # Override fields from passwd + #override_fields = home=/home/virtual/%u } # Static settings generated from template diff --git a/src/auth/Makefile.am b/src/auth/Makefile.am index 5db5d20f31..915929d645 100644 --- a/src/auth/Makefile.am +++ b/src/auth/Makefile.am @@ -98,6 +98,7 @@ auth_SOURCES = \ passdb-vpopmail.c \ passdb-sql.c \ passdb-static.c \ + passdb-template.c \ userdb.c \ userdb-blocking.c \ userdb-checkpassword.c \ @@ -108,6 +109,7 @@ auth_SOURCES = \ userdb-static.c \ userdb-vpopmail.c \ userdb-sql.c \ + userdb-template.c \ $(ldap_sources) headers = \ @@ -134,10 +136,11 @@ headers = \ passdb.h \ passdb-blocking.h \ passdb-cache.h \ + passdb-template.h \ password-scheme.h \ userdb.h \ userdb-blocking.h \ - userdb-static.h \ + userdb-template.h \ userdb-vpopmail.h if GSSAPI_PLUGIN diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 1cb5c00ae8..588637a9b4 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -18,8 +18,10 @@ #include "auth-master-connection.h" #include "passdb.h" #include "passdb-blocking.h" -#include "userdb-blocking.h" #include "passdb-cache.h" +#include "passdb-template.h" +#include "userdb-blocking.h" +#include "userdb-template.h" #include "password-scheme.h" #include @@ -510,17 +512,20 @@ auth_request_verify_plain_callback_finish(enum passdb_result result, void auth_request_verify_plain_callback(enum passdb_result result, struct auth_request *request) { + struct passdb_module *passdb = request->passdb->passdb; + i_assert(request->state == AUTH_REQUEST_STATE_PASSDB); auth_request_set_state(request, AUTH_REQUEST_STATE_MECH_CONTINUE); - if (result != PASSDB_RESULT_INTERNAL_FAILURE) + if (result != PASSDB_RESULT_INTERNAL_FAILURE) { + passdb_template_export(passdb->override_fields_tmpl, request); auth_request_save_cache(request, result); - else { + } else { /* lookup failed. if we're looking here only because the request was expired in cache, fallback to using cached expired record. */ - const char *cache_key = request->passdb->passdb->cache_key; + const char *cache_key = passdb->cache_key; if (passdb_cache_verify_plain(request, cache_key, request->mech_password, @@ -603,6 +608,7 @@ void auth_request_verify_plain(struct auth_request *request, } else if (passdb->blocking) { passdb_blocking_verify_plain(request); } else if (passdb->iface.verify_plain != NULL) { + passdb_template_export(passdb->default_fields_tmpl, request); passdb->iface.verify_plain(request, password, auth_request_verify_plain_callback); } @@ -642,19 +648,21 @@ void auth_request_lookup_credentials_callback(enum passdb_result result, size_t size, struct auth_request *request) { + struct passdb_module *passdb = request->passdb->passdb; const char *cache_cred, *cache_scheme; i_assert(request->state == AUTH_REQUEST_STATE_PASSDB); auth_request_set_state(request, AUTH_REQUEST_STATE_MECH_CONTINUE); - if (result != PASSDB_RESULT_INTERNAL_FAILURE) + if (result != PASSDB_RESULT_INTERNAL_FAILURE) { + passdb_template_export(passdb->override_fields_tmpl, request); auth_request_save_cache(request, result); - else { + } else { /* lookup failed. if we're looking here only because the request was expired in cache, fallback to using cached expired record. */ - const char *cache_key = request->passdb->passdb->cache_key; + const char *cache_key = passdb->cache_key; if (passdb_cache_lookup_credentials(request, cache_key, &cache_cred, &cache_scheme, @@ -710,6 +718,7 @@ void auth_request_lookup_credentials(struct auth_request *request, } else if (passdb->blocking) { passdb_blocking_lookup_credentials(request); } else { + passdb_template_export(passdb->default_fields_tmpl, request); passdb->iface.lookup_credentials(request, auth_request_lookup_credentials_callback); } @@ -807,7 +816,9 @@ void auth_request_userdb_callback(enum userdb_result result, return; } - if (request->userdb_internal_failure && result != USERDB_RESULT_OK) { + if (result == USERDB_RESULT_OK) + userdb_template_export(userdb->override_fields_tmpl, request); + else if (request->userdb_internal_failure) { /* one of the userdb lookups failed. the user might have been in there, so this is an internal failure */ result = USERDB_RESULT_INTERNAL_FAILURE; @@ -1246,8 +1257,12 @@ void auth_request_set_fields(struct auth_request *request, void auth_request_init_userdb_reply(struct auth_request *request) { + struct userdb_module *module = request->userdb->userdb; + request->userdb_reply = auth_stream_reply_init(request->pool); auth_stream_reply_add(request->userdb_reply, NULL, request->user); + + userdb_template_export(module->default_fields_tmpl, request); } static void auth_request_set_uidgid_file(struct auth_request *request, @@ -1303,6 +1318,11 @@ void auth_request_set_userdb_field(struct auth_request *request, return; } else if (strcmp(name, "system_user") == 0) { /* FIXME: the system_user is for backwards compatibility */ + static bool warned = FALSE; + if (!warned) { + i_warning("userdb: Replace system_user with system_groups_user"); + warned = TRUE; + } name = "system_groups_user"; } diff --git a/src/auth/auth-settings.c b/src/auth/auth-settings.c index 178db91ca7..8e57f5435c 100644 --- a/src/auth/auth-settings.c +++ b/src/auth/auth-settings.c @@ -107,6 +107,8 @@ struct service_settings auth_worker_service_settings = { static const struct setting_define auth_passdb_setting_defines[] = { DEF(SET_STR, driver), DEF(SET_STR, args), + DEF(SET_STR, default_fields), + DEF(SET_STR, override_fields), DEF(SET_BOOL, deny), DEF(SET_BOOL, pass), DEF(SET_BOOL, master), @@ -117,6 +119,8 @@ static const struct setting_define auth_passdb_setting_defines[] = { static const struct auth_passdb_settings auth_passdb_default_settings = { .driver = "", .args = "", + .default_fields = "", + .override_fields = "", .deny = FALSE, .pass = FALSE, .master = FALSE @@ -142,13 +146,17 @@ const struct setting_parser_info auth_passdb_setting_parser_info = { static const struct setting_define auth_userdb_setting_defines[] = { DEF(SET_STR, driver), DEF(SET_STR, args), + DEF(SET_STR, default_fields), + DEF(SET_STR, override_fields), SETTING_DEFINE_LIST_END }; static const struct auth_userdb_settings auth_userdb_default_settings = { .driver = "", - .args = "" + .args = "", + .default_fields = "", + .override_fields = "" }; const struct setting_parser_info auth_userdb_setting_parser_info = { diff --git a/src/auth/auth-settings.h b/src/auth/auth-settings.h index 7b1533c8a0..cec94a83d9 100644 --- a/src/auth/auth-settings.h +++ b/src/auth/auth-settings.h @@ -7,6 +7,8 @@ struct master_service_settings_output; struct auth_passdb_settings { const char *driver; const char *args; + const char *default_fields; + const char *override_fields; bool deny; bool pass; bool master; @@ -15,6 +17,8 @@ struct auth_passdb_settings { struct auth_userdb_settings { const char *driver; const char *args; + const char *default_fields; + const char *override_fields; }; struct auth_settings { diff --git a/src/auth/auth.c b/src/auth/auth.c index a99d423ad9..8ea0c065c1 100644 --- a/src/auth/auth.c +++ b/src/auth/auth.c @@ -28,8 +28,7 @@ auth_passdb_preinit(struct auth *auth, const struct auth_passdb_settings *set, for (dest = passdbs; *dest != NULL; dest = &(*dest)->next) ; *dest = auth_passdb; - auth_passdb->passdb = - passdb_preinit(auth->pool, set->driver, set->args); + auth_passdb->passdb = passdb_preinit(auth->pool, set); } static void @@ -43,8 +42,7 @@ auth_userdb_preinit(struct auth *auth, const struct auth_userdb_settings *set) for (dest = &auth->userdbs; *dest != NULL; dest = &(*dest)->next) ; *dest = auth_userdb; - auth_userdb->userdb = - userdb_preinit(auth->pool, set->driver, set->args); + auth_userdb->userdb = userdb_preinit(auth->pool, set); } static struct auth * diff --git a/src/auth/passdb-static.c b/src/auth/passdb-static.c index f4a4d87637..1d6b117f69 100644 --- a/src/auth/passdb-static.c +++ b/src/auth/passdb-static.c @@ -5,12 +5,12 @@ #include "str.h" #include "var-expand.h" #include "passdb.h" - -#define STATIC_PASS_SCHEME "PLAIN" +#include "passdb-template.h" struct static_passdb_module { struct passdb_module module; - ARRAY_TYPE(const_string) tmpl; + struct passdb_template *tmpl; + const char *static_password_tmpl; }; static void @@ -19,34 +19,14 @@ static_save_fields(struct auth_request *request, const char **password_r) struct static_passdb_module *module = (struct static_passdb_module *)request->passdb->passdb; const struct var_expand_table *table; - const char *const *args; - unsigned int i, count; string_t *str = t_str_new(128); auth_request_log_debug(request, "static", "lookup"); + passdb_template_export(module->tmpl, request); table = auth_request_get_var_expand_table(request, NULL); - - *password_r = ""; - args = array_get(&module->tmpl, &count); - i_assert((count % 2) == 0); - for (i = 0; i < count; i += 2) { - const char *key = args[i]; - const char *value = args[i+1]; - - if (value != NULL) { - str_truncate(str, 0); - var_expand(str, args[i+1], table); - value = str_c(str); - } - - if (strcmp(key, "password") == 0) - *password_r = value; - else { - auth_request_set_field(request, key, value, - STATIC_PASS_SCHEME); - } - } + var_expand(str, module->static_password_tmpl, table); + *password_r = str_c(str); } static void @@ -83,28 +63,13 @@ static struct passdb_module * static_preinit(pool_t pool, const char *args) { struct static_passdb_module *module; + const char *value; module = p_new(pool, struct static_passdb_module, 1); - p_array_init(&module->tmpl, pool, 16); - T_BEGIN { - const char *const *tmp; - - tmp = t_strsplit_spaces(args, " "); - for (; *tmp != NULL; tmp++) { - const char *key = *tmp; - const char *value = strchr(key, '='); - - if (value == NULL) - value = ""; - else - key = t_strdup_until(key, value++); - - key = p_strdup(pool, key); - value = p_strdup(pool, value); - array_append(&module->tmpl, &key, 1); - array_append(&module->tmpl, &value, 1); - } - } T_END; + module->tmpl = passdb_template_build(pool, args); + + if (passdb_template_remove(module->tmpl, "password", &value)) + module->static_password_tmpl = value; return &module->module; } diff --git a/src/auth/passdb.c b/src/auth/passdb.c index e12816f2ae..08f7aa0216 100644 --- a/src/auth/passdb.c +++ b/src/auth/passdb.c @@ -4,6 +4,7 @@ #include "array.h" #include "password-scheme.h" #include "auth-worker-server.h" +#include "passdb-template.h" #include "passdb.h" #include @@ -181,34 +182,43 @@ passdb_find(const char *driver, const char *args, unsigned int *idx_r) } struct passdb_module * -passdb_preinit(pool_t pool, const char *driver, const char *args) +passdb_preinit(pool_t pool, const struct auth_passdb_settings *set) { static unsigned int auth_passdb_id = 0; struct passdb_module_interface *iface; struct passdb_module *passdb; unsigned int idx; - iface = passdb_interface_find(driver); + iface = passdb_interface_find(set->driver); if (iface == NULL) - i_fatal("Unknown passdb driver '%s'", driver); + i_fatal("Unknown passdb driver '%s'", set->driver); if (iface->verify_plain == NULL) { i_fatal("Support not compiled in for passdb driver '%s'", - driver); + set->driver); + } + if (iface->preinit == NULL && iface->init == NULL && + *set->args != '\0') { + i_fatal("passdb %s: No args are supported: %s", + set->driver, set->args); } - if (iface->preinit == NULL && iface->init == NULL && *args != '\0') - i_fatal("passdb %s: No args are supported: %s", driver, args); - passdb = passdb_find(driver, args, &idx); + passdb = passdb_find(set->driver, set->args, &idx); if (passdb != NULL) return passdb; if (iface->preinit == NULL) passdb = p_new(pool, struct passdb_module, 1); else - passdb = iface->preinit(pool, args); + passdb = iface->preinit(pool, set->args); passdb->id = ++auth_passdb_id; passdb->iface = *iface; - passdb->args = p_strdup(pool, args); + passdb->args = p_strdup(pool, set->args); + + passdb->default_fields_tmpl = + passdb_template_build(pool, set->default_fields); + passdb->override_fields_tmpl = + passdb_template_build(pool, set->override_fields); + array_append(&passdb_modules, &passdb, 1); return passdb; } diff --git a/src/auth/passdb.h b/src/auth/passdb.h index a6351458a4..a0609c4259 100644 --- a/src/auth/passdb.h +++ b/src/auth/passdb.h @@ -7,6 +7,7 @@ ((pass)[0] != '\0' && (pass)[0] != '*' && (pass)[0] != '!') struct auth_request; +struct auth_passdb_settings; enum passdb_result { PASSDB_RESULT_INTERNAL_FAILURE = -1, @@ -67,6 +68,9 @@ struct passdb_module { /* number of time init() has been called */ int init_refcount; + struct passdb_template *default_fields_tmpl; + struct passdb_template *override_fields_tmpl; + struct passdb_module_interface iface; }; @@ -88,7 +92,7 @@ void passdb_handle_credentials(enum passdb_result result, struct auth_request *auth_request); struct passdb_module * -passdb_preinit(pool_t pool, const char *driver, const char *args); +passdb_preinit(pool_t pool, const struct auth_passdb_settings *set); void passdb_init(struct passdb_module *passdb); void passdb_deinit(struct passdb_module *passdb); diff --git a/src/auth/userdb-passwd.c b/src/auth/userdb-passwd.c index 7214fd759d..ce02d6546d 100644 --- a/src/auth/userdb-passwd.c +++ b/src/auth/userdb-passwd.c @@ -7,13 +7,13 @@ #include "ioloop.h" #include "ipwd.h" -#include "userdb-static.h" +#include "userdb-template.h" #define USER_CACHE_KEY "%u" struct passwd_userdb_module { struct userdb_module module; - struct userdb_static_template *tmpl; + struct userdb_template *tmpl; }; struct passwd_userdb_iterate_context { @@ -50,25 +50,13 @@ static void passwd_lookup(struct auth_request *auth_request, auth_request_set_field(auth_request, "user", pw.pw_name, NULL); auth_request_init_userdb_reply(auth_request); - userdb_static_template_export(module->tmpl, auth_request); - - /* FIXME: the system_user is for backwards compatibility */ - if (!userdb_static_template_isset(module->tmpl, "system_groups_user") && - !userdb_static_template_isset(module->tmpl, "system_user")) { - auth_request_set_userdb_field(auth_request, - "system_groups_user", - pw.pw_name); - } - if (!userdb_static_template_isset(module->tmpl, "uid")) { - auth_request_set_userdb_field(auth_request, - "uid", dec2str(pw.pw_uid)); - } - if (!userdb_static_template_isset(module->tmpl, "gid")) { - auth_request_set_userdb_field(auth_request, - "gid", dec2str(pw.pw_gid)); - } - if (!userdb_static_template_isset(module->tmpl, "home")) - auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); + auth_request_set_userdb_field(auth_request, "system_groups_user", + pw.pw_name); + auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid)); + auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid)); + auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); + + userdb_template_export(module->tmpl, auth_request); callback(USERDB_RESULT_OK, auth_request); } @@ -153,13 +141,15 @@ passwd_passwd_preinit(pool_t pool, const char *args) module = p_new(pool, struct passwd_userdb_module, 1); module->module.cache_key = USER_CACHE_KEY; - module->tmpl = userdb_static_template_build(pool, "passwd", args); + module->tmpl = userdb_template_build(pool, "passwd", args); - if (userdb_static_template_remove(module->tmpl, "blocking", - &value)) { + if (userdb_template_remove(module->tmpl, "blocking", &value)) { module->module.blocking = value == NULL || strcasecmp(value, "yes") == 0; } + /* FIXME: backwards compatibility */ + if (!userdb_template_is_empty(module->tmpl)) + i_warning("userdb passwd: Move templates args to override_fields setting"); return &module->module; } diff --git a/src/auth/userdb-static.c b/src/auth/userdb-static.c index 880e743a3e..b4a419decb 100644 --- a/src/auth/userdb-static.c +++ b/src/auth/userdb-static.c @@ -6,122 +6,10 @@ #include "str.h" #include "var-expand.h" #include "userdb.h" -#include "userdb-static.h" +#include "userdb-template.h" #include -struct userdb_static_template { - ARRAY_DEFINE(args, const char *); -}; - -struct userdb_static_template * -userdb_static_template_build(pool_t pool, const char *userdb_name, - const char *args) -{ - struct userdb_static_template *tmpl; - const char *const *tmp, *key, *value; - uid_t uid; - gid_t gid; - - tmpl = p_new(pool, struct userdb_static_template, 1); - - tmp = t_strsplit_spaces(args, " "); - p_array_init(&tmpl->args, pool, str_array_length(tmp)); - - for (; *tmp != NULL; tmp++) { - value = strchr(*tmp, '='); - if (value == NULL) - key = *tmp; - else { - key = t_strdup_until(*tmp, value); - value++; - } - - if (strcasecmp(key, "uid") == 0) { - uid = userdb_parse_uid(NULL, value); - if (uid == (uid_t)-1) { - i_fatal("%s userdb: Invalid uid: %s", - userdb_name, value); - } - value = dec2str(uid); - } else if (strcasecmp(key, "gid") == 0) { - gid = userdb_parse_gid(NULL, value); - if (gid == (gid_t)-1) { - i_fatal("%s userdb: Invalid gid: %s", - userdb_name, value); - } - value = dec2str(gid); - } else if (*key == '\0') { - i_fatal("%s userdb: Empty key (=%s)", - userdb_name, value); - } - key = p_strdup(pool, key); - value = p_strdup(pool, value); - - array_append(&tmpl->args, &key, 1); - array_append(&tmpl->args, &value, 1); - } - return tmpl; -} - -bool userdb_static_template_isset(struct userdb_static_template *tmpl, - const char *key) -{ - const char *const *args; - unsigned int i, count; - - args = array_get(&tmpl->args, &count); - i_assert((count % 2) == 0); - for (i = 0; i < count; i += 2) { - if (strcmp(args[i], key) == 0) - return TRUE; - } - return FALSE; -} - -bool userdb_static_template_remove(struct userdb_static_template *tmpl, - const char *key, const char **value_r) -{ - const char *const *args; - unsigned int i, count; - - args = array_get(&tmpl->args, &count); - i_assert((count % 2) == 0); - for (i = 0; i < count; i += 2) { - if (strcmp(args[i], key) == 0) { - *value_r = args[i+1]; - array_delete(&tmpl->args, i, 2); - return TRUE; - } - } - return FALSE; -} - -void userdb_static_template_export(struct userdb_static_template *tmpl, - struct auth_request *auth_request) -{ - const struct var_expand_table *table; - string_t *str; - const char *const *args, *value; - unsigned int i, count; - - str = t_str_new(256); - table = auth_request_get_var_expand_table(auth_request, NULL); - - args = array_get(&tmpl->args, &count); - i_assert((count % 2) == 0); - for (i = 0; i < count; i += 2) { - if (args[i+1] == NULL) - value = NULL; - else { - str_truncate(str, 0); - var_expand(str, args[i+1], table); - value = str_c(str); - } - auth_request_set_userdb_field(auth_request, args[i], value); - } -} - struct static_context { userdb_callback_t *callback, *old_callback; void *old_context; @@ -129,7 +17,7 @@ struct static_context { struct static_userdb_module { struct userdb_module module; - struct userdb_static_template *tmpl; + struct userdb_template *tmpl; unsigned int allow_all_users:1; }; @@ -142,7 +30,7 @@ static void static_lookup_real(struct auth_request *auth_request, (struct static_userdb_module *)_module; auth_request_init_userdb_reply(auth_request); - userdb_static_template_export(module->tmpl, auth_request); + userdb_template_export(module->tmpl, auth_request); callback(USERDB_RESULT_OK, auth_request); } @@ -223,10 +111,9 @@ static_preinit(pool_t pool, const char *args) const char *value; module = p_new(pool, struct static_userdb_module, 1); - module->tmpl = userdb_static_template_build(pool, "static", args); + module->tmpl = userdb_template_build(pool, "static", args); - if (userdb_static_template_remove(module->tmpl, "allow_all_users", - &value)) { + if (userdb_template_remove(module->tmpl, "allow_all_users", &value)) { module->allow_all_users = value == NULL || strcasecmp(value, "yes") == 0; } diff --git a/src/auth/userdb-static.h b/src/auth/userdb-static.h deleted file mode 100644 index 82029cc618..0000000000 --- a/src/auth/userdb-static.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef USERDB_STATIC_H -#define USERDB_STATIC_H - -struct userdb_static_template * -userdb_static_template_build(pool_t pool, const char *userdb_name, - const char *args); -bool userdb_static_template_isset(struct userdb_static_template *tmpl, - const char *key); -bool userdb_static_template_remove(struct userdb_static_template *tmpl, - const char *key, const char **value_r); -void userdb_static_template_export(struct userdb_static_template *tmpl, - struct auth_request *auth_request); - -#endif diff --git a/src/auth/userdb.c b/src/auth/userdb.c index da16d2f38c..b2b34e51c6 100644 --- a/src/auth/userdb.c +++ b/src/auth/userdb.c @@ -4,6 +4,7 @@ #include "array.h" #include "ipwd.h" #include "auth-worker-server.h" +#include "userdb-template.h" #include "userdb.h" #include @@ -128,34 +129,45 @@ userdb_find(const char *driver, const char *args, unsigned int *idx_r) } struct userdb_module * -userdb_preinit(pool_t pool, const char *driver, const char *args) +userdb_preinit(pool_t pool, const struct auth_userdb_settings *set) { static unsigned int auth_userdb_id = 0; struct userdb_module_interface *iface; struct userdb_module *userdb; unsigned int idx; - iface = userdb_interface_find(driver); + iface = userdb_interface_find(set->driver); if (iface == NULL) - i_fatal("Unknown userdb driver '%s'", driver); + i_fatal("Unknown userdb driver '%s'", set->driver); if (iface->lookup == NULL) { i_fatal("Support not compiled in for userdb driver '%s'", - driver); + set->driver); + } + if (iface->preinit == NULL && iface->init == NULL && + *set->args != '\0') { + i_fatal("userdb %s: No args are supported: %s", + set->driver, set->args); } - if (iface->preinit == NULL && iface->init == NULL && *args != '\0') - i_fatal("userdb %s: No args are supported: %s", driver, args); - userdb = userdb_find(driver, args, &idx); + userdb = userdb_find(set->driver, set->args, &idx); if (userdb != NULL) return userdb; if (iface->preinit == NULL) userdb = p_new(pool, struct userdb_module, 1); else - userdb = iface->preinit(pool, args); + userdb = iface->preinit(pool, set->args); userdb->id = ++auth_userdb_id; userdb->iface = iface; - userdb->args = p_strdup(pool, args); + userdb->args = p_strdup(pool, set->args); + + userdb->default_fields_tmpl = + userdb_template_build(pool, set->driver, + set->default_fields); + userdb->override_fields_tmpl = + userdb_template_build(pool, set->driver, + set->override_fields); + array_append(&userdb_modules, &userdb, 1); return userdb; } diff --git a/src/auth/userdb.h b/src/auth/userdb.h index 820aa61856..0946824af8 100644 --- a/src/auth/userdb.h +++ b/src/auth/userdb.h @@ -6,6 +6,7 @@ struct auth; struct auth_request; +struct auth_userdb_settings; enum userdb_result { USERDB_RESULT_INTERNAL_FAILURE = -1, @@ -33,6 +34,9 @@ struct userdb_module { /* number of time init() has been called */ int init_refcount; + struct userdb_template *default_fields_tmpl; + struct userdb_template *override_fields_tmpl; + const struct userdb_module_interface *iface; }; @@ -65,7 +69,7 @@ uid_t userdb_parse_uid(struct auth_request *request, const char *str); gid_t userdb_parse_gid(struct auth_request *request, const char *str); struct userdb_module * -userdb_preinit(pool_t pool, const char *driver, const char *args); +userdb_preinit(pool_t pool, const struct auth_userdb_settings *set); void userdb_init(struct userdb_module *userdb); void userdb_deinit(struct userdb_module *userdb);