Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5884:1c1dee40e495 HEAD
Moved generic LDAP result iteration to db_ldap. It also supports now
templates in values.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 03 Jul 2007 05:35:31 +0300 |
parents | 526d1a860b13 |
children | f0685f6ec951 |
files | src/auth/db-ldap.c src/auth/db-ldap.h src/auth/passdb-ldap.c src/auth/userdb-ldap.c |
diffstat | 4 files changed, 211 insertions(+), 100 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/db-ldap.c Tue Jul 03 04:43:45 2007 +0300 +++ b/src/auth/db-ldap.c Tue Jul 03 05:35:31 2007 +0300 @@ -8,6 +8,7 @@ #include "ioloop.h" #include "hash.h" #include "str.h" +#include "var-expand.h" #include "settings.h" #include "userdb.h" #include "db-ldap.h" @@ -41,6 +42,21 @@ # define LDAP_OPT_SUCCESS LDAP_SUCCESS #endif +struct db_ldap_result_iterate_context { + struct ldap_connection *conn; + LDAPMessage *entry; + struct auth_request *auth_request; + + struct hash_table *attr_map; + struct var_expand_table *var_table; + + char *attr, **vals; + const char *name, *value, *template, *val_1_arr[2]; + BerElement *ber; + + string_t *var, *debug; +}; + #define DEF_STR(name) DEF_STRUCT_STR(name, ldap_settings) #define DEF_INT(name) DEF_STRUCT_INT(name, ldap_settings) #define DEF_BOOL(name) DEF_STRUCT_BOOL(name, ldap_settings) @@ -642,6 +658,23 @@ t_pop(); } +struct var_expand_table * +db_ldap_value_get_var_expand_table(struct auth_request *auth_request) +{ + const struct var_expand_table *auth_table; + 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++; + + table = t_new(struct var_expand_table, count + 1); + table[0].key = '$'; + memcpy(table + 1, auth_table, sizeof(*table) * count); + return table; +} + #define IS_LDAP_ESCAPED_CHAR(c) \ ((c) == '*' || (c) == '(' || (c) == ')' || (c) == '\\') @@ -670,6 +703,149 @@ return str_c(ret); } +struct db_ldap_result_iterate_context * +db_ldap_result_iterate_init(struct ldap_connection *conn, LDAPMessage *entry, + struct auth_request *auth_request, + struct hash_table *attr_map) +{ + struct db_ldap_result_iterate_context *ctx; + + ctx = t_new(struct db_ldap_result_iterate_context, 1); + ctx->conn = conn; + ctx->entry = entry; + ctx->auth_request = auth_request; + ctx->attr_map = attr_map; + + if (auth_request->auth->verbose_debug) + ctx->debug = t_str_new(256); + + ctx->attr = ldap_first_attribute(conn->ld, entry, &ctx->ber); + return ctx; +} + +static void +db_ldap_result_iterate_finish(struct db_ldap_result_iterate_context *ctx) +{ + if (ctx->debug != NULL && str_len(ctx->debug) > 0) { + auth_request_log_debug(ctx->auth_request, "ldap", + "result: %s", str_c(ctx->debug) + 1); + } + + ber_free(ctx->ber, 0); +} + +static void +db_ldap_result_change_attr(struct db_ldap_result_iterate_context *ctx) +{ + ctx->name = hash_lookup(ctx->attr_map, ctx->attr); + + if (ctx->debug != NULL) { + str_printfa(ctx->debug, " %s(%s)=", ctx->attr, + ctx->name != NULL ? ctx->name : "?unknown?"); + } + + if (ctx->name == NULL || *ctx->name == '\0') { + ctx->value = NULL; + return; + } + + if (strchr(ctx->name, '%') != NULL && + (ctx->template = strchr(ctx->name, '=')) != NULL) { + /* we want to use variables */ + ctx->name = t_strdup_until(ctx->name, ctx->template); + ctx->template++; + if (ctx->var_table == NULL) { + ctx->var_table = db_ldap_value_get_var_expand_table( + ctx->auth_request); + ctx->var = t_str_new(256); + } + } + + ctx->vals = ldap_get_values(ctx->conn->ld, ctx->entry, + ctx->attr); + ctx->value = ctx->vals[0]; +} + +static void +db_ldap_result_return_value(struct db_ldap_result_iterate_context *ctx) +{ + bool first = ctx->value == ctx->vals[0]; + + if (ctx->template != NULL) { + ctx->var_table[0].value = ctx->value; + str_truncate(ctx->var, 0); + var_expand(ctx->var, ctx->template, ctx->var_table); + ctx->value = str_c(ctx->var); + } + + if (ctx->debug != NULL) { + if (!first) + str_append_c(ctx->debug, '/'); + if (ctx->auth_request->auth->verbose_debug_passwords || + strcmp(ctx->name, "password") != 0) + str_append(ctx->debug, ctx->value); + else + str_append(ctx->debug, PASSWORD_HIDDEN_STR); + } +} + +static bool db_ldap_result_int_next(struct db_ldap_result_iterate_context *ctx) +{ + while (ctx->attr != NULL) { + if (ctx->vals == NULL) { + /* a new attribute */ + db_ldap_result_change_attr(ctx); + } else { + /* continuing existing attribute */ + if (ctx->value != NULL) + ctx->value++; + } + + if (ctx->value != NULL) { + db_ldap_result_return_value(ctx); + return TRUE; + } + + ldap_value_free(ctx->vals); ctx->vals = NULL; + ldap_memfree(ctx->attr); + ctx->attr = ldap_next_attribute(ctx->conn->ld, ctx->entry, + ctx->ber); + } + + db_ldap_result_iterate_finish(ctx); + return FALSE; +} + +bool db_ldap_result_iterate_next(struct db_ldap_result_iterate_context *ctx, + const char **name_r, const char **value_r) +{ + if (!db_ldap_result_int_next(ctx)) + return FALSE; + + *name_r = ctx->name; + *value_r = ctx->value; + return TRUE; +} + +bool db_ldap_result_iterate_next_all(struct db_ldap_result_iterate_context *ctx, + const char **name_r, + const char *const **values_r) +{ + if (!db_ldap_result_int_next(ctx)) + return FALSE; + + if (ctx->template != NULL) { + /* we can use only one value with templates */ + ctx->val_1_arr[0] = ctx->value; + *values_r = ctx->val_1_arr; + } else { + *values_r = (const char *const *)ctx->vals; + } + ctx->value = NULL; + *name_r = ctx->name; + return TRUE; +} + static const char *parse_setting(const char *key, const char *value, struct ldap_connection *conn) {
--- a/src/auth/db-ldap.h Tue Jul 03 04:43:45 2007 +0300 +++ b/src/auth/db-ldap.h Tue Jul 03 05:35:31 2007 +0300 @@ -107,8 +107,21 @@ int db_ldap_connect(struct ldap_connection *conn); +struct var_expand_table * +db_ldap_value_get_var_expand_table(struct auth_request *auth_request); + const char *ldap_escape(const char *str, const struct auth_request *auth_request); const char *ldap_get_error(struct ldap_connection *conn); +struct db_ldap_result_iterate_context * +db_ldap_result_iterate_init(struct ldap_connection *conn, LDAPMessage *entry, + struct auth_request *auth_request, + struct hash_table *attr_map); +bool db_ldap_result_iterate_next(struct db_ldap_result_iterate_context *ctx, + const char **name_r, const char **value_r); +bool db_ldap_result_iterate_next_all(struct db_ldap_result_iterate_context *ctx, + const char **name_r, + const char *const **values_r); + #endif
--- a/src/auth/passdb-ldap.c Tue Jul 03 04:43:45 2007 +0300 +++ b/src/auth/passdb-ldap.c Tue Jul 03 05:35:31 2007 +0300 @@ -34,87 +34,6 @@ } callback; }; -struct ldap_query_save_context { - struct ldap_connection *conn; - struct auth_request *auth_request; - LDAPMessage *entry; - - string_t *debug; -}; - -static void -ldap_query_save_attr(struct ldap_query_save_context *ctx, const char *attr) -{ - struct auth *auth = ctx->auth_request->auth; - const char *name; - char **vals; - unsigned int i; - - name = hash_lookup(ctx->conn->pass_attr_map, attr); - - if (auth->verbose_debug) { - if (ctx->debug == NULL) - ctx->debug = t_str_new(256); - else - str_append_c(ctx->debug, ' '); - str_append(ctx->debug, attr); - str_printfa(ctx->debug, "(%s)=", - name != NULL ? name : "?unknown?"); - } - - if (name == NULL) - return; - - vals = ldap_get_values(ctx->conn->ld, ctx->entry, attr); - if (vals != NULL && *name != '\0') { - for (i = 0; vals[i] != NULL; i++) { - if (ctx->debug != NULL) { - if (i != 0) - str_append_c(ctx->debug, '/'); - if (auth->verbose_debug_passwords || - strcmp(name, "password") != 0) - str_append(ctx->debug, vals[i]); - else { - str_append(ctx->debug, - PASSWORD_HIDDEN_STR); - } - } - auth_request_set_field(ctx->auth_request, name, vals[i], - ctx->conn->set.default_pass_scheme); - } - } - - ldap_value_free(vals); -} - -static void -ldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry, - struct auth_request *auth_request) -{ - struct ldap_query_save_context ctx; - BerElement *ber; - char *attr; - - memset(&ctx, 0, sizeof(ctx)); - ctx.conn = conn; - ctx.auth_request = auth_request; - ctx.entry = entry; - - attr = ldap_first_attribute(conn->ld, entry, &ber); - while (attr != NULL) { - ldap_query_save_attr(&ctx, attr); - ldap_memfree(attr); - - attr = ldap_next_attribute(conn->ld, entry, ber); - } - ber_free(ber, 0); - - if (ctx.debug != NULL) { - auth_request_log_debug(auth_request, "ldap", - "result: %s", str_c(ctx.debug)); - } -} - static LDAPMessage * handle_request_get_entry(struct ldap_connection *conn, struct auth_request *auth_request, @@ -159,6 +78,21 @@ return NULL; } +static void +ldap_query_save_result(struct ldap_connection *conn, + LDAPMessage *entry, struct auth_request *auth_request) +{ + struct db_ldap_result_iterate_context *ldap_iter; + const char *name, *value; + + ldap_iter = db_ldap_result_iterate_init(conn, entry, auth_request, + conn->pass_attr_map); + while (db_ldap_result_iterate_next(ldap_iter, &name, &value)) { + auth_request_set_field(auth_request, name, value, + conn->set.default_pass_scheme); + } +} + static void handle_request(struct ldap_connection *conn, struct ldap_request *request, LDAPMessage *res) {
--- a/src/auth/userdb-ldap.c Tue Jul 03 04:43:45 2007 +0300 +++ b/src/auth/userdb-ldap.c Tue Jul 03 05:35:31 2007 +0300 @@ -34,27 +34,15 @@ ldap_query_get_result(struct ldap_connection *conn, LDAPMessage *entry, struct auth_request *auth_request) { - BerElement *ber; - const char *name; - char *attr, **vals; - - auth_request_init_userdb_reply(auth_request); - - attr = ldap_first_attribute(conn->ld, entry, &ber); - while (attr != NULL) { - name = hash_lookup(conn->user_attr_map, attr); - vals = ldap_get_values(conn->ld, entry, attr); + struct db_ldap_result_iterate_context *ldap_iter; + const char *name, *const *values; - if (name != NULL && *name != '\0' && vals != NULL) { - auth_request_set_userdb_field_values(auth_request, - name, (const char *const *)vals); - } - ldap_value_free(vals); - ldap_memfree(attr); - - attr = ldap_next_attribute(conn->ld, entry, ber); + ldap_iter = db_ldap_result_iterate_init(conn, entry, auth_request, + conn->user_attr_map); + while (db_ldap_result_iterate_next_all(ldap_iter, &name, &values)) { + auth_request_set_userdb_field_values(auth_request, + name, values); } - ber_free(ber, 0); } static void handle_request(struct ldap_connection *conn,