[Previous] [Contents] [Next]


Directory Access Configuration

If you decide to allow per-directory configuration files, you'll need to enable them in the global access.conf file with a good deal of consideration and care. Assuming you have a <Directory> entry for the DocumentRoot, you can enable certain capabilities for individual directories beneath the DocumentRoot on an as-needed basis.

Let's suppose, for the purpose of demonstration, that your archive consists of the DocumentRoot:

/usr/local/etc/httpd/htdocs


And beneath DocumentRoot, you have a subdirectory:

/usr/local/etc/httpd/htdocs/test1


Now assume that there exists, for DocumentRoot, an entry in the access.conf file that looks something like this:

<Directory /usr/local/etc/httpd/htdocs>



 AuthType Basic

 AuthName PasswordAdmin

 AuthUserFile /usr/local/etc/httpd/conf/.htpasswd



 AccessFileName .myhtaccess



 AddType text/html .shtml



 Options Indexes SymLinksIfOwnerMatch IncludesNOEXEC



 AllowOverride AuthConfig FileInfo Indexes Limit



 </Directory>


This entry allows any directory beneath DocumentRoot to have its own .privaccess files, which can then override any of the directives specified for DocumentRoot except the Options directive, which we don't want to let anyone specify beyond what is already allowed. Note that the Options directive is already used to turn on the automatic directory indexes (when index.html doesn't exist) and to follow symlinks if the owner of the symlink and what it points to match, as well as allowing server-side includes, but not the #exec and #include directives within server-side includes files.

Now, assume that the directory test1 has some proprietary or confidential information within it. You could assure that nothing is left to chance by configuring its directory entry in the global access.conf to disallow any overrides or options, like this:

<Directory /usr/local/etc/httpd/htdocs/test1>



 AllowOverride None



 Options None



 <Limit GET POST>

 require valid-user

 </Limit>



 </Directory>


Note that we also specify here that any access to this directory also be validated from the valid users in the AuthUserFile, inherited from the directives for DocumentRoot. We'll look more at user/group authentication in a bit.

You can use Perl and the HTTPD modules to verify that your access configurations for any given file in the archive are what you expect them to be. Here we'll modify our previous script to give us some additional information on the configuration directives for each directory specified in access.conf:

use HTTPD::Config;

 require "stat.pl";

 $conf =  `/usr/local/etc/httpd/conf';

 @files = qw(httpd.conf srm.conf access.conf);

 $V= new HTTPD::Config (SERVER => Apache,

                              SERVER_ROOT => $conf,

                              FILES => [@files]);



 print "Userid: ", $V->user,"\n";

 print "Group: ", $V->group,"\n";

 print "Administrator is: ", $V->server_admin,"\n";

 print "Running at port: ", $V->port,"\n";

 print "Access filename: ",$V->access_file_name,"\n";

 print "User Directory: ", $V->user_dir,"\n";

 print "Global Types:\t", join("\n\t\t",$V->add_type),"\n";

 print "\n\n";



 foreach $dir (keys %{$V->{`Directory'}}){

     print "Options for Directory: $dir\n";

     while(($opt,$val) = each %{$V->{`Directory'}{$dir}{`OPTIONS'}}){

         print "\t",$opt, " : ", @{$val},"\n";

     }

     print "\tLimit: @{$V->{Directory}{$dir}{LIMIT}{METHODS}}\n";

     while(($key,$val) = each %{$V->{Directory}{$dir}{LIMIT}{OPTIONS}}) {

         print "\t\t$key = @{$val}\n";

     }

     print "\n";

 }



 # rudimentary permissions checking



 $webuser = (getpwnam($V->user))[2];

 opendir(ROOT,$V->server_root);

 @files = grep(!/\.\.?/,readdir(ROOT));

 closedir(ROOT);

 foreach $f (@files){

     @s = Stat($V->server_root."/$f");

     if($s[$ST_UID] == $webuser){

         print "Warning: ",$V->server_root,"/$f is owned by ",

                 $V->user,"\n\n";

     }

     if($f eq "httpd"){

         if(($s[$ST_MODE] != 0100700) or ($s[$ST_UID] != 0)){

             print "\tWarning: ",$V->server_root,"/httpd may have\n";

             print "\tpermission problems.  Recommend root ownership\n";

             print "\tand readable, writable and executable only by\n";

             print "\troot user\n";

         }

     }

 }


Note that we added a few lines to the foreach loop, which loops over the <Directory> entries in access.conf, to tell us about any <Limit> directives and how they're configured. Now when we run the script against our existing hierarchy, we get the following output:

Userid: nobody

 Group: nogroup

 Administrator is: wmiddlet@adobe.com

 Running at port: 80

 Access filename: .privaccess

 User Directory: public_html

 Global Types:   text/html .shtml





 Options for Directory: /usr/local/etc/httpd/cgi-bin

         Options : None

         AllowOverride : None

         Limit:



 Options for Directory: /usr/local/etc/httpd/htdocs/test1

         Options : None

         AllowOverride : None

         Limit: GET POST

                 require = valid-user



 Options for Directory: /usr/local/etc/httpd/htdocs

         PerlHandler : main::handler

         AddType : text/html .shtml

         Options : Indexes SymLinksIfOwnerMatch IncludesNOEXEC

         AllowOverride : AuthConfig FileInfo Indexes Limit

         Limit:


The <Limit> options for the test1 directory are now specified.

[Previous] [Contents] [Next]