]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
ldap auth: Update %variables after each field update.
authorTimo Sirainen <tss@iki.fi>
Mon, 24 Sep 2012 13:49:29 +0000 (16:49 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 24 Sep 2012 13:49:29 +0000 (16:49 +0300)
The previous behavior was a bit confusing. "uid=user" at the beginning
updated the %u variable, but if it was after templates it didn't update it.
Also "=user=%{uid}" that was supposed to be equivalent wasn't. Now the
behavior is consistent across all ways to set the fields.

src/auth/auth-request.c
src/auth/auth-request.h
src/auth/db-ldap.c

index 683b97532222c3dfc0569ee191ee498f12ac1202..d7a2c1e60dbaeae8fadfa95b0f1eaf3f346f4554 100644 (file)
@@ -1794,16 +1794,18 @@ const struct var_expand_table auth_request_var_expand_static_tab[] = {
        { '\0', NULL, NULL }
 };
 
-const struct var_expand_table *
-auth_request_get_var_expand_table(const struct auth_request *auth_request,
-                                 auth_request_escape_func_t *escape_func)
+struct var_expand_table *
+auth_request_get_var_expand_table_full(const struct auth_request *auth_request,
+                                      auth_request_escape_func_t *escape_func,
+                                      unsigned int *count)
 {
        struct var_expand_table *tab;
 
        if (escape_func == NULL)
                escape_func = escape_none;
 
-       tab = t_malloc(sizeof(auth_request_var_expand_static_tab));
+       *count += N_ELEMENTS(auth_request_var_expand_static_tab);
+       tab = t_malloc(*count * sizeof(struct var_expand_table));
        memcpy(tab, auth_request_var_expand_static_tab,
               sizeof(auth_request_var_expand_static_tab));
 
@@ -1855,6 +1857,16 @@ auth_request_get_var_expand_table(const struct auth_request *auth_request,
        return tab;
 }
 
+const struct var_expand_table *
+auth_request_get_var_expand_table(const struct auth_request *auth_request,
+                                 auth_request_escape_func_t *escape_func)
+{
+       unsigned int count = 0;
+
+       return auth_request_get_var_expand_table_full(auth_request, escape_func,
+                                                     &count);
+}
+
 static void get_log_prefix(string_t *str, struct auth_request *auth_request,
                           const char *subsystem)
 {
index b28ab350fd11ef2d7f5a49111f2c3c3a0c7f6cbd..0494a25c8c53c9880afb7ed2171f8f937964c5e5 100644 (file)
@@ -207,6 +207,10 @@ int auth_request_password_verify(struct auth_request *request,
 const struct var_expand_table *
 auth_request_get_var_expand_table(const struct auth_request *auth_request,
                                  auth_request_escape_func_t *escape_func);
+struct var_expand_table *
+auth_request_get_var_expand_table_full(const struct auth_request *auth_request,
+                                      auth_request_escape_func_t *escape_func,
+                                      unsigned int *count);
 const char *auth_request_str_escape(const char *string,
                                    const struct auth_request *request);
 
index fa455a47324443f802e87254c314d76b40e14403..85875c2a6b22c0eaa34c3cbf4bd8811a16dc4360 100644 (file)
@@ -63,7 +63,6 @@ struct db_ldap_result_iterate_context {
 
        /* ldap_attr_name => struct db_ldap_value */
        struct hash_table *ldap_attrs;
-       struct var_expand_table *var_table;
 
        const char *val_1_arr[2];
        string_t *var, *debug;
@@ -1068,21 +1067,17 @@ void db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
        *attr_names_r = array_idx_modifiable(&ctx.attr_names, 0);
 }
 
-static struct var_expand_table *
-db_ldap_value_get_var_expand_table(pool_t pool,
-                                  struct auth_request *auth_request)
+static const struct var_expand_table *
+db_ldap_value_get_var_expand_table(struct auth_request *auth_request,
+                                  const char *ldap_value)
 {
-       const struct var_expand_table *auth_table = NULL;
        struct var_expand_table *table;
-       unsigned int count;
-
-       auth_table = auth_request_get_var_expand_table(auth_request, NULL);
-       for (count = 0; auth_table[count].key != '\0'; count++) ;
-       count++;
+       unsigned int count = 1;
 
-       table = p_new(pool, struct var_expand_table, count + 2);
-       table[0].key = '$';
-       memcpy(table + 1, auth_table, sizeof(*table) * count);
+       table = auth_request_get_var_expand_table_full(auth_request, NULL,
+                                                      &count);
+       table[count-1].key = '$';
+       table[count-1].value = ldap_value;
        return table;
 }
 
@@ -1240,6 +1235,7 @@ db_ldap_result_return_value(struct db_ldap_result_iterate_context *ctx,
                { "ldap", db_ldap_field_expand },
                { NULL, NULL }
        };
+       const struct var_expand_table *var_table;
        const char *const *values;
 
        if (ldap_value != NULL)
@@ -1265,14 +1261,18 @@ db_ldap_result_return_value(struct db_ldap_result_iterate_context *ctx,
                                "using value '%s'",
                                field->name, values[0]);
                }
-               if (ctx->var_table == NULL) {
-                       ctx->var_table = db_ldap_value_get_var_expand_table(
-                                               ctx->pool, ctx->auth_request);
+
+               /* do this lookup separately for each expansion, because:
+                  1) the values are allocated from data stack
+                  2) if "user" field is updated, we want %u/%n/%d updated
+                     (and less importantly the same for other variables) */
+               var_table = db_ldap_value_get_var_expand_table(ctx->auth_request,
+                                                              values[0]);
+               if (ctx->var == NULL)
                        ctx->var = str_new(ctx->pool, 256);
-               }
-               ctx->var_table[0].value = values[0];
-               str_truncate(ctx->var, 0);
-               var_expand_with_funcs(ctx->var, field->value, ctx->var_table,
+               else
+                       str_truncate(ctx->var, 0);
+               var_expand_with_funcs(ctx->var, field->value, var_table,
                                      var_funcs_table, ctx);
                ctx->val_1_arr[0] = str_c(ctx->var);
                values = ctx->val_1_arr;