From: Timo Sirainen Date: Mon, 24 Sep 2012 13:49:29 +0000 (+0300) Subject: ldap auth: Update %variables after each field update. X-Git-Tag: 2.2.alpha1~138^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bbc8a478be20d0be16e92179fc32327004ebf86;p=thirdparty%2Fdovecot%2Fcore.git ldap auth: Update %variables after each field update. 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. --- diff --git a/src/auth/auth-request.c b/src/auth/auth-request.c index 683b975322..d7a2c1e60d 100644 --- a/src/auth/auth-request.c +++ b/src/auth/auth-request.c @@ -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) { diff --git a/src/auth/auth-request.h b/src/auth/auth-request.h index b28ab350fd..0494a25c8c 100644 --- a/src/auth/auth-request.h +++ b/src/auth/auth-request.h @@ -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); diff --git a/src/auth/db-ldap.c b/src/auth/db-ldap.c index fa455a4732..85875c2a6b 100644 --- a/src/auth/db-ldap.c +++ b/src/auth/db-ldap.c @@ -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;