[Dovecot] IP based virtual users: stripping login domain?
Hello.
I have a likely unusual request regarding IP based virtual dovecot users.
When you specify a passdb passwd-file name containing "%d", then the domain portion is stripped from the login username, before the user is checked in the passwd-file. However, if you specify a passwd-file name containing "%l" (the local IP), the domain portion of the login is not stripped off before the username is checked in the passwd-file.
This behavior makes sense, and should be considered the right and proper thing to do. But in this case, I want to do something different anyway.
In the setup I'm working on, most logins will use domain based virtual usernames. However, if a customer logs in with an unknown domain in their login username, I'd like to fall back to IP-based virtualization, based on the local IP they connect to.
I can't use auth_username_format to strip off %d, because that would break the domain based virtualization. What I need is an option to make %l work the way %d already works; or a format inside a passwd-file which allows for partial matches in the "username" column.
If I can do this directly using a passwd-file, I'd like to do that. It seems like it'd be easy if I were using an SQL back end, but that's not an option. It's possible with an external authentication script, but I want to explore more direct configuration options, first.
Does anyone have any recommendations? If what I want can't already be done, and I patched dovecot to do one of these things, how likely would it be to have that patch merged into the project?
Thanks, Alan Ferrency pair Networks, Inc. alan@pair.com
On Fri, 14 Sep 2007, Alan Ferrency wrote:
I have a likely unusual request regarding IP based virtual dovecot users.
When you specify a passdb passwd-file name containing "%d", then the domain portion is stripped from the login username, before the user is checked in the passwd-file. However, if you specify a passwd-file name containing "%l" (the local IP), the domain portion of the login is not stripped off before the username is checked in the passwd-file. <snip> Does anyone have any recommendations? If what I want can't already be done, and I patched dovecot to do one of these things, how likely would it be to have that patch merged into the project?
Here is a small patch which causes "%0.l" in a passdb-file filename to cause the username to have its domain stripped off. The patch was built against dovecot 1.0.5, but looking at the 1.1-alpha code, it should be directly applicable there as well. --- db-passwd-file.c 16 Mar 2007 16:23:05 -0000 1.1.1.1 +++ db-passwd-file.c 14 Sep 2007 17:20:14 -0000 @@ -288,9 +288,12 @@ for (p = path; *p != '\0'; p++) { if (*p == '%' && p[1] != '\0') { p++; - if (*p == 'd') { - /* drop domains out only if %d is given - without modifiers */ + if (*p == 'd' || + (p[0] == '0' && + p[1] == '.' && + p[2] == 'l')) { + /* drop domains out if %d is given + without modifiers, or if %0.l is specified. */ db->domain_var = TRUE; } This works, but it feels exceedingly hackish and annoying. It begs for a more general purpose solution. I think both the %d and %l cases would be handled better with an additional configuration option in the passwd-file configuration, which allows you to configure auth_username_format on a per-passwd-file basis. An example configuration would look like this: passdb passwd-file { args = /path/%l.passwd username_format = %n } This configuration would cause db_passwd_file_lookup to look up "%n" in the password file, instead of looking up %u. The current use of %d and %0.d in passwd-file names could also be handled this way: passdb passwd-file { args = /path/%d.passwd username_format = %u # instead of using %0.d.passwd } passdb passwd-file { args = /path/%d.passwd username_format = %n # the old default probably shouldn't change } This configuration also allows other interesting uses which aren't currently possible, by allowing the domain to be removed from the username at lookup time, while still making it available for variable substitution within the passdb-file itself. # IP-based virtual users, all in one file passdb passwd-file { args = /path/ip_based.passwd username_format = %n@%l } # and domain-based virtual users in a separate file passdb passwd-file { args = /path/domain_based.passwd username_format = %u } Is this interesting enough to consider adding to dovecot? Thanks, Alan Ferrency pair Networks, Inc. alan@pair.com
On Fri, 2007-09-14 at 13:33 -0400, Alan Ferrency wrote:
An example configuration would look like this:
passdb passwd-file { args = /path/%l.passwd username_format = %n }
That would be nice configuration, but currently it's too difficult to add more settings inside passdb blocks.
I implemented this to v1.1:
passdb passwd-file { args = username_format=%n /etc/imap.passwd } userdb passwd-file { args = username_format=%n /etc/imap.passwd }
I implemented this to v1.1:
<snip>
Great, thanks!
Yes, my initial digging did lead me to conclude it would be a pain to add new settings into the passdb block. But the format you provided is equivalent, which works fine for me.
Curiously, what happens when you specify this:
auth_username_format=%n passdb passwd-file { args = username_format=%u /etc/imap.passwd }
In my attempt to implement something like this, I didn't find any straightforward way to have "username_format=%u" use the original username, only the auth_username_format.
Also: passdb passwd-file { args = username_format=%u /etc/imap.passwd.%d }
Does this provide the full username, or does the %d still truncate at the '@'?
Although I'm curious how you implemented these points, it's easy to do the right thing in both cases once you know how it works, so it's not a big problem either way.
Thanks.
Alan Ferrency pair Networks, Inc. alan@pair.com
On Sat, 15 Sep 2007, Timo Sirainen wrote:
On Fri, 2007-09-14 at 13:33 -0400, Alan Ferrency wrote:
An example configuration would look like this:
passdb passwd-file { args = /path/%l.passwd username_format = %n }
That would be nice configuration, but currently it's too difficult to add more settings inside passdb blocks.
I implemented this to v1.1:
passdb passwd-file { args = username_format=%n /etc/imap.passwd } userdb passwd-file { args = username_format=%n /etc/imap.passwd }
On 17.9.2007, at 18.59, Alan Ferrency wrote:
Curiously, what happens when you specify this:
auth_username_format=%n passdb passwd-file { args = username_format=%u /etc/imap.passwd }
In my attempt to implement something like this, I didn't find any straightforward way to have "username_format=%u" use the original username, only the auth_username_format.
auth_username_format changes the username permanently and the
original username isn't found from anywhere anymore.
Also: passdb passwd-file { args = username_format=%u /etc/imap.passwd.%d }
Does this provide the full username, or does the %d still truncate at the '@'?
I removed the special casing of %d from v1.1. The default is to
always lookup using %u format. So the original behavior of "args = /
etc/imap.%d" must now be done as "args = username_format=%n /etc/imap.
%d". I thought about leaving it, but it was kind of ugly hack and I
wasn't sure if it would break something if I left it.
Curiously, what happens when you specify this:
auth_username_format=%n passdb passwd-file { args = username_format=%u /etc/imap.passwd }
In my attempt to implement something like this, I didn't find any straightforward way to have "username_format=%u" use the original username, only the auth_username_format.
auth_username_format changes the username permanently and the original username isn't found from anywhere anymore.
Okay, that's what I thought.
I removed the special casing of %d from v1.1.
I think this is the best long-term move. I would've been concerned about making the 1.0 -> 1.1 migration path more difficult. But since I haven't gone to dovecot at all yet, it sounds like a good idea to me :)
Thanks again, Alan Ferrency pair Networks, Inc. alan@pair.com
participants (2)
-
Alan Ferrency
-
Timo Sirainen