###
###  Copyright 2000-2007 University of Illinois Board of Trustees
###  All rights reserved. 
###
###  PAM.pm - PAM configuration module for psgconf
###
###  Campus Information Technologies and Educational Services
###  University of Illinois at Urbana-Champaign
###


package PSGConf::Control::PAM;

use strict;

use PSGConf::Action::GenerateFile::pam_conf;
use PSGConf::Action::GenerateFile::pam_file;
use PSGConf::Data::Boolean;
use PSGConf::Data::List;
use PSGConf::Data::Hash;
use PSGConf::Control::Packages qw(_add_pkgs);

###############################################################################
###  Utility function to be called from other Control modules
###############################################################################

require Exporter;
our @ISA = qw (Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw( _add_pam) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} });
our @EXPORT = qw();

sub _add_pam
{
	my ($self, $psgconf) = @_;

	if (!exists($self->{enable}) || $self->{enable} eq '') {
		warn "\t!!!Control::PAM->_add_pam(): no enable attribute(s)\n";
		return;
	}

     return
		if ($psgconf->data_obj($self->{enable})->equals('false'));

	if (!exists($self->{pam_name}) || $self->{pam_name} eq ''
		&& !exists($self->{pam_conf}) || $self->{pam_conf} eq '' ) {
		warn "\t!!!Control::PAM->_add_pam(): no pam_name/pam_conf attributes\n";
		return;
	}

	$psgconf->data_obj('pam_conf')->insert({
		$self->{pam_name} => $self->{pam_conf}
	}) if ( ! $psgconf->data_obj('pam_conf')->exists($self->{pam_name}) );
}

###############################################################################
###  decide() method
###############################################################################

sub decide
{
	my ($self, $psgconf) = @_;

	return
		if ($psgconf->data_obj('pam_enable')->equals('false'));

	if ($psgconf->data_obj('pam_directory')->equals('true'))
	{
		$psgconf->register_actions(
			(map {
				PSGConf::Action::GenerateFile::pam_file->new(
					name			=> "/etc/pam.d/$_",
					description	=> "PAM configuration for $_",

					### We do not want to backup this file
					### so we know what files to clean out as well
					backup		=> 0,
					pam_file		=> $psgconf->data_obj('pam_conf')->find($_)
				)
			} sort keys %{$psgconf->data_obj('pam_conf')->get()}),

			### remove any other /etc/pam.d/* files
			(map {
				PSGConf::Action::Remove->new(
					name      => $_,
					backup	=> 0
				)
			} grep { m|^/etc/pam.d/([^/]*)$| &&
				!defined $psgconf->data_obj('pam_conf')->find($1); }
				glob('/etc/pam.d/*'))
		);
	}
	else
	{
		$psgconf->register_actions(
			PSGConf::Action::GenerateFile::pam_conf->new(
				'name'		=> '/etc/pam.conf',
				'description'	=> 'PAM configuration file',
				pam_conf	=> $psgconf->data_obj('pam_conf')->get()
			)
		);
	}
}


###############################################################################
###  Constructor
###############################################################################

sub new
{
	my ($class, $psgconf) = @_;
	my ($self);

	$self = {};
	bless($self, $class);

	### So that _add_pkgs knows which directives to look at
	$self->{name} = 'pam';
	$self->{enable} = $self->{name} . '_enable';
	$self->{packages} = $self->{name} . '_packages';

	$psgconf->register_data(
		'pam_conf'		=> PSGConf::Data::Hash->new(
						'value_type' => 'ARRAY'
					),
		'pam_enable'		=> PSGConf::Data::Boolean->new(
						value => 'false'
					),
		'pam_packages'		=> PSGConf::Data::List->new(),
		'pam_directory'		=> PSGConf::Data::Boolean->new(
						value => 'false'
					)
	);

     $psgconf->register_policy($self,
          pam_add_packages   => '_add_pkgs'
     );

	return $self;
}


###############################################################################
###  documentation
###############################################################################

1;

__END__

=head1 NAME

PSGConf::Control::PAM - psgconf control class for PAM configuration

=head1 SYNOPSIS

In F<psgconf_modules>:

  Control PSGConf::Control::PAM

=head1 DESCRIPTION

The B<PSGConf::Control::PAM> module provides a B<psgconf> control object
for configuring PAM.  It supports the following methods:

=over 4

=item new()

The constructor.  Its parameter is a reference to the B<PSGConf>
object.  It registers the following data objects:

=over 4

=item I<pam_conf>

A B<PSGConf::Data::Hash> object containing the PAM configuration for
each service.  The key is the name of the PAM service, and the value is
a reference to a list of entries for that service.

=item I<pam_enable>

A B<PSGConf::Data::Boolean> object that determines whether PAM should be
configured.  The default is no.

=item I<pam_packages>

A B<PSGConf::Data::List> object that lists all packages to install.

=item I<pam_directory>

A B<PSGConf::Data::Boolean> object that determines whether PAM is
configured by generating individual files in the F</etc/pam.d> directory.
The default is to configure PAM by generating F</etc/pam.conf>.

=back

=item decide()

If I<pam_enable> is set, registers the appropriate
B<PSGConf::Action::GenerateFile> objects based on the value of
I<pam_directory>.

=back

=head1 SEE ALSO

L<perl>

pam.conf(4)

L<PSGConf>

L<PSGConf::Action::GenerateFile>

L<PSGConf::Action::Control::Packages>

L<PSGConf::Data::Boolean>

L<PSGConf::Data::List>

L<PSGConf::Data::Hash>

L<psgconf-intro>

=cut



syntax highlighted by Code2HTML, v. 0.9.1