###
### Copyright 2000-2007 University of Illinois Board of Trustees
### All rights reserved.
###
### TCPWrappers.pm - TCPWrappers module for psgconf
###
### Campus Information Technologies and Educational Services
### University of Illinois at Urbana-Champaign
###
package PSGConf::Control::TCPWrappers;
use strict;
use PSGConf::Action::GenerateFile::hosts_allow;
use PSGConf::Action::GenerateFile::Literal;
use PSGConf::Data::Boolean;
use PSGConf::Data::List;
use PSGConf::Data::String;
use PSGConf::Data::Table;
use PSGConf::Control::Packages qw(_add_pkgs);
###############################################################################
### policy methods
###############################################################################
sub _policy_modify_inetd
{
my ($self, $psgconf) = @_;
my ($label, $entry, $inetd, $svc, $proto, @args, $tcpd_path);
return
if ($psgconf->data_obj('use_xinetd')->equals('true'));
$tcpd_path = $psgconf->data_obj('tcpd_path')->get();
$inetd = $psgconf->data_obj('inetd')->get();
foreach $label (keys %$inetd)
{
$entry = $inetd->{$label};
($svc, $proto) = split(/\//, $label);
next
if ($proto ne 'tcp'
|| $entry->{server} eq 'internal'
|| exists($entry->{flags}->{NOLIBWRAP}));
@args = split(/\s+/, $entry->{server_args});
shift(@args)
if (exists($entry->{flags}->{NAMEINARGS}));
unshift(@args, $entry->{server});
$entry->{server_args} = join(' ', @args);
$entry->{server} = $tcpd_path;
$entry->{flags}->{NAMEINARGS} = undef;
}
}
sub _policy_add_rfc931_token
{
my ($self, $psgconf) = @_;
my ($entry);
return
if ( $psgconf->data_obj('tcp_rfc931_enable')->equals('false') );
foreach $entry (@{$psgconf->data_obj('tcp_wrappers')->get()})
{
# If this is the localhost entry, do not
# bother with rfc931.
if ( $entry->[1] !~ /localhost/o ) {
$entry->[3] = $entry->[2];
$entry->[2] = 'rfc931';
}
}
}
sub _policy_expand_hostname_token
{
my ($self, $psgconf) = @_;
my ($entry, $hostname);
$hostname = $psgconf->data_obj('hostname')->get();
foreach $entry (@{$psgconf->data_obj('tcp_wrappers')->get()})
{
### replace "%h" with hostname in host list
$entry->[1] =~ s/%h/$hostname/;
}
}
###############################################################################
### decide() method
###############################################################################
sub decide
{
my ($self, $psgconf) = @_;
return
if ($psgconf->data_obj('tcp_enable')->equals('false')
|| ! $psgconf->data_obj('tcp_wrappers')->count());
$psgconf->register_actions(
PSGConf::Action::GenerateFile::hosts_allow->new(
'name' => '/etc/hosts.allow',
'description' => 'TCP Wrapper configuration file',
entries => $psgconf->data_obj('tcp_wrappers')->get()
),
PSGConf::Action::GenerateFile::Literal->new(
'name' => '/etc/hosts.deny',
'description' => 'TCP Wrapper configuration file',
content => ''
)
);
}
###############################################################################
### Constructor
###############################################################################
sub new
{
my ($class, $psgconf) = @_;
my ($self);
$self = {};
bless($self, $class);
### So that _add_pkgs knows which directives to look at
$self->{name} = 'tcp';
$self->{enable} = $self->{name} . '_enable';
$self->{packages} = $self->{name} . '_packages';
$psgconf->register_data(
tcpd_path => PSGConf::Data::String->new(
'value_abspath' => 1,
value => '/usr/local/sbin/tcpd'
),
tcp_enable => PSGConf::Data::Boolean->new(
value => 'true'
),
tcp_rfc931_enable => PSGConf::Data::Boolean->new(
value => 'false'
),
tcp_packages => PSGConf::Data::List->new(),
tcp_wrappers => PSGConf::Data::Table->new()
);
$psgconf->register_policy($self,
tcpd_expand_hostname_token => '_policy_expand_hostname_token',
tcpd_modify_inetd => '_policy_modify_inetd',
tcpd_add_rfc931 => '_policy_add_rfc931_token',
tcpd_add_packages => '_add_pkgs'
);
return $self;
}
###############################################################################
### documentation
###############################################################################
1;
__END__
=head1 NAME
PSGConf::Control::TCPWrappers - psgconf control class for TCP wrappers
=head1 SYNOPSIS
In F<psgconf_modules>:
Control PSGConf::Control::TCPWrappers
=head1 DESCRIPTION
The B<PSGConf::Control::TCPWrappers> module provides a B<psgconf> control
object for configuring TCP wrappers. 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<tcp_enable>
A B<PSGConf::Data::Boolean> object that indicates whether C<tcp_wrappers>
should be configured.
=item I<tcp_packages>
A B<PSGConf::Data::List> object that lists all packages to install.
=item I<tcpd_path>
A B<PSGConf::Data::String> object containing the absolute path to the
C<tcpd> binary. The default is F</usr/local/sbin/tcpd>.
=item I<tcp_rfc931_enable>
A B<PSGConf::Data::Boolean> object that indicates whether the
F<rfc931> should be used in F</etc/hosts.allow>.
=item I<tcp_wrappers>
A B<PSGConf::Data::Table> object that contains entries for
F</etc/hosts.allow>. Each row consists of the following fields: a
space-delimited list of daemons, a space-delimited list of hosts, and
one or more options.
=back
The constructor also registers the following policy methods:
=over 4
=item I<tcpd_expand_hostname_token>
For each entry in the I<tcp_wrappers> data object, in the host field,
the token C<%h> will be replaced with the value of the I<hostname>
data object, which is provided by the B<PSGConf::Control::Core> module.
=item I<tcpd_modify_inetd>
If I<use_xinetd> is disabled, then modify the entries in the I<inetd> data
object (provided by the B<PSGConf::Control::inetd> module) to use
C<tcpd>. Entries will only be modified if they specify the C<tcp>
protocol, do not have the I<server> attribute set to C<internal>, and do
not have the I<NOLIBWRAP> flag set.
=item I<tcpd_add_rfc931>
If I<tcp_rfc931_enable> is set, then add the token I<rfc931> to all entries
to the I<tcp_wrappers> table.
=back
=item decide()
If the I<tcp_wrappers> data object is defined, it registers
a B<PSGConf::Action::GenerateFile::hosts_allow> action
object to create F</etc/hosts.allow>. Also registers a
B<PSGConf::Action::GenerateFile::Literal> action object to create the
F</etc/hosts.deny> file (which will be an empty file).
=back
=head1 SEE ALSO
L<perl>
hosts_options(5)
L<PSGConf>
L<PSGConf::Action::GenerateFile::hosts_allow>
L<PSGConf::Action::GenerateFile::Literal>
L<PSGConf::Control::Core>
L<PSGConf::Control::inetd>
L<PSGConf::Control::Packages>
L<PSGConf::Data::Boolean>
L<PSGConf::Data::List>
L<PSGConf::Data::String>
L<PSGConf::Data::Table>
L<psgconf-intro>
=cut
syntax highlighted by Code2HTML, v. 0.9.1