Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2057:5e0167577399 HEAD
Fixed var_expand() to take a table of variables rather than a few predefined
ones. Added support for modifiers.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 25 May 2004 01:33:50 +0300 |
parents | 7c47536833ca |
children | 0a1755f79392 |
files | dovecot-example.conf src/auth/auth-master-connection.c src/auth/mech.c src/auth/mech.h src/auth/passdb-ldap.c src/auth/passdb-mysql.c src/auth/passdb-pgsql.c src/auth/userdb-ldap.c src/auth/userdb-mysql.c src/auth/userdb-passwd-file.c src/auth/userdb-passwd.c src/auth/userdb-pgsql.c src/auth/userdb-static.c src/auth/userdb-vpopmail.c src/auth/userdb.h src/lib-index/mail-index-sync-update.c src/lib/strfuncs.c src/lib/strfuncs.h src/lib/var-expand.c src/lib/var-expand.h src/master/common.h src/master/login-process.h src/master/mail-process.c |
diffstat | 23 files changed, 221 insertions(+), 90 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Tue May 25 01:13:55 2004 +0300 +++ b/dovecot-example.conf Tue May 25 01:33:50 2004 +0300 @@ -166,6 +166,12 @@ # %n - user part in user@domain, same as %u if there's no domain # %d - domain part in user@domain, empty if user there's no domain # %h - home directory +# %p - protocol (IMAP or POP3) +# +# You can apply a modifiers for each variable (eg. %Lp = pop3): +# %L - lowercase +# %U - uppercase +# %E - escape '"', "'" and '\' characters by inserting '\' before them. # # You can also limit a width of string by giving the number of max. characters # after the '%' character. For example %1u gives the first character of
--- a/src/auth/auth-master-connection.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/auth-master-connection.c Tue May 25 01:33:50 2004 +0300 @@ -149,7 +149,7 @@ master_request->tag = request->tag; conn->refcount++; - userdb->lookup(auth_request->user, userdb_callback, + userdb->lookup(auth_request, userdb_callback, master_request); /* the auth request is finished, we don't need it anymore */
--- a/src/auth/mech.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/mech.c Tue May 25 01:33:50 2004 +0300 @@ -5,6 +5,7 @@ #include "buffer.h" #include "hash.h" #include "mech.h" +#include "var-expand.h" #include "auth-client-connection.h" #include <stdlib.h> @@ -225,6 +226,48 @@ return FALSE; } +static const char *escape_none(const char *str) +{ + return str; +} + +const struct var_expand_table * +auth_request_get_var_expand_table(const struct auth_request *auth_request, + const char *(*escape_func)(const char *)) +{ + static struct var_expand_table static_tab[] = { + { 'u', NULL }, + { 'n', NULL }, + { 'd', NULL }, + { 'p', NULL }, + { '\0', NULL } + }; + struct var_expand_table *tab; + + if (escape_func == NULL) + escape_func = escape_none; + + tab = t_malloc(sizeof(static_tab)); + memcpy(tab, static_tab, sizeof(static_tab)); + + tab[0].value = escape_func(auth_request->user); + tab[1].value = escape_func(t_strcut(auth_request->user, '@')); + tab[2].value = strchr(auth_request->user, '@'); + if (tab[2].value != NULL) + tab[2].value = escape_func(tab[2].value+1); + + switch (auth_request->protocol) { + case AUTH_PROTOCOL_IMAP: + tab[3].value = "IMAP"; + break; + case AUTH_PROTOCOL_POP3: + tab[3].value = "POP3"; + break; + } + + return tab; +} + extern struct mech_module mech_plain; extern struct mech_module mech_cram_md5; extern struct mech_module mech_digest_md5;
--- a/src/auth/mech.h Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/mech.h Tue May 25 01:33:50 2004 +0300 @@ -75,6 +75,10 @@ void auth_request_ref(struct auth_request *request); int auth_request_unref(struct auth_request *request); +const struct var_expand_table * +auth_request_get_var_expand_table(const struct auth_request *auth_request, + const char *(*escape_func)(const char *)); + void mech_init(void); void mech_deinit(void);
--- a/src/auth/passdb-ldap.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/passdb-ldap.c Tue May 25 01:33:50 2004 +0300 @@ -141,16 +141,18 @@ struct ldap_request *ldap_request) { struct ldap_connection *conn = passdb_ldap_conn->conn; - const char *user, *filter; + const char *filter; string_t *str; - user = ldap_escape(auth_request->user); if (conn->set.pass_filter == NULL) { filter = t_strdup_printf("(&(objectClass=posixAccount)(%s=%s))", - passdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], user); + passdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], + ldap_escape(auth_request->user)); } else { str = t_str_new(512); - var_expand(str, conn->set.pass_filter, user, NULL); + var_expand(str, conn->set.pass_filter, + auth_request_get_var_expand_table(auth_request, + ldap_escape)); filter = str_c(str); }
--- a/src/auth/passdb-mysql.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/passdb-mysql.c Tue May 25 01:33:50 2004 +0300 @@ -108,7 +108,8 @@ str = t_str_new(512); var_expand(str, conn->set.password_query, - str_escape(auth_request->user), NULL); + auth_request_get_var_expand_table(auth_request, + str_escape)); query = str_c(str); mysql_request->callback = mysql_handle_request;
--- a/src/auth/passdb-pgsql.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/passdb-pgsql.c Tue May 25 01:33:50 2004 +0300 @@ -105,7 +105,8 @@ str = t_str_new(512); var_expand(str, conn->set.password_query, - db_pgsql_escape(auth_request->user), NULL); + auth_request_get_var_expand_table(auth_request, + db_pgsql_escape)); query = str_c(str); pgsql_request->callback = pgsql_handle_request;
--- a/src/auth/userdb-ldap.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb-ldap.c Tue May 25 01:33:50 2004 +0300 @@ -149,21 +149,23 @@ t_pop(); } -static void userdb_ldap_lookup(const char *user, userdb_callback_t *callback, - void *context) +static void userdb_ldap_lookup(struct auth_request *auth_request, + userdb_callback_t *callback, void *context) { struct ldap_connection *conn = userdb_ldap_conn->conn; struct userdb_ldap_request *request; const char *filter; string_t *str; - user = ldap_escape(user); if (conn->set.user_filter == NULL) { filter = t_strdup_printf("(&(objectClass=posixAccount)(%s=%s))", - userdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], user); + userdb_ldap_conn->attr_names[ATTR_VIRTUAL_USER], + ldap_escape(auth_request->user)); } else { str = t_str_new(512); - var_expand(str, conn->set.user_filter, user, NULL); + var_expand(str, conn->set.user_filter, + auth_request_get_var_expand_table(auth_request, + ldap_escape)); filter = str_c(str); }
--- a/src/auth/userdb-mysql.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb-mysql.c Tue May 25 01:33:50 2004 +0300 @@ -114,8 +114,8 @@ } } -static void userdb_mysql_lookup(const char *user, userdb_callback_t *callback, - void *context) +static void userdb_mysql_lookup(struct auth_request *auth_request, + userdb_callback_t *callback, void *context) { struct mysql_connection *conn = userdb_mysql_conn->conn; struct userdb_mysql_request *request; @@ -123,14 +123,17 @@ string_t *str; str = t_str_new(512); - var_expand(str, conn->set.user_query, str_escape(user), NULL); + var_expand(str, conn->set.user_query, + auth_request_get_var_expand_table(auth_request, + str_escape)); query = str_c(str); - request = i_malloc(sizeof(struct userdb_mysql_request) + strlen(user)); + request = i_malloc(sizeof(struct userdb_mysql_request) + + strlen(auth_request->user)); request->request.callback = mysql_handle_request; request->request.context = context; request->userdb_callback = callback; - strcpy(request->username, user); + strcpy(request->username, auth_request->user); db_mysql_query(conn, query, &request->request); }
--- a/src/auth/userdb-passwd-file.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb-passwd-file.c Tue May 25 01:33:50 2004 +0300 @@ -11,13 +11,13 @@ struct passwd_file *userdb_pwf = NULL; -static void passwd_file_lookup(const char *user, userdb_callback_t *callback, - void *context) +static void passwd_file_lookup(struct auth_request *auth_request, + userdb_callback_t *callback, void *context) { struct user_data data; struct passwd_user *pu; - pu = db_passwd_file_lookup(userdb_pwf, user); + pu = db_passwd_file_lookup(userdb_pwf, auth_request->user); if (pu == NULL) { callback(NULL, context); return; @@ -27,7 +27,7 @@ data.uid = pu->uid; data.gid = pu->gid; - data.virtual_user = user; + data.virtual_user = auth_request->user; data.home = pu->home; data.mail = pu->mail;
--- a/src/auth/userdb-passwd.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb-passwd.c Tue May 25 01:33:50 2004 +0300 @@ -10,16 +10,16 @@ #include <pwd.h> -static void passwd_lookup(const char *user, userdb_callback_t *callback, - void *context) +static void passwd_lookup(struct auth_request *auth_request, + userdb_callback_t *callback, void *context) { struct user_data data; struct passwd *pw; - pw = getpwnam(user); + pw = getpwnam(auth_request->user); if (pw == NULL) { if (verbose) - i_info("passwd(%s): unknown user", user); + i_info("passwd(%s): unknown user", auth_request->user); callback(NULL, context); return; }
--- a/src/auth/userdb-pgsql.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb-pgsql.c Tue May 25 01:33:50 2004 +0300 @@ -84,8 +84,8 @@ } } -static void userdb_pgsql_lookup(const char *user, userdb_callback_t *callback, - void *context) +static void userdb_pgsql_lookup(struct auth_request *auth_request, + userdb_callback_t *callback, void *context) { struct pgsql_connection *conn = userdb_pgsql_conn->conn; struct userdb_pgsql_request *request; @@ -93,14 +93,17 @@ string_t *str; str = t_str_new(512); - var_expand(str, conn->set.user_query, db_pgsql_escape(user), NULL); + var_expand(str, conn->set.user_query, + auth_request_get_var_expand_table(auth_request, + db_pgsql_escape)); query = str_c(str); - request = i_malloc(sizeof(struct userdb_pgsql_request) + strlen(user)); + request = i_malloc(sizeof(struct userdb_pgsql_request) + + strlen(auth_request->user)); request->request.callback = pgsql_handle_request; request->request.context = context; request->userdb_callback = callback; - strcpy(request->username, user); + strcpy(request->username, auth_request->user); db_pgsql_query(conn, query, &request->request); }
--- a/src/auth/userdb-static.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb-static.c Tue May 25 01:33:50 2004 +0300 @@ -16,8 +16,8 @@ static gid_t static_gid; static char *static_home_template; -static void static_lookup(const char *user, userdb_callback_t *callback, - void *context) +static void static_lookup(struct auth_request *auth_request, + userdb_callback_t *callback, void *context) { struct user_data data; string_t *str; @@ -26,10 +26,11 @@ data.uid = static_uid; data.gid = static_gid; - data.virtual_user = data.system_user = user; + data.virtual_user = data.system_user = auth_request->user; str = t_str_new(256); - var_expand(str, static_home_template, user, NULL); + var_expand(str, static_home_template, + auth_request_get_var_expand_table(auth_request, NULL)); data.home = str_c(str); callback(&data, context);
--- a/src/auth/userdb-vpopmail.c Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb-vpopmail.c Tue May 25 01:33:50 2004 +0300 @@ -46,8 +46,8 @@ #ifdef USERDB_VPOPMAIL -static void vpopmail_lookup(const char *user, userdb_callback_t *callback, - void *context) +static void vpopmail_lookup(struct auth_request *auth_request, + userdb_callback_t *callback, void *context) { char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT]; struct vqpasswd *vpw; @@ -56,7 +56,7 @@ gid_t gid; pool_t pool; - vpw = vpopmail_lookup_vqp(user, vpop_user, vpop_domain); + vpw = vpopmail_lookup_vqp(auth_request->user, vpop_user, vpop_domain); if (vpw == NULL) { callback(NULL, context); return; @@ -67,7 +67,7 @@ if (vget_assign(vpop_domain, NULL, 0, &uid, &gid) == NULL) { if (verbose) { i_info("vpopmail(%s): vget_assign(%s) failed", - user, vpop_domain); + auth_request->user, vpop_domain); } callback(NULL, context); return; @@ -77,12 +77,12 @@ /* user's homedir doesn't exist yet, create it */ if (verbose) { i_info("vpopmail(%s): pw_dir isn't set, creating", - user); + auth_request->user); } if (make_user_dir(vpop_user, vpop_domain, uid, gid) == NULL) { i_error("vpopmail(%s): make_user_dir(%s, %s) failed", - user, vpop_user, vpop_domain); + auth_request->user, vpop_user, vpop_domain); callback(NULL, context); return; }
--- a/src/auth/userdb.h Tue May 25 01:13:55 2004 +0300 +++ b/src/auth/userdb.h Tue May 25 01:33:50 2004 +0300 @@ -1,6 +1,8 @@ #ifndef __USERDB_H #define __USERDB_H +#include "mech.h" + struct user_data { const char *virtual_user; const char *home; @@ -17,8 +19,8 @@ void (*init)(const char *args); void (*deinit)(void); - void (*lookup)(const char *user, userdb_callback_t *callback, - void *context); + void (*lookup)(struct auth_request *auth_request, + userdb_callback_t *callback, void *context); }; extern struct userdb_module *userdb;
--- a/src/lib-index/mail-index-sync-update.c Tue May 25 01:13:55 2004 +0300 +++ b/src/lib-index/mail-index-sync-update.c Tue May 25 01:33:50 2004 +0300 @@ -81,6 +81,7 @@ map->records_count -= count; hdr->messages_count -= count; + view->messages_count -= count; if (map->buffer != NULL) { buffer_set_used_size(map->buffer, map->records_count); @@ -123,6 +124,7 @@ map->records[map->records_count++] = *rec; map->hdr_copy.messages_count++; map->hdr_copy.next_uid = rec->uid+1; + view->messages_count++; mail_index_header_update_counts(&map->hdr_copy, 0, rec->flags); mail_index_header_update_lowwaters(&map->hdr_copy, rec);
--- a/src/lib/strfuncs.c Tue May 25 01:13:55 2004 +0300 +++ b/src/lib/strfuncs.c Tue May 25 01:33:50 2004 +0300 @@ -433,6 +433,16 @@ return str; } +const char *t_str_lcase(const char *str) +{ + return str_lcase(t_strdup_noconst(str)); +} + +const char *t_str_ucase(const char *str) +{ + return str_ucase(t_strdup_noconst(str)); +} + int null_strcmp(const char *s1, const char *s2) { if (s1 == NULL)
--- a/src/lib/strfuncs.h Tue May 25 01:13:55 2004 +0300 +++ b/src/lib/strfuncs.h Tue May 25 01:33:50 2004 +0300 @@ -50,6 +50,8 @@ char *str_ucase(char *str); char *str_lcase(char *str); +const char *t_str_lcase(const char *str); +const char *t_str_ucase(const char *str); int null_strcmp(const char *s1, const char *s2); int memcasecmp(const void *p1, const void *p2, size_t size);
--- a/src/lib/var-expand.c Tue May 25 01:13:55 2004 +0300 +++ b/src/lib/var-expand.c Tue May 25 01:33:50 2004 +0300 @@ -2,53 +2,70 @@ #include "lib.h" #include "str.h" +#include "strescape.h" #include "var-expand.h" +struct var_expand_modifier { + char key; + const char *(*func)(const char *); +}; + +static const struct var_expand_modifier modifiers[] = { + { 'L', t_str_lcase }, + { 'U', t_str_ucase }, + { 'E', str_escape }, + { '\0', NULL } +}; + void var_expand(string_t *dest, const char *str, - const char *user, const char *home) + const struct var_expand_table *table) { + const struct var_expand_modifier *m; + const struct var_expand_table *t; const char *var; unsigned int width; + const char *(*modifier)(const char *); for (; *str != '\0'; str++) { if (*str != '%') str_append_c(dest, *str); else { + str++; width = 0; - while (str[1] >= '0' && str[1] <= '9') { - width = width*10 + (str[1] - '0'); + while (*str >= '0' && *str <= '9') { + width = width*10 + (*str - '0'); str++; } - switch (str[1]) { - case '%': - var = "%"; - break; - case 'u': - var = user; - break; - case 'h': - var = home; - break; - case 'n': - var = t_strcut(user, '@'); - break; - case 'd': - var = strchr(user, '@'); - if (var != NULL) var++; - break; - default: - str_append_c(dest, '%'); - if (str[1] != '\0') - str_append_c(dest, str[1]); - var = NULL; - break; + modifier = NULL; + for (m = modifiers; m->key != '\0'; m++) { + if (m->key == *str) { + modifier = m->func; + str++; + break; + } } - if (str[1] != '\0') - str++; + if (*str == '\0') + break; + + var = NULL; + for (t = table; t->key != '\0'; t++) { + if (t->key == *str) { + var = t->value != NULL ? t->value : ""; + break; + } + } + + if (var == NULL) { + /* not found */ + if (*str == '%') + var = "%"; + } if (var != NULL) { + if (modifier != NULL) + var = modifier(var); if (width == 0) str_append(dest, var); else
--- a/src/lib/var-expand.h Tue May 25 01:13:55 2004 +0300 +++ b/src/lib/var-expand.h Tue May 25 01:33:50 2004 +0300 @@ -1,13 +1,14 @@ #ifndef __VAR_EXPAND_H #define __VAR_EXPAND_H -/* Expand % variables in str: +struct var_expand_table { + char key; + const char *value; +}; - %u user or user@domain - %h home - %n user - %d domain */ +/* Expand % variables in src and append the string in dest. + table must end with key = 0. */ void var_expand(string_t *dest, const char *str, - const char *user, const char *home); + const struct var_expand_table *table); #endif
--- a/src/master/common.h Tue May 25 01:13:55 2004 +0300 +++ b/src/master/common.h Tue May 25 01:33:50 2004 +0300 @@ -9,7 +9,7 @@ #include "../auth/auth-master-interface.h" -enum { +enum process_type { PROCESS_TYPE_UNKNOWN, PROCESS_TYPE_AUTH, PROCESS_TYPE_LOGIN,
--- a/src/master/login-process.h Tue May 25 01:13:55 2004 +0300 +++ b/src/master/login-process.h Tue May 25 01:33:50 2004 +0300 @@ -4,7 +4,7 @@ struct login_group { struct login_group *next; - int process_type; + enum process_type process_type; struct settings *set; unsigned int processes;
--- a/src/master/mail-process.c Tue May 25 01:13:55 2004 +0300 +++ b/src/master/mail-process.c Tue May 25 01:33:50 2004 +0300 @@ -74,8 +74,35 @@ return FALSE; } -static const char *expand_mail_env(const char *env, const char *user, - const char *home) +static const struct var_expand_table * +get_var_expand_table(const char *user, const char *home, + enum process_type process_type) +{ + static struct var_expand_table static_tab[] = { + { 'u', NULL }, + { 'n', NULL }, + { 'd', NULL }, + { 'p', NULL }, + { 'h', NULL }, + { '\0', NULL } + }; + struct var_expand_table *tab; + + tab = t_malloc(sizeof(static_tab)); + memcpy(tab, static_tab, sizeof(static_tab)); + + tab[0].value = user; + tab[1].value = t_strcut(user, '@'); + tab[2].value = strchr(user, '@'); + if (tab[2].value != NULL) tab[2].value++; + tab[3].value = str_ucase(t_strdup_noconst(process_names[process_type])); + tab[4].value = home; + + return tab; +} + +static const char * +expand_mail_env(const char *env, const struct var_expand_table *table) { string_t *str; const char *p; @@ -95,18 +122,17 @@ if (env[0] == '~' && env[1] == '/') { /* expand home */ - str_append(str, home); - env++; + env = t_strconcat("%h", env+1, NULL); } /* expand %vars */ - var_expand(str, env, user, home); + var_expand(str, env, table); return str_c(str); } -static void env_put_namespace(struct namespace_settings *ns, - const char *default_location, - const char *user, const char *home) +static void +env_put_namespace(struct namespace_settings *ns, const char *default_location, + const struct var_expand_table *table) { const char *location; unsigned int i; @@ -120,7 +146,7 @@ location = ns->location != NULL ? ns->location : default_location; - location = expand_mail_env(location, user, home); + location = expand_mail_env(location, table); env_put(t_strdup_printf("NAMESPACE_%u=%s", i, location)); if (ns->separator != NULL) { @@ -135,7 +161,7 @@ /* expand variables, eg. ~%u/ can be useful */ str = t_str_new(256); str_printfa(str, "NAMESPACE_%u_PREFIX=", i); - var_expand(str, ns->prefix, user, home); + var_expand(str, ns->prefix, table); env_put(str_c(str)); } if (ns->inbox) @@ -151,6 +177,7 @@ struct auth_master_reply *reply, const char *data) { struct settings *set = group->set; + const struct var_expand_table *var_expand_table; const char *argv[4]; const char *addr, *mail, *user, *chroot_dir, *home_dir, *full_home_dir; const char *executable, *p, *prefix; @@ -317,12 +344,16 @@ mechanism might allow leaving extra data there. */ mail = data + reply->mail_idx; user = data + reply->virtual_user_idx; + + var_expand_table = + get_var_expand_table(user, home_dir, group->process_type); + if (*mail == '\0' && set->default_mail_env != NULL) - mail = expand_mail_env(set->default_mail_env, user, home_dir); + mail = expand_mail_env(set->default_mail_env, var_expand_table); if (set->server->namespaces != NULL) { env_put_namespace(set->server->namespaces, - mail, user, home_dir); + mail, var_expand_table); } env_put(t_strconcat("MAIL=", mail, NULL));