# See bottom of file for license and copyright information

=begin TML

---+ package Foswiki\::Users\::PAM

Superclass of password handlers that uses PAM "login" services for
authentications. Provides authentitcation and users listing. Don't
allows password modifications.

Users with uid below 1000 (system users) are automatically discarded.

See Foswiki\::Users\::Password for methods usage.

=cut

package Foswiki\::Users\::PAM;
use strict;
use warnings;

use Foswiki\::Users\::Password;
our @ISA = ('Foswiki\::Users\::Password');

use Assert;
use Error qw( :try );
use Authen\::PAM;

use base qw( Foswiki\::Users\::Password );


my $username;
my $password;
my $service	= "login";
my $LowLimit	= 1000;	# don't show users below this limit

sub readOnly {
	return 0;
}

sub checkPassword {
	my( $this, $login, $passU ) = @_;
	ASSERT( $login ) if DEBUG;

	###print( STDERR ">>> checking user: '$login' pass '$passU'\n" );

	$username	= $login;
	$password	= $passU;

	my( $pamh, $res );

	ref ($pamh = new Authen\::PAM( $service, $login, \&_my_conv_func)) ||
 		return 0;

	$res = $pamh->pam_authenticate;

	if ($res != PAM_SUCCESS()) {
		###$this->{error}	= $parmh->pam_strerror($res);
		###print( STDERR ">1> " . $pamh->pam_strerror($res) . "\n" );
		return 0;
	}
	return 1;
}


sub canFetchUsers {
	return 1;
}

sub fetchUsers {
	my $this  = shift;
	my $db    = _readPasswd( $this );
	my @users = sort keys %$db;
	require Foswiki\::ListIterator;
	return new Foswiki\::ListIterator( \@users );
}

sub _readPasswd {
	my $this = shift;
	$this->{error} = undef;

	my $data = {};
	my @tmp;

	while (@tmp = getpwent()) {
		next	if ($tmp[2] < $LowLimit);
		$data->{$tmp[0]}->{gid}		= $tmp[3] || '';
		$data->{$tmp[0]}->{gecos}	= $tmp[4] || '';
	}
	# use Data\::Dumper;
	# print STDERR Dumper( $data );

	return $data;
}

sub _my_conv_func {
	my @res;
	while ( @_ ) {
		my $code = shift;
		my $msg = shift;
		my $ans = "";

		$ans = $username if ($code == PAM_PROMPT_ECHO_ON() );
		$ans = $password if ($code == PAM_PROMPT_ECHO_OFF() );

		push @res, (PAM_SUCCESS(),$ans);
	}
	push @res, PAM_SUCCESS();
	return @res;
}


1;

__END__

This file is a plugin for Foswiki - The Free and Open Source
Wiki, http://foswiki.org/ -- see original packages for
Foswiki copyright

--------------------

(c) 2013 Lorenzo Canovi <lorenzo@kubiclabs.com>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. For
more details read LICENSE in the root of this distribution.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

As per the GPL, removal of this notice is prohibited.
