]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Add auth_cache_parse_key_and_fields()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 12 Mar 2024 20:52:39 +0000 (22:52 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Fri, 17 Jan 2025 08:39:58 +0000 (10:39 +0200)
src/auth/auth-cache.c
src/auth/auth-cache.h

index 42ac687d1afb8c12ec14975e56b2061f86e8d2ae..d6cbe8bb524a4ce40697bfeb9430b39911bc5782 100644 (file)
@@ -80,14 +80,17 @@ static void auth_cache_key_add_tab_idx(string_t *str, unsigned int i)
        }
 }
 
-char *auth_cache_parse_key(pool_t pool, const char *query)
+static char *auth_cache_parse_key_exclude(pool_t pool, const char *query,
+                                         const char *exclude_driver)
 {
        string_t *str;
        bool key_seen[AUTH_REQUEST_VAR_TAB_COUNT];
        const char *extra_vars;
-       unsigned int i, idx, size, tab_idx;
+       unsigned int i, idx, size, tab_idx, exclude_driver_len;
 
        memset(key_seen, 0, sizeof(key_seen));
+       exclude_driver_len = exclude_driver == NULL ? 0 :
+               strlen(exclude_driver);
 
        str = t_str_new(32);
        for (; *query != '\0'; ) {
@@ -107,7 +110,10 @@ char *auth_cache_parse_key(pool_t pool, const char *query)
                        /* just add the key. it would be nice to prevent
                           duplicates here as well, but that's just too
                           much trouble and probably very rare. */
-                       auth_cache_key_add_var(str, query, size);
+                       if (exclude_driver_len == 0 ||
+                           size < exclude_driver_len ||
+                           memcmp(query, exclude_driver, exclude_driver_len) != 0)
+                               auth_cache_key_add_var(str, query, size);
                } else {
                        i_assert(tab_idx < N_ELEMENTS(key_seen));
                        key_seen[tab_idx] = TRUE;
@@ -144,6 +150,31 @@ char *auth_cache_parse_key(pool_t pool, const char *query)
        return p_strdup(pool, str_c(str));
 }
 
+char *auth_cache_parse_key(pool_t pool, const char *query)
+{
+       return auth_cache_parse_key_exclude(pool, query, NULL);
+}
+
+char *auth_cache_parse_key_and_fields(pool_t pool, const char *query,
+                                     const ARRAY_TYPE(const_string) *fields,
+                                     const char *exclude_driver)
+{
+       if (array_is_empty(fields))
+               return auth_cache_parse_key_exclude(pool, query, exclude_driver);
+
+       string_t *full_query = t_str_new(128);
+       str_append(full_query, query);
+
+       unsigned int i, count;
+       const char *const *str = array_get(fields, &count);
+       for (i = 0; i < count; i += 2) {
+               str_append_c(full_query, '\t');
+               str_append(full_query, str[i + 1]);
+       }
+       return auth_cache_parse_key_exclude(pool, str_c(full_query),
+                                           exclude_driver);
+}
+
 static void
 auth_cache_node_unlink(struct auth_cache *cache, struct auth_cache_node *node)
 {
index ab02fe57c06856791533f53d085717e31d840d1f..9bdb918517045bd14c31dd8935b50bf5f804d851 100644 (file)
@@ -19,6 +19,11 @@ struct auth_request;
 /* Parses all %x variables from query and compresses them into tab-separated
    list, so it can be used as a cache key. */
 char *auth_cache_parse_key(pool_t pool, const char *query);
+/* Same as auth_cache_parse_key(), but add also variables from "fields",
+   except variables prefixed with <exclude_driver>":" */
+char *auth_cache_parse_key_and_fields(pool_t pool, const char *query,
+                                     const ARRAY_TYPE(const_string) *fields,
+                                     const char *exclude_driver);
 
 /* Create a new cache. max_size specifies the maximum amount of memory in
    bytes to use for cache (it's not fully exact). ttl_secs specifies time to