[Previous] [Contents] [Next]


Monitoring Userids


As a final note in this section, we'll add a bit more code to our ongoing example to keep track of userids in the .htpasswd file for each <Directory> entry in access.conf.

use HTTPD::Config;

 require HTTPD::UserAdmin;

 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";

         if($opt eq "AuthUserFile"){

             ($path = join(`',@{$val})) =~ s/^(.*)\/.*/$1/;

             print "\tCurrent users in $opt:\n";

             $users = new HTTPD::UserAdmin(DBType => "Text",

                 Path => $path, Locking => 0, Server => "apache");

             #@users = $users->list;

             foreach $user (sort($users->list)){

                 print "\t\t$user : ";

                 print $users->password($user),"\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";

         }

     }

 }


We get a fairly nice report back that looks like this:

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

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

         Current users in AuthUserFile:

                 bmiddlet : ztTO6y2K.3qLE

                 bozo : 0Euk1WMWyXRgg

                 josie : _LhTDVY/y6tPo

         AddType : text/html .shtml

         AuthName : PasswordAdmin

         Options : Indexes SymLinksIfOwnerMatch IncludesNOEXEC

         AuthType : Basic

         AllowOverride : AuthConfig FileInfo Indexes Limit

         Limit: GET

                 deny = from .bozo.com

                 order = mutual-failure

                 allow = from .metronet.com


Of course, if your user database gets very large, then this script may produce more output than you want to see. The idea from the beginning has been that this script would run automatically via cron, having its output compared to the expected output, possibly from the day before, then sending on only the differences for your inspection.

[Previous] [Contents] [Next]