# See bottom of file for license and copyright information

=begin TML

---+ package Foswiki\::Users\::PAMsudo

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.

The module relies on:

  * presence of external helper program /usr/sbin/validateuser

  * sudo entry that allow apache user to run the helper
    program without asking any password, eg:

    	www-data ALL=NOPASSWD: /usr/sbin/validateuser

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

=cut

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

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

use Assert;
use Error qw( :try );

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


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

sub readOnly {
	return 0;
}

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

	# discard uids below limit
	print( STDERR "$login uid=".getpwnam($login)."\n" );
	return 0	if (getpwnam($login) < $LowLimit);

	# ugly hack to taint PATH env
	my $savepath = $ENV{PATH};
	$ENV{PATH} = "";

	my $cmd = join( " ", '|/usr/bin/sudo', '-n',
		'/usr/sbin/validateuser', "'$service'",
		'>/dev/null' );
	my $pipe;
	open( $pipe, $cmd ) || die ( "can't exec '$cmd': $!\n" );
	print( $pipe "$login\n" );
	print( $pipe "$passU\n" );
	my $res = close( $pipe );

	# restores PATH (we need it? yes, I suppose, ENV is global)
	$ENV{PATH} = $savepath;

	return 1	if ($res);
	return 0;
}


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;
}


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.
