httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Roy T. Fielding" <field...@liege.ICS.UCI.EDU>
Subject override mask semantics
Date Wed, 02 Oct 1996 06:35:47 GMT
>> I know why it is generated.  Could someone provide me with meaningful,
>> short names for the following structure (to replace the single chars)?
>> 
>>     struct {
>>         int override;
>>         char letter;
>>     } aOvers[]= {
>>           { OR_LIMIT,    'L' },
>>           { OR_OPTIONS,  'O' },
>>           { OR_FILEINFO, 'F' },
>>           { OR_AUTHCFG,  'A' },
>>           { OR_INDEXES,  'I' },
>>           { ACCESS_CONF, 'a' },
>>           { RSRC_CONF,   'r' },
>>           { (OR_ALL|RSRC_CONF)&~(OR_LIMIT|OR_AUTHCFG), 'd' },
>>                                                     /* outside <Directory>
*/
>>           { OR_ALL|ACCESS_CONF, 'D' },              /* inside <Directory> */
>>           { 0, '\0' }
>>       };
>> 
>> My best guess would be two lines consisting of
>> 
>> 	modifies: Limit, Options, FileInfo, AuthConfig, Indexes
>> 	used  in: access.conf, srm.conf, inside/outside Directory or Location
>> 
>> Does that seem reasonable?
> 
> Doesn't sound right ... the OR_ options specify when the directive is
> permitted. I think.
>
>> p.s. this conversation wouldn't be necessary if everyone understood that
>>      commenting their own code is a *good* thing.
> 
>Really? Which comments where would have rendered this conversation unnecessary?

Any comments regarding the use of the override mask would have helped.

The only reason I was able to guess the above is because I knew that
options are configured, and somewhere the configuration is read, and
where it is read there are constant strings associated with those in
the external documentation.  Even with that, the real purpose of
ACCESS_CONF and RSRC_CONF is only a guess, and there is no rationale
given as to why (OR_ALL|RSRC_CONF)&~(OR_LIMIT|OR_AUTHCFG) implies that
it can occur outside a Directory, and there is no hint at all that the
Location directive shares the same semantics.  Someone who hasn't been
reading the list mail for the past year and a half would have a harder
time figuring it out, and this is a pretty basic part of our API.

Ah, hold on -- I just remembered I should check the API.html file as well.
Hmmm, it says here that

  <li> A bit mask indicating where the command may appear.  There are
       mask bits corresponding to each <code>AllowOverride</code>
       option, and an additional mask bit, <code>RSRC_CONF</code>,
       indicating that the command may appear in the server's own
       config files, but <em>not</em> in any <code>.htaccess</code>
       file.

which would seem to indicate that my guess was wrong.  Time to start over.

By following the C logic, it seems that overrides are only interpreted
in invoke_cmd() of http_config.c, whereupon we have

    if ((parms->override & cmd->req_override) == 0)
        return pstrcat (parms->pool, cmd->name, " not allowed here", NULL);

where parms->override is set according to where the directive occurs:

   *.conf   --> override = (RSRC_CONF|OR_ALL)&~(OR_AUTHCFG|OR_LIMIT);

   within <Directory> or <Location> --> override = OR_ALL|ACCESS_CONF;

  .htaccess --> override = core_dir->override;   /* AllowOverride, I assume */

<Limit> and <Files> do not change the override value, which seems odd.

So, parms->override indicates what overrides are allowed *here* (here
being the particular line of whatever config file is being read), 
and cmd->req_override indicates what overrides are required to be allowed
in order to use this directive here.  Right?  Well, in that case, this

    if ((parms->override & cmd->req_override) == 0)
        return pstrcat (parms->pool, cmd->name, " not allowed here", NULL);

is just plain wrong, since (00100 & 00101) == 00100 (not 0).  It should be

    if ((parms->override & cmd->req_override) != cmd->req_override)
        return pstrcat (parms->pool, cmd->name, " not allowed here", NULL);

since what (I think) it is trying to do is lay a permissions mask over
the directive requirements and see if all the requirements are met.
Could someone please confirm whether or not that is a bug?  In fact,
it may be a security hole.  If it is a bug, we need to fix it and then
check to be sure all the directive definitions use the correct value
for cmd->req_override (since they were tested against incorrect code).

If my interpretation of the code is correct, then

  (req_override & RSRC_CONF)
       ==> allowed in *.conf only outside <Directory> or <Location>

  (req_override & ACCESS_CONF)
       ==> allowed in *.conf only inside <Directory> or <Location>

  (req_override & OR_AUTHCFG)
       ==> allowed in *.conf only inside <Directory> or <Location> or in
           any .htaccess file when AllowOverride includes "All" or "AuthConfig"

  (req_override & OR_LIMIT)
       ==> allowed in *.conf only inside <Directory> or <Location> or in
           any .htaccess file when AllowOverride includes "All" or "Limit"

  (req_override & OR_OPTIONS)
       ==> allowed anywhere in *.conf or in
           any .htaccess file when AllowOverride includes "All" or "Options"

  (req_override & OR_FILEINFO)
       ==> allowed anywhere in *.conf or in
           any .htaccess file when AllowOverride includes "All" or "FileInfo"

  (req_override & OR_INDEXES)
       ==> allowed anywhere in *.conf or in
           any .htaccess file when AllowOverride includes "All" or "Indexes"

If the above is correct, then we should be able to code up a readable
version of the show_overrides function.  And, after 4 hours spent figuring
this out, the right answer *will* be included as comments within
the bloody code (http_config.h).

....Roy

Mime
View raw message