Apache::AuthPAM - Authenticate apache request using PAM services


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

Index


Code Index:

NAME

Top

Apache::AuthPAM - Authenticate apache request using PAM services

SYNOPSIS

Top

  # /etc/httpd.conf
  <Directory /var/www/https/secured-area/>
     AuthType Basic
     AuthName "your server account"
     PerlAuthHandler Apache::AuthPAM
     PerlSetVar PAMservice check_user
     require valid-user
  </Directory>

  # /etc/pam.d/check_user
  #%PAM-1.0
  auth        required    /lib/security/pam_pwdb.so nodelay
  account     required    /lib/security/pam_pwdb.so

DESCRIPTION

Top

This perl module is designed to work with mod_perl and the Authen::PAM module.

You can select the PAM service setting the perl var PAMservice

  PerlSetVar PAMservice the-pam-service-you-want

You can select different PAM services for different directories or locations in your web server filesystem space.

Apache::AuthPAM works as follows:

First, it calls pam_start with the selected service. Second, it calls pam_authenticate with the browser/apache supplied username and password. Later, it calls pam_acct_mgmt. And finally it calls pam_end. If any of the PAM functions fail, Apache::AuthPAM logs an info level message and returns AUTH_REQUIRED. If all PAM functions are succesfull, Apache::AuthPAM logs an info level message and returns OK.

If you are going to use your system password database, you MUST also use mod_ssl.

BUGS

Top

I'am using a global symbol.

Apache::AuthPAM is running as the same user mod_perl is running (on RedHat Linux it is apache). It is running without privileges.

AUTHOR

Top

Héctor Daniel Cortés González <hdcg@cie.unam.mx>

CREDITS

Top

Apache::AuthPAM is a direct adaptation of Demetrios E. Paneras' <dep@media.mit.edu> Apache::AuthenNISplus. Authen::PAM is written by Nikolay Pelov <nikip@iname.com>. The sample PAM application check_user.c was contribuited by Shane Watts with modifications by AGM.

COPYRIGHT

Top

SEE ALSO

Top

perl, mod_perl, mod_ssl, Authen::PAM, Linux-PAM


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

package Apache::AuthPAM;
#
# h2xs -AX -n Apache::AuthPAM
#
use 5.006;
use strict;
use warnings;
use Apache::Constants qw/:common/;
use Apache::Log;
use Authen::PAM qw/pam_start pam_end pam_authenticate pam_acct_mgmt PAM_SUCCESS/;

require Exporter;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use Apache::AuthPAM ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(
	
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(
	
);

our $VERSION = '0.01';

our $MODNAME = 'Apache::AuthPAM';

#
# I use this global to pass user info to the conversation function
#   if you know a better way to do it, please tell me and/or fix it.
#
our %pw;

# Preloaded methods go here.

sub handler {
  # get object request
  my $r = shift;

  # check first request
  return OK unless $r->is_initial_req;

  # get user password
  my ($rc, $pw) = $r->get_basic_auth_pw;

  # decline if not basic
  return $rc if $rc;

  # get log object
  my $log = $r->log;

  # get user name
  my $username = $r->connection->user;

  # avoid blank username
  unless($username) {
    $r->note_basic_auth_failure;
    $log->info("$MODNAME: no user name supplied", $r->uri);
    return AUTH_REQUIRED;
  }

  # load apache config vars
  my $service = $r->dir_config('PAMservice');
  unless($service) {
    $log->alert("$MODNAME: no PAM service name supplied", $r->uri);
    return SERVER_ERROR;
  }

  # DAMN! I shouldn't use globals this way!
  $pw{$$}=$pw;

  # start PAM dialog
  my $pamh;
  my $result = pam_start($service, $username, \&my_conv_func, $pamh);

  unless ($result == PAM_SUCCESS) {
    $r->note_basic_auth_failure;
    $log->crit("$MODNAME: <$service> not started ($result) ", $r->uri);
    pam_end($pamh, 0);
    return SERVER_ERROR;
  }

  $result = pam_authenticate($pamh, 0);
  unless ($result == PAM_SUCCESS) {
    $r->note_basic_auth_failure;
    $log->info("$MODNAME: <$username> not authenticated by $service ($result) ", $r->uri);
    pam_end($pamh, 0);
    return AUTH_REQUIRED;
  }

  $result = pam_acct_mgmt($pamh, 0);
  unless ($result == PAM_SUCCESS) {
    $r->note_basic_auth_failure;
    $log->info("$MODNAME: <$username> no acct mgmt by $service ($result) ", $r->uri);
    pam_end($pamh, 0);
    return AUTH_REQUIRED;
  }

  # Authenticated
  pam_end($pamh, 0);
  $log->info("$MODNAME: <$username> authenticated by $service", $r->uri);
  return OK;
}

#
# Conversation Function
#
sub my_conv_func {
  my @res;
  while(@_) {
    my $msg_type = shift;
    my $msg = shift;
    push @res, (0, $pw{$$});
  }
  push @res, 0;
  return @res;
}

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