I have recently begun playing with Dovecot (1.0.beta8) and have run into an interesting scenario. The way my email system is set up is that users of different domains have completely different base dn's. For instance, if a user is part of test.com the bind dn would be uid=user,ou=People,dc=test,dc=com. The bind dn for user@domain.com would be uid=user,ou=People,dc=domain,dc=com. I could not seem to figure out a way to have the binddn adjusted based on a user's @domain so I modified auth-request.c and var-expand.c to include a new variable expansion concept. In the configuration I'm now able to include the following: auth_bind_userdn = uid=%n,ou=People,dc=%c2,dc=%c1 and %c1 will be expanded to the tld, %c2 will be expanded to the next level domain (domain or test in the above example). This will work up to 9 levels of subdomain (1-9). This is very similar in how postfix expands variables with ldap. I'm a bit rusty with my C, so I'd love some feedback on the patch. If this idea isn't included in the main code, that's fine, but I thought I'd contribute my experiences! Thanks for a great product everyone! Andrew =================================================================== --- dovecot-1.0.beta8/src/auth/auth-request.c 2006-04-12 22:00:06.000000000 -0400 +++ dovecot-1.0.beta8.new/src/auth/auth-request.c 2006-05-15 12:37:06.000000000 -0400 @@ -852,6 +852,7 @@ auth_request_get_var_expand_table(const struct auth_request *auth_request, const char *(*escape_func)(const char *)) { + char *str; static struct var_expand_table static_tab[] = { { 'u', NULL }, { 'n', NULL }, @@ -869,7 +870,27 @@ if (escape_func == NULL) escape_func = escape_none; - tab = t_malloc(sizeof(static_tab)); + /* count the number of domain components + in the given auth_request->user string + so we can allocate the correct sized + array + */ + int dc_count = 0; + str = strchr(auth_request->user, '@'); + while (str != NULL && *str != '\0' && str++) { + if (*str == '.') + dc_count++; + if (dc_count == 9) + break; + } + + /* allocate memory big enough for the static + tab plus each domain compononet. Since we + can only use 1-9 as identifiers, there is + no point in allocating more then 9 + */ + dc_count = (dc_count < 9 ? dc_count : 9); + tab = t_malloc(sizeof(static_tab) + (dc_count*(sizeof(char) + sizeof(char *)))); memcpy(tab, static_tab, sizeof(static_tab)); tab[0].value = escape_func(auth_request->user); @@ -886,6 +907,27 @@ tab[7].value = dec2str(auth_request->client_pid); if (auth_request->mech_password != NULL) tab[8].value = escape_func(auth_request->mech_password); + + char *domain = p_strdup(auth_request->pool, strchr(auth_request->user, '@')); + if (domain != NULL) { + int count = 0; + str = domain + strlen(domain); + do { + str--; + if (*str == '.' || *str == '@') { + *str = '\0'; + count++; + tab[count + 8].key = (char)(48+count); + tab[count + 8].value = escape_func(str+1); + } + if (*str == '@') { + count++; + tab[count + 8].key = '\0'; + tab[count + 8].value = NULL; + break; + } + } while (str != domain && count < 9); + } return tab; } =================================================================== --- dovecot-1.0.beta8/src/lib/var-expand.c 2006-04-12 22:00:06.000000000 -0400 +++ dovecot-1.0.beta8.new/src/lib/var-expand.c 2006-05-12 17:06:42.000000000 -0400 @@ -162,6 +162,11 @@ break; var = NULL; + + /* domain component expansion */ + if (*str == 'c') + str++; + for (t = table; t->key != '\0'; t++) { if (t->key == *str) { var = t->value != NULL ? t->value : "";