File Coverage

blib/lib/Apache/AuthPAM.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Apache::AuthPAM;
2             #
3             # h2xs -AX -n Apache::AuthPAM
4             #
5 1     1   5755 use 5.006;
  1         5  
  1         46  
6 1     1   6 use strict;
  1         2  
  1         39  
7 1     1   6 use warnings;
  1         15  
  1         42  
8 1     1   1573 use Apache::Constants qw/:common/;
  0            
  0            
9             use Apache::Log;
10             use Authen::PAM qw/pam_start pam_end pam_authenticate pam_acct_mgmt PAM_SUCCESS/;
11              
12             require Exporter;
13              
14             our @ISA = qw(Exporter);
15              
16             # Items to export into callers namespace by default. Note: do not export
17             # names by default without a very good reason. Use EXPORT_OK instead.
18             # Do not simply export all your public functions/methods/constants.
19              
20             # This allows declaration use Apache::AuthPAM ':all';
21             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
22             # will save memory.
23             our %EXPORT_TAGS = ( 'all' => [ qw(
24            
25             ) ] );
26              
27             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
28              
29             our @EXPORT = qw(
30            
31             );
32              
33             our $VERSION = '0.01';
34              
35             our $MODNAME = 'Apache::AuthPAM';
36              
37             #
38             # I use this global to pass user info to the conversation function
39             # if you know a better way to do it, please tell me and/or fix it.
40             #
41             our %pw;
42              
43             # Preloaded methods go here.
44              
45             sub handler {
46             # get object request
47             my $r = shift;
48              
49             # check first request
50             return OK unless $r->is_initial_req;
51              
52             # get user password
53             my ($rc, $pw) = $r->get_basic_auth_pw;
54              
55             # decline if not basic
56             return $rc if $rc;
57              
58             # get log object
59             my $log = $r->log;
60              
61             # get user name
62             my $username = $r->connection->user;
63              
64             # avoid blank username
65             unless($username) {
66             $r->note_basic_auth_failure;
67             $log->info("$MODNAME: no user name supplied", $r->uri);
68             return AUTH_REQUIRED;
69             }
70              
71             # load apache config vars
72             my $service = $r->dir_config('PAMservice');
73             unless($service) {
74             $log->alert("$MODNAME: no PAM service name supplied", $r->uri);
75             return SERVER_ERROR;
76             }
77              
78             # DAMN! I shouldn't use globals this way!
79             $pw{$$}=$pw;
80              
81             # start PAM dialog
82             my $pamh;
83             my $result = pam_start($service, $username, \&my_conv_func, $pamh);
84              
85             unless ($result == PAM_SUCCESS) {
86             $r->note_basic_auth_failure;
87             $log->crit("$MODNAME: <$service> not started ($result) ", $r->uri);
88             pam_end($pamh, 0);
89             return SERVER_ERROR;
90             }
91              
92             $result = pam_authenticate($pamh, 0);
93             unless ($result == PAM_SUCCESS) {
94             $r->note_basic_auth_failure;
95             $log->info("$MODNAME: <$username> not authenticated by $service ($result) ", $r->uri);
96             pam_end($pamh, 0);
97             return AUTH_REQUIRED;
98             }
99              
100             $result = pam_acct_mgmt($pamh, 0);
101             unless ($result == PAM_SUCCESS) {
102             $r->note_basic_auth_failure;
103             $log->info("$MODNAME: <$username> no acct mgmt by $service ($result) ", $r->uri);
104             pam_end($pamh, 0);
105             return AUTH_REQUIRED;
106             }
107              
108             # Authenticated
109             pam_end($pamh, 0);
110             $log->info("$MODNAME: <$username> authenticated by $service", $r->uri);
111             return OK;
112             }
113              
114             #
115             # Conversation Function
116             #
117             sub my_conv_func {
118             my @res;
119             while(@_) {
120             my $msg_type = shift;
121             my $msg = shift;
122             push @res, (0, $pw{$$});
123             }
124             push @res, 0;
125             return @res;
126             }
127              
128             1;
129             __END__