[Dovecot] v2.0 configuration parsing
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
Any thoughts?
Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
Any thoughts?
I think the easiest scheme to keep in my brain would be to evaluate the blocks, in order, as if they were branches in code. Fooling around with an arbitrary order of evaluation/specificity would be a recipe for disaster (see, for example, any CSS engine).
So, something like,
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } }
would translate to,
if (protocol == imap) { if (remote_ip matches 192.168.0.0/16) { foo = foo } }
and then later,
remote_ip 192.168.0.0/24 { foo = bar }
would set the value of 'foo' to 'bar', since it would evaluate in a similar fashion, and comes later in the config file.
It's easy to explain, easy to implement, and easy to debug. Ultimately, the users are going to have to understand how it works in order to configure Dovecot properly. "Put the most general rules first, and then override them" is a practice with which most of us are already familiar.
On 8/10/2009, Michael Orlitzky (michael@orlitzky.com) wrote:
It's easy to explain, easy to implement, and easy to debug. Ultimately, the users are going to have to understand how it works in order to configure Dovecot properly. "Put the most general rules first, and then override them" is a practice with which most of us are already familiar.
One thing I'd like is to sort the simple one line foo = bar settings first (before the blocks) - in alphabetcial order. If it makes more sense to keep the blocks in a specific order, thats fine, otherwise you could alphabetize them too.
Right now, if you have a lot of settings, finding any particular setting (ie, when troubleshooting) is much more difficult than it should be, especially for someone new to dovecot.
--
Best regards,
Charles
On 8/10/2009, Charles Marcus (CMarcus@Media-Brokers.com) wrote:
One thing I'd like is to sort the simple one line foo = bar settings first (before the blocks) - in alphabetcial order.
Of course, I meant with respect to doveconf -n output... or did you decide yet on the new command(s)?
--
Best regards,
Charles
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
I completely agree with Michael's opinion.
Patrick.
On 2009-08-11 02:22, Michael Orlitzky wrote:
Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.: [...]
I think the easiest scheme to keep in my brain would be to evaluate the blocks, in order, as if they were branches in code. Fooling around with an arbitrary order of evaluation/specificity would be a recipe for disaster (see, for example, any CSS engine).
So, something like,
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } }
would translate to,
if (protocol == imap) { if (remote_ip matches 192.168.0.0/16) { foo = foo } }
and then later,
remote_ip 192.168.0.0/24 { foo = bar }
would set the value of 'foo' to 'bar', since it would evaluate in a similar fashion, and comes later in the config file.
It's easy to explain, easy to implement, and easy to debug. Ultimately, the users are going to have to understand how it works in order to configure Dovecot properly. "Put the most general rules first, and then override them" is a practice with which most of us are already familiar.
STAR Software (Shanghai) Co., Ltd. http://www.star-group.net/ Phone: +86 (21) 3462 7688 x 826 Fax: +86 (21) 3462 7779
PGP key: E883A005 https://stshacom1.star-china.net/keys/patrick_nagel.asc Fingerprint: E09A D65E 855F B334 E5C3 5386 EF23 20FC E883 A005 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAkqA5IEACgkQ7yMg/OiDoAWaiQCgk1S6lu6JQTcg5VXzwzJxrjCG AXcAoLD2xvbfFoMUrSW+3JrC+PA7c8Fz =jChR -----END PGP SIGNATURE-----
Hi Timo,
What's your thought on the 'precedence order' (hope it make sense),
on protocol, remote_ip, local_ip?
From your sample 1, it would read equals (to most technical people) to protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } protocol ALL { remote_ip 192.168.0.0/24 { foo = bar } }
If follow this syntax, sample 1's answer would be foo = foo, assuming
specific rules overwrite general rules, and assuming protocol is the
first order.
Sample 2 is tough, that's why I asked what's your thought on
precedence order. Restricting syntax to only remote before local (or
vice versa) should resolve it.
Joseph
On 10-Aug-09, at 1:57 PM, Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always
just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense
initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
Any thoughts?
On Mon, 2009-08-10 at 14:33 -0400, Joseph Yee wrote:
Hi Timo,
What's your thought on the 'precedence order' (hope it make sense),
on protocol, remote_ip, local_ip?
I'm not sure if there is one.
Sample 2 is tough, that's why I asked what's your thought on
precedence order. Restricting syntax to only remote before local (or
vice versa) should resolve it.
Actually I don't think it would really solve much either.
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
You could write this as:
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } local_ip 192.168.0.0/24 { remote_ip 10.1.2.3 { foo = bar } }
You'd still have to decide if local_ip is more important than remote_ip, or if it should just be done in order and it should always use either "first" or "last".
On Aug 10, 2009, at 11:57 AM, Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always
just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense
initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
Any thoughts?
Figure out that they intersect and return an error!
Aria Stewart aredridel@nbtsc.org
Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
make it protocols { imap { remote_ip x/16 { foo = foo } } all { remote_ip x/24 { foo = bar } } }
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
I'd strongly suggest to use the same approach as firewalls (or exim): first match wins. I love exim because I can configure it much like my firewalls & routers, and the "fall through until something matches" syntax that most firewalls/ACLs use is well-understood & flexible.
Kind regards,
Felix
-- Felix Schüren Head of Network
Host Europe GmbH - http://www.hosteurope.de Welserstraße 14 - 51149 Köln - Germany Telefon: 0800 467 8387 - Fax: +49 180 5 66 3233 (*) HRB 28495 Amtsgericht Köln - USt-IdNr.: DE187370678 Geschäftsführer: Uwe Braun - Alex Collins - Mark Joseph - Patrick Pulvermüller
(*) 0,14 EUR/Min. aus dem dt. Festnetz, Mobilfunkpreise ggf. abweichend
Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule". The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
make it protocols { imap { remote_ip x/16 { foo = foo } } all { remote_ip x/24 { foo = bar } } }
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
I'd strongly suggest to use the same approach as firewalls (or exim): first match wins. I love exim because I can configure it much like my firewalls & routers, and the "fall through until something matches" syntax that most firewalls/ACLs use is well-understood & flexible.
Kind regards,
Felix
-- Felix Schüren Head of Network
Host Europe GmbH - http://www.hosteurope.de Welserstraße 14 - 51149 Köln - Germany Telefon: 0800 467 8387 - Fax: +49 180 5 66 3233 (*) HRB 28495 Amtsgericht Köln - USt-IdNr.: DE187370678 Geschäftsführer: Uwe Braun - Alex Collins - Mark Joseph - Patrick Pulvermüller
(*) 0,14 EUR/Min. aus dem dt. Festnetz, Mobilfunkpreise ggf. abweichend
On Mon, 2009-08-10 at 20:47 +0200, Felix Schueren wrote:
make it protocols { imap { remote_ip x/16 { foo = foo } } all { remote_ip x/24 { foo = bar } } }
That's just a syntax change. The question is still about if it should match the first one or the most specific one.
I'd strongly suggest to use the same approach as firewalls (or exim): first match wins. I love exim because I can configure it much like my firewalls & routers, and the "fall through until something matches" syntax that most firewalls/ACLs use is well-understood & flexible.
Yeah, I'm beginning to think something like this would be good, with perhaps some restrictions in how the configuration blocks could be used. But is it better to use the first or the last match?..
Timo Sirainen wrote:
On Mon, 2009-08-10 at 20:47 +0200, Felix Schueren wrote:
make it protocols { imap { remote_ip x/16 { foo = foo } } all { remote_ip x/24 { foo = bar } } }
That's just a syntax change. The question is still about if it should match the first one or the most specific one.
I'd strongly suggest to use the same approach as firewalls (or exim): first match wins. I love exim because I can configure it much like my firewalls & routers, and the "fall through until something matches" syntax that most firewalls/ACLs use is well-understood & flexible.
Yeah, I'm beginning to think something like this would be good, with perhaps some restrictions in how the configuration blocks could be used. But is it better to use the first or the last match?..
If at all possible, I would much rather see an error thrown than choosing which one to accept. To me, having Dovecot tolerate broken configurations is less desirable than giving clear feedback for the user to fix it. Anything from:
"foo" is defined more than once overlapping ip declarations "remote_ip" declaration in protocol "imap" conflicts with "remote_ip" declaration in protocol "all"
I suppose if you really want to tolerate the brokenness - at least include the error as a logged warning.
Daniel
On Mon, 2009-08-10 at 12:09 -0700, Daniel L. Miller wrote:
If at all possible, I would much rather see an error thrown than choosing which one to accept. To me, having Dovecot tolerate broken configurations is less desirable than giving clear feedback for the user to fix it. Anything from:
"foo" is defined more than once overlapping ip declarations "remote_ip" declaration in protocol "imap" conflicts with "remote_ip" declaration in protocol "all"
It's not necessarily a broken configuration. For example you could have:
disable_plaintext_auth = yes # default also remote_ip 192.168.0.0/16 { # allow plaintext auth from intranet disable_plaintext_auth = no }
That's an ok configuration, right? But then again, maybe one of those IPs is a proxy to outside world and you don't want plaintext auth from there:
remote_ip 192.168.123.44 { disable_plaintext_auth = yes }
But I guess if there truly are some conflicts it could warn about them .. although that might be more work than it's worth. :)
Timo Sirainen wrote:
On Mon, 2009-08-10 at 12:09 -0700, Daniel L. Miller wrote:
If at all possible, I would much rather see an error thrown than choosing which one to accept. To me, having Dovecot tolerate broken configurations is less desirable than giving clear feedback for the user to fix it. Anything from:
"foo" is defined more than once overlapping ip declarations "remote_ip" declaration in protocol "imap" conflicts with "remote_ip" declaration in protocol "all"
It's not necessarily a broken configuration. For example you could have:
disable_plaintext_auth = yes # default also remote_ip 192.168.0.0/16 { # allow plaintext auth from intranet disable_plaintext_auth = no }
That's an ok configuration, right? But then again, maybe one of those IPs is a proxy to outside world and you don't want plaintext auth from there:
remote_ip 192.168.123.44 { disable_plaintext_auth = yes }
But I guess if there truly are some conflicts it could warn about them .. although that might be more work than it's worth. :)
Well - if those are not broken configs, then I guess I misunderstood the question. I would expect the most restrictive test to govern, so:
remote_ip 192.168.0.0/16 { # allow plaintext auth from intranet disable_plaintext_auth = no }
remote_ip 192.168.10.0/8 { # allow plaintext auth from intranet disable_plaintext_auth = yes }
remote_ip 192.168.0.1 { # allow plaintext auth from intranet disable_plaintext_auth = no }
connecting from 192.168.0.1 should result in disable_plaintext_auth = no.
-- Daniel-5276
Daniel L. Miller wrote:
Timo Sirainen wrote:
On Mon, 2009-08-10 at 12:09 -0700, Daniel L. Miller wrote:
If at all possible, I would much rather see an error thrown than choosing which one to accept. To me, having Dovecot tolerate broken configurations is less desirable than giving clear feedback for the user to fix it. Anything from:
"foo" is defined more than once overlapping ip declarations "remote_ip" declaration in protocol "imap" conflicts with "remote_ip" declaration in protocol "all"
It's not necessarily a broken configuration. For example you could have:
disable_plaintext_auth = yes # default also remote_ip 192.168.0.0/16 { # allow plaintext auth from intranet disable_plaintext_auth = no }
That's an ok configuration, right? But then again, maybe one of those IPs is a proxy to outside world and you don't want plaintext auth from there:
remote_ip 192.168.123.44 { disable_plaintext_auth = yes }
But I guess if there truly are some conflicts it could warn about them .. although that might be more work than it's worth. :)
Well - if those are not broken configs, then I guess I misunderstood the question. I would expect the most restrictive test to govern, so:
remote_ip 192.168.0.0/16 { # allow plaintext auth from intranet disable_plaintext_auth = no }
remote_ip 192.168.10.0/8 { # allow plaintext auth from intranet disable_plaintext_auth = yes }
remote_ip 192.168.0.1 { # allow plaintext auth from intranet disable_plaintext_auth = no }
connecting from 192.168.0.1 should result in disable_plaintext_auth = no.
I agree - however, it makes the config harder to read, and you pretty much need something like "dovecotctl -acl -dump" or an equivalent to netstat -r or iptables -L to display them in the correct order if the ruleset becomes complex. By using a first-match wins syntax, you make the actual config file much simpler to read, as it maps to the running process.
kind regards,
Felix
-- Felix Schüren Head of Network
Host Europe GmbH - http://www.hosteurope.de Welserstraße 14 - 51149 Köln - Germany Telefon: 0800 467 8387 - Fax: +49 180 5 66 3233 (*) HRB 28495 Amtsgericht Köln - USt-IdNr.: DE187370678 Geschäftsführer: Uwe Braun - Alex Collins - Mark Joseph - Patrick Pulvermüller
(*) 0,14 EUR/Min. aus dem dt. Festnetz, Mobilfunkpreise ggf. abweichend
On 8/10/2009, Timo Sirainen (tss@iki.fi) wrote:
Yeah, I'm beginning to think something like this would be good, with perhaps some restrictions in how the configuration blocks could be used. But is it better to use the first or the last match?
For a filter (like a firewall), it makes sense to have the first match win.
For config stuff, I think the LAST should win... at least, thats how postfix works...
Or maybe even better, if you have the same setting defined twice, you could also detect this and issue a warning, like you do now for fd's set too low...
--
Best regards,
Charles
On Mon, 2009-08-10 at 13:57 -0400, Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule".
I think it's possible to do both:
Use the most specific rule, but if it's also not the first rule, it's a broken configuration and it'll fail. If there are ambiguity in specificity, it's also an error.
(I'm also wondering about if it should be the first rule. Somehow to me it comes more naturally that last settings always override previous settings. If we really want to make first settings come first, then the default settings must be at the bottom of dovecot.conf, or they'd need some exception.)
Require the nesting to be in order:
local_ip { remote_ip { protocol {} } }
Any of the levels could be dropped out, but the ordering couldn't be switched. Then we'll basically require that more specific blocks need to be before less specific blocks, or the configuration reading will fail. (Or vice versa? It somehow seems more natural to me..) The block specificity is determined by the nesting order.
- Simple example:
allow plaintext auth from intranet, except from .123.1
remote_ip 192.168.123.1 { disable_plaintext_auth = yes } remote_ip 192.168.0.0/16 { disable_plaintext_auth = no } disable_plaintext_auth = yes
If the remote_ip blocks were switched, it would give an error.
- More complex example:
Client connecting 192.168.0.1 -> 10.1.2.3.
# this first match is used local_ip 192.168.0.1/31 { remote_ip 10.1.2.0/24 { foo = foo } } # ok, exact match (handle the same as duplicate settings in root, # maybe optionally give a warning about them) local_ip 192.168.0.1/31 { remote_ip 10.1.2.0/24 { foo = foo2 } } # error, local_ip more specific local_ip 192.168.0.1 { foo = xx } # ok, local_ip less specific, remote_ip less specific local_ip 192.168.0.0/16 { remote_ip 10.1.2.0/23 { foo = bar } } # error, remote_ip more or equal specific local_ip 192.168.0.0/16 { remote_ip 10.1.2.3 { foo = baz1 } remote_ip 10.1.2.0/24 { foo = baz2 } } # error, protocol more specific local_ip 192.168.0.0/16 { protocol imap { foo = x } }
On Mon, 2009-08-10 at 17:59 -0400, Timo Sirainen wrote:
(I'm also wondering about if it should be the first rule. Somehow to me
I think first rule match is best approach, as someone else pointed out, its how many things that most people here would work with daily work, be it a server daemon configuration, iptables, or Cisco routers. The only exceptions that I can think of immediately is Apache, ircu, and DNews where last (entered in order) matching rule wins.
Noel
On Tue, 2009-08-11 at 09:20 +1000, Noel Butler wrote:
On Mon, 2009-08-10 at 17:59 -0400, Timo Sirainen wrote:
(I'm also wondering about if it should be the first rule. Somehow to me
I think first rule match is best approach, as someone else pointed out, its how many things that most people here would work with daily work, be it a server daemon configuration, iptables, or Cisco routers.
Can you give me some other examples than firewalls or routing?
On Mon, 2009-08-10 at 19:28 -0400, Timo Sirainen wrote:
On Tue, 2009-08-11 at 09:20 +1000, Noel Butler wrote:
On Mon, 2009-08-10 at 17:59 -0400, Timo Sirainen wrote:
(I'm also wondering about if it should be the first rule. Somehow to me
I think first rule match is best approach, as someone else pointed out, its how many things that most people here would work with daily work, be it a server daemon configuration, iptables, or Cisco routers.
Can you give me some other examples than firewalls or routing?
Postfix, (and as mentioned by another poster Exim never used it myself tho), and I think Sendmail as well, MailScanner, and I was wrong about Apache, first vhost matches (I just threw an alias into a 3 vhosts and it went to the first matching vhost)
Noel
On 8/11/2009, Charles Marcus (CMarcus@Media-Brokers.com) wrote:
Eh?? Not on my box. If I add a duplicate setting at the bottom, that setting overrides any previous setting.
In fact, this is one of the reasons postconf -n output is necessary when asking for help on the list... more than once I have seen someone come back and say 'oh, yeah, I forgot I'd set that at the bottom when I wast testing blah blah'.
--
Best regards,
Charles
On 8/10/2009, Noel Butler (noel.butler@ausics.net) wrote:
I think first rule match is best approach, as someone else pointed out, its how many things that most people here would work with daily work, be it a server daemon configuration, iptables, or Cisco routers. The only exceptions that I can think of immediately is Apache, ircu, and DNews where last (entered in order) matching rule wins.
Don't forget postfix - its 'last rule wins' too, and is why I vote for last rule wins for dovecot, or, worst case, if there is more than one give an error, or at least a warning.
--
Best regards,
Charles
On 8/10/2009, Timo Sirainen (tss@iki.fi) wrote:
(I'm also wondering about if it should be the first rule. Somehow to me it comes more naturally that last settings always override previous settings.
For config files, I agree.
If we really want to make first settings come first, then the default settings must be at the bottom of dovecot.conf, or they'd need some exception.)
Or just have the default settings there as an example, but commented out. Have an explanation at the top of the config file that if you only need the default settings, they do not need to be uncommented, and that the last setting wins (or will cause a warning or error, or whatever you decide).
I like that I can use postconf -d (show default settings - and this is why I'd like to have a doveconf -d, as well as doveconf -n), to see if I have specifically set any defaults, and if I did, delete/comment them. This limits the settings returned by postconf -n, which makes it easier to read. I'd like dovecot to have the same capability.
When I did this, I cut the ouput down from 80 lines to less than 40.
--
Best regards,
Charles
On Tue, 2009-08-11 at 07:16 -0400, Charles Marcus wrote:
I like that I can use postconf -d (show default settings - and this is why I'd like to have a doveconf -d, as well as doveconf -n), to see if I have specifically set any defaults, and if I did, delete/comment them. This limits the settings returned by postconf -n, which makes it easier to read. I'd like dovecot to have the same capability.
The difference between dovecot -n and postconf -n is that dovecot -n doesn't show settings that have been explicitly set to defaults.
On 8/13/2009, Timo Sirainen (tss@iki.fi) wrote:
The difference between dovecot -n and postconf -n is that dovecot -n doesn't show settings that have been explicitly set to defaults.
Ahhh, I hadn't noticed that...
So, should it? To me, it kind of makes sense for defaults to be displayed commented in the config file right after the explanatory text the default setting or not...
- for documentation purposes, ie to show what the default setting is, and to serve as an example of proper syntax - and then anything that is explicitly set should show in -n output, whether it is explicitly set to
But its no big deal, that just how things would be if I were king... ;)
--
Best regards,
Charles
On Fri, 2009-08-14 at 06:05 -0400, Charles Marcus wrote:
On 8/13/2009, Timo Sirainen (tss@iki.fi) wrote:
The difference between dovecot -n and postconf -n is that dovecot -n doesn't show settings that have been explicitly set to defaults.
Ahhh, I hadn't noticed that...
So, should it?
doveconf -N now does that, while doveconf -n works like before.
On 9/3/2009 4:43 PM, Timo Sirainen wrote:
The difference between dovecot -n and postconf -n is that dovecot -n doesn't show settings that have been explicitly set to defaults.
doveconf -N now does that, while doveconf -n works like before.
wow - Timo, you are amazing, no doubt about it.
Thanks... :)
--
Best regards,
Charles
On Monday 10 August 2009 19:57:53 Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule".
I generally prefer the "most specific rule wins". If that is not the case, it should not be possible to specify the same configuration within containers of different scope. It is not intuitive to have a value in a restricted scope and in a more general scope, and there are situations when the general value is used even though the specifiv scope
The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
This one is easy. It should be foo in any case :-)
Protocol sections that are more specific are an existing and coarse-granular concept, and AFAIk now it doesn't matter whether the protocol section is before or after the general setting. This concept should in any case be retained.
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
Any thoughts?
Perhaps this should be invalid.
Rainer
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
This one is easy. It should be foo in any case :-)
Why? /24 is more specific than /16, but protocol imap is more specific than (implicit) protocol any. I assume this is why Timo included this example.
Gr.
Matthijs
On Tuesday 11 August 2009 15:32:42 Matthijs Kooijman wrote:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
This one is easy. It should be foo in any case :-)
Why? /24 is more specific than /16, but protocol imap is more specific than (implicit) protocol any. I assume this is why Timo included this example.
You are right, and I left out half of my thoughts. I think there should be only a coarse grained concept of "more specific rules" - e.g. a protocol section is more specific than general config, and a local or remote IP restriction is more specific than a protocol section. I think that the values of these context selectors should not define "more specific". Within one of these levels, either conflicting settings should be invalid, or maybe better yet, a "last wins" rule should apply.
Gr.
Matthijs
Rainer
You are right, and I left out half of my thoughts. I think there should be only a coarse grained concept of "more specific rules" - e.g. a protocol section is more specific than general config, and a local or remote IP restriction is more specific than a protocol section. I think that the values of these context selectors should not define "more specific". Within one of these levels, either conflicting settings should be invalid, But that would prevent the following (intuitive) config from working:
remote_ip 192.168.0.0/16 { foo = bar }
remote_ip 192.168.10.0/24 { foo = baz }
This would need some kind of condition like
remote_ip 192.168.0.0/16 && !192.168.10.0/24 {..}
or something.
or maybe better yet, a "last wins" rule should apply. Or you would indeed use this, which makes the above config easy to write wrongly. (If you swap the conditions). You might still detect that a later directive completely overrides a previous setting in all cases and issue a warning, but this is probably hard to do in general.
An alternative that just occured to me is to always do these kind of "exceptions" in a nested way. The above would then become:
remote_ip 192.168.0.0/16 { foo = bar
remote_ip 192.168.10.0/24 {
foo = baz
}
}
which is probably even more intuitive than my first example. This way, the user explicitly specifies which directives can override other directives. This is comparable to having a fixed order of "protocol", "remote_ip", "local_ip" that was proposed somewhere in this thread, but allows the user to pick the order.
This does mean that you might need explicit "else", or "other" clauses, since you cannot mix different selectors on the same level of the hierarchy.
protocol imap { remote_ip 192.168.0.0/24 { foo = bar } } protocol other remote_ip = 192.168.10.0/16 { foo = baz } }
A big downside of this approach is probably that you can't easily add a rule for some remote_ip condition regardless of the protocol to the last example, since that should then be specified in both protocol blocks... So, not sure if this is really a useful suggestion, but perhaps thinking about it will help :-)
Gr.
Matthijs
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Mon, 10 Aug 2009, Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing
IMO, "most specific" won't work as you pointed out several times, because Dovecot cannot know, which precendence the zillion configuration options and conditionals have in the particular setup.
In my view, "first match" is good, if one needs quick processing time and can cut, once the match is found. E.g. in firewalls and routers. Or when the options are not _conditionally_ assigned, e.g. in sendmail cf, you do not have no way to have a config option _not_ apply.
Most conf files/system I know, that split between common (or default) setting and specific overrides work in last match. They bundle the default settings on top and specify the overrides below, just like a program, as already pointed out. Moreover, because most programs parse the config file til its end anyway. It is more work to debug problems, but in my eyes the conf files look cleaner.
There are a few, where you can "fix" a setting, so it cannot be overwritten later, but mostly because first the system conf file is parsed and should be able to fix some settings against user override.
Maybe a dovecot debug mode can issue the line number when a setting is assigned.
Bye,
Steffen Kaiser -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux)
iQEVAwUBSoGFynWSIuGy1ktrAQJY3Qf/Tv96bzBg4yd4fOuY/rplpf7ap3DJv//K geDA8WWHuzU4J505DmBi0AxvmfZ6ZHFnII0xGnatK9qxaaWDTceqdRJlZWdf25XL Hf52ff4xVOgQXpoqvh0zT8VxM4q9Qe7mH2g4VTz0eKbvVP0qFaHBAv66qa1czgGP 9Xj27YrmE3FKiurCkVCwVzGFQM4akTs+qD3VvBy3sTyoLB3XenzS6e4EXjsbQAQe McaUUL/nJKtKwXyN7aH3lKZaFe3ECsb1SZWtTxQ4GAEuwPeawWIrK3r1S1ykfYUV ZQERdMVWgc1FsG5IdTTYcq5DgHSWEotRcN92Aw7v9i20yaTw1wKSEg== =b+sT -----END PGP SIGNATURE-----
I would suppose that partly overlapping rules are most often a sign of a configuration error. So how about
- most specific rule wins (or last rule wins, forcing more specific rules to appear further down the file)
- partly overlapping flag an error, except for
- using != (or whatever) instead of = surpresses the error and makes the last rule win.
On Mon, 2009-08-10 at 13:57 -0400, Timo Sirainen wrote:
I'm trying to figure out how exactly v2.0 should be parsing configuration files. The most annoying part is if it should always just "use whatever comes first in config" or try some kind of a "use most specific rule".
I've now implemented the "use most specific rule".
The "most specific" kind of makes more sense initially, but then you start wondering how to handle e.g.:
- User logs in to imap from 192.168.0.1. What is foo's value?
protocol imap { remote_ip 192.168.0.0/16 { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
Error in configuration file /usr/local/etc/dovecot/dovecot.conf line 2: remote_ip must not be under protocol
Switching around protocol and remote_ip makes it work, I think it's pretty clear then what should happen (foo=bar always with 192.168.0.*):
remote_ip 192.168.0.0/16 { protocol imap { foo = foo } } remote_ip 192.168.0.0/24 { foo = bar }
- User logs in from 192.168.0.1 to 10.1.2.3. What is foo's value?
local_ip 192.168.0.1 { remote_ip 10.1.2.0/24 { foo = foo } } remote_ip 10.1.2.3 { local_ip 192.168.0.0/24 { foo = bar } }
Error in configuration file /usr/local/etc/dovecot/dovecot.conf line 7: local_ip must not be under remote_ip
Then if you switch around the remote_ip and local_ip it'll start up normally. But when you log in from 192.168.0.1 -> 10.1.2.3 it'll log an error and fail:
Conflict in setting foo found from filter at /usr/local/etc/dovecot/dovecot.conf:7
So this is a runtime error. It would be possible to test out all the different combinations at startup, but with complex configs that might start taking forever..
Currently it doesn't tell where the other side of the conflict came from. It probably wouldn't be too difficult to add, but I think I'll just leave it for future until it actually becomes a problem for someone. :)
It's also possible to test these per-IP configurations with doveconf:
./doveconf -n -f lip=192.168.0.1 -f rip=10.1.2.3 -f service=imap
participants (14)
-
Aria Stewart
-
Charles Marcus
-
Daniel L. Miller
-
Edgar Fuß
-
Felix Schueren
-
Joseph Yee
-
Matthijs Kooijman
-
Michael Orlitzky
-
Noel Butler
-
Patrick Nagel
-
Rainer Frey
-
Rainer Frey (Inxmail GmbH)
-
Steffen Kaiser
-
Timo Sirainen