]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: passdb/userdb sql - Add support for fields { .. }
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 7 Mar 2024 13:06:41 +0000 (15:06 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:12 +0000 (12:34 +0200)
src/auth/passdb-sql.c
src/auth/userdb-sql.c

index aab83459e04726d3bb32c6e51ddf5c820d5c2679..636e21e10318b7216cb636c312a2444d8de5779f 100644 (file)
@@ -58,11 +58,12 @@ const struct setting_parser_info passdb_sql_setting_parser_info = {
        .pool_offset1 = 1 + offsetof(struct passdb_sql_settings, pool),
 };
 
-static void sql_query_save_results(struct sql_result *result,
-                                  struct passdb_sql_request *sql_request)
+static int sql_query_save_results(struct sql_result *result,
+                                 struct passdb_sql_request *sql_request)
 {
        struct auth_request *auth_request = sql_request->auth_request;
        struct passdb_module *_module = auth_request->passdb->passdb;
+       struct auth_fields *fields = auth_fields_init(auth_request->pool);
        unsigned int i, fields_count;
        const char *name, *value;
 
@@ -72,6 +73,10 @@ static void sql_query_save_results(struct sql_result *result,
                value = sql_result_get_field_value(result, i);
 
                if (*name == '\0')
+                       continue;
+
+               auth_fields_add(fields, name, value, 0);
+               if (!auth_request->passdb->set->fields_import_all)
                        ;
                else if (value == NULL)
                        auth_request_set_null_field(auth_request, name);
@@ -80,6 +85,7 @@ static void sql_query_save_results(struct sql_result *result,
                                _module->default_pass_scheme);
                }
        }
+       return auth_request_set_passdb_fields(auth_request, fields);
 }
 
 static void sql_query_callback(struct sql_result *result,
@@ -103,9 +109,9 @@ static void sql_query_callback(struct sql_result *result,
        } else if (ret == 0) {
                auth_request_db_log_unknown_user(auth_request);
                passdb_result = PASSDB_RESULT_USER_UNKNOWN;
-       } else {
-               sql_query_save_results(result, sql_request);
-
+       } else if (sql_query_save_results(result, sql_request) < 0)
+               ;
+       else {
                /* Note that we really want to check if the password field is
                   found. Just checking if password is set isn't enough,
                   because with proxies we might want to return NULL as
@@ -276,22 +282,33 @@ passdb_sql_preinit(pool_t pool, struct event *event,
 {
        struct sql_passdb_module *module;
        const struct passdb_sql_settings *set;
+       const struct auth_passdb_post_settings *post_set;
 
        if (settings_get(event, &passdb_sql_setting_parser_info,
                         SETTINGS_GET_FLAG_NO_CHECK |
                         SETTINGS_GET_FLAG_NO_EXPAND,
                         &set, error_r) < 0)
                return -1;
+       if (settings_get(event, &auth_passdb_post_setting_parser_info,
+                        SETTINGS_GET_FLAG_NO_CHECK |
+                        SETTINGS_GET_FLAG_NO_EXPAND,
+                        &post_set, error_r) < 0) {
+               settings_free(set);
+               return -1;
+       }
 
        module = p_new(pool, struct sql_passdb_module, 1);
        if (sql_init_auto(event, &module->db, error_r) <= 0) {
                settings_free(set);
+               settings_free(post_set);
                return -1;
        }
 
        module->module.default_cache_key =
-               auth_cache_parse_key(pool, set->query);
+               auth_cache_parse_key_and_fields(pool, set->query,
+                                               &post_set->fields, "sql");
        settings_free(set);
+       settings_free(post_set);
 
        *module_r = &module->module;
        return 0;
index ffba715e28e53a93d9f76febd3685348d0b49852..3ed57bbea3e8a67f5adab4766157b20e50ce9375 100644 (file)
@@ -61,10 +61,11 @@ const struct setting_parser_info userdb_sql_setting_parser_info = {
 static void userdb_sql_iterate_next(struct userdb_iterate_context *_ctx);
 static int userdb_sql_iterate_deinit(struct userdb_iterate_context *_ctx);
 
-static void
+static int
 sql_query_get_result(struct sql_result *result,
                     struct auth_request *auth_request)
 {
+       struct auth_fields *fields = auth_fields_init(auth_request->pool);
        const char *name, *value;
        unsigned int i, fields_count;
 
@@ -73,11 +74,16 @@ sql_query_get_result(struct sql_result *result,
                name = sql_result_get_field_name(result, i);
                value = sql_result_get_field_value(result, i);
 
-               if (*name != '\0' && value != NULL) {
+               if (*name == '\0' || value == NULL)
+                       continue;
+
+               auth_fields_add(fields, name, value, 0);
+               if (auth_request->userdb->set->fields_import_all) {
                        auth_request_set_userdb_field(auth_request,
                                                      name, value);
                }
        }
+       return auth_request_set_userdb_fields(auth_request, fields);
 }
 
 static void sql_query_callback(struct sql_result *sql_result,
@@ -96,8 +102,7 @@ static void sql_query_callback(struct sql_result *sql_result,
        } else if (ret == 0) {
                result = USERDB_RESULT_USER_UNKNOWN;
                auth_request_db_log_unknown_user(auth_request);
-       } else {
-               sql_query_get_result(sql_result, auth_request);
+       } else if (sql_query_get_result(sql_result, auth_request) == 0) {
                result = USERDB_RESULT_OK;
        }
 
@@ -283,22 +288,33 @@ userdb_sql_preinit(pool_t pool, struct event *event,
 {
        struct sql_userdb_module *module;
        const struct userdb_sql_settings *set;
+       const struct auth_userdb_post_settings *post_set;
 
        if (settings_get(event, &userdb_sql_setting_parser_info,
                         SETTINGS_GET_FLAG_NO_CHECK |
                         SETTINGS_GET_FLAG_NO_EXPAND,
                         &set, error_r) < 0)
                return -1;
+       if (settings_get(event, &auth_userdb_post_setting_parser_info,
+                        SETTINGS_GET_FLAG_NO_CHECK |
+                        SETTINGS_GET_FLAG_NO_EXPAND,
+                        &post_set, error_r) < 0) {
+               settings_free(set);
+               return -1;
+       }
 
        module = p_new(pool, struct sql_userdb_module, 1);
        if (sql_init_auto(event, &module->db, error_r) <= 0) {
                settings_free(set);
+               settings_free(post_set);
                return -1;
        }
 
        module->module.default_cache_key =
-               auth_cache_parse_key(pool, set->query);
+               auth_cache_parse_key_and_fields(pool, set->query,
+                                               &post_set->fields, "sql");
        settings_free(set);
+       settings_free(post_set);
        *module_r = &module->module;
        return 0;
 }
@@ -329,6 +345,7 @@ static void userdb_sql_deinit(struct userdb_module *_module)
 
 struct userdb_module_interface userdb_sql = {
        .name = "sql",
+       .fields_supported = TRUE,
 
        .preinit = userdb_sql_preinit,
        .init = userdb_sql_init,