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


package PSGConf::Control::RPC::rstatd;

use File::Basename;
use PSGConf::Data::Boolean;
use PSGConf::Data::List;
use PSGConf::Data::String;
use PSGConf::Control::Packages qw(_add_pkgs);
use PSGConf::Util qw(get_addrs);

use strict;


###############################################################################
###  policy methods
###############################################################################

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

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

	$psgconf->data_obj('rpc_enable')->set('true');

     $psgconf->data_obj('rc_scripts')->insert(
		{ 'rstat' => { 'state' => 'enable' } }
	) if ( $psgconf->data_obj('platform')->match('solaris10') );
}

### add TCP wrappers entry
sub _policy_add_tcpwrapper_entry
{
     my ($self, $psgconf) = @_;
     my ($cmd, $hosts);

     return
          if ( $psgconf->data_obj('rstatd_enable')->equals('false') 
			|| $psgconf->data_obj('rstatd_clients')->count() == 0 );

	$cmd = basename ($psgconf->data_obj('rstatd_cmd')->get());

	### Need to translate to IP addresses so that
	### tcp_wrappers works correctly.
	map {
		$hosts .= ' ' if ( defined $hosts );
		$hosts .= join (' ', &get_addrs($psgconf, $_));
	} @{$psgconf->data_obj('rstatd_clients')->get()};

     $psgconf->data_obj('tcp_wrappers')->insert_row(
          { 1 => 'all' },
          [ $cmd, $hosts, 'allow' ]
     )
          if (! $psgconf->data_obj('tcp_wrappers')->find_row(
                         { 0 => qr/\b$cmd\b/ }));

	### Also add access to rpcbind/portmap as well.
	$cmd = ($psgconf->data_obj('platform')->match('aix|linux'))
		? 'portmap'
		: 'rpcbind';

	if (! $psgconf->data_obj('tcp_wrappers')->find_row(
                         { 0 => qr/\b$cmd\b/ })) {
     	$psgconf->data_obj('tcp_wrappers')->insert_row(
			{ 1 => 'all' },
			[ $cmd, $hosts, 'allow' ]
		);
	} else {
		$psgconf->data_obj('tcp_wrappers')->append_to_row_cells(
			{ 0 => qr/\b$cmd\b/ },
			{ 1 => $hosts }
		);
	}
}

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

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

     if (! defined $psgconf->data_obj('inetd_rpc')->find('rstatd/1-4') )
     {
		if ( ! $psgconf->data_obj('platform')->match('solaris10') ) {
			$psgconf->data_obj('inetd_rpc')->insert(
				{ 'rstatd/1-4' => {
               		server         => $psgconf->data_obj('rstatd_cmd')->get(),
					socket_type	=> 'dgram',
					protocol		=> 'udp',
					wait			=> 1
					}
          		}
			);
		}

		if ( $psgconf->data_obj('platform')->match('solaris[89]') ) {
			$psgconf->data_obj('inetd_rpc')->insert(
				{ 'rstatd/1-4' => {
						'socket_type'	=> 'tli',
						'protocol'	=> 'datagram_v'
					}
				}
			);
		}

		if ( $psgconf->data_obj('platform')->match('aix') ) {
			$psgconf->data_obj('inetd_rpc')->insert(
				{ 'rstatd/1-4' => {
						'server_args'	=> '100001 1-3',
						'socket_type'	=> 'sunrpc_udp'
					}
				}
			);
		}
     }
}


###############################################################################
###  constructor
###############################################################################

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

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

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

	$psgconf->register_data(
		rstatd_enable		=> PSGConf::Data::Boolean->new(
							value => 'false'
						),
		rstatd_cmd		=> PSGConf::Data::String->new(
							'value_abspath' => 1,
							value => '/usr/sbin/rpc.rstatd'
						),
		rstatd_packages	=> PSGConf::Data::List->new(),
		rstatd_clients		=> PSGConf::Data::List->new()
	);

	$psgconf->register_policy($self,
		rstatd_add_packages	=> '_add_pkgs',
		rstatd_enable_rc_scripts	=> '_enable_rc_scripts',
		rstatd_add_tcpwrapper_entry => '_policy_add_tcpwrapper_entry',
		rstatd_add_inetd_entry => '_policy_add_inetd_entry'
	);

	return $self;
}


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

1;

__END__

=head1 NAME

PSGConf::Control::RPC::rstatd - psgconf control class for rstatd configuration

=head1 SYNOPSIS

In F<psgconf_modules>:

  Control PSGConf::Control::RPC::rstatd

=head1 DESCRIPTION

The B<PSGConf::Control::RPC::rstatd> module provides a B<psgconf> control object
for configuring RPC services.  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<rstatd_enable>

A B<PSGConf::Data::Boolean> object enabling the RPC module.

=item I<rstatd_packages>

A B<PSGConf::Data::List> object containing the packages to install.

=item I<rstatd_cmd>

A B<PSGConf::Data::String> object containing the location of the rstatd
binary.  Defaults to F</usr/sbin/rpc.rstatd>.

=item I<rstatd_clients>

A B<PSGConf::Data::List> object containing the list of clients that
we will allow to connect to the rstatd server (via tcp_wrappers).

=back

The constructor also registers the following policy method:

=over 4

=item I<rstatd_add_packages>

Adds the packges listed in the C<rstatd_packages> directive to the
C<pkg_install_list> list to be installed by the C<Packages>
Control module.

=item I<rstatd_enable_rc_scripts>

Enables C<rpcbind> or C<portmap> and C<rpc.rstatd> to be started at boot time.

=item I<rstatd_add_tcp_wrappers>

Adds C<rstatd_clients> to the tcpwrappers entry for C<rstatd_cmd>.

=back

=item decide()

=back

=head1 SEE ALSO

L<perl>

L<File::Basename>

L<PSGConf>

L<PSGConf::Control::Packages>

L<PSGConf::Data::Boolean>

L<PSGConf::Data::List>

L<PSGConf::Data::String>

L<PSGConf::Util>

L<psgconf-intro>

=cut



syntax highlighted by Code2HTML, v. 0.9.1