Re: AuthzMergeRules directive
Brad Nicholes wrote: I finally got around to making the switch so that the default merge rule is AND rather than OR. However after making the switch, it occurred to me that since the default rule is AND now, the AuthzMergeRules default should remain ON. Otherwise the rule inheritance won't happen by default which would leave authentication holes in sub-directories. I think with the default being changed to AND, authz should be behaving as discussed on this thread. Thanks, much appreciated. I'll try to set up some tests and take a look as soon as I can. It's been a while since I thought about this stuff, but I think the reason I was keen to make the AuthzMergeRules default off was that it more closely emulated the pre-2.4 behaviour, so that people wouldn't be surprised to discover their 2.2 configurations weren't working as expected. Combined with a default OR rule that might have led, I thought, to unanticipated security holes -- users given access to a subdir with it's own authz config because the OR with the parent dir short- circuited the subdir's authz. Using AND as the default rule will at a minimum close off that problem. My hunch (absent any testing; sorry!) is that a default AND will mean such subdirs are sometimes just not available after an upgrade to 2.4 (assuming no authz config changes are made by someone who doesn't read the release notes) because users won't have access to both the parent dir and the subdir. In 2.2, they'd be authorized against just the subdir's config; here, they'll need to pass the parent's too. (I think.) Anyway, I'll try to work in some testing in the next week or two. Regardless, this change closes a big security problem for quick-and-dirty upgraders, I believe. Thanks again, Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
Brad Nicholes wrote: So what I am really trying to say is that intra-block logic and inter-block logic as far as merging goes, are tied together. If we want to change the way that the logic of two block is merged, we would also have to change the base state of each independent block. It's all or nothing. This would affect how the following block is evaluated: Directory /foo require user joe require user sue /Directory As it currently stands, the logic when combining these two rules would be OR. If we make the change, this would also change the same configuration to use AND instead. I think we determined that this logic would be more secure anyway even if it is different than 2.2.x. Well, I suppose the absolutely key thing is to set the default AuthzMergeRules state to Off. Next up, I guess try changing the On merge state to AND and we'll do some thinking and testing at that point. It does look to me like the pre-2.4 intra-block logic was OR, but I don't know how widely people would have depended on that (as in your example above). My gut instinct is that we'll wind up having to replicate OR within blocks, but implement AND between blocks, to achieve both backwards-compatibility and good security. As a first step, though, I'd suggest just making the two changes to the existing defaults (AuthzMergeRules Off as default, and On = AND) and we'll review again at that point. For my part I hope to deal with a parallel, unrelated, and hopefully uncontroversial set of authn/z edits once SVN returns, namely changing all the hard-coded 0 provider versions to use AUTHN/Z_PROVIDER_VERSION macros. That's a simple first step toward the work outlined in this thread: http://mail-archives.apache.org/mod_mbox/httpd-dev/200804.mbox/[EMAIL PROTECTED] Thanks again, Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
On 4/18/2008 at 8:53 AM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: Brad Nicholes wrote: I could go along with switching the default merging rule from OR to AND, even within a dir block. The reason why it is OR today was basically for backward compatibility. Since there really wasn't any kind of logic before, OR was just the default. If we switch to AND as being the default within a dir block, it may break some existing configurations. However I also think that AND is a safer merging rule going forward. If we just switch the AuthzMergeRules default state to Off, and make On mean AND, that would be a great start. Then maybe we can revisit and take a look at what breaks if the within-block merging is AND too; if it breaks too much stuff, maybe it needs to stay OR. Right now I can't say I have an informed opinion on that. Thanks again for working through this stuff, Chris. After re-examining the code, the above suggestion is much easier said than done. The reason why is because base Directory logic starts from the AUTHZ_REQSTATE_ONE (OR) state. So if you have two Directory blocks, their respective per-dir structures are storing their authz logic as it was evaluated during configuration time. Then when the two Directory blocks are merged, they are merged according to current state. In other words, the following Directory block would be merged using OR: Directory /foo require user joe /Directory Directory /foo/bar authzmergerules on require user sue /Directory The reason why is because when the Directory blocks were first evaluated independently, the starting state was AUTHZ_REQSTATE_ONE. However in the following example the two Directory block will be merge with AND: Directory /foo require user joe /Directory Directory /foo/bar authzmergerules on satisfyall require user sue /satisfyall /Directory The reason why AND is used in this situation is because the satisfyall block in the subdirectory changed its starting state from AUTHZ_REQSTATE_ONE (OR) to AUTHZ_REQSTATE_ALL (AND). There isn't any way to insert a different merging operator. It is always the sub-directory that determines how it will be merged into its parent. So what I am really trying to say is that intra-block logic and inter-block logic as far as merging goes, are tied together. If we want to change the way that the logic of two block is merged, we would also have to change the base state of each independent block. It's all or nothing. This would affect how the following block is evaluated: Directory /foo require user joe require user sue /Directory As it currently stands, the logic when combining these two rules would be OR. If we make the change, this would also change the same configuration to use AND instead. I think we determined that this logic would be more secure anyway even if it is different than 2.2.x. thoughts? Brad
Re: AuthzMergeRules directive
Brad Nicholes wrote: I could go along with switching the default merging rule from OR to AND, even within a dir block. The reason why it is OR today was basically for backward compatibility. Since there really wasn't any kind of logic before, OR was just the default. If we switch to AND as being the default within a dir block, it may break some existing configurations. However I also think that AND is a safer merging rule going forward. If we just switch the AuthzMergeRules default state to Off, and make On mean AND, that would be a great start. Then maybe we can revisit and take a look at what breaks if the within-block merging is AND too; if it breaks too much stuff, maybe it needs to stay OR. Right now I can't say I have an informed opinion on that. Thanks again for working through this stuff, Chris.
Re: AuthzMergeRules directive
On Wed, Apr 16, 2008 at 9:31 PM, Brad Nicholes [EMAIL PROTECTED] wrote: I could go along with switching the default merging rule from OR to AND, even within a dir block. The reason why it is OR today was basically for backward compatibility. Since there really wasn't any kind of logic before, OR was just the default. If we switch to AND as being the default within a dir block, it may break some existing configurations. However I also think that AND is a safer merging rule going forward. +1. AND makes more sense as the default - if they want OR, they can use a directive... -- justin
Re: AuthzMergeRules directive
On 4/14/2008 at 3:29 PM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: Brad Nicholes wrote: This is where it starts to go wrong for me. Where it gets confusing for somebody who is trying to figure out what the configuration is doing is: Directory /www/pages SatisfyAll Require ip 10.10.0.1 Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/pages/private AuthzMergeRules SatisfyOne SatisfyAll Require ldap-group marketing Require ldap-group alt-marketing /SatisfyAll /Directory Now I have to reconcile the logic of the parent with the logic of both the AuthzMergeRules and the SatisfyAll tag. Even though it might not always look like the cleanest configuration, I think it will be less confusing if the logic rules were confined to the SatisfyAll and SatisfyOne tags rather than introducing alternate logic directives. [snip] If you'd like to stick to just Off (my proposed default for AuthzMergeRules) and On, perhaps AND should be the logic implemented by On? Consider the following, where AND'ing helps tighten security as you go down the tree: [snip] Personally, I'm gradually coming around to the feeling that AND is more useful/secure than OR when merging per-dir blocks, and possibly even within a single per-dir block (although that's another conversation), and so should either be an option to AuthzMergeRules or the action implemented by On if there are only two states. The reason I say it might make sense to AND authz requirements within a block is that it reads a little more naturally. Consider the following, which suggests to me that I need a shirt and shoes to be served, not one or the other: Directory /www/service Require shirt on Require shoes on /Directory At rate rate, thanks for hashing through all my scattershot ideas on this stuff. I could go along with switching the default merging rule from OR to AND, even within a dir block. The reason why it is OR today was basically for backward compatibility. Since there really wasn't any kind of logic before, OR was just the default. If we switch to AND as being the default within a dir block, it may break some existing configurations. However I also think that AND is a safer merging rule going forward. Brad
Re: AuthzMergeRules directive
Brad Nicholes wrote: I'm not real excited about adding a new authz directive. Authn and authz are already very complex and adding a new directive to the mix will just help to confuse people even more. That's a good point. Mostly the idea of an Accept replacement for Require came up as a way to distinguish pre-2.4 and 2.4 per-dir authz, and in case there were any Require foo directives which had slightly different meanings in the two contexts and which might therefore trip people up. If we can do without it, all the better. I am OK with this one except for the reason that I mentioned before. By allowing authz to be inherited even when AuthzMergeRules is OFF is kind of a conflict. In other words, since AuthzMergeRules OFF implies an AND, 1 AND 0 should be 0 or no authz rather than inherited authz. However I could buy into this if it seems to make more intuitive sense to the user. Well, I may be missing something, but what I envisioned was that AuthzMergeRules had three options: Off (i.e., inherited until overridden, the pre-2.4 default), SatisfyOne, and SatisfyAll. That would give administrators full control over how they wanted authz in different per-dir blocks to be merged. It seems to me we have three basic possibilities when it comes to merging authz across per-dir blocks, and the most common authz case to consider is going to be where security gets tighter as you move down the document tree. Imagine something like the following in a pre-2.4 configuration, where admin is not a member of team: Directory /htdocs ## full access /Directory Directory /htdocs/team ## anyone in team has access Require group team /Directory Directory /htdocs/team/admin ## only admin user has access Require user admin /Directory 1) The first option for 2.4 merging is to use OR logic (the current default in trunk). This leads to anyone in team having access to /htdocs/team/admin, I believe. I think I'd have to vote -1 against this, because it will lead to lots of previously secure configurations becoming insecure. Plus it would seem to increase the required number of directives (since you have to add AuthzMergeRules Off in each sub-Directory) to achieve what seems to me to be a typical configuration, i.e., increasing security as you go down the tree. 2) Another option might be to use AND logic. In this case, if I'm applying the logic correctly, no one would be able to access /htdocs/team/admin given the configuration above in a 2.4 context (since admin isn't in team). While more secure, this also seems counter-intuitive to me. Maybe -0.5? 3) Finally there's the pre-2.4 logic of overriding all previous authz. This would seem to be the most preferable option, since it ensures many pre-2.4 configurations will continue to work as expected, and I think also reduces configuration verbosity in typical cases. You were concerned, I think, about more complex configurations like this: Directory /www/pages SatisfyAll Require ip 10.10.0.1 Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/pages/private Require ldap-group marketing /Directory I would suggest that the default pre-2.4 logic of overriding previous authz when any authz is defined in a per-dir block is still reasonable as a default. Thus, only those in marketing have access to /www/pages/private, and they can access it from other addresses than 10.10.0.1. Even if this isn't what is desired, it's clear enough that an administrator can figure out what's going on and why the configuration isn't achieving the desired result. I'd propose giving the administrator the choice of both alternatives to the default logic. Instead of simply offering AuthzMergeRules On, there would be two alternatives to the default Off condition. These would be AuthzMergeRules SatisfyOne (the OR logic) and AuthzMergeRules SatisfyAll (the AND logic). We might offer Or and And as synonyms for SatisfyOne and SatisfyAll, respectively. Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
On 4/14/2008 at 12:21 PM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: Brad Nicholes wrote: I'm not real excited about adding a new authz directive. Authn and authz are already very complex and adding a new directive to the mix will just help to confuse people even more. That's a good point. Mostly the idea of an Accept replacement for Require came up as a way to distinguish pre-2.4 and 2.4 per-dir authz, and in case there were any Require foo directives which had slightly different meanings in the two contexts and which might therefore trip people up. If we can do without it, all the better. I am OK with this one except for the reason that I mentioned before. By allowing authz to be inherited even when AuthzMergeRules is OFF is kind of a conflict. In other words, since AuthzMergeRules OFF implies an AND, 1 AND 0 should be 0 or no authz rather than inherited authz. However I could buy into this if it seems to make more intuitive sense to the user. Well, I may be missing something, but what I envisioned was that AuthzMergeRules had three options: Off (i.e., inherited until overridden, the pre-2.4 default), SatisfyOne, and SatisfyAll. That would give administrators full control over how they wanted authz in different per-dir blocks to be merged. It seems to me we have three basic possibilities when it comes to merging authz across per-dir blocks, and the most common authz case to consider is going to be where security gets tighter as you move down the document tree. Imagine something like the following in a pre-2.4 configuration, where admin is not a member of team: Directory /htdocs ## full access /Directory Directory /htdocs/team ## anyone in team has access Require group team /Directory Directory /htdocs/team/admin ## only admin user has access Require user admin /Directory 1) The first option for 2.4 merging is to use OR logic (the current default in trunk). This leads to anyone in team having access to /htdocs/team/admin, I believe. I think I'd have to vote -1 against this, because it will lead to lots of previously secure configurations becoming insecure. Plus it would seem to increase the required number of directives (since you have to add AuthzMergeRules Off in each sub-Directory) to achieve what seems to me to be a typical configuration, i.e., increasing security as you go down the tree. 2) Another option might be to use AND logic. In this case, if I'm applying the logic correctly, no one would be able to access /htdocs/team/admin given the configuration above in a 2.4 context (since admin isn't in team). While more secure, this also seems counter-intuitive to me. Maybe -0.5? 3) Finally there's the pre-2.4 logic of overriding all previous authz. This would seem to be the most preferable option, since it ensures many pre-2.4 configurations will continue to work as expected, and I think also reduces configuration verbosity in typical cases. You were concerned, I think, about more complex configurations like this: Directory /www/pages SatisfyAll Require ip 10.10.0.1 Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/pages/private Require ldap-group marketing /Directory I would suggest that the default pre-2.4 logic of overriding previous authz when any authz is defined in a per-dir block is still reasonable as a default. Thus, only those in marketing have access to /www/pages/private, and they can access it from other addresses than 10.10.0.1. Even if this isn't what is desired, it's clear enough that an administrator can figure out what's going on and why the configuration isn't achieving the desired result. I'm OK with it up to this point. I'd propose giving the administrator the choice of both alternatives to the default logic. Instead of simply offering AuthzMergeRules On, there would be two alternatives to the default Off condition. These would be AuthzMergeRules SatisfyOne (the OR logic) and AuthzMergeRules SatisfyAll (the AND logic). We might offer Or and And as synonyms for SatisfyOne and SatisfyAll, respectively. This is where it starts to go wrong for me. Where it gets confusing for somebody who is trying to figure out what the configuration is doing is: Directory /www/pages SatisfyAll Require ip 10.10.0.1 Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/pages/private AuthzMergeRules SatisfyOne SatisfyAll Require ldap-group marketing Require ldap-group alt-marketing /SatisfyAll /Directory Now I have to reconcile the logic of
Re: AuthzMergeRules directive
Brad Nicholes wrote: This is where it starts to go wrong for me. Where it gets confusing for somebody who is trying to figure out what the configuration is doing is: Directory /www/pages SatisfyAll Require ip 10.10.0.1 Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/pages/private AuthzMergeRules SatisfyOne SatisfyAll Require ldap-group marketing Require ldap-group alt-marketing /SatisfyAll /Directory Now I have to reconcile the logic of the parent with the logic of both the AuthzMergeRules and the SatisfyAll tag. Even though it might not always look like the cleanest configuration, I think it will be less confusing if the logic rules were confined to the SatisfyAll and SatisfyOne tags rather than introducing alternate logic directives. I take your point about complexity, but on the other hand, these aren't alternate logic directives -- they're additional. The logic specified above for /www/pages/private would be: ( Require ip 10.10.0.1 Require ldap-group sales ( Require ldap-group ne-sales || Require ldap-group sw-sales)) || - AuthzMergeRules SastifyOne ( Require ldap-group marketing Require ldap-group alt-marketing) At least with AuthzMergeRules being ON or OFF, the only thing I need to know is if I am merging with the parent or not. All of the logic rules just flow from there. Granted, the above example is complex and maybe non-intuitive, but most people aren't going to attempt or need such a large set of authz directives. For those who really do, there are surely going to be cases where AND'ing block is useful while OR'ing is not at all (since OR'ing tends to short-circuit the configurations deeper down the document tree, which seems unlikely to be what people will mostly want). If you'd like to stick to just Off (my proposed default for AuthzMergeRules) and On, perhaps AND should be the logic implemented by On? Consider the following, where AND'ing helps tighten security as you go down the tree: Directory /www/private Require ip 10.10.0.1 /Directory Directory /www/private/sales ## must come from 10.10.0.1 AuthzMergeRules SatisfyAll SatisfyAll Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/private/sales/admin ## must come from 10.10.0.1, belong to sales, and also ## belong to one of ne-sales or sw-sales AuthzMergeRules SatisfyAll SatisfyAll Require ldap-group admin Require ldap-group sales-admin /SatisfyAll /Directory Perhaps others have opinions on this stuff? Basically my principal concern is that the default AuthzMergeRules setting must be Off. Beyond that, I can live any other choices. Personally, I'm gradually coming around to the feeling that AND is more useful/secure than OR when merging per-dir blocks, and possibly even within a single per-dir block (although that's another conversation), and so should either be an option to AuthzMergeRules or the action implemented by On if there are only two states. The reason I say it might make sense to AND authz requirements within a block is that it reads a little more naturally. Consider the following, which suggests to me that I need a shirt and shoes to be served, not one or the other: Directory /www/service Require shirt on Require shoes on /Directory At rate rate, thanks for hashing through all my scattershot ideas on this stuff. Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
On 09.04.2008 19:08, Chris Darroch wrote: Chris Darroch wrote: Writing that all out it mostly just seems like a depressingly large amount of work, but otherwise feels like it might offer a way forward, both for people upgrading from 2.2 and those starting fresh with 2.4. Thoughts? From a first and quick look seems good. Regards RĂ¼diger
Re: AuthzMergeRules directive
On 4/9/2008 at 11:08 AM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: Chris Darroch wrote: Here's another thought: for people doing mass virtual hosting, and who let their customers put authn/z directives into .htaccess files with AllowOverride AuthConfig, I would think it may be important to ensure that these rules still merge together in the way they used to. Otherwise upgrading to 2.4 might mean tracking down every .htaccess file and rewriting it to do the right thing (sticking in an AuthzMergeRules Off or something). For some people doing vhosting I suspect that would be a tall order, so it would be good if 2.4 would function securely in this situation, by default. That said, I don't use .htaccess files and may not be making any sense today; my apologies. Here's a follow-up notion; admittedly, it represents a lot of re-refactoring work. It would provide an secure upgrade path for people with complex configurations, including those with many legacy .htaccess files to consider. A new directive, Accept, is introduced to take the place of Require. It functions as Require does now in 2.4. Thus we have two groups of authz directives, old (Require/Satisfy/Order/ Deny/Allow) and new (Accept/Reject/SatisfyOne/SatisfyAll). The old directives function as they did in 2.2. Authz directives would be parsed and merged as follows: I'm not real excited about adding a new authz directive. Authn and authz are already very complex and adding a new directive to the mix will just help to confuse people even more. Especially when they can't tell the difference between 'require' and 'accept' or when they should use one or the other. The requirement to stay somewhat backwards compatible in all of this stuff lends to the confusion already. 1) Within a per-dir config block (Location/Directory/etc.) old and new authz directives may not be mixed. If directives from both groups appear, a config-time error is thrown. 2) When merging new authz directives within a per-dir config block, the default merge rule is OR, as in 2.4 at present. This is equivalent to using a SatisfyOne around all new authz directives within a per-dir config block. 3) When merging per-dir config blocks at runtime, the following rules are applied; we'll call the parent block base and the child block new: 3.1) If the new block contains no authz directives, the base's authz configuration is inherited (if any). This follows current 2.2 behaviour. I am OK with this one except for the reason that I mentioned before. By allowing authz to be inherited even when AuthzMergeRules is OFF is kind of a conflict. In other words, since AuthzMergeRules OFF implies an AND, 1 AND 0 should be 0 or no authz rather than inherited authz. However I could buy into this if it seems to make more intuitive sense to the user. 3.2) If the new block contains old authz directives, the base block's authz configuration is discarded, and the new block's authz directives are applied to a clean slate. This follows current 2.2 behaviour. 3.3) If the new block contains new authz directives, the base and new blocks' authz configurations are merged using the rule specified by AuthzMergeRules (as it appears within the new block): This is where things get a little confusing for me. I'm not really too excited about authz logic behavior changing just because of which version of an authz directive you used. This type of change in behavior isn't intuitive. At least with the way it is now,the behavior change would be between 2.2 and 2.4 rather than two different behaviors in 2.4 itself. 3.3.1) If AuthzMergeRules is set to Off or is not defined, the base block's authz configuration is discarded, and the new block's authz directives are applied to a clean slate. This follows current 2.2 behaviour, to avoid confusion and simplify most configurations. 3.3.2) If AuthzMergeRules is set to Or or SatisfyOne, the base block's authz configuration is merged with the new block's as if they were collectively contained within a SatisfyOne block. 3.3.3) If AuthzMergeRules is set to And or SatisfyAll, the base block's authz configuration is merged with the new block's as if they were collectively contained within a SatisfyAll block. This could be OK however I'm not real comfortable with specifying the merging logic in two different ways. In other words, if AuthzMergeRules is set to OR yet SatisfyAll is also specified in the same block. The new authz directives may take a little getting used to when first used, but at least there is a consistent way to do things and a behavior that will be consistent in 2.4 without having to worry a lot about what ifs. Writing that all out it mostly just
Re: AuthzMergeRules directive
Chris Darroch wrote: Here's another thought: for people doing mass virtual hosting, and who let their customers put authn/z directives into .htaccess files with AllowOverride AuthConfig, I would think it may be important to ensure that these rules still merge together in the way they used to. Otherwise upgrading to 2.4 might mean tracking down every .htaccess file and rewriting it to do the right thing (sticking in an AuthzMergeRules Off or something). For some people doing vhosting I suspect that would be a tall order, so it would be good if 2.4 would function securely in this situation, by default. That said, I don't use .htaccess files and may not be making any sense today; my apologies. Here's a follow-up notion; admittedly, it represents a lot of re-refactoring work. It would provide an secure upgrade path for people with complex configurations, including those with many legacy .htaccess files to consider. A new directive, Accept, is introduced to take the place of Require. It functions as Require does now in 2.4. Thus we have two groups of authz directives, old (Require/Satisfy/Order/ Deny/Allow) and new (Accept/Reject/SatisfyOne/SatisfyAll). The old directives function as they did in 2.2. Authz directives would be parsed and merged as follows: 1) Within a per-dir config block (Location/Directory/etc.) old and new authz directives may not be mixed. If directives from both groups appear, a config-time error is thrown. 2) When merging new authz directives within a per-dir config block, the default merge rule is OR, as in 2.4 at present. This is equivalent to using a SatisfyOne around all new authz directives within a per-dir config block. 3) When merging per-dir config blocks at runtime, the following rules are applied; we'll call the parent block base and the child block new: 3.1) If the new block contains no authz directives, the base's authz configuration is inherited (if any). This follows current 2.2 behaviour. 3.2) If the new block contains old authz directives, the base block's authz configuration is discarded, and the new block's authz directives are applied to a clean slate. This follows current 2.2 behaviour. 3.3) If the new block contains new authz directives, the base and new blocks' authz configurations are merged using the rule specified by AuthzMergeRules (as it appears within the new block): 3.3.1) If AuthzMergeRules is set to Off or is not defined, the base block's authz configuration is discarded, and the new block's authz directives are applied to a clean slate. This follows current 2.2 behaviour, to avoid confusion and simplify most configurations. 3.3.2) If AuthzMergeRules is set to Or or SatisfyOne, the base block's authz configuration is merged with the new block's as if they were collectively contained within a SatisfyOne block. 3.3.3) If AuthzMergeRules is set to And or SatisfyAll, the base block's authz configuration is merged with the new block's as if they were collectively contained within a SatisfyAll block. Writing that all out it mostly just seems like a depressingly large amount of work, but otherwise feels like it might offer a way forward, both for people upgrading from 2.2 and those starting fresh with 2.4. Thoughts? Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
Brad Nicholes wrote: Directory /www/pages Reject ip 127.0.0.1//Or any other Require directive /Directory Directory /www/pages/whatever ... /Directory Since the /www/pages/whatever directory did not specify any authz, what should happen? If the AuthzMergeRules is OFF then what is the authz for /www/pages/whatever? I'm not sure that 'all granted' is correct but then neither is 'all denied'. Since the AuthzMergeRules is OFF then merging the authz would be counter intuitive. If AuthzMergeRules is ON then 127.0.0.1 is rejected and all others are allowed. I guess the thinking was that leaving the default ON would leave fewer unknowns however in some instances may not be as intuitive. Well, again referring to my intuition based on configuring 2.2 and prior servers, I would expect the /www/pages authz to cover everything under /www/pages (including /www/pages/whatever) unless I define other authz rules -- at which point, the corresponding authz slate is wiped clean for that subdirectory, and my local authz directives take effect. (Not all authz directives, mind you, just those which I'm overriding.) So I can do something like: Directory /www/pages Require valid-user /Directory Directory /www/pages/images ## still protected Dav filesystem /Directory Directory /www/pages/private Require user admin /Directory One key to this behaviour, IIRC, is that all of the stock authz modules in 2.2 use the default merge_dir_config rules; that is, none of them define their own merge function and all just say: NULL, /* dir merger --- default is to override */ Then the ap_merge_per_dir_configs() logic which gets applied when merging their per-directory configurations is to cause the ancestor's configuration to be inherited, unless there's a new per-directory configuration for the same module. The Require directive is, again IIRC, handled in the core per-directory configuration, and the logic in merge_core_dir_configs() is similar: duplicate the ancestor's configuration, and then override the inherited Require directives if there's a Require directive in the new per-directory configuration: if (new-ap_requires) { conf-ap_requires = new-ap_requires; } So I think the result is that each authz directive gets inherited down through the directory configurations, until something overrides it, at which point everything to do with that directive is started fresh. It's a relatively space-efficient configuration style, actually, because you only need to put in an authz directive if you're changing something from what's inherited. I hope I've described the existing situation accurately; at any rate, it seems to me to be a good way to structure the 2.4 authz merge rules. It would mean you mostly didn't need to specify AuthzMergeRules (saves typing and errors) and things are protected down through the directory hierarchy by default (also good) unless you specifically include a new authz directive, at which point that takes effect and is inherited downwards. So the default merge logic would be, I guess, neither AND nor OR but inherit-until-overridden. Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
On 4/8/2008 at 10:41 AM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: Brad Nicholes wrote: Directory /www/pages Reject ip 127.0.0.1//Or any other Require directive /Directory Directory /www/pages/whatever ... /Directory Since the /www/pages/whatever directory did not specify any authz, what should happen? If the AuthzMergeRules is OFF then what is the authz for /www/pages/whatever? I'm not sure that 'all granted' is correct but then neither is 'all denied'. Since the AuthzMergeRules is OFF then merging the authz would be counter intuitive. If AuthzMergeRules is ON then 127.0.0.1 is rejected and all others are allowed. I guess the thinking was that leaving the default ON would leave fewer unknowns however in some instances may not be as intuitive. Well, again referring to my intuition based on configuring 2.2 and prior servers, I would expect the /www/pages authz to cover everything under /www/pages (including /www/pages/whatever) unless I define other authz rules -- at which point, the corresponding authz slate is wiped clean for that subdirectory, and my local authz directives take effect. (Not all authz directives, mind you, just those which I'm overriding.) So I can do something like: Directory /www/pages Require valid-user /Directory Directory /www/pages/images ## still protected Dav filesystem /Directory Directory /www/pages/private Require user admin /Directory One key to this behaviour, IIRC, is that all of the stock authz modules in 2.2 use the default merge_dir_config rules; that is, none of them define their own merge function and all just say: NULL, /* dir merger --- default is to override */ Then the ap_merge_per_dir_configs() logic which gets applied when merging their per-directory configurations is to cause the ancestor's configuration to be inherited, unless there's a new per-directory configuration for the same module. The Require directive is, again IIRC, handled in the core per-directory configuration, and the logic in merge_core_dir_configs() is similar: duplicate the ancestor's configuration, and then override the inherited Require directives if there's a Require directive in the new per-directory configuration: if (new-ap_requires) { conf-ap_requires = new-ap_requires; } So I think the result is that each authz directive gets inherited down through the directory configurations, until something overrides it, at which point everything to do with that directive is started fresh. It's a relatively space-efficient configuration style, actually, because you only need to put in an authz directive if you're changing something from what's inherited. I hope I've described the existing situation accurately; at any rate, it seems to me to be a good way to structure the 2.4 authz merge rules. It would mean you mostly didn't need to specify AuthzMergeRules (saves typing and errors) and things are protected down through the directory hierarchy by default (also good) unless you specifically include a new authz directive, at which point that takes effect and is inherited downwards. So the default merge logic would be, I guess, neither AND nor OR but inherit-until-overridden. Chris. Your assumptions about how the 2.2 per-dir merging is correct. Unfortunately the same concepts no longer apply to 2.4. The reason why is this: Directory /www/pages SatisfyAll Require ip 10.10.0.1 Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/pages/images ## still protected Dav filesystem /Directory Directory /www/pages/private Require ldap-group marketing /Directory Which ldap-group is overridden vs merged? Since the 2.2 authz had no concept of logic and was simply a list of require statements, it was very easy to add to the list or override an entry in the list. This is no longer the case. The require statements have to be merged according to some type of logic rules. Your suggestion would work if /www/pages/private simply reset and applied only the require statements it found in its own directory block (ie. AuthzMergeRules OFF), but picking the inherited logic apart and trying to rework it, won't really work. BTW, one of the main reasons why the logic operators were added to authz was to solve the problem that existed in 2.2. The problem was that if multiple require statements appeared in a single directory block or in a hierarchy, you never really knew in which order they were actually applied. Basically it came down to the order in which the authz modules happen to have been loaded. By applying the authz through logical operators, it replaced the simple array of entries with a logic tree, which is why the API ap_requires() no
Re: AuthzMergeRules directive
Brad Nicholes wrote: Your assumptions about how the 2.2 per-dir merging is correct. Unfortunately the same concepts no longer apply to 2.4. The reason why is this: Directory /www/pages SatisfyAll Require ip 10.10.0.1 Require ldap-group sales SatisfyOne Require ldap-group ne-sales Require ldap-group sw-sales /SatisfyOne /SatisfyAll /Directory Directory /www/pages/images ## still protected Dav filesystem /Directory Directory /www/pages/private Require ldap-group marketing /Directory Which ldap-group is overridden vs merged? Since the 2.2 authz had no concept of logic and was simply a list of require statements, it was very easy to add to the list or override an entry in the list. This is no longer the case. The require statements have to be merged according to some type of logic rules. Your suggestion would work if /www/pages/private simply reset and applied only the require statements it found in its own directory block (ie. AuthzMergeRules OFF), but picking the inherited logic apart and trying to rework it, won't really work. Ideally, perhaps, it would be possible to throw a configuration-time error indicating that there was ambiguity here. However, since it's going to be effectively impossible to pre-determine all the possible Directory, Location, etc. blocks which might apply to a particular request (and in which order), that's not really possible. As you say, picking things apart isn't going to work either. One alternative is, as we've discussed, a default AuthzMergeRules Off state which would blank the slate when a per-dir config block contained any of Require/Reject/SastifyAll/SastifyOne. What would happen, though, if the default merge rule between per-dir configuration blocks was AND? (Within a block, OR would presumably still make sense.) I have a head cold today, and so may be making even less sense than usual, but I think this would at least ensure that people's configurations got gradually tighter and more restrictive as blocks were merged together down through the location and directory hierarchies. It might take an administrator a while after upgrading to figure out why they couldn't access something anymore, but at least they wouldn't have opened anything up unexpectedly. BTW, one of the main reasons why the logic operators were added to authz was to solve the problem that existed in 2.2. The problem was that if multiple require statements appeared in a single directory block or in a hierarchy, you never really knew in which order they were actually applied. Basically it came down to the order in which the authz modules happen to have been loaded. And there's no easy way, I think, to turn off authz completely, a Require all granted ... the 2.2 docs refer you to using Sastify All and Allow from all. 2.4 is much cleaner, no doubt. My concern just really comes down to the fact that I'm fairly sure that a default OR merge rule between per-dir configuration blocks will lead people into thinking they've secured a subdirectory, when in fact they haven't, because their more-secure rule will be silently short-circuited by less-secure authz rules from above. Here's another thought: for people doing mass virtual hosting, and who let their customers put authn/z directives into .htaccess files with AllowOverride AuthConfig, I would think it may be important to ensure that these rules still merge together in the way they used to. Otherwise upgrading to 2.4 might mean tracking down every .htaccess file and rewriting it to do the right thing (sticking in an AuthzMergeRules Off or something). For some people doing vhosting I suspect that would be a tall order, so it would be good if 2.4 would function securely in this situation, by default. That said, I don't use .htaccess files and may not be making any sense today; my apologies. Thanks, Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
On 4/4/2008 at 4:33 PM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: Brad Nicholes wrote: So here was the thinking behind it when AuthzMergeRules was introduced. Maybe there is still a bug here that needs to be addressed. http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/%3c44C4E0FA.8060 [EMAIL PROTECTED] http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/%3c44CA3C33.6720 [EMAIL PROTECTED] I'm not sure it's a bug per se, but rather, an unexpected break from the intuition developed by administrators used to configuring 2.2.x and prior versions about how authorization cascades through configuration blocks. I may be wrong about this, but here's how I'd expect the example from your second thread to work. The example is: Directory /www/pages Reject ip 127.0.0.1 /Directory Directory /www/pages/secure Authtype Basic ... SatisfyAll Require valid-user Reject user joe /SatisfyAll /Directory My hunch is that prior to 2.2, the fundamental logic when merging authz rules across blocks was neither AND nor OR, but reset. That is, it relies on the configuration walks to find the authz directives in the most closely relevant block. Those directives are then applied; what appeared in less relevant blocks is ignored. I haven't looked closely at the logic, but that's what seems to happen if you've got something like: Directory /htdocs Require valid-user /Directory Directory /htdocs/admin Require user admin /Directory So in your example, my configuration intuition suggest that only what appears in the Directory /www/pages/secure block applies to anything under /www/pages/secure, and that the Reject ip 127.0.0.1 would just not applied at all to these URIs. So I'd expect that to access /www/pages/secure I'd need to be any valid user except joe; whether I was connecting from 127.0.0.1 wouldn't matter. Now, within a block, having OR be the default merge logic would seem to make sense; if you want AND, you need SatisfyAll. So: Directory /www/pages/secure Require user betty Require user joe /Directory means betty and joe alone have access, regardless of what applied to /www/pages. But if the following is also configured, then a reset rule across blocks would mean that it does what one expects; betty and joe would be rejected along with everyone else when attempting to access URIs under /www/pages/secure/really. Directory /www/pages/secure/really Require all denied /Directory This would presumably work identically: Directory /www/pages/secure/really Reject all granted /Directory Anyway, that's a bit of a shot in the dark. Hope it helps. Thanks, Chris. So I believe that the behavior that you have described could be accomplished by just switching the default of AuthzMergeRules from ON to OFF. The only case that I am still worried about is the following: Directory /www/pages Reject ip 127.0.0.1//Or any other Require directive /Directory Directory /www/pages/whatever ... /Directory Since the /www/pages/whatever directory did not specify any authz, what should happen? If the AuthzMergeRules is OFF then what is the authz for /www/pages/whatever? I'm not sure that 'all granted' is correct but then neither is 'all denied'. Since the AuthzMergeRules is OFF then merging the authz would be counter intuitive. If AuthzMergeRules is ON then 127.0.0.1 is rejected and all others are allowed. I guess the thinking was that leaving the default ON would leave fewer unknowns however in some instances may not be as intuitive. Brad
Re: AuthzMergeRules directive
On 4/4/2008 at 5:43 PM, in message [EMAIL PROTECTED], Paul J. Reder [EMAIL PROTECTED] wrote: Perhaps it would make more sense to provide this as an explicit value rather than On vs. Off and set the default to the previous behavior. Perhaps something like: AuthzMergeRules [AND | OR | OVERRIDE] with default being OVERRIDE (if I grok correctly) Meaning that any directives specified at only one level would be merged to lower levels, but the merge behavior of directives specified at multiple levels would be controlled by this directive (i.e. ANDed, ORed, or OVERRIDEn with levels above it). This could result in complex logic if subsequent levels of containers mixed AND, OR, and OVERRIDE, but if it was designed to be explicit then the user would have specific control over each authbit along the way. When I originally looked at the implementation of the authzMergeRules directive, the above suggestion was my first thought. However I think I decided not to go this route simply because the same thing could be accomplished in a less complex way by making the user explicitly decide the merging rules within the configuration of the directory block itself. In other words, if they wanted OR merging between a higher level and a lower level block, then do nothing or specify SatisfyOne in the lower level block. If they wanted AND merging then specify SatisfyAll in the lower level block. This follows the same concepts as would be done within a single directory block. This avoids having to resolve logic conflicts and precedents between two different directives, AuthzMergeRules and SatisfyXXX Brad
AuthzMergeRules directive (was:Re: 2.4)
On 4/4/2008 at 11:37 AM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: William A. Rowe, Jr. wrote: I've been working with the 2.4 authn/z stuff a bit lately and what I keep tripping over is that the default authorization merge rule uses OR logic. For example, if I enable mod_access_compat and put in a traditional: I wonder if anyone would offer a fastfeather talk next week on wed or thurs - it's only 15 minutes - to introduce what's upcoming in 2.4? I won't be there, but here's a recap of the issue for discussion. (Caveat: I may be missing something important!) With 2.2 and prior versions, one can do something like: Directory /htdocs Require valid-user /Directory Directory /htdocs/admin Require user admin /Directory The logic which is then applied is: 1) For all requests under /htdocs, except those under /htdocs/admin, require any valid user. 2) For all requests under /htdocs/admin, require the admin user. With 2.4, unless I'm missing something, the same configuration produces the logic: 1) For all requests under /htdocs, except those under /htdocs/admin, require any valid user. 2) For all requests under /htdocs/admin, require any valid user OR require the user admin. Of course this grants any valid user access. To get the old behaviour, you seem to need to add AuthzMergeRules Off to the second Directory. I just tested versions of this configuration with 2.2 and 2.4 and I think I'm describing the situation correctly. Assuming I am, I fear this will surprise a lot of people who think they've secured their systems after upgrading. It certainly caught me short. Perhaps the default AuthzMergeRules setting should be Off rather than On, at least when merging across configuration blocks? So here was the thinking behind it when AuthzMergeRules was introduced. Maybe there is still a bug here that needs to be addressed. http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/[EMAIL PROTECTED] http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/[EMAIL PROTECTED] Brad
Re: AuthzMergeRules directive
Brad Nicholes wrote: So here was the thinking behind it when AuthzMergeRules was introduced. Maybe there is still a bug here that needs to be addressed. http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/[EMAIL PROTECTED] http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/[EMAIL PROTECTED] I'm not sure it's a bug per se, but rather, an unexpected break from the intuition developed by administrators used to configuring 2.2.x and prior versions about how authorization cascades through configuration blocks. I may be wrong about this, but here's how I'd expect the example from your second thread to work. The example is: Directory /www/pages Reject ip 127.0.0.1 /Directory Directory /www/pages/secure Authtype Basic ... SatisfyAll Require valid-user Reject user joe /SatisfyAll /Directory My hunch is that prior to 2.2, the fundamental logic when merging authz rules across blocks was neither AND nor OR, but reset. That is, it relies on the configuration walks to find the authz directives in the most closely relevant block. Those directives are then applied; what appeared in less relevant blocks is ignored. I haven't looked closely at the logic, but that's what seems to happen if you've got something like: Directory /htdocs Require valid-user /Directory Directory /htdocs/admin Require user admin /Directory So in your example, my configuration intuition suggest that only what appears in the Directory /www/pages/secure block applies to anything under /www/pages/secure, and that the Reject ip 127.0.0.1 would just not applied at all to these URIs. So I'd expect that to access /www/pages/secure I'd need to be any valid user except joe; whether I was connecting from 127.0.0.1 wouldn't matter. Now, within a block, having OR be the default merge logic would seem to make sense; if you want AND, you need SatisfyAll. So: Directory /www/pages/secure Require user betty Require user joe /Directory means betty and joe alone have access, regardless of what applied to /www/pages. But if the following is also configured, then a reset rule across blocks would mean that it does what one expects; betty and joe would be rejected along with everyone else when attempting to access URIs under /www/pages/secure/really. Directory /www/pages/secure/really Require all denied /Directory This would presumably work identically: Directory /www/pages/secure/really Reject all granted /Directory Anyway, that's a bit of a shot in the dark. Hope it helps. Thanks, Chris. -- GPG Key ID: 366A375B GPG Key Fingerprint: 485E 5041 17E1 E2BB C263 E4DE C8E3 FA36 366A 375B
Re: AuthzMergeRules directive
Perhaps it would make more sense to provide this as an explicit value rather than On vs. Off and set the default to the previous behavior. Perhaps something like: AuthzMergeRules [AND | OR | OVERRIDE] with default being OVERRIDE (if I grok correctly) Meaning that any directives specified at only one level would be merged to lower levels, but the merge behavior of directives specified at multiple levels would be controlled by this directive (i.e. ANDed, ORed, or OVERRIDEn with levels above it). This could result in complex logic if subsequent levels of containers mixed AND, OR, and OVERRIDE, but if it was designed to be explicit then the user would have specific control over each authbit along the way. Paul J. Reder Brad Nicholes wrote: On 4/4/2008 at 11:37 AM, in message [EMAIL PROTECTED], Chris Darroch [EMAIL PROTECTED] wrote: William A. Rowe, Jr. wrote: I've been working with the 2.4 authn/z stuff a bit lately and what I keep tripping over is that the default authorization merge rule uses OR logic. For example, if I enable mod_access_compat and put in a traditional: I wonder if anyone would offer a fastfeather talk next week on wed or thurs - it's only 15 minutes - to introduce what's upcoming in 2.4? I won't be there, but here's a recap of the issue for discussion. (Caveat: I may be missing something important!) With 2.2 and prior versions, one can do something like: Directory /htdocs Require valid-user /Directory Directory /htdocs/admin Require user admin /Directory The logic which is then applied is: 1) For all requests under /htdocs, except those under /htdocs/admin, require any valid user. 2) For all requests under /htdocs/admin, require the admin user. With 2.4, unless I'm missing something, the same configuration produces the logic: 1) For all requests under /htdocs, except those under /htdocs/admin, require any valid user. 2) For all requests under /htdocs/admin, require any valid user OR require the user admin. Of course this grants any valid user access. To get the old behaviour, you seem to need to add AuthzMergeRules Off to the second Directory. I just tested versions of this configuration with 2.2 and 2.4 and I think I'm describing the situation correctly. Assuming I am, I fear this will surprise a lot of people who think they've secured their systems after upgrading. It certainly caught me short. Perhaps the default AuthzMergeRules setting should be Off rather than On, at least when merging across configuration blocks? So here was the thinking behind it when AuthzMergeRules was introduced. Maybe there is still a bug here that needs to be addressed. http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/[EMAIL PROTECTED] http://mail-archives.apache.org/mod_mbox/httpd-dev/200607.mbox/[EMAIL PROTECTED] Brad -- Paul J. Reder --- The strength of the Constitution lies entirely in the determination of each citizen to defend it. Only if every single citizen feels duty bound to do his share in this defense are the constitutional rights secure. -- Albert Einstein