File Coverage

blib/lib/Apache/AuthzUnix.pm
Criterion Covered Total %
statement 15 16 93.7
branch n/a
condition 1 3 33.3
subroutine 5 5 100.0
pod n/a
total 21 24 87.5


line stmt bran cond sub pod time code
1             package Apache::AuthzUnix;
2             our $VERSION = '0.02';
3             our $DEBUG = 0;
4             require File::stat;
5 1     1   6684 use File::Basename qw(dirname);
  1         4  
  1         101  
6 1     1   800 use User::pwent;
  1         10264  
  1         7  
7 1     1   704 use User::grent;
  1         1518  
  1         6  
8              
9 1   33     161 use constant MP2 =>
10 1     1   85 ~~(exists $ENV{MOD_PERL_API_VERSION} && $ENV{MOD_PERL_API_VERSION} == 2);
  1         1  
11              
12             BEGIN {
13 1     1   2 my @constants = qw( OK DECLINED );
14 1         1 if (MP2) {
15             require Apache2::Access;
16             require Apache2::RequestRec;
17             require Apache2::Const;
18             import Apache2::Const @constants;
19             }
20             else {
21 1         1436 require Apache::Constants;
22 0           import Apache::Constants @constants;
23             }
24             }
25              
26             sub authz {
27             my $r = shift;
28             my $user = $r->user or return DECLINED();
29             my $fn = $r->filename;
30              
31             if (!-e $r->filename) { $fn = dirname($fn) }
32             # Why did we just do that? Because:
33             # If we're PUTting a file, we want to check if we can write to the directory.
34             # Otherwise, we're GETting a non-existent or autogenerated file (ie autoindex)
35             # If it's a directory index, then we use the permissions of the directory.
36             # If it's non-existent, permissions are an irrelevance!
37              
38             my $stat = File::stat::stat($fn);
39             my $access =
40             _access($user, $stat->mode, $stat->uid, $stat->gid, $r->method);
41             warn "Access to file: "
42             . $r->filename
43             . " (resolved as $fn) : "
44             . ($access ? "allowed" : "denied")
45             if $DEBUG;
46             return $access ? OK() : DECLINED();
47             }
48              
49             sub _access {
50             my ($username, $perms, $uid, $gid, $method) = @_;
51             my ($u, $g, $o) = ($perms & 0700, $perms & 0070, $perms & 0007);
52             my $user = getpwnam($username);
53             my %in_group = map { $_ => 1 } @{ getgrgid($gid)->members };
54             my $bit = $method =~ /(PUT|DELETE)/ ? 2 : 4;
55              
56             return 1 if $o & $bit
57             || ($uid == $user->uid and $u & ($bit << 6))
58             || (($gid == $user->gid or $in_group{$username})
59             and $g & ($bit << 3));
60             return 0;
61             }
62              
63             1;
64             __END__