Apache::AuthzUnix - Apache/Apache2 authorization handler for Unix permissions


Apache-AuthzUnix documentation Contained in the Apache-AuthzUnix distribution.

Index


Code Index:

NAME

Top

Apache::AuthzUnix - Apache/Apache2 authorization handler for Unix permissions

SYNOPSIS

Top

  PerlModule Apache::AuthzUnix;
  <Location ...>
    AuthName auth
    AuthType Basic
    AuthBasicProvider ldap
    PerlAuthzHandler Apache::AuthzUnix::authz
    # Don't need a "requires" line
  </Location>

DESCRIPTION

Top

This module was written to provide authorization for DAV access to home directories, but probably has other uses in the UserDir space.

Assuming that Apache has authenticated a user, this module helps to determine whether or not that user can read (or write) a file on the filesystem. It applies standard Unix user and group tests on the file's permissions to determine read access and, in the case of PUT and DELETE methods, write access. If the file does not exist, then the containing directory is tested, as one would expect.

This module is designed work on both mod_perl versions 1 and 2.

AUTHOR

Top

Simon Cozens, <simon@simon-cozens.org>

COPYRIGHT AND LICENSE

Top


Apache-AuthzUnix documentation Contained in the Apache-AuthzUnix distribution.

package Apache::AuthzUnix;
our $VERSION = '0.02';
our $DEBUG   = 0;
require File::stat;
use File::Basename qw(dirname);
use User::pwent;
use User::grent;

use constant MP2 =>
  ~~(exists $ENV{MOD_PERL_API_VERSION} && $ENV{MOD_PERL_API_VERSION} == 2);

BEGIN {
    my @constants = qw( OK DECLINED );
    if (MP2) {
        require Apache2::Access;
        require Apache2::RequestRec;
        require Apache2::Const;
        import Apache2::Const @constants;
    }
    else {
        require Apache::Constants;
        import Apache::Constants @constants;
    }
}

sub authz {
    my $r    = shift;
    my $user = $r->user or return DECLINED();
    my $fn   = $r->filename;

    if (!-e $r->filename) { $fn = dirname($fn) }
# Why did we just do that? Because:
#  If we're PUTting a file, we want to check if we can write to the directory.
#  Otherwise, we're GETting a non-existent or autogenerated file (ie autoindex)
#     If it's a directory index, then we use the permissions of the directory.
#     If it's non-existent, permissions are an irrelevance!

    my $stat       = File::stat::stat($fn);
    my $access     =
      _access($user, $stat->mode, $stat->uid, $stat->gid, $r->method);
    warn "Access to file: "
      . $r->filename
      . " (resolved as $fn) : "
      . ($access ? "allowed" : "denied")
      if $DEBUG;
    return $access ? OK() : DECLINED();
}

sub _access {
    my ($username, $perms, $uid, $gid, $method) = @_;
    my ($u, $g, $o) = ($perms & 0700, $perms & 0070, $perms & 0007);
    my $user        = getpwnam($username);
    my %in_group    = map { $_ => 1 } @{ getgrgid($gid)->members };
    my $bit         = $method =~ /(PUT|DELETE)/ ? 2 : 4;

    return 1 if $o & $bit
             || ($uid == $user->uid and $u & ($bit << 6))
             || (($gid == $user->gid or $in_group{$username}) 
                 and $g & ($bit << 3));
    return 0;
}

1;
__END__
# Below is stub documentation for your module. You'd better edit it!